aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 6b591c01b09f..808e4ea2bb94 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -372,6 +372,30 @@ void release_open_intent(struct nameidata *nd)
372 fput(nd->intent.open.file); 372 fput(nd->intent.open.file);
373} 373}
374 374
375static inline struct dentry *
376do_revalidate(struct dentry *dentry, struct nameidata *nd)
377{
378 int status = dentry->d_op->d_revalidate(dentry, nd);
379 if (unlikely(status <= 0)) {
380 /*
381 * The dentry failed validation.
382 * If d_revalidate returned 0 attempt to invalidate
383 * the dentry otherwise d_revalidate is asking us
384 * to return a fail status.
385 */
386 if (!status) {
387 if (!d_invalidate(dentry)) {
388 dput(dentry);
389 dentry = NULL;
390 }
391 } else {
392 dput(dentry);
393 dentry = ERR_PTR(status);
394 }
395 }
396 return dentry;
397}
398
375/* 399/*
376 * Internal lookup() using the new generic dcache. 400 * Internal lookup() using the new generic dcache.
377 * SMP-safe 401 * SMP-safe
@@ -386,12 +410,9 @@ static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name,
386 if (!dentry) 410 if (!dentry)
387 dentry = d_lookup(parent, name); 411 dentry = d_lookup(parent, name);
388 412
389 if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { 413 if (dentry && dentry->d_op && dentry->d_op->d_revalidate)
390 if (!dentry->d_op->d_revalidate(dentry, nd) && !d_invalidate(dentry)) { 414 dentry = do_revalidate(dentry, nd);
391 dput(dentry); 415
392 dentry = NULL;
393 }
394 }
395 return dentry; 416 return dentry;
396} 417}
397 418
@@ -484,10 +505,9 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s
484 */ 505 */
485 mutex_unlock(&dir->i_mutex); 506 mutex_unlock(&dir->i_mutex);
486 if (result->d_op && result->d_op->d_revalidate) { 507 if (result->d_op && result->d_op->d_revalidate) {
487 if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) { 508 result = do_revalidate(result, nd);
488 dput(result); 509 if (!result)
489 result = ERR_PTR(-ENOENT); 510 result = ERR_PTR(-ENOENT);
490 }
491 } 511 }
492 return result; 512 return result;
493} 513}
@@ -767,12 +787,12 @@ need_lookup:
767 goto done; 787 goto done;
768 788
769need_revalidate: 789need_revalidate:
770 if (dentry->d_op->d_revalidate(dentry, nd)) 790 dentry = do_revalidate(dentry, nd);
771 goto done; 791 if (!dentry)
772 if (d_invalidate(dentry)) 792 goto need_lookup;
773 goto done; 793 if (IS_ERR(dentry))
774 dput(dentry); 794 goto fail;
775 goto need_lookup; 795 goto done;
776 796
777fail: 797fail:
778 return PTR_ERR(dentry); 798 return PTR_ERR(dentry);