diff options
author | Nick Piggin <npiggin@suse.de> | 2010-01-29 18:38:28 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2010-04-27 11:32:42 -0400 |
commit | 1bb96f6d4dece641a9e9d7b97b109f6930967067 (patch) | |
tree | 25ee49409c0322ebcfd5c9d216bc2cfd11b5ff65 /fs | |
parent | 81d2f3cb75bf112a21fad52e9d3e3a1d7d0c907d (diff) |
fs-inode_lock-scale-4
Protect inode->i_count with i_lock, rather than having it atomic.
Next step should also be to move things together (eg. the refcount increment
into d_instantiate, which will remove a lock/unlock cycle on i_lock).
Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: John Stultz <johnstul@us.ibm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs')
46 files changed, 187 insertions, 89 deletions
diff --git a/fs/affs/inode.c b/fs/affs/inode.c index 3c4ec7d864c4..9af06f0b355c 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c | |||
@@ -379,7 +379,9 @@ affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s3 | |||
379 | affs_adjust_checksum(inode_bh, block - be32_to_cpu(chain)); | 379 | affs_adjust_checksum(inode_bh, block - be32_to_cpu(chain)); |
380 | mark_buffer_dirty_inode(inode_bh, inode); | 380 | mark_buffer_dirty_inode(inode_bh, inode); |
381 | inode->i_nlink = 2; | 381 | inode->i_nlink = 2; |
382 | atomic_inc(&inode->i_count); | 382 | spin_lock(&inode->i_lock); |
383 | inode->i_count++; | ||
384 | spin_unlock(&inode->i_lock); | ||
383 | } | 385 | } |
384 | affs_fix_checksum(sb, bh); | 386 | affs_fix_checksum(sb, bh); |
385 | mark_buffer_dirty_inode(bh, inode); | 387 | mark_buffer_dirty_inode(bh, inode); |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 88067f36e5e7..88106a018440 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -1007,7 +1007,9 @@ static int afs_link(struct dentry *from, struct inode *dir, | |||
1007 | if (ret < 0) | 1007 | if (ret < 0) |
1008 | goto link_error; | 1008 | goto link_error; |
1009 | 1009 | ||
1010 | atomic_inc(&vnode->vfs_inode.i_count); | 1010 | spin_lock(&vnode->vfs_inode.i_lock); |
1011 | vnode->vfs_inode.i_count++; | ||
1012 | spin_unlock(&vnode->vfs_inode.i_lock); | ||
1011 | d_instantiate(dentry, &vnode->vfs_inode); | 1013 | d_instantiate(dentry, &vnode->vfs_inode); |
1012 | key_put(key); | 1014 | key_put(key); |
1013 | _leave(" = 0"); | 1015 | _leave(" = 0"); |
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 9f0bf13291e5..81f82e7e7290 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c | |||
@@ -115,7 +115,9 @@ struct file *anon_inode_getfile(const char *name, | |||
115 | * so we can avoid doing an igrab() and we can use an open-coded | 115 | * so we can avoid doing an igrab() and we can use an open-coded |
116 | * atomic_inc(). | 116 | * atomic_inc(). |
117 | */ | 117 | */ |
118 | atomic_inc(&anon_inode_inode->i_count); | 118 | spin_lock(&anon_inode_inode->i_lock); |
119 | anon_inode_inode->i_count++; | ||
120 | spin_unlock(&anon_inode_inode->i_lock); | ||
119 | 121 | ||
120 | path.dentry->d_op = &anon_inodefs_dentry_operations; | 122 | path.dentry->d_op = &anon_inodefs_dentry_operations; |
121 | d_instantiate(path.dentry, anon_inode_inode); | 123 | d_instantiate(path.dentry, anon_inode_inode); |
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index 1e41aadb1068..a822829df2f2 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c | |||
@@ -178,7 +178,9 @@ static int bfs_link(struct dentry *old, struct inode *dir, | |||
178 | inc_nlink(inode); | 178 | inc_nlink(inode); |
179 | inode->i_ctime = CURRENT_TIME_SEC; | 179 | inode->i_ctime = CURRENT_TIME_SEC; |
180 | mark_inode_dirty(inode); | 180 | mark_inode_dirty(inode); |
181 | atomic_inc(&inode->i_count); | 181 | spin_lock(&inode->i_lock); |
182 | inode->i_count++; | ||
183 | spin_unlock(&inode->i_lock); | ||
182 | d_instantiate(new, inode); | 184 | d_instantiate(new, inode); |
183 | mutex_unlock(&info->bfs_lock); | 185 | mutex_unlock(&info->bfs_lock); |
184 | return 0; | 186 | return 0; |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 8db62b2b6df8..bf503be689c3 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -587,7 +587,12 @@ EXPORT_SYMBOL(bdget); | |||
587 | */ | 587 | */ |
588 | struct block_device *bdgrab(struct block_device *bdev) | 588 | struct block_device *bdgrab(struct block_device *bdev) |
589 | { | 589 | { |
590 | atomic_inc(&bdev->bd_inode->i_count); | 590 | struct inode *inode = bdev->bd_inode; |
591 | |||
592 | spin_lock(&inode->i_lock); | ||
593 | inode->i_count++; | ||
594 | spin_unlock(&inode->i_lock); | ||
595 | |||
591 | return bdev; | 596 | return bdev; |
592 | } | 597 | } |
593 | 598 | ||
@@ -617,7 +622,9 @@ static struct block_device *bd_acquire(struct inode *inode) | |||
617 | spin_lock(&bdev_lock); | 622 | spin_lock(&bdev_lock); |
618 | bdev = inode->i_bdev; | 623 | bdev = inode->i_bdev; |
619 | if (bdev) { | 624 | if (bdev) { |
620 | atomic_inc(&bdev->bd_inode->i_count); | 625 | spin_lock(&inode->i_lock); |
626 | bdev->bd_inode->i_count++; | ||
627 | spin_unlock(&inode->i_lock); | ||
621 | spin_unlock(&bdev_lock); | 628 | spin_unlock(&bdev_lock); |
622 | return bdev; | 629 | return bdev; |
623 | } | 630 | } |
@@ -633,7 +640,9 @@ static struct block_device *bd_acquire(struct inode *inode) | |||
633 | * So, we can access it via ->i_mapping always | 640 | * So, we can access it via ->i_mapping always |
634 | * without igrab(). | 641 | * without igrab(). |
635 | */ | 642 | */ |
636 | atomic_inc(&bdev->bd_inode->i_count); | 643 | spin_lock(&inode->i_lock); |
644 | bdev->bd_inode->i_count++; | ||
645 | spin_unlock(&inode->i_lock); | ||
637 | inode->i_bdev = bdev; | 646 | inode->i_bdev = bdev; |
638 | inode->i_mapping = bdev->bd_inode->i_mapping; | 647 | inode->i_mapping = bdev->bd_inode->i_mapping; |
639 | list_add(&inode->i_devices, &bdev->bd_inodes); | 648 | list_add(&inode->i_devices, &bdev->bd_inodes); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4deb280f8969..9dcc771ff485 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -4446,7 +4446,9 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
4446 | trans = btrfs_start_transaction(root, 1); | 4446 | trans = btrfs_start_transaction(root, 1); |
4447 | 4447 | ||
4448 | btrfs_set_trans_block_group(trans, dir); | 4448 | btrfs_set_trans_block_group(trans, dir); |
4449 | atomic_inc(&inode->i_count); | 4449 | spin_lock(&inode->i_lock); |
4450 | inode->i_count++; | ||
4451 | spin_unlock(&inode->i_lock); | ||
4450 | 4452 | ||
4451 | err = btrfs_add_nondir(trans, dentry, inode, 1, index); | 4453 | err = btrfs_add_nondir(trans, dentry, inode, 1, index); |
4452 | 4454 | ||
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index e3fda978f481..d7346de1049a 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1425,7 +1425,7 @@ int cifs_revalidate(struct dentry *direntry) | |||
1425 | } | 1425 | } |
1426 | cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld " | 1426 | cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld " |
1427 | "jiffies %ld", full_path, direntry->d_inode, | 1427 | "jiffies %ld", full_path, direntry->d_inode, |
1428 | direntry->d_inode->i_count.counter, direntry, | 1428 | direntry->d_inode->i_count, direntry, |
1429 | direntry->d_time, jiffies)); | 1429 | direntry->d_time, jiffies)); |
1430 | 1430 | ||
1431 | if (cifsInode->time == 0) { | 1431 | if (cifsInode->time == 0) { |
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 397d0f598553..ee3410542b72 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
@@ -302,7 +302,9 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode, | |||
302 | } | 302 | } |
303 | 303 | ||
304 | coda_dir_update_mtime(dir_inode); | 304 | coda_dir_update_mtime(dir_inode); |
305 | atomic_inc(&inode->i_count); | 305 | spin_lock(&inode->i_lock); |
306 | inode->i_count++; | ||
307 | spin_unlock(&inode->i_lock); | ||
306 | d_instantiate(de, inode); | 308 | d_instantiate(de, inode); |
307 | inc_nlink(inode); | 309 | inc_nlink(inode); |
308 | 310 | ||
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 2afbcebeda71..44fcbf48c01f 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
@@ -1054,7 +1054,9 @@ static void create_done(struct exofs_io_state *ios, void *p) | |||
1054 | 1054 | ||
1055 | set_obj_created(oi); | 1055 | set_obj_created(oi); |
1056 | 1056 | ||
1057 | atomic_dec(&inode->i_count); | 1057 | spin_lock(&inode->i_lock); |
1058 | inode->i_count--; | ||
1059 | spin_unlock(&inode->i_lock); | ||
1058 | wake_up(&oi->i_wq); | 1060 | wake_up(&oi->i_wq); |
1059 | } | 1061 | } |
1060 | 1062 | ||
@@ -1116,14 +1118,18 @@ struct inode *exofs_new_inode(struct inode *dir, int mode) | |||
1116 | /* increment the refcount so that the inode will still be around when we | 1118 | /* increment the refcount so that the inode will still be around when we |
1117 | * reach the callback | 1119 | * reach the callback |
1118 | */ | 1120 | */ |
1119 | atomic_inc(&inode->i_count); | 1121 | spin_lock(&inode->i_lock); |
1122 | inode->i_count++; | ||
1123 | spin_unlock(&inode->i_lock); | ||
1120 | 1124 | ||
1121 | ios->done = create_done; | 1125 | ios->done = create_done; |
1122 | ios->private = inode; | 1126 | ios->private = inode; |
1123 | ios->cred = oi->i_cred; | 1127 | ios->cred = oi->i_cred; |
1124 | ret = exofs_sbi_create(ios); | 1128 | ret = exofs_sbi_create(ios); |
1125 | if (ret) { | 1129 | if (ret) { |
1126 | atomic_dec(&inode->i_count); | 1130 | spin_lock(&inode->i_lock); |
1131 | inode->i_count--; | ||
1132 | spin_unlock(&inode->i_lock); | ||
1127 | exofs_put_io_state(ios); | 1133 | exofs_put_io_state(ios); |
1128 | return ERR_PTR(ret); | 1134 | return ERR_PTR(ret); |
1129 | } | 1135 | } |
diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c index b7dd0c236863..506778ac4fcd 100644 --- a/fs/exofs/namei.c +++ b/fs/exofs/namei.c | |||
@@ -153,7 +153,9 @@ static int exofs_link(struct dentry *old_dentry, struct inode *dir, | |||
153 | 153 | ||
154 | inode->i_ctime = CURRENT_TIME; | 154 | inode->i_ctime = CURRENT_TIME; |
155 | inode_inc_link_count(inode); | 155 | inode_inc_link_count(inode); |
156 | atomic_inc(&inode->i_count); | 156 | spin_lock(&inode->i_lock); |
157 | inode->i_count++; | ||
158 | spin_unlock(&inode->i_lock); | ||
157 | 159 | ||
158 | return exofs_add_nondir(dentry, inode); | 160 | return exofs_add_nondir(dentry, inode); |
159 | } | 161 | } |
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index dd7175ce5606..34259ac72cef 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c | |||
@@ -196,7 +196,9 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir, | |||
196 | 196 | ||
197 | inode->i_ctime = CURRENT_TIME_SEC; | 197 | inode->i_ctime = CURRENT_TIME_SEC; |
198 | inode_inc_link_count(inode); | 198 | inode_inc_link_count(inode); |
199 | atomic_inc(&inode->i_count); | 199 | spin_lock(&inode->i_lock); |
200 | inode->i_count++; | ||
201 | spin_unlock(&inode->i_lock); | ||
200 | 202 | ||
201 | err = ext2_add_link(dentry, inode); | 203 | err = ext2_add_link(dentry, inode); |
202 | if (!err) { | 204 | if (!err) { |
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index b39991285136..2b40cffa2432 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c | |||
@@ -100,9 +100,9 @@ void ext3_free_inode (handle_t *handle, struct inode * inode) | |||
100 | struct ext3_sb_info *sbi; | 100 | struct ext3_sb_info *sbi; |
101 | int fatal = 0, err; | 101 | int fatal = 0, err; |
102 | 102 | ||
103 | if (atomic_read(&inode->i_count) > 1) { | 103 | if (inode->i_count > 1) { |
104 | printk ("ext3_free_inode: inode has count=%d\n", | 104 | printk ("ext3_free_inode: inode has count=%d\n", |
105 | atomic_read(&inode->i_count)); | 105 | inode->i_count); |
106 | return; | 106 | return; |
107 | } | 107 | } |
108 | if (inode->i_nlink) { | 108 | if (inode->i_nlink) { |
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 7b0e44f7d66f..ee6676c11b5c 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -2246,7 +2246,9 @@ retry: | |||
2246 | 2246 | ||
2247 | inode->i_ctime = CURRENT_TIME_SEC; | 2247 | inode->i_ctime = CURRENT_TIME_SEC; |
2248 | inc_nlink(inode); | 2248 | inc_nlink(inode); |
2249 | atomic_inc(&inode->i_count); | 2249 | spin_lock(&inode->i_lock); |
2250 | inode->i_count++; | ||
2251 | spin_unlock(&inode->i_lock); | ||
2250 | 2252 | ||
2251 | err = ext3_add_entry(handle, dentry, inode); | 2253 | err = ext3_add_entry(handle, dentry, inode); |
2252 | if (!err) { | 2254 | if (!err) { |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index f3624ead4f6c..8297fad406c6 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -192,9 +192,9 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) | |||
192 | struct ext4_sb_info *sbi; | 192 | struct ext4_sb_info *sbi; |
193 | int fatal = 0, err, count, cleared; | 193 | int fatal = 0, err, count, cleared; |
194 | 194 | ||
195 | if (atomic_read(&inode->i_count) > 1) { | 195 | if (inode->i_count > 1) { |
196 | printk(KERN_ERR "ext4_free_inode: inode has count=%d\n", | 196 | printk(KERN_ERR "ext4_free_inode: inode has count=%d\n", |
197 | atomic_read(&inode->i_count)); | 197 | inode->i_count); |
198 | return; | 198 | return; |
199 | } | 199 | } |
200 | if (inode->i_nlink) { | 200 | if (inode->i_nlink) { |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 17a17e10dd60..70150b6f09a2 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -2326,7 +2326,9 @@ retry: | |||
2326 | 2326 | ||
2327 | inode->i_ctime = ext4_current_time(inode); | 2327 | inode->i_ctime = ext4_current_time(inode); |
2328 | ext4_inc_count(handle, inode); | 2328 | ext4_inc_count(handle, inode); |
2329 | atomic_inc(&inode->i_count); | 2329 | spin_lock(&inode->i_lock); |
2330 | inode->i_count++; | ||
2331 | spin_unlock(&inode->i_lock); | ||
2330 | 2332 | ||
2331 | err = ext4_add_entry(handle, dentry, inode); | 2333 | err = ext4_add_entry(handle, dentry, inode); |
2332 | if (!err) { | 2334 | if (!err) { |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 8d57f0e14ebb..1e9ead755050 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -427,7 +427,7 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) | |||
427 | unsigned dirty; | 427 | unsigned dirty; |
428 | int ret; | 428 | int ret; |
429 | 429 | ||
430 | if (!atomic_read(&inode->i_count)) | 430 | if (!inode->i_count) |
431 | WARN_ON(!(inode->i_state & (I_WILL_FREE|I_FREEING))); | 431 | WARN_ON(!(inode->i_state & (I_WILL_FREE|I_FREEING))); |
432 | else | 432 | else |
433 | WARN_ON(inode->i_state & I_WILL_FREE); | 433 | WARN_ON(inode->i_state & I_WILL_FREE); |
@@ -537,7 +537,7 @@ select_queue: | |||
537 | inode->i_state |= I_DIRTY_PAGES; | 537 | inode->i_state |= I_DIRTY_PAGES; |
538 | redirty_tail(inode); | 538 | redirty_tail(inode); |
539 | } | 539 | } |
540 | } else if (atomic_read(&inode->i_count)) { | 540 | } else if (inode->i_count) { |
541 | /* | 541 | /* |
542 | * The inode is clean, inuse | 542 | * The inode is clean, inuse |
543 | */ | 543 | */ |
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 84350e1be66d..f5a07d98ec06 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -253,7 +253,9 @@ out_parent: | |||
253 | gfs2_holder_uninit(ghs); | 253 | gfs2_holder_uninit(ghs); |
254 | gfs2_holder_uninit(ghs + 1); | 254 | gfs2_holder_uninit(ghs + 1); |
255 | if (!error) { | 255 | if (!error) { |
256 | atomic_inc(&inode->i_count); | 256 | spin_lock(&inode->i_lock); |
257 | inode->i_count++; | ||
258 | spin_unlock(&inode->i_lock); | ||
257 | d_instantiate(dentry, inode); | 259 | d_instantiate(dentry, inode); |
258 | mark_inode_dirty(inode); | 260 | mark_inode_dirty(inode); |
259 | } | 261 | } |
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 5f4023678251..557c5335de66 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
@@ -301,7 +301,9 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir, | |||
301 | 301 | ||
302 | inc_nlink(inode); | 302 | inc_nlink(inode); |
303 | hfsplus_instantiate(dst_dentry, inode, cnid); | 303 | hfsplus_instantiate(dst_dentry, inode, cnid); |
304 | atomic_inc(&inode->i_count); | 304 | spin_lock(&inode->i_lock); |
305 | inode->i_count++; | ||
306 | spin_unlock(&inode->i_lock); | ||
305 | inode->i_ctime = CURRENT_TIME_SEC; | 307 | inode->i_ctime = CURRENT_TIME_SEC; |
306 | mark_inode_dirty(inode); | 308 | mark_inode_dirty(inode); |
307 | HFSPLUS_SB(sb).file_count++; | 309 | HFSPLUS_SB(sb).file_count++; |
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index fe703ae46bc7..b22044cb988b 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c | |||
@@ -182,7 +182,7 @@ void hpfs_write_inode(struct inode *i) | |||
182 | struct hpfs_inode_info *hpfs_inode = hpfs_i(i); | 182 | struct hpfs_inode_info *hpfs_inode = hpfs_i(i); |
183 | struct inode *parent; | 183 | struct inode *parent; |
184 | if (i->i_ino == hpfs_sb(i->i_sb)->sb_root) return; | 184 | if (i->i_ino == hpfs_sb(i->i_sb)->sb_root) return; |
185 | if (hpfs_inode->i_rddir_off && !atomic_read(&i->i_count)) { | 185 | if (hpfs_inode->i_rddir_off && !i->i_count) { |
186 | if (*hpfs_inode->i_rddir_off) printk("HPFS: write_inode: some position still there\n"); | 186 | if (*hpfs_inode->i_rddir_off) printk("HPFS: write_inode: some position still there\n"); |
187 | kfree(hpfs_inode->i_rddir_off); | 187 | kfree(hpfs_inode->i_rddir_off); |
188 | hpfs_inode->i_rddir_off = NULL; | 188 | hpfs_inode->i_rddir_off = NULL; |
diff --git a/fs/inode.c b/fs/inode.c index a1f5c2fa1d4a..99d664bafe9f 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -136,7 +136,7 @@ int inode_init_always(struct super_block *sb, struct inode *inode) | |||
136 | inode->i_sb = sb; | 136 | inode->i_sb = sb; |
137 | inode->i_blkbits = sb->s_blocksize_bits; | 137 | inode->i_blkbits = sb->s_blocksize_bits; |
138 | inode->i_flags = 0; | 138 | inode->i_flags = 0; |
139 | atomic_set(&inode->i_count, 1); | 139 | inode->i_count = 1; |
140 | inode->i_op = &empty_iops; | 140 | inode->i_op = &empty_iops; |
141 | inode->i_fop = &empty_fops; | 141 | inode->i_fop = &empty_fops; |
142 | inode->i_nlink = 1; | 142 | inode->i_nlink = 1; |
@@ -290,11 +290,10 @@ static void init_once(void *foo) | |||
290 | void __iget(struct inode *inode) | 290 | void __iget(struct inode *inode) |
291 | { | 291 | { |
292 | assert_spin_locked(&inode->i_lock); | 292 | assert_spin_locked(&inode->i_lock); |
293 | if (atomic_read(&inode->i_count)) { | 293 | inode->i_count++; |
294 | atomic_inc(&inode->i_count); | 294 | if (inode->i_count > 1) |
295 | return; | 295 | return; |
296 | } | 296 | |
297 | atomic_inc(&inode->i_count); | ||
298 | if (!(inode->i_state & (I_DIRTY|I_SYNC))) | 297 | if (!(inode->i_state & (I_DIRTY|I_SYNC))) |
299 | list_move(&inode->i_list, &inode_in_use); | 298 | list_move(&inode->i_list, &inode_in_use); |
300 | inodes_stat.nr_unused--; | 299 | inodes_stat.nr_unused--; |
@@ -399,7 +398,7 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose) | |||
399 | continue; | 398 | continue; |
400 | } | 399 | } |
401 | invalidate_inode_buffers(inode); | 400 | invalidate_inode_buffers(inode); |
402 | if (!atomic_read(&inode->i_count)) { | 401 | if (!inode->i_count) { |
403 | list_move(&inode->i_list, dispose); | 402 | list_move(&inode->i_list, dispose); |
404 | WARN_ON(inode->i_state & I_NEW); | 403 | WARN_ON(inode->i_state & I_NEW); |
405 | inode->i_state |= I_FREEING; | 404 | inode->i_state |= I_FREEING; |
@@ -450,7 +449,7 @@ static int can_unuse(struct inode *inode) | |||
450 | return 0; | 449 | return 0; |
451 | if (inode_has_buffers(inode)) | 450 | if (inode_has_buffers(inode)) |
452 | return 0; | 451 | return 0; |
453 | if (atomic_read(&inode->i_count)) | 452 | if (inode->i_count) |
454 | return 0; | 453 | return 0; |
455 | if (inode->i_data.nrpages) | 454 | if (inode->i_data.nrpages) |
456 | return 0; | 455 | return 0; |
@@ -488,7 +487,7 @@ static void prune_icache(int nr_to_scan) | |||
488 | inode = list_entry(inode_unused.prev, struct inode, i_list); | 487 | inode = list_entry(inode_unused.prev, struct inode, i_list); |
489 | 488 | ||
490 | spin_lock(&inode->i_lock); | 489 | spin_lock(&inode->i_lock); |
491 | if (inode->i_state || atomic_read(&inode->i_count)) { | 490 | if (inode->i_state || inode->i_count) { |
492 | list_move(&inode->i_list, &inode_unused); | 491 | list_move(&inode->i_list, &inode_unused); |
493 | spin_unlock(&inode->i_lock); | 492 | spin_unlock(&inode->i_lock); |
494 | continue; | 493 | continue; |
@@ -1277,8 +1276,6 @@ void generic_delete_inode(struct inode *inode) | |||
1277 | { | 1276 | { |
1278 | const struct super_operations *op = inode->i_sb->s_op; | 1277 | const struct super_operations *op = inode->i_sb->s_op; |
1279 | 1278 | ||
1280 | spin_lock(&sb_inode_list_lock); | ||
1281 | spin_lock(&inode->i_lock); | ||
1282 | list_del_init(&inode->i_list); | 1279 | list_del_init(&inode->i_list); |
1283 | list_del_init(&inode->i_sb_list); | 1280 | list_del_init(&inode->i_sb_list); |
1284 | spin_unlock(&sb_inode_list_lock); | 1281 | spin_unlock(&sb_inode_list_lock); |
@@ -1327,8 +1324,6 @@ int generic_detach_inode(struct inode *inode) | |||
1327 | { | 1324 | { |
1328 | struct super_block *sb = inode->i_sb; | 1325 | struct super_block *sb = inode->i_sb; |
1329 | 1326 | ||
1330 | spin_lock(&sb_inode_list_lock); | ||
1331 | spin_lock(&inode->i_lock); | ||
1332 | if (!hlist_unhashed(&inode->i_hash)) { | 1327 | if (!hlist_unhashed(&inode->i_hash)) { |
1333 | if (!(inode->i_state & (I_DIRTY|I_SYNC))) | 1328 | if (!(inode->i_state & (I_DIRTY|I_SYNC))) |
1334 | list_move(&inode->i_list, &inode_unused); | 1329 | list_move(&inode->i_list, &inode_unused); |
@@ -1427,8 +1422,24 @@ void iput(struct inode *inode) | |||
1427 | if (inode) { | 1422 | if (inode) { |
1428 | BUG_ON(inode->i_state == I_CLEAR); | 1423 | BUG_ON(inode->i_state == I_CLEAR); |
1429 | 1424 | ||
1430 | if (atomic_dec_and_lock(&inode->i_count, &inode_lock)) | 1425 | retry: |
1426 | spin_lock(&inode->i_lock); | ||
1427 | if (inode->i_count == 1) { | ||
1428 | if (!spin_trylock(&inode_lock)) { | ||
1429 | spin_unlock(&inode->i_lock); | ||
1430 | goto retry; | ||
1431 | } | ||
1432 | if (!spin_trylock(&sb_inode_list_lock)) { | ||
1433 | spin_unlock(&inode_lock); | ||
1434 | spin_unlock(&inode->i_lock); | ||
1435 | goto retry; | ||
1436 | } | ||
1437 | inode->i_count--; | ||
1431 | iput_final(inode); | 1438 | iput_final(inode); |
1439 | } else { | ||
1440 | inode->i_count--; | ||
1441 | spin_unlock(&inode->i_lock); | ||
1442 | } | ||
1432 | } | 1443 | } |
1433 | } | 1444 | } |
1434 | EXPORT_SYMBOL(iput); | 1445 | EXPORT_SYMBOL(iput); |
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 7aa4417e085f..40bc1705fa05 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c | |||
@@ -287,7 +287,9 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de | |||
287 | mutex_unlock(&f->sem); | 287 | mutex_unlock(&f->sem); |
288 | d_instantiate(dentry, old_dentry->d_inode); | 288 | d_instantiate(dentry, old_dentry->d_inode); |
289 | dir_i->i_mtime = dir_i->i_ctime = ITIME(now); | 289 | dir_i->i_mtime = dir_i->i_ctime = ITIME(now); |
290 | atomic_inc(&old_dentry->d_inode->i_count); | 290 | spin_lock(&old_dentry->d_inode->i_lock); |
291 | old_dentry->d_inode->i_count++; | ||
292 | spin_unlock(&old_dentry->d_inode->i_lock); | ||
291 | } | 293 | } |
292 | return ret; | 294 | return ret; |
293 | } | 295 | } |
@@ -866,7 +868,9 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | |||
866 | printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret); | 868 | printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret); |
867 | /* Might as well let the VFS know */ | 869 | /* Might as well let the VFS know */ |
868 | d_instantiate(new_dentry, old_dentry->d_inode); | 870 | d_instantiate(new_dentry, old_dentry->d_inode); |
869 | atomic_inc(&old_dentry->d_inode->i_count); | 871 | spin_lock(&old_dentry->d_inode->i_lock); |
872 | old_dentry->d_inode->i_count++; | ||
873 | spin_unlock(&old_dentry->d_inode->i_lock); | ||
870 | new_dir_i->i_mtime = new_dir_i->i_ctime = ITIME(now); | 874 | new_dir_i->i_mtime = new_dir_i->i_ctime = ITIME(now); |
871 | return ret; | 875 | return ret; |
872 | } | 876 | } |
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index d945ea76b445..820212f3fc88 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c | |||
@@ -1279,7 +1279,9 @@ int txCommit(tid_t tid, /* transaction identifier */ | |||
1279 | * lazy commit thread finishes processing | 1279 | * lazy commit thread finishes processing |
1280 | */ | 1280 | */ |
1281 | if (tblk->xflag & COMMIT_DELETE) { | 1281 | if (tblk->xflag & COMMIT_DELETE) { |
1282 | atomic_inc(&tblk->u.ip->i_count); | 1282 | spin_lock(&tblk->u.ip->i_lock); |
1283 | tblk->u.ip->i_count++; | ||
1284 | spin_unlock(&tblk->u.ip->i_lock); | ||
1283 | /* | 1285 | /* |
1284 | * Avoid a rare deadlock | 1286 | * Avoid a rare deadlock |
1285 | * | 1287 | * |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index c79a4270f083..8fa6219d0eeb 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -831,7 +831,9 @@ static int jfs_link(struct dentry *old_dentry, | |||
831 | ip->i_ctime = CURRENT_TIME; | 831 | ip->i_ctime = CURRENT_TIME; |
832 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; | 832 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; |
833 | mark_inode_dirty(dir); | 833 | mark_inode_dirty(dir); |
834 | atomic_inc(&ip->i_count); | 834 | spin_lock(&ip->i_lock); |
835 | ip->i_count++; | ||
836 | spin_unlock(&ip->i_lock); | ||
835 | 837 | ||
836 | iplist[0] = ip; | 838 | iplist[0] = ip; |
837 | iplist[1] = dir; | 839 | iplist[1] = dir; |
diff --git a/fs/libfs.c b/fs/libfs.c index 47e587e0e694..e8a7923a9fbb 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -280,7 +280,9 @@ int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *den | |||
280 | 280 | ||
281 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; | 281 | inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; |
282 | inc_nlink(inode); | 282 | inc_nlink(inode); |
283 | atomic_inc(&inode->i_count); | 283 | spin_lock(&inode->i_lock); |
284 | inode->i_count++; | ||
285 | spin_unlock(&inode->i_lock); | ||
284 | dget(dentry); | 286 | dget(dentry); |
285 | d_instantiate(dentry, inode); | 287 | d_instantiate(dentry, inode); |
286 | return 0; | 288 | return 0; |
diff --git a/fs/locks.c b/fs/locks.c index 66ac25aab803..0e074d5417b0 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -1374,8 +1374,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp) | |||
1374 | if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0)) | 1374 | if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0)) |
1375 | goto out; | 1375 | goto out; |
1376 | if ((arg == F_WRLCK) | 1376 | if ((arg == F_WRLCK) |
1377 | && (dentry->d_count > 1 | 1377 | && (dentry->d_count > 1 || inode->i_count > 1)) |
1378 | || (atomic_read(&inode->i_count) > 1))) | ||
1379 | goto out; | 1378 | goto out; |
1380 | } | 1379 | } |
1381 | 1380 | ||
diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 32b131cd6121..1b0b9f081ffa 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c | |||
@@ -103,7 +103,9 @@ static int minix_link(struct dentry * old_dentry, struct inode * dir, | |||
103 | 103 | ||
104 | inode->i_ctime = CURRENT_TIME_SEC; | 104 | inode->i_ctime = CURRENT_TIME_SEC; |
105 | inode_inc_link_count(inode); | 105 | inode_inc_link_count(inode); |
106 | atomic_inc(&inode->i_count); | 106 | spin_lock(&inode->i_lock); |
107 | inode->i_count++; | ||
108 | spin_unlock(&inode->i_lock); | ||
107 | return add_nondir(dentry, inode); | 109 | return add_nondir(dentry, inode); |
108 | } | 110 | } |
109 | 111 | ||
diff --git a/fs/namei.c b/fs/namei.c index 69e79576c899..157d4e4fc9f9 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2317,8 +2317,11 @@ static long do_unlinkat(int dfd, const char __user *pathname) | |||
2317 | if (nd.last.name[nd.last.len]) | 2317 | if (nd.last.name[nd.last.len]) |
2318 | goto slashes; | 2318 | goto slashes; |
2319 | inode = dentry->d_inode; | 2319 | inode = dentry->d_inode; |
2320 | if (inode) | 2320 | if (inode) { |
2321 | atomic_inc(&inode->i_count); | 2321 | spin_lock(&inode->i_lock); |
2322 | inode->i_count++; | ||
2323 | spin_unlock(&inode->i_lock); | ||
2324 | } | ||
2322 | error = mnt_want_write(nd.path.mnt); | 2325 | error = mnt_want_write(nd.path.mnt); |
2323 | if (error) | 2326 | if (error) |
2324 | goto exit2; | 2327 | goto exit2; |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index a2538cf79fc9..6527b589d5b2 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1538,7 +1538,9 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) | |||
1538 | d_drop(dentry); | 1538 | d_drop(dentry); |
1539 | error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name); | 1539 | error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name); |
1540 | if (error == 0) { | 1540 | if (error == 0) { |
1541 | atomic_inc(&inode->i_count); | 1541 | spin_lock(&inode->i_lock); |
1542 | inode->i_count++; | ||
1543 | spin_unlock(&inode->i_lock); | ||
1542 | d_add(dentry, inode); | 1544 | d_add(dentry, inode); |
1543 | } | 1545 | } |
1544 | return error; | 1546 | return error; |
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index f90a380a6364..5b79ff1dd3a9 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c | |||
@@ -55,7 +55,9 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i | |||
55 | return -ENOMEM; | 55 | return -ENOMEM; |
56 | } | 56 | } |
57 | /* Circumvent igrab(): we know the inode is not being freed */ | 57 | /* Circumvent igrab(): we know the inode is not being freed */ |
58 | atomic_inc(&inode->i_count); | 58 | spin_lock(&inode->i_lock); |
59 | inode->i_count++; | ||
60 | spin_unlock(&inode->i_lock); | ||
59 | /* | 61 | /* |
60 | * Ensure that this dentry is invisible to d_find_alias(). | 62 | * Ensure that this dentry is invisible to d_find_alias(). |
61 | * Otherwise, it may be spliced into the tree by | 63 | * Otherwise, it may be spliced into the tree by |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 5f59a2df21aa..8e7fcc253e43 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -396,7 +396,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
396 | dprintk("NFS: nfs_fhget(%s/%Ld ct=%d)\n", | 396 | dprintk("NFS: nfs_fhget(%s/%Ld ct=%d)\n", |
397 | inode->i_sb->s_id, | 397 | inode->i_sb->s_id, |
398 | (long long)NFS_FILEID(inode), | 398 | (long long)NFS_FILEID(inode), |
399 | atomic_read(&inode->i_count)); | 399 | inode->i_count); |
400 | 400 | ||
401 | out: | 401 | out: |
402 | return inode; | 402 | return inode; |
@@ -1153,7 +1153,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1153 | 1153 | ||
1154 | dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", | 1154 | dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", |
1155 | __func__, inode->i_sb->s_id, inode->i_ino, | 1155 | __func__, inode->i_sb->s_id, inode->i_ino, |
1156 | atomic_read(&inode->i_count), fattr->valid); | 1156 | inode->i_count, fattr->valid); |
1157 | 1157 | ||
1158 | if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid) | 1158 | if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid) |
1159 | goto out_fileid; | 1159 | goto out_fileid; |
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c index e7ed4cdd0ecf..a7dccc002a85 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c | |||
@@ -478,7 +478,7 @@ nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb, | |||
478 | inode->i_sb = sb; /* sb may be NULL for some meta data files */ | 478 | inode->i_sb = sb; /* sb may be NULL for some meta data files */ |
479 | inode->i_blkbits = nilfs->ns_blocksize_bits; | 479 | inode->i_blkbits = nilfs->ns_blocksize_bits; |
480 | inode->i_flags = 0; | 480 | inode->i_flags = 0; |
481 | atomic_set(&inode->i_count, 1); | 481 | inode->i_count = 1; |
482 | inode->i_nlink = 1; | 482 | inode->i_nlink = 1; |
483 | inode->i_ino = ino; | 483 | inode->i_ino = ino; |
484 | inode->i_mode = S_IFREG; | 484 | inode->i_mode = S_IFREG; |
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index 07ba838ef089..bc9308f1d616 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c | |||
@@ -222,7 +222,9 @@ static int nilfs_link(struct dentry *old_dentry, struct inode *dir, | |||
222 | 222 | ||
223 | inode->i_ctime = CURRENT_TIME; | 223 | inode->i_ctime = CURRENT_TIME; |
224 | inode_inc_link_count(inode); | 224 | inode_inc_link_count(inode); |
225 | atomic_inc(&inode->i_count); | 225 | spin_lock(&inode->i_lock); |
226 | inode->i_count++; | ||
227 | spin_unlock(&inode->i_lock); | ||
226 | 228 | ||
227 | err = nilfs_add_nondir(dentry, inode); | 229 | err = nilfs_add_nondir(dentry, inode); |
228 | if (!err) | 230 | if (!err) |
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c index bfe1d2e676fd..869f94bb040f 100644 --- a/fs/notify/inode_mark.c +++ b/fs/notify/inode_mark.c | |||
@@ -383,24 +383,30 @@ void fsnotify_unmount_inodes(struct list_head *list) | |||
383 | * evict all inodes with zero i_count from icache which is | 383 | * evict all inodes with zero i_count from icache which is |
384 | * unnecessarily violent and may in fact be illegal to do. | 384 | * unnecessarily violent and may in fact be illegal to do. |
385 | */ | 385 | */ |
386 | if (!atomic_read(&inode->i_count)) | 386 | if (!inode->i_count) |
387 | continue; | 387 | continue; |
388 | 388 | ||
389 | need_iput_tmp = need_iput; | 389 | need_iput_tmp = need_iput; |
390 | need_iput = NULL; | 390 | need_iput = NULL; |
391 | 391 | ||
392 | /* In case fsnotify_inode_delete() drops a reference. */ | 392 | /* In case fsnotify_inode_delete() drops a reference. */ |
393 | if (inode != need_iput_tmp) | 393 | if (inode != need_iput_tmp) { |
394 | spin_lock(&inode->i_lock); | ||
394 | __iget(inode); | 395 | __iget(inode); |
395 | else | 396 | spin_unlock(&inode->i_lock); |
397 | } else | ||
396 | need_iput_tmp = NULL; | 398 | need_iput_tmp = NULL; |
397 | 399 | ||
398 | /* In case the dropping of a reference would nuke next_i. */ | 400 | /* In case the dropping of a reference would nuke next_i. */ |
399 | if ((&next_i->i_sb_list != list) && | 401 | if (&next_i->i_sb_list != list) { |
400 | atomic_read(&next_i->i_count) && | 402 | spin_lock(&next_i->i_lock); |
401 | !(next_i->i_state & (I_CLEAR | I_FREEING | I_WILL_FREE))) { | 403 | if (next_i->i_count && |
402 | __iget(next_i); | 404 | !(next_i->i_state & |
403 | need_iput = next_i; | 405 | (I_CLEAR | I_FREEING | I_WILL_FREE))) { |
406 | __iget(next_i); | ||
407 | need_iput = next_i; | ||
408 | } | ||
409 | spin_unlock(&next_i->i_lock); | ||
404 | } | 410 | } |
405 | 411 | ||
406 | /* | 412 | /* |
diff --git a/fs/notify/inotify/inotify.c b/fs/notify/inotify/inotify.c index c3dd7655338b..44e90ef0b0a3 100644 --- a/fs/notify/inotify/inotify.c +++ b/fs/notify/inotify/inotify.c | |||
@@ -408,23 +408,28 @@ void inotify_unmount_inodes(struct list_head *list) | |||
408 | * evict all inodes with zero i_count from icache which is | 408 | * evict all inodes with zero i_count from icache which is |
409 | * unnecessarily violent and may in fact be illegal to do. | 409 | * unnecessarily violent and may in fact be illegal to do. |
410 | */ | 410 | */ |
411 | if (!atomic_read(&inode->i_count)) | 411 | if (!inode->i_count) |
412 | continue; | 412 | continue; |
413 | 413 | ||
414 | need_iput_tmp = need_iput; | 414 | need_iput_tmp = need_iput; |
415 | need_iput = NULL; | 415 | need_iput = NULL; |
416 | /* In case inotify_remove_watch_locked() drops a reference. */ | 416 | /* In case inotify_remove_watch_locked() drops a reference. */ |
417 | if (inode != need_iput_tmp) | 417 | if (inode != need_iput_tmp) { |
418 | spin_lock(&inode->i_lock); | ||
418 | __iget(inode); | 419 | __iget(inode); |
419 | else | 420 | spin_unlock(&inode->i_lock); |
421 | } else | ||
420 | need_iput_tmp = NULL; | 422 | need_iput_tmp = NULL; |
421 | /* In case the dropping of a reference would nuke next_i. */ | 423 | /* In case the dropping of a reference would nuke next_i. */ |
422 | if ((&next_i->i_sb_list != list) && | 424 | if (&next_i->i_sb_list != list) { |
423 | atomic_read(&next_i->i_count) && | 425 | spin_lock(&next_i->i_lock); |
424 | !(next_i->i_state & (I_CLEAR | I_FREEING | | 426 | if (next_i->i_count && |
425 | I_WILL_FREE))) { | 427 | !(next_i->i_state & |
426 | __iget(next_i); | 428 | (I_CLEAR|I_FREEING|I_WILL_FREE))) { |
427 | need_iput = next_i; | 429 | __iget(next_i); |
430 | need_iput = next_i; | ||
431 | } | ||
432 | spin_unlock(&next_i->i_lock); | ||
428 | } | 433 | } |
429 | 434 | ||
430 | /* | 435 | /* |
@@ -443,11 +448,10 @@ void inotify_unmount_inodes(struct list_head *list) | |||
443 | mutex_lock(&inode->inotify_mutex); | 448 | mutex_lock(&inode->inotify_mutex); |
444 | watches = &inode->inotify_watches; | 449 | watches = &inode->inotify_watches; |
445 | list_for_each_entry_safe(watch, next_w, watches, i_list) { | 450 | list_for_each_entry_safe(watch, next_w, watches, i_list) { |
446 | struct inotify_handle *ih= watch->ih; | 451 | struct inotify_handle *ih = watch->ih; |
447 | get_inotify_watch(watch); | 452 | get_inotify_watch(watch); |
448 | mutex_lock(&ih->mutex); | 453 | mutex_lock(&ih->mutex); |
449 | ih->in_ops->handle_event(watch, watch->wd, IN_UNMOUNT, 0, | 454 | ih->in_ops->handle_event(watch, watch->wd, IN_UNMOUNT, 0, NULL, NULL); |
450 | NULL, NULL); | ||
451 | inotify_remove_watch_locked(ih, watch); | 455 | inotify_remove_watch_locked(ih, watch); |
452 | mutex_unlock(&ih->mutex); | 456 | mutex_unlock(&ih->mutex); |
453 | put_inotify_watch(watch); | 457 | put_inotify_watch(watch); |
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 80b04770e8e9..3475c2e98c80 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c | |||
@@ -2921,7 +2921,9 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) | |||
2921 | } | 2921 | } |
2922 | if ((sb->s_root = d_alloc_root(vol->root_ino))) { | 2922 | if ((sb->s_root = d_alloc_root(vol->root_ino))) { |
2923 | /* We increment i_count simulating an ntfs_iget(). */ | 2923 | /* We increment i_count simulating an ntfs_iget(). */ |
2924 | atomic_inc(&vol->root_ino->i_count); | 2924 | spin_lock(&vol->root_ino->i_lock); |
2925 | vol->root_ino->i_count++; | ||
2926 | spin_unlock(&vol->root_ino->i_lock); | ||
2925 | ntfs_debug("Exiting, status successful."); | 2927 | ntfs_debug("Exiting, status successful."); |
2926 | /* Release the default upcase if it has no users. */ | 2928 | /* Release the default upcase if it has no users. */ |
2927 | mutex_lock(&ntfs_lock); | 2929 | mutex_lock(&ntfs_lock); |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 50fb26a6a5f5..3d4b7e210bb9 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -719,7 +719,9 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
719 | goto out_commit; | 719 | goto out_commit; |
720 | } | 720 | } |
721 | 721 | ||
722 | atomic_inc(&inode->i_count); | 722 | spin_lock(&inode->i_lock); |
723 | inode->i_count++; | ||
724 | spin_unlock(&inode->i_lock); | ||
723 | dentry->d_op = &ocfs2_dentry_ops; | 725 | dentry->d_op = &ocfs2_dentry_ops; |
724 | d_instantiate(dentry, inode); | 726 | d_instantiate(dentry, inode); |
725 | 727 | ||
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index da2dba082e2d..d3f9b7d05307 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c | |||
@@ -39,7 +39,7 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) | |||
39 | BUG_ON(!S_ISREG(inode->i_mode)); | 39 | BUG_ON(!S_ISREG(inode->i_mode)); |
40 | 40 | ||
41 | /* fast out for when nothing needs to be done */ | 41 | /* fast out for when nothing needs to be done */ |
42 | if ((atomic_read(&inode->i_count) > 1 || | 42 | if ((inode->i_count > 1 || |
43 | !(REISERFS_I(inode)->i_flags & i_pack_on_close_mask) || | 43 | !(REISERFS_I(inode)->i_flags & i_pack_on_close_mask) || |
44 | !tail_has_to_be_packed(inode)) && | 44 | !tail_has_to_be_packed(inode)) && |
45 | REISERFS_I(inode)->i_prealloc_count <= 0) { | 45 | REISERFS_I(inode)->i_prealloc_count <= 0) { |
@@ -94,7 +94,7 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) | |||
94 | if (!err) | 94 | if (!err) |
95 | err = jbegin_failure; | 95 | err = jbegin_failure; |
96 | 96 | ||
97 | if (!err && atomic_read(&inode->i_count) <= 1 && | 97 | if (!err && inode->i_count <= 1 && |
98 | (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) && | 98 | (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) && |
99 | tail_has_to_be_packed(inode)) { | 99 | tail_has_to_be_packed(inode)) { |
100 | /* if regular file is released by last holder and it has been | 100 | /* if regular file is released by last holder and it has been |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 9d4dcf0b07cb..05b3240ed9ab 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -1151,7 +1151,9 @@ static int reiserfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1151 | inode->i_ctime = CURRENT_TIME_SEC; | 1151 | inode->i_ctime = CURRENT_TIME_SEC; |
1152 | reiserfs_update_sd(&th, inode); | 1152 | reiserfs_update_sd(&th, inode); |
1153 | 1153 | ||
1154 | atomic_inc(&inode->i_count); | 1154 | spin_lock(&inode->i_lock); |
1155 | inode->i_count++; | ||
1156 | spin_unlock(&inode->i_lock); | ||
1155 | d_instantiate(dentry, inode); | 1157 | d_instantiate(dentry, inode); |
1156 | retval = journal_end(&th, dir->i_sb, jbegin_count); | 1158 | retval = journal_end(&th, dir->i_sb, jbegin_count); |
1157 | reiserfs_write_unlock(dir->i_sb); | 1159 | reiserfs_write_unlock(dir->i_sb); |
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c index 5fa7118f04e1..17f52e8bb739 100644 --- a/fs/reiserfs/stree.c +++ b/fs/reiserfs/stree.c | |||
@@ -1477,7 +1477,7 @@ static int maybe_indirect_to_direct(struct reiserfs_transaction_handle *th, | |||
1477 | ** reading in the last block. The user will hit problems trying to | 1477 | ** reading in the last block. The user will hit problems trying to |
1478 | ** read the file, but for now we just skip the indirect2direct | 1478 | ** read the file, but for now we just skip the indirect2direct |
1479 | */ | 1479 | */ |
1480 | if (atomic_read(&inode->i_count) > 1 || | 1480 | if (inode->i_count > 1 || |
1481 | !tail_has_to_be_packed(inode) || | 1481 | !tail_has_to_be_packed(inode) || |
1482 | !page || (REISERFS_I(inode)->i_flags & i_nopack_mask)) { | 1482 | !page || (REISERFS_I(inode)->i_flags & i_nopack_mask)) { |
1483 | /* leave tail in an unformatted node */ | 1483 | /* leave tail in an unformatted node */ |
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index 33e047b59b8d..d63da9be14cc 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c | |||
@@ -126,7 +126,9 @@ static int sysv_link(struct dentry * old_dentry, struct inode * dir, | |||
126 | 126 | ||
127 | inode->i_ctime = CURRENT_TIME_SEC; | 127 | inode->i_ctime = CURRENT_TIME_SEC; |
128 | inode_inc_link_count(inode); | 128 | inode_inc_link_count(inode); |
129 | atomic_inc(&inode->i_count); | 129 | spin_lock(&inode->i_lock); |
130 | inode->i_count++; | ||
131 | spin_unlock(&inode->i_lock); | ||
130 | 132 | ||
131 | return add_nondir(dentry, inode); | 133 | return add_nondir(dentry, inode); |
132 | } | 134 | } |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 552fb0111fff..1eed16ffdd68 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
@@ -557,7 +557,9 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir, | |||
557 | 557 | ||
558 | lock_2_inodes(dir, inode); | 558 | lock_2_inodes(dir, inode); |
559 | inc_nlink(inode); | 559 | inc_nlink(inode); |
560 | atomic_inc(&inode->i_count); | 560 | spin_lock(&inode->i_lock); |
561 | inode->i_count++; | ||
562 | spin_unlock(&inode->i_lock); | ||
561 | inode->i_ctime = ubifs_current_time(inode); | 563 | inode->i_ctime = ubifs_current_time(inode); |
562 | dir->i_size += sz_change; | 564 | dir->i_size += sz_change; |
563 | dir_ui->ui_size = dir->i_size; | 565 | dir_ui->ui_size = dir->i_size; |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 43f9d19a6f33..d020118df827 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -342,7 +342,7 @@ static void ubifs_delete_inode(struct inode *inode) | |||
342 | goto out; | 342 | goto out; |
343 | 343 | ||
344 | dbg_gen("inode %lu, mode %#x", inode->i_ino, (int)inode->i_mode); | 344 | dbg_gen("inode %lu, mode %#x", inode->i_ino, (int)inode->i_mode); |
345 | ubifs_assert(!atomic_read(&inode->i_count)); | 345 | ubifs_assert(!inode->i_count); |
346 | ubifs_assert(inode->i_nlink == 0); | 346 | ubifs_assert(inode->i_nlink == 0); |
347 | 347 | ||
348 | truncate_inode_pages(&inode->i_data, 0); | 348 | truncate_inode_pages(&inode->i_data, 0); |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index cd2115060fdc..9e85540e9e01 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -1108,7 +1108,9 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, | |||
1108 | inc_nlink(inode); | 1108 | inc_nlink(inode); |
1109 | inode->i_ctime = current_fs_time(inode->i_sb); | 1109 | inode->i_ctime = current_fs_time(inode->i_sb); |
1110 | mark_inode_dirty(inode); | 1110 | mark_inode_dirty(inode); |
1111 | atomic_inc(&inode->i_count); | 1111 | spin_lock(&inode->i_lock); |
1112 | inode->i_count++; | ||
1113 | spin_unlock(&inode->i_lock); | ||
1112 | d_instantiate(dentry, inode); | 1114 | d_instantiate(dentry, inode); |
1113 | unlock_kernel(); | 1115 | unlock_kernel(); |
1114 | 1116 | ||
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 4c26d9e8bc94..ece37bbb3ea4 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c | |||
@@ -178,7 +178,9 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir, | |||
178 | 178 | ||
179 | inode->i_ctime = CURRENT_TIME_SEC; | 179 | inode->i_ctime = CURRENT_TIME_SEC; |
180 | inode_inc_link_count(inode); | 180 | inode_inc_link_count(inode); |
181 | atomic_inc(&inode->i_count); | 181 | spin_lock(&inode->i_lock); |
182 | inode->i_count++; | ||
183 | spin_unlock(&inode->i_lock); | ||
182 | 184 | ||
183 | error = ufs_add_nondir(dentry, inode); | 185 | error = ufs_add_nondir(dentry, inode); |
184 | unlock_kernel(); | 186 | unlock_kernel(); |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 225946012d0b..f78e1df5353c 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -349,7 +349,9 @@ xfs_vn_link( | |||
349 | if (unlikely(error)) | 349 | if (unlikely(error)) |
350 | return -error; | 350 | return -error; |
351 | 351 | ||
352 | atomic_inc(&inode->i_count); | 352 | spin_lock(&inode->i_lock); |
353 | inode->i_count++; | ||
354 | spin_unlock(&inode->i_lock); | ||
353 | d_instantiate(dentry, inode); | 355 | d_instantiate(dentry, inode); |
354 | return 0; | 356 | return 0; |
355 | } | 357 | } |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index ec1f28c4fc4f..53a14575bf3b 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -493,8 +493,10 @@ void xfs_mark_inode_dirty_sync(xfs_inode_t *); | |||
493 | 493 | ||
494 | #define IHOLD(ip) \ | 494 | #define IHOLD(ip) \ |
495 | do { \ | 495 | do { \ |
496 | ASSERT(atomic_read(&VFS_I(ip)->i_count) > 0) ; \ | 496 | spin_lock(&VFS_I(ip)->i_lock); \ |
497 | atomic_inc(&(VFS_I(ip)->i_count)); \ | 497 | ASSERT(&VFS_I(ip)->i_count > 0); \ |
498 | VFS_I(ip)->i_count++; \ | ||
499 | spin_unlock(&VFS_I(ip)->i_lock); \ | ||
498 | trace_xfs_ihold(ip, _THIS_IP_); \ | 500 | trace_xfs_ihold(ip, _THIS_IP_); \ |
499 | } while (0) | 501 | } while (0) |
500 | 502 | ||