diff options
author | Dave Hansen <haveblue@us.ibm.com> | 2006-10-01 02:29:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-01 03:39:30 -0400 |
commit | 9a53c3a783c2fa9b969628e65695c11c3e51e673 (patch) | |
tree | 5a6115e18ee105246d46e3db3d5b07749d232f5b | |
parent | aab520e2f6c80160cabd187a8d0292d1cec8ff68 (diff) |
[PATCH] r/o bind mounts: unlink: monitor i_nlink
When a filesystem decrements i_nlink to zero, it means that a write must be
performed in order to drop the inode from the filesystem.
We're shortly going to have keep filesystems from being remounted r/o between
the time that this i_nlink decrement and that write occurs.
So, add a little helper function to do the decrements. We'll tie into it in a
bit to note when i_nlink hits zero.
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
Acked-by: Christoph Hellwig <hch@lst.de>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/usb/core/inode.c | 7 | ||||
-rw-r--r-- | fs/autofs/root.c | 2 | ||||
-rw-r--r-- | fs/autofs4/root.c | 2 | ||||
-rw-r--r-- | fs/bfs/dir.c | 9 | ||||
-rw-r--r-- | fs/cifs/inode.c | 10 | ||||
-rw-r--r-- | fs/coda/dir.c | 4 | ||||
-rw-r--r-- | fs/ext2/namei.c | 2 | ||||
-rw-r--r-- | fs/ext3/namei.c | 14 | ||||
-rw-r--r-- | fs/hfs/dir.c | 2 | ||||
-rw-r--r-- | fs/hfsplus/dir.c | 2 | ||||
-rw-r--r-- | fs/hpfs/namei.c | 6 | ||||
-rw-r--r-- | fs/jffs/inode-v23.c | 3 | ||||
-rw-r--r-- | fs/jffs2/dir.c | 6 | ||||
-rw-r--r-- | fs/jfs/namei.c | 14 | ||||
-rw-r--r-- | fs/libfs.c | 10 | ||||
-rw-r--r-- | fs/minix/namei.c | 2 | ||||
-rw-r--r-- | fs/msdos/namei.c | 9 | ||||
-rw-r--r-- | fs/nfs/dir.c | 6 | ||||
-rw-r--r-- | fs/ocfs2/namei.c | 4 | ||||
-rw-r--r-- | fs/qnx4/namei.c | 6 | ||||
-rw-r--r-- | fs/reiserfs/namei.c | 6 | ||||
-rw-r--r-- | fs/sysv/namei.c | 2 | ||||
-rw-r--r-- | fs/udf/namei.c | 18 | ||||
-rw-r--r-- | fs/ufs/namei.c | 2 | ||||
-rw-r--r-- | fs/vfat/namei.c | 9 | ||||
-rw-r--r-- | include/linux/fs.h | 7 | ||||
-rw-r--r-- | ipc/mqueue.c | 2 | ||||
-rw-r--r-- | mm/shmem.c | 10 |
28 files changed, 83 insertions, 93 deletions
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index df3d152f049..88002e45a6b 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c | |||
@@ -332,7 +332,7 @@ static int usbfs_unlink (struct inode *dir, struct dentry *dentry) | |||
332 | { | 332 | { |
333 | struct inode *inode = dentry->d_inode; | 333 | struct inode *inode = dentry->d_inode; |
334 | mutex_lock(&inode->i_mutex); | 334 | mutex_lock(&inode->i_mutex); |
335 | dentry->d_inode->i_nlink--; | 335 | drop_nlink(dentry->d_inode); |
336 | dput(dentry); | 336 | dput(dentry); |
337 | mutex_unlock(&inode->i_mutex); | 337 | mutex_unlock(&inode->i_mutex); |
338 | d_delete(dentry); | 338 | d_delete(dentry); |
@@ -347,10 +347,11 @@ static int usbfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
347 | mutex_lock(&inode->i_mutex); | 347 | mutex_lock(&inode->i_mutex); |
348 | dentry_unhash(dentry); | 348 | dentry_unhash(dentry); |
349 | if (usbfs_empty(dentry)) { | 349 | if (usbfs_empty(dentry)) { |
350 | dentry->d_inode->i_nlink -= 2; | 350 | drop_nlink(dentry->d_inode); |
351 | drop_nlink(dentry->d_inode); | ||
351 | dput(dentry); | 352 | dput(dentry); |
352 | inode->i_flags |= S_DEAD; | 353 | inode->i_flags |= S_DEAD; |
353 | dir->i_nlink--; | 354 | drop_nlink(dir); |
354 | error = 0; | 355 | error = 0; |
355 | } | 356 | } |
356 | mutex_unlock(&inode->i_mutex); | 357 | mutex_unlock(&inode->i_mutex); |
diff --git a/fs/autofs/root.c b/fs/autofs/root.c index 9cac08d6a87..54ad7073192 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c | |||
@@ -414,7 +414,7 @@ static int autofs_root_rmdir(struct inode *dir, struct dentry *dentry) | |||
414 | 414 | ||
415 | dentry->d_time = (unsigned long)(struct autofs_dir_ent *)NULL; | 415 | dentry->d_time = (unsigned long)(struct autofs_dir_ent *)NULL; |
416 | autofs_hash_delete(ent); | 416 | autofs_hash_delete(ent); |
417 | dir->i_nlink--; | 417 | drop_nlink(dir); |
418 | d_drop(dentry); | 418 | d_drop(dentry); |
419 | unlock_kernel(); | 419 | unlock_kernel(); |
420 | 420 | ||
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 563ef9d7da9..348bec0982b 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -676,7 +676,7 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry) | |||
676 | dentry->d_inode->i_nlink = 0; | 676 | dentry->d_inode->i_nlink = 0; |
677 | 677 | ||
678 | if (dir->i_nlink) | 678 | if (dir->i_nlink) |
679 | dir->i_nlink--; | 679 | drop_nlink(dir); |
680 | 680 | ||
681 | return 0; | 681 | return 0; |
682 | } | 682 | } |
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index dcf04cb1328..ce05d1643dd 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c | |||
@@ -117,8 +117,7 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode, | |||
117 | 117 | ||
118 | err = bfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len, inode->i_ino); | 118 | err = bfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len, inode->i_ino); |
119 | if (err) { | 119 | if (err) { |
120 | inode->i_nlink--; | 120 | inode_dec_link_count(inode); |
121 | mark_inode_dirty(inode); | ||
122 | iput(inode); | 121 | iput(inode); |
123 | unlock_kernel(); | 122 | unlock_kernel(); |
124 | return err; | 123 | return err; |
@@ -196,9 +195,8 @@ static int bfs_unlink(struct inode * dir, struct dentry * dentry) | |||
196 | mark_buffer_dirty(bh); | 195 | mark_buffer_dirty(bh); |
197 | dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; | 196 | dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; |
198 | mark_inode_dirty(dir); | 197 | mark_inode_dirty(dir); |
199 | inode->i_nlink--; | ||
200 | inode->i_ctime = dir->i_ctime; | 198 | inode->i_ctime = dir->i_ctime; |
201 | mark_inode_dirty(inode); | 199 | inode_dec_link_count(inode); |
202 | error = 0; | 200 | error = 0; |
203 | 201 | ||
204 | out_brelse: | 202 | out_brelse: |
@@ -249,9 +247,8 @@ static int bfs_rename(struct inode * old_dir, struct dentry * old_dentry, | |||
249 | old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC; | 247 | old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC; |
250 | mark_inode_dirty(old_dir); | 248 | mark_inode_dirty(old_dir); |
251 | if (new_inode) { | 249 | if (new_inode) { |
252 | new_inode->i_nlink--; | ||
253 | new_inode->i_ctime = CURRENT_TIME_SEC; | 250 | new_inode->i_ctime = CURRENT_TIME_SEC; |
254 | mark_inode_dirty(new_inode); | 251 | inode_dec_link_count(new_inode); |
255 | } | 252 | } |
256 | mark_buffer_dirty(old_bh); | 253 | mark_buffer_dirty(old_bh); |
257 | error = 0; | 254 | error = 0; |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 05f874c7441..74441a17e18 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -590,7 +590,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
590 | 590 | ||
591 | if (!rc) { | 591 | if (!rc) { |
592 | if (direntry->d_inode) | 592 | if (direntry->d_inode) |
593 | direntry->d_inode->i_nlink--; | 593 | drop_nlink(direntry->d_inode); |
594 | } else if (rc == -ENOENT) { | 594 | } else if (rc == -ENOENT) { |
595 | d_drop(direntry); | 595 | d_drop(direntry); |
596 | } else if (rc == -ETXTBSY) { | 596 | } else if (rc == -ETXTBSY) { |
@@ -609,7 +609,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
609 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 609 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
610 | CIFSSMBClose(xid, pTcon, netfid); | 610 | CIFSSMBClose(xid, pTcon, netfid); |
611 | if (direntry->d_inode) | 611 | if (direntry->d_inode) |
612 | direntry->d_inode->i_nlink--; | 612 | drop_nlink(direntry->d_inode); |
613 | } | 613 | } |
614 | } else if (rc == -EACCES) { | 614 | } else if (rc == -EACCES) { |
615 | /* try only if r/o attribute set in local lookup data? */ | 615 | /* try only if r/o attribute set in local lookup data? */ |
@@ -663,7 +663,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
663 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 663 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
664 | if (!rc) { | 664 | if (!rc) { |
665 | if (direntry->d_inode) | 665 | if (direntry->d_inode) |
666 | direntry->d_inode->i_nlink--; | 666 | drop_nlink(direntry->d_inode); |
667 | } else if (rc == -ETXTBSY) { | 667 | } else if (rc == -ETXTBSY) { |
668 | int oplock = FALSE; | 668 | int oplock = FALSE; |
669 | __u16 netfid; | 669 | __u16 netfid; |
@@ -684,7 +684,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
684 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 684 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
685 | CIFSSMBClose(xid, pTcon, netfid); | 685 | CIFSSMBClose(xid, pTcon, netfid); |
686 | if (direntry->d_inode) | 686 | if (direntry->d_inode) |
687 | direntry->d_inode->i_nlink--; | 687 | drop_nlink(direntry->d_inode); |
688 | } | 688 | } |
689 | /* BB if rc = -ETXTBUSY goto the rename logic BB */ | 689 | /* BB if rc = -ETXTBUSY goto the rename logic BB */ |
690 | } | 690 | } |
@@ -816,7 +816,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) | |||
816 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 816 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
817 | 817 | ||
818 | if (!rc) { | 818 | if (!rc) { |
819 | inode->i_nlink--; | 819 | drop_nlink(inode); |
820 | i_size_write(direntry->d_inode,0); | 820 | i_size_write(direntry->d_inode,0); |
821 | direntry->d_inode->i_nlink = 0; | 821 | direntry->d_inode->i_nlink = 0; |
822 | } | 822 | } |
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 8651ea6a23b..0a2fd8bb757 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
@@ -367,7 +367,7 @@ int coda_unlink(struct inode *dir, struct dentry *de) | |||
367 | } | 367 | } |
368 | 368 | ||
369 | coda_dir_changed(dir, 0); | 369 | coda_dir_changed(dir, 0); |
370 | de->d_inode->i_nlink--; | 370 | drop_nlink(de->d_inode); |
371 | unlock_kernel(); | 371 | unlock_kernel(); |
372 | 372 | ||
373 | return 0; | 373 | return 0; |
@@ -394,7 +394,7 @@ int coda_rmdir(struct inode *dir, struct dentry *de) | |||
394 | } | 394 | } |
395 | 395 | ||
396 | coda_dir_changed(dir, -1); | 396 | coda_dir_changed(dir, -1); |
397 | de->d_inode->i_nlink--; | 397 | drop_nlink(de->d_inode); |
398 | d_delete(de); | 398 | d_delete(de); |
399 | unlock_kernel(); | 399 | unlock_kernel(); |
400 | 400 | ||
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 4ca82498532..e1af5b4cf80 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c | |||
@@ -326,7 +326,7 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, | |||
326 | ext2_set_link(new_dir, new_de, new_page, old_inode); | 326 | ext2_set_link(new_dir, new_de, new_page, old_inode); |
327 | new_inode->i_ctime = CURRENT_TIME_SEC; | 327 | new_inode->i_ctime = CURRENT_TIME_SEC; |
328 | if (dir_de) | 328 | if (dir_de) |
329 | new_inode->i_nlink--; | 329 | drop_nlink(new_inode); |
330 | inode_dec_link_count(new_inode); | 330 | inode_dec_link_count(new_inode); |
331 | } else { | 331 | } else { |
332 | if (dir_de) { | 332 | if (dir_de) { |
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 235e77b52ea..14c55adfae8 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -1621,7 +1621,7 @@ static inline void ext3_inc_count(handle_t *handle, struct inode *inode) | |||
1621 | 1621 | ||
1622 | static inline void ext3_dec_count(handle_t *handle, struct inode *inode) | 1622 | static inline void ext3_dec_count(handle_t *handle, struct inode *inode) |
1623 | { | 1623 | { |
1624 | inode->i_nlink--; | 1624 | drop_nlink(inode); |
1625 | } | 1625 | } |
1626 | 1626 | ||
1627 | static int ext3_add_nondir(handle_t *handle, | 1627 | static int ext3_add_nondir(handle_t *handle, |
@@ -1743,7 +1743,7 @@ retry: | |||
1743 | inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; | 1743 | inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; |
1744 | dir_block = ext3_bread (handle, inode, 0, 1, &err); | 1744 | dir_block = ext3_bread (handle, inode, 0, 1, &err); |
1745 | if (!dir_block) { | 1745 | if (!dir_block) { |
1746 | inode->i_nlink--; /* is this nlink == 0? */ | 1746 | drop_nlink(inode); /* is this nlink == 0? */ |
1747 | ext3_mark_inode_dirty(handle, inode); | 1747 | ext3_mark_inode_dirty(handle, inode); |
1748 | iput (inode); | 1748 | iput (inode); |
1749 | goto out_stop; | 1749 | goto out_stop; |
@@ -2053,7 +2053,7 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry) | |||
2053 | ext3_orphan_add(handle, inode); | 2053 | ext3_orphan_add(handle, inode); |
2054 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; | 2054 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; |
2055 | ext3_mark_inode_dirty(handle, inode); | 2055 | ext3_mark_inode_dirty(handle, inode); |
2056 | dir->i_nlink--; | 2056 | drop_nlink(dir); |
2057 | ext3_update_dx_flag(dir); | 2057 | ext3_update_dx_flag(dir); |
2058 | ext3_mark_inode_dirty(handle, dir); | 2058 | ext3_mark_inode_dirty(handle, dir); |
2059 | 2059 | ||
@@ -2104,7 +2104,7 @@ static int ext3_unlink(struct inode * dir, struct dentry *dentry) | |||
2104 | dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; | 2104 | dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; |
2105 | ext3_update_dx_flag(dir); | 2105 | ext3_update_dx_flag(dir); |
2106 | ext3_mark_inode_dirty(handle, dir); | 2106 | ext3_mark_inode_dirty(handle, dir); |
2107 | inode->i_nlink--; | 2107 | drop_nlink(inode); |
2108 | if (!inode->i_nlink) | 2108 | if (!inode->i_nlink) |
2109 | ext3_orphan_add(handle, inode); | 2109 | ext3_orphan_add(handle, inode); |
2110 | inode->i_ctime = dir->i_ctime; | 2110 | inode->i_ctime = dir->i_ctime; |
@@ -2326,7 +2326,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, | |||
2326 | } | 2326 | } |
2327 | 2327 | ||
2328 | if (new_inode) { | 2328 | if (new_inode) { |
2329 | new_inode->i_nlink--; | 2329 | drop_nlink(new_inode); |
2330 | new_inode->i_ctime = CURRENT_TIME_SEC; | 2330 | new_inode->i_ctime = CURRENT_TIME_SEC; |
2331 | } | 2331 | } |
2332 | old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC; | 2332 | old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC; |
@@ -2337,9 +2337,9 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, | |||
2337 | PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino); | 2337 | PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino); |
2338 | BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata"); | 2338 | BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata"); |
2339 | ext3_journal_dirty_metadata(handle, dir_bh); | 2339 | ext3_journal_dirty_metadata(handle, dir_bh); |
2340 | old_dir->i_nlink--; | 2340 | drop_nlink(old_dir); |
2341 | if (new_inode) { | 2341 | if (new_inode) { |
2342 | new_inode->i_nlink--; | 2342 | drop_nlink(new_inode); |
2343 | } else { | 2343 | } else { |
2344 | new_dir->i_nlink++; | 2344 | new_dir->i_nlink++; |
2345 | ext3_update_dx_flag(new_dir); | 2345 | ext3_update_dx_flag(new_dir); |
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index 7cd8cc03aea..cfef6ad529a 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c | |||
@@ -246,7 +246,7 @@ static int hfs_unlink(struct inode *dir, struct dentry *dentry) | |||
246 | if (res) | 246 | if (res) |
247 | return res; | 247 | return res; |
248 | 248 | ||
249 | inode->i_nlink--; | 249 | drop_nlink(inode); |
250 | hfs_delete_inode(inode); | 250 | hfs_delete_inode(inode); |
251 | inode->i_ctime = CURRENT_TIME_SEC; | 251 | inode->i_ctime = CURRENT_TIME_SEC; |
252 | mark_inode_dirty(inode); | 252 | mark_inode_dirty(inode); |
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 1f9ece0de32..9ceb0dfaa1c 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
@@ -338,7 +338,7 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) | |||
338 | return res; | 338 | return res; |
339 | 339 | ||
340 | if (inode->i_nlink > 0) | 340 | if (inode->i_nlink > 0) |
341 | inode->i_nlink--; | 341 | drop_nlink(inode); |
342 | hfsplus_delete_inode(inode); | 342 | hfsplus_delete_inode(inode); |
343 | if (inode->i_ino != cnid && !inode->i_nlink) { | 343 | if (inode->i_ino != cnid && !inode->i_nlink) { |
344 | if (!atomic_read(&HFSPLUS_I(inode).opencnt)) { | 344 | if (!atomic_read(&HFSPLUS_I(inode).opencnt)) { |
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index 59e7dc182a0..4078b0becc5 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c | |||
@@ -434,7 +434,7 @@ again: | |||
434 | unlock_kernel(); | 434 | unlock_kernel(); |
435 | return -ENOSPC; | 435 | return -ENOSPC; |
436 | default: | 436 | default: |
437 | inode->i_nlink--; | 437 | drop_nlink(inode); |
438 | err = 0; | 438 | err = 0; |
439 | } | 439 | } |
440 | goto out; | 440 | goto out; |
@@ -494,7 +494,7 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
494 | err = -ENOSPC; | 494 | err = -ENOSPC; |
495 | break; | 495 | break; |
496 | default: | 496 | default: |
497 | dir->i_nlink--; | 497 | drop_nlink(dir); |
498 | inode->i_nlink = 0; | 498 | inode->i_nlink = 0; |
499 | err = 0; | 499 | err = 0; |
500 | } | 500 | } |
@@ -636,7 +636,7 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
636 | hpfs_i(i)->i_parent_dir = new_dir->i_ino; | 636 | hpfs_i(i)->i_parent_dir = new_dir->i_ino; |
637 | if (S_ISDIR(i->i_mode)) { | 637 | if (S_ISDIR(i->i_mode)) { |
638 | new_dir->i_nlink++; | 638 | new_dir->i_nlink++; |
639 | old_dir->i_nlink--; | 639 | drop_nlink(old_dir); |
640 | } | 640 | } |
641 | if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) { | 641 | if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) { |
642 | fnode->up = new_dir->i_ino; | 642 | fnode->up = new_dir->i_ino; |
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c index 068ef0de8de..3f7899ea4cb 100644 --- a/fs/jffs/inode-v23.c +++ b/fs/jffs/inode-v23.c | |||
@@ -1052,9 +1052,8 @@ jffs_remove(struct inode *dir, struct dentry *dentry, int type) | |||
1052 | 1052 | ||
1053 | dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; | 1053 | dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; |
1054 | mark_inode_dirty(dir); | 1054 | mark_inode_dirty(dir); |
1055 | inode->i_nlink--; | ||
1056 | inode->i_ctime = dir->i_ctime; | 1055 | inode->i_ctime = dir->i_ctime; |
1057 | mark_inode_dirty(inode); | 1056 | inode_dec_link_count(inode); |
1058 | 1057 | ||
1059 | d_delete(dentry); /* This also frees the inode */ | 1058 | d_delete(dentry); /* This also frees the inode */ |
1060 | 1059 | ||
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index edd8371fc6a..a5e9f2205b3 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c | |||
@@ -615,7 +615,7 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) | |||
615 | } | 615 | } |
616 | ret = jffs2_unlink(dir_i, dentry); | 616 | ret = jffs2_unlink(dir_i, dentry); |
617 | if (!ret) | 617 | if (!ret) |
618 | dir_i->i_nlink--; | 618 | drop_nlink(dir_i); |
619 | return ret; | 619 | return ret; |
620 | } | 620 | } |
621 | 621 | ||
@@ -823,7 +823,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | |||
823 | 823 | ||
824 | if (victim_f) { | 824 | if (victim_f) { |
825 | /* There was a victim. Kill it off nicely */ | 825 | /* There was a victim. Kill it off nicely */ |
826 | new_dentry->d_inode->i_nlink--; | 826 | drop_nlink(new_dentry->d_inode); |
827 | /* Don't oops if the victim was a dirent pointing to an | 827 | /* Don't oops if the victim was a dirent pointing to an |
828 | inode which didn't exist. */ | 828 | inode which didn't exist. */ |
829 | if (victim_f->inocache) { | 829 | if (victim_f->inocache) { |
@@ -862,7 +862,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | |||
862 | } | 862 | } |
863 | 863 | ||
864 | if (S_ISDIR(old_dentry->d_inode->i_mode)) | 864 | if (S_ISDIR(old_dentry->d_inode->i_mode)) |
865 | old_dir_i->i_nlink--; | 865 | drop_nlink(old_dir_i); |
866 | 866 | ||
867 | new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now); | 867 | new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now); |
868 | 868 | ||
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 295268ad231..088b85976ac 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -393,9 +393,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) | |||
393 | /* update parent directory's link count corresponding | 393 | /* update parent directory's link count corresponding |
394 | * to ".." entry of the target directory deleted | 394 | * to ".." entry of the target directory deleted |
395 | */ | 395 | */ |
396 | dip->i_nlink--; | ||
397 | dip->i_ctime = dip->i_mtime = CURRENT_TIME; | 396 | dip->i_ctime = dip->i_mtime = CURRENT_TIME; |
398 | mark_inode_dirty(dip); | 397 | inode_dec_link_count(dip); |
399 | 398 | ||
400 | /* | 399 | /* |
401 | * OS/2 could have created EA and/or ACL | 400 | * OS/2 could have created EA and/or ACL |
@@ -515,8 +514,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) | |||
515 | mark_inode_dirty(dip); | 514 | mark_inode_dirty(dip); |
516 | 515 | ||
517 | /* update target's inode */ | 516 | /* update target's inode */ |
518 | ip->i_nlink--; | 517 | inode_dec_link_count(ip); |
519 | mark_inode_dirty(ip); | ||
520 | 518 | ||
521 | /* | 519 | /* |
522 | * commit zero link count object | 520 | * commit zero link count object |
@@ -835,7 +833,7 @@ static int jfs_link(struct dentry *old_dentry, | |||
835 | rc = txCommit(tid, 2, &iplist[0], 0); | 833 | rc = txCommit(tid, 2, &iplist[0], 0); |
836 | 834 | ||
837 | if (rc) { | 835 | if (rc) { |
838 | ip->i_nlink--; | 836 | ip->i_nlink--; /* never instantiated */ |
839 | iput(ip); | 837 | iput(ip); |
840 | } else | 838 | } else |
841 | d_instantiate(dentry, ip); | 839 | d_instantiate(dentry, ip); |
@@ -1155,9 +1153,9 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1155 | old_ip->i_ino, JFS_RENAME); | 1153 | old_ip->i_ino, JFS_RENAME); |
1156 | if (rc) | 1154 | if (rc) |
1157 | goto out4; | 1155 | goto out4; |
1158 | new_ip->i_nlink--; | 1156 | drop_nlink(new_ip); |
1159 | if (S_ISDIR(new_ip->i_mode)) { | 1157 | if (S_ISDIR(new_ip->i_mode)) { |
1160 | new_ip->i_nlink--; | 1158 | drop_nlink(new_ip); |
1161 | if (new_ip->i_nlink) { | 1159 | if (new_ip->i_nlink) { |
1162 | mutex_unlock(&JFS_IP(new_ip)->commit_mutex); | 1160 | mutex_unlock(&JFS_IP(new_ip)->commit_mutex); |
1163 | if (old_dir != new_dir) | 1161 | if (old_dir != new_dir) |
@@ -1223,7 +1221,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1223 | goto out4; | 1221 | goto out4; |
1224 | } | 1222 | } |
1225 | if (S_ISDIR(old_ip->i_mode)) { | 1223 | if (S_ISDIR(old_ip->i_mode)) { |
1226 | old_dir->i_nlink--; | 1224 | drop_nlink(old_dir); |
1227 | if (old_dir != new_dir) { | 1225 | if (old_dir != new_dir) { |
1228 | /* | 1226 | /* |
1229 | * Change inode number of parent for moved directory | 1227 | * Change inode number of parent for moved directory |
diff --git a/fs/libfs.c b/fs/libfs.c index 3793aaa1457..9204feba75a 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -275,7 +275,7 @@ int simple_unlink(struct inode *dir, struct dentry *dentry) | |||
275 | struct inode *inode = dentry->d_inode; | 275 | struct inode *inode = dentry->d_inode; |
276 | 276 | ||
277 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; | 277 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; |
278 | inode->i_nlink--; | 278 | drop_nlink(inode); |
279 | dput(dentry); | 279 | dput(dentry); |
280 | return 0; | 280 | return 0; |
281 | } | 281 | } |
@@ -285,9 +285,9 @@ int simple_rmdir(struct inode *dir, struct dentry *dentry) | |||
285 | if (!simple_empty(dentry)) | 285 | if (!simple_empty(dentry)) |
286 | return -ENOTEMPTY; | 286 | return -ENOTEMPTY; |
287 | 287 | ||
288 | dentry->d_inode->i_nlink--; | 288 | drop_nlink(dentry->d_inode); |
289 | simple_unlink(dir, dentry); | 289 | simple_unlink(dir, dentry); |
290 | dir->i_nlink--; | 290 | drop_nlink(dir); |
291 | return 0; | 291 | return 0; |
292 | } | 292 | } |
293 | 293 | ||
@@ -303,9 +303,9 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
303 | if (new_dentry->d_inode) { | 303 | if (new_dentry->d_inode) { |
304 | simple_unlink(new_dir, new_dentry); | 304 | simple_unlink(new_dir, new_dentry); |
305 | if (they_are_dirs) | 305 | if (they_are_dirs) |
306 | old_dir->i_nlink--; | 306 | drop_nlink(old_dir); |
307 | } else if (they_are_dirs) { | 307 | } else if (they_are_dirs) { |
308 | old_dir->i_nlink--; | 308 | drop_nlink(old_dir); |
309 | new_dir->i_nlink++; | 309 | new_dir->i_nlink++; |
310 | } | 310 | } |
311 | 311 | ||
diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 5b6a4540a05..299bb66e3bd 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c | |||
@@ -249,7 +249,7 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, | |||
249 | minix_set_link(new_de, new_page, old_inode); | 249 | minix_set_link(new_de, new_page, old_inode); |
250 | new_inode->i_ctime = CURRENT_TIME_SEC; | 250 | new_inode->i_ctime = CURRENT_TIME_SEC; |
251 | if (dir_de) | 251 | if (dir_de) |
252 | new_inode->i_nlink--; | 252 | drop_nlink(new_inode); |
253 | inode_dec_link_count(new_inode); | 253 | inode_dec_link_count(new_inode); |
254 | } else { | 254 | } else { |
255 | if (dir_de) { | 255 | if (dir_de) { |
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c index d220165d491..635613f2f65 100644 --- a/fs/msdos/namei.c +++ b/fs/msdos/namei.c | |||
@@ -343,7 +343,7 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry) | |||
343 | err = fat_remove_entries(dir, &sinfo); /* and releases bh */ | 343 | err = fat_remove_entries(dir, &sinfo); /* and releases bh */ |
344 | if (err) | 344 | if (err) |
345 | goto out; | 345 | goto out; |
346 | dir->i_nlink--; | 346 | drop_nlink(dir); |
347 | 347 | ||
348 | inode->i_nlink = 0; | 348 | inode->i_nlink = 0; |
349 | inode->i_ctime = CURRENT_TIME_SEC; | 349 | inode->i_ctime = CURRENT_TIME_SEC; |
@@ -549,7 +549,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, | |||
549 | if (err) | 549 | if (err) |
550 | goto error_dotdot; | 550 | goto error_dotdot; |
551 | } | 551 | } |
552 | old_dir->i_nlink--; | 552 | drop_nlink(old_dir); |
553 | if (!new_inode) | 553 | if (!new_inode) |
554 | new_dir->i_nlink++; | 554 | new_dir->i_nlink++; |
555 | } | 555 | } |
@@ -566,10 +566,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, | |||
566 | mark_inode_dirty(old_dir); | 566 | mark_inode_dirty(old_dir); |
567 | 567 | ||
568 | if (new_inode) { | 568 | if (new_inode) { |
569 | drop_nlink(new_inode); | ||
569 | if (is_dir) | 570 | if (is_dir) |
570 | new_inode->i_nlink -= 2; | 571 | drop_nlink(new_inode); |
571 | else | ||
572 | new_inode->i_nlink--; | ||
573 | new_inode->i_ctime = ts; | 572 | new_inode->i_ctime = ts; |
574 | } | 573 | } |
575 | out: | 574 | out: |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 7432f1a43f3..26eecb86f9b 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -843,7 +843,7 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) | |||
843 | nfs_inode_return_delegation(inode); | 843 | nfs_inode_return_delegation(inode); |
844 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { | 844 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { |
845 | lock_kernel(); | 845 | lock_kernel(); |
846 | inode->i_nlink--; | 846 | drop_nlink(inode); |
847 | nfs_complete_unlink(dentry); | 847 | nfs_complete_unlink(dentry); |
848 | unlock_kernel(); | 848 | unlock_kernel(); |
849 | } | 849 | } |
@@ -1401,7 +1401,7 @@ static int nfs_safe_remove(struct dentry *dentry) | |||
1401 | error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); | 1401 | error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); |
1402 | /* The VFS may want to delete this inode */ | 1402 | /* The VFS may want to delete this inode */ |
1403 | if (error == 0) | 1403 | if (error == 0) |
1404 | inode->i_nlink--; | 1404 | drop_nlink(inode); |
1405 | nfs_mark_for_revalidate(inode); | 1405 | nfs_mark_for_revalidate(inode); |
1406 | nfs_end_data_update(inode); | 1406 | nfs_end_data_update(inode); |
1407 | } else | 1407 | } else |
@@ -1639,7 +1639,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1639 | goto out; | 1639 | goto out; |
1640 | } | 1640 | } |
1641 | } else | 1641 | } else |
1642 | new_inode->i_nlink--; | 1642 | drop_nlink(new_inode); |
1643 | 1643 | ||
1644 | go_ahead: | 1644 | go_ahead: |
1645 | /* | 1645 | /* |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 849c3b4bb94..40f83f53053 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -739,7 +739,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
739 | err = ocfs2_journal_dirty(handle, fe_bh); | 739 | err = ocfs2_journal_dirty(handle, fe_bh); |
740 | if (err < 0) { | 740 | if (err < 0) { |
741 | le16_add_cpu(&fe->i_links_count, -1); | 741 | le16_add_cpu(&fe->i_links_count, -1); |
742 | inode->i_nlink--; | 742 | drop_nlink(inode); |
743 | mlog_errno(err); | 743 | mlog_errno(err); |
744 | goto bail; | 744 | goto bail; |
745 | } | 745 | } |
@@ -749,7 +749,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
749 | parent_fe_bh, de_bh); | 749 | parent_fe_bh, de_bh); |
750 | if (err) { | 750 | if (err) { |
751 | le16_add_cpu(&fe->i_links_count, -1); | 751 | le16_add_cpu(&fe->i_links_count, -1); |
752 | inode->i_nlink--; | 752 | drop_nlink(inode); |
753 | mlog_errno(err); | 753 | mlog_errno(err); |
754 | goto bail; | 754 | goto bail; |
755 | } | 755 | } |
diff --git a/fs/qnx4/namei.c b/fs/qnx4/namei.c index c3d83f67154..ad5afa4ea8f 100644 --- a/fs/qnx4/namei.c +++ b/fs/qnx4/namei.c | |||
@@ -189,8 +189,7 @@ int qnx4_rmdir(struct inode *dir, struct dentry *dentry) | |||
189 | inode->i_nlink = 0; | 189 | inode->i_nlink = 0; |
190 | mark_inode_dirty(inode); | 190 | mark_inode_dirty(inode); |
191 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; | 191 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; |
192 | dir->i_nlink--; | 192 | inode_dec_link_count(dir); |
193 | mark_inode_dirty(dir); | ||
194 | retval = 0; | 193 | retval = 0; |
195 | 194 | ||
196 | end_rmdir: | 195 | end_rmdir: |
@@ -234,9 +233,8 @@ int qnx4_unlink(struct inode *dir, struct dentry *dentry) | |||
234 | mark_buffer_dirty(bh); | 233 | mark_buffer_dirty(bh); |
235 | dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; | 234 | dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; |
236 | mark_inode_dirty(dir); | 235 | mark_inode_dirty(dir); |
237 | inode->i_nlink--; | ||
238 | inode->i_ctime = dir->i_ctime; | 236 | inode->i_ctime = dir->i_ctime; |
239 | mark_inode_dirty(inode); | 237 | inode_dec_link_count(inode); |
240 | retval = 0; | 238 | retval = 0; |
241 | 239 | ||
242 | end_unlink: | 240 | end_unlink: |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index c61710e49c6..c76d427e027 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/quotaops.h> | 20 | #include <linux/quotaops.h> |
21 | 21 | ||
22 | #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { i->i_nlink++; if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; } | 22 | #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { i->i_nlink++; if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; } |
23 | #define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) i->i_nlink--; | 23 | #define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) drop_nlink(i); |
24 | 24 | ||
25 | // directory item contains array of entry headers. This performs | 25 | // directory item contains array of entry headers. This performs |
26 | // binary search through that array | 26 | // binary search through that array |
@@ -994,7 +994,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) | |||
994 | inode->i_nlink = 1; | 994 | inode->i_nlink = 1; |
995 | } | 995 | } |
996 | 996 | ||
997 | inode->i_nlink--; | 997 | drop_nlink(inode); |
998 | 998 | ||
999 | /* | 999 | /* |
1000 | * we schedule before doing the add_save_link call, save the link | 1000 | * we schedule before doing the add_save_link call, save the link |
@@ -1475,7 +1475,7 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1475 | if (S_ISDIR(new_dentry_inode->i_mode)) { | 1475 | if (S_ISDIR(new_dentry_inode->i_mode)) { |
1476 | new_dentry_inode->i_nlink = 0; | 1476 | new_dentry_inode->i_nlink = 0; |
1477 | } else { | 1477 | } else { |
1478 | new_dentry_inode->i_nlink--; | 1478 | drop_nlink(new_dentry_inode); |
1479 | } | 1479 | } |
1480 | new_dentry_inode->i_ctime = ctime; | 1480 | new_dentry_inode->i_ctime = ctime; |
1481 | savelink = new_dentry_inode->i_nlink; | 1481 | savelink = new_dentry_inode->i_nlink; |
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index b8a73f716fb..f7c08db8e34 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c | |||
@@ -250,7 +250,7 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry, | |||
250 | sysv_set_link(new_de, new_page, old_inode); | 250 | sysv_set_link(new_de, new_page, old_inode); |
251 | new_inode->i_ctime = CURRENT_TIME_SEC; | 251 | new_inode->i_ctime = CURRENT_TIME_SEC; |
252 | if (dir_de) | 252 | if (dir_de) |
253 | new_inode->i_nlink--; | 253 | drop_nlink(new_inode); |
254 | inode_dec_link_count(new_inode); | 254 | inode_dec_link_count(new_inode); |
255 | } else { | 255 | } else { |
256 | if (dir_de) { | 256 | if (dir_de) { |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index ab9a7629d23..d14d25534aa 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -878,8 +878,7 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry) | |||
878 | inode->i_nlink); | 878 | inode->i_nlink); |
879 | inode->i_nlink = 0; | 879 | inode->i_nlink = 0; |
880 | inode->i_size = 0; | 880 | inode->i_size = 0; |
881 | mark_inode_dirty(inode); | 881 | inode_dec_link_count(inode); |
882 | dir->i_nlink --; | ||
883 | inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); | 882 | inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); |
884 | mark_inode_dirty(dir); | 883 | mark_inode_dirty(dir); |
885 | 884 | ||
@@ -923,8 +922,7 @@ static int udf_unlink(struct inode * dir, struct dentry * dentry) | |||
923 | goto end_unlink; | 922 | goto end_unlink; |
924 | dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); | 923 | dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); |
925 | mark_inode_dirty(dir); | 924 | mark_inode_dirty(dir); |
926 | inode->i_nlink--; | 925 | inode_dec_link_count(inode); |
927 | mark_inode_dirty(inode); | ||
928 | inode->i_ctime = dir->i_ctime; | 926 | inode->i_ctime = dir->i_ctime; |
929 | retval = 0; | 927 | retval = 0; |
930 | 928 | ||
@@ -1101,8 +1099,7 @@ out: | |||
1101 | return err; | 1099 | return err; |
1102 | 1100 | ||
1103 | out_no_entry: | 1101 | out_no_entry: |
1104 | inode->i_nlink--; | 1102 | inode_dec_link_count(inode); |
1105 | mark_inode_dirty(inode); | ||
1106 | iput(inode); | 1103 | iput(inode); |
1107 | goto out; | 1104 | goto out; |
1108 | } | 1105 | } |
@@ -1261,9 +1258,8 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, | |||
1261 | 1258 | ||
1262 | if (new_inode) | 1259 | if (new_inode) |
1263 | { | 1260 | { |
1264 | new_inode->i_nlink--; | ||
1265 | new_inode->i_ctime = current_fs_time(new_inode->i_sb); | 1261 | new_inode->i_ctime = current_fs_time(new_inode->i_sb); |
1266 | mark_inode_dirty(new_inode); | 1262 | inode_dec_link_count(new_inode); |
1267 | } | 1263 | } |
1268 | old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb); | 1264 | old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb); |
1269 | mark_inode_dirty(old_dir); | 1265 | mark_inode_dirty(old_dir); |
@@ -1279,12 +1275,10 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, | |||
1279 | } | 1275 | } |
1280 | else | 1276 | else |
1281 | mark_buffer_dirty_inode(dir_bh, old_inode); | 1277 | mark_buffer_dirty_inode(dir_bh, old_inode); |
1282 | old_dir->i_nlink --; | 1278 | inode_dec_link_count(old_dir); |
1283 | mark_inode_dirty(old_dir); | ||
1284 | if (new_inode) | 1279 | if (new_inode) |
1285 | { | 1280 | { |
1286 | new_inode->i_nlink --; | 1281 | inode_dec_link_count(new_inode); |
1287 | mark_inode_dirty(new_inode); | ||
1288 | } | 1282 | } |
1289 | else | 1283 | else |
1290 | { | 1284 | { |
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index d344b411e26..e84c0ecf073 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c | |||
@@ -308,7 +308,7 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
308 | ufs_set_link(new_dir, new_de, new_page, old_inode); | 308 | ufs_set_link(new_dir, new_de, new_page, old_inode); |
309 | new_inode->i_ctime = CURRENT_TIME_SEC; | 309 | new_inode->i_ctime = CURRENT_TIME_SEC; |
310 | if (dir_de) | 310 | if (dir_de) |
311 | new_inode->i_nlink--; | 311 | drop_nlink(new_inode); |
312 | inode_dec_link_count(new_inode); | 312 | inode_dec_link_count(new_inode); |
313 | } else { | 313 | } else { |
314 | if (dir_de) { | 314 | if (dir_de) { |
diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index 9a8f48bae95..090d74ffa06 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c | |||
@@ -782,7 +782,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry) | |||
782 | err = fat_remove_entries(dir, &sinfo); /* and releases bh */ | 782 | err = fat_remove_entries(dir, &sinfo); /* and releases bh */ |
783 | if (err) | 783 | if (err) |
784 | goto out; | 784 | goto out; |
785 | dir->i_nlink--; | 785 | drop_nlink(dir); |
786 | 786 | ||
787 | inode->i_nlink = 0; | 787 | inode->i_nlink = 0; |
788 | inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; | 788 | inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; |
@@ -930,7 +930,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
930 | if (err) | 930 | if (err) |
931 | goto error_dotdot; | 931 | goto error_dotdot; |
932 | } | 932 | } |
933 | old_dir->i_nlink--; | 933 | drop_nlink(old_dir); |
934 | if (!new_inode) | 934 | if (!new_inode) |
935 | new_dir->i_nlink++; | 935 | new_dir->i_nlink++; |
936 | } | 936 | } |
@@ -947,10 +947,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
947 | mark_inode_dirty(old_dir); | 947 | mark_inode_dirty(old_dir); |
948 | 948 | ||
949 | if (new_inode) { | 949 | if (new_inode) { |
950 | drop_nlink(new_inode); | ||
950 | if (is_dir) | 951 | if (is_dir) |
951 | new_inode->i_nlink -= 2; | 952 | drop_nlink(new_inode); |
952 | else | ||
953 | new_inode->i_nlink--; | ||
954 | new_inode->i_ctime = ts; | 953 | new_inode->i_ctime = ts; |
955 | } | 954 | } |
956 | out: | 955 | out: |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 4bb70871873..26d3c61116c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1225,9 +1225,14 @@ static inline void inode_inc_link_count(struct inode *inode) | |||
1225 | mark_inode_dirty(inode); | 1225 | mark_inode_dirty(inode); |
1226 | } | 1226 | } |
1227 | 1227 | ||
1228 | static inline void inode_dec_link_count(struct inode *inode) | 1228 | static inline void drop_nlink(struct inode *inode) |
1229 | { | 1229 | { |
1230 | inode->i_nlink--; | 1230 | inode->i_nlink--; |
1231 | } | ||
1232 | |||
1233 | static inline void inode_dec_link_count(struct inode *inode) | ||
1234 | { | ||
1235 | drop_nlink(inode); | ||
1231 | mark_inode_dirty(inode); | 1236 | mark_inode_dirty(inode); |
1232 | } | 1237 | } |
1233 | 1238 | ||
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 840f8a6fb85..10aa8eeeb11 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -307,7 +307,7 @@ static int mqueue_unlink(struct inode *dir, struct dentry *dentry) | |||
307 | 307 | ||
308 | dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME; | 308 | dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME; |
309 | dir->i_size -= DIRENT_SIZE; | 309 | dir->i_size -= DIRENT_SIZE; |
310 | inode->i_nlink--; | 310 | drop_nlink(inode); |
311 | dput(dentry); | 311 | dput(dentry); |
312 | return 0; | 312 | return 0; |
313 | } | 313 | } |
diff --git a/mm/shmem.c b/mm/shmem.c index b96de69f236..908dd947b1e 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -1772,7 +1772,7 @@ static int shmem_unlink(struct inode *dir, struct dentry *dentry) | |||
1772 | 1772 | ||
1773 | dir->i_size -= BOGO_DIRENT_SIZE; | 1773 | dir->i_size -= BOGO_DIRENT_SIZE; |
1774 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; | 1774 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; |
1775 | inode->i_nlink--; | 1775 | drop_nlink(inode); |
1776 | dput(dentry); /* Undo the count from "create" - this does all the work */ | 1776 | dput(dentry); /* Undo the count from "create" - this does all the work */ |
1777 | return 0; | 1777 | return 0; |
1778 | } | 1778 | } |
@@ -1782,8 +1782,8 @@ static int shmem_rmdir(struct inode *dir, struct dentry *dentry) | |||
1782 | if (!simple_empty(dentry)) | 1782 | if (!simple_empty(dentry)) |
1783 | return -ENOTEMPTY; | 1783 | return -ENOTEMPTY; |
1784 | 1784 | ||
1785 | dentry->d_inode->i_nlink--; | 1785 | drop_nlink(dentry->d_inode); |
1786 | dir->i_nlink--; | 1786 | drop_nlink(dir); |
1787 | return shmem_unlink(dir, dentry); | 1787 | return shmem_unlink(dir, dentry); |
1788 | } | 1788 | } |
1789 | 1789 | ||
@@ -1804,9 +1804,9 @@ static int shmem_rename(struct inode *old_dir, struct dentry *old_dentry, struct | |||
1804 | if (new_dentry->d_inode) { | 1804 | if (new_dentry->d_inode) { |
1805 | (void) shmem_unlink(new_dir, new_dentry); | 1805 | (void) shmem_unlink(new_dir, new_dentry); |
1806 | if (they_are_dirs) | 1806 | if (they_are_dirs) |
1807 | old_dir->i_nlink--; | 1807 | drop_nlink(old_dir); |
1808 | } else if (they_are_dirs) { | 1808 | } else if (they_are_dirs) { |
1809 | old_dir->i_nlink--; | 1809 | drop_nlink(old_dir); |
1810 | new_dir->i_nlink++; | 1810 | new_dir->i_nlink++; |
1811 | } | 1811 | } |
1812 | 1812 | ||