diff options
Diffstat (limited to 'fs/nilfs2/direct.c')
-rw-r--r-- | fs/nilfs2/direct.c | 139 |
1 files changed, 69 insertions, 70 deletions
diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c index c6379e482781..342d9765df8d 100644 --- a/fs/nilfs2/direct.c +++ b/fs/nilfs2/direct.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "page.h" | 25 | #include "page.h" |
26 | #include "direct.h" | 26 | #include "direct.h" |
27 | #include "alloc.h" | 27 | #include "alloc.h" |
28 | #include "dat.h" | ||
28 | 29 | ||
29 | static inline __le64 *nilfs_direct_dptrs(const struct nilfs_direct *direct) | 30 | static inline __le64 *nilfs_direct_dptrs(const struct nilfs_direct *direct) |
30 | { | 31 | { |
@@ -62,6 +63,47 @@ static int nilfs_direct_lookup(const struct nilfs_bmap *bmap, | |||
62 | return 0; | 63 | return 0; |
63 | } | 64 | } |
64 | 65 | ||
66 | static int nilfs_direct_lookup_contig(const struct nilfs_bmap *bmap, | ||
67 | __u64 key, __u64 *ptrp, | ||
68 | unsigned maxblocks) | ||
69 | { | ||
70 | struct nilfs_direct *direct = (struct nilfs_direct *)bmap; | ||
71 | struct inode *dat = NULL; | ||
72 | __u64 ptr, ptr2; | ||
73 | sector_t blocknr; | ||
74 | int ret, cnt; | ||
75 | |||
76 | if (key > NILFS_DIRECT_KEY_MAX || | ||
77 | (ptr = nilfs_direct_get_ptr(direct, key)) == | ||
78 | NILFS_BMAP_INVALID_PTR) | ||
79 | return -ENOENT; | ||
80 | |||
81 | if (NILFS_BMAP_USE_VBN(bmap)) { | ||
82 | dat = nilfs_bmap_get_dat(bmap); | ||
83 | ret = nilfs_dat_translate(dat, ptr, &blocknr); | ||
84 | if (ret < 0) | ||
85 | return ret; | ||
86 | ptr = blocknr; | ||
87 | } | ||
88 | |||
89 | maxblocks = min_t(unsigned, maxblocks, NILFS_DIRECT_KEY_MAX - key + 1); | ||
90 | for (cnt = 1; cnt < maxblocks && | ||
91 | (ptr2 = nilfs_direct_get_ptr(direct, key + cnt)) != | ||
92 | NILFS_BMAP_INVALID_PTR; | ||
93 | cnt++) { | ||
94 | if (dat) { | ||
95 | ret = nilfs_dat_translate(dat, ptr2, &blocknr); | ||
96 | if (ret < 0) | ||
97 | return ret; | ||
98 | ptr2 = blocknr; | ||
99 | } | ||
100 | if (ptr2 != ptr + cnt) | ||
101 | break; | ||
102 | } | ||
103 | *ptrp = ptr; | ||
104 | return cnt; | ||
105 | } | ||
106 | |||
65 | static __u64 | 107 | static __u64 |
66 | nilfs_direct_find_target_v(const struct nilfs_direct *direct, __u64 key) | 108 | nilfs_direct_find_target_v(const struct nilfs_direct *direct, __u64 key) |
67 | { | 109 | { |
@@ -90,10 +132,9 @@ static int nilfs_direct_prepare_insert(struct nilfs_direct *direct, | |||
90 | { | 132 | { |
91 | int ret; | 133 | int ret; |
92 | 134 | ||
93 | if (direct->d_ops->dop_find_target != NULL) | 135 | if (NILFS_BMAP_USE_VBN(&direct->d_bmap)) |
94 | req->bpr_ptr = direct->d_ops->dop_find_target(direct, key); | 136 | req->bpr_ptr = nilfs_direct_find_target_v(direct, key); |
95 | ret = direct->d_bmap.b_pops->bpop_prepare_alloc_ptr(&direct->d_bmap, | 137 | ret = nilfs_bmap_prepare_alloc_ptr(&direct->d_bmap, req); |
96 | req); | ||
97 | if (ret < 0) | 138 | if (ret < 0) |
98 | return ret; | 139 | return ret; |
99 | 140 | ||
@@ -111,16 +152,14 @@ static void nilfs_direct_commit_insert(struct nilfs_direct *direct, | |||
111 | bh = (struct buffer_head *)((unsigned long)ptr); | 152 | bh = (struct buffer_head *)((unsigned long)ptr); |
112 | set_buffer_nilfs_volatile(bh); | 153 | set_buffer_nilfs_volatile(bh); |
113 | 154 | ||
114 | if (direct->d_bmap.b_pops->bpop_commit_alloc_ptr != NULL) | 155 | nilfs_bmap_commit_alloc_ptr(&direct->d_bmap, req); |
115 | direct->d_bmap.b_pops->bpop_commit_alloc_ptr( | ||
116 | &direct->d_bmap, req); | ||
117 | nilfs_direct_set_ptr(direct, key, req->bpr_ptr); | 156 | nilfs_direct_set_ptr(direct, key, req->bpr_ptr); |
118 | 157 | ||
119 | if (!nilfs_bmap_dirty(&direct->d_bmap)) | 158 | if (!nilfs_bmap_dirty(&direct->d_bmap)) |
120 | nilfs_bmap_set_dirty(&direct->d_bmap); | 159 | nilfs_bmap_set_dirty(&direct->d_bmap); |
121 | 160 | ||
122 | if (direct->d_ops->dop_set_target != NULL) | 161 | if (NILFS_BMAP_USE_VBN(&direct->d_bmap)) |
123 | direct->d_ops->dop_set_target(direct, key, req->bpr_ptr); | 162 | nilfs_direct_set_target_v(direct, key, req->bpr_ptr); |
124 | } | 163 | } |
125 | 164 | ||
126 | static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) | 165 | static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) |
@@ -152,25 +191,18 @@ static int nilfs_direct_prepare_delete(struct nilfs_direct *direct, | |||
152 | { | 191 | { |
153 | int ret; | 192 | int ret; |
154 | 193 | ||
155 | if (direct->d_bmap.b_pops->bpop_prepare_end_ptr != NULL) { | 194 | req->bpr_ptr = nilfs_direct_get_ptr(direct, key); |
156 | req->bpr_ptr = nilfs_direct_get_ptr(direct, key); | 195 | ret = nilfs_bmap_prepare_end_ptr(&direct->d_bmap, req); |
157 | ret = direct->d_bmap.b_pops->bpop_prepare_end_ptr( | 196 | if (!ret) |
158 | &direct->d_bmap, req); | 197 | stats->bs_nblocks = 1; |
159 | if (ret < 0) | 198 | return ret; |
160 | return ret; | ||
161 | } | ||
162 | |||
163 | stats->bs_nblocks = 1; | ||
164 | return 0; | ||
165 | } | 199 | } |
166 | 200 | ||
167 | static void nilfs_direct_commit_delete(struct nilfs_direct *direct, | 201 | static void nilfs_direct_commit_delete(struct nilfs_direct *direct, |
168 | union nilfs_bmap_ptr_req *req, | 202 | union nilfs_bmap_ptr_req *req, |
169 | __u64 key) | 203 | __u64 key) |
170 | { | 204 | { |
171 | if (direct->d_bmap.b_pops->bpop_commit_end_ptr != NULL) | 205 | nilfs_bmap_commit_end_ptr(&direct->d_bmap, req); |
172 | direct->d_bmap.b_pops->bpop_commit_end_ptr( | ||
173 | &direct->d_bmap, req); | ||
174 | nilfs_direct_set_ptr(direct, key, NILFS_BMAP_INVALID_PTR); | 206 | nilfs_direct_set_ptr(direct, key, NILFS_BMAP_INVALID_PTR); |
175 | } | 207 | } |
176 | 208 | ||
@@ -244,8 +276,7 @@ static int nilfs_direct_gather_data(struct nilfs_bmap *bmap, | |||
244 | } | 276 | } |
245 | 277 | ||
246 | int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap, | 278 | int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap, |
247 | __u64 key, __u64 *keys, __u64 *ptrs, | 279 | __u64 key, __u64 *keys, __u64 *ptrs, int n) |
248 | int n, __u64 low, __u64 high) | ||
249 | { | 280 | { |
250 | struct nilfs_direct *direct; | 281 | struct nilfs_direct *direct; |
251 | __le64 *dptrs; | 282 | __le64 *dptrs; |
@@ -275,8 +306,7 @@ int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap, | |||
275 | dptrs[i] = NILFS_BMAP_INVALID_PTR; | 306 | dptrs[i] = NILFS_BMAP_INVALID_PTR; |
276 | } | 307 | } |
277 | 308 | ||
278 | nilfs_direct_init(bmap, low, high); | 309 | nilfs_direct_init(bmap); |
279 | |||
280 | return 0; | 310 | return 0; |
281 | } | 311 | } |
282 | 312 | ||
@@ -293,11 +323,11 @@ static int nilfs_direct_propagate_v(struct nilfs_direct *direct, | |||
293 | if (!buffer_nilfs_volatile(bh)) { | 323 | if (!buffer_nilfs_volatile(bh)) { |
294 | oldreq.bpr_ptr = ptr; | 324 | oldreq.bpr_ptr = ptr; |
295 | newreq.bpr_ptr = ptr; | 325 | newreq.bpr_ptr = ptr; |
296 | ret = nilfs_bmap_prepare_update(&direct->d_bmap, &oldreq, | 326 | ret = nilfs_bmap_prepare_update_v(&direct->d_bmap, &oldreq, |
297 | &newreq); | 327 | &newreq); |
298 | if (ret < 0) | 328 | if (ret < 0) |
299 | return ret; | 329 | return ret; |
300 | nilfs_bmap_commit_update(&direct->d_bmap, &oldreq, &newreq); | 330 | nilfs_bmap_commit_update_v(&direct->d_bmap, &oldreq, &newreq); |
301 | set_buffer_nilfs_volatile(bh); | 331 | set_buffer_nilfs_volatile(bh); |
302 | nilfs_direct_set_ptr(direct, key, newreq.bpr_ptr); | 332 | nilfs_direct_set_ptr(direct, key, newreq.bpr_ptr); |
303 | } else | 333 | } else |
@@ -309,12 +339,10 @@ static int nilfs_direct_propagate_v(struct nilfs_direct *direct, | |||
309 | static int nilfs_direct_propagate(const struct nilfs_bmap *bmap, | 339 | static int nilfs_direct_propagate(const struct nilfs_bmap *bmap, |
310 | struct buffer_head *bh) | 340 | struct buffer_head *bh) |
311 | { | 341 | { |
312 | struct nilfs_direct *direct; | 342 | struct nilfs_direct *direct = (struct nilfs_direct *)bmap; |
313 | 343 | ||
314 | direct = (struct nilfs_direct *)bmap; | 344 | return NILFS_BMAP_USE_VBN(bmap) ? |
315 | return (direct->d_ops->dop_propagate != NULL) ? | 345 | nilfs_direct_propagate_v(direct, bh) : 0; |
316 | direct->d_ops->dop_propagate(direct, bh) : | ||
317 | 0; | ||
318 | } | 346 | } |
319 | 347 | ||
320 | static int nilfs_direct_assign_v(struct nilfs_direct *direct, | 348 | static int nilfs_direct_assign_v(struct nilfs_direct *direct, |
@@ -327,12 +355,9 @@ static int nilfs_direct_assign_v(struct nilfs_direct *direct, | |||
327 | int ret; | 355 | int ret; |
328 | 356 | ||
329 | req.bpr_ptr = ptr; | 357 | req.bpr_ptr = ptr; |
330 | ret = direct->d_bmap.b_pops->bpop_prepare_start_ptr( | 358 | ret = nilfs_bmap_start_v(&direct->d_bmap, &req, blocknr); |
331 | &direct->d_bmap, &req); | 359 | if (unlikely(ret < 0)) |
332 | if (ret < 0) | ||
333 | return ret; | 360 | return ret; |
334 | direct->d_bmap.b_pops->bpop_commit_start_ptr(&direct->d_bmap, | ||
335 | &req, blocknr); | ||
336 | 361 | ||
337 | binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr); | 362 | binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr); |
338 | binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key); | 363 | binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key); |
@@ -377,12 +402,14 @@ static int nilfs_direct_assign(struct nilfs_bmap *bmap, | |||
377 | return -EINVAL; | 402 | return -EINVAL; |
378 | } | 403 | } |
379 | 404 | ||
380 | return direct->d_ops->dop_assign(direct, key, ptr, bh, | 405 | return NILFS_BMAP_USE_VBN(bmap) ? |
381 | blocknr, binfo); | 406 | nilfs_direct_assign_v(direct, key, ptr, bh, blocknr, binfo) : |
407 | nilfs_direct_assign_p(direct, key, ptr, bh, blocknr, binfo); | ||
382 | } | 408 | } |
383 | 409 | ||
384 | static const struct nilfs_bmap_operations nilfs_direct_ops = { | 410 | static const struct nilfs_bmap_operations nilfs_direct_ops = { |
385 | .bop_lookup = nilfs_direct_lookup, | 411 | .bop_lookup = nilfs_direct_lookup, |
412 | .bop_lookup_contig = nilfs_direct_lookup_contig, | ||
386 | .bop_insert = nilfs_direct_insert, | 413 | .bop_insert = nilfs_direct_insert, |
387 | .bop_delete = nilfs_direct_delete, | 414 | .bop_delete = nilfs_direct_delete, |
388 | .bop_clear = NULL, | 415 | .bop_clear = NULL, |
@@ -401,36 +428,8 @@ static const struct nilfs_bmap_operations nilfs_direct_ops = { | |||
401 | }; | 428 | }; |
402 | 429 | ||
403 | 430 | ||
404 | static const struct nilfs_direct_operations nilfs_direct_ops_v = { | 431 | int nilfs_direct_init(struct nilfs_bmap *bmap) |
405 | .dop_find_target = nilfs_direct_find_target_v, | ||
406 | .dop_set_target = nilfs_direct_set_target_v, | ||
407 | .dop_propagate = nilfs_direct_propagate_v, | ||
408 | .dop_assign = nilfs_direct_assign_v, | ||
409 | }; | ||
410 | |||
411 | static const struct nilfs_direct_operations nilfs_direct_ops_p = { | ||
412 | .dop_find_target = NULL, | ||
413 | .dop_set_target = NULL, | ||
414 | .dop_propagate = NULL, | ||
415 | .dop_assign = nilfs_direct_assign_p, | ||
416 | }; | ||
417 | |||
418 | int nilfs_direct_init(struct nilfs_bmap *bmap, __u64 low, __u64 high) | ||
419 | { | 432 | { |
420 | struct nilfs_direct *direct; | ||
421 | |||
422 | direct = (struct nilfs_direct *)bmap; | ||
423 | bmap->b_ops = &nilfs_direct_ops; | 433 | bmap->b_ops = &nilfs_direct_ops; |
424 | bmap->b_low = low; | ||
425 | bmap->b_high = high; | ||
426 | switch (bmap->b_inode->i_ino) { | ||
427 | case NILFS_DAT_INO: | ||
428 | direct->d_ops = &nilfs_direct_ops_p; | ||
429 | break; | ||
430 | default: | ||
431 | direct->d_ops = &nilfs_direct_ops_v; | ||
432 | break; | ||
433 | } | ||
434 | |||
435 | return 0; | 434 | return 0; |
436 | } | 435 | } |