Skip to content

Commit 071a057

Browse files
committed
Merge tag 'ovl-update-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull overlayfs updates from Miklos Szeredi: - Improve performance for certain container setups by introducing a "volatile" mode - ioctl improvements - continue preparation for unprivileged overlay mounts * tag 'ovl-update-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: ovl: use generic vfs_ioc_setflags_prepare() helper ovl: support [S|G]ETFLAGS and FS[S|G]ETXATTR ioctls for directories ovl: rearrange ovl_can_list() ovl: enumerate private xattrs ovl: pass ovl_fs down to functions accessing private xattrs ovl: drop flags argument from ovl_do_setxattr() ovl: adhere to the vfs_ vs. ovl_do_ conventions for xattrs ovl: use ovl_do_getxattr() for private xattr ovl: fold ovl_getxattr() into ovl_get_redirect_xattr() ovl: clean up ovl_getxattr() in copy_up.c duplicate ovl_getxattr() ovl: provide a mount option "volatile" ovl: check for incompatible features in work dir
2 parents fad7011 + be4df0c commit 071a057

12 files changed

Lines changed: 446 additions & 200 deletions

File tree

Documentation/filesystems/overlayfs.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,25 @@ Note: the mount options index=off,nfs_export=on are conflicting for a
564564
read-write mount and will result in an error.
565565

566566

567+
Volatile mount
568+
--------------
569+
570+
This is enabled with the "volatile" mount option. Volatile mounts are not
571+
guaranteed to survive a crash. It is strongly recommended that volatile
572+
mounts are only used if data written to the overlay can be recreated
573+
without significant effort.
574+
575+
The advantage of mounting with the "volatile" option is that all forms of
576+
sync calls to the upper filesystem are omitted.
577+
578+
When overlay is mounted with "volatile" option, the directory
579+
"$workdir/work/incompat/volatile" is created. During next mount, overlay
580+
checks for this directory and refuses to mount if present. This is a strong
581+
indicator that user should throw away upper and work directories and create
582+
fresh one. In very limited cases where the user knows that the system has
583+
not crashed and contents of upperdir are intact, The "volatile" directory
584+
can be removed.
585+
567586
Testsuite
568587
---------
569588

fs/overlayfs/copy_up.c

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ static bool ovl_must_copy_xattr(const char *name)
4343
!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN);
4444
}
4545

46-
int ovl_copy_xattr(struct dentry *old, struct dentry *new)
46+
int ovl_copy_xattr(struct super_block *sb, struct dentry *old,
47+
struct dentry *new)
4748
{
4849
ssize_t list_size, size, value_size = 0;
4950
char *buf, *name, *value = NULL;
@@ -81,7 +82,7 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new)
8182
}
8283
list_size -= slen;
8384

84-
if (ovl_is_private_xattr(name))
85+
if (ovl_is_private_xattr(sb, name))
8586
continue;
8687
retry:
8788
size = vfs_getxattr(old, name, value, value_size);
@@ -128,7 +129,8 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new)
128129
return error;
129130
}
130131

131-
static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
132+
static int ovl_copy_up_data(struct ovl_fs *ofs, struct path *old,
133+
struct path *new, loff_t len)
132134
{
133135
struct file *old_file;
134136
struct file *new_file;
@@ -218,7 +220,7 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
218220
len -= bytes;
219221
}
220222
out:
221-
if (!error)
223+
if (!error && ovl_should_sync(ofs))
222224
error = vfs_fsync(new_file, 0);
223225
fput(new_file);
224226
out_fput:
@@ -354,7 +356,8 @@ int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
354356
}
355357

