summaryrefslogtreecommitdiffstats
path: root/fs/overlayfs/namei.c
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2018-01-11 01:25:32 -0500
committerMiklos Szeredi <mszeredi@redhat.com>2018-01-24 04:19:54 -0500
commit051224438af21047b34160b1e0ad1c5af45fdace (patch)
tree236eb05c06c40ca34f1e89f9aee63fe613c58c28 /fs/overlayfs/namei.c
parent1eff1a1deec727bacead79ec64554c1df190f43c (diff)
ovl: generalize ovl_verify_origin() and helpers
Remove the "origin" language from the functions that handle set, get and verify of "origin" xattr and pass the xattr name as an argument. The same helpers are going to be used for NFS export to get, get and verify the "upper" xattr for directory index entries. ovl_verify_origin() is now a helper used only to verify non upper file handle stored in "origin" xattr of upper inode. The upper root dir file handle is still stored in "origin" xattr on the index dir for backward compatibility. This is going to be changed by the patch that adds directory index entries support. Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/overlayfs/namei.c')
-rw-r--r--fs/overlayfs/namei.c42
1 files changed, 22 insertions, 20 deletions
diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
index 27f25a61f6e4..11e164cb2593 100644
--- a/fs/overlayfs/namei.c
+++ b/fs/overlayfs/namei.c
@@ -114,12 +114,12 @@ static int ovl_check_fh_len(struct ovl_fh *fh, int fh_len)
114 return 0; 114 return 0;
115} 115}
116 116
117static struct ovl_fh *ovl_get_origin_fh(struct dentry *dentry) 117static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name)
118{ 118{
119 int res, err; 119 int res, err;
120 struct ovl_fh *fh = NULL; 120 struct ovl_fh *fh = NULL;
121 121
122 res = vfs_getxattr(dentry, OVL_XATTR_ORIGIN, NULL, 0); 122 res = vfs_getxattr(dentry, name, NULL, 0);
123 if (res < 0) { 123 if (res < 0) {
124 if (res == -ENODATA || res == -EOPNOTSUPP) 124 if (res == -ENODATA || res == -EOPNOTSUPP)
125 return NULL; 125 return NULL;
@@ -133,7 +133,7 @@ static struct ovl_fh *ovl_get_origin_fh(struct dentry *dentry)
133 if (!fh) 133 if (!fh)
134 return ERR_PTR(-ENOMEM); 134 return ERR_PTR(-ENOMEM);
135 135
136 res = vfs_getxattr(dentry, OVL_XATTR_ORIGIN, fh, res); 136 res = vfs_getxattr(dentry, name, fh, res);
137 if (res < 0) 137 if (res < 0)
138 goto fail; 138 goto fail;
139 139
@@ -337,7 +337,7 @@ invalid:
337static int ovl_check_origin(struct ovl_fs *ofs, struct dentry *upperdentry, 337static int ovl_check_origin(struct ovl_fs *ofs, struct dentry *upperdentry,
338 struct ovl_path **stackp, unsigned int *ctrp) 338 struct ovl_path **stackp, unsigned int *ctrp)
339{ 339{
340 struct ovl_fh *fh = ovl_get_origin_fh(upperdentry); 340 struct ovl_fh *fh = ovl_get_fh(upperdentry, OVL_XATTR_ORIGIN);
341 int err; 341 int err;
342 342
343 if (IS_ERR_OR_NULL(fh)) 343 if (IS_ERR_OR_NULL(fh))
@@ -360,12 +360,13 @@ static int ovl_check_origin(struct ovl_fs *ofs, struct dentry *upperdentry,
360} 360}
361 361
362/* 362/*
363 * Verify that @fh matches the origin file handle stored in OVL_XATTR_ORIGIN. 363 * Verify that @fh matches the file handle stored in xattr @name.
364 * Return 0 on match, -ESTALE on mismatch, < 0 on error. 364 * Return 0 on match, -ESTALE on mismatch, < 0 on error.
365 */ 365 */
366static int ovl_verify_origin_fh(struct dentry *dentry, const struct ovl_fh *fh) 366static int ovl_verify_fh(struct dentry *dentry, const char *name,
367 const struct ovl_fh *fh)
367{ 368{
368 struct ovl_fh *ofh = ovl_get_origin_fh(dentry); 369 struct ovl_fh *ofh = ovl_get_fh(dentry, name);
369 int err = 0; 370 int err = 0;
370 371
371 if (!ofh) 372 if (!ofh)
@@ -382,28 +383,28 @@ static int ovl_verify_origin_fh(struct dentry *dentry, const struct ovl_fh *fh)
382} 383}
383 384
384/* 385/*
385 * Verify that an inode matches the origin file handle stored in upper inode. 386 * Verify that @real dentry matches the file handle stored in xattr @name.
386 * 387 *
387 * If @set is true and there is no stored file handle, encode and store origin 388 * If @set is true and there is no stored file handle, encode @real and store
388 * file handle in OVL_XATTR_ORIGIN. 389 * file handle in xattr @name.
389 * 390 *
390 * Return 0 on match, -ESTALE on mismatch, < 0 on error. 391 * Return 0 on match, -ESTALE on mismatch, -ENODATA on no xattr, < 0 on error.
391 */ 392 */
392int ovl_verify_origin(struct dentry *dentry, struct dentry *origin, 393int ovl_verify_set_fh(struct dentry *dentry, const char *name,
393 bool is_upper, bool set) 394 struct dentry *real, bool is_upper, bool set)
394{ 395{
395 struct inode *inode; 396 struct inode *inode;
396 struct ovl_fh *fh; 397 struct ovl_fh *fh;
397 int err; 398 int err;
398 399
399 fh = ovl_encode_fh(origin, is_upper); 400 fh = ovl_encode_fh(real, is_upper);
400 err = PTR_ERR(fh); 401 err = PTR_ERR(fh);
401 if (IS_ERR(fh)) 402 if (IS_ERR(fh))
402 goto fail; 403 goto fail;
403 404
404 err = ovl_verify_origin_fh(dentry, fh); 405 err = ovl_verify_fh(dentry, name, fh);
405 if (set && err == -ENODATA) 406 if (set && err == -ENODATA)
406 err = ovl_do_setxattr(dentry, OVL_XATTR_ORIGIN, fh, fh->len, 0); 407 err = ovl_do_setxattr(dentry, name, fh, fh->len, 0);
407 if (err) 408 if (err)
408 goto fail; 409 goto fail;
409 410
@@ -412,9 +413,10 @@ out:
412 return err; 413 return err;
413 414
414fail: 415fail:
415 inode = d_inode(origin); 416 inode = d_inode(real);
416 pr_warn_ratelimited("overlayfs: failed to verify origin (%pd2, ino=%lu, err=%i)\n", 417 pr_warn_ratelimited("overlayfs: failed to verify %s (%pd2, ino=%lu, err=%i)\n",
417 origin, inode ? inode->i_ino : 0, err); 418 is_upper ? "upper" : "origin", real,
419 inode ? inode->i_ino : 0, err);
418 goto out; 420 goto out;
419} 421}
420 422
@@ -466,7 +468,7 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index)
466 if (err) 468 if (err)
467 goto fail; 469 goto fail;
468 470
469 err = ovl_verify_origin_fh(index, fh); 471 err = ovl_verify_fh(index, OVL_XATTR_ORIGIN, fh);
470 if (err) 472 if (err)
471 goto fail; 473 goto fail;
472 474