diff options
Diffstat (limited to 'fs/nilfs2/direct.c')
-rw-r--r-- | fs/nilfs2/direct.c | 161 |
1 files changed, 58 insertions, 103 deletions
diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c index 342d9765df8d..d369ac718277 100644 --- a/fs/nilfs2/direct.c +++ b/fs/nilfs2/direct.c | |||
@@ -125,106 +125,64 @@ static void nilfs_direct_set_target_v(struct nilfs_direct *direct, | |||
125 | direct->d_bmap.b_last_allocated_ptr = ptr; | 125 | direct->d_bmap.b_last_allocated_ptr = ptr; |
126 | } | 126 | } |
127 | 127 | ||
128 | static int nilfs_direct_prepare_insert(struct nilfs_direct *direct, | ||
129 | __u64 key, | ||
130 | union nilfs_bmap_ptr_req *req, | ||
131 | struct nilfs_bmap_stats *stats) | ||
132 | { | ||
133 | int ret; | ||
134 | |||
135 | if (NILFS_BMAP_USE_VBN(&direct->d_bmap)) | ||
136 | req->bpr_ptr = nilfs_direct_find_target_v(direct, key); | ||
137 | ret = nilfs_bmap_prepare_alloc_ptr(&direct->d_bmap, req); | ||
138 | if (ret < 0) | ||
139 | return ret; | ||
140 | |||
141 | stats->bs_nblocks = 1; | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static void nilfs_direct_commit_insert(struct nilfs_direct *direct, | ||
146 | union nilfs_bmap_ptr_req *req, | ||
147 | __u64 key, __u64 ptr) | ||
148 | { | ||
149 | struct buffer_head *bh; | ||
150 | |||
151 | /* ptr must be a pointer to a buffer head. */ | ||
152 | bh = (struct buffer_head *)((unsigned long)ptr); | ||
153 | set_buffer_nilfs_volatile(bh); | ||
154 | |||
155 | nilfs_bmap_commit_alloc_ptr(&direct->d_bmap, req); | ||
156 | nilfs_direct_set_ptr(direct, key, req->bpr_ptr); | ||
157 | |||
158 | if (!nilfs_bmap_dirty(&direct->d_bmap)) | ||
159 | nilfs_bmap_set_dirty(&direct->d_bmap); | ||
160 | |||
161 | if (NILFS_BMAP_USE_VBN(&direct->d_bmap)) | ||
162 | nilfs_direct_set_target_v(direct, key, req->bpr_ptr); | ||
163 | } | ||
164 | |||
165 | static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) | 128 | static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) |
166 | { | 129 | { |
167 | struct nilfs_direct *direct; | 130 | struct nilfs_direct *direct = (struct nilfs_direct *)bmap; |
168 | union nilfs_bmap_ptr_req req; | 131 | union nilfs_bmap_ptr_req req; |
169 | struct nilfs_bmap_stats stats; | 132 | struct inode *dat = NULL; |
133 | struct buffer_head *bh; | ||
170 | int ret; | 134 | int ret; |
171 | 135 | ||
172 | direct = (struct nilfs_direct *)bmap; | ||
173 | if (key > NILFS_DIRECT_KEY_MAX) | 136 | if (key > NILFS_DIRECT_KEY_MAX) |
174 | return -ENOENT; | 137 | return -ENOENT; |
175 | if (nilfs_direct_get_ptr(direct, key) != NILFS_BMAP_INVALID_PTR) | 138 | if (nilfs_direct_get_ptr(direct, key) != NILFS_BMAP_INVALID_PTR) |
176 | return -EEXIST; | 139 | return -EEXIST; |
177 | 140 | ||
178 | ret = nilfs_direct_prepare_insert(direct, key, &req, &stats); | 141 | if (NILFS_BMAP_USE_VBN(bmap)) { |
179 | if (ret < 0) | 142 | req.bpr_ptr = nilfs_direct_find_target_v(direct, key); |
180 | return ret; | 143 | dat = nilfs_bmap_get_dat(bmap); |
181 | nilfs_direct_commit_insert(direct, &req, key, ptr); | 144 | } |
182 | nilfs_bmap_add_blocks(bmap, stats.bs_nblocks); | 145 | ret = nilfs_bmap_prepare_alloc_ptr(bmap, &req, dat); |
146 | if (!ret) { | ||
147 | /* ptr must be a pointer to a buffer head. */ | ||
148 | bh = (struct buffer_head *)((unsigned long)ptr); | ||
149 | set_buffer_nilfs_volatile(bh); | ||
183 | 150 | ||
184 | return 0; | 151 | nilfs_bmap_commit_alloc_ptr(bmap, &req, dat); |
185 | } | 152 | nilfs_direct_set_ptr(direct, key, req.bpr_ptr); |
186 | 153 | ||
187 | static int nilfs_direct_prepare_delete(struct nilfs_direct *direct, | 154 | if (!nilfs_bmap_dirty(bmap)) |
188 | union nilfs_bmap_ptr_req *req, | 155 | nilfs_bmap_set_dirty(bmap); |
189 | __u64 key, | ||
190 | struct nilfs_bmap_stats *stats) | ||
191 | { | ||
192 | int ret; | ||
193 | 156 | ||
194 | req->bpr_ptr = nilfs_direct_get_ptr(direct, key); | 157 | if (NILFS_BMAP_USE_VBN(bmap)) |
195 | ret = nilfs_bmap_prepare_end_ptr(&direct->d_bmap, req); | 158 | nilfs_direct_set_target_v(direct, key, req.bpr_ptr); |
196 | if (!ret) | ||
197 | stats->bs_nblocks = 1; | ||
198 | return ret; | ||
199 | } | ||
200 | 159 | ||
201 | static void nilfs_direct_commit_delete(struct nilfs_direct *direct, | 160 | nilfs_bmap_add_blocks(bmap, 1); |
202 | union nilfs_bmap_ptr_req *req, | 161 | } |
203 | __u64 key) | 162 | return ret; |
204 | { | ||
205 | nilfs_bmap_commit_end_ptr(&direct->d_bmap, req); | ||
206 | nilfs_direct_set_ptr(direct, key, NILFS_BMAP_INVALID_PTR); | ||
207 | } | 163 | } |
208 | 164 | ||
209 | static int nilfs_direct_delete(struct nilfs_bmap *bmap, __u64 key) | 165 | static int nilfs_direct_delete(struct nilfs_bmap *bmap, __u64 key) |
210 | { | 166 | { |
211 | struct nilfs_direct *direct; | 167 | struct nilfs_direct *direct = (struct nilfs_direct *)bmap; |
212 | union nilfs_bmap_ptr_req req; | 168 | union nilfs_bmap_ptr_req req; |
213 | struct nilfs_bmap_stats stats; | 169 | struct inode *dat; |
214 | int ret; | 170 | int ret; |
215 | 171 | ||
216 | direct = (struct nilfs_direct *)bmap; | 172 | if (key > NILFS_DIRECT_KEY_MAX || |
217 | if ((key > NILFS_DIRECT_KEY_MAX) || | ||
218 | nilfs_direct_get_ptr(direct, key) == NILFS_BMAP_INVALID_PTR) | 173 | nilfs_direct_get_ptr(direct, key) == NILFS_BMAP_INVALID_PTR) |
219 | return -ENOENT; | 174 | return -ENOENT; |
220 | 175 | ||
221 | ret = nilfs_direct_prepare_delete(direct, &req, key, &stats); | 176 | dat = NILFS_BMAP_USE_VBN(bmap) ? nilfs_bmap_get_dat(bmap) : NULL; |
222 | if (ret < 0) | 177 | req.bpr_ptr = nilfs_direct_get_ptr(direct, key); |
223 | return ret; | ||
224 | nilfs_direct_commit_delete(direct, &req, key); | ||
225 | nilfs_bmap_sub_blocks(bmap, stats.bs_nblocks); | ||
226 | 178 | ||
227 | return 0; | 179 | ret = nilfs_bmap_prepare_end_ptr(bmap, &req, dat); |
180 | if (!ret) { | ||
181 | nilfs_bmap_commit_end_ptr(bmap, &req, dat); | ||
182 | nilfs_direct_set_ptr(direct, key, NILFS_BMAP_INVALID_PTR); | ||
183 | nilfs_bmap_sub_blocks(bmap, 1); | ||
184 | } | ||
185 | return ret; | ||
228 | } | 186 | } |
229 | 187 | ||
230 | static int nilfs_direct_last_key(const struct nilfs_bmap *bmap, __u64 *keyp) | 188 | static int nilfs_direct_last_key(const struct nilfs_bmap *bmap, __u64 *keyp) |
@@ -310,59 +268,56 @@ int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap, | |||
310 | return 0; | 268 | return 0; |
311 | } | 269 | } |
312 | 270 | ||
313 | static int nilfs_direct_propagate_v(struct nilfs_direct *direct, | 271 | static int nilfs_direct_propagate(const struct nilfs_bmap *bmap, |
314 | struct buffer_head *bh) | 272 | struct buffer_head *bh) |
315 | { | 273 | { |
316 | union nilfs_bmap_ptr_req oldreq, newreq; | 274 | struct nilfs_direct *direct = (struct nilfs_direct *)bmap; |
275 | struct nilfs_palloc_req oldreq, newreq; | ||
276 | struct inode *dat; | ||
317 | __u64 key; | 277 | __u64 key; |
318 | __u64 ptr; | 278 | __u64 ptr; |
319 | int ret; | 279 | int ret; |
320 | 280 | ||
321 | key = nilfs_bmap_data_get_key(&direct->d_bmap, bh); | 281 | if (!NILFS_BMAP_USE_VBN(bmap)) |
282 | return 0; | ||
283 | |||
284 | dat = nilfs_bmap_get_dat(bmap); | ||
285 | key = nilfs_bmap_data_get_key(bmap, bh); | ||
322 | ptr = nilfs_direct_get_ptr(direct, key); | 286 | ptr = nilfs_direct_get_ptr(direct, key); |
323 | if (!buffer_nilfs_volatile(bh)) { | 287 | if (!buffer_nilfs_volatile(bh)) { |
324 | oldreq.bpr_ptr = ptr; | 288 | oldreq.pr_entry_nr = ptr; |
325 | newreq.bpr_ptr = ptr; | 289 | newreq.pr_entry_nr = ptr; |
326 | ret = nilfs_bmap_prepare_update_v(&direct->d_bmap, &oldreq, | 290 | ret = nilfs_dat_prepare_update(dat, &oldreq, &newreq); |
327 | &newreq); | ||
328 | if (ret < 0) | 291 | if (ret < 0) |
329 | return ret; | 292 | return ret; |
330 | nilfs_bmap_commit_update_v(&direct->d_bmap, &oldreq, &newreq); | 293 | nilfs_dat_commit_update(dat, &oldreq, &newreq, |
294 | bmap->b_ptr_type == NILFS_BMAP_PTR_VS); | ||
331 | set_buffer_nilfs_volatile(bh); | 295 | set_buffer_nilfs_volatile(bh); |
332 | nilfs_direct_set_ptr(direct, key, newreq.bpr_ptr); | 296 | nilfs_direct_set_ptr(direct, key, newreq.pr_entry_nr); |
333 | } else | 297 | } else |
334 | ret = nilfs_bmap_mark_dirty(&direct->d_bmap, ptr); | 298 | ret = nilfs_dat_mark_dirty(dat, ptr); |
335 | 299 | ||
336 | return ret; | 300 | return ret; |
337 | } | 301 | } |
338 | 302 | ||
339 | static int nilfs_direct_propagate(const struct nilfs_bmap *bmap, | ||
340 | struct buffer_head *bh) | ||
341 | { | ||
342 | struct nilfs_direct *direct = (struct nilfs_direct *)bmap; | ||
343 | |||
344 | return NILFS_BMAP_USE_VBN(bmap) ? | ||
345 | nilfs_direct_propagate_v(direct, bh) : 0; | ||
346 | } | ||
347 | |||
348 | static int nilfs_direct_assign_v(struct nilfs_direct *direct, | 303 | static int nilfs_direct_assign_v(struct nilfs_direct *direct, |
349 | __u64 key, __u64 ptr, | 304 | __u64 key, __u64 ptr, |
350 | struct buffer_head **bh, | 305 | struct buffer_head **bh, |
351 | sector_t blocknr, | 306 | sector_t blocknr, |
352 | union nilfs_binfo *binfo) | 307 | union nilfs_binfo *binfo) |
353 | { | 308 | { |
309 | struct inode *dat = nilfs_bmap_get_dat(&direct->d_bmap); | ||
354 | union nilfs_bmap_ptr_req req; | 310 | union nilfs_bmap_ptr_req req; |
355 | int ret; | 311 | int ret; |
356 | 312 | ||
357 | req.bpr_ptr = ptr; | 313 | req.bpr_ptr = ptr; |
358 | ret = nilfs_bmap_start_v(&direct->d_bmap, &req, blocknr); | 314 | ret = nilfs_dat_prepare_start(dat, &req.bpr_req); |
359 | if (unlikely(ret < 0)) | 315 | if (!ret) { |
360 | return ret; | 316 | nilfs_dat_commit_start(dat, &req.bpr_req, blocknr); |
361 | 317 | binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr); | |
362 | binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr); | 318 | binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key); |
363 | binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key); | 319 | } |
364 | 320 | return ret; | |
365 | return 0; | ||
366 | } | 321 | } |
367 | 322 | ||
368 | static int nilfs_direct_assign_p(struct nilfs_direct *direct, | 323 | static int nilfs_direct_assign_p(struct nilfs_direct *direct, |