Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+79 -19
+5 -2
Documentation/filesystems/overlayfs.rst
··· 367 367 368 368 When the "metacopy" feature is enabled, overlayfs will only copy 369 369 up metadata (as opposed to whole file), when a metadata specific operation 370 - like chown/chmod is performed. Full file will be copied up later when 371 - file is opened for WRITE operation. 370 + like chown/chmod is performed. An upper file in this state is marked with 371 + "trusted.overlayfs.metacopy" xattr which indicates that the upper file 372 + contains no data. The data will be copied up later when file is opened for 373 + WRITE operation. After the lower file's data is copied up, 374 + the "trusted.overlayfs.metacopy" xattr is removed from the upper file. 372 375 373 376 In other words, this is delayed data copy up operation and data is copied 374 377 up when there is a need to actually modify data.
+39 -4
fs/overlayfs/copy_up.c
··· 243 243 return 0; 244 244 } 245 245 246 + static int ovl_sync_file(struct path *path) 247 + { 248 + struct file *new_file; 249 + int err; 250 + 251 + new_file = ovl_path_open(path, O_LARGEFILE | O_RDONLY); 252 + if (IS_ERR(new_file)) 253 + return PTR_ERR(new_file); 254 + 255 + err = vfs_fsync(new_file, 0); 256 + fput(new_file); 257 + 258 + return err; 259 + } 260 + 246 261 static int ovl_copy_up_file(struct ovl_fs *ofs, struct dentry *dentry, 247 - struct file *new_file, loff_t len) 262 + struct file *new_file, loff_t len, 263 + bool datasync) 248 264 { 249 265 struct path datapath; 250 266 struct file *old_file; ··· 358 342 359 343 len -= bytes; 360 344 } 361 - if (!error && ovl_should_sync(ofs)) 345 + /* call fsync once, either now or later along with metadata */ 346 + if (!error && ovl_should_sync(ofs) && datasync) 362 347 error = vfs_fsync(new_file, 0); 363 348 out_fput: 364 349 fput(old_file); ··· 591 574 bool indexed; 592 575 bool metacopy; 593 576 bool metacopy_digest; 577 + bool metadata_fsync; 594 578 }; 595 579 596 580 static int ovl_link_up(struct ovl_copy_up_ctx *c) ··· 652 634 if (IS_ERR(new_file)) 653 635 return PTR_ERR(new_file); 654 636 655 - err = ovl_copy_up_file(ofs, c->dentry, new_file, c->stat.size); 637 + err = ovl_copy_up_file(ofs, c->dentry, new_file, c->stat.size, 638 + !c->metadata_fsync); 656 639 fput(new_file); 657 640 658 641 return err; ··· 719 700 if (!err) 720 701 err = ovl_set_attr(ofs, temp, &c->stat); 721 702 inode_unlock(temp->d_inode); 703 + 704 + /* fsync metadata before moving it into upper dir */ 705 + if (!err && ovl_should_sync(ofs) && c->metadata_fsync) 706 + err = ovl_sync_file(&upperpath); 722 707 723 708 return err; 724 709 } ··· 883 860 884 861 temp = tmpfile->f_path.dentry; 885 862 if (!c->metacopy && c->stat.size) { 886 - err = ovl_copy_up_file(ofs, c->dentry, tmpfile, c->stat.size); 863 + err = ovl_copy_up_file(ofs, c->dentry, tmpfile, c->stat.size, 864 + !c->metadata_fsync); 887 865 if (err) 888 866 goto out_fput; 889 867 } ··· 1159 1135 !kgid_has_mapping(current_user_ns(), ctx.stat.gid)) 1160 1136 return -EOVERFLOW; 1161 1137 1138 + /* 1139 + * With metacopy disabled, we fsync after final metadata copyup, for 1140 + * both regular files and directories to get atomic copyup semantics 1141 + * on filesystems that do not use strict metadata ordering (e.g. ubifs). 1142 + * 1143 + * With metacopy enabled we want to avoid fsync on all meta copyup 1144 + * that will hurt performance of workloads such as chown -R, so we 1145 + * only fsync on data copyup as legacy behavior. 1146 + */ 1147 + ctx.metadata_fsync = !OVL_FS(dentry->d_sb)->config.metacopy && 1148 + (S_ISREG(ctx.stat.mode) || S_ISDIR(ctx.stat.mode)); 1162 1149 ctx.metacopy = ovl_need_meta_copy_up(dentry, ctx.stat.mode, flags); 1163 1150 1164 1151 if (parent) {
+33 -5
fs/overlayfs/params.c
··· 755 755 { 756 756 struct ovl_opt_set set = ctx->set; 757 757 758 - if (ctx->nr_data > 0 && !config->metacopy) { 759 - pr_err("lower data-only dirs require metacopy support.\n"); 760 - return -EINVAL; 761 - } 762 - 763 758 /* Workdir/index are useless in non-upper mount */ 764 759 if (!config->upperdir) { 765 760 if (config->workdir) { ··· 904 909 */ 905 910 config->redirect_mode = OVL_REDIRECT_NOFOLLOW; 906 911 config->metacopy = false; 912 + } 913 + 914 + /* 915 + * Fail if we don't have trusted xattr capability and a feature was 916 + * explicitly requested that requires them. 917 + */ 918 + if (!config->userxattr && !capable(CAP_SYS_ADMIN)) { 919 + if (set.redirect && 920 + config->redirect_mode != OVL_REDIRECT_NOFOLLOW) { 921 + pr_err("redirect_dir requires permission to access trusted xattrs\n"); 922 + return -EPERM; 923 + } 924 + if (config->metacopy && set.metacopy) { 925 + pr_err("metacopy requires permission to access trusted xattrs\n"); 926 + return -EPERM; 927 + } 928 + if (config->verity_mode) { 929 + pr_err("verity requires permission to access trusted xattrs\n"); 930 + return -EPERM; 931 + } 932 + if (ctx->nr_data > 0) { 933 + pr_err("lower data-only dirs require permission to access trusted xattrs\n"); 934 + return -EPERM; 935 + } 936 + /* 937 + * Other xattr-dependent features should be disabled without 938 + * great disturbance to the user in ovl_make_workdir(). 939 + */ 940 + } 941 + 942 + if (ctx->nr_data > 0 && !config->metacopy) { 943 + pr_err("lower data-only dirs require metacopy support.\n"); 944 + return -EINVAL; 907 945 } 908 946 909 947 return 0;
+2 -8
fs/overlayfs/super.c
··· 202 202 int ret; 203 203 204 204 ret = ovl_sync_status(ofs); 205 - /* 206 - * We have to always set the err, because the return value isn't 207 - * checked in syncfs, and instead indirectly return an error via 208 - * the sb's writeback errseq, which VFS inspects after this call. 209 - */ 210 - if (ret < 0) { 211 - errseq_set(&sb->s_wb_err, -EIO); 205 + 206 + if (ret < 0) 212 207 return -EIO; 213 - } 214 208 215 209 if (!ret) 216 210 return ret;