Skip to content

Commit 610afc0

Browse files
author
Miklos Szeredi
committed
ovl: pass ovl_fs down to functions accessing private xattrs
This paves the way for optionally using the "user.overlay." xattr namespace. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
1 parent 26150ab commit 610afc0

9 files changed

Lines changed: 107 additions & 86 deletions

File tree

fs/overlayfs/copy_up.c

Lines changed: 9 additions & 7 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);
@@ -355,7 +356,8 @@ int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
355356
}
356357

357358
/* Store file handle of @upper dir in @index dir entry */
358-
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)
359361
{
360362
const struct ovl_fh *fh;
361363
int err;
@@ -364,7 +366,7 @@ static int ovl_set_upper_fh(struct dentry *upper, struct dentry *index)
364366
if (IS_ERR(fh))
365367
return PTR_ERR(fh);
366368

367-
err = ovl_do_setxattr(index, OVL_XATTR_UPPER, fh->buf, fh->fb.len);
369+
err = ovl_do_setxattr(ofs, index, OVL_XATTR_UPPER, fh->buf, fh->fb.len);
368370

369371
kfree(fh);
370372
return err;
@@ -409,7 +411,7 @@ static int ovl_create_index(struct dentry *dentry, struct dentry *origin,
409411
if (IS_ERR(temp))
410412
goto free_name;
411413

412-
err = ovl_set_upper_fh(upper, temp);
414+
err = ovl_set_upper_fh(OVL_FS(dentry->d_sb), upper, temp);
413415
if (err)
414416
goto out;
415417

@@ -507,7 +509,7 @@ static int ovl_copy_up_inode(struct ovl_copy_up_ctx *c, struct dentry *temp)
507509
return err;
508510
}
509511

510-
err = ovl_copy_xattr(c->lowerpath.dentry, temp);
512+
err = ovl_copy_xattr(c->dentry->d_sb, c->lowerpath.dentry, temp);
511513
if (err)
512514
return err;
513515

@@ -847,7 +849,7 @@ static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c)
847849
}
848850

849851

850-
err = ovl_do_removexattr(upperpath.dentry, OVL_XATTR_METACOPY);
852+
err = ovl_do_removexattr(ofs, upperpath.dentry, OVL_XATTR_METACOPY);
851853
if (err)
852854
goto out_free;
853855

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
}

fs/overlayfs/inode.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ static const char *ovl_get_link(struct dentry *dentry,
327327
return p;
328328
}
329329

330-
bool ovl_is_private_xattr(const char *name)
330+
bool ovl_is_private_xattr(struct super_block *sb, const char *name)
331331
{
332332
return strncmp(name, OVL_XATTR_PREFIX,
333333
sizeof(OVL_XATTR_PREFIX) - 1) == 0;
@@ -391,14 +391,14 @@ int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name,
391391
return res;
392392
}
393393

394-
static bool ovl_can_list(const char *s)
394+
static bool ovl_can_list(struct super_block *sb, const char *s)
395395
{
396396
/* List all non-trusted xatts */
397397
if (strncmp(s, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0)
398398
return true;
399399

400400
/* Never list trusted.overlay, list other trusted for superuser only */
401-
return !ovl_is_private_xattr(s) &&
401+
return !ovl_is_private_xattr(sb, s) &&
402402
ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN);
403403
}
404404

@@ -425,7 +425,7 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
425425
return -EIO;
426426

