aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/the_nilfs.c
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2009-06-07 12:39:29 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2009-06-11 21:36:17 -0400
commit33c8e57c86d1bd1548c12a4f7c4bceb94b862cca (patch)
tree8e2052a81dc1036e64d78da1082ab6af01ae4bbd /fs/nilfs2/the_nilfs.c
parent81fc20bd0e75ba6357bce2403767d7c2585d8f28 (diff)
nilfs2: get rid of sget use for acquiring nilfs object
This will change the way to obtain nilfs object in nilfs_get_sb() function. Previously, a preliminary sget() call was performed, and the nilfs object was acquired from a super block instance found by the sget() call. This patch, instead, instroduces a new dedicated function find_or_create_nilfs(); as the name implies, the function finds an existent nilfs object from a global list or creates a new one if no object is found on the device. Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/nilfs2/the_nilfs.c')
-rw-r--r--fs/nilfs2/the_nilfs.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index a91f15b8673c..45dbf6a61744 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -35,6 +35,10 @@
35#include "seglist.h" 35#include "seglist.h"
36#include "segbuf.h" 36#include "segbuf.h"
37 37
38
39static LIST_HEAD(nilfs_objects);
40static DEFINE_SPINLOCK(nilfs_lock);
41
38void nilfs_set_last_segment(struct the_nilfs *nilfs, 42void nilfs_set_last_segment(struct the_nilfs *nilfs,
39 sector_t start_blocknr, u64 seq, __u64 cno) 43 sector_t start_blocknr, u64 seq, __u64 cno)
40{ 44{
@@ -55,7 +59,7 @@ void nilfs_set_last_segment(struct the_nilfs *nilfs,
55 * Return Value: On success, pointer to the_nilfs is returned. 59 * Return Value: On success, pointer to the_nilfs is returned.
56 * On error, NULL is returned. 60 * On error, NULL is returned.
57 */ 61 */
58struct the_nilfs *alloc_nilfs(struct block_device *bdev) 62static struct the_nilfs *alloc_nilfs(struct block_device *bdev)
59{ 63{
60 struct the_nilfs *nilfs; 64 struct the_nilfs *nilfs;
61 65
@@ -69,6 +73,7 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev)
69 atomic_set(&nilfs->ns_ndirtyblks, 0); 73 atomic_set(&nilfs->ns_ndirtyblks, 0);
70 init_rwsem(&nilfs->ns_sem); 74 init_rwsem(&nilfs->ns_sem);
71 mutex_init(&nilfs->ns_writer_mutex); 75 mutex_init(&nilfs->ns_writer_mutex);
76 INIT_LIST_HEAD(&nilfs->ns_list);
72 INIT_LIST_HEAD(&nilfs->ns_supers); 77 INIT_LIST_HEAD(&nilfs->ns_supers);
73 spin_lock_init(&nilfs->ns_last_segment_lock); 78 spin_lock_init(&nilfs->ns_last_segment_lock);
74 nilfs->ns_gc_inodes_h = NULL; 79 nilfs->ns_gc_inodes_h = NULL;
@@ -78,6 +83,45 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev)
78} 83}
79 84
80/** 85/**
86 * find_or_create_nilfs - find or create nilfs object
87 * @bdev: block device to which the_nilfs is related
88 *
89 * find_nilfs() looks up an existent nilfs object created on the
90 * device and gets the reference count of the object. If no nilfs object
91 * is found on the device, a new nilfs object is allocated.
92 *
93 * Return Value: On success, pointer to the nilfs object is returned.
94 * On error, NULL is returned.
95 */
96struct the_nilfs *find_or_create_nilfs(struct block_device *bdev)
97{
98 struct the_nilfs *nilfs, *new = NULL;
99
100 retry:
101 spin_lock(&nilfs_lock);
102 list_for_each_entry(nilfs, &nilfs_objects, ns_list) {
103 if (nilfs->ns_bdev == bdev) {
104 get_nilfs(nilfs);
105 spin_unlock(&nilfs_lock);
106 if (new)
107 put_nilfs(new);
108 return nilfs; /* existing object */
109 }
110 }
111 if (new) {
112 list_add_tail(&new->ns_list, &nilfs_objects);
113 spin_unlock(&nilfs_lock);
114 return new; /* new object */
115 }
116 spin_unlock(&nilfs_lock);
117
118 new = alloc_nilfs(bdev);
119 if (new)
120 goto retry;
121 return NULL; /* insufficient memory */
122}
123
124/**
81 * put_nilfs - release a reference to the_nilfs 125 * put_nilfs - release a reference to the_nilfs
82 * @nilfs: the_nilfs structure to be released 126 * @nilfs: the_nilfs structure to be released
83 * 127 *
@@ -86,13 +130,20 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev)
86 */ 130 */
87void put_nilfs(struct the_nilfs *nilfs) 131void put_nilfs(struct the_nilfs *nilfs)
88{ 132{
89 if (!atomic_dec_and_test(&nilfs->ns_count)) 133 spin_lock(&nilfs_lock);
134 if (!atomic_dec_and_test(&nilfs->ns_count)) {
135 spin_unlock(&nilfs_lock);
90 return; 136 return;
137 }
138 list_del_init(&nilfs->ns_list);
139 spin_unlock(&nilfs_lock);
140
91 /* 141 /*
92 * Increment of ns_count never occur below because the caller 142 * Increment of ns_count never occurs below because the caller
93 * of get_nilfs() holds at least one reference to the_nilfs. 143 * of get_nilfs() holds at least one reference to the_nilfs.
94 * Thus its exclusion control is not required here. 144 * Thus its exclusion control is not required here.
95 */ 145 */
146
96 might_sleep(); 147 might_sleep();
97 if (nilfs_loaded(nilfs)) { 148 if (nilfs_loaded(nilfs)) {
98 nilfs_mdt_clear(nilfs->ns_sufile); 149 nilfs_mdt_clear(nilfs->ns_sufile);