aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/the_nilfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2/the_nilfs.c')
-rw-r--r--fs/nilfs2/the_nilfs.c75
1 files changed, 5 insertions, 70 deletions
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index 960c28797bb2..6eeb4f072f83 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -35,9 +35,6 @@
35#include "segbuf.h" 35#include "segbuf.h"
36 36
37 37
38static LIST_HEAD(nilfs_objects);
39static DEFINE_SPINLOCK(nilfs_lock);
40
41static int nilfs_valid_sb(struct nilfs_super_block *sbp); 38static int nilfs_valid_sb(struct nilfs_super_block *sbp);
42 39
43void nilfs_set_last_segment(struct the_nilfs *nilfs, 40void nilfs_set_last_segment(struct the_nilfs *nilfs,
@@ -61,16 +58,13 @@ void nilfs_set_last_segment(struct the_nilfs *nilfs,
61} 58}
62 59
63/** 60/**
64 * alloc_nilfs - allocate the_nilfs structure 61 * alloc_nilfs - allocate a nilfs object
65 * @bdev: block device to which the_nilfs is related 62 * @bdev: block device to which the_nilfs is related
66 * 63 *
67 * alloc_nilfs() allocates memory for the_nilfs and
68 * initializes its reference count and locks.
69 *
70 * Return Value: On success, pointer to the_nilfs is returned. 64 * Return Value: On success, pointer to the_nilfs is returned.
71 * On error, NULL is returned. 65 * On error, NULL is returned.
72 */ 66 */
73static struct the_nilfs *alloc_nilfs(struct block_device *bdev) 67struct the_nilfs *alloc_nilfs(struct block_device *bdev)
74{ 68{
75 struct the_nilfs *nilfs; 69 struct the_nilfs *nilfs;
76 70
@@ -79,12 +73,9 @@ static struct the_nilfs *alloc_nilfs(struct block_device *bdev)
79 return NULL; 73 return NULL;
80 74
81 nilfs->ns_bdev = bdev; 75 nilfs->ns_bdev = bdev;
82 atomic_set(&nilfs->ns_count, 1);
83 atomic_set(&nilfs->ns_ndirtyblks, 0); 76 atomic_set(&nilfs->ns_ndirtyblks, 0);
84 init_rwsem(&nilfs->ns_sem); 77 init_rwsem(&nilfs->ns_sem);
85 mutex_init(&nilfs->ns_mount_mutex);
86 init_rwsem(&nilfs->ns_writer_sem); 78 init_rwsem(&nilfs->ns_writer_sem);
87 INIT_LIST_HEAD(&nilfs->ns_list);
88 INIT_LIST_HEAD(&nilfs->ns_gc_inodes); 79 INIT_LIST_HEAD(&nilfs->ns_gc_inodes);
89 spin_lock_init(&nilfs->ns_last_segment_lock); 80 spin_lock_init(&nilfs->ns_last_segment_lock);
90 nilfs->ns_cptree = RB_ROOT; 81 nilfs->ns_cptree = RB_ROOT;
@@ -95,67 +86,11 @@ static struct the_nilfs *alloc_nilfs(struct block_device *bdev)
95} 86}
96 87
97/** 88/**
98 * find_or_create_nilfs - find or create nilfs object 89 * destroy_nilfs - destroy nilfs object
99 * @bdev: block device to which the_nilfs is related 90 * @nilfs: nilfs object to be released
100 *
101 * find_nilfs() looks up an existent nilfs object created on the
102 * device and gets the reference count of the object. If no nilfs object
103 * is found on the device, a new nilfs object is allocated.
104 *
105 * Return Value: On success, pointer to the nilfs object is returned.
106 * On error, NULL is returned.
107 */
108struct the_nilfs *find_or_create_nilfs(struct block_device *bdev)
109{
110 struct the_nilfs *nilfs, *new = NULL;
111
112 retry:
113 spin_lock(&nilfs_lock);
114 list_for_each_entry(nilfs, &nilfs_objects, ns_list) {
115 if (nilfs->ns_bdev == bdev) {
116 get_nilfs(nilfs);
117 spin_unlock(&nilfs_lock);
118 if (new)
119 put_nilfs(new);
120 return nilfs; /* existing object */
121 }
122 }
123 if (new) {
124 list_add_tail(&new->ns_list, &nilfs_objects);
125 spin_unlock(&nilfs_lock);
126 return new; /* new object */
127 }
128 spin_unlock(&nilfs_lock);
129
130 new = alloc_nilfs(bdev);
131 if (new)
132 goto retry;
133 return NULL; /* insufficient memory */
134}
135
136/**
137 * put_nilfs - release a reference to the_nilfs
138 * @nilfs: the_nilfs structure to be released
139 *
140 * put_nilfs() decrements a reference counter of the_nilfs.
141 * If the reference count reaches zero, the_nilfs is freed.
142 */ 91 */
143void put_nilfs(struct the_nilfs *nilfs) 92void destroy_nilfs(struct the_nilfs *nilfs)
144{ 93{
145 spin_lock(&nilfs_lock);
146 if (!atomic_dec_and_test(&nilfs->ns_count)) {
147 spin_unlock(&nilfs_lock);
148 return;
149 }
150 list_del_init(&nilfs->ns_list);
151 spin_unlock(&nilfs_lock);
152
153 /*
154 * Increment of ns_count never occurs below because the caller
155 * of get_nilfs() holds at least one reference to the_nilfs.
156 * Thus its exclusion control is not required here.
157 */
158
159 might_sleep(); 94 might_sleep();
160 if (nilfs_loaded(nilfs)) { 95 if (nilfs_loaded(nilfs)) {
161 nilfs_mdt_destroy(nilfs->ns_sufile); 96 nilfs_mdt_destroy(nilfs->ns_sufile);