aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/overlayfs/super.c20
1 files changed, 9 insertions, 11 deletions
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index e2a94a26767b..8ccebaf64c5b 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -273,12 +273,11 @@ static bool ovl_is_opaquedir(struct dentry *dentry)
273{ 273{
274 int res; 274 int res;
275 char val; 275 char val;
276 struct inode *inode = dentry->d_inode;
277 276
278 if (!S_ISDIR(inode->i_mode) || !inode->i_op->getxattr) 277 if (!d_is_dir(dentry))
279 return false; 278 return false;
280 279
281 res = inode->i_op->getxattr(dentry, inode, OVL_XATTR_OPAQUE, &val, 1); 280 res = vfs_getxattr(dentry, OVL_XATTR_OPAQUE, &val, 1);
282 if (res == 1 && val == 'y') 281 if (res == 1 && val == 'y')
283 return true; 282 return true;
284 283
@@ -419,16 +418,12 @@ static bool ovl_dentry_weird(struct dentry *dentry)
419 DCACHE_OP_COMPARE); 418 DCACHE_OP_COMPARE);
420} 419}
421 420
422static inline struct dentry *ovl_lookup_real(struct super_block *ovl_sb, 421static inline struct dentry *ovl_lookup_real(struct dentry *dir,
423 struct dentry *dir,
424 const struct qstr *name) 422 const struct qstr *name)
425{ 423{
426 const struct cred *old_cred;
427 struct dentry *dentry; 424 struct dentry *dentry;
428 425
429 old_cred = ovl_override_creds(ovl_sb);
430 dentry = lookup_one_len_unlocked(name->name, dir, name->len); 426 dentry = lookup_one_len_unlocked(name->name, dir, name->len);
431 revert_creds(old_cred);
432 427
433 if (IS_ERR(dentry)) { 428 if (IS_ERR(dentry)) {
434 if (PTR_ERR(dentry) == -ENOENT) 429 if (PTR_ERR(dentry) == -ENOENT)
@@ -469,6 +464,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
469 unsigned int flags) 464 unsigned int flags)
470{ 465{
471 struct ovl_entry *oe; 466 struct ovl_entry *oe;
467 const struct cred *old_cred;
472 struct ovl_entry *poe = dentry->d_parent->d_fsdata; 468 struct ovl_entry *poe = dentry->d_parent->d_fsdata;
473 struct path *stack = NULL; 469 struct path *stack = NULL;
474 struct dentry *upperdir, *upperdentry = NULL; 470 struct dentry *upperdir, *upperdentry = NULL;
@@ -479,9 +475,10 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
479 unsigned int i; 475 unsigned int i;
480 int err; 476 int err;
481 477
478 old_cred = ovl_override_creds(dentry->d_sb);
482 upperdir = ovl_upperdentry_dereference(poe); 479 upperdir = ovl_upperdentry_dereference(poe);
483 if (upperdir) { 480 if (upperdir) {
484 this = ovl_lookup_real(dentry->d_sb, upperdir, &dentry->d_name); 481 this = ovl_lookup_real(upperdir, &dentry->d_name);
485 err = PTR_ERR(this); 482 err = PTR_ERR(this);
486 if (IS_ERR(this)) 483 if (IS_ERR(this))
487 goto out; 484 goto out;
@@ -514,8 +511,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
514 bool opaque = false; 511 bool opaque = false;
515 struct path lowerpath = poe->lowerstack[i]; 512 struct path lowerpath = poe->lowerstack[i];
516 513
517 this = ovl_lookup_real(dentry->d_sb, 514 this = ovl_lookup_real(lowerpath.dentry, &dentry->d_name);
518 lowerpath.dentry, &dentry->d_name);
519 err = PTR_ERR(this); 515 err = PTR_ERR(this);
520 if (IS_ERR(this)) { 516 if (IS_ERR(this)) {
521 /* 517 /*
@@ -588,6 +584,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
588 ovl_copyattr(realdentry->d_inode, inode); 584 ovl_copyattr(realdentry->d_inode, inode);
589 } 585 }
590 586
587 revert_creds(old_cred);
591 oe->opaque = upperopaque; 588 oe->opaque = upperopaque;
592 oe->__upperdentry = upperdentry; 589 oe->__upperdentry = upperdentry;
593 memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr); 590 memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr);
@@ -606,6 +603,7 @@ out_put:
606out_put_upper: 603out_put_upper:
607 dput(upperdentry); 604 dput(upperdentry);
608out: 605out:
606 revert_creds(old_cred);
609 return ERR_PTR(err); 607 return ERR_PTR(err);
610} 608}
611 609