aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/autofs4/root.c38
-rw-r--r--fs/namei.c50
2 files changed, 65 insertions, 23 deletions
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 5100f984783f..27e17f96cada 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -137,7 +137,9 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
137 nd.flags = LOOKUP_DIRECTORY; 137 nd.flags = LOOKUP_DIRECTORY;
138 ret = (dentry->d_op->d_revalidate)(dentry, &nd); 138 ret = (dentry->d_op->d_revalidate)(dentry, &nd);
139 139
140 if (!ret) { 140 if (ret <= 0) {
141 if (ret < 0)
142 status = ret;
141 dcache_dir_close(inode, file); 143 dcache_dir_close(inode, file);
142 goto out; 144 goto out;
143 } 145 }
@@ -400,13 +402,23 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd)
400 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); 402 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
401 int oz_mode = autofs4_oz_mode(sbi); 403 int oz_mode = autofs4_oz_mode(sbi);
402 int flags = nd ? nd->flags : 0; 404 int flags = nd ? nd->flags : 0;
403 int status = 0; 405 int status = 1;
404 406
405 /* Pending dentry */ 407 /* Pending dentry */
406 if (autofs4_ispending(dentry)) { 408 if (autofs4_ispending(dentry)) {
407 if (!oz_mode) 409 /* The daemon never causes a mount to trigger */
408 status = try_to_fill_dentry(dentry, flags); 410 if (oz_mode)
409 return !status; 411 return 1;
412
413 /*
414 * A zero status is success otherwise we have a
415 * negative error code.
416 */
417 status = try_to_fill_dentry(dentry, flags);
418 if (status == 0)
419 return 1;
420
421 return status;
410 } 422 }
411 423
412 /* Negative dentry.. invalidate if "old" */ 424 /* Negative dentry.. invalidate if "old" */
@@ -421,9 +433,19 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd)
421 DPRINTK("dentry=%p %.*s, emptydir", 433 DPRINTK("dentry=%p %.*s, emptydir",
422 dentry, dentry->d_name.len, dentry->d_name.name); 434 dentry, dentry->d_name.len, dentry->d_name.name);
423 spin_unlock(&dcache_lock); 435 spin_unlock(&dcache_lock);
424 if (!oz_mode) 436 /* The daemon never causes a mount to trigger */
425 status = try_to_fill_dentry(dentry, flags); 437 if (oz_mode)
426 return !status; 438 return 1;
439
440 /*
441 * A zero status is success otherwise we have a
442 * negative error code.
443 */
444 status = try_to_fill_dentry(dentry, flags);
445 if (status == 0)
446 return 1;
447
448 return status;
427 } 449 }
428 spin_unlock(&dcache_lock); 450 spin_unlock(&dcache_lock);
429 451
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);