diff options
Diffstat (limited to 'fs/autofs4/root.c')
-rw-r--r-- | fs/autofs4/root.c | 23 |
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; |