diff options
Diffstat (limited to 'fs/nilfs2')
-rw-r--r-- | fs/nilfs2/mdt.c | 8 | ||||
-rw-r--r-- | fs/nilfs2/the_nilfs.c | 3 | ||||
-rw-r--r-- | fs/nilfs2/the_nilfs.h | 27 |
3 files changed, 12 insertions, 26 deletions
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c index 2dfd47714ae5..a5cd80162dc5 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c | |||
@@ -402,6 +402,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) | |||
402 | struct inode *inode = container_of(page->mapping, | 402 | struct inode *inode = container_of(page->mapping, |
403 | struct inode, i_data); | 403 | struct inode, i_data); |
404 | struct super_block *sb = inode->i_sb; | 404 | struct super_block *sb = inode->i_sb; |
405 | struct the_nilfs *nilfs = NILFS_MDT(inode)->mi_nilfs; | ||
405 | struct nilfs_sb_info *writer = NULL; | 406 | struct nilfs_sb_info *writer = NULL; |
406 | int err = 0; | 407 | int err = 0; |
407 | 408 | ||
@@ -411,9 +412,10 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) | |||
411 | if (page->mapping->assoc_mapping) | 412 | if (page->mapping->assoc_mapping) |
412 | return 0; /* Do not request flush for shadow page cache */ | 413 | return 0; /* Do not request flush for shadow page cache */ |
413 | if (!sb) { | 414 | if (!sb) { |
414 | writer = nilfs_get_writer(NILFS_MDT(inode)->mi_nilfs); | 415 | down_read(&nilfs->ns_writer_sem); |
416 | writer = nilfs->ns_writer; | ||
415 | if (!writer) { | 417 | if (!writer) { |
416 | nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs); | 418 | up_read(&nilfs->ns_writer_sem); |
417 | return -EROFS; | 419 | return -EROFS; |
418 | } | 420 | } |
419 | sb = writer->s_super; | 421 | sb = writer->s_super; |
@@ -425,7 +427,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) | |||
425 | nilfs_flush_segment(sb, inode->i_ino); | 427 | nilfs_flush_segment(sb, inode->i_ino); |
426 | 428 | ||
427 | if (writer) | 429 | if (writer) |
428 | nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs); | 430 | up_read(&nilfs->ns_writer_sem); |
429 | return err; | 431 | return err; |
430 | } | 432 | } |
431 | 433 | ||
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 8b8889825716..0c4573653b87 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c | |||
@@ -68,12 +68,11 @@ static struct the_nilfs *alloc_nilfs(struct block_device *bdev) | |||
68 | 68 | ||
69 | nilfs->ns_bdev = bdev; | 69 | nilfs->ns_bdev = bdev; |
70 | atomic_set(&nilfs->ns_count, 1); | 70 | atomic_set(&nilfs->ns_count, 1); |
71 | atomic_set(&nilfs->ns_writer_refcount, -1); | ||
72 | atomic_set(&nilfs->ns_ndirtyblks, 0); | 71 | atomic_set(&nilfs->ns_ndirtyblks, 0); |
73 | init_rwsem(&nilfs->ns_sem); | 72 | init_rwsem(&nilfs->ns_sem); |
74 | init_rwsem(&nilfs->ns_super_sem); | 73 | init_rwsem(&nilfs->ns_super_sem); |
75 | mutex_init(&nilfs->ns_mount_mutex); | 74 | mutex_init(&nilfs->ns_mount_mutex); |
76 | mutex_init(&nilfs->ns_writer_mutex); | 75 | init_rwsem(&nilfs->ns_writer_sem); |
77 | INIT_LIST_HEAD(&nilfs->ns_list); | 76 | INIT_LIST_HEAD(&nilfs->ns_list); |
78 | INIT_LIST_HEAD(&nilfs->ns_supers); | 77 | INIT_LIST_HEAD(&nilfs->ns_supers); |
79 | spin_lock_init(&nilfs->ns_last_segment_lock); | 78 | spin_lock_init(&nilfs->ns_last_segment_lock); |
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h index 1b9caafb8662..fa3a1dfe4053 100644 --- a/fs/nilfs2/the_nilfs.h +++ b/fs/nilfs2/the_nilfs.h | |||
@@ -50,8 +50,7 @@ enum { | |||
50 | * @ns_sem: semaphore for shared states | 50 | * @ns_sem: semaphore for shared states |
51 | * @ns_super_sem: semaphore for global operations across super block instances | 51 | * @ns_super_sem: semaphore for global operations across super block instances |
52 | * @ns_mount_mutex: mutex protecting mount process of nilfs | 52 | * @ns_mount_mutex: mutex protecting mount process of nilfs |
53 | * @ns_writer_mutex: mutex protecting ns_writer attach/detach | 53 | * @ns_writer_sem: semaphore protecting ns_writer attach/detach |
54 | * @ns_writer_refcount: number of referrers on ns_writer | ||
55 | * @ns_current: back pointer to current mount | 54 | * @ns_current: back pointer to current mount |
56 | * @ns_sbh: buffer heads of on-disk super blocks | 55 | * @ns_sbh: buffer heads of on-disk super blocks |
57 | * @ns_sbp: pointers to super block data | 56 | * @ns_sbp: pointers to super block data |
@@ -100,8 +99,7 @@ struct the_nilfs { | |||
100 | struct rw_semaphore ns_sem; | 99 | struct rw_semaphore ns_sem; |
101 | struct rw_semaphore ns_super_sem; | 100 | struct rw_semaphore ns_super_sem; |
102 | struct mutex ns_mount_mutex; | 101 | struct mutex ns_mount_mutex; |
103 | struct mutex ns_writer_mutex; | 102 | struct rw_semaphore ns_writer_sem; |
104 | atomic_t ns_writer_refcount; | ||
105 | 103 | ||
106 | /* | 104 | /* |
107 | * components protected by ns_super_sem | 105 | * components protected by ns_super_sem |
@@ -221,34 +219,21 @@ static inline void get_nilfs(struct the_nilfs *nilfs) | |||
221 | atomic_inc(&nilfs->ns_count); | 219 | atomic_inc(&nilfs->ns_count); |
222 | } | 220 | } |
223 | 221 | ||
224 | static inline struct nilfs_sb_info *nilfs_get_writer(struct the_nilfs *nilfs) | ||
225 | { | ||
226 | if (atomic_inc_and_test(&nilfs->ns_writer_refcount)) | ||
227 | mutex_lock(&nilfs->ns_writer_mutex); | ||
228 | return nilfs->ns_writer; | ||
229 | } | ||
230 | |||
231 | static inline void nilfs_put_writer(struct the_nilfs *nilfs) | ||
232 | { | ||
233 | if (atomic_add_negative(-1, &nilfs->ns_writer_refcount)) | ||
234 | mutex_unlock(&nilfs->ns_writer_mutex); | ||
235 | } | ||
236 | |||
237 | static inline void | 222 | static inline void |
238 | nilfs_attach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) | 223 | nilfs_attach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) |
239 | { | 224 | { |
240 | mutex_lock(&nilfs->ns_writer_mutex); | 225 | down_write(&nilfs->ns_writer_sem); |
241 | nilfs->ns_writer = sbi; | 226 | nilfs->ns_writer = sbi; |
242 | mutex_unlock(&nilfs->ns_writer_mutex); | 227 | up_write(&nilfs->ns_writer_sem); |
243 | } | 228 | } |
244 | 229 | ||
245 | static inline void | 230 | static inline void |
246 | nilfs_detach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) | 231 | nilfs_detach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) |
247 | { | 232 | { |
248 | mutex_lock(&nilfs->ns_writer_mutex); | 233 | down_write(&nilfs->ns_writer_sem); |
249 | if (sbi == nilfs->ns_writer) | 234 | if (sbi == nilfs->ns_writer) |
250 | nilfs->ns_writer = NULL; | 235 | nilfs->ns_writer = NULL; |
251 | mutex_unlock(&nilfs->ns_writer_mutex); | 236 | up_write(&nilfs->ns_writer_sem); |
252 | } | 237 | } |
253 | 238 | ||
254 | static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi) | 239 | static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi) |