356358
/* Store file handle of @upper dir in @index dir entry */
357-
static int ovl_set_upper_fh(struct dentry *upper, struct dentry *index)
359+
static int ovl_set_upper_fh(struct ovl_fs *ofs, struct dentry *upper,
360+
struct dentry *index)
358361
{
359362
const struct ovl_fh *fh;
360363
int err;
@@ -363,7 +366,7 @@ static int ovl_set_upper_fh(struct dentry *upper, struct dentry *index)
363366
if (IS_ERR(fh))
364367
return PTR_ERR(fh);
365368

366-
err = ovl_do_setxattr(index, OVL_XATTR_UPPER, fh->buf, fh->fb.len, 0);
369+
err = ovl_do_setxattr(ofs, index, OVL_XATTR_UPPER, fh->buf, fh->fb.len);
367370

368371
kfree(fh);
369372
return err;
@@ -408,7 +411,7 @@ static int ovl_create_index(struct dentry *dentry, struct dentry *origin,
408411
if (IS_ERR(temp))
409412
goto free_name;
410413

411-
err = ovl_set_upper_fh(upper, temp);
414+
err = ovl_set_upper_fh(OVL_FS(dentry->d_sb), upper, temp);
412415
if (err)
413416
goto out;
414417

@@ -484,6 +487,7 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c)
484487

485488
static int ovl_copy_up_inode(struct ovl_copy_up_ctx *c, struct dentry *temp)
486489
{
490+
struct ovl_fs *ofs = OVL_FS(c->dentry->d_sb);
487491
int err;
488492

489493
/*
@@ -499,12 +503,13 @@ static int ovl_copy_up_inode(struct ovl_copy_up_ctx *c, struct dentry *temp)
499503
upperpath.dentry = temp;
500504

501505
ovl_path_lowerdata(c->dentry, &datapath);
502-
err = ovl_copy_up_data(&datapath, &upperpath, c->stat.size);
506+
err = ovl_copy_up_data(ofs, &datapath, &upperpath,
507+
c->stat.size);
503508
if (err)
504509
return err;
505510
}
506511

507-
err = ovl_copy_xattr(c->lowerpath.dentry, temp);
512+
err = ovl_copy_xattr(c->dentry->d_sb, c->lowerpath.dentry, temp);
508513
if (err)
509514
return err;
510515

@@ -781,9 +786,33 @@ static bool ovl_need_meta_copy_up(struct dentry *dentry, umode_t mode,
781786
return true;
782787
}
783788

789+
static ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value)
790+
{
791+
ssize_t res;
792+
char *buf;
793+
794+
res = vfs_getxattr(dentry, name, NULL, 0);
795+
if (res == -ENODATA || res == -EOPNOTSUPP)
796+
res = 0;
797+
798+
if (res > 0) {
799+
buf = kzalloc(res, GFP_KERNEL);
800+
if (!buf)
801+
return -ENOMEM;
802+
803+
res = vfs_getxattr(dentry, name, buf, res);
804+
if (res < 0)
805+
kfree(buf);
806+
else
807+
*value = buf;
808+
}
809+
return res;
810+
}
811+
784812
/* Copy up data of an inode which was copied up metadata only in the past. */
785813
static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c)
786814
{
815+
struct ovl_fs *ofs = OVL_FS(c->dentry->d_sb);
787816
struct path upperpath, datapath;
788817
int err;
789818
char *capability = NULL;
@@ -799,12 +828,12 @@ static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c)
799828

800829
if (c->stat.size) {
801830
err = cap_size = ovl_getxattr(upperpath.dentry, XATTR_NAME_CAPS,
802-
&capability, 0);
803-
if (err < 0 && err != -ENODATA)
831+
&capability);
832+
if (cap_size < 0)
804833
goto out;
805834
}
806835

807-
err = ovl_copy_up_data(&datapath, &upperpath, c->stat.size);
836+
err = ovl_copy_up_data(ofs, &datapath, &upperpath, c->stat.size);
808837
if (err)
809838
goto out_free;
810839

@@ -813,14 +842,14 @@ static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c)
813842
* don't want that to happen for normal copy-up operation.
814843
*/
815844
if (capability) {
816-
err = ovl_do_setxattr(upperpath.dentry, XATTR_NAME_CAPS,
817-
capability, cap_size, 0);
845+
err = vfs_setxattr(upperpath.dentry, XATTR_NAME_CAPS,
846+
capability, cap_size, 0);
818847
if (err)
819848
goto out_free;
820849
}
821850

822851

823-
err = vfs_removexattr(upperpath.dentry, OVL_XATTR_METACOPY);
852+
err = ovl_do_removexattr(ofs, upperpath.dentry, OVL_XATTR_METACOPY);
824853
if (err)
825854
goto out_free;
826855

fs/overlayfs/dir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry,
394394
if (IS_ERR(opaquedir))
395395
goto out_unlock;
396396

397-
err = ovl_copy_xattr(upper, opaquedir);
397+
err = ovl_copy_xattr(dentry->d_sb, upper, opaquedir);
398398
if (err)
399399
goto out_cleanup;
400400

fs/overlayfs/export.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ static struct dentry *ovl_lower_fh_to_d(struct super_block *sb,
752752
goto out_err;
753753
}
754754
if (index) {
755-
err = ovl_verify_origin(index, origin.dentry, false);
755+
err = ovl_verify_origin(ofs, index, origin.dentry, false);
756756
if (err)
757757
goto out_err;
758758
}

0 commit comments

Comments
 (0)