The following commit has been merged in the master branch: commit 45d986d11313ff2d8ed2cf6a34e2aefdc4639a99 Merge: 4a39ac5b7d62679c07a3e3d12b0f6982377d8a7d 6c4a5f96450415735c31ed70ff354f0ee5cbf67b Author: Linus Torvalds torvalds@linux-foundation.org Date: Thu Sep 19 06:33:18 2024 +0200
Merge tag 'ovl-update-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/overlayfs/vfs
Pull overlayfs updates from Amir Goldstein:
- Increase robustness of overlayfs to crashes in the case of underlying filesystems that to not guarantee metadata ordering to persistent storage (problem was reported with ubifs).
- Deny mount inside container with features that require root privileges to work properly, instead of failing operations later.
- Some clarifications to overlayfs documentation.
* tag 'ovl-update-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/overlayfs/vfs: ovl: fail if trusted xattrs are needed but caller lacks permission overlayfs.rst: update metacopy section in overlayfs documentation ovl: fsync after metadata copy-up ovl: don't set the superblock's errseq_t manually
diff --combined fs/overlayfs/copy_up.c index 337a5be99ac9f,051a802893a18..2ed6ad641a206 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@@ -115,12 -115,12 +115,12 @@@ int ovl_copy_xattr(struct super_block * continue;
error = security_inode_copy_up_xattr(old, name); - if (error < 0 && error != -EOPNOTSUPP) - break; - if (error == 1) { + if (error == -ECANCELED) { error = 0; continue; /* Discard */ } + if (error < 0 && error != -EOPNOTSUPP) + break;
if (is_posix_acl_xattr(name)) { error = ovl_copy_acl(OVL_FS(sb), oldpath, new, name); @@@ -243,8 -243,24 +243,24 @@@ static int ovl_verify_area(loff_t pos, return 0; }
+ static int ovl_sync_file(struct path *path) + { + struct file *new_file; + int err; + + new_file = ovl_path_open(path, O_LARGEFILE | O_RDONLY); + if (IS_ERR(new_file)) + return PTR_ERR(new_file); + + err = vfs_fsync(new_file, 0); + fput(new_file); + + return err; + } + static int ovl_copy_up_file(struct ovl_fs *ofs, struct dentry *dentry, - struct file *new_file, loff_t len) + struct file *new_file, loff_t len, + bool datasync) { struct path datapath; struct file *old_file; @@@ -342,7 -358,8 +358,8 @@@
len -= bytes; } - if (!error && ovl_should_sync(ofs)) + /* call fsync once, either now or later along with metadata */ + if (!error && ovl_should_sync(ofs) && datasync) error = vfs_fsync(new_file, 0); out_fput: fput(old_file); @@@ -574,6 -591,7 +591,7 @@@ struct ovl_copy_up_ctx bool indexed; bool metacopy; bool metacopy_digest; + bool metadata_fsync; };
static int ovl_link_up(struct ovl_copy_up_ctx *c) @@@ -634,7 -652,8 +652,8 @@@ static int ovl_copy_up_data(struct ovl_ if (IS_ERR(new_file)) return PTR_ERR(new_file);
- err = ovl_copy_up_file(ofs, c->dentry, new_file, c->stat.size); + err = ovl_copy_up_file(ofs, c->dentry, new_file, c->stat.size, + !c->metadata_fsync); fput(new_file);
return err; @@@ -701,6 -720,10 +720,10 @@@ static int ovl_copy_up_metadata(struct err = ovl_set_attr(ofs, temp, &c->stat); inode_unlock(temp->d_inode);
+ /* fsync metadata before moving it into upper dir */ + if (!err && ovl_should_sync(ofs) && c->metadata_fsync) + err = ovl_sync_file(&upperpath); + return err; }
@@@ -860,7 -883,8 +883,8 @@@ static int ovl_copy_up_tmpfile(struct o
temp = tmpfile->f_path.dentry; if (!c->metacopy && c->stat.size) { - err = ovl_copy_up_file(ofs, c->dentry, tmpfile, c->stat.size); + err = ovl_copy_up_file(ofs, c->dentry, tmpfile, c->stat.size, + !c->metadata_fsync); if (err) goto out_fput; } @@@ -1135,6 -1159,17 +1159,17 @@@ static int ovl_copy_up_one(struct dentr !kgid_has_mapping(current_user_ns(), ctx.stat.gid)) return -EOVERFLOW;
+ /* + * With metacopy disabled, we fsync after final metadata copyup, for + * both regular files and directories to get atomic copyup semantics + * on filesystems that do not use strict metadata ordering (e.g. ubifs). + * + * With metacopy enabled we want to avoid fsync on all meta copyup + * that will hurt performance of workloads such as chown -R, so we + * only fsync on data copyup as legacy behavior. + */ + ctx.metadata_fsync = !OVL_FS(dentry->d_sb)->config.metacopy && + (S_ISREG(ctx.stat.mode) || S_ISDIR(ctx.stat.mode)); ctx.metacopy = ovl_need_meta_copy_up(dentry, ctx.stat.mode, flags);
if (parent) {
linux-merge@lists.open-mesh.org