diff options
Diffstat (limited to 'fs/9p/vfs_inode.c')
-rw-r--r-- | fs/9p/vfs_inode.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index fdc086d07447..334ad12a7bbe 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -510,8 +510,17 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) | |||
510 | return PTR_ERR(v9fid); | 510 | return PTR_ERR(v9fid); |
511 | 511 | ||
512 | retval = p9_client_remove(v9fid); | 512 | retval = p9_client_remove(v9fid); |
513 | if (!retval) | 513 | if (!retval) { |
514 | drop_nlink(file_inode); | 514 | /* |
515 | * directories on unlink should have zero | ||
516 | * link count | ||
517 | */ | ||
518 | if (rmdir) { | ||
519 | clear_nlink(file_inode); | ||
520 | drop_nlink(dir); | ||
521 | } else | ||
522 | drop_nlink(file_inode); | ||
523 | } | ||
515 | return retval; | 524 | return retval; |
516 | } | 525 | } |
517 | 526 | ||
@@ -697,7 +706,8 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
697 | if (IS_ERR(fid)) { | 706 | if (IS_ERR(fid)) { |
698 | err = PTR_ERR(fid); | 707 | err = PTR_ERR(fid); |
699 | fid = NULL; | 708 | fid = NULL; |
700 | } | 709 | } else |
710 | inc_nlink(dir); | ||
701 | 711 | ||
702 | if (fid) | 712 | if (fid) |
703 | p9_client_clunk(fid); | 713 | p9_client_clunk(fid); |
@@ -809,6 +819,7 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
809 | struct inode *new_dir, struct dentry *new_dentry) | 819 | struct inode *new_dir, struct dentry *new_dentry) |
810 | { | 820 | { |
811 | struct inode *old_inode; | 821 | struct inode *old_inode; |
822 | struct inode *new_inode; | ||
812 | struct v9fs_session_info *v9ses; | 823 | struct v9fs_session_info *v9ses; |
813 | struct p9_fid *oldfid; | 824 | struct p9_fid *oldfid; |
814 | struct p9_fid *olddirfid; | 825 | struct p9_fid *olddirfid; |
@@ -819,6 +830,7 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
819 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); | 830 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); |
820 | retval = 0; | 831 | retval = 0; |
821 | old_inode = old_dentry->d_inode; | 832 | old_inode = old_dentry->d_inode; |
833 | new_inode = new_dentry->d_inode; | ||
822 | v9ses = v9fs_inode2v9ses(old_inode); | 834 | v9ses = v9fs_inode2v9ses(old_inode); |
823 | oldfid = v9fs_fid_lookup(old_dentry); | 835 | oldfid = v9fs_fid_lookup(old_dentry); |
824 | if (IS_ERR(oldfid)) | 836 | if (IS_ERR(oldfid)) |
@@ -859,9 +871,21 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
859 | retval = p9_client_wstat(oldfid, &wstat); | 871 | retval = p9_client_wstat(oldfid, &wstat); |
860 | 872 | ||
861 | clunk_newdir: | 873 | clunk_newdir: |
862 | if (!retval) | 874 | if (!retval) { |
875 | if (new_inode) { | ||
876 | if (S_ISDIR(new_inode->i_mode)) | ||
877 | clear_nlink(new_inode); | ||
878 | else | ||
879 | drop_nlink(new_inode); | ||
880 | } | ||
881 | if (S_ISDIR(old_inode->i_mode)) { | ||
882 | if (!new_inode) | ||
883 | inc_nlink(new_dir); | ||
884 | drop_nlink(old_dir); | ||
885 | } | ||
863 | /* successful rename */ | 886 | /* successful rename */ |
864 | d_move(old_dentry, new_dentry); | 887 | d_move(old_dentry, new_dentry); |
888 | } | ||
865 | up_write(&v9ses->rename_sem); | 889 | up_write(&v9ses->rename_sem); |
866 | p9_client_clunk(newdirfid); | 890 | p9_client_clunk(newdirfid); |
867 | 891 | ||