427427
len -= slen;
428-
if (!ovl_can_list(s)) {
428+
if (!ovl_can_list(dentry->d_sb, s)) {
429429
res -= slen;
430430
memmove(s, s + slen, len);
431431
} else {
@@ -722,7 +722,7 @@ static int ovl_set_nlink_common(struct dentry *dentry,
722722
if (WARN_ON(len >= sizeof(buf)))
723723
return -EIO;
724724

725-
return ovl_do_setxattr(ovl_dentry_upper(dentry),
725+
return ovl_do_setxattr(OVL_FS(inode->i_sb), ovl_dentry_upper(dentry),
726726
OVL_XATTR_NLINK, buf, len);
727727
}
728728

@@ -736,7 +736,7 @@ int ovl_set_nlink_lower(struct dentry *dentry)
736736
return ovl_set_nlink_common(dentry, ovl_dentry_lower(dentry), "L%+i");
737737
}
738738

739-
unsigned int ovl_get_nlink(struct dentry *lowerdentry,
739+
unsigned int ovl_get_nlink(struct ovl_fs *ofs, struct dentry *lowerdentry,
740740
struct dentry *upperdentry,
741741
unsigned int fallback)
742742
{
@@ -748,7 +748,7 @@ unsigned int ovl_get_nlink(struct dentry *lowerdentry,
748748
if (!lowerdentry || !upperdentry || d_inode(lowerdentry)->i_nlink == 1)
749749
return fallback;
750750

751-
err = ovl_do_getxattr(upperdentry, OVL_XATTR_NLINK,
751+
err = ovl_do_getxattr(ofs, upperdentry, OVL_XATTR_NLINK,
752752
&buf, sizeof(buf) - 1);
753753
if (err < 0)
754754
goto fail;
@@ -947,6 +947,7 @@ static struct inode *ovl_iget5(struct super_block *sb, struct inode *newinode,
947947
struct inode *ovl_get_inode(struct super_block *sb,
948948
struct ovl_inode_params *oip)
949949
{
950+
struct ovl_fs *ofs = OVL_FS(sb);
950951
struct dentry *upperdentry = oip->upperdentry;
951952
struct ovl_path *lowerpath = oip->lowerpath;
952953
struct inode *realinode = upperdentry ? d_inode(upperdentry) : NULL;
@@ -994,7 +995,8 @@ struct inode *ovl_get_inode(struct super_block *sb,
994995

995996
/* Recalculate nlink for non-dir due to indexing */
996997
if (!is_dir)
997-
nlink = ovl_get_nlink(lowerdentry, upperdentry, nlink);
998+
nlink = ovl_get_nlink(ofs, lowerdentry, upperdentry,
999+
nlink);
9981000
set_nlink(inode, nlink);
9991001
ino = key->i_ino;
10001002
} else {
@@ -1010,7 +1012,7 @@ struct inode *ovl_get_inode(struct super_block *sb,
10101012
ovl_fill_inode(inode, realinode->i_mode, realinode->i_rdev);
10111013
ovl_inode_init(inode, oip, ino, fsid);
10121014

1013-
if (upperdentry && ovl_is_impuredir(upperdentry))
1015+
if (upperdentry && ovl_is_impuredir(sb, upperdentry))
10141016
ovl_set_flag(OVL_IMPURE, inode);
10151017

10161018
if (oip->index)
@@ -1024,7 +1026,7 @@ struct inode *ovl_get_inode(struct super_block *sb,
10241026
/* Check for non-merge dir that may have whiteouts */
10251027
if (is_dir) {
10261028
if (((upperdentry && lowerdentry) || oip->numlower > 1) ||
1027-
ovl_check_origin_xattr(upperdentry ?: lowerdentry)) {
1029+
ovl_check_origin_xattr(ofs, upperdentry ?: lowerdentry)) {
10281030
ovl_set_flag(OVL_WHITEOUTS, inode);
10291031
}
10301032
}

fs/overlayfs/namei.c

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ static int ovl_check_redirect(struct dentry *dentry, struct ovl_lookup_data *d,
3030
{
3131
int res;
3232
char *buf;
33+
struct ovl_fs *ofs = OVL_FS(d->sb);
3334

34-
buf = ovl_get_redirect_xattr(dentry, prelen + strlen(post));
35+
buf = ovl_get_redirect_xattr(ofs, dentry, prelen + strlen(post));
3536
if (IS_ERR_OR_NULL(buf))
3637
return PTR_ERR(buf);
3738

@@ -104,12 +105,13 @@ int ovl_check_fb_len(struct ovl_fb *fb, int fb_len)
104105
return 0;
105106
}
106107

107-
static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name)
108+
static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *dentry,
109+
const char *name)
108110
{
109111
int res, err;
110112
struct ovl_fh *fh = NULL;
111113

112-
res = ovl_do_getxattr(dentry, name, NULL, 0);
114+
res = ovl_do_getxattr(ofs, dentry, name, NULL, 0);
113115
if (res < 0) {
114116
if (res == -ENODATA || res == -EOPNOTSUPP)
115117
return NULL;
@@ -123,7 +125,7 @@ static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name)
123125
if (!fh)
124126
return ERR_PTR(-ENOMEM);
125127

126-
res = ovl_do_getxattr(dentry, name, fh->buf, res);
128+
res = ovl_do_getxattr(ofs, dentry, name, fh->buf, res);
127129
if (res < 0)
128130
goto fail;
129131

@@ -186,9 +188,9 @@ struct dentry *ovl_decode_real_fh(struct ovl_fh *fh, struct vfsmount *mnt,
186188
return real;
187189
}
188190

189-
static bool ovl_is_opaquedir(struct dentry *dentry)
191+
static bool ovl_is_opaquedir(struct super_block *sb, struct dentry *dentry)
190192
{
191-
return ovl_check_dir_xattr(dentry, OVL_XATTR_OPAQUE);
193+
return ovl_check_dir_xattr(sb, dentry, OVL_XATTR_OPAQUE);
192194
}
193195

194196
static struct dentry *ovl_lookup_positive_unlocked(const char *name,
@@ -251,7 +253,7 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
251253
d->stop = true;
252254
goto put_and_out;
253255
}
254-
err = ovl_check_metacopy_xattr(this);
256+
err = ovl_check_metacopy_xattr(OVL_FS(d->sb), this);
255257
if (err < 0)
256258
goto out_err;
257259

@@ -271,7 +273,7 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
271273
if (d->last)
272274
goto out;
273275

274-
if (ovl_is_opaquedir(this)) {
276+
if (ovl_is_opaquedir(d->sb, this)) {
275277
d->stop = true;
276278
if (last_element)
277279
d->opaque = true;
@@ -391,7 +393,7 @@ int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected,
391393
static int ovl_check_origin(struct ovl_fs *ofs, struct dentry *upperdentry,
392394
struct ovl_path **stackp)
393395
{
394-
struct ovl_fh *fh = ovl_get_fh(upperdentry, OVL_XATTR_ORIGIN);
396+
struct ovl_fh *fh = ovl_get_fh(ofs, upperdentry, OVL_XATTR_ORIGIN);
395397
int err;
396398

397399
if (IS_ERR_OR_NULL(fh))
@@ -413,10 +415,10 @@ static int ovl_check_origin(struct ovl_fs *ofs, struct dentry *upperdentry,
413415
* Verify that @fh matches the file handle stored in xattr @name.
414416
* Return 0 on match, -ESTALE on mismatch, < 0 on error.
415417
*/
416-
static int ovl_verify_fh(struct dentry *dentry, const char *name,
417-
const struct ovl_fh *fh)
418+
static int ovl_verify_fh(struct ovl_fs *ofs, struct dentry *dentry,
419+
const char *name, const struct ovl_fh *fh)
418420
{
419-
struct ovl_fh *ofh = ovl_get_fh(dentry, name);
421+
struct ovl_fh *ofh = ovl_get_fh(ofs, dentry, name);
420422
int err = 0;
421423

422424
if (!ofh)
@@ -440,8 +442,9 @@ static int ovl_verify_fh(struct dentry *dentry, const char *name,
440442
*
441443
* Return 0 on match, -ESTALE on mismatch, -ENODATA on no xattr, < 0 on error.
442444
*/
443-
int ovl_verify_set_fh(struct dentry *dentry, const char *name,
444-
struct dentry *real, bool is_upper, bool set)
445+
int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry,
446+
const char *name, struct dentry *real, bool is_upper,
447+
bool set)
445448
{
446449
struct inode *inode;
447450
struct ovl_fh *fh;
@@ -454,9 +457,9 @@ int ovl_verify_set_fh(struct dentry *dentry, const char *name,
454457
goto fail;
455458
}
456459

457-
err = ovl_verify_fh(dentry, name, fh);
460+
err = ovl_verify_fh(ofs, dentry, name, fh);
458461
if (set && err == -ENODATA)
459-
err = ovl_do_setxattr(dentry, name, fh->buf, fh->fb.len);
462+
err = ovl_do_setxattr(ofs, dentry, name, fh->buf, fh->fb.len);
460463
if (err)
461464
goto fail;
462465

@@ -481,7 +484,7 @@ struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index)
481484
if (!d_is_dir(index))
482485
return dget(index);
483486

484-
fh = ovl_get_fh(index, OVL_XATTR_UPPER);
487+
fh = ovl_get_fh(ofs, index, OVL_XATTR_UPPER);
485488
if (IS_ERR_OR_NULL(fh))
486489
return ERR_CAST(fh);
487490

@@ -574,7 +577,7 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index)
574577
goto fail;
575578
}
576579

577-
err = ovl_verify_fh(upper, OVL_XATTR_ORIGIN, fh);
580+
err = ovl_verify_fh(ofs, upper, OVL_XATTR_ORIGIN, fh);
578581
dput(upper);
579582
if (err)
580583
goto fail;
@@ -585,7 +588,7 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index)
585588
if (err)
586589
goto fail;
587590

588-
if (ovl_get_nlink(origin.dentry, index, 0) == 0)
591+
if (ovl_get_nlink(ofs, origin.dentry, index, 0) == 0)
589592
goto orphan;
590593
}
591594

@@ -741,7 +744,7 @@ struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper,
741744
}
742745

743746
/* Verify that dir index 'upper' xattr points to upper dir */
744-
err = ovl_verify_upper(index, upper, false);
747+
err = ovl_verify_upper(ofs, index, upper, false);
745748
if (err) {
746749
if (err == -ESTALE) {
747750
pr_warn_ratelimited("suspected multiply redirected dir found (upper=%pd2, origin=%pd2, index=%pd2).\n",
@@ -790,12 +793,12 @@ int ovl_path_next(int idx, struct dentry *dentry, struct path *path)
790793
}
791794

792795
/* Fix missing 'origin' xattr */
793-
static int ovl_fix_origin(struct dentry *dentry, struct dentry *lower,
794-
struct dentry *upper)
796+
static int ovl_fix_origin(struct ovl_fs *ofs, struct dentry *dentry,
797+
struct dentry *lower, struct dentry *upper)
795798
{
796799
int err;
797800

798-
if (ovl_check_origin_xattr(upper))
801+
if (ovl_check_origin_xattr(ofs, upper))
799802
return 0;
800803

801804
err = ovl_want_write(dentry);
@@ -920,7 +923,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
920923
* of lower dir and set upper parent "impure".
921924
*/
922925
if (upperdentry && !ctr && !ofs->noxattr && d.is_dir) {
923-
err = ovl_fix_origin(dentry, this, upperdentry);
926+
err = ovl_fix_origin(ofs, dentry, this, upperdentry);
924927
if (err) {
925928
dput(this);
926929
goto out_put;
@@ -939,7 +942,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
939942
if (upperdentry && !ctr &&
940943
((d.is_dir && ovl_verify_lower(dentry->d_sb)) ||
941944
(!d.is_dir && ofs->config.index && origin_path))) {
942-
err = ovl_verify_origin(upperdentry, this, false);
945+
err = ovl_verify_origin(ofs, upperdentry, this, false);
943946
if (err) {
944947
dput(this);
945948
if (d.is_dir)
@@ -1060,13 +1063,13 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
10601063
ovl_dentry_set_upper_alias(dentry);
10611064
else if (index) {
10621065
upperdentry = dget(index);
1063-
upperredirect = ovl_get_redirect_xattr(upperdentry, 0);
1066+
upperredirect = ovl_get_redirect_xattr(ofs, upperdentry, 0);
10641067
if (IS_ERR(upperredirect)) {
10651068
err = PTR_ERR(upperredirect);
10661069
upperredirect = NULL;
10671070
goto out_free_oe;
10681071
}
1069-
err = ovl_check_metacopy_xattr(upperdentry);
1072+
err = ovl_check_metacopy_xattr(ofs, upperdentry);
10701073
if (err < 0)
10711074
goto out_free_oe;
10721075
uppermetacopy = err;

0 commit comments

Comments
 (0)