aboutsummaryrefslogtreecommitdiffstats
path: root/fs/autofs4/root.c
diff options
context:
space:
mode:
authorIan Kent <raven@themaw.net>2006-03-27 04:14:46 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-27 11:44:39 -0500
commit1aff3c8b0511b5bb54acf7859e0c6ec9ae7287a9 (patch)
treebe50f4c89a14240b568010da1b0ce3c182352afc /fs/autofs4/root.c
parent1ce12bad85863478619688c0c7363f93a9e5edb8 (diff)
[PATCH] autofs4: fix false negative return from expire
Fix the case where an expire returns busy on a tree mount when it is in fact not busy. This case was overlooked when the patch to prevent the expiring away of "scaffolding" directories for tree mounts was applied. The problem arises when a tree of mounts is a member of a map with other keys. The current logic will not expire the tree if any other mount in the map is busy. The solution is to maintain a "minimum" use count for each autofs dentry and compare this to the actual dentry usage count during expire. Signed-off-by: Ian Kent <raven@themaw.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/autofs4/root.c')
-rw-r--r--fs/autofs4/root.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index c7ff35774344..d196712c4b94 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -490,6 +490,7 @@ static int autofs4_dir_symlink(struct inode *dir,
490{ 490{
491 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); 491 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
492 struct autofs_info *ino = autofs4_dentry_ino(dentry); 492 struct autofs_info *ino = autofs4_dentry_ino(dentry);
493 struct autofs_info *p_ino;
493 struct inode *inode; 494 struct inode *inode;
494 char *cp; 495 char *cp;
495 496
@@ -523,6 +524,10 @@ static int autofs4_dir_symlink(struct inode *dir,
523 524
524 dentry->d_fsdata = ino; 525 dentry->d_fsdata = ino;
525 ino->dentry = dget(dentry); 526 ino->dentry = dget(dentry);
527 atomic_inc(&ino->count);
528 p_ino = autofs4_dentry_ino(dentry->d_parent);
529 if (p_ino && dentry->d_parent != dentry)
530 atomic_inc(&p_ino->count);
526 ino->inode = inode; 531 ino->inode = inode;
527 532
528 dir->i_mtime = CURRENT_TIME; 533 dir->i_mtime = CURRENT_TIME;
@@ -549,11 +554,17 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
549{ 554{
550 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); 555 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
551 struct autofs_info *ino = autofs4_dentry_ino(dentry); 556 struct autofs_info *ino = autofs4_dentry_ino(dentry);
557 struct autofs_info *p_ino;
552 558
553 /* This allows root to remove symlinks */ 559 /* This allows root to remove symlinks */
554 if ( !autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) ) 560 if ( !autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) )
555 return -EACCES; 561 return -EACCES;
556 562
563 if (atomic_dec_and_test(&ino->count)) {
564 p_ino = autofs4_dentry_ino(dentry->d_parent);
565 if (p_ino && dentry->d_parent != dentry)
566 atomic_dec(&p_ino->count);
567 }
557 dput(ino->dentry); 568 dput(ino->dentry);
558 569
559 dentry->d_inode->i_size = 0; 570 dentry->d_inode->i_size = 0;
@@ -570,6 +581,7 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
570{ 581{
571 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); 582 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
572 struct autofs_info *ino = autofs4_dentry_ino(dentry); 583 struct autofs_info *ino = autofs4_dentry_ino(dentry);
584 struct autofs_info *p_ino;
573 585
574 if (!autofs4_oz_mode(sbi)) 586 if (!autofs4_oz_mode(sbi))
575 return -EACCES; 587 return -EACCES;
@@ -584,8 +596,12 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
584 spin_unlock(&dentry->d_lock); 596 spin_unlock(&dentry->d_lock);
585 spin_unlock(&dcache_lock); 597 spin_unlock(&dcache_lock);
586 598
599 if (atomic_dec_and_test(&ino->count)) {
600 p_ino = autofs4_dentry_ino(dentry->d_parent);
601 if (p_ino && dentry->d_parent != dentry)
602 atomic_dec(&p_ino->count);
603 }
587 dput(ino->dentry); 604 dput(ino->dentry);
588
589 dentry->d_inode->i_size = 0; 605 dentry->d_inode->i_size = 0;
590 dentry->d_inode->i_nlink = 0; 606 dentry->d_inode->i_nlink = 0;
591 607
@@ -599,6 +615,7 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
599{ 615{
600 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); 616 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
601 struct autofs_info *ino = autofs4_dentry_ino(dentry); 617 struct autofs_info *ino = autofs4_dentry_ino(dentry);
618 struct autofs_info *p_ino;
602 struct inode *inode; 619 struct inode *inode;
603 620
604 if ( !autofs4_oz_mode(sbi) ) 621 if ( !autofs4_oz_mode(sbi) )
@@ -621,6 +638,10 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
621 638
622 dentry->d_fsdata = ino; 639 dentry->d_fsdata = ino;
623 ino->dentry = dget(dentry); 640 ino->dentry = dget(dentry);
641 atomic_inc(&ino->count);
642 p_ino = autofs4_dentry_ino(dentry->d_parent);
643 if (p_ino && dentry->d_parent != dentry)
644 atomic_inc(&p_ino->count);
624 ino->inode = inode; 645 ino->inode = inode;
625 dir->i_nlink++; 646 dir->i_nlink++;
626 dir->i_mtime = CURRENT_TIME; 647 dir->i_mtime = CURRENT_TIME;