Skip to content

Commit 15fd2ea

Browse files
rhvgoyalMiklos Szeredi
authored andcommitted
ovl: clear ATTR_OPEN from attr->ia_valid
As of now during open(), we don't pass bunch of flags to underlying filesystem. O_TRUNC is one of these. Normally this is not a problem as VFS calls ->setattr() with zero size and underlying filesystem sets file size to 0. But when overlayfs is running on top of virtiofs, it has an optimization where it does not send setattr request to server if dectects that truncation is part of open(O_TRUNC). It assumes that server already zeroed file size as part of open(O_TRUNC). fuse_do_setattr() { if (attr->ia_valid & ATTR_OPEN) { /* * No need to send request to userspace, since actual * truncation has already been done by OPEN. But still * need to truncate page cache. */ } } IOW, fuse expects O_TRUNC to be passed to it as part of open flags. But currently overlayfs does not pass O_TRUNC to underlying filesystem hence fuse/virtiofs breaks. Setup overlayfs on top of virtiofs and following does not zero the file size of a file is either upper only or has already been copied up. fd = open(foo.txt, O_TRUNC | O_WRONLY); There are two ways to fix this. Either pass O_TRUNC to underlying filesystem or clear ATTR_OPEN from attr->ia_valid so that fuse ends up sending a SETATTR request to server. Miklos is concerned that O_TRUNC might have side affects so it is better to clear ATTR_OPEN for now. Hence this patch clears ATTR_OPEN from attr->ia_valid. I found this problem while running unionmount-testsuite. With this patch, unionmount-testsuite passes with overlayfs on top of virtiofs. Signed-off-by: Vivek Goyal <[email protected]> Fixes: bccece1 ("ovl: allow remote upper") Signed-off-by: Miklos Szeredi <[email protected]>
1 parent e67f021 commit 15fd2ea

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

fs/overlayfs/inode.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,23 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
5959
attr->ia_valid &= ~ATTR_MODE;
6060

6161
/*
62-
* We might have to translate ovl file into underlying file
63-
* object once some use cases are there. For now, simply don't
64-
* let underlying filesystem rely on attr->ia_file
62+
* We might have to translate ovl file into real file object
63+
* once use cases emerge. For now, simply don't let underlying
64+
* filesystem rely on attr->ia_file
6565
*/
6666
attr->ia_valid &= ~ATTR_FILE;
6767

68+
/*
69+
* If open(O_TRUNC) is done, VFS calls ->setattr with ATTR_OPEN
70+
* set. Overlayfs does not pass O_TRUNC flag to underlying
71+
* filesystem during open -> do not pass ATTR_OPEN. This
72+
* disables optimization in fuse which assumes open(O_TRUNC)
73+
* already set file size to 0. But we never passed O_TRUNC to
74+
* fuse. So by clearing ATTR_OPEN, fuse will be forced to send
75+
* setattr request to server.
76+
*/
77+
attr->ia_valid &= ~ATTR_OPEN;
78+
6879
inode_lock(upperdentry->d_inode);
6980
old_cred = ovl_override_creds(dentry->d_sb);
7081
err = notify_change(upperdentry, attr, NULL);

0 commit comments

Comments
 (0)