aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-11 14:49:18 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-11 14:49:18 -0500
commit4e2ccdb0409146f8cf64a11b6ef82a9c928ced2a (patch)
tree986896cc558ae23017e79ab08eb55b25c3a54549
parent3ef884b4c04e857c283cc77ca70ad8f638d94b0e (diff)
parenta694291a6211537189c6080f77f63cdabfc9b63e (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: (49 commits) nilfs2: separate wait function from nilfs_segctor_write nilfs2: add iterator for segment buffers nilfs2: hide nilfs_write_info struct in segment buffer code nilfs2: relocate io status variables to segment buffer nilfs2: do not return io error for bio allocation failure nilfs2: use list_splice_tail or list_splice_tail_init nilfs2: replace mark_inode_dirty as nilfs_mark_inode_dirty nilfs2: delete mark_inode_dirty in nilfs_delete_entry nilfs2: delete mark_inode_dirty in nilfs_commit_chunk nilfs2: change return type of nilfs_commit_chunk nilfs2: split nilfs_unlink as nilfs_do_unlink and nilfs_unlink nilfs2: delete redundant mark_inode_dirty nilfs2: expand inode_inc_link_count and inode_dec_link_count nilfs2: delete mark_inode_dirty from nilfs_set_link nilfs2: delete mark_inode_dirty in nilfs_new_inode nilfs2: add norecovery mount option nilfs2: add helper to get if volume is in a valid state nilfs2: move recovery completion into load_nilfs function nilfs2: apply readahead for recovery on mount nilfs2: clean up get/put function of a segment usage ...
-rw-r--r--Documentation/filesystems/nilfs2.txt7
-rw-r--r--fs/nilfs2/alloc.c108
-rw-r--r--fs/nilfs2/alloc.h21
-rw-r--r--fs/nilfs2/bmap.c8
-rw-r--r--fs/nilfs2/btnode.c76
-rw-r--r--fs/nilfs2/btnode.h6
-rw-r--r--fs/nilfs2/btree.c106
-rw-r--r--fs/nilfs2/btree.h22
-rw-r--r--fs/nilfs2/cpfile.c26
-rw-r--r--fs/nilfs2/cpfile.h3
-rw-r--r--fs/nilfs2/dat.c47
-rw-r--r--fs/nilfs2/dat.h3
-rw-r--r--fs/nilfs2/dir.c24
-rw-r--r--fs/nilfs2/gcdat.c3
-rw-r--r--fs/nilfs2/gcinode.c6
-rw-r--r--fs/nilfs2/ifile.c35
-rw-r--r--fs/nilfs2/ifile.h2
-rw-r--r--fs/nilfs2/inode.c7
-rw-r--r--fs/nilfs2/mdt.c56
-rw-r--r--fs/nilfs2/mdt.h25
-rw-r--r--fs/nilfs2/namei.c83
-rw-r--r--fs/nilfs2/recovery.c34
-rw-r--r--fs/nilfs2/segbuf.c185
-rw-r--r--fs/nilfs2/segbuf.h54
-rw-r--r--fs/nilfs2/segment.c369
-rw-r--r--fs/nilfs2/segment.h2
-rw-r--r--fs/nilfs2/sufile.c203
-rw-r--r--fs/nilfs2/sufile.h14
-rw-r--r--fs/nilfs2/super.c88
-rw-r--r--fs/nilfs2/the_nilfs.c155
-rw-r--r--fs/nilfs2/the_nilfs.h10
-rw-r--r--include/linux/nilfs2_fs.h24
32 files changed, 1025 insertions, 787 deletions
diff --git a/Documentation/filesystems/nilfs2.txt b/Documentation/filesystems/nilfs2.txt
index 01539f410676..4949fcaa6b6a 100644
--- a/Documentation/filesystems/nilfs2.txt
+++ b/Documentation/filesystems/nilfs2.txt
@@ -49,8 +49,7 @@ Mount options
49NILFS2 supports the following mount options: 49NILFS2 supports the following mount options:
50(*) == default 50(*) == default
51 51
52barrier=on(*) This enables/disables barriers. barrier=off disables 52nobarrier Disables barriers.
53 it, barrier=on enables it.
54errors=continue(*) Keep going on a filesystem error. 53errors=continue(*) Keep going on a filesystem error.
55errors=remount-ro Remount the filesystem read-only on an error. 54errors=remount-ro Remount the filesystem read-only on an error.
56errors=panic Panic and halt the machine if an error occurs. 55errors=panic Panic and halt the machine if an error occurs.
@@ -71,6 +70,10 @@ order=strict Apply strict in-order semantics that preserves sequence
71 blocks. That means, it is guaranteed that no 70 blocks. That means, it is guaranteed that no
72 overtaking of events occurs in the recovered file 71 overtaking of events occurs in the recovered file
73 system after a crash. 72 system after a crash.
73norecovery Disable recovery of the filesystem on mount.
74 This disables every write access on the device for
75 read-only mounts or snapshots. This option will fail
76 for r/w mounts on an unclean volume.
74 77
75NILFS2 usage 78NILFS2 usage
76============ 79============
diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c
index d69e6ae59251..3f959f1879d8 100644
--- a/fs/nilfs2/alloc.c
+++ b/fs/nilfs2/alloc.c
@@ -142,29 +142,75 @@ static void nilfs_palloc_desc_block_init(struct inode *inode,
142 } 142 }
143} 143}
144 144
145static int nilfs_palloc_get_block(struct inode *inode, unsigned long blkoff,
146 int create,
147 void (*init_block)(struct inode *,
148 struct buffer_head *,
149 void *),
150 struct buffer_head **bhp,
151 struct nilfs_bh_assoc *prev,
152 spinlock_t *lock)
153{
154 int ret;
155
156 spin_lock(lock);
157 if (prev->bh && blkoff == prev->blkoff) {
158 get_bh(prev->bh);
159 *bhp = prev->bh;
160 spin_unlock(lock);
161 return 0;
162 }
163 spin_unlock(lock);
164
165 ret = nilfs_mdt_get_block(inode, blkoff, create, init_block, bhp);
166 if (!ret) {
167 spin_lock(lock);
168 /*
169 * The following code must be safe for change of the
170 * cache contents during the get block call.
171 */
172 brelse(prev->bh);
173 get_bh(*bhp);
174 prev->bh = *bhp;
175 prev->blkoff = blkoff;
176 spin_unlock(lock);
177 }
178 return ret;
179}
180
145static int nilfs_palloc_get_desc_block(struct inode *inode, 181static int nilfs_palloc_get_desc_block(struct inode *inode,
146 unsigned long group, 182 unsigned long group,
147 int create, struct buffer_head **bhp) 183 int create, struct buffer_head **bhp)
148{ 184{
149 return nilfs_mdt_get_block(inode, 185 struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
150 nilfs_palloc_desc_blkoff(inode, group), 186
151 create, nilfs_palloc_desc_block_init, bhp); 187 return nilfs_palloc_get_block(inode,
188 nilfs_palloc_desc_blkoff(inode, group),
189 create, nilfs_palloc_desc_block_init,
190 bhp, &cache->prev_desc, &cache->lock);
152} 191}
153 192
154static int nilfs_palloc_get_bitmap_block(struct inode *inode, 193static int nilfs_palloc_get_bitmap_block(struct inode *inode,
155 unsigned long group, 194 unsigned long group,
156 int create, struct buffer_head **bhp) 195 int create, struct buffer_head **bhp)
157{ 196{
158 return nilfs_mdt_get_block(inode, 197 struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
159 nilfs_palloc_bitmap_blkoff(inode, group), 198
160 create, NULL, bhp); 199 return nilfs_palloc_get_block(inode,
200 nilfs_palloc_bitmap_blkoff(inode, group),
201 create, NULL, bhp,
202 &cache->prev_bitmap, &cache->lock);
161} 203}
162 204
163int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr, 205int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr,
164 int create, struct buffer_head **bhp) 206 int create, struct buffer_head **bhp)
165{ 207{
166 return nilfs_mdt_get_block(inode, nilfs_palloc_entry_blkoff(inode, nr), 208 struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
167 create, NULL, bhp); 209
210 return nilfs_palloc_get_block(inode,
211 nilfs_palloc_entry_blkoff(inode, nr),
212 create, NULL, bhp,
213 &cache->prev_entry, &cache->lock);
168} 214}
169 215
170static struct nilfs_palloc_group_desc * 216static struct nilfs_palloc_group_desc *
@@ -176,13 +222,6 @@ nilfs_palloc_block_get_group_desc(const struct inode *inode,
176 group % nilfs_palloc_groups_per_desc_block(inode); 222 group % nilfs_palloc_groups_per_desc_block(inode);
177} 223}
178 224
179static unsigned char *
180nilfs_palloc_block_get_bitmap(const struct inode *inode,
181 const struct buffer_head *bh, void *kaddr)
182{
183 return (unsigned char *)(kaddr + bh_offset(bh));
184}
185
186void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr, 225void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr,
187 const struct buffer_head *bh, void *kaddr) 226 const struct buffer_head *bh, void *kaddr)
188{ 227{
@@ -289,8 +328,7 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode,
289 if (ret < 0) 328 if (ret < 0)
290 goto out_desc; 329 goto out_desc;
291 bitmap_kaddr = kmap(bitmap_bh->b_page); 330 bitmap_kaddr = kmap(bitmap_bh->b_page);
292 bitmap = nilfs_palloc_block_get_bitmap( 331 bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
293 inode, bitmap_bh, bitmap_kaddr);
294 pos = nilfs_palloc_find_available_slot( 332 pos = nilfs_palloc_find_available_slot(
295 inode, group, group_offset, bitmap, 333 inode, group, group_offset, bitmap,
296 entries_per_group); 334 entries_per_group);
@@ -351,8 +389,7 @@ void nilfs_palloc_commit_free_entry(struct inode *inode,
351 desc = nilfs_palloc_block_get_group_desc(inode, group, 389 desc = nilfs_palloc_block_get_group_desc(inode, group,
352 req->pr_desc_bh, desc_kaddr); 390 req->pr_desc_bh, desc_kaddr);
353 bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page); 391 bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page);
354 bitmap = nilfs_palloc_block_get_bitmap(inode, req->pr_bitmap_bh, 392 bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
355 bitmap_kaddr);
356 393
357 if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group), 394 if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group),
358 group_offset, bitmap)) 395 group_offset, bitmap))
@@ -385,8 +422,7 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode,
385 desc = nilfs_palloc_block_get_group_desc(inode, group, 422 desc = nilfs_palloc_block_get_group_desc(inode, group,
386 req->pr_desc_bh, desc_kaddr); 423 req->pr_desc_bh, desc_kaddr);
387 bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page); 424 bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page);
388 bitmap = nilfs_palloc_block_get_bitmap(inode, req->pr_bitmap_bh, 425 bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
389 bitmap_kaddr);
390 if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group), 426 if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group),
391 group_offset, bitmap)) 427 group_offset, bitmap))
392 printk(KERN_WARNING "%s: entry numer %llu already freed\n", 428 printk(KERN_WARNING "%s: entry numer %llu already freed\n",
@@ -472,8 +508,7 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
472 desc = nilfs_palloc_block_get_group_desc( 508 desc = nilfs_palloc_block_get_group_desc(
473 inode, group, desc_bh, desc_kaddr); 509 inode, group, desc_bh, desc_kaddr);
474 bitmap_kaddr = kmap(bitmap_bh->b_page); 510 bitmap_kaddr = kmap(bitmap_bh->b_page);
475 bitmap = nilfs_palloc_block_get_bitmap( 511 bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
476 inode, bitmap_bh, bitmap_kaddr);
477 for (j = i, n = 0; 512 for (j = i, n = 0;
478 (j < nitems) && nilfs_palloc_group_is_in(inode, group, 513 (j < nitems) && nilfs_palloc_group_is_in(inode, group,
479 entry_nrs[j]); 514 entry_nrs[j]);
@@ -502,3 +537,30 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
502 } 537 }
503 return 0; 538 return 0;
504} 539}
540
541void nilfs_palloc_setup_cache(struct inode *inode,
542 struct nilfs_palloc_cache *cache)
543{
544 NILFS_MDT(inode)->mi_palloc_cache = cache;
545 spin_lock_init(&cache->lock);
546}
547
548void nilfs_palloc_clear_cache(struct inode *inode)
549{
550 struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
551
552 spin_lock(&cache->lock);
553 brelse(cache->prev_desc.bh);
554 brelse(cache->prev_bitmap.bh);
555 brelse(cache->prev_entry.bh);
556 cache->prev_desc.bh = NULL;
557 cache->prev_bitmap.bh = NULL;
558 cache->prev_entry.bh = NULL;
559 spin_unlock(&cache->lock);
560}
561
562void nilfs_palloc_destroy_cache(struct inode *inode)
563{
564 nilfs_palloc_clear_cache(inode);
565 NILFS_MDT(inode)->mi_palloc_cache = NULL;
566}
diff --git a/fs/nilfs2/alloc.h b/fs/nilfs2/alloc.h
index 4ace5475c2c7..f4543ac4f560 100644
--- a/fs/nilfs2/alloc.h
+++ b/fs/nilfs2/alloc.h
@@ -69,4 +69,25 @@ int nilfs_palloc_freev(struct inode *, __u64 *, size_t);
69#define nilfs_clear_bit_atomic ext2_clear_bit_atomic 69#define nilfs_clear_bit_atomic ext2_clear_bit_atomic
70#define nilfs_find_next_zero_bit ext2_find_next_zero_bit 70#define nilfs_find_next_zero_bit ext2_find_next_zero_bit
71 71
72/*
73 * persistent object allocator cache
74 */
75
76struct nilfs_bh_assoc {
77 unsigned long blkoff;
78 struct buffer_head *bh;
79};
80
81struct nilfs_palloc_cache {
82 spinlock_t lock;
83 struct nilfs_bh_assoc prev_desc;
84 struct nilfs_bh_assoc prev_bitmap;
85 struct nilfs_bh_assoc prev_entry;
86};
87
88void nilfs_palloc_setup_cache(struct inode *inode,
89 struct nilfs_palloc_cache *cache);
90void nilfs_palloc_clear_cache(struct inode *inode);
91void nilfs_palloc_destroy_cache(struct inode *inode);
92
72#endif /* _NILFS_ALLOC_H */ 93#endif /* _NILFS_ALLOC_H */
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
index 08834df6ec68..f4a14ea2ed9c 100644
--- a/fs/nilfs2/bmap.c
+++ b/fs/nilfs2/bmap.c
@@ -402,19 +402,11 @@ int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *bmap)
402void nilfs_bmap_add_blocks(const struct nilfs_bmap *bmap, int n) 402void nilfs_bmap_add_blocks(const struct nilfs_bmap *bmap, int n)
403{ 403{
404 inode_add_bytes(bmap->b_inode, (1 << bmap->b_inode->i_blkbits) * n); 404 inode_add_bytes(bmap->b_inode, (1 << bmap->b_inode->i_blkbits) * n);
405 if (NILFS_MDT(bmap->b_inode))
406 nilfs_mdt_mark_dirty(bmap->b_inode);
407 else
408 mark_inode_dirty(bmap->b_inode);
409} 405}
410 406
411void nilfs_bmap_sub_blocks(const struct nilfs_bmap *bmap, int n) 407void nilfs_bmap_sub_blocks(const struct nilfs_bmap *bmap, int n)
412{ 408{
413 inode_sub_bytes(bmap->b_inode, (1 << bmap->b_inode->i_blkbits) * n); 409 inode_sub_bytes(bmap->b_inode, (1 << bmap->b_inode->i_blkbits) * n);
414 if (NILFS_MDT(bmap->b_inode))
415 nilfs_mdt_mark_dirty(bmap->b_inode);
416 else
417 mark_inode_dirty(bmap->b_inode);
418} 410}
419 411
420__u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *bmap, 412__u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *bmap,
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index 84c25382f8e3..471e269536ae 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -68,9 +68,34 @@ void nilfs_btnode_cache_clear(struct address_space *btnc)
68 truncate_inode_pages(btnc, 0); 68 truncate_inode_pages(btnc, 0);
69} 69}
70 70
71struct buffer_head *
72nilfs_btnode_create_block(struct address_space *btnc, __u64 blocknr)
73{
74 struct inode *inode = NILFS_BTNC_I(btnc);
75 struct buffer_head *bh;
76
77 bh = nilfs_grab_buffer(inode, btnc, blocknr, 1 << BH_NILFS_Node);
78 if (unlikely(!bh))
79 return NULL;
80
81 if (unlikely(buffer_mapped(bh) || buffer_uptodate(bh) ||
82 buffer_dirty(bh))) {
83 brelse(bh);
84 BUG();
85 }
86 memset(bh->b_data, 0, 1 << inode->i_blkbits);
87 bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev;
88 bh->b_blocknr = blocknr;
89 set_buffer_mapped(bh);
90 set_buffer_uptodate(bh);
91
92 unlock_page(bh->b_page);
93 page_cache_release(bh->b_page);
94 return bh;
95}
96
71int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr, 97int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
72 sector_t pblocknr, struct buffer_head **pbh, 98 sector_t pblocknr, struct buffer_head **pbh)
73 int newblk)
74{ 99{
75 struct buffer_head *bh; 100 struct buffer_head *bh;
76 struct inode *inode = NILFS_BTNC_I(btnc); 101 struct inode *inode = NILFS_BTNC_I(btnc);
@@ -81,19 +106,6 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
81 return -ENOMEM; 106 return -ENOMEM;
82 107
83 err = -EEXIST; /* internal code */ 108 err = -EEXIST; /* internal code */
84 if (newblk) {
85 if (unlikely(buffer_mapped(bh) || buffer_uptodate(bh) ||
86 buffer_dirty(bh))) {
87 brelse(bh);
88 BUG();
89 }
90 memset(bh->b_data, 0, 1 << inode->i_blkbits);
91 bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev;
92 bh->b_blocknr = blocknr;
93 set_buffer_mapped(bh);
94 set_buffer_uptodate(bh);
95 goto found;
96 }
97 109
98 if (buffer_uptodate(bh) || buffer_dirty(bh)) 110 if (buffer_uptodate(bh) || buffer_dirty(bh))
99 goto found; 111 goto found;
@@ -135,27 +147,6 @@ out_locked:
135 return err; 147 return err;
136} 148}
137 149
138int nilfs_btnode_get(struct address_space *btnc, __u64 blocknr,
139 sector_t pblocknr, struct buffer_head **pbh, int newblk)
140{
141 struct buffer_head *bh;
142 int err;
143
144 err = nilfs_btnode_submit_block(btnc, blocknr, pblocknr, pbh, newblk);
145 if (err == -EEXIST) /* internal code (cache hit) */
146 return 0;
147 if (unlikely(err))
148 return err;
149
150 bh = *pbh;
151 wait_on_buffer(bh);
152 if (!buffer_uptodate(bh)) {
153 brelse(bh);
154 return -EIO;
155 }
156 return 0;
157}
158
159/** 150/**
160 * nilfs_btnode_delete - delete B-tree node buffer 151 * nilfs_btnode_delete - delete B-tree node buffer
161 * @bh: buffer to be deleted 152 * @bh: buffer to be deleted
@@ -244,12 +235,13 @@ retry:
244 unlock_page(obh->b_page); 235 unlock_page(obh->b_page);
245 } 236 }
246 237
247 err = nilfs_btnode_get(btnc, newkey, 0, &nbh, 1); 238 nbh = nilfs_btnode_create_block(btnc, newkey);
248 if (likely(!err)) { 239 if (!nbh)
249 BUG_ON(nbh == obh); 240 return -ENOMEM;
250 ctxt->newbh = nbh; 241
251 } 242 BUG_ON(nbh == obh);
252 return err; 243 ctxt->newbh = nbh;
244 return 0;
253 245
254 failed_unlock: 246 failed_unlock:
255 unlock_page(obh->b_page); 247 unlock_page(obh->b_page);
diff --git a/fs/nilfs2/btnode.h b/fs/nilfs2/btnode.h
index 3e2275172ed6..07da83f07712 100644
--- a/fs/nilfs2/btnode.h
+++ b/fs/nilfs2/btnode.h
@@ -40,10 +40,10 @@ struct nilfs_btnode_chkey_ctxt {
40void nilfs_btnode_cache_init_once(struct address_space *); 40void nilfs_btnode_cache_init_once(struct address_space *);
41void nilfs_btnode_cache_init(struct address_space *, struct backing_dev_info *); 41void nilfs_btnode_cache_init(struct address_space *, struct backing_dev_info *);
42void nilfs_btnode_cache_clear(struct address_space *); 42void nilfs_btnode_cache_clear(struct address_space *);
43struct buffer_head *nilfs_btnode_create_block(struct address_space *btnc,
44 __u64 blocknr);
43int nilfs_btnode_submit_block(struct address_space *, __u64, sector_t, 45int nilfs_btnode_submit_block(struct address_space *, __u64, sector_t,
44 struct buffer_head **, int); 46 struct buffer_head **);
45int nilfs_btnode_get(struct address_space *, __u64, sector_t,
46 struct buffer_head **, int);
47void nilfs_btnode_delete(struct buffer_head *); 47void nilfs_btnode_delete(struct buffer_head *);
48int nilfs_btnode_prepare_change_key(struct address_space *, 48int nilfs_btnode_prepare_change_key(struct address_space *,
49 struct nilfs_btnode_chkey_ctxt *); 49 struct nilfs_btnode_chkey_ctxt *);
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index e25b507a474f..7cdd98b8d514 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -114,7 +114,18 @@ static int nilfs_btree_get_block(const struct nilfs_btree *btree, __u64 ptr,
114{ 114{
115 struct address_space *btnc = 115 struct address_space *btnc =
116 &NILFS_BMAP_I((struct nilfs_bmap *)btree)->i_btnode_cache; 116 &NILFS_BMAP_I((struct nilfs_bmap *)btree)->i_btnode_cache;
117 return nilfs_btnode_get(btnc, ptr, 0, bhp, 0); 117 int err;
118
119 err = nilfs_btnode_submit_block(btnc, ptr, 0, bhp);
120 if (err)
121 return err == -EEXIST ? 0 : err;
122
123 wait_on_buffer(*bhp);
124 if (!buffer_uptodate(*bhp)) {
125 brelse(*bhp);
126 return -EIO;
127 }
128 return 0;
118} 129}
119 130
120static int nilfs_btree_get_new_block(const struct nilfs_btree *btree, 131static int nilfs_btree_get_new_block(const struct nilfs_btree *btree,
@@ -122,12 +133,15 @@ static int nilfs_btree_get_new_block(const struct nilfs_btree *btree,
122{ 133{
123 struct address_space *btnc = 134 struct address_space *btnc =
124 &NILFS_BMAP_I((struct nilfs_bmap *)btree)->i_btnode_cache; 135 &NILFS_BMAP_I((struct nilfs_bmap *)btree)->i_btnode_cache;
125 int ret; 136 struct buffer_head *bh;
126 137
127 ret = nilfs_btnode_get(btnc, ptr, 0, bhp, 1); 138 bh = nilfs_btnode_create_block(btnc, ptr);
128 if (!ret) 139 if (!bh)
129 set_buffer_nilfs_volatile(*bhp); 140 return -ENOMEM;
130 return ret; 141
142 set_buffer_nilfs_volatile(bh);
143 *bhp = bh;
144 return 0;
131} 145}
132 146
133static inline int 147static inline int
@@ -444,6 +458,18 @@ nilfs_btree_get_node(const struct nilfs_btree *btree,
444 nilfs_btree_get_nonroot_node(path, level); 458 nilfs_btree_get_nonroot_node(path, level);
445} 459}
446 460
461static inline int
462nilfs_btree_bad_node(struct nilfs_btree_node *node, int level)
463{
464 if (unlikely(nilfs_btree_node_get_level(node) != level)) {
465 dump_stack();
466 printk(KERN_CRIT "NILFS: btree level mismatch: %d != %d\n",
467 nilfs_btree_node_get_level(node), level);
468 return 1;
469 }
470 return 0;
471}
472
447static int nilfs_btree_do_lookup(const struct nilfs_btree *btree, 473static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
448 struct nilfs_btree_path *path, 474 struct nilfs_btree_path *path,
449 __u64 key, __u64 *ptrp, int minlevel) 475 __u64 key, __u64 *ptrp, int minlevel)
@@ -467,7 +493,8 @@ static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
467 if (ret < 0) 493 if (ret < 0)
468 return ret; 494 return ret;
469 node = nilfs_btree_get_nonroot_node(path, level); 495 node = nilfs_btree_get_nonroot_node(path, level);
470 BUG_ON(level != nilfs_btree_node_get_level(node)); 496 if (nilfs_btree_bad_node(node, level))
497 return -EINVAL;
471 if (!found) 498 if (!found)
472 found = nilfs_btree_node_lookup(node, key, &index); 499 found = nilfs_btree_node_lookup(node, key, &index);
473 else 500 else
@@ -512,7 +539,8 @@ static int nilfs_btree_do_lookup_last(const struct nilfs_btree *btree,
512 if (ret < 0) 539 if (ret < 0)
513 return ret; 540 return ret;
514 node = nilfs_btree_get_nonroot_node(path, level); 541 node = nilfs_btree_get_nonroot_node(path, level);
515 BUG_ON(level != nilfs_btree_node_get_level(node)); 542 if (nilfs_btree_bad_node(node, level))
543 return -EINVAL;
516 index = nilfs_btree_node_get_nchildren(node) - 1; 544 index = nilfs_btree_node_get_nchildren(node) - 1;
517 ptr = nilfs_btree_node_get_ptr(btree, node, index); 545 ptr = nilfs_btree_node_get_ptr(btree, node, index);
518 path[level].bp_index = index; 546 path[level].bp_index = index;
@@ -638,13 +666,11 @@ static void nilfs_btree_promote_key(struct nilfs_btree *btree,
638{ 666{
639 if (level < nilfs_btree_height(btree) - 1) { 667 if (level < nilfs_btree_height(btree) - 1) {
640 do { 668 do {
641 lock_buffer(path[level].bp_bh);
642 nilfs_btree_node_set_key( 669 nilfs_btree_node_set_key(
643 nilfs_btree_get_nonroot_node(path, level), 670 nilfs_btree_get_nonroot_node(path, level),
644 path[level].bp_index, key); 671 path[level].bp_index, key);
645 if (!buffer_dirty(path[level].bp_bh)) 672 if (!buffer_dirty(path[level].bp_bh))
646 nilfs_btnode_mark_dirty(path[level].bp_bh); 673 nilfs_btnode_mark_dirty(path[level].bp_bh);
647 unlock_buffer(path[level].bp_bh);
648 } while ((path[level].bp_index == 0) && 674 } while ((path[level].bp_index == 0) &&
649 (++level < nilfs_btree_height(btree) - 1)); 675 (++level < nilfs_btree_height(btree) - 1));
650 } 676 }
@@ -663,13 +689,11 @@ static void nilfs_btree_do_insert(struct nilfs_btree *btree,
663 struct nilfs_btree_node *node; 689 struct nilfs_btree_node *node;
664 690
665 if (level < nilfs_btree_height(btree) - 1) { 691 if (level < nilfs_btree_height(btree) - 1) {
666 lock_buffer(path[level].bp_bh);
667 node = nilfs_btree_get_nonroot_node(path, level); 692 node = nilfs_btree_get_nonroot_node(path, level);
668 nilfs_btree_node_insert(btree, node, *keyp, *ptrp, 693 nilfs_btree_node_insert(btree, node, *keyp, *ptrp,
669 path[level].bp_index); 694 path[level].bp_index);
670 if (!buffer_dirty(path[level].bp_bh)) 695 if (!buffer_dirty(path[level].bp_bh))
671 nilfs_btnode_mark_dirty(path[level].bp_bh); 696 nilfs_btnode_mark_dirty(path[level].bp_bh);
672 unlock_buffer(path[level].bp_bh);
673 697
674 if (path[level].bp_index == 0) 698 if (path[level].bp_index == 0)
675 nilfs_btree_promote_key(btree, path, level + 1, 699 nilfs_btree_promote_key(btree, path, level + 1,
@@ -689,9 +713,6 @@ static void nilfs_btree_carry_left(struct nilfs_btree *btree,
689 struct nilfs_btree_node *node, *left; 713 struct nilfs_btree_node *node, *left;
690 int nchildren, lnchildren, n, move; 714 int nchildren, lnchildren, n, move;
691 715
692 lock_buffer(path[level].bp_bh);
693 lock_buffer(path[level].bp_sib_bh);
694
695 node = nilfs_btree_get_nonroot_node(path, level); 716 node = nilfs_btree_get_nonroot_node(path, level);
696 left = nilfs_btree_get_sib_node(path, level); 717 left = nilfs_btree_get_sib_node(path, level);
697 nchildren = nilfs_btree_node_get_nchildren(node); 718 nchildren = nilfs_btree_node_get_nchildren(node);
@@ -712,9 +733,6 @@ static void nilfs_btree_carry_left(struct nilfs_btree *btree,
712 if (!buffer_dirty(path[level].bp_sib_bh)) 733 if (!buffer_dirty(path[level].bp_sib_bh))
713 nilfs_btnode_mark_dirty(path[level].bp_sib_bh); 734 nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
714 735
715 unlock_buffer(path[level].bp_bh);
716 unlock_buffer(path[level].bp_sib_bh);
717
718 nilfs_btree_promote_key(btree, path, level + 1, 736 nilfs_btree_promote_key(btree, path, level + 1,
719 nilfs_btree_node_get_key(node, 0)); 737 nilfs_btree_node_get_key(node, 0));
720 738
@@ -740,9 +758,6 @@ static void nilfs_btree_carry_right(struct nilfs_btree *btree,
740 struct nilfs_btree_node *node, *right; 758 struct nilfs_btree_node *node, *right;
741 int nchildren, rnchildren, n, move; 759 int nchildren, rnchildren, n, move;
742 760
743 lock_buffer(path[level].bp_bh);
744 lock_buffer(path[level].bp_sib_bh);
745
746 node = nilfs_btree_get_nonroot_node(path, level); 761 node = nilfs_btree_get_nonroot_node(path, level);
747 right = nilfs_btree_get_sib_node(path, level); 762 right = nilfs_btree_get_sib_node(path, level);
748 nchildren = nilfs_btree_node_get_nchildren(node); 763 nchildren = nilfs_btree_node_get_nchildren(node);
@@ -763,9 +778,6 @@ static void nilfs_btree_carry_right(struct nilfs_btree *btree,
763 if (!buffer_dirty(path[level].bp_sib_bh)) 778 if (!buffer_dirty(path[level].bp_sib_bh))
764 nilfs_btnode_mark_dirty(path[level].bp_sib_bh); 779 nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
765 780
766 unlock_buffer(path[level].bp_bh);
767 unlock_buffer(path[level].bp_sib_bh);
768
769 path[level + 1].bp_index++; 781 path[level + 1].bp_index++;
770 nilfs_btree_promote_key(btree, path, level + 1, 782 nilfs_btree_promote_key(btree, path, level + 1,
771 nilfs_btree_node_get_key(right, 0)); 783 nilfs_btree_node_get_key(right, 0));
@@ -794,9 +806,6 @@ static void nilfs_btree_split(struct nilfs_btree *btree,
794 __u64 newptr; 806 __u64 newptr;
795 int nchildren, n, move; 807 int nchildren, n, move;
796 808
797 lock_buffer(path[level].bp_bh);
798 lock_buffer(path[level].bp_sib_bh);
799
800 node = nilfs_btree_get_nonroot_node(path, level); 809 node = nilfs_btree_get_nonroot_node(path, level);
801 right = nilfs_btree_get_sib_node(path, level); 810 right = nilfs_btree_get_sib_node(path, level);
802 nchildren = nilfs_btree_node_get_nchildren(node); 811 nchildren = nilfs_btree_node_get_nchildren(node);
@@ -815,9 +824,6 @@ static void nilfs_btree_split(struct nilfs_btree *btree,
815 if (!buffer_dirty(path[level].bp_sib_bh)) 824 if (!buffer_dirty(path[level].bp_sib_bh))
816 nilfs_btnode_mark_dirty(path[level].bp_sib_bh); 825 nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
817 826
818 unlock_buffer(path[level].bp_bh);
819 unlock_buffer(path[level].bp_sib_bh);
820
821 newkey = nilfs_btree_node_get_key(right, 0); 827 newkey = nilfs_btree_node_get_key(right, 0);
822 newptr = path[level].bp_newreq.bpr_ptr; 828 newptr = path[level].bp_newreq.bpr_ptr;
823 829
@@ -852,8 +858,6 @@ static void nilfs_btree_grow(struct nilfs_btree *btree,
852 struct nilfs_btree_node *root, *child; 858 struct nilfs_btree_node *root, *child;
853 int n; 859 int n;
854 860
855 lock_buffer(path[level].bp_sib_bh);
856
857 root = nilfs_btree_get_root(btree); 861 root = nilfs_btree_get_root(btree);
858 child = nilfs_btree_get_sib_node(path, level); 862 child = nilfs_btree_get_sib_node(path, level);
859 863
@@ -865,8 +869,6 @@ static void nilfs_btree_grow(struct nilfs_btree *btree,
865 if (!buffer_dirty(path[level].bp_sib_bh)) 869 if (!buffer_dirty(path[level].bp_sib_bh))
866 nilfs_btnode_mark_dirty(path[level].bp_sib_bh); 870 nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
867 871
868 unlock_buffer(path[level].bp_sib_bh);
869
870 path[level].bp_bh = path[level].bp_sib_bh; 872 path[level].bp_bh = path[level].bp_sib_bh;
871 path[level].bp_sib_bh = NULL; 873 path[level].bp_sib_bh = NULL;
872 874
@@ -1023,11 +1025,9 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
1023 1025
1024 stats->bs_nblocks++; 1026 stats->bs_nblocks++;
1025 1027
1026 lock_buffer(bh);
1027 nilfs_btree_node_init(btree, 1028 nilfs_btree_node_init(btree,
1028 (struct nilfs_btree_node *)bh->b_data, 1029 (struct nilfs_btree_node *)bh->b_data,
1029 0, level, 0, NULL, NULL); 1030 0, level, 0, NULL, NULL);
1030 unlock_buffer(bh);
1031 path[level].bp_sib_bh = bh; 1031 path[level].bp_sib_bh = bh;
1032 path[level].bp_op = nilfs_btree_split; 1032 path[level].bp_op = nilfs_btree_split;
1033 } 1033 }
@@ -1052,10 +1052,8 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
1052 if (ret < 0) 1052 if (ret < 0)
1053 goto err_out_curr_node; 1053 goto err_out_curr_node;
1054 1054
1055 lock_buffer(bh);
1056 nilfs_btree_node_init(btree, (struct nilfs_btree_node *)bh->b_data, 1055 nilfs_btree_node_init(btree, (struct nilfs_btree_node *)bh->b_data,
1057 0, level, 0, NULL, NULL); 1056 0, level, 0, NULL, NULL);
1058 unlock_buffer(bh);
1059 path[level].bp_sib_bh = bh; 1057 path[level].bp_sib_bh = bh;
1060 path[level].bp_op = nilfs_btree_grow; 1058 path[level].bp_op = nilfs_btree_grow;
1061 1059
@@ -1154,13 +1152,11 @@ static void nilfs_btree_do_delete(struct nilfs_btree *btree,
1154 struct nilfs_btree_node *node; 1152 struct nilfs_btree_node *node;
1155 1153
1156 if (level < nilfs_btree_height(btree) - 1) { 1154 if (level < nilfs_btree_height(btree) - 1) {
1157 lock_buffer(path[level].bp_bh);
1158 node = nilfs_btree_get_nonroot_node(path, level); 1155 node = nilfs_btree_get_nonroot_node(path, level);
1159 nilfs_btree_node_delete(btree, node, keyp, ptrp, 1156 nilfs_btree_node_delete(btree, node, keyp, ptrp,
1160 path[level].bp_index); 1157 path[level].bp_index);
1161 if (!buffer_dirty(path[level].bp_bh)) 1158 if (!buffer_dirty(path[level].bp_bh))
1162 nilfs_btnode_mark_dirty(path[level].bp_bh); 1159 nilfs_btnode_mark_dirty(path[level].bp_bh);
1163 unlock_buffer(path[level].bp_bh);
1164 if (path[level].bp_index == 0) 1160 if (path[level].bp_index == 0)
1165 nilfs_btree_promote_key(btree, path, level + 1, 1161 nilfs_btree_promote_key(btree, path, level + 1,
1166 nilfs_btree_node_get_key(node, 0)); 1162 nilfs_btree_node_get_key(node, 0));
@@ -1180,9 +1176,6 @@ static void nilfs_btree_borrow_left(struct nilfs_btree *btree,
1180 1176
1181 nilfs_btree_do_delete(btree, path, level, keyp, ptrp); 1177 nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
1182 1178
1183 lock_buffer(path[level].bp_bh);
1184 lock_buffer(path[level].bp_sib_bh);
1185
1186 node = nilfs_btree_get_nonroot_node(path, level); 1179 node = nilfs_btree_get_nonroot_node(path, level);
1187 left = nilfs_btree_get_sib_node(path, level); 1180 left = nilfs_btree_get_sib_node(path, level);
1188 nchildren = nilfs_btree_node_get_nchildren(node); 1181 nchildren = nilfs_btree_node_get_nchildren(node);
@@ -1197,9 +1190,6 @@ static void nilfs_btree_borrow_left(struct nilfs_btree *btree,
1197 if (!buffer_dirty(path[level].bp_sib_bh)) 1190 if (!buffer_dirty(path[level].bp_sib_bh))
1198 nilfs_btnode_mark_dirty(path[level].bp_sib_bh); 1191 nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
1199 1192
1200 unlock_buffer(path[level].bp_bh);
1201 unlock_buffer(path[level].bp_sib_bh);
1202
1203 nilfs_btree_promote_key(btree, path, level + 1, 1193 nilfs_btree_promote_key(btree, path, level + 1,
1204 nilfs_btree_node_get_key(node, 0)); 1194 nilfs_btree_node_get_key(node, 0));
1205 1195
@@ -1217,9 +1207,6 @@ static void nilfs_btree_borrow_right(struct nilfs_btree *btree,
1217 1207
1218 nilfs_btree_do_delete(btree, path, level, keyp, ptrp); 1208 nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
1219 1209
1220 lock_buffer(path[level].bp_bh);
1221 lock_buffer(path[level].bp_sib_bh);
1222
1223 node = nilfs_btree_get_nonroot_node(path, level); 1210 node = nilfs_btree_get_nonroot_node(path, level);
1224 right = nilfs_btree_get_sib_node(path, level); 1211 right = nilfs_btree_get_sib_node(path, level);
1225 nchildren = nilfs_btree_node_get_nchildren(node); 1212 nchildren = nilfs_btree_node_get_nchildren(node);
@@ -1234,9 +1221,6 @@ static void nilfs_btree_borrow_right(struct nilfs_btree *btree,
1234 if (!buffer_dirty(path[level].bp_sib_bh)) 1221 if (!buffer_dirty(path[level].bp_sib_bh))
1235 nilfs_btnode_mark_dirty(path[level].bp_sib_bh); 1222 nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
1236 1223
1237 unlock_buffer(path[level].bp_bh);
1238 unlock_buffer(path[level].bp_sib_bh);
1239
1240 path[level + 1].bp_index++; 1224 path[level + 1].bp_index++;
1241 nilfs_btree_promote_key(btree, path, level + 1, 1225 nilfs_btree_promote_key(btree, path, level + 1,
1242 nilfs_btree_node_get_key(right, 0)); 1226 nilfs_btree_node_get_key(right, 0));
@@ -1255,9 +1239,6 @@ static void nilfs_btree_concat_left(struct nilfs_btree *btree,
1255 1239
1256 nilfs_btree_do_delete(btree, path, level, keyp, ptrp); 1240 nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
1257 1241
1258 lock_buffer(path[level].bp_bh);
1259 lock_buffer(path[level].bp_sib_bh);
1260
1261 node = nilfs_btree_get_nonroot_node(path, level); 1242 node = nilfs_btree_get_nonroot_node(path, level);
1262 left = nilfs_btree_get_sib_node(path, level); 1243 left = nilfs_btree_get_sib_node(path, level);
1263 1244
@@ -1268,9 +1249,6 @@ static void nilfs_btree_concat_left(struct nilfs_btree *btree,
1268 if (!buffer_dirty(path[level].bp_sib_bh)) 1249 if (!buffer_dirty(path[level].bp_sib_bh))
1269 nilfs_btnode_mark_dirty(path[level].bp_sib_bh); 1250 nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
1270 1251
1271 unlock_buffer(path[level].bp_bh);
1272 unlock_buffer(path[level].bp_sib_bh);
1273
1274 nilfs_btnode_delete(path[level].bp_bh); 1252 nilfs_btnode_delete(path[level].bp_bh);
1275 path[level].bp_bh = path[level].bp_sib_bh; 1253 path[level].bp_bh = path[level].bp_sib_bh;
1276 path[level].bp_sib_bh = NULL; 1254 path[level].bp_sib_bh = NULL;
@@ -1286,9 +1264,6 @@ static void nilfs_btree_concat_right(struct nilfs_btree *btree,
1286 1264
1287 nilfs_btree_do_delete(btree, path, level, keyp, ptrp); 1265 nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
1288 1266
1289 lock_buffer(path[level].bp_bh);
1290 lock_buffer(path[level].bp_sib_bh);
1291
1292 node = nilfs_btree_get_nonroot_node(path, level); 1267 node = nilfs_btree_get_nonroot_node(path, level);
1293 right = nilfs_btree_get_sib_node(path, level); 1268 right = nilfs_btree_get_sib_node(path, level);
1294 1269
@@ -1299,9 +1274,6 @@ static void nilfs_btree_concat_right(struct nilfs_btree *btree,
1299 if (!buffer_dirty(path[level].bp_bh)) 1274 if (!buffer_dirty(path[level].bp_bh))
1300 nilfs_btnode_mark_dirty(path[level].bp_bh); 1275 nilfs_btnode_mark_dirty(path[level].bp_bh);
1301 1276
1302 unlock_buffer(path[level].bp_bh);
1303 unlock_buffer(path[level].bp_sib_bh);
1304
1305 nilfs_btnode_delete(path[level].bp_sib_bh); 1277 nilfs_btnode_delete(path[level].bp_sib_bh);
1306 path[level].bp_sib_bh = NULL; 1278 path[level].bp_sib_bh = NULL;
1307 path[level + 1].bp_index++; 1279 path[level + 1].bp_index++;
@@ -1316,7 +1288,6 @@ static void nilfs_btree_shrink(struct nilfs_btree *btree,
1316 1288
1317 nilfs_btree_do_delete(btree, path, level, keyp, ptrp); 1289 nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
1318 1290
1319 lock_buffer(path[level].bp_bh);
1320 root = nilfs_btree_get_root(btree); 1291 root = nilfs_btree_get_root(btree);
1321 child = nilfs_btree_get_nonroot_node(path, level); 1292 child = nilfs_btree_get_nonroot_node(path, level);
1322 1293
@@ -1324,7 +1295,6 @@ static void nilfs_btree_shrink(struct nilfs_btree *btree,
1324 nilfs_btree_node_set_level(root, level); 1295 nilfs_btree_node_set_level(root, level);
1325 n = nilfs_btree_node_get_nchildren(child); 1296 n = nilfs_btree_node_get_nchildren(child);
1326 nilfs_btree_node_move_left(btree, root, child, n); 1297 nilfs_btree_node_move_left(btree, root, child, n);
1327 unlock_buffer(path[level].bp_bh);
1328 1298
1329 nilfs_btnode_delete(path[level].bp_bh); 1299 nilfs_btnode_delete(path[level].bp_bh);
1330 path[level].bp_bh = NULL; 1300 path[level].bp_bh = NULL;
@@ -1699,7 +1669,6 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
1699 nilfs_bmap_commit_alloc_ptr(bmap, nreq, dat); 1669 nilfs_bmap_commit_alloc_ptr(bmap, nreq, dat);
1700 1670
1701 /* create child node at level 1 */ 1671 /* create child node at level 1 */
1702 lock_buffer(bh);
1703 node = (struct nilfs_btree_node *)bh->b_data; 1672 node = (struct nilfs_btree_node *)bh->b_data;
1704 nilfs_btree_node_init(btree, node, 0, 1, n, keys, ptrs); 1673 nilfs_btree_node_init(btree, node, 0, 1, n, keys, ptrs);
1705 nilfs_btree_node_insert(btree, node, 1674 nilfs_btree_node_insert(btree, node,
@@ -1709,7 +1678,6 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
1709 if (!nilfs_bmap_dirty(bmap)) 1678 if (!nilfs_bmap_dirty(bmap))
1710 nilfs_bmap_set_dirty(bmap); 1679 nilfs_bmap_set_dirty(bmap);
1711 1680
1712 unlock_buffer(bh);
1713 brelse(bh); 1681 brelse(bh);
1714 1682
1715 /* create root node at level 2 */ 1683 /* create root node at level 2 */
@@ -2050,7 +2018,7 @@ static void nilfs_btree_lookup_dirty_buffers(struct nilfs_bmap *bmap,
2050 for (level = NILFS_BTREE_LEVEL_NODE_MIN; 2018 for (level = NILFS_BTREE_LEVEL_NODE_MIN;
2051 level < NILFS_BTREE_LEVEL_MAX; 2019 level < NILFS_BTREE_LEVEL_MAX;
2052 level++) 2020 level++)
2053 list_splice(&lists[level], listp->prev); 2021 list_splice_tail(&lists[level], listp);
2054} 2022}
2055 2023
2056static int nilfs_btree_assign_p(struct nilfs_btree *btree, 2024static int nilfs_btree_assign_p(struct nilfs_btree *btree,
diff --git a/fs/nilfs2/btree.h b/fs/nilfs2/btree.h
index 0e72bbbc6b64..4b82d84ade75 100644
--- a/fs/nilfs2/btree.h
+++ b/fs/nilfs2/btree.h
@@ -34,28 +34,6 @@ struct nilfs_btree;
34struct nilfs_btree_path; 34struct nilfs_btree_path;
35 35
36/** 36/**
37 * struct nilfs_btree_node - B-tree node
38 * @bn_flags: flags
39 * @bn_level: level
40 * @bn_nchildren: number of children
41 * @bn_pad: padding
42 */
43struct nilfs_btree_node {
44 __u8 bn_flags;
45 __u8 bn_level;
46 __le16 bn_nchildren;
47 __le32 bn_pad;
48};
49
50/* flags */
51#define NILFS_BTREE_NODE_ROOT 0x01
52
53/* level */
54#define NILFS_BTREE_LEVEL_DATA 0
55#define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1)
56#define NILFS_BTREE_LEVEL_MAX 14
57
58/**
59 * struct nilfs_btree - B-tree structure 37 * struct nilfs_btree - B-tree structure
60 * @bt_bmap: bmap base structure 38 * @bt_bmap: bmap base structure
61 */ 39 */
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c
index 3f5d5d06f53c..d5ad54e204a5 100644
--- a/fs/nilfs2/cpfile.c
+++ b/fs/nilfs2/cpfile.c
@@ -926,3 +926,29 @@ int nilfs_cpfile_get_stat(struct inode *cpfile, struct nilfs_cpstat *cpstat)
926 up_read(&NILFS_MDT(cpfile)->mi_sem); 926 up_read(&NILFS_MDT(cpfile)->mi_sem);
927 return ret; 927 return ret;
928} 928}
929
930/**
931 * nilfs_cpfile_read - read cpfile inode
932 * @cpfile: cpfile inode
933 * @raw_inode: on-disk cpfile inode
934 */
935int nilfs_cpfile_read(struct inode *cpfile, struct nilfs_inode *raw_inode)
936{
937 return nilfs_read_inode_common(cpfile, raw_inode);
938}
939
940/**
941 * nilfs_cpfile_new - create cpfile
942 * @nilfs: nilfs object
943 * @cpsize: size of a checkpoint entry
944 */
945struct inode *nilfs_cpfile_new(struct the_nilfs *nilfs, size_t cpsize)
946{
947 struct inode *cpfile;
948
949 cpfile = nilfs_mdt_new(nilfs, NULL, NILFS_CPFILE_INO, 0);
950 if (cpfile)
951 nilfs_mdt_set_entry_size(cpfile, cpsize,
952 sizeof(struct nilfs_cpfile_header));
953 return cpfile;
954}
diff --git a/fs/nilfs2/cpfile.h b/fs/nilfs2/cpfile.h
index debea896e701..bc0809e0ab43 100644
--- a/fs/nilfs2/cpfile.h
+++ b/fs/nilfs2/cpfile.h
@@ -40,4 +40,7 @@ int nilfs_cpfile_get_stat(struct inode *, struct nilfs_cpstat *);
40ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int, void *, unsigned, 40ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int, void *, unsigned,
41 size_t); 41 size_t);
42 42
43int nilfs_cpfile_read(struct inode *cpfile, struct nilfs_inode *raw_inode);
44struct inode *nilfs_cpfile_new(struct the_nilfs *nilfs, size_t cpsize);
45
43#endif /* _NILFS_CPFILE_H */ 46#endif /* _NILFS_CPFILE_H */
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c
index 1ff8e15bd36b..187dd07ba86c 100644
--- a/fs/nilfs2/dat.c
+++ b/fs/nilfs2/dat.c
@@ -33,6 +33,16 @@
33#define NILFS_CNO_MIN ((__u64)1) 33#define NILFS_CNO_MIN ((__u64)1)
34#define NILFS_CNO_MAX (~(__u64)0) 34#define NILFS_CNO_MAX (~(__u64)0)
35 35
36struct nilfs_dat_info {
37 struct nilfs_mdt_info mi;
38 struct nilfs_palloc_cache palloc_cache;
39};
40
41static inline struct nilfs_dat_info *NILFS_DAT_I(struct inode *dat)
42{
43 return (struct nilfs_dat_info *)NILFS_MDT(dat);
44}
45
36static int nilfs_dat_prepare_entry(struct inode *dat, 46static int nilfs_dat_prepare_entry(struct inode *dat,
37 struct nilfs_palloc_req *req, int create) 47 struct nilfs_palloc_req *req, int create)
38{ 48{
@@ -425,3 +435,40 @@ ssize_t nilfs_dat_get_vinfo(struct inode *dat, void *buf, unsigned visz,
425 435
426 return nvi; 436 return nvi;
427} 437}
438
439/**
440 * nilfs_dat_read - read dat inode
441 * @dat: dat inode
442 * @raw_inode: on-disk dat inode
443 */
444int nilfs_dat_read(struct inode *dat, struct nilfs_inode *raw_inode)
445{
446 return nilfs_read_inode_common(dat, raw_inode);
447}
448
449/**
450 * nilfs_dat_new - create dat file
451 * @nilfs: nilfs object
452 * @entry_size: size of a dat entry
453 */
454struct inode *nilfs_dat_new(struct the_nilfs *nilfs, size_t entry_size)
455{
456 static struct lock_class_key dat_lock_key;
457 struct inode *dat;
458 struct nilfs_dat_info *di;
459 int err;
460
461 dat = nilfs_mdt_new(nilfs, NULL, NILFS_DAT_INO, sizeof(*di));
462 if (dat) {
463 err = nilfs_palloc_init_blockgroup(dat, entry_size);
464 if (unlikely(err)) {
465 nilfs_mdt_destroy(dat);
466 return NULL;
467 }
468
469 di = NILFS_DAT_I(dat);
470 lockdep_set_class(&di->mi.mi_sem, &dat_lock_key);
471 nilfs_palloc_setup_cache(dat, &di->palloc_cache);
472 }
473 return dat;
474}
diff --git a/fs/nilfs2/dat.h b/fs/nilfs2/dat.h
index 406070d3ff49..d31c3aab0efe 100644
--- a/fs/nilfs2/dat.h
+++ b/fs/nilfs2/dat.h
@@ -53,4 +53,7 @@ int nilfs_dat_freev(struct inode *, __u64 *, size_t);
53int nilfs_dat_move(struct inode *, __u64, sector_t); 53int nilfs_dat_move(struct inode *, __u64, sector_t);
54ssize_t nilfs_dat_get_vinfo(struct inode *, void *, unsigned, size_t); 54ssize_t nilfs_dat_get_vinfo(struct inode *, void *, unsigned, size_t);
55 55
56int nilfs_dat_read(struct inode *dat, struct nilfs_inode *raw_inode);
57struct inode *nilfs_dat_new(struct the_nilfs *nilfs, size_t entry_size);
58
56#endif /* _NILFS_DAT_H */ 59#endif /* _NILFS_DAT_H */
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index e097099bfc8f..76d803e060a9 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -99,9 +99,9 @@ static int nilfs_prepare_chunk(struct page *page,
99 NULL, nilfs_get_block); 99 NULL, nilfs_get_block);
100} 100}
101 101
102static int nilfs_commit_chunk(struct page *page, 102static void nilfs_commit_chunk(struct page *page,
103 struct address_space *mapping, 103 struct address_space *mapping,
104 unsigned from, unsigned to) 104 unsigned from, unsigned to)
105{ 105{
106 struct inode *dir = mapping->host; 106 struct inode *dir = mapping->host;
107 struct nilfs_sb_info *sbi = NILFS_SB(dir->i_sb); 107 struct nilfs_sb_info *sbi = NILFS_SB(dir->i_sb);
@@ -112,15 +112,13 @@ static int nilfs_commit_chunk(struct page *page,
112 112
113 nr_dirty = nilfs_page_count_clean_buffers(page, from, to); 113 nr_dirty = nilfs_page_count_clean_buffers(page, from, to);
114 copied = block_write_end(NULL, mapping, pos, len, len, page, NULL); 114 copied = block_write_end(NULL, mapping, pos, len, len, page, NULL);
115 if (pos + copied > dir->i_size) { 115 if (pos + copied > dir->i_size)
116 i_size_write(dir, pos + copied); 116 i_size_write(dir, pos + copied);
117 mark_inode_dirty(dir);
118 }
119 if (IS_DIRSYNC(dir)) 117 if (IS_DIRSYNC(dir))
120 nilfs_set_transaction_flag(NILFS_TI_SYNC); 118 nilfs_set_transaction_flag(NILFS_TI_SYNC);
121 err = nilfs_set_file_dirty(sbi, dir, nr_dirty); 119 err = nilfs_set_file_dirty(sbi, dir, nr_dirty);
120 WARN_ON(err); /* do not happen */
122 unlock_page(page); 121 unlock_page(page);
123 return err;
124} 122}
125 123
126static void nilfs_check_page(struct page *page) 124static void nilfs_check_page(struct page *page)
@@ -455,11 +453,10 @@ void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de,
455 BUG_ON(err); 453 BUG_ON(err);
456 de->inode = cpu_to_le64(inode->i_ino); 454 de->inode = cpu_to_le64(inode->i_ino);
457 nilfs_set_de_type(de, inode); 455 nilfs_set_de_type(de, inode);
458 err = nilfs_commit_chunk(page, mapping, from, to); 456 nilfs_commit_chunk(page, mapping, from, to);
459 nilfs_put_page(page); 457 nilfs_put_page(page);
460 dir->i_mtime = dir->i_ctime = CURRENT_TIME; 458 dir->i_mtime = dir->i_ctime = CURRENT_TIME;
461/* NILFS_I(dir)->i_flags &= ~NILFS_BTREE_FL; */ 459/* NILFS_I(dir)->i_flags &= ~NILFS_BTREE_FL; */
462 mark_inode_dirty(dir);
463} 460}
464 461
465/* 462/*
@@ -548,10 +545,10 @@ got_it:
548 memcpy(de->name, name, namelen); 545 memcpy(de->name, name, namelen);
549 de->inode = cpu_to_le64(inode->i_ino); 546 de->inode = cpu_to_le64(inode->i_ino);
550 nilfs_set_de_type(de, inode); 547 nilfs_set_de_type(de, inode);
551 err = nilfs_commit_chunk(page, page->mapping, from, to); 548 nilfs_commit_chunk(page, page->mapping, from, to);
552 dir->i_mtime = dir->i_ctime = CURRENT_TIME; 549 dir->i_mtime = dir->i_ctime = CURRENT_TIME;
553/* NILFS_I(dir)->i_flags &= ~NILFS_BTREE_FL; */ 550/* NILFS_I(dir)->i_flags &= ~NILFS_BTREE_FL; */
554 mark_inode_dirty(dir); 551 nilfs_mark_inode_dirty(dir);
555 /* OFFSET_CACHE */ 552 /* OFFSET_CACHE */
556out_put: 553out_put:
557 nilfs_put_page(page); 554 nilfs_put_page(page);
@@ -595,10 +592,9 @@ int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page)
595 if (pde) 592 if (pde)
596 pde->rec_len = cpu_to_le16(to - from); 593 pde->rec_len = cpu_to_le16(to - from);
597 dir->inode = 0; 594 dir->inode = 0;
598 err = nilfs_commit_chunk(page, mapping, from, to); 595 nilfs_commit_chunk(page, mapping, from, to);
599 inode->i_ctime = inode->i_mtime = CURRENT_TIME; 596 inode->i_ctime = inode->i_mtime = CURRENT_TIME;
600/* NILFS_I(inode)->i_flags &= ~NILFS_BTREE_FL; */ 597/* NILFS_I(inode)->i_flags &= ~NILFS_BTREE_FL; */
601 mark_inode_dirty(inode);
602out: 598out:
603 nilfs_put_page(page); 599 nilfs_put_page(page);
604 return err; 600 return err;
@@ -640,7 +636,7 @@ int nilfs_make_empty(struct inode *inode, struct inode *parent)
640 memcpy(de->name, "..\0", 4); 636 memcpy(de->name, "..\0", 4);
641 nilfs_set_de_type(de, inode); 637 nilfs_set_de_type(de, inode);
642 kunmap_atomic(kaddr, KM_USER0); 638 kunmap_atomic(kaddr, KM_USER0);
643 err = nilfs_commit_chunk(page, mapping, 0, chunk_size); 639 nilfs_commit_chunk(page, mapping, 0, chunk_size);
644fail: 640fail:
645 page_cache_release(page); 641 page_cache_release(page);
646 return err; 642 return err;
diff --git a/fs/nilfs2/gcdat.c b/fs/nilfs2/gcdat.c
index 93383c5cee90..dd5f7e0a95f6 100644
--- a/fs/nilfs2/gcdat.c
+++ b/fs/nilfs2/gcdat.c
@@ -61,6 +61,8 @@ void nilfs_commit_gcdat_inode(struct the_nilfs *nilfs)
61 61
62 nilfs_bmap_commit_gcdat(gii->i_bmap, dii->i_bmap); 62 nilfs_bmap_commit_gcdat(gii->i_bmap, dii->i_bmap);
63 63
64 nilfs_palloc_clear_cache(dat);
65 nilfs_palloc_clear_cache(gcdat);
64 nilfs_clear_dirty_pages(mapping); 66 nilfs_clear_dirty_pages(mapping);
65 nilfs_copy_back_pages(mapping, gmapping); 67 nilfs_copy_back_pages(mapping, gmapping);
66 /* note: mdt dirty flags should be cleared by segctor. */ 68 /* note: mdt dirty flags should be cleared by segctor. */
@@ -79,6 +81,7 @@ void nilfs_clear_gcdat_inode(struct the_nilfs *nilfs)
79 gcdat->i_state = I_CLEAR; 81 gcdat->i_state = I_CLEAR;
80 gii->i_flags = 0; 82 gii->i_flags = 0;
81 83
84 nilfs_palloc_clear_cache(gcdat);
82 truncate_inode_pages(gcdat->i_mapping, 0); 85 truncate_inode_pages(gcdat->i_mapping, 0);
83 truncate_inode_pages(&gii->i_btnode_cache, 0); 86 truncate_inode_pages(&gii->i_btnode_cache, 0);
84} 87}
diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c
index e6de0a27ab5d..e16a6664dfa2 100644
--- a/fs/nilfs2/gcinode.c
+++ b/fs/nilfs2/gcinode.c
@@ -149,7 +149,7 @@ int nilfs_gccache_submit_read_node(struct inode *inode, sector_t pbn,
149 __u64 vbn, struct buffer_head **out_bh) 149 __u64 vbn, struct buffer_head **out_bh)
150{ 150{
151 int ret = nilfs_btnode_submit_block(&NILFS_I(inode)->i_btnode_cache, 151 int ret = nilfs_btnode_submit_block(&NILFS_I(inode)->i_btnode_cache,
152 vbn ? : pbn, pbn, out_bh, 0); 152 vbn ? : pbn, pbn, out_bh);
153 if (ret == -EEXIST) /* internal code (cache hit) */ 153 if (ret == -EEXIST) /* internal code (cache hit) */
154 ret = 0; 154 ret = 0;
155 return ret; 155 return ret;
@@ -212,9 +212,10 @@ void nilfs_destroy_gccache(struct the_nilfs *nilfs)
212static struct inode *alloc_gcinode(struct the_nilfs *nilfs, ino_t ino, 212static struct inode *alloc_gcinode(struct the_nilfs *nilfs, ino_t ino,
213 __u64 cno) 213 __u64 cno)
214{ 214{
215 struct inode *inode = nilfs_mdt_new_common(nilfs, NULL, ino, GFP_NOFS); 215 struct inode *inode;
216 struct nilfs_inode_info *ii; 216 struct nilfs_inode_info *ii;
217 217
218 inode = nilfs_mdt_new_common(nilfs, NULL, ino, GFP_NOFS, 0);
218 if (!inode) 219 if (!inode)
219 return NULL; 220 return NULL;
220 221
@@ -265,7 +266,6 @@ struct inode *nilfs_gc_iget(struct the_nilfs *nilfs, ino_t ino, __u64 cno)
265 */ 266 */
266void nilfs_clear_gcinode(struct inode *inode) 267void nilfs_clear_gcinode(struct inode *inode)
267{ 268{
268 nilfs_mdt_clear(inode);
269 nilfs_mdt_destroy(inode); 269 nilfs_mdt_destroy(inode);
270} 270}
271 271
diff --git a/fs/nilfs2/ifile.c b/fs/nilfs2/ifile.c
index de86401f209f..922d9dd42c8f 100644
--- a/fs/nilfs2/ifile.c
+++ b/fs/nilfs2/ifile.c
@@ -29,6 +29,17 @@
29#include "alloc.h" 29#include "alloc.h"
30#include "ifile.h" 30#include "ifile.h"
31 31
32
33struct nilfs_ifile_info {
34 struct nilfs_mdt_info mi;
35 struct nilfs_palloc_cache palloc_cache;
36};
37
38static inline struct nilfs_ifile_info *NILFS_IFILE_I(struct inode *ifile)
39{
40 return (struct nilfs_ifile_info *)NILFS_MDT(ifile);
41}
42
32/** 43/**
33 * nilfs_ifile_create_inode - create a new disk inode 44 * nilfs_ifile_create_inode - create a new disk inode
34 * @ifile: ifile inode 45 * @ifile: ifile inode
@@ -148,3 +159,27 @@ int nilfs_ifile_get_inode_block(struct inode *ifile, ino_t ino,
148 } 159 }
149 return err; 160 return err;
150} 161}
162
163/**
164 * nilfs_ifile_new - create inode file
165 * @sbi: nilfs_sb_info struct
166 * @inode_size: size of an inode
167 */
168struct inode *nilfs_ifile_new(struct nilfs_sb_info *sbi, size_t inode_size)
169{
170 struct inode *ifile;
171 int err;
172
173 ifile = nilfs_mdt_new(sbi->s_nilfs, sbi->s_super, NILFS_IFILE_INO,
174 sizeof(struct nilfs_ifile_info));
175 if (ifile) {
176 err = nilfs_palloc_init_blockgroup(ifile, inode_size);
177 if (unlikely(err)) {
178 nilfs_mdt_destroy(ifile);
179 return NULL;
180 }
181 nilfs_palloc_setup_cache(ifile,
182 &NILFS_IFILE_I(ifile)->palloc_cache);
183 }
184 return ifile;
185}
diff --git a/fs/nilfs2/ifile.h b/fs/nilfs2/ifile.h
index ecc3ba76db47..cbca32e498f2 100644
--- a/fs/nilfs2/ifile.h
+++ b/fs/nilfs2/ifile.h
@@ -49,4 +49,6 @@ int nilfs_ifile_create_inode(struct inode *, ino_t *, struct buffer_head **);
49int nilfs_ifile_delete_inode(struct inode *, ino_t); 49int nilfs_ifile_delete_inode(struct inode *, ino_t);
50int nilfs_ifile_get_inode_block(struct inode *, ino_t, struct buffer_head **); 50int nilfs_ifile_get_inode_block(struct inode *, ino_t, struct buffer_head **);
51 51
52struct inode *nilfs_ifile_new(struct nilfs_sb_info *sbi, size_t inode_size);
53
52#endif /* _NILFS_IFILE_H */ 54#endif /* _NILFS_IFILE_H */
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 2a0a5a3ac134..7868cc122ac7 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -97,6 +97,7 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff,
97 nilfs_transaction_abort(inode->i_sb); 97 nilfs_transaction_abort(inode->i_sb);
98 goto out; 98 goto out;
99 } 99 }
100 nilfs_mark_inode_dirty(inode);
100 nilfs_transaction_commit(inode->i_sb); /* never fails */ 101 nilfs_transaction_commit(inode->i_sb); /* never fails */
101 /* Error handling should be detailed */ 102 /* Error handling should be detailed */
102 set_buffer_new(bh_result); 103 set_buffer_new(bh_result);
@@ -322,7 +323,6 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode)
322 nilfs_init_acl(), proper cancellation of 323 nilfs_init_acl(), proper cancellation of
323 above jobs should be considered */ 324 above jobs should be considered */
324 325
325 mark_inode_dirty(inode);
326 return inode; 326 return inode;
327 327
328 failed_acl: 328 failed_acl:
@@ -525,7 +525,6 @@ void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh)
525 525
526 raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, ibh); 526 raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, ibh);
527 527
528 /* The buffer is guarded with lock_buffer() by the caller */
529 if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state)) 528 if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state))
530 memset(raw_inode, 0, NILFS_MDT(sbi->s_ifile)->mi_entry_size); 529 memset(raw_inode, 0, NILFS_MDT(sbi->s_ifile)->mi_entry_size);
531 set_bit(NILFS_I_INODE_DIRTY, &ii->i_state); 530 set_bit(NILFS_I_INODE_DIRTY, &ii->i_state);
@@ -599,6 +598,7 @@ void nilfs_truncate(struct inode *inode)
599 if (IS_SYNC(inode)) 598 if (IS_SYNC(inode))
600 nilfs_set_transaction_flag(NILFS_TI_SYNC); 599 nilfs_set_transaction_flag(NILFS_TI_SYNC);
601 600
601 nilfs_mark_inode_dirty(inode);
602 nilfs_set_file_dirty(NILFS_SB(sb), inode, 0); 602 nilfs_set_file_dirty(NILFS_SB(sb), inode, 0);
603 nilfs_transaction_commit(sb); 603 nilfs_transaction_commit(sb);
604 /* May construct a logical segment and may fail in sync mode. 604 /* May construct a logical segment and may fail in sync mode.
@@ -623,6 +623,7 @@ void nilfs_delete_inode(struct inode *inode)
623 truncate_inode_pages(&inode->i_data, 0); 623 truncate_inode_pages(&inode->i_data, 0);
624 624
625 nilfs_truncate_bmap(ii, 0); 625 nilfs_truncate_bmap(ii, 0);
626 nilfs_mark_inode_dirty(inode);
626 nilfs_free_inode(inode); 627 nilfs_free_inode(inode);
627 /* nilfs_free_inode() marks inode buffer dirty */ 628 /* nilfs_free_inode() marks inode buffer dirty */
628 if (IS_SYNC(inode)) 629 if (IS_SYNC(inode))
@@ -745,9 +746,7 @@ int nilfs_mark_inode_dirty(struct inode *inode)
745 "failed to reget inode block.\n"); 746 "failed to reget inode block.\n");
746 return err; 747 return err;
747 } 748 }
748 lock_buffer(ibh);
749 nilfs_update_inode(inode, ibh); 749 nilfs_update_inode(inode, ibh);
750 unlock_buffer(ibh);
751 nilfs_mdt_mark_buffer_dirty(ibh); 750 nilfs_mdt_mark_buffer_dirty(ibh);
752 nilfs_mdt_mark_dirty(sbi->s_ifile); 751 nilfs_mdt_mark_dirty(sbi->s_ifile);
753 brelse(ibh); 752 brelse(ibh);
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index f6326112d647..06713ffcc7f2 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -186,7 +186,7 @@ nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff,
186} 186}
187 187
188static int nilfs_mdt_read_block(struct inode *inode, unsigned long block, 188static int nilfs_mdt_read_block(struct inode *inode, unsigned long block,
189 struct buffer_head **out_bh) 189 int readahead, struct buffer_head **out_bh)
190{ 190{
191 struct buffer_head *first_bh, *bh; 191 struct buffer_head *first_bh, *bh;
192 unsigned long blkoff; 192 unsigned long blkoff;
@@ -200,16 +200,18 @@ static int nilfs_mdt_read_block(struct inode *inode, unsigned long block,
200 if (unlikely(err)) 200 if (unlikely(err))
201 goto failed; 201 goto failed;
202 202
203 blkoff = block + 1; 203 if (readahead) {
204 for (i = 0; i < nr_ra_blocks; i++, blkoff++) { 204 blkoff = block + 1;
205 err = nilfs_mdt_submit_block(inode, blkoff, READA, &bh); 205 for (i = 0; i < nr_ra_blocks; i++, blkoff++) {
206 if (likely(!err || err == -EEXIST)) 206 err = nilfs_mdt_submit_block(inode, blkoff, READA, &bh);
207 brelse(bh); 207 if (likely(!err || err == -EEXIST))
208 else if (err != -EBUSY) 208 brelse(bh);
209 break; /* abort readahead if bmap lookup failed */ 209 else if (err != -EBUSY)
210 210 break;
211 if (!buffer_locked(first_bh)) 211 /* abort readahead if bmap lookup failed */
212 goto out_no_wait; 212 if (!buffer_locked(first_bh))
213 goto out_no_wait;
214 }
213 } 215 }
214 216
215 wait_on_buffer(first_bh); 217 wait_on_buffer(first_bh);
@@ -263,7 +265,7 @@ int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create,
263 265
264 /* Should be rewritten with merging nilfs_mdt_read_block() */ 266 /* Should be rewritten with merging nilfs_mdt_read_block() */
265 retry: 267 retry:
266 ret = nilfs_mdt_read_block(inode, blkoff, out_bh); 268 ret = nilfs_mdt_read_block(inode, blkoff, !create, out_bh);
267 if (!create || ret != -ENOENT) 269 if (!create || ret != -ENOENT)
268 return ret; 270 return ret;
269 271
@@ -371,7 +373,7 @@ int nilfs_mdt_mark_block_dirty(struct inode *inode, unsigned long block)
371 struct buffer_head *bh; 373 struct buffer_head *bh;
372 int err; 374 int err;
373 375
374 err = nilfs_mdt_read_block(inode, block, &bh); 376 err = nilfs_mdt_read_block(inode, block, 0, &bh);
375 if (unlikely(err)) 377 if (unlikely(err))
376 return err; 378 return err;
377 nilfs_mark_buffer_dirty(bh); 379 nilfs_mark_buffer_dirty(bh);
@@ -445,9 +447,17 @@ static const struct file_operations def_mdt_fops;
445 * longer than those of the super block structs; they may continue for 447 * longer than those of the super block structs; they may continue for
446 * several consecutive mounts/umounts. This would need discussions. 448 * several consecutive mounts/umounts. This would need discussions.
447 */ 449 */
450/**
451 * nilfs_mdt_new_common - allocate a pseudo inode for metadata file
452 * @nilfs: nilfs object
453 * @sb: super block instance the metadata file belongs to
454 * @ino: inode number
455 * @gfp_mask: gfp mask for data pages
456 * @objsz: size of the private object attached to inode->i_private
457 */
448struct inode * 458struct inode *
449nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb, 459nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb,
450 ino_t ino, gfp_t gfp_mask) 460 ino_t ino, gfp_t gfp_mask, size_t objsz)
451{ 461{
452 struct inode *inode = nilfs_alloc_inode_common(nilfs); 462 struct inode *inode = nilfs_alloc_inode_common(nilfs);
453 463
@@ -455,8 +465,9 @@ nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb,
455 return NULL; 465 return NULL;
456 else { 466 else {
457 struct address_space * const mapping = &inode->i_data; 467 struct address_space * const mapping = &inode->i_data;
458 struct nilfs_mdt_info *mi = kzalloc(sizeof(*mi), GFP_NOFS); 468 struct nilfs_mdt_info *mi;
459 469
470 mi = kzalloc(max(sizeof(*mi), objsz), GFP_NOFS);
460 if (!mi) { 471 if (!mi) {
461 nilfs_destroy_inode(inode); 472 nilfs_destroy_inode(inode);
462 return NULL; 473 return NULL;
@@ -513,11 +524,11 @@ nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb,
513} 524}
514 525
515struct inode *nilfs_mdt_new(struct the_nilfs *nilfs, struct super_block *sb, 526struct inode *nilfs_mdt_new(struct the_nilfs *nilfs, struct super_block *sb,
516 ino_t ino) 527 ino_t ino, size_t objsz)
517{ 528{
518 struct inode *inode = nilfs_mdt_new_common(nilfs, sb, ino, 529 struct inode *inode;
519 NILFS_MDT_GFP);
520 530
531 inode = nilfs_mdt_new_common(nilfs, sb, ino, NILFS_MDT_GFP, objsz);
521 if (!inode) 532 if (!inode)
522 return NULL; 533 return NULL;
523 534
@@ -544,14 +555,15 @@ void nilfs_mdt_set_shadow(struct inode *orig, struct inode *shadow)
544 &NILFS_I(orig)->i_btnode_cache; 555 &NILFS_I(orig)->i_btnode_cache;
545} 556}
546 557
547void nilfs_mdt_clear(struct inode *inode) 558static void nilfs_mdt_clear(struct inode *inode)
548{ 559{
549 struct nilfs_inode_info *ii = NILFS_I(inode); 560 struct nilfs_inode_info *ii = NILFS_I(inode);
550 561
551 invalidate_mapping_pages(inode->i_mapping, 0, -1); 562 invalidate_mapping_pages(inode->i_mapping, 0, -1);
552 truncate_inode_pages(inode->i_mapping, 0); 563 truncate_inode_pages(inode->i_mapping, 0);
553 564
554 nilfs_bmap_clear(ii->i_bmap); 565 if (test_bit(NILFS_I_BMAP, &ii->i_state))
566 nilfs_bmap_clear(ii->i_bmap);
555 nilfs_btnode_cache_clear(&ii->i_btnode_cache); 567 nilfs_btnode_cache_clear(&ii->i_btnode_cache);
556} 568}
557 569
@@ -559,6 +571,10 @@ void nilfs_mdt_destroy(struct inode *inode)
559{ 571{
560 struct nilfs_mdt_info *mdi = NILFS_MDT(inode); 572 struct nilfs_mdt_info *mdi = NILFS_MDT(inode);
561 573
574 if (mdi->mi_palloc_cache)
575 nilfs_palloc_destroy_cache(inode);
576 nilfs_mdt_clear(inode);
577
562 kfree(mdi->mi_bgl); /* kfree(NULL) is safe */ 578 kfree(mdi->mi_bgl); /* kfree(NULL) is safe */
563 kfree(mdi); 579 kfree(mdi);
564 nilfs_destroy_inode(inode); 580 nilfs_destroy_inode(inode);
diff --git a/fs/nilfs2/mdt.h b/fs/nilfs2/mdt.h
index 431599733c9b..6c4bbb0470fc 100644
--- a/fs/nilfs2/mdt.h
+++ b/fs/nilfs2/mdt.h
@@ -36,6 +36,7 @@
36 * @mi_entry_size: size of an entry 36 * @mi_entry_size: size of an entry
37 * @mi_first_entry_offset: offset to the first entry 37 * @mi_first_entry_offset: offset to the first entry
38 * @mi_entries_per_block: number of entries in a block 38 * @mi_entries_per_block: number of entries in a block
39 * @mi_palloc_cache: persistent object allocator cache
39 * @mi_blocks_per_group: number of blocks in a group 40 * @mi_blocks_per_group: number of blocks in a group
40 * @mi_blocks_per_desc_block: number of blocks per descriptor block 41 * @mi_blocks_per_desc_block: number of blocks per descriptor block
41 */ 42 */
@@ -46,6 +47,7 @@ struct nilfs_mdt_info {
46 unsigned mi_entry_size; 47 unsigned mi_entry_size;
47 unsigned mi_first_entry_offset; 48 unsigned mi_first_entry_offset;
48 unsigned long mi_entries_per_block; 49 unsigned long mi_entries_per_block;
50 struct nilfs_palloc_cache *mi_palloc_cache;
49 unsigned long mi_blocks_per_group; 51 unsigned long mi_blocks_per_group;
50 unsigned long mi_blocks_per_desc_block; 52 unsigned long mi_blocks_per_desc_block;
51}; 53};
@@ -74,11 +76,11 @@ int nilfs_mdt_forget_block(struct inode *, unsigned long);
74int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long); 76int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long);
75int nilfs_mdt_fetch_dirty(struct inode *); 77int nilfs_mdt_fetch_dirty(struct inode *);
76 78
77struct inode *nilfs_mdt_new(struct the_nilfs *, struct super_block *, ino_t); 79struct inode *nilfs_mdt_new(struct the_nilfs *, struct super_block *, ino_t,
80 size_t);
78struct inode *nilfs_mdt_new_common(struct the_nilfs *, struct super_block *, 81struct inode *nilfs_mdt_new_common(struct the_nilfs *, struct super_block *,
79 ino_t, gfp_t); 82 ino_t, gfp_t, size_t);
80void nilfs_mdt_destroy(struct inode *); 83void nilfs_mdt_destroy(struct inode *);
81void nilfs_mdt_clear(struct inode *);
82void nilfs_mdt_set_entry_size(struct inode *, unsigned, unsigned); 84void nilfs_mdt_set_entry_size(struct inode *, unsigned, unsigned);
83void nilfs_mdt_set_shadow(struct inode *, struct inode *); 85void nilfs_mdt_set_shadow(struct inode *, struct inode *);
84 86
@@ -104,21 +106,4 @@ static inline __u64 nilfs_mdt_cno(struct inode *inode)
104#define nilfs_mdt_bgl_lock(inode, bg) \ 106#define nilfs_mdt_bgl_lock(inode, bg) \
105 (&NILFS_MDT(inode)->mi_bgl->locks[(bg) & (NR_BG_LOCKS-1)].lock) 107 (&NILFS_MDT(inode)->mi_bgl->locks[(bg) & (NR_BG_LOCKS-1)].lock)
106 108
107
108static inline int
109nilfs_mdt_read_inode_direct(struct inode *inode, struct buffer_head *bh,
110 unsigned n)
111{
112 return nilfs_read_inode_common(
113 inode, (struct nilfs_inode *)(bh->b_data + n));
114}
115
116static inline void
117nilfs_mdt_write_inode_direct(struct inode *inode, struct buffer_head *bh,
118 unsigned n)
119{
120 nilfs_write_inode_common(
121 inode, (struct nilfs_inode *)(bh->b_data + n), 1);
122}
123
124#endif /* _NILFS_MDT_H */ 109#endif /* _NILFS_MDT_H */
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index ed02e886fa79..07ba838ef089 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -120,7 +120,7 @@ static int nilfs_create(struct inode *dir, struct dentry *dentry, int mode,
120 inode->i_op = &nilfs_file_inode_operations; 120 inode->i_op = &nilfs_file_inode_operations;
121 inode->i_fop = &nilfs_file_operations; 121 inode->i_fop = &nilfs_file_operations;
122 inode->i_mapping->a_ops = &nilfs_aops; 122 inode->i_mapping->a_ops = &nilfs_aops;
123 mark_inode_dirty(inode); 123 nilfs_mark_inode_dirty(inode);
124 err = nilfs_add_nondir(dentry, inode); 124 err = nilfs_add_nondir(dentry, inode);
125 } 125 }
126 if (!err) 126 if (!err)
@@ -148,7 +148,7 @@ nilfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
148 err = PTR_ERR(inode); 148 err = PTR_ERR(inode);
149 if (!IS_ERR(inode)) { 149 if (!IS_ERR(inode)) {
150 init_special_inode(inode, inode->i_mode, rdev); 150 init_special_inode(inode, inode->i_mode, rdev);
151 mark_inode_dirty(inode); 151 nilfs_mark_inode_dirty(inode);
152 err = nilfs_add_nondir(dentry, inode); 152 err = nilfs_add_nondir(dentry, inode);
153 } 153 }
154 if (!err) 154 if (!err)
@@ -188,7 +188,7 @@ static int nilfs_symlink(struct inode *dir, struct dentry *dentry,
188 goto out_fail; 188 goto out_fail;
189 189
190 /* mark_inode_dirty(inode); */ 190 /* mark_inode_dirty(inode); */
191 /* nilfs_new_inode() and page_symlink() do this */ 191 /* page_symlink() do this */
192 192
193 err = nilfs_add_nondir(dentry, inode); 193 err = nilfs_add_nondir(dentry, inode);
194out: 194out:
@@ -200,7 +200,8 @@ out:
200 return err; 200 return err;
201 201
202out_fail: 202out_fail:
203 inode_dec_link_count(inode); 203 drop_nlink(inode);
204 nilfs_mark_inode_dirty(inode);
204 iput(inode); 205 iput(inode);
205 goto out; 206 goto out;
206} 207}
@@ -245,7 +246,7 @@ static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
245 if (err) 246 if (err)
246 return err; 247 return err;
247 248
248 inode_inc_link_count(dir); 249 inc_nlink(dir);
249 250
250 inode = nilfs_new_inode(dir, S_IFDIR | mode); 251 inode = nilfs_new_inode(dir, S_IFDIR | mode);
251 err = PTR_ERR(inode); 252 err = PTR_ERR(inode);
@@ -256,7 +257,7 @@ static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
256 inode->i_fop = &nilfs_dir_operations; 257 inode->i_fop = &nilfs_dir_operations;
257 inode->i_mapping->a_ops = &nilfs_aops; 258 inode->i_mapping->a_ops = &nilfs_aops;
258 259
259 inode_inc_link_count(inode); 260 inc_nlink(inode);
260 261
261 err = nilfs_make_empty(inode, dir); 262 err = nilfs_make_empty(inode, dir);
262 if (err) 263 if (err)
@@ -266,6 +267,7 @@ static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
266 if (err) 267 if (err)
267 goto out_fail; 268 goto out_fail;
268 269
270 nilfs_mark_inode_dirty(inode);
269 d_instantiate(dentry, inode); 271 d_instantiate(dentry, inode);
270out: 272out:
271 if (!err) 273 if (!err)
@@ -276,26 +278,23 @@ out:
276 return err; 278 return err;
277 279
278out_fail: 280out_fail:
279 inode_dec_link_count(inode); 281 drop_nlink(inode);
280 inode_dec_link_count(inode); 282 drop_nlink(inode);
283 nilfs_mark_inode_dirty(inode);
281 iput(inode); 284 iput(inode);
282out_dir: 285out_dir:
283 inode_dec_link_count(dir); 286 drop_nlink(dir);
287 nilfs_mark_inode_dirty(dir);
284 goto out; 288 goto out;
285} 289}
286 290
287static int nilfs_unlink(struct inode *dir, struct dentry *dentry) 291static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry)
288{ 292{
289 struct inode *inode; 293 struct inode *inode;
290 struct nilfs_dir_entry *de; 294 struct nilfs_dir_entry *de;
291 struct page *page; 295 struct page *page;
292 struct nilfs_transaction_info ti;
293 int err; 296 int err;
294 297
295 err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
296 if (err)
297 return err;
298
299 err = -ENOENT; 298 err = -ENOENT;
300 de = nilfs_find_entry(dir, dentry, &page); 299 de = nilfs_find_entry(dir, dentry, &page);
301 if (!de) 300 if (!de)
@@ -317,12 +316,28 @@ static int nilfs_unlink(struct inode *dir, struct dentry *dentry)
317 goto out; 316 goto out;
318 317
319 inode->i_ctime = dir->i_ctime; 318 inode->i_ctime = dir->i_ctime;
320 inode_dec_link_count(inode); 319 drop_nlink(inode);
321 err = 0; 320 err = 0;
322out: 321out:
323 if (!err) 322 return err;
323}
324
325static int nilfs_unlink(struct inode *dir, struct dentry *dentry)
326{
327 struct nilfs_transaction_info ti;
328 int err;
329
330 err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
331 if (err)
332 return err;
333
334 err = nilfs_do_unlink(dir, dentry);
335
336 if (!err) {
337 nilfs_mark_inode_dirty(dir);
338 nilfs_mark_inode_dirty(dentry->d_inode);
324 err = nilfs_transaction_commit(dir->i_sb); 339 err = nilfs_transaction_commit(dir->i_sb);
325 else 340 } else
326 nilfs_transaction_abort(dir->i_sb); 341 nilfs_transaction_abort(dir->i_sb);
327 342
328 return err; 343 return err;
@@ -340,11 +355,13 @@ static int nilfs_rmdir(struct inode *dir, struct dentry *dentry)
340 355
341 err = -ENOTEMPTY; 356 err = -ENOTEMPTY;
342 if (nilfs_empty_dir(inode)) { 357 if (nilfs_empty_dir(inode)) {
343 err = nilfs_unlink(dir, dentry); 358 err = nilfs_do_unlink(dir, dentry);
344 if (!err) { 359 if (!err) {
345 inode->i_size = 0; 360 inode->i_size = 0;
346 inode_dec_link_count(inode); 361 drop_nlink(inode);
347 inode_dec_link_count(dir); 362 nilfs_mark_inode_dirty(inode);
363 drop_nlink(dir);
364 nilfs_mark_inode_dirty(dir);
348 } 365 }
349 } 366 }
350 if (!err) 367 if (!err)
@@ -395,42 +412,48 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry,
395 new_de = nilfs_find_entry(new_dir, new_dentry, &new_page); 412 new_de = nilfs_find_entry(new_dir, new_dentry, &new_page);
396 if (!new_de) 413 if (!new_de)
397 goto out_dir; 414 goto out_dir;
398 inode_inc_link_count(old_inode); 415 inc_nlink(old_inode);
399 nilfs_set_link(new_dir, new_de, new_page, old_inode); 416 nilfs_set_link(new_dir, new_de, new_page, old_inode);
417 nilfs_mark_inode_dirty(new_dir);
400 new_inode->i_ctime = CURRENT_TIME; 418 new_inode->i_ctime = CURRENT_TIME;
401 if (dir_de) 419 if (dir_de)
402 drop_nlink(new_inode); 420 drop_nlink(new_inode);
403 inode_dec_link_count(new_inode); 421 drop_nlink(new_inode);
422 nilfs_mark_inode_dirty(new_inode);
404 } else { 423 } else {
405 if (dir_de) { 424 if (dir_de) {
406 err = -EMLINK; 425 err = -EMLINK;
407 if (new_dir->i_nlink >= NILFS_LINK_MAX) 426 if (new_dir->i_nlink >= NILFS_LINK_MAX)
408 goto out_dir; 427 goto out_dir;
409 } 428 }
410 inode_inc_link_count(old_inode); 429 inc_nlink(old_inode);
411 err = nilfs_add_link(new_dentry, old_inode); 430 err = nilfs_add_link(new_dentry, old_inode);
412 if (err) { 431 if (err) {
413 inode_dec_link_count(old_inode); 432 drop_nlink(old_inode);
433 nilfs_mark_inode_dirty(old_inode);
414 goto out_dir; 434 goto out_dir;
415 } 435 }
416 if (dir_de) 436 if (dir_de) {
417 inode_inc_link_count(new_dir); 437 inc_nlink(new_dir);
438 nilfs_mark_inode_dirty(new_dir);
439 }
418 } 440 }
419 441
420 /* 442 /*
421 * Like most other Unix systems, set the ctime for inodes on a 443 * Like most other Unix systems, set the ctime for inodes on a
422 * rename. 444 * rename.
423 * inode_dec_link_count() will mark the inode dirty.
424 */ 445 */
425 old_inode->i_ctime = CURRENT_TIME; 446 old_inode->i_ctime = CURRENT_TIME;
426 447
427 nilfs_delete_entry(old_de, old_page); 448 nilfs_delete_entry(old_de, old_page);
428 inode_dec_link_count(old_inode); 449 drop_nlink(old_inode);
429 450
430 if (dir_de) { 451 if (dir_de) {
431 nilfs_set_link(old_inode, dir_de, dir_page, new_dir); 452 nilfs_set_link(old_inode, dir_de, dir_page, new_dir);
432 inode_dec_link_count(old_dir); 453 drop_nlink(old_dir);
433 } 454 }
455 nilfs_mark_inode_dirty(old_dir);
456 nilfs_mark_inode_dirty(old_inode);
434 457
435 err = nilfs_transaction_commit(old_dir->i_sb); 458 err = nilfs_transaction_commit(old_dir->i_sb);
436 return err; 459 return err;
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
index 6dc83591d118..c9c96c7825dc 100644
--- a/fs/nilfs2/recovery.c
+++ b/fs/nilfs2/recovery.c
@@ -770,14 +770,8 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs,
770 nilfs_finish_roll_forward(nilfs, sbi, ri); 770 nilfs_finish_roll_forward(nilfs, sbi, ri);
771 } 771 }
772 772
773 nilfs_detach_checkpoint(sbi);
774 return 0;
775
776 failed: 773 failed:
777 nilfs_detach_checkpoint(sbi); 774 nilfs_detach_checkpoint(sbi);
778 nilfs_mdt_clear(nilfs->ns_cpfile);
779 nilfs_mdt_clear(nilfs->ns_sufile);
780 nilfs_mdt_clear(nilfs->ns_dat);
781 return err; 775 return err;
782} 776}
783 777
@@ -804,6 +798,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
804 struct nilfs_segsum_info ssi; 798 struct nilfs_segsum_info ssi;
805 sector_t pseg_start, pseg_end, sr_pseg_start = 0; 799 sector_t pseg_start, pseg_end, sr_pseg_start = 0;
806 sector_t seg_start, seg_end; /* range of full segment (block number) */ 800 sector_t seg_start, seg_end; /* range of full segment (block number) */
801 sector_t b, end;
807 u64 seg_seq; 802 u64 seg_seq;
808 __u64 segnum, nextnum = 0; 803 __u64 segnum, nextnum = 0;
809 __u64 cno; 804 __u64 cno;
@@ -819,6 +814,11 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
819 /* Calculate range of segment */ 814 /* Calculate range of segment */
820 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); 815 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end);
821 816
817 /* Read ahead segment */
818 b = seg_start;
819 while (b <= seg_end)
820 sb_breadahead(sbi->s_super, b++);
821
822 for (;;) { 822 for (;;) {
823 /* Load segment summary */ 823 /* Load segment summary */
824 ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi, 1); 824 ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi, 1);
@@ -841,14 +841,20 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
841 ri->ri_nextnum = nextnum; 841 ri->ri_nextnum = nextnum;
842 empty_seg = 0; 842 empty_seg = 0;
843 843
844 if (!NILFS_SEG_HAS_SR(&ssi) && !scan_newer) {
845 /* This will never happen because a superblock
846 (last_segment) always points to a pseg
847 having a super root. */
848 ret = NILFS_SEG_FAIL_CONSISTENCY;
849 goto failed;
850 }
851
852 if (pseg_start == seg_start) {
853 nilfs_get_segment_range(nilfs, nextnum, &b, &end);
854 while (b <= end)
855 sb_breadahead(sbi->s_super, b++);
856 }
844 if (!NILFS_SEG_HAS_SR(&ssi)) { 857 if (!NILFS_SEG_HAS_SR(&ssi)) {
845 if (!scan_newer) {
846 /* This will never happen because a superblock
847 (last_segment) always points to a pseg
848 having a super root. */
849 ret = NILFS_SEG_FAIL_CONSISTENCY;
850 goto failed;
851 }
852 if (!ri->ri_lsegs_start && NILFS_SEG_LOGBGN(&ssi)) { 858 if (!ri->ri_lsegs_start && NILFS_SEG_LOGBGN(&ssi)) {
853 ri->ri_lsegs_start = pseg_start; 859 ri->ri_lsegs_start = pseg_start;
854 ri->ri_lsegs_start_seq = seg_seq; 860 ri->ri_lsegs_start_seq = seg_seq;
@@ -919,7 +925,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
919 925
920 super_root_found: 926 super_root_found:
921 /* Updating pointers relating to the latest checkpoint */ 927 /* Updating pointers relating to the latest checkpoint */
922 list_splice(&segments, ri->ri_used_segments.prev); 928 list_splice_tail(&segments, &ri->ri_used_segments);
923 nilfs->ns_last_pseg = sr_pseg_start; 929 nilfs->ns_last_pseg = sr_pseg_start;
924 nilfs->ns_last_seq = nilfs->ns_seg_seq; 930 nilfs->ns_last_seq = nilfs->ns_seg_seq;
925 nilfs->ns_last_cno = ri->ri_cno; 931 nilfs->ns_last_cno = ri->ri_cno;
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c
index e6d9e37fa241..645c78656aa0 100644
--- a/fs/nilfs2/segbuf.c
+++ b/fs/nilfs2/segbuf.c
@@ -24,10 +24,22 @@
24#include <linux/buffer_head.h> 24#include <linux/buffer_head.h>
25#include <linux/writeback.h> 25#include <linux/writeback.h>
26#include <linux/crc32.h> 26#include <linux/crc32.h>
27#include <linux/backing-dev.h>
27#include "page.h" 28#include "page.h"
28#include "segbuf.h" 29#include "segbuf.h"
29 30
30 31
32struct nilfs_write_info {
33 struct the_nilfs *nilfs;
34 struct bio *bio;
35 int start, end; /* The region to be submitted */
36 int rest_blocks;
37 int max_pages;
38 int nr_vecs;
39 sector_t blocknr;
40};
41
42
31static struct kmem_cache *nilfs_segbuf_cachep; 43static struct kmem_cache *nilfs_segbuf_cachep;
32 44
33static void nilfs_segbuf_init_once(void *obj) 45static void nilfs_segbuf_init_once(void *obj)
@@ -63,6 +75,11 @@ struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *sb)
63 INIT_LIST_HEAD(&segbuf->sb_list); 75 INIT_LIST_HEAD(&segbuf->sb_list);
64 INIT_LIST_HEAD(&segbuf->sb_segsum_buffers); 76 INIT_LIST_HEAD(&segbuf->sb_segsum_buffers);
65 INIT_LIST_HEAD(&segbuf->sb_payload_buffers); 77 INIT_LIST_HEAD(&segbuf->sb_payload_buffers);
78
79 init_completion(&segbuf->sb_bio_event);
80 atomic_set(&segbuf->sb_err, 0);
81 segbuf->sb_nbio = 0;
82
66 return segbuf; 83 return segbuf;
67} 84}
68 85
@@ -83,6 +100,22 @@ void nilfs_segbuf_map(struct nilfs_segment_buffer *segbuf, __u64 segnum,
83 segbuf->sb_fseg_end - segbuf->sb_pseg_start + 1; 100 segbuf->sb_fseg_end - segbuf->sb_pseg_start + 1;
84} 101}
85 102
103/**
104 * nilfs_segbuf_map_cont - map a new log behind a given log
105 * @segbuf: new segment buffer
106 * @prev: segment buffer containing a log to be continued
107 */
108void nilfs_segbuf_map_cont(struct nilfs_segment_buffer *segbuf,
109 struct nilfs_segment_buffer *prev)
110{
111 segbuf->sb_segnum = prev->sb_segnum;
112 segbuf->sb_fseg_start = prev->sb_fseg_start;
113 segbuf->sb_fseg_end = prev->sb_fseg_end;
114 segbuf->sb_pseg_start = prev->sb_pseg_start + prev->sb_sum.nblocks;
115 segbuf->sb_rest_blocks =
116 segbuf->sb_fseg_end - segbuf->sb_pseg_start + 1;
117}
118
86void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *segbuf, 119void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *segbuf,
87 __u64 nextnum, struct the_nilfs *nilfs) 120 __u64 nextnum, struct the_nilfs *nilfs)
88{ 121{
@@ -132,8 +165,6 @@ int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned flags,
132 segbuf->sb_sum.sumbytes = sizeof(struct nilfs_segment_summary); 165 segbuf->sb_sum.sumbytes = sizeof(struct nilfs_segment_summary);
133 segbuf->sb_sum.nfinfo = segbuf->sb_sum.nfileblk = 0; 166 segbuf->sb_sum.nfinfo = segbuf->sb_sum.nfileblk = 0;
134 segbuf->sb_sum.ctime = ctime; 167 segbuf->sb_sum.ctime = ctime;
135
136 segbuf->sb_io_error = 0;
137 return 0; 168 return 0;
138} 169}
139 170
@@ -219,7 +250,7 @@ void nilfs_segbuf_fill_in_data_crc(struct nilfs_segment_buffer *segbuf,
219 raw_sum->ss_datasum = cpu_to_le32(crc); 250 raw_sum->ss_datasum = cpu_to_le32(crc);
220} 251}
221 252
222void nilfs_release_buffers(struct list_head *list) 253static void nilfs_release_buffers(struct list_head *list)
223{ 254{
224 struct buffer_head *bh, *n; 255 struct buffer_head *bh, *n;
225 256
@@ -241,13 +272,56 @@ void nilfs_release_buffers(struct list_head *list)
241 } 272 }
242} 273}
243 274
275static void nilfs_segbuf_clear(struct nilfs_segment_buffer *segbuf)
276{
277 nilfs_release_buffers(&segbuf->sb_segsum_buffers);
278 nilfs_release_buffers(&segbuf->sb_payload_buffers);
279}
280
281/*
282 * Iterators for segment buffers
283 */
284void nilfs_clear_logs(struct list_head *logs)
285{
286 struct nilfs_segment_buffer *segbuf;
287
288 list_for_each_entry(segbuf, logs, sb_list)
289 nilfs_segbuf_clear(segbuf);
290}
291
292void nilfs_truncate_logs(struct list_head *logs,
293 struct nilfs_segment_buffer *last)
294{
295 struct nilfs_segment_buffer *n, *segbuf;
296
297 segbuf = list_prepare_entry(last, logs, sb_list);
298 list_for_each_entry_safe_continue(segbuf, n, logs, sb_list) {
299 list_del_init(&segbuf->sb_list);
300 nilfs_segbuf_clear(segbuf);
301 nilfs_segbuf_free(segbuf);
302 }
303}
304
305int nilfs_wait_on_logs(struct list_head *logs)
306{
307 struct nilfs_segment_buffer *segbuf;
308 int err;
309
310 list_for_each_entry(segbuf, logs, sb_list) {
311 err = nilfs_segbuf_wait(segbuf);
312 if (err)
313 return err;
314 }
315 return 0;
316}
317
244/* 318/*
245 * BIO operations 319 * BIO operations
246 */ 320 */
247static void nilfs_end_bio_write(struct bio *bio, int err) 321static void nilfs_end_bio_write(struct bio *bio, int err)
248{ 322{
249 const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); 323 const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
250 struct nilfs_write_info *wi = bio->bi_private; 324 struct nilfs_segment_buffer *segbuf = bio->bi_private;
251 325
252 if (err == -EOPNOTSUPP) { 326 if (err == -EOPNOTSUPP) {
253 set_bit(BIO_EOPNOTSUPP, &bio->bi_flags); 327 set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
@@ -256,21 +330,22 @@ static void nilfs_end_bio_write(struct bio *bio, int err)
256 } 330 }
257 331
258 if (!uptodate) 332 if (!uptodate)
259 atomic_inc(&wi->err); 333 atomic_inc(&segbuf->sb_err);
260 334
261 bio_put(bio); 335 bio_put(bio);
262 complete(&wi->bio_event); 336 complete(&segbuf->sb_bio_event);
263} 337}
264 338
265static int nilfs_submit_seg_bio(struct nilfs_write_info *wi, int mode) 339static int nilfs_segbuf_submit_bio(struct nilfs_segment_buffer *segbuf,
340 struct nilfs_write_info *wi, int mode)
266{ 341{
267 struct bio *bio = wi->bio; 342 struct bio *bio = wi->bio;
268 int err; 343 int err;
269 344
270 if (wi->nbio > 0 && bdi_write_congested(wi->bdi)) { 345 if (segbuf->sb_nbio > 0 && bdi_write_congested(wi->nilfs->ns_bdi)) {
271 wait_for_completion(&wi->bio_event); 346 wait_for_completion(&segbuf->sb_bio_event);
272 wi->nbio--; 347 segbuf->sb_nbio--;
273 if (unlikely(atomic_read(&wi->err))) { 348 if (unlikely(atomic_read(&segbuf->sb_err))) {
274 bio_put(bio); 349 bio_put(bio);
275 err = -EIO; 350 err = -EIO;
276 goto failed; 351 goto failed;
@@ -278,7 +353,7 @@ static int nilfs_submit_seg_bio(struct nilfs_write_info *wi, int mode)
278 } 353 }
279 354
280 bio->bi_end_io = nilfs_end_bio_write; 355 bio->bi_end_io = nilfs_end_bio_write;
281 bio->bi_private = wi; 356 bio->bi_private = segbuf;
282 bio_get(bio); 357 bio_get(bio);
283 submit_bio(mode, bio); 358 submit_bio(mode, bio);
284 if (bio_flagged(bio, BIO_EOPNOTSUPP)) { 359 if (bio_flagged(bio, BIO_EOPNOTSUPP)) {
@@ -286,7 +361,7 @@ static int nilfs_submit_seg_bio(struct nilfs_write_info *wi, int mode)
286 err = -EOPNOTSUPP; 361 err = -EOPNOTSUPP;
287 goto failed; 362 goto failed;
288 } 363 }
289 wi->nbio++; 364 segbuf->sb_nbio++;
290 bio_put(bio); 365 bio_put(bio);
291 366
292 wi->bio = NULL; 367 wi->bio = NULL;
@@ -301,17 +376,15 @@ static int nilfs_submit_seg_bio(struct nilfs_write_info *wi, int mode)
301} 376}
302 377
303/** 378/**
304 * nilfs_alloc_seg_bio - allocate a bio for writing segment. 379 * nilfs_alloc_seg_bio - allocate a new bio for writing log
305 * @sb: super block 380 * @nilfs: nilfs object
306 * @start: beginning disk block number of this BIO. 381 * @start: start block number of the bio
307 * @nr_vecs: request size of page vector. 382 * @nr_vecs: request size of page vector.
308 * 383 *
309 * alloc_seg_bio() allocates a new BIO structure and initialize it.
310 *
311 * Return Value: On success, pointer to the struct bio is returned. 384 * Return Value: On success, pointer to the struct bio is returned.
312 * On error, NULL is returned. 385 * On error, NULL is returned.
313 */ 386 */
314static struct bio *nilfs_alloc_seg_bio(struct super_block *sb, sector_t start, 387static struct bio *nilfs_alloc_seg_bio(struct the_nilfs *nilfs, sector_t start,
315 int nr_vecs) 388 int nr_vecs)
316{ 389{
317 struct bio *bio; 390 struct bio *bio;
@@ -322,36 +395,33 @@ static struct bio *nilfs_alloc_seg_bio(struct super_block *sb, sector_t start,
322 bio = bio_alloc(GFP_NOIO, nr_vecs); 395 bio = bio_alloc(GFP_NOIO, nr_vecs);
323 } 396 }
324 if (likely(bio)) { 397 if (likely(bio)) {
325 bio->bi_bdev = sb->s_bdev; 398 bio->bi_bdev = nilfs->ns_bdev;
326 bio->bi_sector = (sector_t)start << (sb->s_blocksize_bits - 9); 399 bio->bi_sector = start << (nilfs->ns_blocksize_bits - 9);
327 } 400 }
328 return bio; 401 return bio;
329} 402}
330 403
331void nilfs_segbuf_prepare_write(struct nilfs_segment_buffer *segbuf, 404static void nilfs_segbuf_prepare_write(struct nilfs_segment_buffer *segbuf,
332 struct nilfs_write_info *wi) 405 struct nilfs_write_info *wi)
333{ 406{
334 wi->bio = NULL; 407 wi->bio = NULL;
335 wi->rest_blocks = segbuf->sb_sum.nblocks; 408 wi->rest_blocks = segbuf->sb_sum.nblocks;
336 wi->max_pages = bio_get_nr_vecs(wi->sb->s_bdev); 409 wi->max_pages = bio_get_nr_vecs(wi->nilfs->ns_bdev);
337 wi->nr_vecs = min(wi->max_pages, wi->rest_blocks); 410 wi->nr_vecs = min(wi->max_pages, wi->rest_blocks);
338 wi->start = wi->end = 0; 411 wi->start = wi->end = 0;
339 wi->nbio = 0;
340 wi->blocknr = segbuf->sb_pseg_start; 412 wi->blocknr = segbuf->sb_pseg_start;
341
342 atomic_set(&wi->err, 0);
343 init_completion(&wi->bio_event);
344} 413}
345 414
346static int nilfs_submit_bh(struct nilfs_write_info *wi, struct buffer_head *bh, 415static int nilfs_segbuf_submit_bh(struct nilfs_segment_buffer *segbuf,
347 int mode) 416 struct nilfs_write_info *wi,
417 struct buffer_head *bh, int mode)
348{ 418{
349 int len, err; 419 int len, err;
350 420
351 BUG_ON(wi->nr_vecs <= 0); 421 BUG_ON(wi->nr_vecs <= 0);
352 repeat: 422 repeat:
353 if (!wi->bio) { 423 if (!wi->bio) {
354 wi->bio = nilfs_alloc_seg_bio(wi->sb, wi->blocknr + wi->end, 424 wi->bio = nilfs_alloc_seg_bio(wi->nilfs, wi->blocknr + wi->end,
355 wi->nr_vecs); 425 wi->nr_vecs);
356 if (unlikely(!wi->bio)) 426 if (unlikely(!wi->bio))
357 return -ENOMEM; 427 return -ENOMEM;
@@ -363,76 +433,83 @@ static int nilfs_submit_bh(struct nilfs_write_info *wi, struct buffer_head *bh,
363 return 0; 433 return 0;
364 } 434 }
365 /* bio is FULL */ 435 /* bio is FULL */
366 err = nilfs_submit_seg_bio(wi, mode); 436 err = nilfs_segbuf_submit_bio(segbuf, wi, mode);
367 /* never submit current bh */ 437 /* never submit current bh */
368 if (likely(!err)) 438 if (likely(!err))
369 goto repeat; 439 goto repeat;
370 return err; 440 return err;
371} 441}
372 442
443/**
444 * nilfs_segbuf_write - submit write requests of a log
445 * @segbuf: buffer storing a log to be written
446 * @nilfs: nilfs object
447 *
448 * Return Value: On Success, 0 is returned. On Error, one of the following
449 * negative error code is returned.
450 *
451 * %-EIO - I/O error
452 *
453 * %-ENOMEM - Insufficient memory available.
454 */
373int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf, 455int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
374 struct nilfs_write_info *wi) 456 struct the_nilfs *nilfs)
375{ 457{
458 struct nilfs_write_info wi;
376 struct buffer_head *bh; 459 struct buffer_head *bh;
377 int res, rw = WRITE; 460 int res = 0, rw = WRITE;
461
462 wi.nilfs = nilfs;
463 nilfs_segbuf_prepare_write(segbuf, &wi);
378 464
379 list_for_each_entry(bh, &segbuf->sb_segsum_buffers, b_assoc_buffers) { 465 list_for_each_entry(bh, &segbuf->sb_segsum_buffers, b_assoc_buffers) {
380 res = nilfs_submit_bh(wi, bh, rw); 466 res = nilfs_segbuf_submit_bh(segbuf, &wi, bh, rw);
381 if (unlikely(res)) 467 if (unlikely(res))
382 goto failed_bio; 468 goto failed_bio;
383 } 469 }
384 470
385 list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) { 471 list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) {
386 res = nilfs_submit_bh(wi, bh, rw); 472 res = nilfs_segbuf_submit_bh(segbuf, &wi, bh, rw);
387 if (unlikely(res)) 473 if (unlikely(res))
388 goto failed_bio; 474 goto failed_bio;
389 } 475 }
390 476
391 if (wi->bio) { 477 if (wi.bio) {
392 /* 478 /*
393 * Last BIO is always sent through the following 479 * Last BIO is always sent through the following
394 * submission. 480 * submission.
395 */ 481 */
396 rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); 482 rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG);
397 res = nilfs_submit_seg_bio(wi, rw); 483 res = nilfs_segbuf_submit_bio(segbuf, &wi, rw);
398 if (unlikely(res))
399 goto failed_bio;
400 } 484 }
401 485
402 res = 0;
403 out:
404 return res;
405
406 failed_bio: 486 failed_bio:
407 atomic_inc(&wi->err); 487 return res;
408 goto out;
409} 488}
410 489
411/** 490/**
412 * nilfs_segbuf_wait - wait for completion of requested BIOs 491 * nilfs_segbuf_wait - wait for completion of requested BIOs
413 * @wi: nilfs_write_info 492 * @segbuf: segment buffer
414 * 493 *
415 * Return Value: On Success, 0 is returned. On Error, one of the following 494 * Return Value: On Success, 0 is returned. On Error, one of the following
416 * negative error code is returned. 495 * negative error code is returned.
417 * 496 *
418 * %-EIO - I/O error 497 * %-EIO - I/O error
419 */ 498 */
420int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf, 499int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf)
421 struct nilfs_write_info *wi)
422{ 500{
423 int err = 0; 501 int err = 0;
424 502
425 if (!wi->nbio) 503 if (!segbuf->sb_nbio)
426 return 0; 504 return 0;
427 505
428 do { 506 do {
429 wait_for_completion(&wi->bio_event); 507 wait_for_completion(&segbuf->sb_bio_event);
430 } while (--wi->nbio > 0); 508 } while (--segbuf->sb_nbio > 0);
431 509
432 if (unlikely(atomic_read(&wi->err) > 0)) { 510 if (unlikely(atomic_read(&segbuf->sb_err) > 0)) {
433 printk(KERN_ERR "NILFS: IO error writing segment\n"); 511 printk(KERN_ERR "NILFS: IO error writing segment\n");
434 err = -EIO; 512 err = -EIO;
435 segbuf->sb_io_error = 1;
436 } 513 }
437 return err; 514 return err;
438} 515}
diff --git a/fs/nilfs2/segbuf.h b/fs/nilfs2/segbuf.h
index 0c3076f4e592..6af1630fb401 100644
--- a/fs/nilfs2/segbuf.h
+++ b/fs/nilfs2/segbuf.h
@@ -27,7 +27,6 @@
27#include <linux/buffer_head.h> 27#include <linux/buffer_head.h>
28#include <linux/bio.h> 28#include <linux/bio.h>
29#include <linux/completion.h> 29#include <linux/completion.h>
30#include <linux/backing-dev.h>
31 30
32/** 31/**
33 * struct nilfs_segsum_info - On-memory segment summary 32 * struct nilfs_segsum_info - On-memory segment summary
@@ -77,7 +76,9 @@ struct nilfs_segsum_info {
77 * @sb_rest_blocks: Number of residual blocks in the current segment 76 * @sb_rest_blocks: Number of residual blocks in the current segment
78 * @sb_segsum_buffers: List of buffers for segment summaries 77 * @sb_segsum_buffers: List of buffers for segment summaries
79 * @sb_payload_buffers: List of buffers for segment payload 78 * @sb_payload_buffers: List of buffers for segment payload
80 * @sb_io_error: I/O error status 79 * @sb_nbio: Number of flying bio requests
80 * @sb_err: I/O error status
81 * @sb_bio_event: Completion event of log writing
81 */ 82 */
82struct nilfs_segment_buffer { 83struct nilfs_segment_buffer {
83 struct super_block *sb_super; 84 struct super_block *sb_super;
@@ -96,7 +97,9 @@ struct nilfs_segment_buffer {
96 struct list_head sb_payload_buffers; /* including super root */ 97 struct list_head sb_payload_buffers; /* including super root */
97 98
98 /* io status */ 99 /* io status */
99 int sb_io_error; 100 int sb_nbio;
101 atomic_t sb_err;
102 struct completion sb_bio_event;
100}; 103};
101 104
102#define NILFS_LIST_SEGBUF(head) \ 105#define NILFS_LIST_SEGBUF(head) \
@@ -125,6 +128,8 @@ struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *);
125void nilfs_segbuf_free(struct nilfs_segment_buffer *); 128void nilfs_segbuf_free(struct nilfs_segment_buffer *);
126void nilfs_segbuf_map(struct nilfs_segment_buffer *, __u64, unsigned long, 129void nilfs_segbuf_map(struct nilfs_segment_buffer *, __u64, unsigned long,
127 struct the_nilfs *); 130 struct the_nilfs *);
131void nilfs_segbuf_map_cont(struct nilfs_segment_buffer *segbuf,
132 struct nilfs_segment_buffer *prev);
128void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *, __u64, 133void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *, __u64,
129 struct the_nilfs *); 134 struct the_nilfs *);
130int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned, time_t); 135int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned, time_t);
@@ -161,41 +166,18 @@ nilfs_segbuf_add_file_buffer(struct nilfs_segment_buffer *segbuf,
161 segbuf->sb_sum.nfileblk++; 166 segbuf->sb_sum.nfileblk++;
162} 167}
163 168
164void nilfs_release_buffers(struct list_head *); 169int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
170 struct the_nilfs *nilfs);
171int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf);
165 172
166static inline void nilfs_segbuf_clear(struct nilfs_segment_buffer *segbuf) 173void nilfs_clear_logs(struct list_head *logs);
174void nilfs_truncate_logs(struct list_head *logs,
175 struct nilfs_segment_buffer *last);
176int nilfs_wait_on_logs(struct list_head *logs);
177
178static inline void nilfs_destroy_logs(struct list_head *logs)
167{ 179{
168 nilfs_release_buffers(&segbuf->sb_segsum_buffers); 180 nilfs_truncate_logs(logs, NULL);
169 nilfs_release_buffers(&segbuf->sb_payload_buffers);
170} 181}
171 182
172struct nilfs_write_info {
173 struct bio *bio;
174 int start, end; /* The region to be submitted */
175 int rest_blocks;
176 int max_pages;
177 int nr_vecs;
178 sector_t blocknr;
179
180 int nbio;
181 atomic_t err;
182 struct completion bio_event;
183 /* completion event of segment write */
184
185 /*
186 * The following fields must be set explicitly
187 */
188 struct super_block *sb;
189 struct backing_dev_info *bdi; /* backing dev info */
190 struct buffer_head *bh_sr;
191};
192
193
194void nilfs_segbuf_prepare_write(struct nilfs_segment_buffer *,
195 struct nilfs_write_info *);
196int nilfs_segbuf_write(struct nilfs_segment_buffer *,
197 struct nilfs_write_info *);
198int nilfs_segbuf_wait(struct nilfs_segment_buffer *,
199 struct nilfs_write_info *);
200
201#endif /* _NILFS_SEGBUF_H */ 183#endif /* _NILFS_SEGBUF_H */
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 6eff66a070d5..17584c524486 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -974,12 +974,12 @@ static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci,
974 nilfs->ns_nongc_ctime : sci->sc_seg_ctime); 974 nilfs->ns_nongc_ctime : sci->sc_seg_ctime);
975 raw_sr->sr_flags = 0; 975 raw_sr->sr_flags = 0;
976 976
977 nilfs_mdt_write_inode_direct( 977 nilfs_write_inode_common(nilfs_dat_inode(nilfs), (void *)raw_sr +
978 nilfs_dat_inode(nilfs), bh_sr, NILFS_SR_DAT_OFFSET(isz)); 978 NILFS_SR_DAT_OFFSET(isz), 1);
979 nilfs_mdt_write_inode_direct( 979 nilfs_write_inode_common(nilfs->ns_cpfile, (void *)raw_sr +
980 nilfs->ns_cpfile, bh_sr, NILFS_SR_CPFILE_OFFSET(isz)); 980 NILFS_SR_CPFILE_OFFSET(isz), 1);
981 nilfs_mdt_write_inode_direct( 981 nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr +
982 nilfs->ns_sufile, bh_sr, NILFS_SR_SUFILE_OFFSET(isz)); 982 NILFS_SR_SUFILE_OFFSET(isz), 1);
983} 983}
984 984
985static void nilfs_redirty_inodes(struct list_head *head) 985static void nilfs_redirty_inodes(struct list_head *head)
@@ -1273,73 +1273,75 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
1273 return err; 1273 return err;
1274} 1274}
1275 1275
1276static int nilfs_touch_segusage(struct inode *sufile, __u64 segnum) 1276/**
1277{ 1277 * nilfs_segctor_begin_construction - setup segment buffer to make a new log
1278 struct buffer_head *bh_su; 1278 * @sci: nilfs_sc_info
1279 struct nilfs_segment_usage *raw_su; 1279 * @nilfs: nilfs object
1280 int err; 1280 */
1281
1282 err = nilfs_sufile_get_segment_usage(sufile, segnum, &raw_su, &bh_su);
1283 if (unlikely(err))
1284 return err;
1285 nilfs_mdt_mark_buffer_dirty(bh_su);
1286 nilfs_mdt_mark_dirty(sufile);
1287 nilfs_sufile_put_segment_usage(sufile, segnum, bh_su);
1288 return 0;
1289}
1290
1291static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci, 1281static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci,
1292 struct the_nilfs *nilfs) 1282 struct the_nilfs *nilfs)
1293{ 1283{
1294 struct nilfs_segment_buffer *segbuf, *n; 1284 struct nilfs_segment_buffer *segbuf, *prev;
1295 __u64 nextnum; 1285 __u64 nextnum;
1296 int err; 1286 int err, alloc = 0;
1297 1287
1298 if (list_empty(&sci->sc_segbufs)) { 1288 segbuf = nilfs_segbuf_new(sci->sc_super);
1299 segbuf = nilfs_segbuf_new(sci->sc_super); 1289 if (unlikely(!segbuf))
1300 if (unlikely(!segbuf)) 1290 return -ENOMEM;
1301 return -ENOMEM; 1291
1302 list_add(&segbuf->sb_list, &sci->sc_segbufs); 1292 if (list_empty(&sci->sc_write_logs)) {
1303 } else 1293 nilfs_segbuf_map(segbuf, nilfs->ns_segnum,
1304 segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs); 1294 nilfs->ns_pseg_offset, nilfs);
1295 if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) {
1296 nilfs_shift_to_next_segment(nilfs);
1297 nilfs_segbuf_map(segbuf, nilfs->ns_segnum, 0, nilfs);
1298 }
1305 1299
1306 nilfs_segbuf_map(segbuf, nilfs->ns_segnum, nilfs->ns_pseg_offset, 1300 segbuf->sb_sum.seg_seq = nilfs->ns_seg_seq;
1307 nilfs); 1301 nextnum = nilfs->ns_nextnum;
1308 1302
1309 if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) { 1303 if (nilfs->ns_segnum == nilfs->ns_nextnum)
1310 nilfs_shift_to_next_segment(nilfs); 1304 /* Start from the head of a new full segment */
1311 nilfs_segbuf_map(segbuf, nilfs->ns_segnum, 0, nilfs); 1305 alloc++;
1306 } else {
1307 /* Continue logs */
1308 prev = NILFS_LAST_SEGBUF(&sci->sc_write_logs);
1309 nilfs_segbuf_map_cont(segbuf, prev);
1310 segbuf->sb_sum.seg_seq = prev->sb_sum.seg_seq;
1311 nextnum = prev->sb_nextnum;
1312
1313 if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) {
1314 nilfs_segbuf_map(segbuf, prev->sb_nextnum, 0, nilfs);
1315 segbuf->sb_sum.seg_seq++;
1316 alloc++;
1317 }
1312 } 1318 }
1313 sci->sc_segbuf_nblocks = segbuf->sb_rest_blocks;
1314 1319
1315 err = nilfs_touch_segusage(nilfs->ns_sufile, segbuf->sb_segnum); 1320 err = nilfs_sufile_mark_dirty(nilfs->ns_sufile, segbuf->sb_segnum);
1316 if (unlikely(err)) 1321 if (err)
1317 return err; 1322 goto failed;
1318 1323
1319 if (nilfs->ns_segnum == nilfs->ns_nextnum) { 1324 if (alloc) {
1320 /* Start from the head of a new full segment */
1321 err = nilfs_sufile_alloc(nilfs->ns_sufile, &nextnum); 1325 err = nilfs_sufile_alloc(nilfs->ns_sufile, &nextnum);
1322 if (unlikely(err)) 1326 if (err)
1323 return err; 1327 goto failed;
1324 } else 1328 }
1325 nextnum = nilfs->ns_nextnum;
1326
1327 segbuf->sb_sum.seg_seq = nilfs->ns_seg_seq;
1328 nilfs_segbuf_set_next_segnum(segbuf, nextnum, nilfs); 1329 nilfs_segbuf_set_next_segnum(segbuf, nextnum, nilfs);
1329 1330
1330 /* truncating segment buffers */ 1331 BUG_ON(!list_empty(&sci->sc_segbufs));
1331 list_for_each_entry_safe_continue(segbuf, n, &sci->sc_segbufs, 1332 list_add_tail(&segbuf->sb_list, &sci->sc_segbufs);
1332 sb_list) { 1333 sci->sc_segbuf_nblocks = segbuf->sb_rest_blocks;
1333 list_del_init(&segbuf->sb_list);
1334 nilfs_segbuf_free(segbuf);
1335 }
1336 return 0; 1334 return 0;
1335
1336 failed:
1337 nilfs_segbuf_free(segbuf);
1338 return err;
1337} 1339}
1338 1340
1339static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci, 1341static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci,
1340 struct the_nilfs *nilfs, int nadd) 1342 struct the_nilfs *nilfs, int nadd)
1341{ 1343{
1342 struct nilfs_segment_buffer *segbuf, *prev, *n; 1344 struct nilfs_segment_buffer *segbuf, *prev;
1343 struct inode *sufile = nilfs->ns_sufile; 1345 struct inode *sufile = nilfs->ns_sufile;
1344 __u64 nextnextnum; 1346 __u64 nextnextnum;
1345 LIST_HEAD(list); 1347 LIST_HEAD(list);
@@ -1352,7 +1354,7 @@ static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci,
1352 * not be dirty. The following call ensures that the buffer is dirty 1354 * not be dirty. The following call ensures that the buffer is dirty
1353 * and will pin the buffer on memory until the sufile is written. 1355 * and will pin the buffer on memory until the sufile is written.
1354 */ 1356 */
1355 err = nilfs_touch_segusage(sufile, prev->sb_nextnum); 1357 err = nilfs_sufile_mark_dirty(sufile, prev->sb_nextnum);
1356 if (unlikely(err)) 1358 if (unlikely(err))
1357 return err; 1359 return err;
1358 1360
@@ -1378,33 +1380,33 @@ static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci,
1378 list_add_tail(&segbuf->sb_list, &list); 1380 list_add_tail(&segbuf->sb_list, &list);
1379 prev = segbuf; 1381 prev = segbuf;
1380 } 1382 }
1381 list_splice(&list, sci->sc_segbufs.prev); 1383 list_splice_tail(&list, &sci->sc_segbufs);
1382 return 0; 1384 return 0;
1383 1385
1384 failed_segbuf: 1386 failed_segbuf:
1385 nilfs_segbuf_free(segbuf); 1387 nilfs_segbuf_free(segbuf);
1386 failed: 1388 failed:
1387 list_for_each_entry_safe(segbuf, n, &list, sb_list) { 1389 list_for_each_entry(segbuf, &list, sb_list) {
1388 ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum); 1390 ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1389 WARN_ON(ret); /* never fails */ 1391 WARN_ON(ret); /* never fails */
1390 list_del_init(&segbuf->sb_list);
1391 nilfs_segbuf_free(segbuf);
1392 } 1392 }
1393 nilfs_destroy_logs(&list);
1393 return err; 1394 return err;
1394} 1395}
1395 1396
1396static void nilfs_segctor_free_incomplete_segments(struct nilfs_sc_info *sci, 1397static void nilfs_free_incomplete_logs(struct list_head *logs,
1397 struct the_nilfs *nilfs) 1398 struct the_nilfs *nilfs)
1398{ 1399{
1399 struct nilfs_segment_buffer *segbuf; 1400 struct nilfs_segment_buffer *segbuf, *prev;
1400 int ret, done = 0; 1401 struct inode *sufile = nilfs->ns_sufile;
1402 int ret;
1401 1403
1402 segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs); 1404 segbuf = NILFS_FIRST_SEGBUF(logs);
1403 if (nilfs->ns_nextnum != segbuf->sb_nextnum) { 1405 if (nilfs->ns_nextnum != segbuf->sb_nextnum) {
1404 ret = nilfs_sufile_free(nilfs->ns_sufile, segbuf->sb_nextnum); 1406 ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1405 WARN_ON(ret); /* never fails */ 1407 WARN_ON(ret); /* never fails */
1406 } 1408 }
1407 if (segbuf->sb_io_error) { 1409 if (atomic_read(&segbuf->sb_err)) {
1408 /* Case 1: The first segment failed */ 1410 /* Case 1: The first segment failed */
1409 if (segbuf->sb_pseg_start != segbuf->sb_fseg_start) 1411 if (segbuf->sb_pseg_start != segbuf->sb_fseg_start)
1410 /* Case 1a: Partial segment appended into an existing 1412 /* Case 1a: Partial segment appended into an existing
@@ -1413,106 +1415,54 @@ static void nilfs_segctor_free_incomplete_segments(struct nilfs_sc_info *sci,
1413 segbuf->sb_fseg_end); 1415 segbuf->sb_fseg_end);
1414 else /* Case 1b: New full segment */ 1416 else /* Case 1b: New full segment */
1415 set_nilfs_discontinued(nilfs); 1417 set_nilfs_discontinued(nilfs);
1416 done++;
1417 } 1418 }
1418 1419
1419 list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) { 1420 prev = segbuf;
1420 ret = nilfs_sufile_free(nilfs->ns_sufile, segbuf->sb_nextnum); 1421 list_for_each_entry_continue(segbuf, logs, sb_list) {
1421 WARN_ON(ret); /* never fails */ 1422 if (prev->sb_nextnum != segbuf->sb_nextnum) {
1422 if (!done && segbuf->sb_io_error) { 1423 ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1423 if (segbuf->sb_segnum != nilfs->ns_nextnum) 1424 WARN_ON(ret); /* never fails */
1424 /* Case 2: extended segment (!= next) failed */
1425 nilfs_sufile_set_error(nilfs->ns_sufile,
1426 segbuf->sb_segnum);
1427 done++;
1428 }
1429 }
1430}
1431
1432static void nilfs_segctor_clear_segment_buffers(struct nilfs_sc_info *sci)
1433{
1434 struct nilfs_segment_buffer *segbuf;
1435
1436 list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list)
1437 nilfs_segbuf_clear(segbuf);
1438 sci->sc_super_root = NULL;
1439}
1440
1441static void nilfs_segctor_destroy_segment_buffers(struct nilfs_sc_info *sci)
1442{
1443 struct nilfs_segment_buffer *segbuf;
1444
1445 while (!list_empty(&sci->sc_segbufs)) {
1446 segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
1447 list_del_init(&segbuf->sb_list);
1448 nilfs_segbuf_free(segbuf);
1449 }
1450 /* sci->sc_curseg = NULL; */
1451}
1452
1453static void nilfs_segctor_end_construction(struct nilfs_sc_info *sci,
1454 struct the_nilfs *nilfs, int err)
1455{
1456 if (unlikely(err)) {
1457 nilfs_segctor_free_incomplete_segments(sci, nilfs);
1458 if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
1459 int ret;
1460
1461 ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile,
1462 sci->sc_freesegs,
1463 sci->sc_nfreesegs,
1464 NULL);
1465 WARN_ON(ret); /* do not happen */
1466 } 1425 }
1426 if (atomic_read(&segbuf->sb_err) &&
1427 segbuf->sb_segnum != nilfs->ns_nextnum)
1428 /* Case 2: extended segment (!= next) failed */
1429 nilfs_sufile_set_error(sufile, segbuf->sb_segnum);
1430 prev = segbuf;
1467 } 1431 }
1468 nilfs_segctor_clear_segment_buffers(sci);
1469} 1432}
1470 1433
1471static void nilfs_segctor_update_segusage(struct nilfs_sc_info *sci, 1434static void nilfs_segctor_update_segusage(struct nilfs_sc_info *sci,
1472 struct inode *sufile) 1435 struct inode *sufile)
1473{ 1436{
1474 struct nilfs_segment_buffer *segbuf; 1437 struct nilfs_segment_buffer *segbuf;
1475 struct buffer_head *bh_su;
1476 struct nilfs_segment_usage *raw_su;
1477 unsigned long live_blocks; 1438 unsigned long live_blocks;
1478 int ret; 1439 int ret;
1479 1440
1480 list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { 1441 list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
1481 ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum,
1482 &raw_su, &bh_su);
1483 WARN_ON(ret); /* always succeed because bh_su is dirty */
1484 live_blocks = segbuf->sb_sum.nblocks + 1442 live_blocks = segbuf->sb_sum.nblocks +
1485 (segbuf->sb_pseg_start - segbuf->sb_fseg_start); 1443 (segbuf->sb_pseg_start - segbuf->sb_fseg_start);
1486 raw_su->su_lastmod = cpu_to_le64(sci->sc_seg_ctime); 1444 ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
1487 raw_su->su_nblocks = cpu_to_le32(live_blocks); 1445 live_blocks,
1488 nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum, 1446 sci->sc_seg_ctime);
1489 bh_su); 1447 WARN_ON(ret); /* always succeed because the segusage is dirty */
1490 } 1448 }
1491} 1449}
1492 1450
1493static void nilfs_segctor_cancel_segusage(struct nilfs_sc_info *sci, 1451static void nilfs_cancel_segusage(struct list_head *logs, struct inode *sufile)
1494 struct inode *sufile)
1495{ 1452{
1496 struct nilfs_segment_buffer *segbuf; 1453 struct nilfs_segment_buffer *segbuf;
1497 struct buffer_head *bh_su;
1498 struct nilfs_segment_usage *raw_su;
1499 int ret; 1454 int ret;
1500 1455
1501 segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs); 1456 segbuf = NILFS_FIRST_SEGBUF(logs);
1502 ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum, 1457 ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
1503 &raw_su, &bh_su); 1458 segbuf->sb_pseg_start -
1504 WARN_ON(ret); /* always succeed because bh_su is dirty */ 1459 segbuf->sb_fseg_start, 0);
1505 raw_su->su_nblocks = cpu_to_le32(segbuf->sb_pseg_start - 1460 WARN_ON(ret); /* always succeed because the segusage is dirty */
1506 segbuf->sb_fseg_start);
1507 nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum, bh_su);
1508 1461
1509 list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) { 1462 list_for_each_entry_continue(segbuf, logs, sb_list) {
1510 ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum, 1463 ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
1511 &raw_su, &bh_su); 1464 0, 0);
1512 WARN_ON(ret); /* always succeed */ 1465 WARN_ON(ret); /* always succeed */
1513 raw_su->su_nblocks = 0;
1514 nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum,
1515 bh_su);
1516 } 1466 }
1517} 1467}
1518 1468
@@ -1520,17 +1470,15 @@ static void nilfs_segctor_truncate_segments(struct nilfs_sc_info *sci,
1520 struct nilfs_segment_buffer *last, 1470 struct nilfs_segment_buffer *last,
1521 struct inode *sufile) 1471 struct inode *sufile)
1522{ 1472{
1523 struct nilfs_segment_buffer *segbuf = last, *n; 1473 struct nilfs_segment_buffer *segbuf = last;
1524 int ret; 1474 int ret;
1525 1475
1526 list_for_each_entry_safe_continue(segbuf, n, &sci->sc_segbufs, 1476 list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) {
1527 sb_list) {
1528 list_del_init(&segbuf->sb_list);
1529 sci->sc_segbuf_nblocks -= segbuf->sb_rest_blocks; 1477 sci->sc_segbuf_nblocks -= segbuf->sb_rest_blocks;
1530 ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum); 1478 ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1531 WARN_ON(ret); 1479 WARN_ON(ret);
1532 nilfs_segbuf_free(segbuf);
1533 } 1480 }
1481 nilfs_truncate_logs(&sci->sc_segbufs, last);
1534} 1482}
1535 1483
1536 1484
@@ -1569,7 +1517,7 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
1569 NULL); 1517 NULL);
1570 WARN_ON(err); /* do not happen */ 1518 WARN_ON(err); /* do not happen */
1571 } 1519 }
1572 nilfs_segctor_clear_segment_buffers(sci); 1520 nilfs_clear_logs(&sci->sc_segbufs);
1573 1521
1574 err = nilfs_segctor_extend_segments(sci, nilfs, nadd); 1522 err = nilfs_segctor_extend_segments(sci, nilfs, nadd);
1575 if (unlikely(err)) 1523 if (unlikely(err))
@@ -1814,26 +1762,18 @@ static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci,
1814} 1762}
1815 1763
1816static int nilfs_segctor_write(struct nilfs_sc_info *sci, 1764static int nilfs_segctor_write(struct nilfs_sc_info *sci,
1817 struct backing_dev_info *bdi) 1765 struct the_nilfs *nilfs)
1818{ 1766{
1819 struct nilfs_segment_buffer *segbuf; 1767 struct nilfs_segment_buffer *segbuf;
1820 struct nilfs_write_info wi; 1768 int ret = 0;
1821 int err, res;
1822
1823 wi.sb = sci->sc_super;
1824 wi.bh_sr = sci->sc_super_root;
1825 wi.bdi = bdi;
1826 1769
1827 list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { 1770 list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
1828 nilfs_segbuf_prepare_write(segbuf, &wi); 1771 ret = nilfs_segbuf_write(segbuf, nilfs);
1829 err = nilfs_segbuf_write(segbuf, &wi); 1772 if (ret)
1830 1773 break;
1831 res = nilfs_segbuf_wait(segbuf, &wi);
1832 err = err ? : res;
1833 if (err)
1834 return err;
1835 } 1774 }
1836 return 0; 1775 list_splice_tail_init(&sci->sc_segbufs, &sci->sc_write_logs);
1776 return ret;
1837} 1777}
1838 1778
1839static void __nilfs_end_page_io(struct page *page, int err) 1779static void __nilfs_end_page_io(struct page *page, int err)
@@ -1911,15 +1851,17 @@ static void nilfs_clear_copied_buffers(struct list_head *list, int err)
1911 } 1851 }
1912} 1852}
1913 1853
1914static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci, 1854static void nilfs_abort_logs(struct list_head *logs, struct page *failed_page,
1915 struct page *failed_page, int err) 1855 struct buffer_head *bh_sr, int err)
1916{ 1856{
1917 struct nilfs_segment_buffer *segbuf; 1857 struct nilfs_segment_buffer *segbuf;
1918 struct page *bd_page = NULL, *fs_page = NULL; 1858 struct page *bd_page = NULL, *fs_page = NULL;
1859 struct buffer_head *bh;
1919 1860
1920 list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { 1861 if (list_empty(logs))
1921 struct buffer_head *bh; 1862 return;
1922 1863
1864 list_for_each_entry(segbuf, logs, sb_list) {
1923 list_for_each_entry(bh, &segbuf->sb_segsum_buffers, 1865 list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
1924 b_assoc_buffers) { 1866 b_assoc_buffers) {
1925 if (bh->b_page != bd_page) { 1867 if (bh->b_page != bd_page) {
@@ -1931,7 +1873,7 @@ static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci,
1931 1873
1932 list_for_each_entry(bh, &segbuf->sb_payload_buffers, 1874 list_for_each_entry(bh, &segbuf->sb_payload_buffers,
1933 b_assoc_buffers) { 1875 b_assoc_buffers) {
1934 if (bh == sci->sc_super_root) { 1876 if (bh == bh_sr) {
1935 if (bh->b_page != bd_page) { 1877 if (bh->b_page != bd_page) {
1936 end_page_writeback(bd_page); 1878 end_page_writeback(bd_page);
1937 bd_page = bh->b_page; 1879 bd_page = bh->b_page;
@@ -1941,7 +1883,7 @@ static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci,
1941 if (bh->b_page != fs_page) { 1883 if (bh->b_page != fs_page) {
1942 nilfs_end_page_io(fs_page, err); 1884 nilfs_end_page_io(fs_page, err);
1943 if (fs_page && fs_page == failed_page) 1885 if (fs_page && fs_page == failed_page)
1944 goto done; 1886 return;
1945 fs_page = bh->b_page; 1887 fs_page = bh->b_page;
1946 } 1888 }
1947 } 1889 }
@@ -1950,8 +1892,34 @@ static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci,
1950 end_page_writeback(bd_page); 1892 end_page_writeback(bd_page);
1951 1893
1952 nilfs_end_page_io(fs_page, err); 1894 nilfs_end_page_io(fs_page, err);
1953 done: 1895}
1896
1897static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
1898 struct the_nilfs *nilfs, int err)
1899{
1900 LIST_HEAD(logs);
1901 int ret;
1902
1903 list_splice_tail_init(&sci->sc_write_logs, &logs);
1904 ret = nilfs_wait_on_logs(&logs);
1905 if (ret)
1906 nilfs_abort_logs(&logs, NULL, sci->sc_super_root, ret);
1907
1908 list_splice_tail_init(&sci->sc_segbufs, &logs);
1909 nilfs_cancel_segusage(&logs, nilfs->ns_sufile);
1910 nilfs_free_incomplete_logs(&logs, nilfs);
1954 nilfs_clear_copied_buffers(&sci->sc_copied_buffers, err); 1911 nilfs_clear_copied_buffers(&sci->sc_copied_buffers, err);
1912
1913 if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
1914 ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile,
1915 sci->sc_freesegs,
1916 sci->sc_nfreesegs,
1917 NULL);
1918 WARN_ON(ret); /* do not happen */
1919 }
1920
1921 nilfs_destroy_logs(&logs);
1922 sci->sc_super_root = NULL;
1955} 1923}
1956 1924
1957static void nilfs_set_next_segment(struct the_nilfs *nilfs, 1925static void nilfs_set_next_segment(struct the_nilfs *nilfs,
@@ -1973,7 +1941,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
1973 struct the_nilfs *nilfs = sbi->s_nilfs; 1941 struct the_nilfs *nilfs = sbi->s_nilfs;
1974 int update_sr = (sci->sc_super_root != NULL); 1942 int update_sr = (sci->sc_super_root != NULL);
1975 1943
1976 list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { 1944 list_for_each_entry(segbuf, &sci->sc_write_logs, sb_list) {
1977 struct buffer_head *bh; 1945 struct buffer_head *bh;
1978 1946
1979 list_for_each_entry(bh, &segbuf->sb_segsum_buffers, 1947 list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
@@ -2046,7 +2014,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
2046 2014
2047 sci->sc_nblk_inc += sci->sc_nblk_this_inc; 2015 sci->sc_nblk_inc += sci->sc_nblk_this_inc;
2048 2016
2049 segbuf = NILFS_LAST_SEGBUF(&sci->sc_segbufs); 2017 segbuf = NILFS_LAST_SEGBUF(&sci->sc_write_logs);
2050 nilfs_set_next_segment(nilfs, segbuf); 2018 nilfs_set_next_segment(nilfs, segbuf);
2051 2019
2052 if (update_sr) { 2020 if (update_sr) {
@@ -2057,10 +2025,23 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
2057 clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags); 2025 clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags);
2058 clear_bit(NILFS_SC_DIRTY, &sci->sc_flags); 2026 clear_bit(NILFS_SC_DIRTY, &sci->sc_flags);
2059 set_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags); 2027 set_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags);
2028 nilfs_segctor_clear_metadata_dirty(sci);
2060 } else 2029 } else
2061 clear_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags); 2030 clear_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags);
2062} 2031}
2063 2032
2033static int nilfs_segctor_wait(struct nilfs_sc_info *sci)
2034{
2035 int ret;
2036
2037 ret = nilfs_wait_on_logs(&sci->sc_write_logs);
2038 if (!ret) {
2039 nilfs_segctor_complete_write(sci);
2040 nilfs_destroy_logs(&sci->sc_write_logs);
2041 }
2042 return ret;
2043}
2044
2064static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci, 2045static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci,
2065 struct nilfs_sb_info *sbi) 2046 struct nilfs_sb_info *sbi)
2066{ 2047{
@@ -2173,7 +2154,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
2173 /* Avoid empty segment */ 2154 /* Avoid empty segment */
2174 if (sci->sc_stage.scnt == NILFS_ST_DONE && 2155 if (sci->sc_stage.scnt == NILFS_ST_DONE &&
2175 NILFS_SEG_EMPTY(&sci->sc_curseg->sb_sum)) { 2156 NILFS_SEG_EMPTY(&sci->sc_curseg->sb_sum)) {
2176 nilfs_segctor_end_construction(sci, nilfs, 1); 2157 nilfs_segctor_abort_construction(sci, nilfs, 1);
2177 goto out; 2158 goto out;
2178 } 2159 }
2179 2160
@@ -2187,7 +2168,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
2187 if (has_sr) { 2168 if (has_sr) {
2188 err = nilfs_segctor_fill_in_checkpoint(sci); 2169 err = nilfs_segctor_fill_in_checkpoint(sci);
2189 if (unlikely(err)) 2170 if (unlikely(err))
2190 goto failed_to_make_up; 2171 goto failed_to_write;
2191 2172
2192 nilfs_segctor_fill_in_super_root(sci, nilfs); 2173 nilfs_segctor_fill_in_super_root(sci, nilfs);
2193 } 2174 }
@@ -2195,42 +2176,46 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
2195 2176
2196 /* Write partial segments */ 2177 /* Write partial segments */
2197 err = nilfs_segctor_prepare_write(sci, &failed_page); 2178 err = nilfs_segctor_prepare_write(sci, &failed_page);
2198 if (unlikely(err)) 2179 if (err) {
2180 nilfs_abort_logs(&sci->sc_segbufs, failed_page,
2181 sci->sc_super_root, err);
2199 goto failed_to_write; 2182 goto failed_to_write;
2200 2183 }
2201 nilfs_segctor_fill_in_checksums(sci, nilfs->ns_crc_seed); 2184 nilfs_segctor_fill_in_checksums(sci, nilfs->ns_crc_seed);
2202 2185
2203 err = nilfs_segctor_write(sci, nilfs->ns_bdi); 2186 err = nilfs_segctor_write(sci, nilfs);
2204 if (unlikely(err)) 2187 if (unlikely(err))
2205 goto failed_to_write; 2188 goto failed_to_write;
2206 2189
2207 nilfs_segctor_complete_write(sci); 2190 if (sci->sc_stage.scnt == NILFS_ST_DONE ||
2208 2191 nilfs->ns_blocksize_bits != PAGE_CACHE_SHIFT) {
2209 /* Commit segments */ 2192 /*
2210 if (has_sr) 2193 * At this point, we avoid double buffering
2211 nilfs_segctor_clear_metadata_dirty(sci); 2194 * for blocksize < pagesize because page dirty
2212 2195 * flag is turned off during write and dirty
2213 nilfs_segctor_end_construction(sci, nilfs, 0); 2196 * buffers are not properly collected for
2214 2197 * pages crossing over segments.
2198 */
2199 err = nilfs_segctor_wait(sci);
2200 if (err)
2201 goto failed_to_write;
2202 }
2215 } while (sci->sc_stage.scnt != NILFS_ST_DONE); 2203 } while (sci->sc_stage.scnt != NILFS_ST_DONE);
2216 2204
2205 sci->sc_super_root = NULL;
2206
2217 out: 2207 out:
2218 nilfs_segctor_destroy_segment_buffers(sci);
2219 nilfs_segctor_check_out_files(sci, sbi); 2208 nilfs_segctor_check_out_files(sci, sbi);
2220 return err; 2209 return err;
2221 2210
2222 failed_to_write: 2211 failed_to_write:
2223 nilfs_segctor_abort_write(sci, failed_page, err);
2224 nilfs_segctor_cancel_segusage(sci, nilfs->ns_sufile);
2225
2226 failed_to_make_up:
2227 if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED) 2212 if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
2228 nilfs_redirty_inodes(&sci->sc_dirty_files); 2213 nilfs_redirty_inodes(&sci->sc_dirty_files);
2229 2214
2230 failed: 2215 failed:
2231 if (nilfs_doing_gc()) 2216 if (nilfs_doing_gc())
2232 nilfs_redirty_inodes(&sci->sc_gc_inodes); 2217 nilfs_redirty_inodes(&sci->sc_gc_inodes);
2233 nilfs_segctor_end_construction(sci, nilfs, err); 2218 nilfs_segctor_abort_construction(sci, nilfs, err);
2234 goto out; 2219 goto out;
2235} 2220}
2236 2221
@@ -2559,7 +2544,7 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
2559 2544
2560 sci->sc_freesegs = kbufs[4]; 2545 sci->sc_freesegs = kbufs[4];
2561 sci->sc_nfreesegs = argv[4].v_nmembs; 2546 sci->sc_nfreesegs = argv[4].v_nmembs;
2562 list_splice_init(&nilfs->ns_gc_inodes, sci->sc_gc_inodes.prev); 2547 list_splice_tail_init(&nilfs->ns_gc_inodes, &sci->sc_gc_inodes);
2563 2548
2564 for (;;) { 2549 for (;;) {
2565 nilfs_segctor_accept(sci, &req); 2550 nilfs_segctor_accept(sci, &req);
@@ -2788,6 +2773,7 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi)
2788 spin_lock_init(&sci->sc_state_lock); 2773 spin_lock_init(&sci->sc_state_lock);
2789 INIT_LIST_HEAD(&sci->sc_dirty_files); 2774 INIT_LIST_HEAD(&sci->sc_dirty_files);
2790 INIT_LIST_HEAD(&sci->sc_segbufs); 2775 INIT_LIST_HEAD(&sci->sc_segbufs);
2776 INIT_LIST_HEAD(&sci->sc_write_logs);
2791 INIT_LIST_HEAD(&sci->sc_gc_inodes); 2777 INIT_LIST_HEAD(&sci->sc_gc_inodes);
2792 INIT_LIST_HEAD(&sci->sc_copied_buffers); 2778 INIT_LIST_HEAD(&sci->sc_copied_buffers);
2793 2779
@@ -2855,6 +2841,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
2855 } 2841 }
2856 2842
2857 WARN_ON(!list_empty(&sci->sc_segbufs)); 2843 WARN_ON(!list_empty(&sci->sc_segbufs));
2844 WARN_ON(!list_empty(&sci->sc_write_logs));
2858 2845
2859 down_write(&sbi->s_nilfs->ns_segctor_sem); 2846 down_write(&sbi->s_nilfs->ns_segctor_sem);
2860 2847
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
index 0d2a475a741b..3d3ab2f9864c 100644
--- a/fs/nilfs2/segment.h
+++ b/fs/nilfs2/segment.h
@@ -97,6 +97,7 @@ struct nilfs_segsum_pointer {
97 * @sc_dsync_start: start byte offset of data pages 97 * @sc_dsync_start: start byte offset of data pages
98 * @sc_dsync_end: end byte offset of data pages (inclusive) 98 * @sc_dsync_end: end byte offset of data pages (inclusive)
99 * @sc_segbufs: List of segment buffers 99 * @sc_segbufs: List of segment buffers
100 * @sc_write_logs: List of segment buffers to hold logs under writing
100 * @sc_segbuf_nblocks: Number of available blocks in segment buffers. 101 * @sc_segbuf_nblocks: Number of available blocks in segment buffers.
101 * @sc_curseg: Current segment buffer 102 * @sc_curseg: Current segment buffer
102 * @sc_super_root: Pointer to the super root buffer 103 * @sc_super_root: Pointer to the super root buffer
@@ -143,6 +144,7 @@ struct nilfs_sc_info {
143 144
144 /* Segment buffers */ 145 /* Segment buffers */
145 struct list_head sc_segbufs; 146 struct list_head sc_segbufs;
147 struct list_head sc_write_logs;
146 unsigned long sc_segbuf_nblocks; 148 unsigned long sc_segbuf_nblocks;
147 struct nilfs_segment_buffer *sc_curseg; 149 struct nilfs_segment_buffer *sc_curseg;
148 struct buffer_head *sc_super_root; 150 struct buffer_head *sc_super_root;
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
index 37994d4a59cc..b6c36d0cc331 100644
--- a/fs/nilfs2/sufile.c
+++ b/fs/nilfs2/sufile.c
@@ -31,6 +31,16 @@
31#include "sufile.h" 31#include "sufile.h"
32 32
33 33
34struct nilfs_sufile_info {
35 struct nilfs_mdt_info mi;
36 unsigned long ncleansegs;
37};
38
39static inline struct nilfs_sufile_info *NILFS_SUI(struct inode *sufile)
40{
41 return (struct nilfs_sufile_info *)NILFS_MDT(sufile);
42}
43
34static inline unsigned long 44static inline unsigned long
35nilfs_sufile_segment_usages_per_block(const struct inode *sufile) 45nilfs_sufile_segment_usages_per_block(const struct inode *sufile)
36{ 46{
@@ -62,14 +72,6 @@ nilfs_sufile_segment_usages_in_block(const struct inode *sufile, __u64 curr,
62 max - curr + 1); 72 max - curr + 1);
63} 73}
64 74
65static inline struct nilfs_sufile_header *
66nilfs_sufile_block_get_header(const struct inode *sufile,
67 struct buffer_head *bh,
68 void *kaddr)
69{
70 return kaddr + bh_offset(bh);
71}
72
73static struct nilfs_segment_usage * 75static struct nilfs_segment_usage *
74nilfs_sufile_block_get_segment_usage(const struct inode *sufile, __u64 segnum, 76nilfs_sufile_block_get_segment_usage(const struct inode *sufile, __u64 segnum,
75 struct buffer_head *bh, void *kaddr) 77 struct buffer_head *bh, void *kaddr)
@@ -110,6 +112,15 @@ static void nilfs_sufile_mod_counter(struct buffer_head *header_bh,
110} 112}
111 113
112/** 114/**
115 * nilfs_sufile_get_ncleansegs - return the number of clean segments
116 * @sufile: inode of segment usage file
117 */
118unsigned long nilfs_sufile_get_ncleansegs(struct inode *sufile)
119{
120 return NILFS_SUI(sufile)->ncleansegs;
121}
122
123/**
113 * nilfs_sufile_updatev - modify multiple segment usages at a time 124 * nilfs_sufile_updatev - modify multiple segment usages at a time
114 * @sufile: inode of segment usage file 125 * @sufile: inode of segment usage file
115 * @segnumv: array of segment numbers 126 * @segnumv: array of segment numbers
@@ -270,7 +281,7 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump)
270 if (ret < 0) 281 if (ret < 0)
271 goto out_sem; 282 goto out_sem;
272 kaddr = kmap_atomic(header_bh->b_page, KM_USER0); 283 kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
273 header = nilfs_sufile_block_get_header(sufile, header_bh, kaddr); 284 header = kaddr + bh_offset(header_bh);
274 ncleansegs = le64_to_cpu(header->sh_ncleansegs); 285 ncleansegs = le64_to_cpu(header->sh_ncleansegs);
275 last_alloc = le64_to_cpu(header->sh_last_alloc); 286 last_alloc = le64_to_cpu(header->sh_last_alloc);
276 kunmap_atomic(kaddr, KM_USER0); 287 kunmap_atomic(kaddr, KM_USER0);
@@ -302,13 +313,13 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump)
302 kunmap_atomic(kaddr, KM_USER0); 313 kunmap_atomic(kaddr, KM_USER0);
303 314
304 kaddr = kmap_atomic(header_bh->b_page, KM_USER0); 315 kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
305 header = nilfs_sufile_block_get_header( 316 header = kaddr + bh_offset(header_bh);
306 sufile, header_bh, kaddr);
307 le64_add_cpu(&header->sh_ncleansegs, -1); 317 le64_add_cpu(&header->sh_ncleansegs, -1);
308 le64_add_cpu(&header->sh_ndirtysegs, 1); 318 le64_add_cpu(&header->sh_ndirtysegs, 1);
309 header->sh_last_alloc = cpu_to_le64(segnum); 319 header->sh_last_alloc = cpu_to_le64(segnum);
310 kunmap_atomic(kaddr, KM_USER0); 320 kunmap_atomic(kaddr, KM_USER0);
311 321
322 NILFS_SUI(sufile)->ncleansegs--;
312 nilfs_mdt_mark_buffer_dirty(header_bh); 323 nilfs_mdt_mark_buffer_dirty(header_bh);
313 nilfs_mdt_mark_buffer_dirty(su_bh); 324 nilfs_mdt_mark_buffer_dirty(su_bh);
314 nilfs_mdt_mark_dirty(sufile); 325 nilfs_mdt_mark_dirty(sufile);
@@ -351,6 +362,8 @@ void nilfs_sufile_do_cancel_free(struct inode *sufile, __u64 segnum,
351 kunmap_atomic(kaddr, KM_USER0); 362 kunmap_atomic(kaddr, KM_USER0);
352 363
353 nilfs_sufile_mod_counter(header_bh, -1, 1); 364 nilfs_sufile_mod_counter(header_bh, -1, 1);
365 NILFS_SUI(sufile)->ncleansegs--;
366
354 nilfs_mdt_mark_buffer_dirty(su_bh); 367 nilfs_mdt_mark_buffer_dirty(su_bh);
355 nilfs_mdt_mark_dirty(sufile); 368 nilfs_mdt_mark_dirty(sufile);
356} 369}
@@ -380,6 +393,8 @@ void nilfs_sufile_do_scrap(struct inode *sufile, __u64 segnum,
380 kunmap_atomic(kaddr, KM_USER0); 393 kunmap_atomic(kaddr, KM_USER0);
381 394
382 nilfs_sufile_mod_counter(header_bh, clean ? (u64)-1 : 0, dirty ? 0 : 1); 395 nilfs_sufile_mod_counter(header_bh, clean ? (u64)-1 : 0, dirty ? 0 : 1);
396 NILFS_SUI(sufile)->ncleansegs -= clean;
397
383 nilfs_mdt_mark_buffer_dirty(su_bh); 398 nilfs_mdt_mark_buffer_dirty(su_bh);
384 nilfs_mdt_mark_dirty(sufile); 399 nilfs_mdt_mark_dirty(sufile);
385} 400}
@@ -409,79 +424,65 @@ void nilfs_sufile_do_free(struct inode *sufile, __u64 segnum,
409 nilfs_mdt_mark_buffer_dirty(su_bh); 424 nilfs_mdt_mark_buffer_dirty(su_bh);
410 425
411 nilfs_sufile_mod_counter(header_bh, 1, sudirty ? (u64)-1 : 0); 426 nilfs_sufile_mod_counter(header_bh, 1, sudirty ? (u64)-1 : 0);
427 NILFS_SUI(sufile)->ncleansegs++;
428
412 nilfs_mdt_mark_dirty(sufile); 429 nilfs_mdt_mark_dirty(sufile);
413} 430}
414 431
415/** 432/**
416 * nilfs_sufile_get_segment_usage - get a segment usage 433 * nilfs_sufile_mark_dirty - mark the buffer having a segment usage dirty
417 * @sufile: inode of segment usage file 434 * @sufile: inode of segment usage file
418 * @segnum: segment number 435 * @segnum: segment number
419 * @sup: pointer to segment usage
420 * @bhp: pointer to buffer head
421 *
422 * Description: nilfs_sufile_get_segment_usage() acquires the segment usage
423 * specified by @segnum.
424 *
425 * Return Value: On success, 0 is returned, and the segment usage and the
426 * buffer head of the buffer on which the segment usage is located are stored
427 * in the place pointed by @sup and @bhp, respectively. On error, one of the
428 * following negative error codes is returned.
429 *
430 * %-EIO - I/O error.
431 *
432 * %-ENOMEM - Insufficient amount of memory available.
433 *
434 * %-EINVAL - Invalid segment usage number.
435 */ 436 */
436int nilfs_sufile_get_segment_usage(struct inode *sufile, __u64 segnum, 437int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
437 struct nilfs_segment_usage **sup,
438 struct buffer_head **bhp)
439{ 438{
440 struct buffer_head *bh; 439 struct buffer_head *bh;
441 struct nilfs_segment_usage *su;
442 void *kaddr;
443 int ret; 440 int ret;
444 441
445 /* segnum is 0 origin */ 442 ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh);
446 if (segnum >= nilfs_sufile_get_nsegments(sufile)) 443 if (!ret) {
447 return -EINVAL; 444 nilfs_mdt_mark_buffer_dirty(bh);
448 down_write(&NILFS_MDT(sufile)->mi_sem); 445 nilfs_mdt_mark_dirty(sufile);
449 ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 1, &bh);
450 if (ret < 0)
451 goto out_sem;
452 kaddr = kmap(bh->b_page);
453 su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);
454 if (nilfs_segment_usage_error(su)) {
455 kunmap(bh->b_page);
456 brelse(bh); 446 brelse(bh);
457 ret = -EINVAL;
458 goto out_sem;
459 } 447 }
460
461 if (sup != NULL)
462 *sup = su;
463 *bhp = bh;
464
465 out_sem:
466 up_write(&NILFS_MDT(sufile)->mi_sem);
467 return ret; 448 return ret;
468} 449}
469 450
470/** 451/**
471 * nilfs_sufile_put_segment_usage - put a segment usage 452 * nilfs_sufile_set_segment_usage - set usage of a segment
472 * @sufile: inode of segment usage file 453 * @sufile: inode of segment usage file
473 * @segnum: segment number 454 * @segnum: segment number
474 * @bh: buffer head 455 * @nblocks: number of live blocks in the segment
475 * 456 * @modtime: modification time (option)
476 * Description: nilfs_sufile_put_segment_usage() releases the segment usage
477 * specified by @segnum. @bh must be the buffer head which have been returned
478 * by a previous call to nilfs_sufile_get_segment_usage() with @segnum.
479 */ 457 */
480void nilfs_sufile_put_segment_usage(struct inode *sufile, __u64 segnum, 458int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
481 struct buffer_head *bh) 459 unsigned long nblocks, time_t modtime)
482{ 460{
483 kunmap(bh->b_page); 461 struct buffer_head *bh;
462 struct nilfs_segment_usage *su;
463 void *kaddr;
464 int ret;
465
466 down_write(&NILFS_MDT(sufile)->mi_sem);
467 ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh);
468 if (ret < 0)
469 goto out_sem;
470
471 kaddr = kmap_atomic(bh->b_page, KM_USER0);
472 su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);
473 WARN_ON(nilfs_segment_usage_error(su));
474 if (modtime)
475 su->su_lastmod = cpu_to_le64(modtime);
476 su->su_nblocks = cpu_to_le32(nblocks);
477 kunmap_atomic(kaddr, KM_USER0);
478
479 nilfs_mdt_mark_buffer_dirty(bh);
480 nilfs_mdt_mark_dirty(sufile);
484 brelse(bh); 481 brelse(bh);
482
483 out_sem:
484 up_write(&NILFS_MDT(sufile)->mi_sem);
485 return ret;
485} 486}
486 487
487/** 488/**
@@ -515,7 +516,7 @@ int nilfs_sufile_get_stat(struct inode *sufile, struct nilfs_sustat *sustat)
515 goto out_sem; 516 goto out_sem;
516 517
517 kaddr = kmap_atomic(header_bh->b_page, KM_USER0); 518 kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
518 header = nilfs_sufile_block_get_header(sufile, header_bh, kaddr); 519 header = kaddr + bh_offset(header_bh);
519 sustat->ss_nsegs = nilfs_sufile_get_nsegments(sufile); 520 sustat->ss_nsegs = nilfs_sufile_get_nsegments(sufile);
520 sustat->ss_ncleansegs = le64_to_cpu(header->sh_ncleansegs); 521 sustat->ss_ncleansegs = le64_to_cpu(header->sh_ncleansegs);
521 sustat->ss_ndirtysegs = le64_to_cpu(header->sh_ndirtysegs); 522 sustat->ss_ndirtysegs = le64_to_cpu(header->sh_ndirtysegs);
@@ -532,33 +533,6 @@ int nilfs_sufile_get_stat(struct inode *sufile, struct nilfs_sustat *sustat)
532 return ret; 533 return ret;
533} 534}
534 535
535/**
536 * nilfs_sufile_get_ncleansegs - get the number of clean segments
537 * @sufile: inode of segment usage file
538 * @nsegsp: pointer to the number of clean segments
539 *
540 * Description: nilfs_sufile_get_ncleansegs() acquires the number of clean
541 * segments.
542 *
543 * Return Value: On success, 0 is returned and the number of clean segments is
544 * stored in the place pointed by @nsegsp. On error, one of the following
545 * negative error codes is returned.
546 *
547 * %-EIO - I/O error.
548 *
549 * %-ENOMEM - Insufficient amount of memory available.
550 */
551int nilfs_sufile_get_ncleansegs(struct inode *sufile, unsigned long *nsegsp)
552{
553 struct nilfs_sustat sustat;
554 int ret;
555
556 ret = nilfs_sufile_get_stat(sufile, &sustat);
557 if (ret == 0)
558 *nsegsp = sustat.ss_ncleansegs;
559 return ret;
560}
561
562void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum, 536void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum,
563 struct buffer_head *header_bh, 537 struct buffer_head *header_bh,
564 struct buffer_head *su_bh) 538 struct buffer_head *su_bh)
@@ -577,8 +551,10 @@ void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum,
577 nilfs_segment_usage_set_error(su); 551 nilfs_segment_usage_set_error(su);
578 kunmap_atomic(kaddr, KM_USER0); 552 kunmap_atomic(kaddr, KM_USER0);
579 553
580 if (suclean) 554 if (suclean) {
581 nilfs_sufile_mod_counter(header_bh, -1, 0); 555 nilfs_sufile_mod_counter(header_bh, -1, 0);
556 NILFS_SUI(sufile)->ncleansegs--;
557 }
582 nilfs_mdt_mark_buffer_dirty(su_bh); 558 nilfs_mdt_mark_buffer_dirty(su_bh);
583 nilfs_mdt_mark_dirty(sufile); 559 nilfs_mdt_mark_dirty(sufile);
584} 560}
@@ -657,3 +633,48 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf,
657 up_read(&NILFS_MDT(sufile)->mi_sem); 633 up_read(&NILFS_MDT(sufile)->mi_sem);
658 return ret; 634 return ret;
659} 635}
636
637/**
638 * nilfs_sufile_read - read sufile inode
639 * @sufile: sufile inode
640 * @raw_inode: on-disk sufile inode
641 */
642int nilfs_sufile_read(struct inode *sufile, struct nilfs_inode *raw_inode)
643{
644 struct nilfs_sufile_info *sui = NILFS_SUI(sufile);
645 struct buffer_head *header_bh;
646 struct nilfs_sufile_header *header;
647 void *kaddr;
648 int ret;
649
650 ret = nilfs_read_inode_common(sufile, raw_inode);
651 if (ret < 0)
652 return ret;
653
654 ret = nilfs_sufile_get_header_block(sufile, &header_bh);
655 if (!ret) {
656 kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
657 header = kaddr + bh_offset(header_bh);
658 sui->ncleansegs = le64_to_cpu(header->sh_ncleansegs);
659 kunmap_atomic(kaddr, KM_USER0);
660 brelse(header_bh);
661 }
662 return ret;
663}
664
665/**
666 * nilfs_sufile_new - create sufile
667 * @nilfs: nilfs object
668 * @susize: size of a segment usage entry
669 */
670struct inode *nilfs_sufile_new(struct the_nilfs *nilfs, size_t susize)
671{
672 struct inode *sufile;
673
674 sufile = nilfs_mdt_new(nilfs, NULL, NILFS_SUFILE_INO,
675 sizeof(struct nilfs_sufile_info));
676 if (sufile)
677 nilfs_mdt_set_entry_size(sufile, susize,
678 sizeof(struct nilfs_sufile_header));
679 return sufile;
680}
diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h
index 0e99e5c0bd0f..15163b8aff7d 100644
--- a/fs/nilfs2/sufile.h
+++ b/fs/nilfs2/sufile.h
@@ -34,14 +34,13 @@ static inline unsigned long nilfs_sufile_get_nsegments(struct inode *sufile)
34 return NILFS_MDT(sufile)->mi_nilfs->ns_nsegments; 34 return NILFS_MDT(sufile)->mi_nilfs->ns_nsegments;
35} 35}
36 36
37unsigned long nilfs_sufile_get_ncleansegs(struct inode *sufile);
38
37int nilfs_sufile_alloc(struct inode *, __u64 *); 39int nilfs_sufile_alloc(struct inode *, __u64 *);
38int nilfs_sufile_get_segment_usage(struct inode *, __u64, 40int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum);
39 struct nilfs_segment_usage **, 41int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
40 struct buffer_head **); 42 unsigned long nblocks, time_t modtime);
41void nilfs_sufile_put_segment_usage(struct inode *, __u64,
42 struct buffer_head *);
43int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *); 43int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *);
44int nilfs_sufile_get_ncleansegs(struct inode *, unsigned long *);
45ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned, 44ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned,
46 size_t); 45 size_t);
47 46
@@ -62,6 +61,9 @@ void nilfs_sufile_do_cancel_free(struct inode *, __u64, struct buffer_head *,
62void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *, 61void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *,
63 struct buffer_head *); 62 struct buffer_head *);
64 63
64int nilfs_sufile_read(struct inode *sufile, struct nilfs_inode *raw_inode);
65struct inode *nilfs_sufile_new(struct the_nilfs *nilfs, size_t susize);
66
65/** 67/**
66 * nilfs_sufile_scrap - make a segment garbage 68 * nilfs_sufile_scrap - make a segment garbage
67 * @sufile: inode of segment usage file 69 * @sufile: inode of segment usage file
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 644e66727dd0..5403b3ef3a42 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -363,14 +363,10 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno)
363 list_add(&sbi->s_list, &nilfs->ns_supers); 363 list_add(&sbi->s_list, &nilfs->ns_supers);
364 up_write(&nilfs->ns_super_sem); 364 up_write(&nilfs->ns_super_sem);
365 365
366 sbi->s_ifile = nilfs_mdt_new(nilfs, sbi->s_super, NILFS_IFILE_INO); 366 sbi->s_ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size);
367 if (!sbi->s_ifile) 367 if (!sbi->s_ifile)
368 return -ENOMEM; 368 return -ENOMEM;
369 369
370 err = nilfs_palloc_init_blockgroup(sbi->s_ifile, nilfs->ns_inode_size);
371 if (unlikely(err))
372 goto failed;
373
374 down_read(&nilfs->ns_segctor_sem); 370 down_read(&nilfs->ns_segctor_sem);
375 err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp, 371 err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp,
376 &bh_cp); 372 &bh_cp);
@@ -411,7 +407,6 @@ void nilfs_detach_checkpoint(struct nilfs_sb_info *sbi)
411{ 407{
412 struct the_nilfs *nilfs = sbi->s_nilfs; 408 struct the_nilfs *nilfs = sbi->s_nilfs;
413 409
414 nilfs_mdt_clear(sbi->s_ifile);
415 nilfs_mdt_destroy(sbi->s_ifile); 410 nilfs_mdt_destroy(sbi->s_ifile);
416 sbi->s_ifile = NULL; 411 sbi->s_ifile = NULL;
417 down_write(&nilfs->ns_super_sem); 412 down_write(&nilfs->ns_super_sem);
@@ -419,22 +414,6 @@ void nilfs_detach_checkpoint(struct nilfs_sb_info *sbi)
419 up_write(&nilfs->ns_super_sem); 414 up_write(&nilfs->ns_super_sem);
420} 415}
421 416
422static int nilfs_mark_recovery_complete(struct nilfs_sb_info *sbi)
423{
424 struct the_nilfs *nilfs = sbi->s_nilfs;
425 int err = 0;
426
427 down_write(&nilfs->ns_sem);
428 if (!(nilfs->ns_mount_state & NILFS_VALID_FS)) {
429 nilfs->ns_mount_state |= NILFS_VALID_FS;
430 err = nilfs_commit_super(sbi, 1);
431 if (likely(!err))
432 printk(KERN_INFO "NILFS: recovery complete.\n");
433 }
434 up_write(&nilfs->ns_sem);
435 return err;
436}
437
438static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf) 417static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf)
439{ 418{
440 struct super_block *sb = dentry->d_sb; 419 struct super_block *sb = dentry->d_sb;
@@ -490,7 +469,7 @@ static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
490 struct nilfs_sb_info *sbi = NILFS_SB(sb); 469 struct nilfs_sb_info *sbi = NILFS_SB(sb);
491 470
492 if (!nilfs_test_opt(sbi, BARRIER)) 471 if (!nilfs_test_opt(sbi, BARRIER))
493 seq_printf(seq, ",barrier=off"); 472 seq_printf(seq, ",nobarrier");
494 if (nilfs_test_opt(sbi, SNAPSHOT)) 473 if (nilfs_test_opt(sbi, SNAPSHOT))
495 seq_printf(seq, ",cp=%llu", 474 seq_printf(seq, ",cp=%llu",
496 (unsigned long long int)sbi->s_snapshot_cno); 475 (unsigned long long int)sbi->s_snapshot_cno);
@@ -500,6 +479,8 @@ static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
500 seq_printf(seq, ",errors=panic"); 479 seq_printf(seq, ",errors=panic");
501 if (nilfs_test_opt(sbi, STRICT_ORDER)) 480 if (nilfs_test_opt(sbi, STRICT_ORDER))
502 seq_printf(seq, ",order=strict"); 481 seq_printf(seq, ",order=strict");
482 if (nilfs_test_opt(sbi, NORECOVERY))
483 seq_printf(seq, ",norecovery");
503 484
504 return 0; 485 return 0;
505} 486}
@@ -568,7 +549,7 @@ static const struct export_operations nilfs_export_ops = {
568 549
569enum { 550enum {
570 Opt_err_cont, Opt_err_panic, Opt_err_ro, 551 Opt_err_cont, Opt_err_panic, Opt_err_ro,
571 Opt_barrier, Opt_snapshot, Opt_order, 552 Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery,
572 Opt_err, 553 Opt_err,
573}; 554};
574 555
@@ -576,25 +557,13 @@ static match_table_t tokens = {
576 {Opt_err_cont, "errors=continue"}, 557 {Opt_err_cont, "errors=continue"},
577 {Opt_err_panic, "errors=panic"}, 558 {Opt_err_panic, "errors=panic"},
578 {Opt_err_ro, "errors=remount-ro"}, 559 {Opt_err_ro, "errors=remount-ro"},
579 {Opt_barrier, "barrier=%s"}, 560 {Opt_nobarrier, "nobarrier"},
580 {Opt_snapshot, "cp=%u"}, 561 {Opt_snapshot, "cp=%u"},
581 {Opt_order, "order=%s"}, 562 {Opt_order, "order=%s"},
563 {Opt_norecovery, "norecovery"},
582 {Opt_err, NULL} 564 {Opt_err, NULL}
583}; 565};
584 566
585static int match_bool(substring_t *s, int *result)
586{
587 int len = s->to - s->from;
588
589 if (strncmp(s->from, "on", len) == 0)
590 *result = 1;
591 else if (strncmp(s->from, "off", len) == 0)
592 *result = 0;
593 else
594 return 1;
595 return 0;
596}
597
598static int parse_options(char *options, struct super_block *sb) 567static int parse_options(char *options, struct super_block *sb)
599{ 568{
600 struct nilfs_sb_info *sbi = NILFS_SB(sb); 569 struct nilfs_sb_info *sbi = NILFS_SB(sb);
@@ -612,13 +581,8 @@ static int parse_options(char *options, struct super_block *sb)
612 581
613 token = match_token(p, tokens, args); 582 token = match_token(p, tokens, args);
614 switch (token) { 583 switch (token) {
615 case Opt_barrier: 584 case Opt_nobarrier:
616 if (match_bool(&args[0], &option)) 585 nilfs_clear_opt(sbi, BARRIER);
617 return 0;
618 if (option)
619 nilfs_set_opt(sbi, BARRIER);
620 else
621 nilfs_clear_opt(sbi, BARRIER);
622 break; 586 break;
623 case Opt_order: 587 case Opt_order:
624 if (strcmp(args[0].from, "relaxed") == 0) 588 if (strcmp(args[0].from, "relaxed") == 0)
@@ -647,6 +611,9 @@ static int parse_options(char *options, struct super_block *sb)
647 sbi->s_snapshot_cno = option; 611 sbi->s_snapshot_cno = option;
648 nilfs_set_opt(sbi, SNAPSHOT); 612 nilfs_set_opt(sbi, SNAPSHOT);
649 break; 613 break;
614 case Opt_norecovery:
615 nilfs_set_opt(sbi, NORECOVERY);
616 break;
650 default: 617 default:
651 printk(KERN_ERR 618 printk(KERN_ERR
652 "NILFS: Unrecognized mount option \"%s\"\n", p); 619 "NILFS: Unrecognized mount option \"%s\"\n", p);
@@ -672,9 +639,7 @@ static int nilfs_setup_super(struct nilfs_sb_info *sbi)
672 int mnt_count = le16_to_cpu(sbp->s_mnt_count); 639 int mnt_count = le16_to_cpu(sbp->s_mnt_count);
673 640
674 /* nilfs->sem must be locked by the caller. */ 641 /* nilfs->sem must be locked by the caller. */
675 if (!(nilfs->ns_mount_state & NILFS_VALID_FS)) { 642 if (nilfs->ns_mount_state & NILFS_ERROR_FS) {
676 printk(KERN_WARNING "NILFS warning: mounting unchecked fs\n");
677 } else if (nilfs->ns_mount_state & NILFS_ERROR_FS) {
678 printk(KERN_WARNING 643 printk(KERN_WARNING
679 "NILFS warning: mounting fs with errors\n"); 644 "NILFS warning: mounting fs with errors\n");
680#if 0 645#if 0
@@ -782,11 +747,10 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
782 sb->s_root = NULL; 747 sb->s_root = NULL;
783 sb->s_time_gran = 1; 748 sb->s_time_gran = 1;
784 749
785 if (!nilfs_loaded(nilfs)) { 750 err = load_nilfs(nilfs, sbi);
786 err = load_nilfs(nilfs, sbi); 751 if (err)
787 if (err) 752 goto failed_sbi;
788 goto failed_sbi; 753
789 }
790 cno = nilfs_last_cno(nilfs); 754 cno = nilfs_last_cno(nilfs);
791 755
792 if (sb->s_flags & MS_RDONLY) { 756 if (sb->s_flags & MS_RDONLY) {
@@ -854,12 +818,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
854 up_write(&nilfs->ns_sem); 818 up_write(&nilfs->ns_sem);
855 } 819 }
856 820
857 err = nilfs_mark_recovery_complete(sbi);
858 if (unlikely(err)) {
859 printk(KERN_ERR "NILFS: recovery failed.\n");
860 goto failed_root;
861 }
862
863 down_write(&nilfs->ns_super_sem); 821 down_write(&nilfs->ns_super_sem);
864 if (!nilfs_test_opt(sbi, SNAPSHOT)) 822 if (!nilfs_test_opt(sbi, SNAPSHOT))
865 nilfs->ns_current = sbi; 823 nilfs->ns_current = sbi;
@@ -867,10 +825,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
867 825
868 return 0; 826 return 0;
869 827
870 failed_root:
871 dput(sb->s_root);
872 sb->s_root = NULL;
873
874 failed_segctor: 828 failed_segctor:
875 nilfs_detach_segment_constructor(sbi); 829 nilfs_detach_segment_constructor(sbi);
876 830
@@ -915,6 +869,14 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
915 goto restore_opts; 869 goto restore_opts;
916 } 870 }
917 871
872 if (!nilfs_valid_fs(nilfs)) {
873 printk(KERN_WARNING "NILFS (device %s): couldn't "
874 "remount because the filesystem is in an "
875 "incomplete recovery state.\n", sb->s_id);
876 err = -EINVAL;
877 goto restore_opts;
878 }
879
918 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) 880 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
919 goto out; 881 goto out;
920 if (*flags & MS_RDONLY) { 882 if (*flags & MS_RDONLY) {
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index ad391a8c3e7e..6241e1722efc 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -146,13 +146,9 @@ void put_nilfs(struct the_nilfs *nilfs)
146 146
147 might_sleep(); 147 might_sleep();
148 if (nilfs_loaded(nilfs)) { 148 if (nilfs_loaded(nilfs)) {
149 nilfs_mdt_clear(nilfs->ns_sufile);
150 nilfs_mdt_destroy(nilfs->ns_sufile); 149 nilfs_mdt_destroy(nilfs->ns_sufile);
151 nilfs_mdt_clear(nilfs->ns_cpfile);
152 nilfs_mdt_destroy(nilfs->ns_cpfile); 150 nilfs_mdt_destroy(nilfs->ns_cpfile);
153 nilfs_mdt_clear(nilfs->ns_dat);
154 nilfs_mdt_destroy(nilfs->ns_dat); 151 nilfs_mdt_destroy(nilfs->ns_dat);
155 /* XXX: how and when to clear nilfs->ns_gc_dat? */
156 nilfs_mdt_destroy(nilfs->ns_gc_dat); 152 nilfs_mdt_destroy(nilfs->ns_gc_dat);
157 } 153 }
158 if (nilfs_init(nilfs)) { 154 if (nilfs_init(nilfs)) {
@@ -166,7 +162,6 @@ void put_nilfs(struct the_nilfs *nilfs)
166static int nilfs_load_super_root(struct the_nilfs *nilfs, 162static int nilfs_load_super_root(struct the_nilfs *nilfs,
167 struct nilfs_sb_info *sbi, sector_t sr_block) 163 struct nilfs_sb_info *sbi, sector_t sr_block)
168{ 164{
169 static struct lock_class_key dat_lock_key;
170 struct buffer_head *bh_sr; 165 struct buffer_head *bh_sr;
171 struct nilfs_super_root *raw_sr; 166 struct nilfs_super_root *raw_sr;
172 struct nilfs_super_block **sbp = nilfs->ns_sbp; 167 struct nilfs_super_block **sbp = nilfs->ns_sbp;
@@ -187,51 +182,36 @@ static int nilfs_load_super_root(struct the_nilfs *nilfs,
187 inode_size = nilfs->ns_inode_size; 182 inode_size = nilfs->ns_inode_size;
188 183
189 err = -ENOMEM; 184 err = -ENOMEM;
190 nilfs->ns_dat = nilfs_mdt_new(nilfs, NULL, NILFS_DAT_INO); 185 nilfs->ns_dat = nilfs_dat_new(nilfs, dat_entry_size);
191 if (unlikely(!nilfs->ns_dat)) 186 if (unlikely(!nilfs->ns_dat))
192 goto failed; 187 goto failed;
193 188
194 nilfs->ns_gc_dat = nilfs_mdt_new(nilfs, NULL, NILFS_DAT_INO); 189 nilfs->ns_gc_dat = nilfs_dat_new(nilfs, dat_entry_size);
195 if (unlikely(!nilfs->ns_gc_dat)) 190 if (unlikely(!nilfs->ns_gc_dat))
196 goto failed_dat; 191 goto failed_dat;
197 192
198 nilfs->ns_cpfile = nilfs_mdt_new(nilfs, NULL, NILFS_CPFILE_INO); 193 nilfs->ns_cpfile = nilfs_cpfile_new(nilfs, checkpoint_size);
199 if (unlikely(!nilfs->ns_cpfile)) 194 if (unlikely(!nilfs->ns_cpfile))
200 goto failed_gc_dat; 195 goto failed_gc_dat;
201 196
202 nilfs->ns_sufile = nilfs_mdt_new(nilfs, NULL, NILFS_SUFILE_INO); 197 nilfs->ns_sufile = nilfs_sufile_new(nilfs, segment_usage_size);
203 if (unlikely(!nilfs->ns_sufile)) 198 if (unlikely(!nilfs->ns_sufile))
204 goto failed_cpfile; 199 goto failed_cpfile;
205 200
206 err = nilfs_palloc_init_blockgroup(nilfs->ns_dat, dat_entry_size);
207 if (unlikely(err))
208 goto failed_sufile;
209
210 err = nilfs_palloc_init_blockgroup(nilfs->ns_gc_dat, dat_entry_size);
211 if (unlikely(err))
212 goto failed_sufile;
213
214 lockdep_set_class(&NILFS_MDT(nilfs->ns_dat)->mi_sem, &dat_lock_key);
215 lockdep_set_class(&NILFS_MDT(nilfs->ns_gc_dat)->mi_sem, &dat_lock_key);
216
217 nilfs_mdt_set_shadow(nilfs->ns_dat, nilfs->ns_gc_dat); 201 nilfs_mdt_set_shadow(nilfs->ns_dat, nilfs->ns_gc_dat);
218 nilfs_mdt_set_entry_size(nilfs->ns_cpfile, checkpoint_size,
219 sizeof(struct nilfs_cpfile_header));
220 nilfs_mdt_set_entry_size(nilfs->ns_sufile, segment_usage_size,
221 sizeof(struct nilfs_sufile_header));
222 202
223 err = nilfs_mdt_read_inode_direct( 203 err = nilfs_dat_read(nilfs->ns_dat, (void *)bh_sr->b_data +
224 nilfs->ns_dat, bh_sr, NILFS_SR_DAT_OFFSET(inode_size)); 204 NILFS_SR_DAT_OFFSET(inode_size));
225 if (unlikely(err)) 205 if (unlikely(err))
226 goto failed_sufile; 206 goto failed_sufile;
227 207
228 err = nilfs_mdt_read_inode_direct( 208 err = nilfs_cpfile_read(nilfs->ns_cpfile, (void *)bh_sr->b_data +
229 nilfs->ns_cpfile, bh_sr, NILFS_SR_CPFILE_OFFSET(inode_size)); 209 NILFS_SR_CPFILE_OFFSET(inode_size));
230 if (unlikely(err)) 210 if (unlikely(err))
231 goto failed_sufile; 211 goto failed_sufile;
232 212
233 err = nilfs_mdt_read_inode_direct( 213 err = nilfs_sufile_read(nilfs->ns_sufile, (void *)bh_sr->b_data +
234 nilfs->ns_sufile, bh_sr, NILFS_SR_SUFILE_OFFSET(inode_size)); 214 NILFS_SR_SUFILE_OFFSET(inode_size));
235 if (unlikely(err)) 215 if (unlikely(err))
236 goto failed_sufile; 216 goto failed_sufile;
237 217
@@ -281,29 +261,30 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
281 struct nilfs_recovery_info ri; 261 struct nilfs_recovery_info ri;
282 unsigned int s_flags = sbi->s_super->s_flags; 262 unsigned int s_flags = sbi->s_super->s_flags;
283 int really_read_only = bdev_read_only(nilfs->ns_bdev); 263 int really_read_only = bdev_read_only(nilfs->ns_bdev);
284 unsigned valid_fs; 264 int valid_fs = nilfs_valid_fs(nilfs);
285 int err = 0; 265 int err;
286
287 nilfs_init_recovery_info(&ri);
288 266
289 down_write(&nilfs->ns_sem); 267 if (nilfs_loaded(nilfs)) {
290 valid_fs = (nilfs->ns_mount_state & NILFS_VALID_FS); 268 if (valid_fs ||
291 up_write(&nilfs->ns_sem); 269 ((s_flags & MS_RDONLY) && nilfs_test_opt(sbi, NORECOVERY)))
270 return 0;
271 printk(KERN_ERR "NILFS: the filesystem is in an incomplete "
272 "recovery state.\n");
273 return -EINVAL;
274 }
292 275
293 if (!valid_fs && (s_flags & MS_RDONLY)) { 276 if (!valid_fs) {
294 printk(KERN_INFO "NILFS: INFO: recovery " 277 printk(KERN_WARNING "NILFS warning: mounting unchecked fs\n");
295 "required for readonly filesystem.\n"); 278 if (s_flags & MS_RDONLY) {
296 if (really_read_only) { 279 printk(KERN_INFO "NILFS: INFO: recovery "
297 printk(KERN_ERR "NILFS: write access " 280 "required for readonly filesystem.\n");
298 "unavailable, cannot proceed.\n"); 281 printk(KERN_INFO "NILFS: write access will "
299 err = -EROFS; 282 "be enabled during recovery.\n");
300 goto failed;
301 } 283 }
302 printk(KERN_INFO "NILFS: write access will "
303 "be enabled during recovery.\n");
304 sbi->s_super->s_flags &= ~MS_RDONLY;
305 } 284 }
306 285
286 nilfs_init_recovery_info(&ri);
287
307 err = nilfs_search_super_root(nilfs, sbi, &ri); 288 err = nilfs_search_super_root(nilfs, sbi, &ri);
308 if (unlikely(err)) { 289 if (unlikely(err)) {
309 printk(KERN_ERR "NILFS: error searching super root.\n"); 290 printk(KERN_ERR "NILFS: error searching super root.\n");
@@ -316,19 +297,56 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
316 goto failed; 297 goto failed;
317 } 298 }
318 299
319 if (!valid_fs) { 300 if (valid_fs)
320 err = nilfs_recover_logical_segments(nilfs, sbi, &ri); 301 goto skip_recovery;
321 if (unlikely(err)) { 302
322 nilfs_mdt_destroy(nilfs->ns_cpfile); 303 if (s_flags & MS_RDONLY) {
323 nilfs_mdt_destroy(nilfs->ns_sufile); 304 if (nilfs_test_opt(sbi, NORECOVERY)) {
324 nilfs_mdt_destroy(nilfs->ns_dat); 305 printk(KERN_INFO "NILFS: norecovery option specified. "
325 goto failed; 306 "skipping roll-forward recovery\n");
307 goto skip_recovery;
326 } 308 }
327 if (ri.ri_need_recovery == NILFS_RECOVERY_SR_UPDATED) 309 if (really_read_only) {
328 sbi->s_super->s_dirt = 1; 310 printk(KERN_ERR "NILFS: write access "
311 "unavailable, cannot proceed.\n");
312 err = -EROFS;
313 goto failed_unload;
314 }
315 sbi->s_super->s_flags &= ~MS_RDONLY;
316 } else if (nilfs_test_opt(sbi, NORECOVERY)) {
317 printk(KERN_ERR "NILFS: recovery cancelled because norecovery "
318 "option was specified for a read/write mount\n");
319 err = -EINVAL;
320 goto failed_unload;
329 } 321 }
330 322
323 err = nilfs_recover_logical_segments(nilfs, sbi, &ri);
324 if (err)
325 goto failed_unload;
326
327 down_write(&nilfs->ns_sem);
328 nilfs->ns_mount_state |= NILFS_VALID_FS;
329 nilfs->ns_sbp[0]->s_state = cpu_to_le16(nilfs->ns_mount_state);
330 err = nilfs_commit_super(sbi, 1);
331 up_write(&nilfs->ns_sem);
332
333 if (err) {
334 printk(KERN_ERR "NILFS: failed to update super block. "
335 "recovery unfinished.\n");
336 goto failed_unload;
337 }
338 printk(KERN_INFO "NILFS: recovery complete.\n");
339
340 skip_recovery:
331 set_nilfs_loaded(nilfs); 341 set_nilfs_loaded(nilfs);
342 nilfs_clear_recovery_info(&ri);
343 sbi->s_super->s_flags = s_flags;
344 return 0;
345
346 failed_unload:
347 nilfs_mdt_destroy(nilfs->ns_cpfile);
348 nilfs_mdt_destroy(nilfs->ns_sufile);
349 nilfs_mdt_destroy(nilfs->ns_dat);
332 350
333 failed: 351 failed:
334 nilfs_clear_recovery_info(&ri); 352 nilfs_clear_recovery_info(&ri);
@@ -632,30 +650,23 @@ int nilfs_count_free_blocks(struct the_nilfs *nilfs, sector_t *nblocks)
632{ 650{
633 struct inode *dat = nilfs_dat_inode(nilfs); 651 struct inode *dat = nilfs_dat_inode(nilfs);
634 unsigned long ncleansegs; 652 unsigned long ncleansegs;
635 int err;
636 653
637 down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ 654 down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
638 err = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile, &ncleansegs); 655 ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
639 up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ 656 up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
640 if (likely(!err)) 657 *nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment;
641 *nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment; 658 return 0;
642 return err;
643} 659}
644 660
645int nilfs_near_disk_full(struct the_nilfs *nilfs) 661int nilfs_near_disk_full(struct the_nilfs *nilfs)
646{ 662{
647 struct inode *sufile = nilfs->ns_sufile;
648 unsigned long ncleansegs, nincsegs; 663 unsigned long ncleansegs, nincsegs;
649 int ret;
650 664
651 ret = nilfs_sufile_get_ncleansegs(sufile, &ncleansegs); 665 ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
652 if (likely(!ret)) { 666 nincsegs = atomic_read(&nilfs->ns_ndirtyblks) /
653 nincsegs = atomic_read(&nilfs->ns_ndirtyblks) / 667 nilfs->ns_blocks_per_segment + 1;
654 nilfs->ns_blocks_per_segment + 1; 668
655 if (ncleansegs <= nilfs->ns_nrsvsegs + nincsegs) 669 return ncleansegs <= nilfs->ns_nrsvsegs + nincsegs;
656 ret++;
657 }
658 return ret;
659} 670}
660 671
661/** 672/**
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
index 20abd55881e0..589786e33464 100644
--- a/fs/nilfs2/the_nilfs.h
+++ b/fs/nilfs2/the_nilfs.h
@@ -258,6 +258,16 @@ static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi)
258 kfree(sbi); 258 kfree(sbi);
259} 259}
260 260
261static inline int nilfs_valid_fs(struct the_nilfs *nilfs)
262{
263 unsigned valid_fs;
264
265 down_read(&nilfs->ns_sem);
266 valid_fs = (nilfs->ns_mount_state & NILFS_VALID_FS);
267 up_read(&nilfs->ns_sem);
268 return valid_fs;
269}
270
261static inline void 271static inline void
262nilfs_get_segment_range(struct the_nilfs *nilfs, __u64 segnum, 272nilfs_get_segment_range(struct the_nilfs *nilfs, __u64 segnum,
263 sector_t *seg_start, sector_t *seg_end) 273 sector_t *seg_start, sector_t *seg_end)
diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h
index ce520402e840..3fe02cf8b65a 100644
--- a/include/linux/nilfs2_fs.h
+++ b/include/linux/nilfs2_fs.h
@@ -151,6 +151,8 @@ struct nilfs_super_root {
151#define NILFS_MOUNT_BARRIER 0x1000 /* Use block barriers */ 151#define NILFS_MOUNT_BARRIER 0x1000 /* Use block barriers */
152#define NILFS_MOUNT_STRICT_ORDER 0x2000 /* Apply strict in-order 152#define NILFS_MOUNT_STRICT_ORDER 0x2000 /* Apply strict in-order
153 semantics also for data */ 153 semantics also for data */
154#define NILFS_MOUNT_NORECOVERY 0x4000 /* Disable write access during
155 mount-time recovery */
154 156
155 157
156/** 158/**
@@ -403,6 +405,28 @@ struct nilfs_segment_summary {
403#define NILFS_SS_GC 0x0010 /* segment written for cleaner operation */ 405#define NILFS_SS_GC 0x0010 /* segment written for cleaner operation */
404 406
405/** 407/**
408 * struct nilfs_btree_node - B-tree node
409 * @bn_flags: flags
410 * @bn_level: level
411 * @bn_nchildren: number of children
412 * @bn_pad: padding
413 */
414struct nilfs_btree_node {
415 __u8 bn_flags;
416 __u8 bn_level;
417 __le16 bn_nchildren;
418 __le32 bn_pad;
419};
420
421/* flags */
422#define NILFS_BTREE_NODE_ROOT 0x01
423
424/* level */
425#define NILFS_BTREE_LEVEL_DATA 0
426#define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1)
427#define NILFS_BTREE_LEVEL_MAX 14
428
429/**
406 * struct nilfs_palloc_group_desc - block group descriptor 430 * struct nilfs_palloc_group_desc - block group descriptor
407 * @pg_nfrees: number of free entries in block group 431 * @pg_nfrees: number of free entries in block group
408 */ 432 */