diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 17:34:33 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 17:34:33 -0400 |
commit | af8cb8aa38296ecc43aca7fae9e574db7b8ae0c4 (patch) | |
tree | 636090652a055bff0930ad713e315ff185282330 | |
parent | 6cdb5930a6fa0e35b236f4aa0e056001fe1384b4 (diff) | |
parent | 41f4db0f48c72db3a93cc1a0b18368d9a9aca700 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2: (21 commits)
fs/Kconfig: move nilfs2 outside misc filesystems
nilfs2: convert nilfs_bmap_lookup to an inline function
nilfs2: allow btree code to directly call dat operations
nilfs2: add update functions of virtual block address to dat
nilfs2: remove individual gfp constants for each metadata file
nilfs2: stop zero-fill of btree path just before free it
nilfs2: remove unused btree argument from btree functions
nilfs2: remove nilfs_dat_abort_start and nilfs_dat_abort_free
nilfs2: shorten freeze period due to GC in write operation v3
nilfs2: add more check routines in mount process
nilfs2: An unassigned variable is assigned to a never used structure member
nilfs2: use GFP_NOIO for bio_alloc instead of GFP_NOWAIT
nilfs2: stop using periodic write_super callback
nilfs2: clean up nilfs_write_super
nilfs2: fix disorder of nilfs_write_super in nilfs_sync_fs
nilfs2: remove redundant super block commit
nilfs2: implement nilfs_show_options to display mount options in /proc/mounts
nilfs2: always lookup disk block address before reading metadata block
nilfs2: use semaphore to protect pointer to a writable FS-instance
nilfs2: fix format string compile warning (ino_t)
...
-rw-r--r-- | fs/Kconfig | 2 | ||||
-rw-r--r-- | fs/nilfs2/Kconfig | 2 | ||||
-rw-r--r-- | fs/nilfs2/bmap.c | 151 | ||||
-rw-r--r-- | fs/nilfs2/bmap.h | 76 | ||||
-rw-r--r-- | fs/nilfs2/btree.c | 625 | ||||
-rw-r--r-- | fs/nilfs2/cpfile.c | 11 | ||||
-rw-r--r-- | fs/nilfs2/cpfile.h | 2 | ||||
-rw-r--r-- | fs/nilfs2/dat.c | 42 | ||||
-rw-r--r-- | fs/nilfs2/dat.h | 8 | ||||
-rw-r--r-- | fs/nilfs2/direct.c | 161 | ||||
-rw-r--r-- | fs/nilfs2/ifile.h | 1 | ||||
-rw-r--r-- | fs/nilfs2/inode.c | 3 | ||||
-rw-r--r-- | fs/nilfs2/ioctl.c | 26 | ||||
-rw-r--r-- | fs/nilfs2/mdt.c | 40 | ||||
-rw-r--r-- | fs/nilfs2/mdt.h | 3 | ||||
-rw-r--r-- | fs/nilfs2/recovery.c | 3 | ||||
-rw-r--r-- | fs/nilfs2/segbuf.c | 4 | ||||
-rw-r--r-- | fs/nilfs2/segment.c | 7 | ||||
-rw-r--r-- | fs/nilfs2/sufile.h | 1 | ||||
-rw-r--r-- | fs/nilfs2/super.c | 100 | ||||
-rw-r--r-- | fs/nilfs2/the_nilfs.c | 15 | ||||
-rw-r--r-- | fs/nilfs2/the_nilfs.h | 43 |
22 files changed, 567 insertions, 759 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index 0e7da7bb5d93..455aa207e67e 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -43,6 +43,7 @@ source "fs/xfs/Kconfig" | |||
43 | source "fs/gfs2/Kconfig" | 43 | source "fs/gfs2/Kconfig" |
44 | source "fs/ocfs2/Kconfig" | 44 | source "fs/ocfs2/Kconfig" |
45 | source "fs/btrfs/Kconfig" | 45 | source "fs/btrfs/Kconfig" |
46 | source "fs/nilfs2/Kconfig" | ||
46 | 47 | ||
47 | endif # BLOCK | 48 | endif # BLOCK |
48 | 49 | ||
@@ -186,7 +187,6 @@ source "fs/romfs/Kconfig" | |||
186 | source "fs/sysv/Kconfig" | 187 | source "fs/sysv/Kconfig" |
187 | source "fs/ufs/Kconfig" | 188 | source "fs/ufs/Kconfig" |
188 | source "fs/exofs/Kconfig" | 189 | source "fs/exofs/Kconfig" |
189 | source "fs/nilfs2/Kconfig" | ||
190 | 190 | ||
191 | endif # MISC_FILESYSTEMS | 191 | endif # MISC_FILESYSTEMS |
192 | 192 | ||
diff --git a/fs/nilfs2/Kconfig b/fs/nilfs2/Kconfig index 72da095d4009..251da07b2a1d 100644 --- a/fs/nilfs2/Kconfig +++ b/fs/nilfs2/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config NILFS2_FS | 1 | config NILFS2_FS |
2 | tristate "NILFS2 file system support (EXPERIMENTAL)" | 2 | tristate "NILFS2 file system support (EXPERIMENTAL)" |
3 | depends on BLOCK && EXPERIMENTAL | 3 | depends on EXPERIMENTAL |
4 | select CRC32 | 4 | select CRC32 |
5 | help | 5 | help |
6 | NILFS2 is a log-structured file system (LFS) supporting continuous | 6 | NILFS2 is a log-structured file system (LFS) supporting continuous |
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c index 99d58a028b94..08834df6ec68 100644 --- a/fs/nilfs2/bmap.c +++ b/fs/nilfs2/bmap.c | |||
@@ -36,6 +36,26 @@ struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap) | |||
36 | return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode)); | 36 | return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode)); |
37 | } | 37 | } |
38 | 38 | ||
39 | /** | ||
40 | * nilfs_bmap_lookup_at_level - find a data block or node block | ||
41 | * @bmap: bmap | ||
42 | * @key: key | ||
43 | * @level: level | ||
44 | * @ptrp: place to store the value associated to @key | ||
45 | * | ||
46 | * Description: nilfs_bmap_lookup_at_level() finds a record whose key | ||
47 | * matches @key in the block at @level of the bmap. | ||
48 | * | ||
49 | * Return Value: On success, 0 is returned and the record associated with @key | ||
50 | * is stored in the place pointed by @ptrp. On error, one of the following | ||
51 | * negative error codes is returned. | ||
52 | * | ||
53 | * %-EIO - I/O error. | ||
54 | * | ||
55 | * %-ENOMEM - Insufficient amount of memory available. | ||
56 | * | ||
57 | * %-ENOENT - A record associated with @key does not exist. | ||
58 | */ | ||
39 | int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level, | 59 | int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level, |
40 | __u64 *ptrp) | 60 | __u64 *ptrp) |
41 | { | 61 | { |
@@ -69,39 +89,6 @@ int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp, | |||
69 | return ret; | 89 | return ret; |
70 | } | 90 | } |
71 | 91 | ||
72 | /** | ||
73 | * nilfs_bmap_lookup - find a record | ||
74 | * @bmap: bmap | ||
75 | * @key: key | ||
76 | * @recp: pointer to record | ||
77 | * | ||
78 | * Description: nilfs_bmap_lookup() finds a record whose key matches @key in | ||
79 | * @bmap. | ||
80 | * | ||
81 | * Return Value: On success, 0 is returned and the record associated with @key | ||
82 | * is stored in the place pointed by @recp. On error, one of the following | ||
83 | * negative error codes is returned. | ||
84 | * | ||
85 | * %-EIO - I/O error. | ||
86 | * | ||
87 | * %-ENOMEM - Insufficient amount of memory available. | ||
88 | * | ||
89 | * %-ENOENT - A record associated with @key does not exist. | ||
90 | */ | ||
91 | int nilfs_bmap_lookup(struct nilfs_bmap *bmap, | ||
92 | unsigned long key, | ||
93 | unsigned long *recp) | ||
94 | { | ||
95 | __u64 ptr; | ||
96 | int ret; | ||
97 | |||
98 | /* XXX: use macro for level 1 */ | ||
99 | ret = nilfs_bmap_lookup_at_level(bmap, key, 1, &ptr); | ||
100 | if (recp != NULL) | ||
101 | *recp = ptr; | ||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) | 92 | static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) |
106 | { | 93 | { |
107 | __u64 keys[NILFS_BMAP_SMALL_HIGH + 1]; | 94 | __u64 keys[NILFS_BMAP_SMALL_HIGH + 1]; |
@@ -469,104 +456,6 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap) | |||
469 | (entries_per_group / NILFS_BMAP_GROUP_DIV); | 456 | (entries_per_group / NILFS_BMAP_GROUP_DIV); |
470 | } | 457 | } |
471 | 458 | ||
472 | int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *bmap, | ||
473 | union nilfs_bmap_ptr_req *req) | ||
474 | { | ||
475 | return nilfs_dat_prepare_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req); | ||
476 | } | ||
477 | |||
478 | void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *bmap, | ||
479 | union nilfs_bmap_ptr_req *req) | ||
480 | { | ||
481 | nilfs_dat_commit_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req); | ||
482 | } | ||
483 | |||
484 | void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *bmap, | ||
485 | union nilfs_bmap_ptr_req *req) | ||
486 | { | ||
487 | nilfs_dat_abort_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req); | ||
488 | } | ||
489 | |||
490 | int nilfs_bmap_start_v(struct nilfs_bmap *bmap, union nilfs_bmap_ptr_req *req, | ||
491 | sector_t blocknr) | ||
492 | { | ||
493 | struct inode *dat = nilfs_bmap_get_dat(bmap); | ||
494 | int ret; | ||
495 | |||
496 | ret = nilfs_dat_prepare_start(dat, &req->bpr_req); | ||
497 | if (likely(!ret)) | ||
498 | nilfs_dat_commit_start(dat, &req->bpr_req, blocknr); | ||
499 | return ret; | ||
500 | } | ||
501 | |||
502 | int nilfs_bmap_prepare_end_v(struct nilfs_bmap *bmap, | ||
503 | union nilfs_bmap_ptr_req *req) | ||
504 | { | ||
505 | return nilfs_dat_prepare_end(nilfs_bmap_get_dat(bmap), &req->bpr_req); | ||
506 | } | ||
507 | |||
508 | void nilfs_bmap_commit_end_v(struct nilfs_bmap *bmap, | ||
509 | union nilfs_bmap_ptr_req *req) | ||
510 | { | ||
511 | nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req, | ||
512 | bmap->b_ptr_type == NILFS_BMAP_PTR_VS); | ||
513 | } | ||
514 | |||
515 | void nilfs_bmap_abort_end_v(struct nilfs_bmap *bmap, | ||
516 | union nilfs_bmap_ptr_req *req) | ||
517 | { | ||
518 | nilfs_dat_abort_end(nilfs_bmap_get_dat(bmap), &req->bpr_req); | ||
519 | } | ||
520 | |||
521 | int nilfs_bmap_move_v(const struct nilfs_bmap *bmap, __u64 vblocknr, | ||
522 | sector_t blocknr) | ||
523 | { | ||
524 | return nilfs_dat_move(nilfs_bmap_get_dat(bmap), vblocknr, blocknr); | ||
525 | } | ||
526 | |||
527 | int nilfs_bmap_mark_dirty(const struct nilfs_bmap *bmap, __u64 vblocknr) | ||
528 | { | ||
529 | return nilfs_dat_mark_dirty(nilfs_bmap_get_dat(bmap), vblocknr); | ||
530 | } | ||
531 | |||
532 | int nilfs_bmap_prepare_update_v(struct nilfs_bmap *bmap, | ||
533 | union nilfs_bmap_ptr_req *oldreq, | ||
534 | union nilfs_bmap_ptr_req *newreq) | ||
535 | { | ||
536 | struct inode *dat = nilfs_bmap_get_dat(bmap); | ||
537 | int ret; | ||
538 | |||
539 | ret = nilfs_dat_prepare_end(dat, &oldreq->bpr_req); | ||
540 | if (ret < 0) | ||
541 | return ret; | ||
542 | ret = nilfs_dat_prepare_alloc(dat, &newreq->bpr_req); | ||
543 | if (ret < 0) | ||
544 | nilfs_dat_abort_end(dat, &oldreq->bpr_req); | ||
545 | |||
546 | return ret; | ||
547 | } | ||
548 | |||
549 | void nilfs_bmap_commit_update_v(struct nilfs_bmap *bmap, | ||
550 | union nilfs_bmap_ptr_req *oldreq, | ||
551 | union nilfs_bmap_ptr_req *newreq) | ||
552 | { | ||
553 | struct inode *dat = nilfs_bmap_get_dat(bmap); | ||
554 | |||
555 | nilfs_dat_commit_end(dat, &oldreq->bpr_req, | ||
556 | bmap->b_ptr_type == NILFS_BMAP_PTR_VS); | ||
557 | nilfs_dat_commit_alloc(dat, &newreq->bpr_req); | ||
558 | } | ||
559 | |||
560 | void nilfs_bmap_abort_update_v(struct nilfs_bmap *bmap, | ||
561 | union nilfs_bmap_ptr_req *oldreq, | ||
562 | union nilfs_bmap_ptr_req *newreq) | ||
563 | { | ||
564 | struct inode *dat = nilfs_bmap_get_dat(bmap); | ||
565 | |||
566 | nilfs_dat_abort_end(dat, &oldreq->bpr_req); | ||
567 | nilfs_dat_abort_alloc(dat, &newreq->bpr_req); | ||
568 | } | ||
569 | |||
570 | static struct lock_class_key nilfs_bmap_dat_lock_key; | 459 | static struct lock_class_key nilfs_bmap_dat_lock_key; |
571 | static struct lock_class_key nilfs_bmap_mdt_lock_key; | 460 | static struct lock_class_key nilfs_bmap_mdt_lock_key; |
572 | 461 | ||
diff --git a/fs/nilfs2/bmap.h b/fs/nilfs2/bmap.h index b2890cdcef12..9980d7dbab91 100644 --- a/fs/nilfs2/bmap.h +++ b/fs/nilfs2/bmap.h | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/buffer_head.h> | 28 | #include <linux/buffer_head.h> |
29 | #include <linux/nilfs2_fs.h> | 29 | #include <linux/nilfs2_fs.h> |
30 | #include "alloc.h" | 30 | #include "alloc.h" |
31 | #include "dat.h" | ||
31 | 32 | ||
32 | #define NILFS_BMAP_INVALID_PTR 0 | 33 | #define NILFS_BMAP_INVALID_PTR 0 |
33 | 34 | ||
@@ -141,7 +142,6 @@ struct nilfs_bmap { | |||
141 | int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *); | 142 | int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *); |
142 | int nilfs_bmap_read(struct nilfs_bmap *, struct nilfs_inode *); | 143 | int nilfs_bmap_read(struct nilfs_bmap *, struct nilfs_inode *); |
143 | void nilfs_bmap_write(struct nilfs_bmap *, struct nilfs_inode *); | 144 | void nilfs_bmap_write(struct nilfs_bmap *, struct nilfs_inode *); |
144 | int nilfs_bmap_lookup(struct nilfs_bmap *, unsigned long, unsigned long *); | ||
145 | int nilfs_bmap_lookup_contig(struct nilfs_bmap *, __u64, __u64 *, unsigned); | 145 | int nilfs_bmap_lookup_contig(struct nilfs_bmap *, __u64, __u64 *, unsigned); |
146 | int nilfs_bmap_insert(struct nilfs_bmap *, unsigned long, unsigned long); | 146 | int nilfs_bmap_insert(struct nilfs_bmap *, unsigned long, unsigned long); |
147 | int nilfs_bmap_delete(struct nilfs_bmap *, unsigned long); | 147 | int nilfs_bmap_delete(struct nilfs_bmap *, unsigned long); |
@@ -160,90 +160,76 @@ void nilfs_bmap_init_gcdat(struct nilfs_bmap *, struct nilfs_bmap *); | |||
160 | void nilfs_bmap_commit_gcdat(struct nilfs_bmap *, struct nilfs_bmap *); | 160 | void nilfs_bmap_commit_gcdat(struct nilfs_bmap *, struct nilfs_bmap *); |
161 | 161 | ||
162 | 162 | ||
163 | static inline int nilfs_bmap_lookup(struct nilfs_bmap *bmap, __u64 key, | ||
164 | __u64 *ptr) | ||
165 | { | ||
166 | return nilfs_bmap_lookup_at_level(bmap, key, 1, ptr); | ||
167 | } | ||
168 | |||
163 | /* | 169 | /* |
164 | * Internal use only | 170 | * Internal use only |
165 | */ | 171 | */ |
166 | struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *); | 172 | struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *); |
167 | int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *, | ||
168 | union nilfs_bmap_ptr_req *); | ||
169 | void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *, | ||
170 | union nilfs_bmap_ptr_req *); | ||
171 | void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *, | ||
172 | union nilfs_bmap_ptr_req *); | ||
173 | 173 | ||
174 | static inline int nilfs_bmap_prepare_alloc_ptr(struct nilfs_bmap *bmap, | 174 | static inline int nilfs_bmap_prepare_alloc_ptr(struct nilfs_bmap *bmap, |
175 | union nilfs_bmap_ptr_req *req) | 175 | union nilfs_bmap_ptr_req *req, |
176 | struct inode *dat) | ||
176 | { | 177 | { |
177 | if (NILFS_BMAP_USE_VBN(bmap)) | 178 | if (dat) |
178 | return nilfs_bmap_prepare_alloc_v(bmap, req); | 179 | return nilfs_dat_prepare_alloc(dat, &req->bpr_req); |
179 | /* ignore target ptr */ | 180 | /* ignore target ptr */ |
180 | req->bpr_ptr = bmap->b_last_allocated_ptr++; | 181 | req->bpr_ptr = bmap->b_last_allocated_ptr++; |
181 | return 0; | 182 | return 0; |
182 | } | 183 | } |
183 | 184 | ||
184 | static inline void nilfs_bmap_commit_alloc_ptr(struct nilfs_bmap *bmap, | 185 | static inline void nilfs_bmap_commit_alloc_ptr(struct nilfs_bmap *bmap, |
185 | union nilfs_bmap_ptr_req *req) | 186 | union nilfs_bmap_ptr_req *req, |
187 | struct inode *dat) | ||
186 | { | 188 | { |
187 | if (NILFS_BMAP_USE_VBN(bmap)) | 189 | if (dat) |
188 | nilfs_bmap_commit_alloc_v(bmap, req); | 190 | nilfs_dat_commit_alloc(dat, &req->bpr_req); |
189 | } | 191 | } |
190 | 192 | ||
191 | static inline void nilfs_bmap_abort_alloc_ptr(struct nilfs_bmap *bmap, | 193 | static inline void nilfs_bmap_abort_alloc_ptr(struct nilfs_bmap *bmap, |
192 | union nilfs_bmap_ptr_req *req) | 194 | union nilfs_bmap_ptr_req *req, |
195 | struct inode *dat) | ||
193 | { | 196 | { |
194 | if (NILFS_BMAP_USE_VBN(bmap)) | 197 | if (dat) |
195 | nilfs_bmap_abort_alloc_v(bmap, req); | 198 | nilfs_dat_abort_alloc(dat, &req->bpr_req); |
196 | else | 199 | else |
197 | bmap->b_last_allocated_ptr--; | 200 | bmap->b_last_allocated_ptr--; |
198 | } | 201 | } |
199 | 202 | ||
200 | int nilfs_bmap_prepare_end_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *); | ||
201 | void nilfs_bmap_commit_end_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *); | ||
202 | void nilfs_bmap_abort_end_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *); | ||
203 | |||
204 | static inline int nilfs_bmap_prepare_end_ptr(struct nilfs_bmap *bmap, | 203 | static inline int nilfs_bmap_prepare_end_ptr(struct nilfs_bmap *bmap, |
205 | union nilfs_bmap_ptr_req *req) | 204 | union nilfs_bmap_ptr_req *req, |
205 | struct inode *dat) | ||
206 | { | 206 | { |
207 | return NILFS_BMAP_USE_VBN(bmap) ? | 207 | return dat ? nilfs_dat_prepare_end(dat, &req->bpr_req) : 0; |
208 | nilfs_bmap_prepare_end_v(bmap, req) : 0; | ||
209 | } | 208 | } |
210 | 209 | ||
211 | static inline void nilfs_bmap_commit_end_ptr(struct nilfs_bmap *bmap, | 210 | static inline void nilfs_bmap_commit_end_ptr(struct nilfs_bmap *bmap, |
212 | union nilfs_bmap_ptr_req *req) | 211 | union nilfs_bmap_ptr_req *req, |
212 | struct inode *dat) | ||
213 | { | 213 | { |
214 | if (NILFS_BMAP_USE_VBN(bmap)) | 214 | if (dat) |
215 | nilfs_bmap_commit_end_v(bmap, req); | 215 | nilfs_dat_commit_end(dat, &req->bpr_req, |
216 | bmap->b_ptr_type == NILFS_BMAP_PTR_VS); | ||
216 | } | 217 | } |
217 | 218 | ||
218 | static inline void nilfs_bmap_abort_end_ptr(struct nilfs_bmap *bmap, | 219 | static inline void nilfs_bmap_abort_end_ptr(struct nilfs_bmap *bmap, |
219 | union nilfs_bmap_ptr_req *req) | 220 | union nilfs_bmap_ptr_req *req, |
221 | struct inode *dat) | ||
220 | { | 222 | { |
221 | if (NILFS_BMAP_USE_VBN(bmap)) | 223 | if (dat) |
222 | nilfs_bmap_abort_end_v(bmap, req); | 224 | nilfs_dat_abort_end(dat, &req->bpr_req); |
223 | } | 225 | } |
224 | 226 | ||
225 | int nilfs_bmap_start_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *, | ||
226 | sector_t); | ||
227 | int nilfs_bmap_move_v(const struct nilfs_bmap *, __u64, sector_t); | ||
228 | int nilfs_bmap_mark_dirty(const struct nilfs_bmap *, __u64); | ||
229 | |||
230 | |||
231 | __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *, | 227 | __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *, |
232 | const struct buffer_head *); | 228 | const struct buffer_head *); |
233 | 229 | ||
234 | __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *, __u64); | 230 | __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *, __u64); |
235 | __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *); | 231 | __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *); |
236 | 232 | ||
237 | int nilfs_bmap_prepare_update_v(struct nilfs_bmap *, | ||
238 | union nilfs_bmap_ptr_req *, | ||
239 | union nilfs_bmap_ptr_req *); | ||
240 | void nilfs_bmap_commit_update_v(struct nilfs_bmap *, | ||
241 | union nilfs_bmap_ptr_req *, | ||
242 | union nilfs_bmap_ptr_req *); | ||
243 | void nilfs_bmap_abort_update_v(struct nilfs_bmap *, | ||
244 | union nilfs_bmap_ptr_req *, | ||
245 | union nilfs_bmap_ptr_req *); | ||
246 | |||
247 | void nilfs_bmap_add_blocks(const struct nilfs_bmap *, int); | 233 | void nilfs_bmap_add_blocks(const struct nilfs_bmap *, int); |
248 | void nilfs_bmap_sub_blocks(const struct nilfs_bmap *, int); | 234 | void nilfs_bmap_sub_blocks(const struct nilfs_bmap *, int); |
249 | 235 | ||
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c index aa412724b64e..e25b507a474f 100644 --- a/fs/nilfs2/btree.c +++ b/fs/nilfs2/btree.c | |||
@@ -71,21 +71,17 @@ void nilfs_btree_path_cache_destroy(void) | |||
71 | kmem_cache_destroy(nilfs_btree_path_cache); | 71 | kmem_cache_destroy(nilfs_btree_path_cache); |
72 | } | 72 | } |
73 | 73 | ||
74 | static inline struct nilfs_btree_path * | 74 | static inline struct nilfs_btree_path *nilfs_btree_alloc_path(void) |
75 | nilfs_btree_alloc_path(const struct nilfs_btree *btree) | ||
76 | { | 75 | { |
77 | return (struct nilfs_btree_path *) | 76 | return kmem_cache_alloc(nilfs_btree_path_cache, GFP_NOFS); |
78 | kmem_cache_alloc(nilfs_btree_path_cache, GFP_NOFS); | ||
79 | } | 77 | } |
80 | 78 | ||
81 | static inline void nilfs_btree_free_path(const struct nilfs_btree *btree, | 79 | static inline void nilfs_btree_free_path(struct nilfs_btree_path *path) |
82 | struct nilfs_btree_path *path) | ||
83 | { | 80 | { |
84 | kmem_cache_free(nilfs_btree_path_cache, path); | 81 | kmem_cache_free(nilfs_btree_path_cache, path); |
85 | } | 82 | } |
86 | 83 | ||
87 | static void nilfs_btree_init_path(const struct nilfs_btree *btree, | 84 | static void nilfs_btree_init_path(struct nilfs_btree_path *path) |
88 | struct nilfs_btree_path *path) | ||
89 | { | 85 | { |
90 | int level; | 86 | int level; |
91 | 87 | ||
@@ -101,26 +97,13 @@ static void nilfs_btree_init_path(const struct nilfs_btree *btree, | |||
101 | } | 97 | } |
102 | } | 98 | } |
103 | 99 | ||
104 | static void nilfs_btree_clear_path(const struct nilfs_btree *btree, | 100 | static void nilfs_btree_release_path(struct nilfs_btree_path *path) |
105 | struct nilfs_btree_path *path) | ||
106 | { | 101 | { |
107 | int level; | 102 | int level; |
108 | 103 | ||
109 | for (level = NILFS_BTREE_LEVEL_DATA; | 104 | for (level = NILFS_BTREE_LEVEL_DATA; level < NILFS_BTREE_LEVEL_MAX; |
110 | level < NILFS_BTREE_LEVEL_MAX; | 105 | level++) |
111 | level++) { | 106 | brelse(path[level].bp_bh); |
112 | if (path[level].bp_bh != NULL) { | ||
113 | brelse(path[level].bp_bh); | ||
114 | path[level].bp_bh = NULL; | ||
115 | } | ||
116 | /* sib_bh is released or deleted by prepare or commit | ||
117 | * operations. */ | ||
118 | path[level].bp_sib_bh = NULL; | ||
119 | path[level].bp_index = 0; | ||
120 | path[level].bp_oldreq.bpr_ptr = NILFS_BMAP_INVALID_PTR; | ||
121 | path[level].bp_newreq.bpr_ptr = NILFS_BMAP_INVALID_PTR; | ||
122 | path[level].bp_op = NULL; | ||
123 | } | ||
124 | } | 107 | } |
125 | 108 | ||
126 | /* | 109 | /* |
@@ -148,129 +131,110 @@ static int nilfs_btree_get_new_block(const struct nilfs_btree *btree, | |||
148 | } | 131 | } |
149 | 132 | ||
150 | static inline int | 133 | static inline int |
151 | nilfs_btree_node_get_flags(const struct nilfs_btree *btree, | 134 | nilfs_btree_node_get_flags(const struct nilfs_btree_node *node) |
152 | const struct nilfs_btree_node *node) | ||
153 | { | 135 | { |
154 | return node->bn_flags; | 136 | return node->bn_flags; |
155 | } | 137 | } |
156 | 138 | ||
157 | static inline void | 139 | static inline void |
158 | nilfs_btree_node_set_flags(struct nilfs_btree *btree, | 140 | nilfs_btree_node_set_flags(struct nilfs_btree_node *node, int flags) |
159 | struct nilfs_btree_node *node, | ||
160 | int flags) | ||
161 | { | 141 | { |
162 | node->bn_flags = flags; | 142 | node->bn_flags = flags; |
163 | } | 143 | } |
164 | 144 | ||
165 | static inline int nilfs_btree_node_root(const struct nilfs_btree *btree, | 145 | static inline int nilfs_btree_node_root(const struct nilfs_btree_node *node) |
166 | const struct nilfs_btree_node *node) | ||
167 | { | 146 | { |
168 | return nilfs_btree_node_get_flags(btree, node) & NILFS_BTREE_NODE_ROOT; | 147 | return nilfs_btree_node_get_flags(node) & NILFS_BTREE_NODE_ROOT; |
169 | } | 148 | } |
170 | 149 | ||
171 | static inline int | 150 | static inline int |
172 | nilfs_btree_node_get_level(const struct nilfs_btree *btree, | 151 | nilfs_btree_node_get_level(const struct nilfs_btree_node *node) |
173 | const struct nilfs_btree_node *node) | ||
174 | { | 152 | { |
175 | return node->bn_level; | 153 | return node->bn_level; |
176 | } | 154 | } |
177 | 155 | ||
178 | static inline void | 156 | static inline void |
179 | nilfs_btree_node_set_level(struct nilfs_btree *btree, | 157 | nilfs_btree_node_set_level(struct nilfs_btree_node *node, int level) |
180 | struct nilfs_btree_node *node, | ||
181 | int level) | ||
182 | { | 158 | { |
183 | node->bn_level = level; | 159 | node->bn_level = level; |
184 | } | 160 | } |
185 | 161 | ||
186 | static inline int | 162 | static inline int |
187 | nilfs_btree_node_get_nchildren(const struct nilfs_btree *btree, | 163 | nilfs_btree_node_get_nchildren(const struct nilfs_btree_node *node) |
188 | const struct nilfs_btree_node *node) | ||
189 | { | 164 | { |
190 | return le16_to_cpu(node->bn_nchildren); | 165 | return le16_to_cpu(node->bn_nchildren); |
191 | } | 166 | } |
192 | 167 | ||
193 | static inline void | 168 | static inline void |
194 | nilfs_btree_node_set_nchildren(struct nilfs_btree *btree, | 169 | nilfs_btree_node_set_nchildren(struct nilfs_btree_node *node, int nchildren) |
195 | struct nilfs_btree_node *node, | ||
196 | int nchildren) | ||
197 | { | 170 | { |
198 | node->bn_nchildren = cpu_to_le16(nchildren); | 171 | node->bn_nchildren = cpu_to_le16(nchildren); |
199 | } | 172 | } |
200 | 173 | ||
201 | static inline int | 174 | static inline int nilfs_btree_node_size(const struct nilfs_btree *btree) |
202 | nilfs_btree_node_size(const struct nilfs_btree *btree) | ||
203 | { | 175 | { |
204 | return 1 << btree->bt_bmap.b_inode->i_blkbits; | 176 | return 1 << btree->bt_bmap.b_inode->i_blkbits; |
205 | } | 177 | } |
206 | 178 | ||
207 | static inline int | 179 | static inline int |
208 | nilfs_btree_node_nchildren_min(const struct nilfs_btree *btree, | 180 | nilfs_btree_node_nchildren_min(const struct nilfs_btree_node *node, |
209 | const struct nilfs_btree_node *node) | 181 | const struct nilfs_btree *btree) |
210 | { | 182 | { |
211 | return nilfs_btree_node_root(btree, node) ? | 183 | return nilfs_btree_node_root(node) ? |
212 | NILFS_BTREE_ROOT_NCHILDREN_MIN : | 184 | NILFS_BTREE_ROOT_NCHILDREN_MIN : |
213 | NILFS_BTREE_NODE_NCHILDREN_MIN(nilfs_btree_node_size(btree)); | 185 | NILFS_BTREE_NODE_NCHILDREN_MIN(nilfs_btree_node_size(btree)); |
214 | } | 186 | } |
215 | 187 | ||
216 | static inline int | 188 | static inline int |
217 | nilfs_btree_node_nchildren_max(const struct nilfs_btree *btree, | 189 | nilfs_btree_node_nchildren_max(const struct nilfs_btree_node *node, |
218 | const struct nilfs_btree_node *node) | 190 | const struct nilfs_btree *btree) |
219 | { | 191 | { |
220 | return nilfs_btree_node_root(btree, node) ? | 192 | return nilfs_btree_node_root(node) ? |
221 | NILFS_BTREE_ROOT_NCHILDREN_MAX : | 193 | NILFS_BTREE_ROOT_NCHILDREN_MAX : |
222 | NILFS_BTREE_NODE_NCHILDREN_MAX(nilfs_btree_node_size(btree)); | 194 | NILFS_BTREE_NODE_NCHILDREN_MAX(nilfs_btree_node_size(btree)); |
223 | } | 195 | } |
224 | 196 | ||
225 | static inline __le64 * | 197 | static inline __le64 * |
226 | nilfs_btree_node_dkeys(const struct nilfs_btree *btree, | 198 | nilfs_btree_node_dkeys(const struct nilfs_btree_node *node) |
227 | const struct nilfs_btree_node *node) | ||
228 | { | 199 | { |
229 | return (__le64 *)((char *)(node + 1) + | 200 | return (__le64 *)((char *)(node + 1) + |
230 | (nilfs_btree_node_root(btree, node) ? | 201 | (nilfs_btree_node_root(node) ? |
231 | 0 : NILFS_BTREE_NODE_EXTRA_PAD_SIZE)); | 202 | 0 : NILFS_BTREE_NODE_EXTRA_PAD_SIZE)); |
232 | } | 203 | } |
233 | 204 | ||
234 | static inline __le64 * | 205 | static inline __le64 * |
235 | nilfs_btree_node_dptrs(const struct nilfs_btree *btree, | 206 | nilfs_btree_node_dptrs(const struct nilfs_btree_node *node, |
236 | const struct nilfs_btree_node *node) | 207 | const struct nilfs_btree *btree) |
237 | { | 208 | { |
238 | return (__le64 *)(nilfs_btree_node_dkeys(btree, node) + | 209 | return (__le64 *)(nilfs_btree_node_dkeys(node) + |
239 | nilfs_btree_node_nchildren_max(btree, node)); | 210 | nilfs_btree_node_nchildren_max(node, btree)); |
240 | } | 211 | } |
241 | 212 | ||
242 | static inline __u64 | 213 | static inline __u64 |
243 | nilfs_btree_node_get_key(const struct nilfs_btree *btree, | 214 | nilfs_btree_node_get_key(const struct nilfs_btree_node *node, int index) |
244 | const struct nilfs_btree_node *node, int index) | ||
245 | { | 215 | { |
246 | return nilfs_bmap_dkey_to_key(*(nilfs_btree_node_dkeys(btree, node) + | 216 | return nilfs_bmap_dkey_to_key(*(nilfs_btree_node_dkeys(node) + index)); |
247 | index)); | ||
248 | } | 217 | } |
249 | 218 | ||
250 | static inline void | 219 | static inline void |
251 | nilfs_btree_node_set_key(struct nilfs_btree *btree, | 220 | nilfs_btree_node_set_key(struct nilfs_btree_node *node, int index, __u64 key) |
252 | struct nilfs_btree_node *node, int index, __u64 key) | ||
253 | { | 221 | { |
254 | *(nilfs_btree_node_dkeys(btree, node) + index) = | 222 | *(nilfs_btree_node_dkeys(node) + index) = nilfs_bmap_key_to_dkey(key); |
255 | nilfs_bmap_key_to_dkey(key); | ||
256 | } | 223 | } |
257 | 224 | ||
258 | static inline __u64 | 225 | static inline __u64 |
259 | nilfs_btree_node_get_ptr(const struct nilfs_btree *btree, | 226 | nilfs_btree_node_get_ptr(const struct nilfs_btree *btree, |
260 | const struct nilfs_btree_node *node, | 227 | const struct nilfs_btree_node *node, int index) |
261 | int index) | ||
262 | { | 228 | { |
263 | return nilfs_bmap_dptr_to_ptr(*(nilfs_btree_node_dptrs(btree, node) + | 229 | return nilfs_bmap_dptr_to_ptr(*(nilfs_btree_node_dptrs(node, btree) + |
264 | index)); | 230 | index)); |
265 | } | 231 | } |
266 | 232 | ||
267 | static inline void | 233 | static inline void |
268 | nilfs_btree_node_set_ptr(struct nilfs_btree *btree, | 234 | nilfs_btree_node_set_ptr(struct nilfs_btree *btree, |
269 | struct nilfs_btree_node *node, | 235 | struct nilfs_btree_node *node, int index, __u64 ptr) |
270 | int index, | ||
271 | __u64 ptr) | ||
272 | { | 236 | { |
273 | *(nilfs_btree_node_dptrs(btree, node) + index) = | 237 | *(nilfs_btree_node_dptrs(node, btree) + index) = |
274 | nilfs_bmap_ptr_to_dptr(ptr); | 238 | nilfs_bmap_ptr_to_dptr(ptr); |
275 | } | 239 | } |
276 | 240 | ||
@@ -283,12 +247,12 @@ static void nilfs_btree_node_init(struct nilfs_btree *btree, | |||
283 | __le64 *dptrs; | 247 | __le64 *dptrs; |
284 | int i; | 248 | int i; |
285 | 249 | ||
286 | nilfs_btree_node_set_flags(btree, node, flags); | 250 | nilfs_btree_node_set_flags(node, flags); |
287 | nilfs_btree_node_set_level(btree, node, level); | 251 | nilfs_btree_node_set_level(node, level); |
288 | nilfs_btree_node_set_nchildren(btree, node, nchildren); | 252 | nilfs_btree_node_set_nchildren(node, nchildren); |
289 | 253 | ||
290 | dkeys = nilfs_btree_node_dkeys(btree, node); | 254 | dkeys = nilfs_btree_node_dkeys(node); |
291 | dptrs = nilfs_btree_node_dptrs(btree, node); | 255 | dptrs = nilfs_btree_node_dptrs(node, btree); |
292 | for (i = 0; i < nchildren; i++) { | 256 | for (i = 0; i < nchildren; i++) { |
293 | dkeys[i] = nilfs_bmap_key_to_dkey(keys[i]); | 257 | dkeys[i] = nilfs_bmap_key_to_dkey(keys[i]); |
294 | dptrs[i] = nilfs_bmap_ptr_to_dptr(ptrs[i]); | 258 | dptrs[i] = nilfs_bmap_ptr_to_dptr(ptrs[i]); |
@@ -305,13 +269,13 @@ static void nilfs_btree_node_move_left(struct nilfs_btree *btree, | |||
305 | __le64 *ldptrs, *rdptrs; | 269 | __le64 *ldptrs, *rdptrs; |
306 | int lnchildren, rnchildren; | 270 | int lnchildren, rnchildren; |
307 | 271 | ||
308 | ldkeys = nilfs_btree_node_dkeys(btree, left); | 272 | ldkeys = nilfs_btree_node_dkeys(left); |
309 | ldptrs = nilfs_btree_node_dptrs(btree, left); | 273 | ldptrs = nilfs_btree_node_dptrs(left, btree); |
310 | lnchildren = nilfs_btree_node_get_nchildren(btree, left); | 274 | lnchildren = nilfs_btree_node_get_nchildren(left); |
311 | 275 | ||
312 | rdkeys = nilfs_btree_node_dkeys(btree, right); | 276 | rdkeys = nilfs_btree_node_dkeys(right); |
313 | rdptrs = nilfs_btree_node_dptrs(btree, right); | 277 | rdptrs = nilfs_btree_node_dptrs(right, btree); |
314 | rnchildren = nilfs_btree_node_get_nchildren(btree, right); | 278 | rnchildren = nilfs_btree_node_get_nchildren(right); |
315 | 279 | ||
316 | memcpy(ldkeys + lnchildren, rdkeys, n * sizeof(*rdkeys)); | 280 | memcpy(ldkeys + lnchildren, rdkeys, n * sizeof(*rdkeys)); |
317 | memcpy(ldptrs + lnchildren, rdptrs, n * sizeof(*rdptrs)); | 281 | memcpy(ldptrs + lnchildren, rdptrs, n * sizeof(*rdptrs)); |
@@ -320,8 +284,8 @@ static void nilfs_btree_node_move_left(struct nilfs_btree *btree, | |||
320 | 284 | ||
321 | lnchildren += n; | 285 | lnchildren += n; |
322 | rnchildren -= n; | 286 | rnchildren -= n; |
323 | nilfs_btree_node_set_nchildren(btree, left, lnchildren); | 287 | nilfs_btree_node_set_nchildren(left, lnchildren); |
324 | nilfs_btree_node_set_nchildren(btree, right, rnchildren); | 288 | nilfs_btree_node_set_nchildren(right, rnchildren); |
325 | } | 289 | } |
326 | 290 | ||
327 | /* Assume that the buffer heads corresponding to left and right are locked. */ | 291 | /* Assume that the buffer heads corresponding to left and right are locked. */ |
@@ -334,13 +298,13 @@ static void nilfs_btree_node_move_right(struct nilfs_btree *btree, | |||
334 | __le64 *ldptrs, *rdptrs; | 298 | __le64 *ldptrs, *rdptrs; |
335 | int lnchildren, rnchildren; | 299 | int lnchildren, rnchildren; |
336 | 300 | ||
337 | ldkeys = nilfs_btree_node_dkeys(btree, left); | 301 | ldkeys = nilfs_btree_node_dkeys(left); |
338 | ldptrs = nilfs_btree_node_dptrs(btree, left); | 302 | ldptrs = nilfs_btree_node_dptrs(left, btree); |
339 | lnchildren = nilfs_btree_node_get_nchildren(btree, left); | 303 | lnchildren = nilfs_btree_node_get_nchildren(left); |
340 | 304 | ||
341 | rdkeys = nilfs_btree_node_dkeys(btree, right); | 305 | rdkeys = nilfs_btree_node_dkeys(right); |
342 | rdptrs = nilfs_btree_node_dptrs(btree, right); | 306 | rdptrs = nilfs_btree_node_dptrs(right, btree); |
343 | rnchildren = nilfs_btree_node_get_nchildren(btree, right); | 307 | rnchildren = nilfs_btree_node_get_nchildren(right); |
344 | 308 | ||
345 | memmove(rdkeys + n, rdkeys, rnchildren * sizeof(*rdkeys)); | 309 | memmove(rdkeys + n, rdkeys, rnchildren * sizeof(*rdkeys)); |
346 | memmove(rdptrs + n, rdptrs, rnchildren * sizeof(*rdptrs)); | 310 | memmove(rdptrs + n, rdptrs, rnchildren * sizeof(*rdptrs)); |
@@ -349,8 +313,8 @@ static void nilfs_btree_node_move_right(struct nilfs_btree *btree, | |||
349 | 313 | ||
350 | lnchildren -= n; | 314 | lnchildren -= n; |
351 | rnchildren += n; | 315 | rnchildren += n; |
352 | nilfs_btree_node_set_nchildren(btree, left, lnchildren); | 316 | nilfs_btree_node_set_nchildren(left, lnchildren); |
353 | nilfs_btree_node_set_nchildren(btree, right, rnchildren); | 317 | nilfs_btree_node_set_nchildren(right, rnchildren); |
354 | } | 318 | } |
355 | 319 | ||
356 | /* Assume that the buffer head corresponding to node is locked. */ | 320 | /* Assume that the buffer head corresponding to node is locked. */ |
@@ -362,9 +326,9 @@ static void nilfs_btree_node_insert(struct nilfs_btree *btree, | |||
362 | __le64 *dptrs; | 326 | __le64 *dptrs; |
363 | int nchildren; | 327 | int nchildren; |
364 | 328 | ||
365 | dkeys = nilfs_btree_node_dkeys(btree, node); | 329 | dkeys = nilfs_btree_node_dkeys(node); |
366 | dptrs = nilfs_btree_node_dptrs(btree, node); | 330 | dptrs = nilfs_btree_node_dptrs(node, btree); |
367 | nchildren = nilfs_btree_node_get_nchildren(btree, node); | 331 | nchildren = nilfs_btree_node_get_nchildren(node); |
368 | if (index < nchildren) { | 332 | if (index < nchildren) { |
369 | memmove(dkeys + index + 1, dkeys + index, | 333 | memmove(dkeys + index + 1, dkeys + index, |
370 | (nchildren - index) * sizeof(*dkeys)); | 334 | (nchildren - index) * sizeof(*dkeys)); |
@@ -374,7 +338,7 @@ static void nilfs_btree_node_insert(struct nilfs_btree *btree, | |||
374 | dkeys[index] = nilfs_bmap_key_to_dkey(key); | 338 | dkeys[index] = nilfs_bmap_key_to_dkey(key); |
375 | dptrs[index] = nilfs_bmap_ptr_to_dptr(ptr); | 339 | dptrs[index] = nilfs_bmap_ptr_to_dptr(ptr); |
376 | nchildren++; | 340 | nchildren++; |
377 | nilfs_btree_node_set_nchildren(btree, node, nchildren); | 341 | nilfs_btree_node_set_nchildren(node, nchildren); |
378 | } | 342 | } |
379 | 343 | ||
380 | /* Assume that the buffer head corresponding to node is locked. */ | 344 | /* Assume that the buffer head corresponding to node is locked. */ |
@@ -388,11 +352,11 @@ static void nilfs_btree_node_delete(struct nilfs_btree *btree, | |||
388 | __le64 *dptrs; | 352 | __le64 *dptrs; |
389 | int nchildren; | 353 | int nchildren; |
390 | 354 | ||
391 | dkeys = nilfs_btree_node_dkeys(btree, node); | 355 | dkeys = nilfs_btree_node_dkeys(node); |
392 | dptrs = nilfs_btree_node_dptrs(btree, node); | 356 | dptrs = nilfs_btree_node_dptrs(node, btree); |
393 | key = nilfs_bmap_dkey_to_key(dkeys[index]); | 357 | key = nilfs_bmap_dkey_to_key(dkeys[index]); |
394 | ptr = nilfs_bmap_dptr_to_ptr(dptrs[index]); | 358 | ptr = nilfs_bmap_dptr_to_ptr(dptrs[index]); |
395 | nchildren = nilfs_btree_node_get_nchildren(btree, node); | 359 | nchildren = nilfs_btree_node_get_nchildren(node); |
396 | if (keyp != NULL) | 360 | if (keyp != NULL) |
397 | *keyp = key; | 361 | *keyp = key; |
398 | if (ptrp != NULL) | 362 | if (ptrp != NULL) |
@@ -405,11 +369,10 @@ static void nilfs_btree_node_delete(struct nilfs_btree *btree, | |||
405 | (nchildren - index - 1) * sizeof(*dptrs)); | 369 | (nchildren - index - 1) * sizeof(*dptrs)); |
406 | } | 370 | } |
407 | nchildren--; | 371 | nchildren--; |
408 | nilfs_btree_node_set_nchildren(btree, node, nchildren); | 372 | nilfs_btree_node_set_nchildren(node, nchildren); |
409 | } | 373 | } |
410 | 374 | ||
411 | static int nilfs_btree_node_lookup(const struct nilfs_btree *btree, | 375 | static int nilfs_btree_node_lookup(const struct nilfs_btree_node *node, |
412 | const struct nilfs_btree_node *node, | ||
413 | __u64 key, int *indexp) | 376 | __u64 key, int *indexp) |
414 | { | 377 | { |
415 | __u64 nkey; | 378 | __u64 nkey; |
@@ -417,12 +380,12 @@ static int nilfs_btree_node_lookup(const struct nilfs_btree *btree, | |||
417 | 380 | ||
418 | /* binary search */ | 381 | /* binary search */ |
419 | low = 0; | 382 | low = 0; |
420 | high = nilfs_btree_node_get_nchildren(btree, node) - 1; | 383 | high = nilfs_btree_node_get_nchildren(node) - 1; |
421 | index = 0; | 384 | index = 0; |
422 | s = 0; | 385 | s = 0; |
423 | while (low <= high) { | 386 | while (low <= high) { |
424 | index = (low + high) / 2; | 387 | index = (low + high) / 2; |
425 | nkey = nilfs_btree_node_get_key(btree, node, index); | 388 | nkey = nilfs_btree_node_get_key(node, index); |
426 | if (nkey == key) { | 389 | if (nkey == key) { |
427 | s = 0; | 390 | s = 0; |
428 | goto out; | 391 | goto out; |
@@ -436,9 +399,8 @@ static int nilfs_btree_node_lookup(const struct nilfs_btree *btree, | |||
436 | } | 399 | } |
437 | 400 | ||
438 | /* adjust index */ | 401 | /* adjust index */ |
439 | if (nilfs_btree_node_get_level(btree, node) > | 402 | if (nilfs_btree_node_get_level(node) > NILFS_BTREE_LEVEL_NODE_MIN) { |
440 | NILFS_BTREE_LEVEL_NODE_MIN) { | 403 | if (s > 0 && index > 0) |
441 | if ((s > 0) && (index > 0)) | ||
442 | index--; | 404 | index--; |
443 | } else if (s < 0) | 405 | } else if (s < 0) |
444 | index++; | 406 | index++; |
@@ -456,25 +418,20 @@ nilfs_btree_get_root(const struct nilfs_btree *btree) | |||
456 | } | 418 | } |
457 | 419 | ||
458 | static inline struct nilfs_btree_node * | 420 | static inline struct nilfs_btree_node * |
459 | nilfs_btree_get_nonroot_node(const struct nilfs_btree *btree, | 421 | nilfs_btree_get_nonroot_node(const struct nilfs_btree_path *path, int level) |
460 | const struct nilfs_btree_path *path, | ||
461 | int level) | ||
462 | { | 422 | { |
463 | return (struct nilfs_btree_node *)path[level].bp_bh->b_data; | 423 | return (struct nilfs_btree_node *)path[level].bp_bh->b_data; |
464 | } | 424 | } |
465 | 425 | ||
466 | static inline struct nilfs_btree_node * | 426 | static inline struct nilfs_btree_node * |
467 | nilfs_btree_get_sib_node(const struct nilfs_btree *btree, | 427 | nilfs_btree_get_sib_node(const struct nilfs_btree_path *path, int level) |
468 | const struct nilfs_btree_path *path, | ||
469 | int level) | ||
470 | { | 428 | { |
471 | return (struct nilfs_btree_node *)path[level].bp_sib_bh->b_data; | 429 | return (struct nilfs_btree_node *)path[level].bp_sib_bh->b_data; |
472 | } | 430 | } |
473 | 431 | ||
474 | static inline int nilfs_btree_height(const struct nilfs_btree *btree) | 432 | static inline int nilfs_btree_height(const struct nilfs_btree *btree) |
475 | { | 433 | { |
476 | return nilfs_btree_node_get_level(btree, nilfs_btree_get_root(btree)) | 434 | return nilfs_btree_node_get_level(nilfs_btree_get_root(btree)) + 1; |
477 | + 1; | ||
478 | } | 435 | } |
479 | 436 | ||
480 | static inline struct nilfs_btree_node * | 437 | static inline struct nilfs_btree_node * |
@@ -484,7 +441,7 @@ nilfs_btree_get_node(const struct nilfs_btree *btree, | |||
484 | { | 441 | { |
485 | return (level == nilfs_btree_height(btree) - 1) ? | 442 | return (level == nilfs_btree_height(btree) - 1) ? |
486 | nilfs_btree_get_root(btree) : | 443 | nilfs_btree_get_root(btree) : |
487 | nilfs_btree_get_nonroot_node(btree, path, level); | 444 | nilfs_btree_get_nonroot_node(path, level); |
488 | } | 445 | } |
489 | 446 | ||
490 | static int nilfs_btree_do_lookup(const struct nilfs_btree *btree, | 447 | static int nilfs_btree_do_lookup(const struct nilfs_btree *btree, |
@@ -496,12 +453,11 @@ static int nilfs_btree_do_lookup(const struct nilfs_btree *btree, | |||
496 | int level, index, found, ret; | 453 | int level, index, found, ret; |
497 | 454 | ||
498 | node = nilfs_btree_get_root(btree); | 455 | node = nilfs_btree_get_root(btree); |
499 | level = nilfs_btree_node_get_level(btree, node); | 456 | level = nilfs_btree_node_get_level(node); |
500 | if ((level < minlevel) || | 457 | if (level < minlevel || nilfs_btree_node_get_nchildren(node) <= 0) |
501 | (nilfs_btree_node_get_nchildren(btree, node) <= 0)) | ||
502 | return -ENOENT; | 458 | return -ENOENT; |
503 | 459 | ||
504 | found = nilfs_btree_node_lookup(btree, node, key, &index); | 460 | found = nilfs_btree_node_lookup(node, key, &index); |
505 | ptr = nilfs_btree_node_get_ptr(btree, node, index); | 461 | ptr = nilfs_btree_node_get_ptr(btree, node, index); |
506 | path[level].bp_bh = NULL; | 462 | path[level].bp_bh = NULL; |
507 | path[level].bp_index = index; | 463 | path[level].bp_index = index; |
@@ -510,14 +466,13 @@ static int nilfs_btree_do_lookup(const struct nilfs_btree *btree, | |||
510 | ret = nilfs_btree_get_block(btree, ptr, &path[level].bp_bh); | 466 | ret = nilfs_btree_get_block(btree, ptr, &path[level].bp_bh); |
511 | if (ret < 0) | 467 | if (ret < 0) |
512 | return ret; | 468 | return ret; |
513 | node = nilfs_btree_get_nonroot_node(btree, path, level); | 469 | node = nilfs_btree_get_nonroot_node(path, level); |
514 | BUG_ON(level != nilfs_btree_node_get_level(btree, node)); | 470 | BUG_ON(level != nilfs_btree_node_get_level(node)); |
515 | if (!found) | 471 | if (!found) |
516 | found = nilfs_btree_node_lookup(btree, node, key, | 472 | found = nilfs_btree_node_lookup(node, key, &index); |
517 | &index); | ||
518 | else | 473 | else |
519 | index = 0; | 474 | index = 0; |
520 | if (index < nilfs_btree_node_nchildren_max(btree, node)) | 475 | if (index < nilfs_btree_node_nchildren_max(node, btree)) |
521 | ptr = nilfs_btree_node_get_ptr(btree, node, index); | 476 | ptr = nilfs_btree_node_get_ptr(btree, node, index); |
522 | else { | 477 | else { |
523 | WARN_ON(found || level != NILFS_BTREE_LEVEL_NODE_MIN); | 478 | WARN_ON(found || level != NILFS_BTREE_LEVEL_NODE_MIN); |
@@ -544,10 +499,10 @@ static int nilfs_btree_do_lookup_last(const struct nilfs_btree *btree, | |||
544 | int index, level, ret; | 499 | int index, level, ret; |
545 | 500 | ||
546 | node = nilfs_btree_get_root(btree); | 501 | node = nilfs_btree_get_root(btree); |
547 | index = nilfs_btree_node_get_nchildren(btree, node) - 1; | 502 | index = nilfs_btree_node_get_nchildren(node) - 1; |
548 | if (index < 0) | 503 | if (index < 0) |
549 | return -ENOENT; | 504 | return -ENOENT; |
550 | level = nilfs_btree_node_get_level(btree, node); | 505 | level = nilfs_btree_node_get_level(node); |
551 | ptr = nilfs_btree_node_get_ptr(btree, node, index); | 506 | ptr = nilfs_btree_node_get_ptr(btree, node, index); |
552 | path[level].bp_bh = NULL; | 507 | path[level].bp_bh = NULL; |
553 | path[level].bp_index = index; | 508 | path[level].bp_index = index; |
@@ -556,15 +511,15 @@ static int nilfs_btree_do_lookup_last(const struct nilfs_btree *btree, | |||
556 | ret = nilfs_btree_get_block(btree, ptr, &path[level].bp_bh); | 511 | ret = nilfs_btree_get_block(btree, ptr, &path[level].bp_bh); |
557 | if (ret < 0) | 512 | if (ret < 0) |
558 | return ret; | 513 | return ret; |
559 | node = nilfs_btree_get_nonroot_node(btree, path, level); | 514 | node = nilfs_btree_get_nonroot_node(path, level); |
560 | BUG_ON(level != nilfs_btree_node_get_level(btree, node)); | 515 | BUG_ON(level != nilfs_btree_node_get_level(node)); |
561 | index = nilfs_btree_node_get_nchildren(btree, node) - 1; | 516 | index = nilfs_btree_node_get_nchildren(node) - 1; |
562 | ptr = nilfs_btree_node_get_ptr(btree, node, index); | 517 | ptr = nilfs_btree_node_get_ptr(btree, node, index); |
563 | path[level].bp_index = index; | 518 | path[level].bp_index = index; |
564 | } | 519 | } |
565 | 520 | ||
566 | if (keyp != NULL) | 521 | if (keyp != NULL) |
567 | *keyp = nilfs_btree_node_get_key(btree, node, index); | 522 | *keyp = nilfs_btree_node_get_key(node, index); |
568 | if (ptrp != NULL) | 523 | if (ptrp != NULL) |
569 | *ptrp = ptr; | 524 | *ptrp = ptr; |
570 | 525 | ||
@@ -580,18 +535,18 @@ static int nilfs_btree_lookup(const struct nilfs_bmap *bmap, | |||
580 | int ret; | 535 | int ret; |
581 | 536 | ||
582 | btree = (struct nilfs_btree *)bmap; | 537 | btree = (struct nilfs_btree *)bmap; |
583 | path = nilfs_btree_alloc_path(btree); | 538 | path = nilfs_btree_alloc_path(); |
584 | if (path == NULL) | 539 | if (path == NULL) |
585 | return -ENOMEM; | 540 | return -ENOMEM; |
586 | nilfs_btree_init_path(btree, path); | 541 | nilfs_btree_init_path(path); |
587 | 542 | ||
588 | ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level); | 543 | ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level); |
589 | 544 | ||
590 | if (ptrp != NULL) | 545 | if (ptrp != NULL) |
591 | *ptrp = ptr; | 546 | *ptrp = ptr; |
592 | 547 | ||
593 | nilfs_btree_clear_path(btree, path); | 548 | nilfs_btree_release_path(path); |
594 | nilfs_btree_free_path(btree, path); | 549 | nilfs_btree_free_path(path); |
595 | 550 | ||
596 | return ret; | 551 | return ret; |
597 | } | 552 | } |
@@ -608,10 +563,10 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap, | |||
608 | int level = NILFS_BTREE_LEVEL_NODE_MIN; | 563 | int level = NILFS_BTREE_LEVEL_NODE_MIN; |
609 | int ret, cnt, index, maxlevel; | 564 | int ret, cnt, index, maxlevel; |
610 | 565 | ||
611 | path = nilfs_btree_alloc_path(btree); | 566 | path = nilfs_btree_alloc_path(); |
612 | if (path == NULL) | 567 | if (path == NULL) |
613 | return -ENOMEM; | 568 | return -ENOMEM; |
614 | nilfs_btree_init_path(btree, path); | 569 | nilfs_btree_init_path(path); |
615 | ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level); | 570 | ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level); |
616 | if (ret < 0) | 571 | if (ret < 0) |
617 | goto out; | 572 | goto out; |
@@ -631,8 +586,8 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap, | |||
631 | node = nilfs_btree_get_node(btree, path, level); | 586 | node = nilfs_btree_get_node(btree, path, level); |
632 | index = path[level].bp_index + 1; | 587 | index = path[level].bp_index + 1; |
633 | for (;;) { | 588 | for (;;) { |
634 | while (index < nilfs_btree_node_get_nchildren(btree, node)) { | 589 | while (index < nilfs_btree_node_get_nchildren(node)) { |
635 | if (nilfs_btree_node_get_key(btree, node, index) != | 590 | if (nilfs_btree_node_get_key(node, index) != |
636 | key + cnt) | 591 | key + cnt) |
637 | goto end; | 592 | goto end; |
638 | ptr2 = nilfs_btree_node_get_ptr(btree, node, index); | 593 | ptr2 = nilfs_btree_node_get_ptr(btree, node, index); |
@@ -653,8 +608,8 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap, | |||
653 | /* look-up right sibling node */ | 608 | /* look-up right sibling node */ |
654 | node = nilfs_btree_get_node(btree, path, level + 1); | 609 | node = nilfs_btree_get_node(btree, path, level + 1); |
655 | index = path[level + 1].bp_index + 1; | 610 | index = path[level + 1].bp_index + 1; |
656 | if (index >= nilfs_btree_node_get_nchildren(btree, node) || | 611 | if (index >= nilfs_btree_node_get_nchildren(node) || |
657 | nilfs_btree_node_get_key(btree, node, index) != key + cnt) | 612 | nilfs_btree_node_get_key(node, index) != key + cnt) |
658 | break; | 613 | break; |
659 | ptr2 = nilfs_btree_node_get_ptr(btree, node, index); | 614 | ptr2 = nilfs_btree_node_get_ptr(btree, node, index); |
660 | path[level + 1].bp_index = index; | 615 | path[level + 1].bp_index = index; |
@@ -664,7 +619,7 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap, | |||
664 | ret = nilfs_btree_get_block(btree, ptr2, &path[level].bp_bh); | 619 | ret = nilfs_btree_get_block(btree, ptr2, &path[level].bp_bh); |
665 | if (ret < 0) | 620 | if (ret < 0) |
666 | goto out; | 621 | goto out; |
667 | node = nilfs_btree_get_nonroot_node(btree, path, level); | 622 | node = nilfs_btree_get_nonroot_node(path, level); |
668 | index = 0; | 623 | index = 0; |
669 | path[level].bp_index = index; | 624 | path[level].bp_index = index; |
670 | } | 625 | } |
@@ -672,8 +627,8 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap, | |||
672 | *ptrp = ptr; | 627 | *ptrp = ptr; |
673 | ret = cnt; | 628 | ret = cnt; |
674 | out: | 629 | out: |
675 | nilfs_btree_clear_path(btree, path); | 630 | nilfs_btree_release_path(path); |
676 | nilfs_btree_free_path(btree, path); | 631 | nilfs_btree_free_path(path); |
677 | return ret; | 632 | return ret; |
678 | } | 633 | } |
679 | 634 | ||
@@ -685,9 +640,7 @@ static void nilfs_btree_promote_key(struct nilfs_btree *btree, | |||
685 | do { | 640 | do { |
686 | lock_buffer(path[level].bp_bh); | 641 | lock_buffer(path[level].bp_bh); |
687 | nilfs_btree_node_set_key( | 642 | nilfs_btree_node_set_key( |
688 | btree, | 643 | nilfs_btree_get_nonroot_node(path, level), |
689 | nilfs_btree_get_nonroot_node( | ||
690 | btree, path, level), | ||
691 | path[level].bp_index, key); | 644 | path[level].bp_index, key); |
692 | if (!buffer_dirty(path[level].bp_bh)) | 645 | if (!buffer_dirty(path[level].bp_bh)) |
693 | nilfs_btnode_mark_dirty(path[level].bp_bh); | 646 | nilfs_btnode_mark_dirty(path[level].bp_bh); |
@@ -698,8 +651,7 @@ static void nilfs_btree_promote_key(struct nilfs_btree *btree, | |||
698 | 651 | ||
699 | /* root */ | 652 | /* root */ |
700 | if (level == nilfs_btree_height(btree) - 1) { | 653 | if (level == nilfs_btree_height(btree) - 1) { |
701 | nilfs_btree_node_set_key(btree, | 654 | nilfs_btree_node_set_key(nilfs_btree_get_root(btree), |
702 | nilfs_btree_get_root(btree), | ||
703 | path[level].bp_index, key); | 655 | path[level].bp_index, key); |
704 | } | 656 | } |
705 | } | 657 | } |
@@ -712,7 +664,7 @@ static void nilfs_btree_do_insert(struct nilfs_btree *btree, | |||
712 | 664 | ||
713 | if (level < nilfs_btree_height(btree) - 1) { | 665 | if (level < nilfs_btree_height(btree) - 1) { |
714 | lock_buffer(path[level].bp_bh); | 666 | lock_buffer(path[level].bp_bh); |
715 | node = nilfs_btree_get_nonroot_node(btree, path, level); | 667 | node = nilfs_btree_get_nonroot_node(path, level); |
716 | nilfs_btree_node_insert(btree, node, *keyp, *ptrp, | 668 | nilfs_btree_node_insert(btree, node, *keyp, *ptrp, |
717 | path[level].bp_index); | 669 | path[level].bp_index); |
718 | if (!buffer_dirty(path[level].bp_bh)) | 670 | if (!buffer_dirty(path[level].bp_bh)) |
@@ -721,8 +673,8 @@ static void nilfs_btree_do_insert(struct nilfs_btree *btree, | |||
721 | 673 | ||
722 | if (path[level].bp_index == 0) | 674 | if (path[level].bp_index == 0) |
723 | nilfs_btree_promote_key(btree, path, level + 1, | 675 | nilfs_btree_promote_key(btree, path, level + 1, |
724 | nilfs_btree_node_get_key( | 676 | nilfs_btree_node_get_key(node, |
725 | btree, node, 0)); | 677 | 0)); |
726 | } else { | 678 | } else { |
727 | node = nilfs_btree_get_root(btree); | 679 | node = nilfs_btree_get_root(btree); |
728 | nilfs_btree_node_insert(btree, node, *keyp, *ptrp, | 680 | nilfs_btree_node_insert(btree, node, *keyp, *ptrp, |
@@ -740,10 +692,10 @@ static void nilfs_btree_carry_left(struct nilfs_btree *btree, | |||
740 | lock_buffer(path[level].bp_bh); | 692 | lock_buffer(path[level].bp_bh); |
741 | lock_buffer(path[level].bp_sib_bh); | 693 | lock_buffer(path[level].bp_sib_bh); |
742 | 694 | ||
743 | node = nilfs_btree_get_nonroot_node(btree, path, level); | 695 | node = nilfs_btree_get_nonroot_node(path, level); |
744 | left = nilfs_btree_get_sib_node(btree, path, level); | 696 | left = nilfs_btree_get_sib_node(path, level); |
745 | nchildren = nilfs_btree_node_get_nchildren(btree, node); | 697 | nchildren = nilfs_btree_node_get_nchildren(node); |
746 | lnchildren = nilfs_btree_node_get_nchildren(btree, left); | 698 | lnchildren = nilfs_btree_node_get_nchildren(left); |
747 | move = 0; | 699 | move = 0; |
748 | 700 | ||
749 | n = (nchildren + lnchildren + 1) / 2 - lnchildren; | 701 | n = (nchildren + lnchildren + 1) / 2 - lnchildren; |
@@ -764,7 +716,7 @@ static void nilfs_btree_carry_left(struct nilfs_btree *btree, | |||
764 | unlock_buffer(path[level].bp_sib_bh); | 716 | unlock_buffer(path[level].bp_sib_bh); |
765 | 717 | ||
766 | nilfs_btree_promote_key(btree, path, level + 1, | 718 | nilfs_btree_promote_key(btree, path, level + 1, |
767 | nilfs_btree_node_get_key(btree, node, 0)); | 719 | nilfs_btree_node_get_key(node, 0)); |
768 | 720 | ||
769 | if (move) { | 721 | if (move) { |
770 | brelse(path[level].bp_bh); | 722 | brelse(path[level].bp_bh); |
@@ -791,10 +743,10 @@ static void nilfs_btree_carry_right(struct nilfs_btree *btree, | |||
791 | lock_buffer(path[level].bp_bh); | 743 | lock_buffer(path[level].bp_bh); |
792 | lock_buffer(path[level].bp_sib_bh); | 744 | lock_buffer(path[level].bp_sib_bh); |
793 | 745 | ||
794 | node = nilfs_btree_get_nonroot_node(btree, path, level); | 746 | node = nilfs_btree_get_nonroot_node(path, level); |
795 | right = nilfs_btree_get_sib_node(btree, path, level); | 747 | right = nilfs_btree_get_sib_node(path, level); |
796 | nchildren = nilfs_btree_node_get_nchildren(btree, node); | 748 | nchildren = nilfs_btree_node_get_nchildren(node); |
797 | rnchildren = nilfs_btree_node_get_nchildren(btree, right); | 749 | rnchildren = nilfs_btree_node_get_nchildren(right); |
798 | move = 0; | 750 | move = 0; |
799 | 751 | ||
800 | n = (nchildren + rnchildren + 1) / 2 - rnchildren; | 752 | n = (nchildren + rnchildren + 1) / 2 - rnchildren; |
@@ -816,15 +768,14 @@ static void nilfs_btree_carry_right(struct nilfs_btree *btree, | |||
816 | 768 | ||
817 | path[level + 1].bp_index++; | 769 | path[level + 1].bp_index++; |
818 | nilfs_btree_promote_key(btree, path, level + 1, | 770 | nilfs_btree_promote_key(btree, path, level + 1, |
819 | nilfs_btree_node_get_key(btree, right, 0)); | 771 | nilfs_btree_node_get_key(right, 0)); |
820 | path[level + 1].bp_index--; | 772 | path[level + 1].bp_index--; |
821 | 773 | ||
822 | if (move) { | 774 | if (move) { |
823 | brelse(path[level].bp_bh); | 775 | brelse(path[level].bp_bh); |
824 | path[level].bp_bh = path[level].bp_sib_bh; | 776 | path[level].bp_bh = path[level].bp_sib_bh; |
825 | path[level].bp_sib_bh = NULL; | 777 | path[level].bp_sib_bh = NULL; |
826 | path[level].bp_index -= | 778 | path[level].bp_index -= nilfs_btree_node_get_nchildren(node); |
827 | nilfs_btree_node_get_nchildren(btree, node); | ||
828 | path[level + 1].bp_index++; | 779 | path[level + 1].bp_index++; |
829 | } else { | 780 | } else { |
830 | brelse(path[level].bp_sib_bh); | 781 | brelse(path[level].bp_sib_bh); |
@@ -846,9 +797,9 @@ static void nilfs_btree_split(struct nilfs_btree *btree, | |||
846 | lock_buffer(path[level].bp_bh); | 797 | lock_buffer(path[level].bp_bh); |
847 | lock_buffer(path[level].bp_sib_bh); | 798 | lock_buffer(path[level].bp_sib_bh); |
848 | 799 | ||
849 | node = nilfs_btree_get_nonroot_node(btree, path, level); | 800 | node = nilfs_btree_get_nonroot_node(path, level); |
850 | right = nilfs_btree_get_sib_node(btree, path, level); | 801 | right = nilfs_btree_get_sib_node(path, level); |
851 | nchildren = nilfs_btree_node_get_nchildren(btree, node); | 802 | nchildren = nilfs_btree_node_get_nchildren(node); |
852 | move = 0; | 803 | move = 0; |
853 | 804 | ||
854 | n = (nchildren + 1) / 2; | 805 | n = (nchildren + 1) / 2; |
@@ -867,16 +818,15 @@ static void nilfs_btree_split(struct nilfs_btree *btree, | |||
867 | unlock_buffer(path[level].bp_bh); | 818 | unlock_buffer(path[level].bp_bh); |
868 | unlock_buffer(path[level].bp_sib_bh); | 819 | unlock_buffer(path[level].bp_sib_bh); |
869 | 820 | ||
870 | newkey = nilfs_btree_node_get_key(btree, right, 0); | 821 | newkey = nilfs_btree_node_get_key(right, 0); |
871 | newptr = path[level].bp_newreq.bpr_ptr; | 822 | newptr = path[level].bp_newreq.bpr_ptr; |
872 | 823 | ||
873 | if (move) { | 824 | if (move) { |
874 | path[level].bp_index -= | 825 | path[level].bp_index -= nilfs_btree_node_get_nchildren(node); |
875 | nilfs_btree_node_get_nchildren(btree, node); | ||
876 | nilfs_btree_node_insert(btree, right, *keyp, *ptrp, | 826 | nilfs_btree_node_insert(btree, right, *keyp, *ptrp, |
877 | path[level].bp_index); | 827 | path[level].bp_index); |
878 | 828 | ||
879 | *keyp = nilfs_btree_node_get_key(btree, right, 0); | 829 | *keyp = nilfs_btree_node_get_key(right, 0); |
880 | *ptrp = path[level].bp_newreq.bpr_ptr; | 830 | *ptrp = path[level].bp_newreq.bpr_ptr; |
881 | 831 | ||
882 | brelse(path[level].bp_bh); | 832 | brelse(path[level].bp_bh); |
@@ -885,7 +835,7 @@ static void nilfs_btree_split(struct nilfs_btree *btree, | |||
885 | } else { | 835 | } else { |
886 | nilfs_btree_do_insert(btree, path, level, keyp, ptrp); | 836 | nilfs_btree_do_insert(btree, path, level, keyp, ptrp); |
887 | 837 | ||
888 | *keyp = nilfs_btree_node_get_key(btree, right, 0); | 838 | *keyp = nilfs_btree_node_get_key(right, 0); |
889 | *ptrp = path[level].bp_newreq.bpr_ptr; | 839 | *ptrp = path[level].bp_newreq.bpr_ptr; |
890 | 840 | ||
891 | brelse(path[level].bp_sib_bh); | 841 | brelse(path[level].bp_sib_bh); |
@@ -905,12 +855,12 @@ static void nilfs_btree_grow(struct nilfs_btree *btree, | |||
905 | lock_buffer(path[level].bp_sib_bh); | 855 | lock_buffer(path[level].bp_sib_bh); |
906 | 856 | ||
907 | root = nilfs_btree_get_root(btree); | 857 | root = nilfs_btree_get_root(btree); |
908 | child = nilfs_btree_get_sib_node(btree, path, level); | 858 | child = nilfs_btree_get_sib_node(path, level); |
909 | 859 | ||
910 | n = nilfs_btree_node_get_nchildren(btree, root); | 860 | n = nilfs_btree_node_get_nchildren(root); |
911 | 861 | ||
912 | nilfs_btree_node_move_right(btree, root, child, n); | 862 | nilfs_btree_node_move_right(btree, root, child, n); |
913 | nilfs_btree_node_set_level(btree, root, level + 1); | 863 | nilfs_btree_node_set_level(root, level + 1); |
914 | 864 | ||
915 | if (!buffer_dirty(path[level].bp_sib_bh)) | 865 | if (!buffer_dirty(path[level].bp_sib_bh)) |
916 | nilfs_btnode_mark_dirty(path[level].bp_sib_bh); | 866 | nilfs_btnode_mark_dirty(path[level].bp_sib_bh); |
@@ -922,7 +872,7 @@ static void nilfs_btree_grow(struct nilfs_btree *btree, | |||
922 | 872 | ||
923 | nilfs_btree_do_insert(btree, path, level, keyp, ptrp); | 873 | nilfs_btree_do_insert(btree, path, level, keyp, ptrp); |
924 | 874 | ||
925 | *keyp = nilfs_btree_node_get_key(btree, child, 0); | 875 | *keyp = nilfs_btree_node_get_key(child, 0); |
926 | *ptrp = path[level].bp_newreq.bpr_ptr; | 876 | *ptrp = path[level].bp_newreq.bpr_ptr; |
927 | } | 877 | } |
928 | 878 | ||
@@ -990,26 +940,29 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree, | |||
990 | struct nilfs_btree_node *node, *parent, *sib; | 940 | struct nilfs_btree_node *node, *parent, *sib; |
991 | __u64 sibptr; | 941 | __u64 sibptr; |
992 | int pindex, level, ret; | 942 | int pindex, level, ret; |
943 | struct inode *dat = NULL; | ||
993 | 944 | ||
994 | stats->bs_nblocks = 0; | 945 | stats->bs_nblocks = 0; |
995 | level = NILFS_BTREE_LEVEL_DATA; | 946 | level = NILFS_BTREE_LEVEL_DATA; |
996 | 947 | ||
997 | /* allocate a new ptr for data block */ | 948 | /* allocate a new ptr for data block */ |
998 | if (NILFS_BMAP_USE_VBN(&btree->bt_bmap)) | 949 | if (NILFS_BMAP_USE_VBN(&btree->bt_bmap)) { |
999 | path[level].bp_newreq.bpr_ptr = | 950 | path[level].bp_newreq.bpr_ptr = |
1000 | nilfs_btree_find_target_v(btree, path, key); | 951 | nilfs_btree_find_target_v(btree, path, key); |
952 | dat = nilfs_bmap_get_dat(&btree->bt_bmap); | ||
953 | } | ||
1001 | 954 | ||
1002 | ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap, | 955 | ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap, |
1003 | &path[level].bp_newreq); | 956 | &path[level].bp_newreq, dat); |
1004 | if (ret < 0) | 957 | if (ret < 0) |
1005 | goto err_out_data; | 958 | goto err_out_data; |
1006 | 959 | ||
1007 | for (level = NILFS_BTREE_LEVEL_NODE_MIN; | 960 | for (level = NILFS_BTREE_LEVEL_NODE_MIN; |
1008 | level < nilfs_btree_height(btree) - 1; | 961 | level < nilfs_btree_height(btree) - 1; |
1009 | level++) { | 962 | level++) { |
1010 | node = nilfs_btree_get_nonroot_node(btree, path, level); | 963 | node = nilfs_btree_get_nonroot_node(path, level); |
1011 | if (nilfs_btree_node_get_nchildren(btree, node) < | 964 | if (nilfs_btree_node_get_nchildren(node) < |
1012 | nilfs_btree_node_nchildren_max(btree, node)) { | 965 | nilfs_btree_node_nchildren_max(node, btree)) { |
1013 | path[level].bp_op = nilfs_btree_do_insert; | 966 | path[level].bp_op = nilfs_btree_do_insert; |
1014 | stats->bs_nblocks++; | 967 | stats->bs_nblocks++; |
1015 | goto out; | 968 | goto out; |
@@ -1026,8 +979,8 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree, | |||
1026 | if (ret < 0) | 979 | if (ret < 0) |
1027 | goto err_out_child_node; | 980 | goto err_out_child_node; |
1028 | sib = (struct nilfs_btree_node *)bh->b_data; | 981 | sib = (struct nilfs_btree_node *)bh->b_data; |
1029 | if (nilfs_btree_node_get_nchildren(btree, sib) < | 982 | if (nilfs_btree_node_get_nchildren(sib) < |
1030 | nilfs_btree_node_nchildren_max(btree, sib)) { | 983 | nilfs_btree_node_nchildren_max(sib, btree)) { |
1031 | path[level].bp_sib_bh = bh; | 984 | path[level].bp_sib_bh = bh; |
1032 | path[level].bp_op = nilfs_btree_carry_left; | 985 | path[level].bp_op = nilfs_btree_carry_left; |
1033 | stats->bs_nblocks++; | 986 | stats->bs_nblocks++; |
@@ -1038,15 +991,15 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree, | |||
1038 | 991 | ||
1039 | /* right sibling */ | 992 | /* right sibling */ |
1040 | if (pindex < | 993 | if (pindex < |
1041 | nilfs_btree_node_get_nchildren(btree, parent) - 1) { | 994 | nilfs_btree_node_get_nchildren(parent) - 1) { |
1042 | sibptr = nilfs_btree_node_get_ptr(btree, parent, | 995 | sibptr = nilfs_btree_node_get_ptr(btree, parent, |
1043 | pindex + 1); | 996 | pindex + 1); |
1044 | ret = nilfs_btree_get_block(btree, sibptr, &bh); | 997 | ret = nilfs_btree_get_block(btree, sibptr, &bh); |
1045 | if (ret < 0) | 998 | if (ret < 0) |
1046 | goto err_out_child_node; | 999 | goto err_out_child_node; |
1047 | sib = (struct nilfs_btree_node *)bh->b_data; | 1000 | sib = (struct nilfs_btree_node *)bh->b_data; |
1048 | if (nilfs_btree_node_get_nchildren(btree, sib) < | 1001 | if (nilfs_btree_node_get_nchildren(sib) < |
1049 | nilfs_btree_node_nchildren_max(btree, sib)) { | 1002 | nilfs_btree_node_nchildren_max(sib, btree)) { |
1050 | path[level].bp_sib_bh = bh; | 1003 | path[level].bp_sib_bh = bh; |
1051 | path[level].bp_op = nilfs_btree_carry_right; | 1004 | path[level].bp_op = nilfs_btree_carry_right; |
1052 | stats->bs_nblocks++; | 1005 | stats->bs_nblocks++; |
@@ -1059,7 +1012,7 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree, | |||
1059 | path[level].bp_newreq.bpr_ptr = | 1012 | path[level].bp_newreq.bpr_ptr = |
1060 | path[level - 1].bp_newreq.bpr_ptr + 1; | 1013 | path[level - 1].bp_newreq.bpr_ptr + 1; |
1061 | ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap, | 1014 | ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap, |
1062 | &path[level].bp_newreq); | 1015 | &path[level].bp_newreq, dat); |
1063 | if (ret < 0) | 1016 | if (ret < 0) |
1064 | goto err_out_child_node; | 1017 | goto err_out_child_node; |
1065 | ret = nilfs_btree_get_new_block(btree, | 1018 | ret = nilfs_btree_get_new_block(btree, |
@@ -1081,8 +1034,8 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree, | |||
1081 | 1034 | ||
1082 | /* root */ | 1035 | /* root */ |
1083 | node = nilfs_btree_get_root(btree); | 1036 | node = nilfs_btree_get_root(btree); |
1084 | if (nilfs_btree_node_get_nchildren(btree, node) < | 1037 | if (nilfs_btree_node_get_nchildren(node) < |
1085 | nilfs_btree_node_nchildren_max(btree, node)) { | 1038 | nilfs_btree_node_nchildren_max(node, btree)) { |
1086 | path[level].bp_op = nilfs_btree_do_insert; | 1039 | path[level].bp_op = nilfs_btree_do_insert; |
1087 | stats->bs_nblocks++; | 1040 | stats->bs_nblocks++; |
1088 | goto out; | 1041 | goto out; |
@@ -1091,7 +1044,7 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree, | |||
1091 | /* grow */ | 1044 | /* grow */ |
1092 | path[level].bp_newreq.bpr_ptr = path[level - 1].bp_newreq.bpr_ptr + 1; | 1045 | path[level].bp_newreq.bpr_ptr = path[level - 1].bp_newreq.bpr_ptr + 1; |
1093 | ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap, | 1046 | ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap, |
1094 | &path[level].bp_newreq); | 1047 | &path[level].bp_newreq, dat); |
1095 | if (ret < 0) | 1048 | if (ret < 0) |
1096 | goto err_out_child_node; | 1049 | goto err_out_child_node; |
1097 | ret = nilfs_btree_get_new_block(btree, path[level].bp_newreq.bpr_ptr, | 1050 | ret = nilfs_btree_get_new_block(btree, path[level].bp_newreq.bpr_ptr, |
@@ -1119,16 +1072,18 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree, | |||
1119 | 1072 | ||
1120 | /* error */ | 1073 | /* error */ |
1121 | err_out_curr_node: | 1074 | err_out_curr_node: |
1122 | nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq); | 1075 | nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq, |
1076 | dat); | ||
1123 | err_out_child_node: | 1077 | err_out_child_node: |
1124 | for (level--; level > NILFS_BTREE_LEVEL_DATA; level--) { | 1078 | for (level--; level > NILFS_BTREE_LEVEL_DATA; level--) { |
1125 | nilfs_btnode_delete(path[level].bp_sib_bh); | 1079 | nilfs_btnode_delete(path[level].bp_sib_bh); |
1126 | nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, | 1080 | nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, |
1127 | &path[level].bp_newreq); | 1081 | &path[level].bp_newreq, dat); |
1128 | 1082 | ||
1129 | } | 1083 | } |
1130 | 1084 | ||
1131 | nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq); | 1085 | nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq, |
1086 | dat); | ||
1132 | err_out_data: | 1087 | err_out_data: |
1133 | *levelp = level; | 1088 | *levelp = level; |
1134 | stats->bs_nblocks = 0; | 1089 | stats->bs_nblocks = 0; |
@@ -1139,16 +1094,19 @@ static void nilfs_btree_commit_insert(struct nilfs_btree *btree, | |||
1139 | struct nilfs_btree_path *path, | 1094 | struct nilfs_btree_path *path, |
1140 | int maxlevel, __u64 key, __u64 ptr) | 1095 | int maxlevel, __u64 key, __u64 ptr) |
1141 | { | 1096 | { |
1097 | struct inode *dat = NULL; | ||
1142 | int level; | 1098 | int level; |
1143 | 1099 | ||
1144 | set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr)); | 1100 | set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr)); |
1145 | ptr = path[NILFS_BTREE_LEVEL_DATA].bp_newreq.bpr_ptr; | 1101 | ptr = path[NILFS_BTREE_LEVEL_DATA].bp_newreq.bpr_ptr; |
1146 | if (NILFS_BMAP_USE_VBN(&btree->bt_bmap)) | 1102 | if (NILFS_BMAP_USE_VBN(&btree->bt_bmap)) { |
1147 | nilfs_btree_set_target_v(btree, key, ptr); | 1103 | nilfs_btree_set_target_v(btree, key, ptr); |
1104 | dat = nilfs_bmap_get_dat(&btree->bt_bmap); | ||
1105 | } | ||
1148 | 1106 | ||
1149 | for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) { | 1107 | for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) { |
1150 | nilfs_bmap_commit_alloc_ptr(&btree->bt_bmap, | 1108 | nilfs_bmap_commit_alloc_ptr(&btree->bt_bmap, |
1151 | &path[level - 1].bp_newreq); | 1109 | &path[level - 1].bp_newreq, dat); |
1152 | path[level].bp_op(btree, path, level, &key, &ptr); | 1110 | path[level].bp_op(btree, path, level, &key, &ptr); |
1153 | } | 1111 | } |
1154 | 1112 | ||
@@ -1164,10 +1122,10 @@ static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) | |||
1164 | int level, ret; | 1122 | int level, ret; |
1165 | 1123 | ||
1166 | btree = (struct nilfs_btree *)bmap; | 1124 | btree = (struct nilfs_btree *)bmap; |
1167 | path = nilfs_btree_alloc_path(btree); | 1125 | path = nilfs_btree_alloc_path(); |
1168 | if (path == NULL) | 1126 | if (path == NULL) |
1169 | return -ENOMEM; | 1127 | return -ENOMEM; |
1170 | nilfs_btree_init_path(btree, path); | 1128 | nilfs_btree_init_path(path); |
1171 | 1129 | ||
1172 | ret = nilfs_btree_do_lookup(btree, path, key, NULL, | 1130 | ret = nilfs_btree_do_lookup(btree, path, key, NULL, |
1173 | NILFS_BTREE_LEVEL_NODE_MIN); | 1131 | NILFS_BTREE_LEVEL_NODE_MIN); |
@@ -1184,8 +1142,8 @@ static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) | |||
1184 | nilfs_bmap_add_blocks(bmap, stats.bs_nblocks); | 1142 | nilfs_bmap_add_blocks(bmap, stats.bs_nblocks); |
1185 | 1143 | ||
1186 | out: | 1144 | out: |
1187 | nilfs_btree_clear_path(btree, path); | 1145 | nilfs_btree_release_path(path); |
1188 | nilfs_btree_free_path(btree, path); | 1146 | nilfs_btree_free_path(path); |
1189 | return ret; | 1147 | return ret; |
1190 | } | 1148 | } |
1191 | 1149 | ||
@@ -1197,7 +1155,7 @@ static void nilfs_btree_do_delete(struct nilfs_btree *btree, | |||
1197 | 1155 | ||
1198 | if (level < nilfs_btree_height(btree) - 1) { | 1156 | if (level < nilfs_btree_height(btree) - 1) { |
1199 | lock_buffer(path[level].bp_bh); | 1157 | lock_buffer(path[level].bp_bh); |
1200 | node = nilfs_btree_get_nonroot_node(btree, path, level); | 1158 | node = nilfs_btree_get_nonroot_node(path, level); |
1201 | nilfs_btree_node_delete(btree, node, keyp, ptrp, | 1159 | nilfs_btree_node_delete(btree, node, keyp, ptrp, |
1202 | path[level].bp_index); | 1160 | path[level].bp_index); |
1203 | if (!buffer_dirty(path[level].bp_bh)) | 1161 | if (!buffer_dirty(path[level].bp_bh)) |
@@ -1205,7 +1163,7 @@ static void nilfs_btree_do_delete(struct nilfs_btree *btree, | |||
1205 | unlock_buffer(path[level].bp_bh); | 1163 | unlock_buffer(path[level].bp_bh); |
1206 | if (path[level].bp_index == 0) | 1164 | if (path[level].bp_index == 0) |
1207 | nilfs_btree_promote_key(btree, path, level + 1, | 1165 | nilfs_btree_promote_key(btree, path, level + 1, |
1208 | nilfs_btree_node_get_key(btree, node, 0)); | 1166 | nilfs_btree_node_get_key(node, 0)); |
1209 | } else { | 1167 | } else { |
1210 | node = nilfs_btree_get_root(btree); | 1168 | node = nilfs_btree_get_root(btree); |
1211 | nilfs_btree_node_delete(btree, node, keyp, ptrp, | 1169 | nilfs_btree_node_delete(btree, node, keyp, ptrp, |
@@ -1225,10 +1183,10 @@ static void nilfs_btree_borrow_left(struct nilfs_btree *btree, | |||
1225 | lock_buffer(path[level].bp_bh); | 1183 | lock_buffer(path[level].bp_bh); |
1226 | lock_buffer(path[level].bp_sib_bh); | 1184 | lock_buffer(path[level].bp_sib_bh); |
1227 | 1185 | ||
1228 | node = nilfs_btree_get_nonroot_node(btree, path, level); | 1186 | node = nilfs_btree_get_nonroot_node(path, level); |
1229 | left = nilfs_btree_get_sib_node(btree, path, level); | 1187 | left = nilfs_btree_get_sib_node(path, level); |
1230 | nchildren = nilfs_btree_node_get_nchildren(btree, node); | 1188 | nchildren = nilfs_btree_node_get_nchildren(node); |
1231 | lnchildren = nilfs_btree_node_get_nchildren(btree, left); | 1189 | lnchildren = nilfs_btree_node_get_nchildren(left); |
1232 | 1190 | ||
1233 | n = (nchildren + lnchildren) / 2 - nchildren; | 1191 | n = (nchildren + lnchildren) / 2 - nchildren; |
1234 | 1192 | ||
@@ -1243,7 +1201,7 @@ static void nilfs_btree_borrow_left(struct nilfs_btree *btree, | |||
1243 | unlock_buffer(path[level].bp_sib_bh); | 1201 | unlock_buffer(path[level].bp_sib_bh); |
1244 | 1202 | ||
1245 | nilfs_btree_promote_key(btree, path, level + 1, | 1203 | nilfs_btree_promote_key(btree, path, level + 1, |
1246 | nilfs_btree_node_get_key(btree, node, 0)); | 1204 | nilfs_btree_node_get_key(node, 0)); |
1247 | 1205 | ||
1248 | brelse(path[level].bp_sib_bh); | 1206 | brelse(path[level].bp_sib_bh); |
1249 | path[level].bp_sib_bh = NULL; | 1207 | path[level].bp_sib_bh = NULL; |
@@ -1262,10 +1220,10 @@ static void nilfs_btree_borrow_right(struct nilfs_btree *btree, | |||
1262 | lock_buffer(path[level].bp_bh); | 1220 | lock_buffer(path[level].bp_bh); |
1263 | lock_buffer(path[level].bp_sib_bh); | 1221 | lock_buffer(path[level].bp_sib_bh); |
1264 | 1222 | ||
1265 | node = nilfs_btree_get_nonroot_node(btree, path, level); | 1223 | node = nilfs_btree_get_nonroot_node(path, level); |
1266 | right = nilfs_btree_get_sib_node(btree, path, level); | 1224 | right = nilfs_btree_get_sib_node(path, level); |
1267 | nchildren = nilfs_btree_node_get_nchildren(btree, node); | 1225 | nchildren = nilfs_btree_node_get_nchildren(node); |
1268 | rnchildren = nilfs_btree_node_get_nchildren(btree, right); | 1226 | rnchildren = nilfs_btree_node_get_nchildren(right); |
1269 | 1227 | ||
1270 | n = (nchildren + rnchildren) / 2 - nchildren; | 1228 | n = (nchildren + rnchildren) / 2 - nchildren; |
1271 | 1229 | ||
@@ -1281,7 +1239,7 @@ static void nilfs_btree_borrow_right(struct nilfs_btree *btree, | |||
1281 | 1239 | ||
1282 | path[level + 1].bp_index++; | 1240 | path[level + 1].bp_index++; |
1283 | nilfs_btree_promote_key(btree, path, level + 1, | 1241 | nilfs_btree_promote_key(btree, path, level + 1, |
1284 | nilfs_btree_node_get_key(btree, right, 0)); | 1242 | nilfs_btree_node_get_key(right, 0)); |
1285 | path[level + 1].bp_index--; | 1243 | path[level + 1].bp_index--; |
1286 | 1244 | ||
1287 | brelse(path[level].bp_sib_bh); | 1245 | brelse(path[level].bp_sib_bh); |
@@ -1300,10 +1258,10 @@ static void nilfs_btree_concat_left(struct nilfs_btree *btree, | |||
1300 | lock_buffer(path[level].bp_bh); | 1258 | lock_buffer(path[level].bp_bh); |
1301 | lock_buffer(path[level].bp_sib_bh); | 1259 | lock_buffer(path[level].bp_sib_bh); |
1302 | 1260 | ||
1303 | node = nilfs_btree_get_nonroot_node(btree, path, level); | 1261 | node = nilfs_btree_get_nonroot_node(path, level); |
1304 | left = nilfs_btree_get_sib_node(btree, path, level); | 1262 | left = nilfs_btree_get_sib_node(path, level); |
1305 | 1263 | ||
1306 | n = nilfs_btree_node_get_nchildren(btree, node); | 1264 | n = nilfs_btree_node_get_nchildren(node); |
1307 | 1265 | ||
1308 | nilfs_btree_node_move_left(btree, left, node, n); | 1266 | nilfs_btree_node_move_left(btree, left, node, n); |
1309 | 1267 | ||
@@ -1316,7 +1274,7 @@ static void nilfs_btree_concat_left(struct nilfs_btree *btree, | |||
1316 | nilfs_btnode_delete(path[level].bp_bh); | 1274 | nilfs_btnode_delete(path[level].bp_bh); |
1317 | path[level].bp_bh = path[level].bp_sib_bh; | 1275 | path[level].bp_bh = path[level].bp_sib_bh; |
1318 | path[level].bp_sib_bh = NULL; | 1276 | path[level].bp_sib_bh = NULL; |
1319 | path[level].bp_index += nilfs_btree_node_get_nchildren(btree, left); | 1277 | path[level].bp_index += nilfs_btree_node_get_nchildren(left); |
1320 | } | 1278 | } |
1321 | 1279 | ||
1322 | static void nilfs_btree_concat_right(struct nilfs_btree *btree, | 1280 | static void nilfs_btree_concat_right(struct nilfs_btree *btree, |
@@ -1331,10 +1289,10 @@ static void nilfs_btree_concat_right(struct nilfs_btree *btree, | |||
1331 | lock_buffer(path[level].bp_bh); | 1289 | lock_buffer(path[level].bp_bh); |
1332 | lock_buffer(path[level].bp_sib_bh); | 1290 | lock_buffer(path[level].bp_sib_bh); |
1333 | 1291 | ||
1334 | node = nilfs_btree_get_nonroot_node(btree, path, level); | 1292 | node = nilfs_btree_get_nonroot_node(path, level); |
1335 | right = nilfs_btree_get_sib_node(btree, path, level); | 1293 | right = nilfs_btree_get_sib_node(path, level); |
1336 | 1294 | ||
1337 | n = nilfs_btree_node_get_nchildren(btree, right); | 1295 | n = nilfs_btree_node_get_nchildren(right); |
1338 | 1296 | ||
1339 | nilfs_btree_node_move_left(btree, node, right, n); | 1297 | nilfs_btree_node_move_left(btree, node, right, n); |
1340 | 1298 | ||
@@ -1360,11 +1318,11 @@ static void nilfs_btree_shrink(struct nilfs_btree *btree, | |||
1360 | 1318 | ||
1361 | lock_buffer(path[level].bp_bh); | 1319 | lock_buffer(path[level].bp_bh); |
1362 | root = nilfs_btree_get_root(btree); | 1320 | root = nilfs_btree_get_root(btree); |
1363 | child = nilfs_btree_get_nonroot_node(btree, path, level); | 1321 | child = nilfs_btree_get_nonroot_node(path, level); |
1364 | 1322 | ||
1365 | nilfs_btree_node_delete(btree, root, NULL, NULL, 0); | 1323 | nilfs_btree_node_delete(btree, root, NULL, NULL, 0); |
1366 | nilfs_btree_node_set_level(btree, root, level); | 1324 | nilfs_btree_node_set_level(root, level); |
1367 | n = nilfs_btree_node_get_nchildren(btree, child); | 1325 | n = nilfs_btree_node_get_nchildren(child); |
1368 | nilfs_btree_node_move_left(btree, root, child, n); | 1326 | nilfs_btree_node_move_left(btree, root, child, n); |
1369 | unlock_buffer(path[level].bp_bh); | 1327 | unlock_buffer(path[level].bp_bh); |
1370 | 1328 | ||
@@ -1376,7 +1334,8 @@ static void nilfs_btree_shrink(struct nilfs_btree *btree, | |||
1376 | static int nilfs_btree_prepare_delete(struct nilfs_btree *btree, | 1334 | static int nilfs_btree_prepare_delete(struct nilfs_btree *btree, |
1377 | struct nilfs_btree_path *path, | 1335 | struct nilfs_btree_path *path, |
1378 | int *levelp, | 1336 | int *levelp, |
1379 | struct nilfs_bmap_stats *stats) | 1337 | struct nilfs_bmap_stats *stats, |
1338 | struct inode *dat) | ||
1380 | { | 1339 | { |
1381 | struct buffer_head *bh; | 1340 | struct buffer_head *bh; |
1382 | struct nilfs_btree_node *node, *parent, *sib; | 1341 | struct nilfs_btree_node *node, *parent, *sib; |
@@ -1388,17 +1347,17 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree, | |||
1388 | for (level = NILFS_BTREE_LEVEL_NODE_MIN; | 1347 | for (level = NILFS_BTREE_LEVEL_NODE_MIN; |
1389 | level < nilfs_btree_height(btree) - 1; | 1348 | level < nilfs_btree_height(btree) - 1; |
1390 | level++) { | 1349 | level++) { |
1391 | node = nilfs_btree_get_nonroot_node(btree, path, level); | 1350 | node = nilfs_btree_get_nonroot_node(path, level); |
1392 | path[level].bp_oldreq.bpr_ptr = | 1351 | path[level].bp_oldreq.bpr_ptr = |
1393 | nilfs_btree_node_get_ptr(btree, node, | 1352 | nilfs_btree_node_get_ptr(btree, node, |
1394 | path[level].bp_index); | 1353 | path[level].bp_index); |
1395 | ret = nilfs_bmap_prepare_end_ptr(&btree->bt_bmap, | 1354 | ret = nilfs_bmap_prepare_end_ptr(&btree->bt_bmap, |
1396 | &path[level].bp_oldreq); | 1355 | &path[level].bp_oldreq, dat); |
1397 | if (ret < 0) | 1356 | if (ret < 0) |
1398 | goto err_out_child_node; | 1357 | goto err_out_child_node; |
1399 | 1358 | ||
1400 | if (nilfs_btree_node_get_nchildren(btree, node) > | 1359 | if (nilfs_btree_node_get_nchildren(node) > |
1401 | nilfs_btree_node_nchildren_min(btree, node)) { | 1360 | nilfs_btree_node_nchildren_min(node, btree)) { |
1402 | path[level].bp_op = nilfs_btree_do_delete; | 1361 | path[level].bp_op = nilfs_btree_do_delete; |
1403 | stats->bs_nblocks++; | 1362 | stats->bs_nblocks++; |
1404 | goto out; | 1363 | goto out; |
@@ -1415,8 +1374,8 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree, | |||
1415 | if (ret < 0) | 1374 | if (ret < 0) |
1416 | goto err_out_curr_node; | 1375 | goto err_out_curr_node; |
1417 | sib = (struct nilfs_btree_node *)bh->b_data; | 1376 | sib = (struct nilfs_btree_node *)bh->b_data; |
1418 | if (nilfs_btree_node_get_nchildren(btree, sib) > | 1377 | if (nilfs_btree_node_get_nchildren(sib) > |
1419 | nilfs_btree_node_nchildren_min(btree, sib)) { | 1378 | nilfs_btree_node_nchildren_min(sib, btree)) { |
1420 | path[level].bp_sib_bh = bh; | 1379 | path[level].bp_sib_bh = bh; |
1421 | path[level].bp_op = nilfs_btree_borrow_left; | 1380 | path[level].bp_op = nilfs_btree_borrow_left; |
1422 | stats->bs_nblocks++; | 1381 | stats->bs_nblocks++; |
@@ -1428,7 +1387,7 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree, | |||
1428 | /* continue; */ | 1387 | /* continue; */ |
1429 | } | 1388 | } |
1430 | } else if (pindex < | 1389 | } else if (pindex < |
1431 | nilfs_btree_node_get_nchildren(btree, parent) - 1) { | 1390 | nilfs_btree_node_get_nchildren(parent) - 1) { |
1432 | /* right sibling */ | 1391 | /* right sibling */ |
1433 | sibptr = nilfs_btree_node_get_ptr(btree, parent, | 1392 | sibptr = nilfs_btree_node_get_ptr(btree, parent, |
1434 | pindex + 1); | 1393 | pindex + 1); |
@@ -1436,8 +1395,8 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree, | |||
1436 | if (ret < 0) | 1395 | if (ret < 0) |
1437 | goto err_out_curr_node; | 1396 | goto err_out_curr_node; |
1438 | sib = (struct nilfs_btree_node *)bh->b_data; | 1397 | sib = (struct nilfs_btree_node *)bh->b_data; |
1439 | if (nilfs_btree_node_get_nchildren(btree, sib) > | 1398 | if (nilfs_btree_node_get_nchildren(sib) > |
1440 | nilfs_btree_node_nchildren_min(btree, sib)) { | 1399 | nilfs_btree_node_nchildren_min(sib, btree)) { |
1441 | path[level].bp_sib_bh = bh; | 1400 | path[level].bp_sib_bh = bh; |
1442 | path[level].bp_op = nilfs_btree_borrow_right; | 1401 | path[level].bp_op = nilfs_btree_borrow_right; |
1443 | stats->bs_nblocks++; | 1402 | stats->bs_nblocks++; |
@@ -1452,7 +1411,7 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree, | |||
1452 | /* no siblings */ | 1411 | /* no siblings */ |
1453 | /* the only child of the root node */ | 1412 | /* the only child of the root node */ |
1454 | WARN_ON(level != nilfs_btree_height(btree) - 2); | 1413 | WARN_ON(level != nilfs_btree_height(btree) - 2); |
1455 | if (nilfs_btree_node_get_nchildren(btree, node) - 1 <= | 1414 | if (nilfs_btree_node_get_nchildren(node) - 1 <= |
1456 | NILFS_BTREE_ROOT_NCHILDREN_MAX) { | 1415 | NILFS_BTREE_ROOT_NCHILDREN_MAX) { |
1457 | path[level].bp_op = nilfs_btree_shrink; | 1416 | path[level].bp_op = nilfs_btree_shrink; |
1458 | stats->bs_nblocks += 2; | 1417 | stats->bs_nblocks += 2; |
@@ -1471,7 +1430,7 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree, | |||
1471 | nilfs_btree_node_get_ptr(btree, node, path[level].bp_index); | 1430 | nilfs_btree_node_get_ptr(btree, node, path[level].bp_index); |
1472 | 1431 | ||
1473 | ret = nilfs_bmap_prepare_end_ptr(&btree->bt_bmap, | 1432 | ret = nilfs_bmap_prepare_end_ptr(&btree->bt_bmap, |
1474 | &path[level].bp_oldreq); | 1433 | &path[level].bp_oldreq, dat); |
1475 | if (ret < 0) | 1434 | if (ret < 0) |
1476 | goto err_out_child_node; | 1435 | goto err_out_child_node; |
1477 | 1436 | ||
@@ -1486,12 +1445,12 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree, | |||
1486 | 1445 | ||
1487 | /* error */ | 1446 | /* error */ |
1488 | err_out_curr_node: | 1447 | err_out_curr_node: |
1489 | nilfs_bmap_abort_end_ptr(&btree->bt_bmap, &path[level].bp_oldreq); | 1448 | nilfs_bmap_abort_end_ptr(&btree->bt_bmap, &path[level].bp_oldreq, dat); |
1490 | err_out_child_node: | 1449 | err_out_child_node: |
1491 | for (level--; level >= NILFS_BTREE_LEVEL_NODE_MIN; level--) { | 1450 | for (level--; level >= NILFS_BTREE_LEVEL_NODE_MIN; level--) { |
1492 | brelse(path[level].bp_sib_bh); | 1451 | brelse(path[level].bp_sib_bh); |
1493 | nilfs_bmap_abort_end_ptr(&btree->bt_bmap, | 1452 | nilfs_bmap_abort_end_ptr(&btree->bt_bmap, |
1494 | &path[level].bp_oldreq); | 1453 | &path[level].bp_oldreq, dat); |
1495 | } | 1454 | } |
1496 | *levelp = level; | 1455 | *levelp = level; |
1497 | stats->bs_nblocks = 0; | 1456 | stats->bs_nblocks = 0; |
@@ -1500,13 +1459,13 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree, | |||
1500 | 1459 | ||
1501 | static void nilfs_btree_commit_delete(struct nilfs_btree *btree, | 1460 | static void nilfs_btree_commit_delete(struct nilfs_btree *btree, |
1502 | struct nilfs_btree_path *path, | 1461 | struct nilfs_btree_path *path, |
1503 | int maxlevel) | 1462 | int maxlevel, struct inode *dat) |
1504 | { | 1463 | { |
1505 | int level; | 1464 | int level; |
1506 | 1465 | ||
1507 | for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) { | 1466 | for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) { |
1508 | nilfs_bmap_commit_end_ptr(&btree->bt_bmap, | 1467 | nilfs_bmap_commit_end_ptr(&btree->bt_bmap, |
1509 | &path[level].bp_oldreq); | 1468 | &path[level].bp_oldreq, dat); |
1510 | path[level].bp_op(btree, path, level, NULL, NULL); | 1469 | path[level].bp_op(btree, path, level, NULL, NULL); |
1511 | } | 1470 | } |
1512 | 1471 | ||
@@ -1520,27 +1479,32 @@ static int nilfs_btree_delete(struct nilfs_bmap *bmap, __u64 key) | |||
1520 | struct nilfs_btree *btree; | 1479 | struct nilfs_btree *btree; |
1521 | struct nilfs_btree_path *path; | 1480 | struct nilfs_btree_path *path; |
1522 | struct nilfs_bmap_stats stats; | 1481 | struct nilfs_bmap_stats stats; |
1482 | struct inode *dat; | ||
1523 | int level, ret; | 1483 | int level, ret; |
1524 | 1484 | ||
1525 | btree = (struct nilfs_btree *)bmap; | 1485 | btree = (struct nilfs_btree *)bmap; |
1526 | path = nilfs_btree_alloc_path(btree); | 1486 | path = nilfs_btree_alloc_path(); |
1527 | if (path == NULL) | 1487 | if (path == NULL) |
1528 | return -ENOMEM; | 1488 | return -ENOMEM; |
1529 | nilfs_btree_init_path(btree, path); | 1489 | nilfs_btree_init_path(path); |
1530 | ret = nilfs_btree_do_lookup(btree, path, key, NULL, | 1490 | ret = nilfs_btree_do_lookup(btree, path, key, NULL, |
1531 | NILFS_BTREE_LEVEL_NODE_MIN); | 1491 | NILFS_BTREE_LEVEL_NODE_MIN); |
1532 | if (ret < 0) | 1492 | if (ret < 0) |
1533 | goto out; | 1493 | goto out; |
1534 | 1494 | ||
1535 | ret = nilfs_btree_prepare_delete(btree, path, &level, &stats); | 1495 | |
1496 | dat = NILFS_BMAP_USE_VBN(&btree->bt_bmap) ? | ||
1497 | nilfs_bmap_get_dat(&btree->bt_bmap) : NULL; | ||
1498 | |||
1499 | ret = nilfs_btree_prepare_delete(btree, path, &level, &stats, dat); | ||
1536 | if (ret < 0) | 1500 | if (ret < 0) |
1537 | goto out; | 1501 | goto out; |
1538 | nilfs_btree_commit_delete(btree, path, level); | 1502 | nilfs_btree_commit_delete(btree, path, level, dat); |
1539 | nilfs_bmap_sub_blocks(bmap, stats.bs_nblocks); | 1503 | nilfs_bmap_sub_blocks(bmap, stats.bs_nblocks); |
1540 | 1504 | ||
1541 | out: | 1505 | out: |
1542 | nilfs_btree_clear_path(btree, path); | 1506 | nilfs_btree_release_path(path); |
1543 | nilfs_btree_free_path(btree, path); | 1507 | nilfs_btree_free_path(path); |
1544 | return ret; | 1508 | return ret; |
1545 | } | 1509 | } |
1546 | 1510 | ||
@@ -1551,15 +1515,15 @@ static int nilfs_btree_last_key(const struct nilfs_bmap *bmap, __u64 *keyp) | |||
1551 | int ret; | 1515 | int ret; |
1552 | 1516 | ||
1553 | btree = (struct nilfs_btree *)bmap; | 1517 | btree = (struct nilfs_btree *)bmap; |
1554 | path = nilfs_btree_alloc_path(btree); | 1518 | path = nilfs_btree_alloc_path(); |
1555 | if (path == NULL) | 1519 | if (path == NULL) |
1556 | return -ENOMEM; | 1520 | return -ENOMEM; |
1557 | nilfs_btree_init_path(btree, path); | 1521 | nilfs_btree_init_path(path); |
1558 | 1522 | ||
1559 | ret = nilfs_btree_do_lookup_last(btree, path, keyp, NULL); | 1523 | ret = nilfs_btree_do_lookup_last(btree, path, keyp, NULL); |
1560 | 1524 | ||
1561 | nilfs_btree_clear_path(btree, path); | 1525 | nilfs_btree_release_path(path); |
1562 | nilfs_btree_free_path(btree, path); | 1526 | nilfs_btree_free_path(path); |
1563 | 1527 | ||
1564 | return ret; | 1528 | return ret; |
1565 | } | 1529 | } |
@@ -1581,7 +1545,7 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *bmap, __u64 key) | |||
1581 | node = root; | 1545 | node = root; |
1582 | break; | 1546 | break; |
1583 | case 3: | 1547 | case 3: |
1584 | nchildren = nilfs_btree_node_get_nchildren(btree, root); | 1548 | nchildren = nilfs_btree_node_get_nchildren(root); |
1585 | if (nchildren > 1) | 1549 | if (nchildren > 1) |
1586 | return 0; | 1550 | return 0; |
1587 | ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1); | 1551 | ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1); |
@@ -1594,10 +1558,10 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *bmap, __u64 key) | |||
1594 | return 0; | 1558 | return 0; |
1595 | } | 1559 | } |
1596 | 1560 | ||
1597 | nchildren = nilfs_btree_node_get_nchildren(btree, node); | 1561 | nchildren = nilfs_btree_node_get_nchildren(node); |
1598 | maxkey = nilfs_btree_node_get_key(btree, node, nchildren - 1); | 1562 | maxkey = nilfs_btree_node_get_key(node, nchildren - 1); |
1599 | nextmaxkey = (nchildren > 1) ? | 1563 | nextmaxkey = (nchildren > 1) ? |
1600 | nilfs_btree_node_get_key(btree, node, nchildren - 2) : 0; | 1564 | nilfs_btree_node_get_key(node, nchildren - 2) : 0; |
1601 | if (bh != NULL) | 1565 | if (bh != NULL) |
1602 | brelse(bh); | 1566 | brelse(bh); |
1603 | 1567 | ||
@@ -1623,7 +1587,7 @@ static int nilfs_btree_gather_data(struct nilfs_bmap *bmap, | |||
1623 | node = root; | 1587 | node = root; |
1624 | break; | 1588 | break; |
1625 | case 3: | 1589 | case 3: |
1626 | nchildren = nilfs_btree_node_get_nchildren(btree, root); | 1590 | nchildren = nilfs_btree_node_get_nchildren(root); |
1627 | WARN_ON(nchildren > 1); | 1591 | WARN_ON(nchildren > 1); |
1628 | ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1); | 1592 | ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1); |
1629 | ret = nilfs_btree_get_block(btree, ptr, &bh); | 1593 | ret = nilfs_btree_get_block(btree, ptr, &bh); |
@@ -1636,11 +1600,11 @@ static int nilfs_btree_gather_data(struct nilfs_bmap *bmap, | |||
1636 | return -EINVAL; | 1600 | return -EINVAL; |
1637 | } | 1601 | } |
1638 | 1602 | ||
1639 | nchildren = nilfs_btree_node_get_nchildren(btree, node); | 1603 | nchildren = nilfs_btree_node_get_nchildren(node); |
1640 | if (nchildren < nitems) | 1604 | if (nchildren < nitems) |
1641 | nitems = nchildren; | 1605 | nitems = nchildren; |
1642 | dkeys = nilfs_btree_node_dkeys(btree, node); | 1606 | dkeys = nilfs_btree_node_dkeys(node); |
1643 | dptrs = nilfs_btree_node_dptrs(btree, node); | 1607 | dptrs = nilfs_btree_node_dptrs(node, btree); |
1644 | for (i = 0; i < nitems; i++) { | 1608 | for (i = 0; i < nitems; i++) { |
1645 | keys[i] = nilfs_bmap_dkey_to_key(dkeys[i]); | 1609 | keys[i] = nilfs_bmap_dkey_to_key(dkeys[i]); |
1646 | ptrs[i] = nilfs_bmap_dptr_to_ptr(dptrs[i]); | 1610 | ptrs[i] = nilfs_bmap_dptr_to_ptr(dptrs[i]); |
@@ -1660,18 +1624,20 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key, | |||
1660 | struct nilfs_bmap_stats *stats) | 1624 | struct nilfs_bmap_stats *stats) |
1661 | { | 1625 | { |
1662 | struct buffer_head *bh; | 1626 | struct buffer_head *bh; |
1663 | struct nilfs_btree *btree; | 1627 | struct nilfs_btree *btree = (struct nilfs_btree *)bmap; |
1628 | struct inode *dat = NULL; | ||
1664 | int ret; | 1629 | int ret; |
1665 | 1630 | ||
1666 | btree = (struct nilfs_btree *)bmap; | ||
1667 | stats->bs_nblocks = 0; | 1631 | stats->bs_nblocks = 0; |
1668 | 1632 | ||
1669 | /* for data */ | 1633 | /* for data */ |
1670 | /* cannot find near ptr */ | 1634 | /* cannot find near ptr */ |
1671 | if (NILFS_BMAP_USE_VBN(bmap)) | 1635 | if (NILFS_BMAP_USE_VBN(bmap)) { |
1672 | dreq->bpr_ptr = nilfs_btree_find_target_v(btree, NULL, key); | 1636 | dreq->bpr_ptr = nilfs_btree_find_target_v(btree, NULL, key); |
1637 | dat = nilfs_bmap_get_dat(bmap); | ||
1638 | } | ||
1673 | 1639 | ||
1674 | ret = nilfs_bmap_prepare_alloc_ptr(bmap, dreq); | 1640 | ret = nilfs_bmap_prepare_alloc_ptr(bmap, dreq, dat); |
1675 | if (ret < 0) | 1641 | if (ret < 0) |
1676 | return ret; | 1642 | return ret; |
1677 | 1643 | ||
@@ -1679,7 +1645,7 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key, | |||
1679 | stats->bs_nblocks++; | 1645 | stats->bs_nblocks++; |
1680 | if (nreq != NULL) { | 1646 | if (nreq != NULL) { |
1681 | nreq->bpr_ptr = dreq->bpr_ptr + 1; | 1647 | nreq->bpr_ptr = dreq->bpr_ptr + 1; |
1682 | ret = nilfs_bmap_prepare_alloc_ptr(bmap, nreq); | 1648 | ret = nilfs_bmap_prepare_alloc_ptr(bmap, nreq, dat); |
1683 | if (ret < 0) | 1649 | if (ret < 0) |
1684 | goto err_out_dreq; | 1650 | goto err_out_dreq; |
1685 | 1651 | ||
@@ -1696,9 +1662,9 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key, | |||
1696 | 1662 | ||
1697 | /* error */ | 1663 | /* error */ |
1698 | err_out_nreq: | 1664 | err_out_nreq: |
1699 | nilfs_bmap_abort_alloc_ptr(bmap, nreq); | 1665 | nilfs_bmap_abort_alloc_ptr(bmap, nreq, dat); |
1700 | err_out_dreq: | 1666 | err_out_dreq: |
1701 | nilfs_bmap_abort_alloc_ptr(bmap, dreq); | 1667 | nilfs_bmap_abort_alloc_ptr(bmap, dreq, dat); |
1702 | stats->bs_nblocks = 0; | 1668 | stats->bs_nblocks = 0; |
1703 | return ret; | 1669 | return ret; |
1704 | 1670 | ||
@@ -1713,8 +1679,9 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap, | |||
1713 | union nilfs_bmap_ptr_req *nreq, | 1679 | union nilfs_bmap_ptr_req *nreq, |
1714 | struct buffer_head *bh) | 1680 | struct buffer_head *bh) |
1715 | { | 1681 | { |
1716 | struct nilfs_btree *btree; | 1682 | struct nilfs_btree *btree = (struct nilfs_btree *)bmap; |
1717 | struct nilfs_btree_node *node; | 1683 | struct nilfs_btree_node *node; |
1684 | struct inode *dat; | ||
1718 | __u64 tmpptr; | 1685 | __u64 tmpptr; |
1719 | 1686 | ||
1720 | /* free resources */ | 1687 | /* free resources */ |
@@ -1725,11 +1692,11 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap, | |||
1725 | set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr)); | 1692 | set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr)); |
1726 | 1693 | ||
1727 | /* convert and insert */ | 1694 | /* convert and insert */ |
1728 | btree = (struct nilfs_btree *)bmap; | 1695 | dat = NILFS_BMAP_USE_VBN(bmap) ? nilfs_bmap_get_dat(bmap) : NULL; |
1729 | nilfs_btree_init(bmap); | 1696 | nilfs_btree_init(bmap); |
1730 | if (nreq != NULL) { | 1697 | if (nreq != NULL) { |
1731 | nilfs_bmap_commit_alloc_ptr(bmap, dreq); | 1698 | nilfs_bmap_commit_alloc_ptr(bmap, dreq, dat); |
1732 | nilfs_bmap_commit_alloc_ptr(bmap, nreq); | 1699 | nilfs_bmap_commit_alloc_ptr(bmap, nreq, dat); |
1733 | 1700 | ||
1734 | /* create child node at level 1 */ | 1701 | /* create child node at level 1 */ |
1735 | lock_buffer(bh); | 1702 | lock_buffer(bh); |
@@ -1751,7 +1718,7 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap, | |||
1751 | nilfs_btree_node_init(btree, node, NILFS_BTREE_NODE_ROOT, | 1718 | nilfs_btree_node_init(btree, node, NILFS_BTREE_NODE_ROOT, |
1752 | 2, 1, &keys[0], &tmpptr); | 1719 | 2, 1, &keys[0], &tmpptr); |
1753 | } else { | 1720 | } else { |
1754 | nilfs_bmap_commit_alloc_ptr(bmap, dreq); | 1721 | nilfs_bmap_commit_alloc_ptr(bmap, dreq, dat); |
1755 | 1722 | ||
1756 | /* create root node at level 1 */ | 1723 | /* create root node at level 1 */ |
1757 | node = nilfs_btree_get_root(btree); | 1724 | node = nilfs_btree_get_root(btree); |
@@ -1822,7 +1789,7 @@ static int nilfs_btree_propagate_p(struct nilfs_btree *btree, | |||
1822 | 1789 | ||
1823 | static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree, | 1790 | static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree, |
1824 | struct nilfs_btree_path *path, | 1791 | struct nilfs_btree_path *path, |
1825 | int level) | 1792 | int level, struct inode *dat) |
1826 | { | 1793 | { |
1827 | struct nilfs_btree_node *parent; | 1794 | struct nilfs_btree_node *parent; |
1828 | int ret; | 1795 | int ret; |
@@ -1832,9 +1799,8 @@ static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree, | |||
1832 | nilfs_btree_node_get_ptr(btree, parent, | 1799 | nilfs_btree_node_get_ptr(btree, parent, |
1833 | path[level + 1].bp_index); | 1800 | path[level + 1].bp_index); |
1834 | path[level].bp_newreq.bpr_ptr = path[level].bp_oldreq.bpr_ptr + 1; | 1801 | path[level].bp_newreq.bpr_ptr = path[level].bp_oldreq.bpr_ptr + 1; |
1835 | ret = nilfs_bmap_prepare_update_v(&btree->bt_bmap, | 1802 | ret = nilfs_dat_prepare_update(dat, &path[level].bp_oldreq.bpr_req, |
1836 | &path[level].bp_oldreq, | 1803 | &path[level].bp_newreq.bpr_req); |
1837 | &path[level].bp_newreq); | ||
1838 | if (ret < 0) | 1804 | if (ret < 0) |
1839 | return ret; | 1805 | return ret; |
1840 | 1806 | ||
@@ -1846,9 +1812,9 @@ static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree, | |||
1846 | &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache, | 1812 | &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache, |
1847 | &path[level].bp_ctxt); | 1813 | &path[level].bp_ctxt); |
1848 | if (ret < 0) { | 1814 | if (ret < 0) { |
1849 | nilfs_bmap_abort_update_v(&btree->bt_bmap, | 1815 | nilfs_dat_abort_update(dat, |
1850 | &path[level].bp_oldreq, | 1816 | &path[level].bp_oldreq.bpr_req, |
1851 | &path[level].bp_newreq); | 1817 | &path[level].bp_newreq.bpr_req); |
1852 | return ret; | 1818 | return ret; |
1853 | } | 1819 | } |
1854 | } | 1820 | } |
@@ -1858,13 +1824,13 @@ static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree, | |||
1858 | 1824 | ||
1859 | static void nilfs_btree_commit_update_v(struct nilfs_btree *btree, | 1825 | static void nilfs_btree_commit_update_v(struct nilfs_btree *btree, |
1860 | struct nilfs_btree_path *path, | 1826 | struct nilfs_btree_path *path, |
1861 | int level) | 1827 | int level, struct inode *dat) |
1862 | { | 1828 | { |
1863 | struct nilfs_btree_node *parent; | 1829 | struct nilfs_btree_node *parent; |
1864 | 1830 | ||
1865 | nilfs_bmap_commit_update_v(&btree->bt_bmap, | 1831 | nilfs_dat_commit_update(dat, &path[level].bp_oldreq.bpr_req, |
1866 | &path[level].bp_oldreq, | 1832 | &path[level].bp_newreq.bpr_req, |
1867 | &path[level].bp_newreq); | 1833 | btree->bt_bmap.b_ptr_type == NILFS_BMAP_PTR_VS); |
1868 | 1834 | ||
1869 | if (buffer_nilfs_node(path[level].bp_bh)) { | 1835 | if (buffer_nilfs_node(path[level].bp_bh)) { |
1870 | nilfs_btnode_commit_change_key( | 1836 | nilfs_btnode_commit_change_key( |
@@ -1881,11 +1847,10 @@ static void nilfs_btree_commit_update_v(struct nilfs_btree *btree, | |||
1881 | 1847 | ||
1882 | static void nilfs_btree_abort_update_v(struct nilfs_btree *btree, | 1848 | static void nilfs_btree_abort_update_v(struct nilfs_btree *btree, |
1883 | struct nilfs_btree_path *path, | 1849 | struct nilfs_btree_path *path, |
1884 | int level) | 1850 | int level, struct inode *dat) |
1885 | { | 1851 | { |
1886 | nilfs_bmap_abort_update_v(&btree->bt_bmap, | 1852 | nilfs_dat_abort_update(dat, &path[level].bp_oldreq.bpr_req, |
1887 | &path[level].bp_oldreq, | 1853 | &path[level].bp_newreq.bpr_req); |
1888 | &path[level].bp_newreq); | ||
1889 | if (buffer_nilfs_node(path[level].bp_bh)) | 1854 | if (buffer_nilfs_node(path[level].bp_bh)) |
1890 | nilfs_btnode_abort_change_key( | 1855 | nilfs_btnode_abort_change_key( |
1891 | &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache, | 1856 | &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache, |
@@ -1894,14 +1859,14 @@ static void nilfs_btree_abort_update_v(struct nilfs_btree *btree, | |||
1894 | 1859 | ||
1895 | static int nilfs_btree_prepare_propagate_v(struct nilfs_btree *btree, | 1860 | static int nilfs_btree_prepare_propagate_v(struct nilfs_btree *btree, |
1896 | struct nilfs_btree_path *path, | 1861 | struct nilfs_btree_path *path, |
1897 | int minlevel, | 1862 | int minlevel, int *maxlevelp, |
1898 | int *maxlevelp) | 1863 | struct inode *dat) |
1899 | { | 1864 | { |
1900 | int level, ret; | 1865 | int level, ret; |
1901 | 1866 | ||
1902 | level = minlevel; | 1867 | level = minlevel; |
1903 | if (!buffer_nilfs_volatile(path[level].bp_bh)) { | 1868 | if (!buffer_nilfs_volatile(path[level].bp_bh)) { |
1904 | ret = nilfs_btree_prepare_update_v(btree, path, level); | 1869 | ret = nilfs_btree_prepare_update_v(btree, path, level, dat); |
1905 | if (ret < 0) | 1870 | if (ret < 0) |
1906 | return ret; | 1871 | return ret; |
1907 | } | 1872 | } |
@@ -1909,7 +1874,7 @@ static int nilfs_btree_prepare_propagate_v(struct nilfs_btree *btree, | |||
1909 | !buffer_dirty(path[level].bp_bh)) { | 1874 | !buffer_dirty(path[level].bp_bh)) { |
1910 | 1875 | ||
1911 | WARN_ON(buffer_nilfs_volatile(path[level].bp_bh)); | 1876 | WARN_ON(buffer_nilfs_volatile(path[level].bp_bh)); |
1912 | ret = nilfs_btree_prepare_update_v(btree, path, level); | 1877 | ret = nilfs_btree_prepare_update_v(btree, path, level, dat); |
1913 | if (ret < 0) | 1878 | if (ret < 0) |
1914 | goto out; | 1879 | goto out; |
1915 | } | 1880 | } |
@@ -1921,39 +1886,40 @@ static int nilfs_btree_prepare_propagate_v(struct nilfs_btree *btree, | |||
1921 | /* error */ | 1886 | /* error */ |
1922 | out: | 1887 | out: |
1923 | while (--level > minlevel) | 1888 | while (--level > minlevel) |
1924 | nilfs_btree_abort_update_v(btree, path, level); | 1889 | nilfs_btree_abort_update_v(btree, path, level, dat); |
1925 | if (!buffer_nilfs_volatile(path[level].bp_bh)) | 1890 | if (!buffer_nilfs_volatile(path[level].bp_bh)) |
1926 | nilfs_btree_abort_update_v(btree, path, level); | 1891 | nilfs_btree_abort_update_v(btree, path, level, dat); |
1927 | return ret; | 1892 | return ret; |
1928 | } | 1893 | } |
1929 | 1894 | ||
1930 | static void nilfs_btree_commit_propagate_v(struct nilfs_btree *btree, | 1895 | static void nilfs_btree_commit_propagate_v(struct nilfs_btree *btree, |
1931 | struct nilfs_btree_path *path, | 1896 | struct nilfs_btree_path *path, |
1932 | int minlevel, | 1897 | int minlevel, int maxlevel, |
1933 | int maxlevel, | 1898 | struct buffer_head *bh, |
1934 | struct buffer_head *bh) | 1899 | struct inode *dat) |
1935 | { | 1900 | { |
1936 | int level; | 1901 | int level; |
1937 | 1902 | ||
1938 | if (!buffer_nilfs_volatile(path[minlevel].bp_bh)) | 1903 | if (!buffer_nilfs_volatile(path[minlevel].bp_bh)) |
1939 | nilfs_btree_commit_update_v(btree, path, minlevel); | 1904 | nilfs_btree_commit_update_v(btree, path, minlevel, dat); |
1940 | 1905 | ||
1941 | for (level = minlevel + 1; level <= maxlevel; level++) | 1906 | for (level = minlevel + 1; level <= maxlevel; level++) |
1942 | nilfs_btree_commit_update_v(btree, path, level); | 1907 | nilfs_btree_commit_update_v(btree, path, level, dat); |
1943 | } | 1908 | } |
1944 | 1909 | ||
1945 | static int nilfs_btree_propagate_v(struct nilfs_btree *btree, | 1910 | static int nilfs_btree_propagate_v(struct nilfs_btree *btree, |
1946 | struct nilfs_btree_path *path, | 1911 | struct nilfs_btree_path *path, |
1947 | int level, | 1912 | int level, struct buffer_head *bh) |
1948 | struct buffer_head *bh) | ||
1949 | { | 1913 | { |
1950 | int maxlevel, ret; | 1914 | int maxlevel, ret; |
1951 | struct nilfs_btree_node *parent; | 1915 | struct nilfs_btree_node *parent; |
1916 | struct inode *dat = nilfs_bmap_get_dat(&btree->bt_bmap); | ||
1952 | __u64 ptr; | 1917 | __u64 ptr; |
1953 | 1918 | ||
1954 | get_bh(bh); | 1919 | get_bh(bh); |
1955 | path[level].bp_bh = bh; | 1920 | path[level].bp_bh = bh; |
1956 | ret = nilfs_btree_prepare_propagate_v(btree, path, level, &maxlevel); | 1921 | ret = nilfs_btree_prepare_propagate_v(btree, path, level, &maxlevel, |
1922 | dat); | ||
1957 | if (ret < 0) | 1923 | if (ret < 0) |
1958 | goto out; | 1924 | goto out; |
1959 | 1925 | ||
@@ -1961,12 +1927,12 @@ static int nilfs_btree_propagate_v(struct nilfs_btree *btree, | |||
1961 | parent = nilfs_btree_get_node(btree, path, level + 1); | 1927 | parent = nilfs_btree_get_node(btree, path, level + 1); |
1962 | ptr = nilfs_btree_node_get_ptr(btree, parent, | 1928 | ptr = nilfs_btree_node_get_ptr(btree, parent, |
1963 | path[level + 1].bp_index); | 1929 | path[level + 1].bp_index); |
1964 | ret = nilfs_bmap_mark_dirty(&btree->bt_bmap, ptr); | 1930 | ret = nilfs_dat_mark_dirty(dat, ptr); |
1965 | if (ret < 0) | 1931 | if (ret < 0) |
1966 | goto out; | 1932 | goto out; |
1967 | } | 1933 | } |
1968 | 1934 | ||
1969 | nilfs_btree_commit_propagate_v(btree, path, level, maxlevel, bh); | 1935 | nilfs_btree_commit_propagate_v(btree, path, level, maxlevel, bh, dat); |
1970 | 1936 | ||
1971 | out: | 1937 | out: |
1972 | brelse(path[level].bp_bh); | 1938 | brelse(path[level].bp_bh); |
@@ -1986,15 +1952,15 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap, | |||
1986 | WARN_ON(!buffer_dirty(bh)); | 1952 | WARN_ON(!buffer_dirty(bh)); |
1987 | 1953 | ||
1988 | btree = (struct nilfs_btree *)bmap; | 1954 | btree = (struct nilfs_btree *)bmap; |
1989 | path = nilfs_btree_alloc_path(btree); | 1955 | path = nilfs_btree_alloc_path(); |
1990 | if (path == NULL) | 1956 | if (path == NULL) |
1991 | return -ENOMEM; | 1957 | return -ENOMEM; |
1992 | nilfs_btree_init_path(btree, path); | 1958 | nilfs_btree_init_path(path); |
1993 | 1959 | ||
1994 | if (buffer_nilfs_node(bh)) { | 1960 | if (buffer_nilfs_node(bh)) { |
1995 | node = (struct nilfs_btree_node *)bh->b_data; | 1961 | node = (struct nilfs_btree_node *)bh->b_data; |
1996 | key = nilfs_btree_node_get_key(btree, node, 0); | 1962 | key = nilfs_btree_node_get_key(node, 0); |
1997 | level = nilfs_btree_node_get_level(btree, node); | 1963 | level = nilfs_btree_node_get_level(node); |
1998 | } else { | 1964 | } else { |
1999 | key = nilfs_bmap_data_get_key(bmap, bh); | 1965 | key = nilfs_bmap_data_get_key(bmap, bh); |
2000 | level = NILFS_BTREE_LEVEL_DATA; | 1966 | level = NILFS_BTREE_LEVEL_DATA; |
@@ -2013,8 +1979,8 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap, | |||
2013 | nilfs_btree_propagate_p(btree, path, level, bh); | 1979 | nilfs_btree_propagate_p(btree, path, level, bh); |
2014 | 1980 | ||
2015 | out: | 1981 | out: |
2016 | nilfs_btree_clear_path(btree, path); | 1982 | nilfs_btree_release_path(path); |
2017 | nilfs_btree_free_path(btree, path); | 1983 | nilfs_btree_free_path(path); |
2018 | 1984 | ||
2019 | return ret; | 1985 | return ret; |
2020 | } | 1986 | } |
@@ -2022,7 +1988,7 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap, | |||
2022 | static int nilfs_btree_propagate_gc(const struct nilfs_bmap *bmap, | 1988 | static int nilfs_btree_propagate_gc(const struct nilfs_bmap *bmap, |
2023 | struct buffer_head *bh) | 1989 | struct buffer_head *bh) |
2024 | { | 1990 | { |
2025 | return nilfs_bmap_mark_dirty(bmap, bh->b_blocknr); | 1991 | return nilfs_dat_mark_dirty(nilfs_bmap_get_dat(bmap), bh->b_blocknr); |
2026 | } | 1992 | } |
2027 | 1993 | ||
2028 | static void nilfs_btree_add_dirty_buffer(struct nilfs_btree *btree, | 1994 | static void nilfs_btree_add_dirty_buffer(struct nilfs_btree *btree, |
@@ -2037,12 +2003,12 @@ static void nilfs_btree_add_dirty_buffer(struct nilfs_btree *btree, | |||
2037 | 2003 | ||
2038 | get_bh(bh); | 2004 | get_bh(bh); |
2039 | node = (struct nilfs_btree_node *)bh->b_data; | 2005 | node = (struct nilfs_btree_node *)bh->b_data; |
2040 | key = nilfs_btree_node_get_key(btree, node, 0); | 2006 | key = nilfs_btree_node_get_key(node, 0); |
2041 | level = nilfs_btree_node_get_level(btree, node); | 2007 | level = nilfs_btree_node_get_level(node); |
2042 | list_for_each(head, &lists[level]) { | 2008 | list_for_each(head, &lists[level]) { |
2043 | cbh = list_entry(head, struct buffer_head, b_assoc_buffers); | 2009 | cbh = list_entry(head, struct buffer_head, b_assoc_buffers); |
2044 | cnode = (struct nilfs_btree_node *)cbh->b_data; | 2010 | cnode = (struct nilfs_btree_node *)cbh->b_data; |
2045 | ckey = nilfs_btree_node_get_key(btree, cnode, 0); | 2011 | ckey = nilfs_btree_node_get_key(cnode, 0); |
2046 | if (key < ckey) | 2012 | if (key < ckey) |
2047 | break; | 2013 | break; |
2048 | } | 2014 | } |
@@ -2120,8 +2086,7 @@ static int nilfs_btree_assign_p(struct nilfs_btree *btree, | |||
2120 | nilfs_btree_node_set_ptr(btree, parent, | 2086 | nilfs_btree_node_set_ptr(btree, parent, |
2121 | path[level + 1].bp_index, blocknr); | 2087 | path[level + 1].bp_index, blocknr); |
2122 | 2088 | ||
2123 | key = nilfs_btree_node_get_key(btree, parent, | 2089 | key = nilfs_btree_node_get_key(parent, path[level + 1].bp_index); |
2124 | path[level + 1].bp_index); | ||
2125 | /* on-disk format */ | 2090 | /* on-disk format */ |
2126 | binfo->bi_dat.bi_blkoff = nilfs_bmap_key_to_dkey(key); | 2091 | binfo->bi_dat.bi_blkoff = nilfs_bmap_key_to_dkey(key); |
2127 | binfo->bi_dat.bi_level = level; | 2092 | binfo->bi_dat.bi_level = level; |
@@ -2137,6 +2102,7 @@ static int nilfs_btree_assign_v(struct nilfs_btree *btree, | |||
2137 | union nilfs_binfo *binfo) | 2102 | union nilfs_binfo *binfo) |
2138 | { | 2103 | { |
2139 | struct nilfs_btree_node *parent; | 2104 | struct nilfs_btree_node *parent; |
2105 | struct inode *dat = nilfs_bmap_get_dat(&btree->bt_bmap); | ||
2140 | __u64 key; | 2106 | __u64 key; |
2141 | __u64 ptr; | 2107 | __u64 ptr; |
2142 | union nilfs_bmap_ptr_req req; | 2108 | union nilfs_bmap_ptr_req req; |
@@ -2146,12 +2112,12 @@ static int nilfs_btree_assign_v(struct nilfs_btree *btree, | |||
2146 | ptr = nilfs_btree_node_get_ptr(btree, parent, | 2112 | ptr = nilfs_btree_node_get_ptr(btree, parent, |
2147 | path[level + 1].bp_index); | 2113 | path[level + 1].bp_index); |
2148 | req.bpr_ptr = ptr; | 2114 | req.bpr_ptr = ptr; |
2149 | ret = nilfs_bmap_start_v(&btree->bt_bmap, &req, blocknr); | 2115 | ret = nilfs_dat_prepare_start(dat, &req.bpr_req); |
2150 | if (unlikely(ret < 0)) | 2116 | if (ret < 0) |
2151 | return ret; | 2117 | return ret; |
2118 | nilfs_dat_commit_start(dat, &req.bpr_req, blocknr); | ||
2152 | 2119 | ||
2153 | key = nilfs_btree_node_get_key(btree, parent, | 2120 | key = nilfs_btree_node_get_key(parent, path[level + 1].bp_index); |
2154 | path[level + 1].bp_index); | ||
2155 | /* on-disk format */ | 2121 | /* on-disk format */ |
2156 | binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr); | 2122 | binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr); |
2157 | binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key); | 2123 | binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key); |
@@ -2171,15 +2137,15 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap, | |||
2171 | int level, ret; | 2137 | int level, ret; |
2172 | 2138 | ||
2173 | btree = (struct nilfs_btree *)bmap; | 2139 | btree = (struct nilfs_btree *)bmap; |
2174 | path = nilfs_btree_alloc_path(btree); | 2140 | path = nilfs_btree_alloc_path(); |
2175 | if (path == NULL) | 2141 | if (path == NULL) |
2176 | return -ENOMEM; | 2142 | return -ENOMEM; |
2177 | nilfs_btree_init_path(btree, path); | 2143 | nilfs_btree_init_path(path); |
2178 | 2144 | ||
2179 | if (buffer_nilfs_node(*bh)) { | 2145 | if (buffer_nilfs_node(*bh)) { |
2180 | node = (struct nilfs_btree_node *)(*bh)->b_data; | 2146 | node = (struct nilfs_btree_node *)(*bh)->b_data; |
2181 | key = nilfs_btree_node_get_key(btree, node, 0); | 2147 | key = nilfs_btree_node_get_key(node, 0); |
2182 | level = nilfs_btree_node_get_level(btree, node); | 2148 | level = nilfs_btree_node_get_level(node); |
2183 | } else { | 2149 | } else { |
2184 | key = nilfs_bmap_data_get_key(bmap, *bh); | 2150 | key = nilfs_bmap_data_get_key(bmap, *bh); |
2185 | level = NILFS_BTREE_LEVEL_DATA; | 2151 | level = NILFS_BTREE_LEVEL_DATA; |
@@ -2196,8 +2162,8 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap, | |||
2196 | nilfs_btree_assign_p(btree, path, level, bh, blocknr, binfo); | 2162 | nilfs_btree_assign_p(btree, path, level, bh, blocknr, binfo); |
2197 | 2163 | ||
2198 | out: | 2164 | out: |
2199 | nilfs_btree_clear_path(btree, path); | 2165 | nilfs_btree_release_path(path); |
2200 | nilfs_btree_free_path(btree, path); | 2166 | nilfs_btree_free_path(path); |
2201 | 2167 | ||
2202 | return ret; | 2168 | return ret; |
2203 | } | 2169 | } |
@@ -2207,19 +2173,18 @@ static int nilfs_btree_assign_gc(struct nilfs_bmap *bmap, | |||
2207 | sector_t blocknr, | 2173 | sector_t blocknr, |
2208 | union nilfs_binfo *binfo) | 2174 | union nilfs_binfo *binfo) |
2209 | { | 2175 | { |
2210 | struct nilfs_btree *btree; | ||
2211 | struct nilfs_btree_node *node; | 2176 | struct nilfs_btree_node *node; |
2212 | __u64 key; | 2177 | __u64 key; |
2213 | int ret; | 2178 | int ret; |
2214 | 2179 | ||
2215 | btree = (struct nilfs_btree *)bmap; | 2180 | ret = nilfs_dat_move(nilfs_bmap_get_dat(bmap), (*bh)->b_blocknr, |
2216 | ret = nilfs_bmap_move_v(bmap, (*bh)->b_blocknr, blocknr); | 2181 | blocknr); |
2217 | if (ret < 0) | 2182 | if (ret < 0) |
2218 | return ret; | 2183 | return ret; |
2219 | 2184 | ||
2220 | if (buffer_nilfs_node(*bh)) { | 2185 | if (buffer_nilfs_node(*bh)) { |
2221 | node = (struct nilfs_btree_node *)(*bh)->b_data; | 2186 | node = (struct nilfs_btree_node *)(*bh)->b_data; |
2222 | key = nilfs_btree_node_get_key(btree, node, 0); | 2187 | key = nilfs_btree_node_get_key(node, 0); |
2223 | } else | 2188 | } else |
2224 | key = nilfs_bmap_data_get_key(bmap, *bh); | 2189 | key = nilfs_bmap_data_get_key(bmap, *bh); |
2225 | 2190 | ||
@@ -2239,10 +2204,10 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level) | |||
2239 | int ret; | 2204 | int ret; |
2240 | 2205 | ||
2241 | btree = (struct nilfs_btree *)bmap; | 2206 | btree = (struct nilfs_btree *)bmap; |
2242 | path = nilfs_btree_alloc_path(btree); | 2207 | path = nilfs_btree_alloc_path(); |
2243 | if (path == NULL) | 2208 | if (path == NULL) |
2244 | return -ENOMEM; | 2209 | return -ENOMEM; |
2245 | nilfs_btree_init_path(btree, path); | 2210 | nilfs_btree_init_path(path); |
2246 | 2211 | ||
2247 | ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level + 1); | 2212 | ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level + 1); |
2248 | if (ret < 0) { | 2213 | if (ret < 0) { |
@@ -2262,8 +2227,8 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level) | |||
2262 | nilfs_bmap_set_dirty(&btree->bt_bmap); | 2227 | nilfs_bmap_set_dirty(&btree->bt_bmap); |
2263 | 2228 | ||
2264 | out: | 2229 | out: |
2265 | nilfs_btree_clear_path(btree, path); | 2230 | nilfs_btree_release_path(path); |
2266 | nilfs_btree_free_path(btree, path); | 2231 | nilfs_btree_free_path(path); |
2267 | return ret; | 2232 | return ret; |
2268 | } | 2233 | } |
2269 | 2234 | ||
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c index aec942cf79e3..1c6cfb59128d 100644 --- a/fs/nilfs2/cpfile.c +++ b/fs/nilfs2/cpfile.c | |||
@@ -815,8 +815,10 @@ int nilfs_cpfile_is_snapshot(struct inode *cpfile, __u64 cno) | |||
815 | void *kaddr; | 815 | void *kaddr; |
816 | int ret; | 816 | int ret; |
817 | 817 | ||
818 | if (cno == 0) | 818 | /* CP number is invalid if it's zero or larger than the |
819 | return -ENOENT; /* checkpoint number 0 is invalid */ | 819 | largest exist one.*/ |
820 | if (cno == 0 || cno >= nilfs_mdt_cno(cpfile)) | ||
821 | return -ENOENT; | ||
820 | down_read(&NILFS_MDT(cpfile)->mi_sem); | 822 | down_read(&NILFS_MDT(cpfile)->mi_sem); |
821 | 823 | ||
822 | ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &bh); | 824 | ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &bh); |
@@ -824,7 +826,10 @@ int nilfs_cpfile_is_snapshot(struct inode *cpfile, __u64 cno) | |||
824 | goto out; | 826 | goto out; |
825 | kaddr = kmap_atomic(bh->b_page, KM_USER0); | 827 | kaddr = kmap_atomic(bh->b_page, KM_USER0); |
826 | cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr); | 828 | cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr); |
827 | ret = nilfs_checkpoint_snapshot(cp); | 829 | if (nilfs_checkpoint_invalid(cp)) |
830 | ret = -ENOENT; | ||
831 | else | ||
832 | ret = nilfs_checkpoint_snapshot(cp); | ||
828 | kunmap_atomic(kaddr, KM_USER0); | 833 | kunmap_atomic(kaddr, KM_USER0); |
829 | brelse(bh); | 834 | brelse(bh); |
830 | 835 | ||
diff --git a/fs/nilfs2/cpfile.h b/fs/nilfs2/cpfile.h index 788a45950197..debea896e701 100644 --- a/fs/nilfs2/cpfile.h +++ b/fs/nilfs2/cpfile.h | |||
@@ -27,8 +27,6 @@ | |||
27 | #include <linux/buffer_head.h> | 27 | #include <linux/buffer_head.h> |
28 | #include <linux/nilfs2_fs.h> | 28 | #include <linux/nilfs2_fs.h> |
29 | 29 | ||
30 | #define NILFS_CPFILE_GFP NILFS_MDT_GFP | ||
31 | |||
32 | 30 | ||
33 | int nilfs_cpfile_get_checkpoint(struct inode *, __u64, int, | 31 | int nilfs_cpfile_get_checkpoint(struct inode *, __u64, int, |
34 | struct nilfs_checkpoint **, | 32 | struct nilfs_checkpoint **, |
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c index 8927ca27e6f7..1ff8e15bd36b 100644 --- a/fs/nilfs2/dat.c +++ b/fs/nilfs2/dat.c | |||
@@ -109,12 +109,6 @@ void nilfs_dat_commit_free(struct inode *dat, struct nilfs_palloc_req *req) | |||
109 | nilfs_palloc_commit_free_entry(dat, req); | 109 | nilfs_palloc_commit_free_entry(dat, req); |
110 | } | 110 | } |
111 | 111 | ||
112 | void nilfs_dat_abort_free(struct inode *dat, struct nilfs_palloc_req *req) | ||
113 | { | ||
114 | nilfs_dat_abort_entry(dat, req); | ||
115 | nilfs_palloc_abort_free_entry(dat, req); | ||
116 | } | ||
117 | |||
118 | int nilfs_dat_prepare_start(struct inode *dat, struct nilfs_palloc_req *req) | 112 | int nilfs_dat_prepare_start(struct inode *dat, struct nilfs_palloc_req *req) |
119 | { | 113 | { |
120 | int ret; | 114 | int ret; |
@@ -140,11 +134,6 @@ void nilfs_dat_commit_start(struct inode *dat, struct nilfs_palloc_req *req, | |||
140 | nilfs_dat_commit_entry(dat, req); | 134 | nilfs_dat_commit_entry(dat, req); |
141 | } | 135 | } |
142 | 136 | ||
143 | void nilfs_dat_abort_start(struct inode *dat, struct nilfs_palloc_req *req) | ||
144 | { | ||
145 | nilfs_dat_abort_entry(dat, req); | ||
146 | } | ||
147 | |||
148 | int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req) | 137 | int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req) |
149 | { | 138 | { |
150 | struct nilfs_dat_entry *entry; | 139 | struct nilfs_dat_entry *entry; |
@@ -222,6 +211,37 @@ void nilfs_dat_abort_end(struct inode *dat, struct nilfs_palloc_req *req) | |||
222 | nilfs_dat_abort_entry(dat, req); | 211 | nilfs_dat_abort_entry(dat, req); |
223 | } | 212 | } |
224 | 213 | ||
214 | int nilfs_dat_prepare_update(struct inode *dat, | ||
215 | struct nilfs_palloc_req *oldreq, | ||
216 | struct nilfs_palloc_req *newreq) | ||
217 | { | ||
218 | int ret; | ||
219 | |||
220 | ret = nilfs_dat_prepare_end(dat, oldreq); | ||
221 | if (!ret) { | ||
222 | ret = nilfs_dat_prepare_alloc(dat, newreq); | ||
223 | if (ret < 0) | ||
224 | nilfs_dat_abort_end(dat, oldreq); | ||
225 | } | ||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | void nilfs_dat_commit_update(struct inode *dat, | ||
230 | struct nilfs_palloc_req *oldreq, | ||
231 | struct nilfs_palloc_req *newreq, int dead) | ||
232 | { | ||
233 | nilfs_dat_commit_end(dat, oldreq, dead); | ||
234 | nilfs_dat_commit_alloc(dat, newreq); | ||
235 | } | ||
236 | |||
237 | void nilfs_dat_abort_update(struct inode *dat, | ||
238 | struct nilfs_palloc_req *oldreq, | ||
239 | struct nilfs_palloc_req *newreq) | ||
240 | { | ||
241 | nilfs_dat_abort_end(dat, oldreq); | ||
242 | nilfs_dat_abort_alloc(dat, newreq); | ||
243 | } | ||
244 | |||
225 | /** | 245 | /** |
226 | * nilfs_dat_mark_dirty - | 246 | * nilfs_dat_mark_dirty - |
227 | * @dat: DAT file inode | 247 | * @dat: DAT file inode |
diff --git a/fs/nilfs2/dat.h b/fs/nilfs2/dat.h index d328b81eead4..406070d3ff49 100644 --- a/fs/nilfs2/dat.h +++ b/fs/nilfs2/dat.h | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/buffer_head.h> | 27 | #include <linux/buffer_head.h> |
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | 29 | ||
30 | #define NILFS_DAT_GFP NILFS_MDT_GFP | ||
31 | 30 | ||
32 | struct nilfs_palloc_req; | 31 | struct nilfs_palloc_req; |
33 | 32 | ||
@@ -39,10 +38,15 @@ void nilfs_dat_abort_alloc(struct inode *, struct nilfs_palloc_req *); | |||
39 | int nilfs_dat_prepare_start(struct inode *, struct nilfs_palloc_req *); | 38 | int nilfs_dat_prepare_start(struct inode *, struct nilfs_palloc_req *); |
40 | void nilfs_dat_commit_start(struct inode *, struct nilfs_palloc_req *, | 39 | void nilfs_dat_commit_start(struct inode *, struct nilfs_palloc_req *, |
41 | sector_t); | 40 | sector_t); |
42 | void nilfs_dat_abort_start(struct inode *, struct nilfs_palloc_req *); | ||
43 | int nilfs_dat_prepare_end(struct inode *, struct nilfs_palloc_req *); | 41 | int nilfs_dat_prepare_end(struct inode *, struct nilfs_palloc_req *); |
44 | void nilfs_dat_commit_end(struct inode *, struct nilfs_palloc_req *, int); | 42 | void nilfs_dat_commit_end(struct inode *, struct nilfs_palloc_req *, int); |
45 | void nilfs_dat_abort_end(struct inode *, struct nilfs_palloc_req *); | 43 | void nilfs_dat_abort_end(struct inode *, struct nilfs_palloc_req *); |
44 | int nilfs_dat_prepare_update(struct inode *, struct nilfs_palloc_req *, | ||
45 | struct nilfs_palloc_req *); | ||
46 | void nilfs_dat_commit_update(struct inode *, struct nilfs_palloc_req *, | ||
47 | struct nilfs_palloc_req *, int); | ||
48 | void nilfs_dat_abort_update(struct inode *, struct nilfs_palloc_req *, | ||
49 | struct nilfs_palloc_req *); | ||
46 | 50 | ||
47 | int nilfs_dat_mark_dirty(struct inode *, __u64); | 51 | int nilfs_dat_mark_dirty(struct inode *, __u64); |
48 | int nilfs_dat_freev(struct inode *, __u64 *, size_t); | 52 | int nilfs_dat_freev(struct inode *, __u64 *, size_t); |
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, |
diff --git a/fs/nilfs2/ifile.h b/fs/nilfs2/ifile.h index 5d30a35679b5..ecc3ba76db47 100644 --- a/fs/nilfs2/ifile.h +++ b/fs/nilfs2/ifile.h | |||
@@ -31,7 +31,6 @@ | |||
31 | #include "mdt.h" | 31 | #include "mdt.h" |
32 | #include "alloc.h" | 32 | #include "alloc.h" |
33 | 33 | ||
34 | #define NILFS_IFILE_GFP NILFS_MDT_GFP | ||
35 | 34 | ||
36 | static inline struct nilfs_inode * | 35 | static inline struct nilfs_inode * |
37 | nilfs_ifile_map_inode(struct inode *ifile, ino_t ino, struct buffer_head *ibh) | 36 | nilfs_ifile_map_inode(struct inode *ifile, ino_t ino, struct buffer_head *ibh) |
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index fe9d8f2a13f8..807e584b163d 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -430,7 +430,8 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino, | |||
430 | 430 | ||
431 | raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, bh); | 431 | raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, bh); |
432 | 432 | ||
433 | if (nilfs_read_inode_common(inode, raw_inode)) | 433 | err = nilfs_read_inode_common(inode, raw_inode); |
434 | if (err) | ||
434 | goto failed_unmap; | 435 | goto failed_unmap; |
435 | 436 | ||
436 | if (S_ISREG(inode->i_mode)) { | 437 | if (S_ISREG(inode->i_mode)) { |
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index 6ea5f872e2de..6572ea4bc4df 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c | |||
@@ -442,12 +442,6 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs, | |||
442 | const char *msg; | 442 | const char *msg; |
443 | int ret; | 443 | int ret; |
444 | 444 | ||
445 | ret = nilfs_ioctl_move_blocks(nilfs, &argv[0], kbufs[0]); | ||
446 | if (ret < 0) { | ||
447 | msg = "cannot read source blocks"; | ||
448 | goto failed; | ||
449 | } | ||
450 | |||
451 | ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], kbufs[1]); | 445 | ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], kbufs[1]); |
452 | if (ret < 0) { | 446 | if (ret < 0) { |
453 | /* | 447 | /* |
@@ -548,7 +542,25 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp, | |||
548 | } | 542 | } |
549 | } | 543 | } |
550 | 544 | ||
551 | ret = nilfs_clean_segments(inode->i_sb, argv, kbufs); | 545 | /* |
546 | * nilfs_ioctl_move_blocks() will call nilfs_gc_iget(), | ||
547 | * which will operates an inode list without blocking. | ||
548 | * To protect the list from concurrent operations, | ||
549 | * nilfs_ioctl_move_blocks should be atomic operation. | ||
550 | */ | ||
551 | if (test_and_set_bit(THE_NILFS_GC_RUNNING, &nilfs->ns_flags)) { | ||
552 | ret = -EBUSY; | ||
553 | goto out_free; | ||
554 | } | ||
555 | |||
556 | ret = nilfs_ioctl_move_blocks(nilfs, &argv[0], kbufs[0]); | ||
557 | if (ret < 0) | ||
558 | printk(KERN_ERR "NILFS: GC failed during preparation: " | ||
559 | "cannot read source blocks: err=%d\n", ret); | ||
560 | else | ||
561 | ret = nilfs_clean_segments(inode->i_sb, argv, kbufs); | ||
562 | |||
563 | clear_nilfs_gc_running(nilfs); | ||
552 | 564 | ||
553 | out_free: | 565 | out_free: |
554 | while (--n >= 0) | 566 | while (--n >= 0) |
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c index 2dfd47714ae5..156bf6091a96 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c | |||
@@ -103,15 +103,12 @@ static int nilfs_mdt_create_block(struct inode *inode, unsigned long block, | |||
103 | goto failed_unlock; | 103 | goto failed_unlock; |
104 | 104 | ||
105 | err = -EEXIST; | 105 | err = -EEXIST; |
106 | if (buffer_uptodate(bh) || buffer_mapped(bh)) | 106 | if (buffer_uptodate(bh)) |
107 | goto failed_bh; | 107 | goto failed_bh; |
108 | #if 0 | 108 | |
109 | /* The uptodate flag is not protected by the page lock, but | ||
110 | the mapped flag is. Thus, we don't have to wait the buffer. */ | ||
111 | wait_on_buffer(bh); | 109 | wait_on_buffer(bh); |
112 | if (buffer_uptodate(bh)) | 110 | if (buffer_uptodate(bh)) |
113 | goto failed_bh; | 111 | goto failed_bh; |
114 | #endif | ||
115 | 112 | ||
116 | bh->b_bdev = nilfs->ns_bdev; | 113 | bh->b_bdev = nilfs->ns_bdev; |
117 | err = nilfs_mdt_insert_new_block(inode, block, bh, init_block); | 114 | err = nilfs_mdt_insert_new_block(inode, block, bh, init_block); |
@@ -139,7 +136,7 @@ nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff, | |||
139 | int mode, struct buffer_head **out_bh) | 136 | int mode, struct buffer_head **out_bh) |
140 | { | 137 | { |
141 | struct buffer_head *bh; | 138 | struct buffer_head *bh; |
142 | unsigned long blknum = 0; | 139 | __u64 blknum = 0; |
143 | int ret = -ENOMEM; | 140 | int ret = -ENOMEM; |
144 | 141 | ||
145 | bh = nilfs_grab_buffer(inode, inode->i_mapping, blkoff, 0); | 142 | bh = nilfs_grab_buffer(inode, inode->i_mapping, blkoff, 0); |
@@ -162,17 +159,15 @@ nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff, | |||
162 | unlock_buffer(bh); | 159 | unlock_buffer(bh); |
163 | goto out; | 160 | goto out; |
164 | } | 161 | } |
165 | if (!buffer_mapped(bh)) { /* unused buffer */ | 162 | |
166 | ret = nilfs_bmap_lookup(NILFS_I(inode)->i_bmap, blkoff, | 163 | ret = nilfs_bmap_lookup(NILFS_I(inode)->i_bmap, blkoff, &blknum); |
167 | &blknum); | 164 | if (unlikely(ret)) { |
168 | if (unlikely(ret)) { | 165 | unlock_buffer(bh); |
169 | unlock_buffer(bh); | 166 | goto failed_bh; |
170 | goto failed_bh; | ||
171 | } | ||
172 | bh->b_bdev = NILFS_MDT(inode)->mi_nilfs->ns_bdev; | ||
173 | bh->b_blocknr = blknum; | ||
174 | set_buffer_mapped(bh); | ||
175 | } | 167 | } |
168 | bh->b_bdev = NILFS_MDT(inode)->mi_nilfs->ns_bdev; | ||
169 | bh->b_blocknr = (sector_t)blknum; | ||
170 | set_buffer_mapped(bh); | ||
176 | 171 | ||
177 | bh->b_end_io = end_buffer_read_sync; | 172 | bh->b_end_io = end_buffer_read_sync; |
178 | get_bh(bh); | 173 | get_bh(bh); |
@@ -402,6 +397,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) | |||
402 | struct inode *inode = container_of(page->mapping, | 397 | struct inode *inode = container_of(page->mapping, |
403 | struct inode, i_data); | 398 | struct inode, i_data); |
404 | struct super_block *sb = inode->i_sb; | 399 | struct super_block *sb = inode->i_sb; |
400 | struct the_nilfs *nilfs = NILFS_MDT(inode)->mi_nilfs; | ||
405 | struct nilfs_sb_info *writer = NULL; | 401 | struct nilfs_sb_info *writer = NULL; |
406 | int err = 0; | 402 | int err = 0; |
407 | 403 | ||
@@ -411,9 +407,10 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) | |||
411 | if (page->mapping->assoc_mapping) | 407 | if (page->mapping->assoc_mapping) |
412 | return 0; /* Do not request flush for shadow page cache */ | 408 | return 0; /* Do not request flush for shadow page cache */ |
413 | if (!sb) { | 409 | if (!sb) { |
414 | writer = nilfs_get_writer(NILFS_MDT(inode)->mi_nilfs); | 410 | down_read(&nilfs->ns_writer_sem); |
411 | writer = nilfs->ns_writer; | ||
415 | if (!writer) { | 412 | if (!writer) { |
416 | nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs); | 413 | up_read(&nilfs->ns_writer_sem); |
417 | return -EROFS; | 414 | return -EROFS; |
418 | } | 415 | } |
419 | sb = writer->s_super; | 416 | sb = writer->s_super; |
@@ -425,7 +422,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) | |||
425 | nilfs_flush_segment(sb, inode->i_ino); | 422 | nilfs_flush_segment(sb, inode->i_ino); |
426 | 423 | ||
427 | if (writer) | 424 | if (writer) |
428 | nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs); | 425 | up_read(&nilfs->ns_writer_sem); |
429 | return err; | 426 | return err; |
430 | } | 427 | } |
431 | 428 | ||
@@ -516,9 +513,10 @@ nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb, | |||
516 | } | 513 | } |
517 | 514 | ||
518 | struct inode *nilfs_mdt_new(struct the_nilfs *nilfs, struct super_block *sb, | 515 | struct inode *nilfs_mdt_new(struct the_nilfs *nilfs, struct super_block *sb, |
519 | ino_t ino, gfp_t gfp_mask) | 516 | ino_t ino) |
520 | { | 517 | { |
521 | struct inode *inode = nilfs_mdt_new_common(nilfs, sb, ino, gfp_mask); | 518 | struct inode *inode = nilfs_mdt_new_common(nilfs, sb, ino, |
519 | NILFS_MDT_GFP); | ||
522 | 520 | ||
523 | if (!inode) | 521 | if (!inode) |
524 | return NULL; | 522 | return NULL; |
diff --git a/fs/nilfs2/mdt.h b/fs/nilfs2/mdt.h index df683e0bca6a..431599733c9b 100644 --- a/fs/nilfs2/mdt.h +++ b/fs/nilfs2/mdt.h | |||
@@ -74,8 +74,7 @@ int nilfs_mdt_forget_block(struct inode *, unsigned long); | |||
74 | int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long); | 74 | int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long); |
75 | int nilfs_mdt_fetch_dirty(struct inode *); | 75 | int nilfs_mdt_fetch_dirty(struct inode *); |
76 | 76 | ||
77 | struct inode *nilfs_mdt_new(struct the_nilfs *, struct super_block *, ino_t, | 77 | struct inode *nilfs_mdt_new(struct the_nilfs *, struct super_block *, ino_t); |
78 | gfp_t); | ||
79 | struct inode *nilfs_mdt_new_common(struct the_nilfs *, struct super_block *, | 78 | struct inode *nilfs_mdt_new_common(struct the_nilfs *, struct super_block *, |
80 | ino_t, gfp_t); | 79 | ino_t, gfp_t); |
81 | void nilfs_mdt_destroy(struct inode *); | 80 | void nilfs_mdt_destroy(struct inode *); |
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c index d80cc71be749..6dc83591d118 100644 --- a/fs/nilfs2/recovery.c +++ b/fs/nilfs2/recovery.c | |||
@@ -552,7 +552,8 @@ static int recover_dsync_blocks(struct nilfs_sb_info *sbi, | |||
552 | printk(KERN_WARNING | 552 | printk(KERN_WARNING |
553 | "NILFS warning: error recovering data block " | 553 | "NILFS warning: error recovering data block " |
554 | "(err=%d, ino=%lu, block-offset=%llu)\n", | 554 | "(err=%d, ino=%lu, block-offset=%llu)\n", |
555 | err, rb->ino, (unsigned long long)rb->blkoff); | 555 | err, (unsigned long)rb->ino, |
556 | (unsigned long long)rb->blkoff); | ||
556 | if (!err2) | 557 | if (!err2) |
557 | err2 = err; | 558 | err2 = err; |
558 | next: | 559 | next: |
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c index 9e3fe17bb96b..e6d9e37fa241 100644 --- a/fs/nilfs2/segbuf.c +++ b/fs/nilfs2/segbuf.c | |||
@@ -316,10 +316,10 @@ static struct bio *nilfs_alloc_seg_bio(struct super_block *sb, sector_t start, | |||
316 | { | 316 | { |
317 | struct bio *bio; | 317 | struct bio *bio; |
318 | 318 | ||
319 | bio = bio_alloc(GFP_NOWAIT, nr_vecs); | 319 | bio = bio_alloc(GFP_NOIO, nr_vecs); |
320 | if (bio == NULL) { | 320 | if (bio == NULL) { |
321 | while (!bio && (nr_vecs >>= 1)) | 321 | while (!bio && (nr_vecs >>= 1)) |
322 | bio = bio_alloc(GFP_NOWAIT, nr_vecs); | 322 | bio = bio_alloc(GFP_NOIO, nr_vecs); |
323 | } | 323 | } |
324 | if (likely(bio)) { | 324 | if (likely(bio)) { |
325 | bio->bi_bdev = sb->s_bdev; | 325 | bio->bi_bdev = sb->s_bdev; |
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 51ff3d0a4ee2..683df89dbae5 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -2501,7 +2501,8 @@ static int nilfs_segctor_construct(struct nilfs_sc_info *sci, | |||
2501 | if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) && | 2501 | if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) && |
2502 | nilfs_discontinued(nilfs)) { | 2502 | nilfs_discontinued(nilfs)) { |
2503 | down_write(&nilfs->ns_sem); | 2503 | down_write(&nilfs->ns_sem); |
2504 | req->sb_err = nilfs_commit_super(sbi, 0); | 2504 | req->sb_err = nilfs_commit_super(sbi, |
2505 | nilfs_altsb_need_update(nilfs)); | ||
2505 | up_write(&nilfs->ns_sem); | 2506 | up_write(&nilfs->ns_sem); |
2506 | } | 2507 | } |
2507 | } | 2508 | } |
@@ -2689,6 +2690,7 @@ static int nilfs_segctor_thread(void *arg) | |||
2689 | } else { | 2690 | } else { |
2690 | DEFINE_WAIT(wait); | 2691 | DEFINE_WAIT(wait); |
2691 | int should_sleep = 1; | 2692 | int should_sleep = 1; |
2693 | struct the_nilfs *nilfs; | ||
2692 | 2694 | ||
2693 | prepare_to_wait(&sci->sc_wait_daemon, &wait, | 2695 | prepare_to_wait(&sci->sc_wait_daemon, &wait, |
2694 | TASK_INTERRUPTIBLE); | 2696 | TASK_INTERRUPTIBLE); |
@@ -2709,6 +2711,9 @@ static int nilfs_segctor_thread(void *arg) | |||
2709 | finish_wait(&sci->sc_wait_daemon, &wait); | 2711 | finish_wait(&sci->sc_wait_daemon, &wait); |
2710 | timeout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) && | 2712 | timeout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) && |
2711 | time_after_eq(jiffies, sci->sc_timer->expires)); | 2713 | time_after_eq(jiffies, sci->sc_timer->expires)); |
2714 | nilfs = sci->sc_sbi->s_nilfs; | ||
2715 | if (sci->sc_super->s_dirt && nilfs_sb_need_update(nilfs)) | ||
2716 | set_nilfs_discontinued(nilfs); | ||
2712 | } | 2717 | } |
2713 | goto loop; | 2718 | goto loop; |
2714 | 2719 | ||
diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h index a2c4d76c3366..0e99e5c0bd0f 100644 --- a/fs/nilfs2/sufile.h +++ b/fs/nilfs2/sufile.h | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/nilfs2_fs.h> | 28 | #include <linux/nilfs2_fs.h> |
29 | #include "mdt.h" | 29 | #include "mdt.h" |
30 | 30 | ||
31 | #define NILFS_SUFILE_GFP NILFS_MDT_GFP | ||
32 | 31 | ||
33 | static inline unsigned long nilfs_sufile_get_nsegments(struct inode *sufile) | 32 | static inline unsigned long nilfs_sufile_get_nsegments(struct inode *sufile) |
34 | { | 33 | { |
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 151964f0de4c..55f3d6b60732 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -50,6 +50,8 @@ | |||
50 | #include <linux/writeback.h> | 50 | #include <linux/writeback.h> |
51 | #include <linux/kobject.h> | 51 | #include <linux/kobject.h> |
52 | #include <linux/exportfs.h> | 52 | #include <linux/exportfs.h> |
53 | #include <linux/seq_file.h> | ||
54 | #include <linux/mount.h> | ||
53 | #include "nilfs.h" | 55 | #include "nilfs.h" |
54 | #include "mdt.h" | 56 | #include "mdt.h" |
55 | #include "alloc.h" | 57 | #include "alloc.h" |
@@ -65,7 +67,6 @@ MODULE_DESCRIPTION("A New Implementation of the Log-structured Filesystem " | |||
65 | "(NILFS)"); | 67 | "(NILFS)"); |
66 | MODULE_LICENSE("GPL"); | 68 | MODULE_LICENSE("GPL"); |
67 | 69 | ||
68 | static void nilfs_write_super(struct super_block *sb); | ||
69 | static int nilfs_remount(struct super_block *sb, int *flags, char *data); | 70 | static int nilfs_remount(struct super_block *sb, int *flags, char *data); |
70 | 71 | ||
71 | /** | 72 | /** |
@@ -311,9 +312,6 @@ static void nilfs_put_super(struct super_block *sb) | |||
311 | 312 | ||
312 | lock_kernel(); | 313 | lock_kernel(); |
313 | 314 | ||
314 | if (sb->s_dirt) | ||
315 | nilfs_write_super(sb); | ||
316 | |||
317 | nilfs_detach_segment_constructor(sbi); | 315 | nilfs_detach_segment_constructor(sbi); |
318 | 316 | ||
319 | if (!(sb->s_flags & MS_RDONLY)) { | 317 | if (!(sb->s_flags & MS_RDONLY)) { |
@@ -336,63 +334,21 @@ static void nilfs_put_super(struct super_block *sb) | |||
336 | unlock_kernel(); | 334 | unlock_kernel(); |
337 | } | 335 | } |
338 | 336 | ||
339 | /** | 337 | static int nilfs_sync_fs(struct super_block *sb, int wait) |
340 | * nilfs_write_super - write super block(s) of NILFS | ||
341 | * @sb: super_block | ||
342 | * | ||
343 | * nilfs_write_super() gets a fs-dependent lock, writes super block(s), and | ||
344 | * clears s_dirt. This function is called in the section protected by | ||
345 | * lock_super(). | ||
346 | * | ||
347 | * The s_dirt flag is managed by each filesystem and we protect it by ns_sem | ||
348 | * of the struct the_nilfs. Lock order must be as follows: | ||
349 | * | ||
350 | * 1. lock_super() | ||
351 | * 2. down_write(&nilfs->ns_sem) | ||
352 | * | ||
353 | * Inside NILFS, locking ns_sem is enough to protect s_dirt and the buffer | ||
354 | * of the super block (nilfs->ns_sbp[]). | ||
355 | * | ||
356 | * In most cases, VFS functions call lock_super() before calling these | ||
357 | * methods. So we must be careful not to bring on deadlocks when using | ||
358 | * lock_super(); see generic_shutdown_super(), write_super(), and so on. | ||
359 | * | ||
360 | * Note that order of lock_kernel() and lock_super() depends on contexts | ||
361 | * of VFS. We should also note that lock_kernel() can be used in its | ||
362 | * protective section and only the outermost one has an effect. | ||
363 | */ | ||
364 | static void nilfs_write_super(struct super_block *sb) | ||
365 | { | 338 | { |
366 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 339 | struct nilfs_sb_info *sbi = NILFS_SB(sb); |
367 | struct the_nilfs *nilfs = sbi->s_nilfs; | 340 | struct the_nilfs *nilfs = sbi->s_nilfs; |
368 | |||
369 | down_write(&nilfs->ns_sem); | ||
370 | if (!(sb->s_flags & MS_RDONLY)) { | ||
371 | struct nilfs_super_block **sbp = nilfs->ns_sbp; | ||
372 | u64 t = get_seconds(); | ||
373 | int dupsb; | ||
374 | |||
375 | if (!nilfs_discontinued(nilfs) && t >= nilfs->ns_sbwtime[0] && | ||
376 | t < nilfs->ns_sbwtime[0] + NILFS_SB_FREQ) { | ||
377 | up_write(&nilfs->ns_sem); | ||
378 | return; | ||
379 | } | ||
380 | dupsb = sbp[1] && t > nilfs->ns_sbwtime[1] + NILFS_ALTSB_FREQ; | ||
381 | nilfs_commit_super(sbi, dupsb); | ||
382 | } | ||
383 | sb->s_dirt = 0; | ||
384 | up_write(&nilfs->ns_sem); | ||
385 | } | ||
386 | |||
387 | static int nilfs_sync_fs(struct super_block *sb, int wait) | ||
388 | { | ||
389 | int err = 0; | 341 | int err = 0; |
390 | 342 | ||
391 | nilfs_write_super(sb); | ||
392 | |||
393 | /* This function is called when super block should be written back */ | 343 | /* This function is called when super block should be written back */ |
394 | if (wait) | 344 | if (wait) |
395 | err = nilfs_construct_segment(sb); | 345 | err = nilfs_construct_segment(sb); |
346 | |||
347 | down_write(&nilfs->ns_sem); | ||
348 | if (sb->s_dirt) | ||
349 | nilfs_commit_super(sbi, 1); | ||
350 | up_write(&nilfs->ns_sem); | ||
351 | |||
396 | return err; | 352 | return err; |
397 | } | 353 | } |
398 | 354 | ||
@@ -407,8 +363,7 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno) | |||
407 | list_add(&sbi->s_list, &nilfs->ns_supers); | 363 | list_add(&sbi->s_list, &nilfs->ns_supers); |
408 | up_write(&nilfs->ns_super_sem); | 364 | up_write(&nilfs->ns_super_sem); |
409 | 365 | ||
410 | sbi->s_ifile = nilfs_mdt_new( | 366 | sbi->s_ifile = nilfs_mdt_new(nilfs, sbi->s_super, NILFS_IFILE_INO); |
411 | nilfs, sbi->s_super, NILFS_IFILE_INO, NILFS_IFILE_GFP); | ||
412 | if (!sbi->s_ifile) | 367 | if (!sbi->s_ifile) |
413 | return -ENOMEM; | 368 | return -ENOMEM; |
414 | 369 | ||
@@ -529,6 +484,26 @@ static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
529 | return 0; | 484 | return 0; |
530 | } | 485 | } |
531 | 486 | ||
487 | static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | ||
488 | { | ||
489 | struct super_block *sb = vfs->mnt_sb; | ||
490 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | ||
491 | |||
492 | if (!nilfs_test_opt(sbi, BARRIER)) | ||
493 | seq_printf(seq, ",barrier=off"); | ||
494 | if (nilfs_test_opt(sbi, SNAPSHOT)) | ||
495 | seq_printf(seq, ",cp=%llu", | ||
496 | (unsigned long long int)sbi->s_snapshot_cno); | ||
497 | if (nilfs_test_opt(sbi, ERRORS_RO)) | ||
498 | seq_printf(seq, ",errors=remount-ro"); | ||
499 | if (nilfs_test_opt(sbi, ERRORS_PANIC)) | ||
500 | seq_printf(seq, ",errors=panic"); | ||
501 | if (nilfs_test_opt(sbi, STRICT_ORDER)) | ||
502 | seq_printf(seq, ",order=strict"); | ||
503 | |||
504 | return 0; | ||
505 | } | ||
506 | |||
532 | static struct super_operations nilfs_sops = { | 507 | static struct super_operations nilfs_sops = { |
533 | .alloc_inode = nilfs_alloc_inode, | 508 | .alloc_inode = nilfs_alloc_inode, |
534 | .destroy_inode = nilfs_destroy_inode, | 509 | .destroy_inode = nilfs_destroy_inode, |
@@ -538,7 +513,7 @@ static struct super_operations nilfs_sops = { | |||
538 | /* .drop_inode = nilfs_drop_inode, */ | 513 | /* .drop_inode = nilfs_drop_inode, */ |
539 | .delete_inode = nilfs_delete_inode, | 514 | .delete_inode = nilfs_delete_inode, |
540 | .put_super = nilfs_put_super, | 515 | .put_super = nilfs_put_super, |
541 | .write_super = nilfs_write_super, | 516 | /* .write_super = nilfs_write_super, */ |
542 | .sync_fs = nilfs_sync_fs, | 517 | .sync_fs = nilfs_sync_fs, |
543 | /* .write_super_lockfs */ | 518 | /* .write_super_lockfs */ |
544 | /* .unlockfs */ | 519 | /* .unlockfs */ |
@@ -546,7 +521,7 @@ static struct super_operations nilfs_sops = { | |||
546 | .remount_fs = nilfs_remount, | 521 | .remount_fs = nilfs_remount, |
547 | .clear_inode = nilfs_clear_inode, | 522 | .clear_inode = nilfs_clear_inode, |
548 | /* .umount_begin */ | 523 | /* .umount_begin */ |
549 | /* .show_options */ | 524 | .show_options = nilfs_show_options |
550 | }; | 525 | }; |
551 | 526 | ||
552 | static struct inode * | 527 | static struct inode * |
@@ -816,10 +791,15 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
816 | 791 | ||
817 | if (sb->s_flags & MS_RDONLY) { | 792 | if (sb->s_flags & MS_RDONLY) { |
818 | if (nilfs_test_opt(sbi, SNAPSHOT)) { | 793 | if (nilfs_test_opt(sbi, SNAPSHOT)) { |
794 | down_read(&nilfs->ns_segctor_sem); | ||
819 | err = nilfs_cpfile_is_snapshot(nilfs->ns_cpfile, | 795 | err = nilfs_cpfile_is_snapshot(nilfs->ns_cpfile, |
820 | sbi->s_snapshot_cno); | 796 | sbi->s_snapshot_cno); |
821 | if (err < 0) | 797 | up_read(&nilfs->ns_segctor_sem); |
798 | if (err < 0) { | ||
799 | if (err == -ENOENT) | ||
800 | err = -EINVAL; | ||
822 | goto failed_sbi; | 801 | goto failed_sbi; |
802 | } | ||
823 | if (!err) { | 803 | if (!err) { |
824 | printk(KERN_ERR | 804 | printk(KERN_ERR |
825 | "NILFS: The specified checkpoint is " | 805 | "NILFS: The specified checkpoint is " |
@@ -1127,10 +1107,6 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags, | |||
1127 | */ | 1107 | */ |
1128 | sd.sbi = nilfs_find_sbinfo(nilfs, !(flags & MS_RDONLY), sd.cno); | 1108 | sd.sbi = nilfs_find_sbinfo(nilfs, !(flags & MS_RDONLY), sd.cno); |
1129 | 1109 | ||
1130 | if (!sd.cno) | ||
1131 | /* trying to get the latest checkpoint. */ | ||
1132 | sd.cno = nilfs_last_cno(nilfs); | ||
1133 | |||
1134 | /* | 1110 | /* |
1135 | * Get super block instance holding the nilfs_sb_info struct. | 1111 | * Get super block instance holding the nilfs_sb_info struct. |
1136 | * A new instance is allocated if no existing mount is present or | 1112 | * A new instance is allocated if no existing mount is present or |
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 8b8889825716..d4168e269c5d 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); |
@@ -188,23 +187,19 @@ static int nilfs_load_super_root(struct the_nilfs *nilfs, | |||
188 | inode_size = nilfs->ns_inode_size; | 187 | inode_size = nilfs->ns_inode_size; |
189 | 188 | ||
190 | err = -ENOMEM; | 189 | err = -ENOMEM; |
191 | nilfs->ns_dat = nilfs_mdt_new( | 190 | nilfs->ns_dat = nilfs_mdt_new(nilfs, NULL, NILFS_DAT_INO); |
192 | nilfs, NULL, NILFS_DAT_INO, NILFS_DAT_GFP); | ||
193 | if (unlikely(!nilfs->ns_dat)) | 191 | if (unlikely(!nilfs->ns_dat)) |
194 | goto failed; | 192 | goto failed; |
195 | 193 | ||
196 | nilfs->ns_gc_dat = nilfs_mdt_new( | 194 | nilfs->ns_gc_dat = nilfs_mdt_new(nilfs, NULL, NILFS_DAT_INO); |
197 | nilfs, NULL, NILFS_DAT_INO, NILFS_DAT_GFP); | ||
198 | if (unlikely(!nilfs->ns_gc_dat)) | 195 | if (unlikely(!nilfs->ns_gc_dat)) |
199 | goto failed_dat; | 196 | goto failed_dat; |
200 | 197 | ||
201 | nilfs->ns_cpfile = nilfs_mdt_new( | 198 | nilfs->ns_cpfile = nilfs_mdt_new(nilfs, NULL, NILFS_CPFILE_INO); |
202 | nilfs, NULL, NILFS_CPFILE_INO, NILFS_CPFILE_GFP); | ||
203 | if (unlikely(!nilfs->ns_cpfile)) | 199 | if (unlikely(!nilfs->ns_cpfile)) |
204 | goto failed_gc_dat; | 200 | goto failed_gc_dat; |
205 | 201 | ||
206 | nilfs->ns_sufile = nilfs_mdt_new( | 202 | nilfs->ns_sufile = nilfs_mdt_new(nilfs, NULL, NILFS_SUFILE_INO); |
207 | nilfs, NULL, NILFS_SUFILE_INO, NILFS_SUFILE_GFP); | ||
208 | if (unlikely(!nilfs->ns_sufile)) | 203 | if (unlikely(!nilfs->ns_sufile)) |
209 | goto failed_cpfile; | 204 | goto failed_cpfile; |
210 | 205 | ||
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h index 1b9caafb8662..20abd55881e0 100644 --- a/fs/nilfs2/the_nilfs.h +++ b/fs/nilfs2/the_nilfs.h | |||
@@ -37,6 +37,7 @@ enum { | |||
37 | THE_NILFS_LOADED, /* Roll-back/roll-forward has done and | 37 | THE_NILFS_LOADED, /* Roll-back/roll-forward has done and |
38 | the latest checkpoint was loaded */ | 38 | the latest checkpoint was loaded */ |
39 | THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */ | 39 | THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */ |
40 | THE_NILFS_GC_RUNNING, /* gc process is running */ | ||
40 | }; | 41 | }; |
41 | 42 | ||
42 | /** | 43 | /** |
@@ -50,8 +51,7 @@ enum { | |||
50 | * @ns_sem: semaphore for shared states | 51 | * @ns_sem: semaphore for shared states |
51 | * @ns_super_sem: semaphore for global operations across super block instances | 52 | * @ns_super_sem: semaphore for global operations across super block instances |
52 | * @ns_mount_mutex: mutex protecting mount process of nilfs | 53 | * @ns_mount_mutex: mutex protecting mount process of nilfs |
53 | * @ns_writer_mutex: mutex protecting ns_writer attach/detach | 54 | * @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 | 55 | * @ns_current: back pointer to current mount |
56 | * @ns_sbh: buffer heads of on-disk super blocks | 56 | * @ns_sbh: buffer heads of on-disk super blocks |
57 | * @ns_sbp: pointers to super block data | 57 | * @ns_sbp: pointers to super block data |
@@ -100,8 +100,7 @@ struct the_nilfs { | |||
100 | struct rw_semaphore ns_sem; | 100 | struct rw_semaphore ns_sem; |
101 | struct rw_semaphore ns_super_sem; | 101 | struct rw_semaphore ns_super_sem; |
102 | struct mutex ns_mount_mutex; | 102 | struct mutex ns_mount_mutex; |
103 | struct mutex ns_writer_mutex; | 103 | struct rw_semaphore ns_writer_sem; |
104 | atomic_t ns_writer_refcount; | ||
105 | 104 | ||
106 | /* | 105 | /* |
107 | * components protected by ns_super_sem | 106 | * components protected by ns_super_sem |
@@ -197,11 +196,26 @@ static inline int nilfs_##name(struct the_nilfs *nilfs) \ | |||
197 | THE_NILFS_FNS(INIT, init) | 196 | THE_NILFS_FNS(INIT, init) |
198 | THE_NILFS_FNS(LOADED, loaded) | 197 | THE_NILFS_FNS(LOADED, loaded) |
199 | THE_NILFS_FNS(DISCONTINUED, discontinued) | 198 | THE_NILFS_FNS(DISCONTINUED, discontinued) |
199 | THE_NILFS_FNS(GC_RUNNING, gc_running) | ||
200 | 200 | ||
201 | /* Minimum interval of periodical update of superblocks (in seconds) */ | 201 | /* Minimum interval of periodical update of superblocks (in seconds) */ |
202 | #define NILFS_SB_FREQ 10 | 202 | #define NILFS_SB_FREQ 10 |
203 | #define NILFS_ALTSB_FREQ 60 /* spare superblock */ | 203 | #define NILFS_ALTSB_FREQ 60 /* spare superblock */ |
204 | 204 | ||
205 | static inline int nilfs_sb_need_update(struct the_nilfs *nilfs) | ||
206 | { | ||
207 | u64 t = get_seconds(); | ||
208 | return t < nilfs->ns_sbwtime[0] || | ||
209 | t > nilfs->ns_sbwtime[0] + NILFS_SB_FREQ; | ||
210 | } | ||
211 | |||
212 | static inline int nilfs_altsb_need_update(struct the_nilfs *nilfs) | ||
213 | { | ||
214 | u64 t = get_seconds(); | ||
215 | struct nilfs_super_block **sbp = nilfs->ns_sbp; | ||
216 | return sbp[1] && t > nilfs->ns_sbwtime[1] + NILFS_ALTSB_FREQ; | ||
217 | } | ||
218 | |||
205 | void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64); | 219 | void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64); |
206 | struct the_nilfs *find_or_create_nilfs(struct block_device *); | 220 | struct the_nilfs *find_or_create_nilfs(struct block_device *); |
207 | void put_nilfs(struct the_nilfs *); | 221 | void put_nilfs(struct the_nilfs *); |
@@ -221,34 +235,21 @@ static inline void get_nilfs(struct the_nilfs *nilfs) | |||
221 | atomic_inc(&nilfs->ns_count); | 235 | atomic_inc(&nilfs->ns_count); |
222 | } | 236 | } |
223 | 237 | ||
224 | static 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 | |||
231 | static 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 | |||
237 | static inline void | 238 | static inline void |
238 | nilfs_attach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) | 239 | nilfs_attach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) |
239 | { | 240 | { |
240 | mutex_lock(&nilfs->ns_writer_mutex); | 241 | down_write(&nilfs->ns_writer_sem); |
241 | nilfs->ns_writer = sbi; | 242 | nilfs->ns_writer = sbi; |
242 | mutex_unlock(&nilfs->ns_writer_mutex); | 243 | up_write(&nilfs->ns_writer_sem); |
243 | } | 244 | } |
244 | 245 | ||
245 | static inline void | 246 | static inline void |
246 | nilfs_detach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) | 247 | nilfs_detach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) |
247 | { | 248 | { |
248 | mutex_lock(&nilfs->ns_writer_mutex); | 249 | down_write(&nilfs->ns_writer_sem); |
249 | if (sbi == nilfs->ns_writer) | 250 | if (sbi == nilfs->ns_writer) |
250 | nilfs->ns_writer = NULL; | 251 | nilfs->ns_writer = NULL; |
251 | mutex_unlock(&nilfs->ns_writer_mutex); | 252 | up_write(&nilfs->ns_writer_sem); |
252 | } | 253 | } |
253 | 254 | ||
254 | static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi) | 255 | static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi) |