aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2')
-rw-r--r--fs/nilfs2/mdt.c8
-rw-r--r--fs/nilfs2/the_nilfs.c3
-rw-r--r--fs/nilfs2/the_nilfs.h27
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
224static 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
231static 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
237static inline void 222static inline void
238nilfs_attach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) 223nilfs_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
245static inline void 230static inline void
246nilfs_detach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) 231nilfs_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
254static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi) 239static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi)