aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2')
-rw-r--r--fs/nilfs2/alloc.c109
-rw-r--r--fs/nilfs2/alloc.h23
-rw-r--r--fs/nilfs2/bmap.c12
-rw-r--r--fs/nilfs2/btnode.c77
-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.c57
-rw-r--r--fs/nilfs2/cpfile.h3
-rw-r--r--fs/nilfs2/dat.c52
-rw-r--r--fs/nilfs2/dat.h3
-rw-r--r--fs/nilfs2/dir.c40
-rw-r--r--fs/nilfs2/direct.c17
-rw-r--r--fs/nilfs2/gcdat.c3
-rw-r--r--fs/nilfs2/gcinode.c11
-rw-r--r--fs/nilfs2/ifile.c35
-rw-r--r--fs/nilfs2/ifile.h2
-rw-r--r--fs/nilfs2/inode.c8
-rw-r--r--fs/nilfs2/ioctl.c69
-rw-r--r--fs/nilfs2/mdt.c57
-rw-r--r--fs/nilfs2/mdt.h25
-rw-r--r--fs/nilfs2/namei.c96
-rw-r--r--fs/nilfs2/nilfs.h4
-rw-r--r--fs/nilfs2/page.c5
-rw-r--r--fs/nilfs2/recovery.c76
-rw-r--r--fs/nilfs2/segbuf.c208
-rw-r--r--fs/nilfs2/segbuf.h51
-rw-r--r--fs/nilfs2/segment.c501
-rw-r--r--fs/nilfs2/segment.h8
-rw-r--r--fs/nilfs2/sufile.c205
-rw-r--r--fs/nilfs2/sufile.h14
-rw-r--r--fs/nilfs2/super.c110
-rw-r--r--fs/nilfs2/the_nilfs.c195
-rw-r--r--fs/nilfs2/the_nilfs.h14
34 files changed, 1263 insertions, 961 deletions
diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c
index d69e6ae59251..8d6356a804f3 100644
--- a/fs/nilfs2/alloc.c
+++ b/fs/nilfs2/alloc.c
@@ -26,6 +26,7 @@
26#include <linux/buffer_head.h> 26#include <linux/buffer_head.h>
27#include <linux/fs.h> 27#include <linux/fs.h>
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/slab.h>
29#include "mdt.h" 30#include "mdt.h"
30#include "alloc.h" 31#include "alloc.h"
31 32
@@ -142,29 +143,75 @@ static void nilfs_palloc_desc_block_init(struct inode *inode,
142 } 143 }
143} 144}
144 145
146static int nilfs_palloc_get_block(struct inode *inode, unsigned long blkoff,
147 int create,
148 void (*init_block)(struct inode *,
149 struct buffer_head *,
150 void *),
151 struct buffer_head **bhp,
152 struct nilfs_bh_assoc *prev,
153 spinlock_t *lock)
154{
155 int ret;
156
157 spin_lock(lock);
158 if (prev->bh && blkoff == prev->blkoff) {
159 get_bh(prev->bh);
160 *bhp = prev->bh;
161 spin_unlock(lock);
162 return 0;
163 }
164 spin_unlock(lock);
165
166 ret = nilfs_mdt_get_block(inode, blkoff, create, init_block, bhp);
167 if (!ret) {
168 spin_lock(lock);
169 /*
170 * The following code must be safe for change of the
171 * cache contents during the get block call.
172 */
173 brelse(prev->bh);
174 get_bh(*bhp);
175 prev->bh = *bhp;
176 prev->blkoff = blkoff;
177 spin_unlock(lock);
178 }
179 return ret;
180}
181
145static int nilfs_palloc_get_desc_block(struct inode *inode, 182static int nilfs_palloc_get_desc_block(struct inode *inode,
146 unsigned long group, 183 unsigned long group,
147 int create, struct buffer_head **bhp) 184 int create, struct buffer_head **bhp)
148{ 185{
149 return nilfs_mdt_get_block(inode, 186 struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
150 nilfs_palloc_desc_blkoff(inode, group), 187
151 create, nilfs_palloc_desc_block_init, bhp); 188 return nilfs_palloc_get_block(inode,
189 nilfs_palloc_desc_blkoff(inode, group),
190 create, nilfs_palloc_desc_block_init,
191 bhp, &cache->prev_desc, &cache->lock);
152} 192}
153 193
154static int nilfs_palloc_get_bitmap_block(struct inode *inode, 194static int nilfs_palloc_get_bitmap_block(struct inode *inode,
155 unsigned long group, 195 unsigned long group,
156 int create, struct buffer_head **bhp) 196 int create, struct buffer_head **bhp)
157{ 197{
158 return nilfs_mdt_get_block(inode, 198 struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
159 nilfs_palloc_bitmap_blkoff(inode, group), 199
160 create, NULL, bhp); 200 return nilfs_palloc_get_block(inode,
201 nilfs_palloc_bitmap_blkoff(inode, group),
202 create, NULL, bhp,
203 &cache->prev_bitmap, &cache->lock);
161} 204}
162 205
163int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr, 206int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr,
164 int create, struct buffer_head **bhp) 207 int create, struct buffer_head **bhp)
165{ 208{
166 return nilfs_mdt_get_block(inode, nilfs_palloc_entry_blkoff(inode, nr), 209 struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
167 create, NULL, bhp); 210
211 return nilfs_palloc_get_block(inode,
212 nilfs_palloc_entry_blkoff(inode, nr),
213 create, NULL, bhp,
214 &cache->prev_entry, &cache->lock);
168} 215}
169 216
170static struct nilfs_palloc_group_desc * 217static struct nilfs_palloc_group_desc *
@@ -176,13 +223,6 @@ nilfs_palloc_block_get_group_desc(const struct inode *inode,
176 group % nilfs_palloc_groups_per_desc_block(inode); 223 group % nilfs_palloc_groups_per_desc_block(inode);
177} 224}
178 225
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, 226void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr,
187 const struct buffer_head *bh, void *kaddr) 227 const struct buffer_head *bh, void *kaddr)
188{ 228{
@@ -289,8 +329,7 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode,
289 if (ret < 0) 329 if (ret < 0)
290 goto out_desc; 330 goto out_desc;
291 bitmap_kaddr = kmap(bitmap_bh->b_page); 331 bitmap_kaddr = kmap(bitmap_bh->b_page);
292 bitmap = nilfs_palloc_block_get_bitmap( 332 bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
293 inode, bitmap_bh, bitmap_kaddr);
294 pos = nilfs_palloc_find_available_slot( 333 pos = nilfs_palloc_find_available_slot(
295 inode, group, group_offset, bitmap, 334 inode, group, group_offset, bitmap,
296 entries_per_group); 335 entries_per_group);
@@ -351,8 +390,7 @@ void nilfs_palloc_commit_free_entry(struct inode *inode,
351 desc = nilfs_palloc_block_get_group_desc(inode, group, 390 desc = nilfs_palloc_block_get_group_desc(inode, group,
352 req->pr_desc_bh, desc_kaddr); 391 req->pr_desc_bh, desc_kaddr);
353 bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page); 392 bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page);
354 bitmap = nilfs_palloc_block_get_bitmap(inode, req->pr_bitmap_bh, 393 bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
355 bitmap_kaddr);
356 394
357 if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group), 395 if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group),
358 group_offset, bitmap)) 396 group_offset, bitmap))
@@ -385,8 +423,7 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode,
385 desc = nilfs_palloc_block_get_group_desc(inode, group, 423 desc = nilfs_palloc_block_get_group_desc(inode, group,
386 req->pr_desc_bh, desc_kaddr); 424 req->pr_desc_bh, desc_kaddr);
387 bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page); 425 bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page);
388 bitmap = nilfs_palloc_block_get_bitmap(inode, req->pr_bitmap_bh, 426 bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
389 bitmap_kaddr);
390 if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group), 427 if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group),
391 group_offset, bitmap)) 428 group_offset, bitmap))
392 printk(KERN_WARNING "%s: entry numer %llu already freed\n", 429 printk(KERN_WARNING "%s: entry numer %llu already freed\n",
@@ -472,8 +509,7 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
472 desc = nilfs_palloc_block_get_group_desc( 509 desc = nilfs_palloc_block_get_group_desc(
473 inode, group, desc_bh, desc_kaddr); 510 inode, group, desc_bh, desc_kaddr);
474 bitmap_kaddr = kmap(bitmap_bh->b_page); 511 bitmap_kaddr = kmap(bitmap_bh->b_page);
475 bitmap = nilfs_palloc_block_get_bitmap( 512 bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
476 inode, bitmap_bh, bitmap_kaddr);
477 for (j = i, n = 0; 513 for (j = i, n = 0;
478 (j < nitems) && nilfs_palloc_group_is_in(inode, group, 514 (j < nitems) && nilfs_palloc_group_is_in(inode, group,
479 entry_nrs[j]); 515 entry_nrs[j]);
@@ -502,3 +538,30 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
502 } 538 }
503 return 0; 539 return 0;
504} 540}
541
542void nilfs_palloc_setup_cache(struct inode *inode,
543 struct nilfs_palloc_cache *cache)
544{
545 NILFS_MDT(inode)->mi_palloc_cache = cache;
546 spin_lock_init(&cache->lock);
547}
548
549void nilfs_palloc_clear_cache(struct inode *inode)
550{
551 struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
552
553 spin_lock(&cache->lock);
554 brelse(cache->prev_desc.bh);
555 brelse(cache->prev_bitmap.bh);
556 brelse(cache->prev_entry.bh);
557 cache->prev_desc.bh = NULL;
558 cache->prev_bitmap.bh = NULL;
559 cache->prev_entry.bh = NULL;
560 spin_unlock(&cache->lock);
561}
562
563void nilfs_palloc_destroy_cache(struct inode *inode)
564{
565 nilfs_palloc_clear_cache(inode);
566 NILFS_MDT(inode)->mi_palloc_cache = NULL;
567}
diff --git a/fs/nilfs2/alloc.h b/fs/nilfs2/alloc.h
index 4ace5475c2c7..5cccf874d692 100644
--- a/fs/nilfs2/alloc.h
+++ b/fs/nilfs2/alloc.h
@@ -42,7 +42,7 @@ void *nilfs_palloc_block_get_entry(const struct inode *, __u64,
42 const struct buffer_head *, void *); 42 const struct buffer_head *, void *);
43 43
44/** 44/**
45 * nilfs_palloc_req - persistent alloctor request and reply 45 * nilfs_palloc_req - persistent allocator request and reply
46 * @pr_entry_nr: entry number (vblocknr or inode number) 46 * @pr_entry_nr: entry number (vblocknr or inode number)
47 * @pr_desc_bh: buffer head of the buffer containing block group descriptors 47 * @pr_desc_bh: buffer head of the buffer containing block group descriptors
48 * @pr_bitmap_bh: buffer head of the buffer containing a block group bitmap 48 * @pr_bitmap_bh: buffer head of the buffer containing a block group bitmap
@@ -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..effdbdbe6c11 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,
@@ -425,8 +417,8 @@ __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *bmap,
425 417
426 key = page_index(bh->b_page) << (PAGE_CACHE_SHIFT - 418 key = page_index(bh->b_page) << (PAGE_CACHE_SHIFT -
427 bmap->b_inode->i_blkbits); 419 bmap->b_inode->i_blkbits);
428 for (pbh = page_buffers(bh->b_page); pbh != bh; 420 for (pbh = page_buffers(bh->b_page); pbh != bh; pbh = pbh->b_this_page)
429 pbh = pbh->b_this_page, key++); 421 key++;
430 422
431 return key; 423 return key;
432} 424}
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index 84c25382f8e3..447ce47a3306 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -27,6 +27,7 @@
27#include <linux/buffer_head.h> 27#include <linux/buffer_head.h>
28#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/backing-dev.h> 29#include <linux/backing-dev.h>
30#include <linux/gfp.h>
30#include "nilfs.h" 31#include "nilfs.h"
31#include "mdt.h" 32#include "mdt.h"
32#include "dat.h" 33#include "dat.h"
@@ -68,9 +69,34 @@ void nilfs_btnode_cache_clear(struct address_space *btnc)
68 truncate_inode_pages(btnc, 0); 69 truncate_inode_pages(btnc, 0);
69} 70}
70 71
72struct buffer_head *
73nilfs_btnode_create_block(struct address_space *btnc, __u64 blocknr)
74{
75 struct inode *inode = NILFS_BTNC_I(btnc);
76 struct buffer_head *bh;
77
78 bh = nilfs_grab_buffer(inode, btnc, blocknr, 1 << BH_NILFS_Node);
79 if (unlikely(!bh))
80 return NULL;
81
82 if (unlikely(buffer_mapped(bh) || buffer_uptodate(bh) ||
83 buffer_dirty(bh))) {
84 brelse(bh);
85 BUG();
86 }
87 memset(bh->b_data, 0, 1 << inode->i_blkbits);
88 bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev;
89 bh->b_blocknr = blocknr;
90 set_buffer_mapped(bh);
91 set_buffer_uptodate(bh);
92
93 unlock_page(bh->b_page);
94 page_cache_release(bh->b_page);
95 return bh;
96}
97
71int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr, 98int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
72 sector_t pblocknr, struct buffer_head **pbh, 99 sector_t pblocknr, struct buffer_head **pbh)
73 int newblk)
74{ 100{
75 struct buffer_head *bh; 101 struct buffer_head *bh;
76 struct inode *inode = NILFS_BTNC_I(btnc); 102 struct inode *inode = NILFS_BTNC_I(btnc);
@@ -81,19 +107,6 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
81 return -ENOMEM; 107 return -ENOMEM;
82 108
83 err = -EEXIST; /* internal code */ 109 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 110
98 if (buffer_uptodate(bh) || buffer_dirty(bh)) 111 if (buffer_uptodate(bh) || buffer_dirty(bh))
99 goto found; 112 goto found;
@@ -135,27 +148,6 @@ out_locked:
135 return err; 148 return err;
136} 149}
137 150
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/** 151/**
160 * nilfs_btnode_delete - delete B-tree node buffer 152 * nilfs_btnode_delete - delete B-tree node buffer
161 * @bh: buffer to be deleted 153 * @bh: buffer to be deleted
@@ -244,12 +236,13 @@ retry:
244 unlock_page(obh->b_page); 236 unlock_page(obh->b_page);
245 } 237 }
246 238
247 err = nilfs_btnode_get(btnc, newkey, 0, &nbh, 1); 239 nbh = nilfs_btnode_create_block(btnc, newkey);
248 if (likely(!err)) { 240 if (!nbh)
249 BUG_ON(nbh == obh); 241 return -ENOMEM;
250 ctxt->newbh = nbh; 242
251 } 243 BUG_ON(nbh == obh);
252 return err; 244 ctxt->newbh = nbh;
245 return 0;
253 246
254 failed_unlock: 247 failed_unlock:
255 unlock_page(obh->b_page); 248 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..18737818db63 100644
--- a/fs/nilfs2/cpfile.c
+++ b/fs/nilfs2/cpfile.c
@@ -328,19 +328,24 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile,
328 tnicps += nicps; 328 tnicps += nicps;
329 nilfs_mdt_mark_buffer_dirty(cp_bh); 329 nilfs_mdt_mark_buffer_dirty(cp_bh);
330 nilfs_mdt_mark_dirty(cpfile); 330 nilfs_mdt_mark_dirty(cpfile);
331 if (!nilfs_cpfile_is_in_first(cpfile, cno) && 331 if (!nilfs_cpfile_is_in_first(cpfile, cno)) {
332 (count = nilfs_cpfile_block_sub_valid_checkpoints( 332 count =
333 cpfile, cp_bh, kaddr, nicps)) == 0) { 333 nilfs_cpfile_block_sub_valid_checkpoints(
334 /* make hole */ 334 cpfile, cp_bh, kaddr, nicps);
335 kunmap_atomic(kaddr, KM_USER0); 335 if (count == 0) {
336 brelse(cp_bh); 336 /* make hole */
337 ret = nilfs_cpfile_delete_checkpoint_block( 337 kunmap_atomic(kaddr, KM_USER0);
338 cpfile, cno); 338 brelse(cp_bh);
339 if (ret == 0) 339 ret =
340 continue; 340 nilfs_cpfile_delete_checkpoint_block(
341 printk(KERN_ERR "%s: cannot delete block\n", 341 cpfile, cno);
342 __func__); 342 if (ret == 0)
343 break; 343 continue;
344 printk(KERN_ERR
345 "%s: cannot delete block\n",
346 __func__);
347 break;
348 }
344 } 349 }
345 } 350 }
346 351
@@ -926,3 +931,29 @@ int nilfs_cpfile_get_stat(struct inode *cpfile, struct nilfs_cpstat *cpstat)
926 up_read(&NILFS_MDT(cpfile)->mi_sem); 931 up_read(&NILFS_MDT(cpfile)->mi_sem);
927 return ret; 932 return ret;
928} 933}
934
935/**
936 * nilfs_cpfile_read - read cpfile inode
937 * @cpfile: cpfile inode
938 * @raw_inode: on-disk cpfile inode
939 */
940int nilfs_cpfile_read(struct inode *cpfile, struct nilfs_inode *raw_inode)
941{
942 return nilfs_read_inode_common(cpfile, raw_inode);
943}
944
945/**
946 * nilfs_cpfile_new - create cpfile
947 * @nilfs: nilfs object
948 * @cpsize: size of a checkpoint entry
949 */
950struct inode *nilfs_cpfile_new(struct the_nilfs *nilfs, size_t cpsize)
951{
952 struct inode *cpfile;
953
954 cpfile = nilfs_mdt_new(nilfs, NULL, NILFS_CPFILE_INO, 0);
955 if (cpfile)
956 nilfs_mdt_set_entry_size(cpfile, cpsize,
957 sizeof(struct nilfs_cpfile_header));
958 return cpfile;
959}
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..013146755683 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{
@@ -278,7 +288,7 @@ int nilfs_dat_mark_dirty(struct inode *dat, __u64 vblocknr)
278 * @vblocknrs and @nitems. 288 * @vblocknrs and @nitems.
279 * 289 *
280 * Return Value: On success, 0 is returned. On error, one of the following 290 * Return Value: On success, 0 is returned. On error, one of the following
281 * nagative error codes is returned. 291 * negative error codes is returned.
282 * 292 *
283 * %-EIO - I/O error. 293 * %-EIO - I/O error.
284 * 294 *
@@ -378,8 +388,7 @@ int nilfs_dat_translate(struct inode *dat, __u64 vblocknr, sector_t *blocknrp)
378 ret = -ENOENT; 388 ret = -ENOENT;
379 goto out; 389 goto out;
380 } 390 }
381 if (blocknrp != NULL) 391 *blocknrp = blocknr;
382 *blocknrp = blocknr;
383 392
384 out: 393 out:
385 kunmap_atomic(kaddr, KM_USER0); 394 kunmap_atomic(kaddr, KM_USER0);
@@ -425,3 +434,40 @@ ssize_t nilfs_dat_get_vinfo(struct inode *dat, void *buf, unsigned visz,
425 434
426 return nvi; 435 return nvi;
427} 436}
437
438/**
439 * nilfs_dat_read - read dat inode
440 * @dat: dat inode
441 * @raw_inode: on-disk dat inode
442 */
443int nilfs_dat_read(struct inode *dat, struct nilfs_inode *raw_inode)
444{
445 return nilfs_read_inode_common(dat, raw_inode);
446}
447
448/**
449 * nilfs_dat_new - create dat file
450 * @nilfs: nilfs object
451 * @entry_size: size of a dat entry
452 */
453struct inode *nilfs_dat_new(struct the_nilfs *nilfs, size_t entry_size)
454{
455 static struct lock_class_key dat_lock_key;
456 struct inode *dat;
457 struct nilfs_dat_info *di;
458 int err;
459
460 dat = nilfs_mdt_new(nilfs, NULL, NILFS_DAT_INO, sizeof(*di));
461 if (dat) {
462 err = nilfs_palloc_init_blockgroup(dat, entry_size);
463 if (unlikely(err)) {
464 nilfs_mdt_destroy(dat);
465 return NULL;
466 }
467
468 di = NILFS_DAT_I(dat);
469 lockdep_set_class(&di->mi.mi_sem, &dat_lock_key);
470 nilfs_palloc_setup_cache(dat, &di->palloc_cache);
471 }
472 return dat;
473}
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..85c89dfc71f0 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)
@@ -226,7 +224,7 @@ fail:
226 * len <= NILFS_NAME_LEN and de != NULL are guaranteed by caller. 224 * len <= NILFS_NAME_LEN and de != NULL are guaranteed by caller.
227 */ 225 */
228static int 226static int
229nilfs_match(int len, const char * const name, struct nilfs_dir_entry *de) 227nilfs_match(int len, const unsigned char *name, struct nilfs_dir_entry *de)
230{ 228{
231 if (len != de->name_len) 229 if (len != de->name_len)
232 return 0; 230 return 0;
@@ -351,11 +349,11 @@ done:
351 * Entry is guaranteed to be valid. 349 * Entry is guaranteed to be valid.
352 */ 350 */
353struct nilfs_dir_entry * 351struct nilfs_dir_entry *
354nilfs_find_entry(struct inode *dir, struct dentry *dentry, 352nilfs_find_entry(struct inode *dir, const struct qstr *qstr,
355 struct page **res_page) 353 struct page **res_page)
356{ 354{
357 const char *name = dentry->d_name.name; 355 const unsigned char *name = qstr->name;
358 int namelen = dentry->d_name.len; 356 int namelen = qstr->len;
359 unsigned reclen = NILFS_DIR_REC_LEN(namelen); 357 unsigned reclen = NILFS_DIR_REC_LEN(namelen);
360 unsigned long start, n; 358 unsigned long start, n;
361 unsigned long npages = dir_pages(dir); 359 unsigned long npages = dir_pages(dir);
@@ -398,7 +396,7 @@ nilfs_find_entry(struct inode *dir, struct dentry *dentry,
398 /* next page is past the blocks we've got */ 396 /* next page is past the blocks we've got */
399 if (unlikely(n > (dir->i_blocks >> (PAGE_CACHE_SHIFT - 9)))) { 397 if (unlikely(n > (dir->i_blocks >> (PAGE_CACHE_SHIFT - 9)))) {
400 nilfs_error(dir->i_sb, __func__, 398 nilfs_error(dir->i_sb, __func__,
401 "dir %lu size %lld exceeds block cout %llu", 399 "dir %lu size %lld exceeds block count %llu",
402 dir->i_ino, dir->i_size, 400 dir->i_ino, dir->i_size,
403 (unsigned long long)dir->i_blocks); 401 (unsigned long long)dir->i_blocks);
404 goto out; 402 goto out;
@@ -426,13 +424,13 @@ struct nilfs_dir_entry *nilfs_dotdot(struct inode *dir, struct page **p)
426 return de; 424 return de;
427} 425}
428 426
429ino_t nilfs_inode_by_name(struct inode *dir, struct dentry *dentry) 427ino_t nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr)
430{ 428{
431 ino_t res = 0; 429 ino_t res = 0;
432 struct nilfs_dir_entry *de; 430 struct nilfs_dir_entry *de;
433 struct page *page; 431 struct page *page;
434 432
435 de = nilfs_find_entry(dir, dentry, &page); 433 de = nilfs_find_entry(dir, qstr, &page);
436 if (de) { 434 if (de) {
437 res = le64_to_cpu(de->inode); 435 res = le64_to_cpu(de->inode);
438 kunmap(page); 436 kunmap(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/*
@@ -468,7 +465,7 @@ void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de,
468int nilfs_add_link(struct dentry *dentry, struct inode *inode) 465int nilfs_add_link(struct dentry *dentry, struct inode *inode)
469{ 466{
470 struct inode *dir = dentry->d_parent->d_inode; 467 struct inode *dir = dentry->d_parent->d_inode;
471 const char *name = dentry->d_name.name; 468 const unsigned char *name = dentry->d_name.name;
472 int namelen = dentry->d_name.len; 469 int namelen = dentry->d_name.len;
473 unsigned chunk_size = nilfs_chunk_size(dir); 470 unsigned chunk_size = nilfs_chunk_size(dir);
474 unsigned reclen = NILFS_DIR_REC_LEN(namelen); 471 unsigned reclen = NILFS_DIR_REC_LEN(namelen);
@@ -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/direct.c b/fs/nilfs2/direct.c
index d369ac718277..236753df5cdf 100644
--- a/fs/nilfs2/direct.c
+++ b/fs/nilfs2/direct.c
@@ -51,11 +51,11 @@ static int nilfs_direct_lookup(const struct nilfs_bmap *bmap,
51 struct nilfs_direct *direct; 51 struct nilfs_direct *direct;
52 __u64 ptr; 52 __u64 ptr;
53 53
54 direct = (struct nilfs_direct *)bmap; 54 direct = (struct nilfs_direct *)bmap; /* XXX: use macro for level 1 */
55 if ((key > NILFS_DIRECT_KEY_MAX) || 55 if (key > NILFS_DIRECT_KEY_MAX || level != 1)
56 (level != 1) || /* XXX: use macro for level 1 */ 56 return -ENOENT;
57 ((ptr = nilfs_direct_get_ptr(direct, key)) == 57 ptr = nilfs_direct_get_ptr(direct, key);
58 NILFS_BMAP_INVALID_PTR)) 58 if (ptr == NILFS_BMAP_INVALID_PTR)
59 return -ENOENT; 59 return -ENOENT;
60 60
61 if (ptrp != NULL) 61 if (ptrp != NULL)
@@ -73,9 +73,10 @@ static int nilfs_direct_lookup_contig(const struct nilfs_bmap *bmap,
73 sector_t blocknr; 73 sector_t blocknr;
74 int ret, cnt; 74 int ret, cnt;
75 75
76 if (key > NILFS_DIRECT_KEY_MAX || 76 if (key > NILFS_DIRECT_KEY_MAX)
77 (ptr = nilfs_direct_get_ptr(direct, key)) == 77 return -ENOENT;
78 NILFS_BMAP_INVALID_PTR) 78 ptr = nilfs_direct_get_ptr(direct, key);
79 if (ptr == NILFS_BMAP_INVALID_PTR)
79 return -ENOENT; 80 return -ENOENT;
80 81
81 if (NILFS_BMAP_USE_VBN(bmap)) { 82 if (NILFS_BMAP_USE_VBN(bmap)) {
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..145f03cd7d3e 100644
--- a/fs/nilfs2/gcinode.c
+++ b/fs/nilfs2/gcinode.c
@@ -28,10 +28,10 @@
28 * gcinodes), and this file provides lookup function of the dummy 28 * gcinodes), and this file provides lookup function of the dummy
29 * inodes and their buffer read function. 29 * inodes and their buffer read function.
30 * 30 *
31 * Since NILFS2 keeps up multiple checkpoints/snapshots accross GC, it 31 * Since NILFS2 keeps up multiple checkpoints/snapshots across GC, it
32 * has to treat blocks that belong to a same file but have different 32 * has to treat blocks that belong to a same file but have different
33 * checkpoint numbers. To avoid interference among generations, dummy 33 * checkpoint numbers. To avoid interference among generations, dummy
34 * inodes are managed separatly from actual inodes, and their lookup 34 * inodes are managed separately from actual inodes, and their lookup
35 * function (nilfs_gc_iget) is designed to be specified with a 35 * function (nilfs_gc_iget) is designed to be specified with a
36 * checkpoint number argument as well as an inode number. 36 * checkpoint number argument as well as an inode number.
37 * 37 *
@@ -45,6 +45,7 @@
45#include <linux/buffer_head.h> 45#include <linux/buffer_head.h>
46#include <linux/mpage.h> 46#include <linux/mpage.h>
47#include <linux/hash.h> 47#include <linux/hash.h>
48#include <linux/slab.h>
48#include <linux/swap.h> 49#include <linux/swap.h>
49#include "nilfs.h" 50#include "nilfs.h"
50#include "page.h" 51#include "page.h"
@@ -149,7 +150,7 @@ int nilfs_gccache_submit_read_node(struct inode *inode, sector_t pbn,
149 __u64 vbn, struct buffer_head **out_bh) 150 __u64 vbn, struct buffer_head **out_bh)
150{ 151{
151 int ret = nilfs_btnode_submit_block(&NILFS_I(inode)->i_btnode_cache, 152 int ret = nilfs_btnode_submit_block(&NILFS_I(inode)->i_btnode_cache,
152 vbn ? : pbn, pbn, out_bh, 0); 153 vbn ? : pbn, pbn, out_bh);
153 if (ret == -EEXIST) /* internal code (cache hit) */ 154 if (ret == -EEXIST) /* internal code (cache hit) */
154 ret = 0; 155 ret = 0;
155 return ret; 156 return ret;
@@ -212,9 +213,10 @@ void nilfs_destroy_gccache(struct the_nilfs *nilfs)
212static struct inode *alloc_gcinode(struct the_nilfs *nilfs, ino_t ino, 213static struct inode *alloc_gcinode(struct the_nilfs *nilfs, ino_t ino,
213 __u64 cno) 214 __u64 cno)
214{ 215{
215 struct inode *inode = nilfs_mdt_new_common(nilfs, NULL, ino, GFP_NOFS); 216 struct inode *inode;
216 struct nilfs_inode_info *ii; 217 struct nilfs_inode_info *ii;
217 218
219 inode = nilfs_mdt_new_common(nilfs, NULL, ino, GFP_NOFS, 0);
218 if (!inode) 220 if (!inode)
219 return NULL; 221 return NULL;
220 222
@@ -265,7 +267,6 @@ struct inode *nilfs_gc_iget(struct the_nilfs *nilfs, ino_t ino, __u64 cno)
265 */ 267 */
266void nilfs_clear_gcinode(struct inode *inode) 268void nilfs_clear_gcinode(struct inode *inode)
267{ 269{
268 nilfs_mdt_clear(inode);
269 nilfs_mdt_destroy(inode); 270 nilfs_mdt_destroy(inode);
270} 271}
271 272
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..0957b58f909d 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include <linux/buffer_head.h> 24#include <linux/buffer_head.h>
25#include <linux/gfp.h>
25#include <linux/mpage.h> 26#include <linux/mpage.h>
26#include <linux/writeback.h> 27#include <linux/writeback.h>
27#include <linux/uio.h> 28#include <linux/uio.h>
@@ -97,6 +98,7 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff,
97 nilfs_transaction_abort(inode->i_sb); 98 nilfs_transaction_abort(inode->i_sb);
98 goto out; 99 goto out;
99 } 100 }
101 nilfs_mark_inode_dirty(inode);
100 nilfs_transaction_commit(inode->i_sb); /* never fails */ 102 nilfs_transaction_commit(inode->i_sb); /* never fails */
101 /* Error handling should be detailed */ 103 /* Error handling should be detailed */
102 set_buffer_new(bh_result); 104 set_buffer_new(bh_result);
@@ -322,7 +324,6 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode)
322 nilfs_init_acl(), proper cancellation of 324 nilfs_init_acl(), proper cancellation of
323 above jobs should be considered */ 325 above jobs should be considered */
324 326
325 mark_inode_dirty(inode);
326 return inode; 327 return inode;
327 328
328 failed_acl: 329 failed_acl:
@@ -525,7 +526,6 @@ void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh)
525 526
526 raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, ibh); 527 raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, ibh);
527 528
528 /* The buffer is guarded with lock_buffer() by the caller */
529 if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state)) 529 if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state))
530 memset(raw_inode, 0, NILFS_MDT(sbi->s_ifile)->mi_entry_size); 530 memset(raw_inode, 0, NILFS_MDT(sbi->s_ifile)->mi_entry_size);
531 set_bit(NILFS_I_INODE_DIRTY, &ii->i_state); 531 set_bit(NILFS_I_INODE_DIRTY, &ii->i_state);
@@ -599,6 +599,7 @@ void nilfs_truncate(struct inode *inode)
599 if (IS_SYNC(inode)) 599 if (IS_SYNC(inode))
600 nilfs_set_transaction_flag(NILFS_TI_SYNC); 600 nilfs_set_transaction_flag(NILFS_TI_SYNC);
601 601
602 nilfs_mark_inode_dirty(inode);
602 nilfs_set_file_dirty(NILFS_SB(sb), inode, 0); 603 nilfs_set_file_dirty(NILFS_SB(sb), inode, 0);
603 nilfs_transaction_commit(sb); 604 nilfs_transaction_commit(sb);
604 /* May construct a logical segment and may fail in sync mode. 605 /* May construct a logical segment and may fail in sync mode.
@@ -623,6 +624,7 @@ void nilfs_delete_inode(struct inode *inode)
623 truncate_inode_pages(&inode->i_data, 0); 624 truncate_inode_pages(&inode->i_data, 0);
624 625
625 nilfs_truncate_bmap(ii, 0); 626 nilfs_truncate_bmap(ii, 0);
627 nilfs_mark_inode_dirty(inode);
626 nilfs_free_inode(inode); 628 nilfs_free_inode(inode);
627 /* nilfs_free_inode() marks inode buffer dirty */ 629 /* nilfs_free_inode() marks inode buffer dirty */
628 if (IS_SYNC(inode)) 630 if (IS_SYNC(inode))
@@ -745,9 +747,7 @@ int nilfs_mark_inode_dirty(struct inode *inode)
745 "failed to reget inode block.\n"); 747 "failed to reget inode block.\n");
746 return err; 748 return err;
747 } 749 }
748 lock_buffer(ibh);
749 nilfs_update_inode(inode, ibh); 750 nilfs_update_inode(inode, ibh);
750 unlock_buffer(ibh);
751 nilfs_mdt_mark_buffer_dirty(ibh); 751 nilfs_mdt_mark_buffer_dirty(ibh);
752 nilfs_mdt_mark_dirty(sbi->s_ifile); 752 nilfs_mdt_mark_dirty(sbi->s_ifile);
753 brelse(ibh); 753 brelse(ibh);
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
index f6af76042d80..c2ff1b306012 100644
--- a/fs/nilfs2/ioctl.c
+++ b/fs/nilfs2/ioctl.c
@@ -23,9 +23,11 @@
23#include <linux/fs.h> 23#include <linux/fs.h>
24#include <linux/wait.h> 24#include <linux/wait.h>
25#include <linux/smp_lock.h> /* lock_kernel(), unlock_kernel() */ 25#include <linux/smp_lock.h> /* lock_kernel(), unlock_kernel() */
26#include <linux/slab.h>
26#include <linux/capability.h> /* capable() */ 27#include <linux/capability.h> /* capable() */
27#include <linux/uaccess.h> /* copy_from_user(), copy_to_user() */ 28#include <linux/uaccess.h> /* copy_from_user(), copy_to_user() */
28#include <linux/vmalloc.h> 29#include <linux/vmalloc.h>
30#include <linux/mount.h> /* mnt_want_write(), mnt_drop_write() */
29#include <linux/nilfs2_fs.h> 31#include <linux/nilfs2_fs.h>
30#include "nilfs.h" 32#include "nilfs.h"
31#include "segment.h" 33#include "segment.h"
@@ -107,20 +109,28 @@ static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
107 109
108 if (!capable(CAP_SYS_ADMIN)) 110 if (!capable(CAP_SYS_ADMIN))
109 return -EPERM; 111 return -EPERM;
112
113 ret = mnt_want_write(filp->f_path.mnt);
114 if (ret)
115 return ret;
116
117 ret = -EFAULT;
110 if (copy_from_user(&cpmode, argp, sizeof(cpmode))) 118 if (copy_from_user(&cpmode, argp, sizeof(cpmode)))
111 return -EFAULT; 119 goto out;
112 120
113 mutex_lock(&nilfs->ns_mount_mutex); 121 mutex_lock(&nilfs->ns_mount_mutex);
122
114 nilfs_transaction_begin(inode->i_sb, &ti, 0); 123 nilfs_transaction_begin(inode->i_sb, &ti, 0);
115 ret = nilfs_cpfile_change_cpmode( 124 ret = nilfs_cpfile_change_cpmode(
116 cpfile, cpmode.cm_cno, cpmode.cm_mode); 125 cpfile, cpmode.cm_cno, cpmode.cm_mode);
117 if (unlikely(ret < 0)) { 126 if (unlikely(ret < 0))
118 nilfs_transaction_abort(inode->i_sb); 127 nilfs_transaction_abort(inode->i_sb);
119 mutex_unlock(&nilfs->ns_mount_mutex); 128 else
120 return ret; 129 nilfs_transaction_commit(inode->i_sb); /* never fails */
121 } 130
122 nilfs_transaction_commit(inode->i_sb); /* never fails */
123 mutex_unlock(&nilfs->ns_mount_mutex); 131 mutex_unlock(&nilfs->ns_mount_mutex);
132out:
133 mnt_drop_write(filp->f_path.mnt);
124 return ret; 134 return ret;
125} 135}
126 136
@@ -135,16 +145,23 @@ nilfs_ioctl_delete_checkpoint(struct inode *inode, struct file *filp,
135 145
136 if (!capable(CAP_SYS_ADMIN)) 146 if (!capable(CAP_SYS_ADMIN))
137 return -EPERM; 147 return -EPERM;
148
149 ret = mnt_want_write(filp->f_path.mnt);
150 if (ret)
151 return ret;
152
153 ret = -EFAULT;
138 if (copy_from_user(&cno, argp, sizeof(cno))) 154 if (copy_from_user(&cno, argp, sizeof(cno)))
139 return -EFAULT; 155 goto out;
140 156
141 nilfs_transaction_begin(inode->i_sb, &ti, 0); 157 nilfs_transaction_begin(inode->i_sb, &ti, 0);
142 ret = nilfs_cpfile_delete_checkpoint(cpfile, cno); 158 ret = nilfs_cpfile_delete_checkpoint(cpfile, cno);
143 if (unlikely(ret < 0)) { 159 if (unlikely(ret < 0))
144 nilfs_transaction_abort(inode->i_sb); 160 nilfs_transaction_abort(inode->i_sb);
145 return ret; 161 else
146 } 162 nilfs_transaction_commit(inode->i_sb); /* never fails */
147 nilfs_transaction_commit(inode->i_sb); /* never fails */ 163out:
164 mnt_drop_write(filp->f_path.mnt);
148 return ret; 165 return ret;
149} 166}
150 167
@@ -480,7 +497,7 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
480 unsigned int cmd, void __user *argp) 497 unsigned int cmd, void __user *argp)
481{ 498{
482 struct nilfs_argv argv[5]; 499 struct nilfs_argv argv[5];
483 const static size_t argsz[5] = { 500 static const size_t argsz[5] = {
484 sizeof(struct nilfs_vdesc), 501 sizeof(struct nilfs_vdesc),
485 sizeof(struct nilfs_period), 502 sizeof(struct nilfs_period),
486 sizeof(__u64), 503 sizeof(__u64),
@@ -496,12 +513,19 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
496 if (!capable(CAP_SYS_ADMIN)) 513 if (!capable(CAP_SYS_ADMIN))
497 return -EPERM; 514 return -EPERM;
498 515
516 ret = mnt_want_write(filp->f_path.mnt);
517 if (ret)
518 return ret;
519
520 ret = -EFAULT;
499 if (copy_from_user(argv, argp, sizeof(argv))) 521 if (copy_from_user(argv, argp, sizeof(argv)))
500 return -EFAULT; 522 goto out;
501 523
524 ret = -EINVAL;
502 nsegs = argv[4].v_nmembs; 525 nsegs = argv[4].v_nmembs;
503 if (argv[4].v_size != argsz[4]) 526 if (argv[4].v_size != argsz[4])
504 return -EINVAL; 527 goto out;
528
505 /* 529 /*
506 * argv[4] points to segment numbers this ioctl cleans. We 530 * argv[4] points to segment numbers this ioctl cleans. We
507 * use kmalloc() for its buffer because memory used for the 531 * use kmalloc() for its buffer because memory used for the
@@ -509,9 +533,10 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
509 */ 533 */
510 kbufs[4] = memdup_user((void __user *)(unsigned long)argv[4].v_base, 534 kbufs[4] = memdup_user((void __user *)(unsigned long)argv[4].v_base,
511 nsegs * sizeof(__u64)); 535 nsegs * sizeof(__u64));
512 if (IS_ERR(kbufs[4])) 536 if (IS_ERR(kbufs[4])) {
513 return PTR_ERR(kbufs[4]); 537 ret = PTR_ERR(kbufs[4]);
514 538 goto out;
539 }
515 nilfs = NILFS_SB(inode->i_sb)->s_nilfs; 540 nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
516 541
517 for (n = 0; n < 4; n++) { 542 for (n = 0; n < 4; n++) {
@@ -563,10 +588,12 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
563 nilfs_remove_all_gcinode(nilfs); 588 nilfs_remove_all_gcinode(nilfs);
564 clear_nilfs_gc_running(nilfs); 589 clear_nilfs_gc_running(nilfs);
565 590
566 out_free: 591out_free:
567 while (--n >= 0) 592 while (--n >= 0)
568 vfree(kbufs[n]); 593 vfree(kbufs[n]);
569 kfree(kbufs[4]); 594 kfree(kbufs[4]);
595out:
596 mnt_drop_write(filp->f_path.mnt);
570 return ret; 597 return ret;
571} 598}
572 599
@@ -575,13 +602,17 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
575{ 602{
576 __u64 cno; 603 __u64 cno;
577 int ret; 604 int ret;
605 struct the_nilfs *nilfs;
578 606
579 ret = nilfs_construct_segment(inode->i_sb); 607 ret = nilfs_construct_segment(inode->i_sb);
580 if (ret < 0) 608 if (ret < 0)
581 return ret; 609 return ret;
582 610
583 if (argp != NULL) { 611 if (argp != NULL) {
584 cno = NILFS_SB(inode->i_sb)->s_nilfs->ns_cno - 1; 612 nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
613 down_read(&nilfs->ns_segctor_sem);
614 cno = nilfs->ns_cno - 1;
615 up_read(&nilfs->ns_segctor_sem);
585 if (copy_to_user(argp, &cno, sizeof(cno))) 616 if (copy_to_user(argp, &cno, sizeof(cno)))
586 return -EFAULT; 617 return -EFAULT;
587 } 618 }
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index f6326112d647..024be8c35bb6 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -26,6 +26,7 @@
26#include <linux/writeback.h> 26#include <linux/writeback.h>
27#include <linux/backing-dev.h> 27#include <linux/backing-dev.h>
28#include <linux/swap.h> 28#include <linux/swap.h>
29#include <linux/slab.h>
29#include "nilfs.h" 30#include "nilfs.h"
30#include "segment.h" 31#include "segment.h"
31#include "page.h" 32#include "page.h"
@@ -186,7 +187,7 @@ nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff,
186} 187}
187 188
188static int nilfs_mdt_read_block(struct inode *inode, unsigned long block, 189static int nilfs_mdt_read_block(struct inode *inode, unsigned long block,
189 struct buffer_head **out_bh) 190 int readahead, struct buffer_head **out_bh)
190{ 191{
191 struct buffer_head *first_bh, *bh; 192 struct buffer_head *first_bh, *bh;
192 unsigned long blkoff; 193 unsigned long blkoff;
@@ -200,16 +201,18 @@ static int nilfs_mdt_read_block(struct inode *inode, unsigned long block,
200 if (unlikely(err)) 201 if (unlikely(err))
201 goto failed; 202 goto failed;
202 203
203 blkoff = block + 1; 204 if (readahead) {
204 for (i = 0; i < nr_ra_blocks; i++, blkoff++) { 205 blkoff = block + 1;
205 err = nilfs_mdt_submit_block(inode, blkoff, READA, &bh); 206 for (i = 0; i < nr_ra_blocks; i++, blkoff++) {
206 if (likely(!err || err == -EEXIST)) 207 err = nilfs_mdt_submit_block(inode, blkoff, READA, &bh);
207 brelse(bh); 208 if (likely(!err || err == -EEXIST))
208 else if (err != -EBUSY) 209 brelse(bh);
209 break; /* abort readahead if bmap lookup failed */ 210 else if (err != -EBUSY)
210 211 break;
211 if (!buffer_locked(first_bh)) 212 /* abort readahead if bmap lookup failed */
212 goto out_no_wait; 213 if (!buffer_locked(first_bh))
214 goto out_no_wait;
215 }
213 } 216 }
214 217
215 wait_on_buffer(first_bh); 218 wait_on_buffer(first_bh);
@@ -263,7 +266,7 @@ int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create,
263 266
264 /* Should be rewritten with merging nilfs_mdt_read_block() */ 267 /* Should be rewritten with merging nilfs_mdt_read_block() */
265 retry: 268 retry:
266 ret = nilfs_mdt_read_block(inode, blkoff, out_bh); 269 ret = nilfs_mdt_read_block(inode, blkoff, !create, out_bh);
267 if (!create || ret != -ENOENT) 270 if (!create || ret != -ENOENT)
268 return ret; 271 return ret;
269 272
@@ -371,7 +374,7 @@ int nilfs_mdt_mark_block_dirty(struct inode *inode, unsigned long block)
371 struct buffer_head *bh; 374 struct buffer_head *bh;
372 int err; 375 int err;
373 376
374 err = nilfs_mdt_read_block(inode, block, &bh); 377 err = nilfs_mdt_read_block(inode, block, 0, &bh);
375 if (unlikely(err)) 378 if (unlikely(err))
376 return err; 379 return err;
377 nilfs_mark_buffer_dirty(bh); 380 nilfs_mark_buffer_dirty(bh);
@@ -445,9 +448,17 @@ static const struct file_operations def_mdt_fops;
445 * longer than those of the super block structs; they may continue for 448 * longer than those of the super block structs; they may continue for
446 * several consecutive mounts/umounts. This would need discussions. 449 * several consecutive mounts/umounts. This would need discussions.
447 */ 450 */
451/**
452 * nilfs_mdt_new_common - allocate a pseudo inode for metadata file
453 * @nilfs: nilfs object
454 * @sb: super block instance the metadata file belongs to
455 * @ino: inode number
456 * @gfp_mask: gfp mask for data pages
457 * @objsz: size of the private object attached to inode->i_private
458 */
448struct inode * 459struct inode *
449nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb, 460nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb,
450 ino_t ino, gfp_t gfp_mask) 461 ino_t ino, gfp_t gfp_mask, size_t objsz)
451{ 462{
452 struct inode *inode = nilfs_alloc_inode_common(nilfs); 463 struct inode *inode = nilfs_alloc_inode_common(nilfs);
453 464
@@ -455,8 +466,9 @@ nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb,
455 return NULL; 466 return NULL;
456 else { 467 else {
457 struct address_space * const mapping = &inode->i_data; 468 struct address_space * const mapping = &inode->i_data;
458 struct nilfs_mdt_info *mi = kzalloc(sizeof(*mi), GFP_NOFS); 469 struct nilfs_mdt_info *mi;
459 470
471 mi = kzalloc(max(sizeof(*mi), objsz), GFP_NOFS);
460 if (!mi) { 472 if (!mi) {
461 nilfs_destroy_inode(inode); 473 nilfs_destroy_inode(inode);
462 return NULL; 474 return NULL;
@@ -513,11 +525,11 @@ nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb,
513} 525}
514 526
515struct inode *nilfs_mdt_new(struct the_nilfs *nilfs, struct super_block *sb, 527struct inode *nilfs_mdt_new(struct the_nilfs *nilfs, struct super_block *sb,
516 ino_t ino) 528 ino_t ino, size_t objsz)
517{ 529{
518 struct inode *inode = nilfs_mdt_new_common(nilfs, sb, ino, 530 struct inode *inode;
519 NILFS_MDT_GFP);
520 531
532 inode = nilfs_mdt_new_common(nilfs, sb, ino, NILFS_MDT_GFP, objsz);
521 if (!inode) 533 if (!inode)
522 return NULL; 534 return NULL;
523 535
@@ -544,14 +556,15 @@ void nilfs_mdt_set_shadow(struct inode *orig, struct inode *shadow)
544 &NILFS_I(orig)->i_btnode_cache; 556 &NILFS_I(orig)->i_btnode_cache;
545} 557}
546 558
547void nilfs_mdt_clear(struct inode *inode) 559static void nilfs_mdt_clear(struct inode *inode)
548{ 560{
549 struct nilfs_inode_info *ii = NILFS_I(inode); 561 struct nilfs_inode_info *ii = NILFS_I(inode);
550 562
551 invalidate_mapping_pages(inode->i_mapping, 0, -1); 563 invalidate_mapping_pages(inode->i_mapping, 0, -1);
552 truncate_inode_pages(inode->i_mapping, 0); 564 truncate_inode_pages(inode->i_mapping, 0);
553 565
554 nilfs_bmap_clear(ii->i_bmap); 566 if (test_bit(NILFS_I_BMAP, &ii->i_state))
567 nilfs_bmap_clear(ii->i_bmap);
555 nilfs_btnode_cache_clear(&ii->i_btnode_cache); 568 nilfs_btnode_cache_clear(&ii->i_btnode_cache);
556} 569}
557 570
@@ -559,6 +572,10 @@ void nilfs_mdt_destroy(struct inode *inode)
559{ 572{
560 struct nilfs_mdt_info *mdi = NILFS_MDT(inode); 573 struct nilfs_mdt_info *mdi = NILFS_MDT(inode);
561 574
575 if (mdi->mi_palloc_cache)
576 nilfs_palloc_destroy_cache(inode);
577 nilfs_mdt_clear(inode);
578
562 kfree(mdi->mi_bgl); /* kfree(NULL) is safe */ 579 kfree(mdi->mi_bgl); /* kfree(NULL) is safe */
563 kfree(mdi); 580 kfree(mdi);
564 nilfs_destroy_inode(inode); 581 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..ad6ed2cf19b4 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -67,7 +67,7 @@ nilfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
67 if (dentry->d_name.len > NILFS_NAME_LEN) 67 if (dentry->d_name.len > NILFS_NAME_LEN)
68 return ERR_PTR(-ENAMETOOLONG); 68 return ERR_PTR(-ENAMETOOLONG);
69 69
70 ino = nilfs_inode_by_name(dir, dentry); 70 ino = nilfs_inode_by_name(dir, &dentry->d_name);
71 inode = NULL; 71 inode = NULL;
72 if (ino) { 72 if (ino) {
73 inode = nilfs_iget(dir->i_sb, ino); 73 inode = nilfs_iget(dir->i_sb, ino);
@@ -81,10 +81,7 @@ struct dentry *nilfs_get_parent(struct dentry *child)
81{ 81{
82 unsigned long ino; 82 unsigned long ino;
83 struct inode *inode; 83 struct inode *inode;
84 struct dentry dotdot; 84 struct qstr dotdot = {.name = "..", .len = 2};
85
86 dotdot.d_name.name = "..";
87 dotdot.d_name.len = 2;
88 85
89 ino = nilfs_inode_by_name(child->d_inode, &dotdot); 86 ino = nilfs_inode_by_name(child->d_inode, &dotdot);
90 if (!ino) 87 if (!ino)
@@ -120,7 +117,7 @@ static int nilfs_create(struct inode *dir, struct dentry *dentry, int mode,
120 inode->i_op = &nilfs_file_inode_operations; 117 inode->i_op = &nilfs_file_inode_operations;
121 inode->i_fop = &nilfs_file_operations; 118 inode->i_fop = &nilfs_file_operations;
122 inode->i_mapping->a_ops = &nilfs_aops; 119 inode->i_mapping->a_ops = &nilfs_aops;
123 mark_inode_dirty(inode); 120 nilfs_mark_inode_dirty(inode);
124 err = nilfs_add_nondir(dentry, inode); 121 err = nilfs_add_nondir(dentry, inode);
125 } 122 }
126 if (!err) 123 if (!err)
@@ -148,7 +145,7 @@ nilfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
148 err = PTR_ERR(inode); 145 err = PTR_ERR(inode);
149 if (!IS_ERR(inode)) { 146 if (!IS_ERR(inode)) {
150 init_special_inode(inode, inode->i_mode, rdev); 147 init_special_inode(inode, inode->i_mode, rdev);
151 mark_inode_dirty(inode); 148 nilfs_mark_inode_dirty(inode);
152 err = nilfs_add_nondir(dentry, inode); 149 err = nilfs_add_nondir(dentry, inode);
153 } 150 }
154 if (!err) 151 if (!err)
@@ -188,7 +185,7 @@ static int nilfs_symlink(struct inode *dir, struct dentry *dentry,
188 goto out_fail; 185 goto out_fail;
189 186
190 /* mark_inode_dirty(inode); */ 187 /* mark_inode_dirty(inode); */
191 /* nilfs_new_inode() and page_symlink() do this */ 188 /* page_symlink() do this */
192 189
193 err = nilfs_add_nondir(dentry, inode); 190 err = nilfs_add_nondir(dentry, inode);
194out: 191out:
@@ -200,7 +197,8 @@ out:
200 return err; 197 return err;
201 198
202out_fail: 199out_fail:
203 inode_dec_link_count(inode); 200 drop_nlink(inode);
201 nilfs_mark_inode_dirty(inode);
204 iput(inode); 202 iput(inode);
205 goto out; 203 goto out;
206} 204}
@@ -245,7 +243,7 @@ static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
245 if (err) 243 if (err)
246 return err; 244 return err;
247 245
248 inode_inc_link_count(dir); 246 inc_nlink(dir);
249 247
250 inode = nilfs_new_inode(dir, S_IFDIR | mode); 248 inode = nilfs_new_inode(dir, S_IFDIR | mode);
251 err = PTR_ERR(inode); 249 err = PTR_ERR(inode);
@@ -256,7 +254,7 @@ static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
256 inode->i_fop = &nilfs_dir_operations; 254 inode->i_fop = &nilfs_dir_operations;
257 inode->i_mapping->a_ops = &nilfs_aops; 255 inode->i_mapping->a_ops = &nilfs_aops;
258 256
259 inode_inc_link_count(inode); 257 inc_nlink(inode);
260 258
261 err = nilfs_make_empty(inode, dir); 259 err = nilfs_make_empty(inode, dir);
262 if (err) 260 if (err)
@@ -266,6 +264,7 @@ static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
266 if (err) 264 if (err)
267 goto out_fail; 265 goto out_fail;
268 266
267 nilfs_mark_inode_dirty(inode);
269 d_instantiate(dentry, inode); 268 d_instantiate(dentry, inode);
270out: 269out:
271 if (!err) 270 if (!err)
@@ -276,28 +275,25 @@ out:
276 return err; 275 return err;
277 276
278out_fail: 277out_fail:
279 inode_dec_link_count(inode); 278 drop_nlink(inode);
280 inode_dec_link_count(inode); 279 drop_nlink(inode);
280 nilfs_mark_inode_dirty(inode);
281 iput(inode); 281 iput(inode);
282out_dir: 282out_dir:
283 inode_dec_link_count(dir); 283 drop_nlink(dir);
284 nilfs_mark_inode_dirty(dir);
284 goto out; 285 goto out;
285} 286}
286 287
287static int nilfs_unlink(struct inode *dir, struct dentry *dentry) 288static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry)
288{ 289{
289 struct inode *inode; 290 struct inode *inode;
290 struct nilfs_dir_entry *de; 291 struct nilfs_dir_entry *de;
291 struct page *page; 292 struct page *page;
292 struct nilfs_transaction_info ti;
293 int err; 293 int err;
294 294
295 err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
296 if (err)
297 return err;
298
299 err = -ENOENT; 295 err = -ENOENT;
300 de = nilfs_find_entry(dir, dentry, &page); 296 de = nilfs_find_entry(dir, &dentry->d_name, &page);
301 if (!de) 297 if (!de)
302 goto out; 298 goto out;
303 299
@@ -317,12 +313,28 @@ static int nilfs_unlink(struct inode *dir, struct dentry *dentry)
317 goto out; 313 goto out;
318 314
319 inode->i_ctime = dir->i_ctime; 315 inode->i_ctime = dir->i_ctime;
320 inode_dec_link_count(inode); 316 drop_nlink(inode);
321 err = 0; 317 err = 0;
322out: 318out:
323 if (!err) 319 return err;
320}
321
322static int nilfs_unlink(struct inode *dir, struct dentry *dentry)
323{
324 struct nilfs_transaction_info ti;
325 int err;
326
327 err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
328 if (err)
329 return err;
330
331 err = nilfs_do_unlink(dir, dentry);
332
333 if (!err) {
334 nilfs_mark_inode_dirty(dir);
335 nilfs_mark_inode_dirty(dentry->d_inode);
324 err = nilfs_transaction_commit(dir->i_sb); 336 err = nilfs_transaction_commit(dir->i_sb);
325 else 337 } else
326 nilfs_transaction_abort(dir->i_sb); 338 nilfs_transaction_abort(dir->i_sb);
327 339
328 return err; 340 return err;
@@ -340,11 +352,13 @@ static int nilfs_rmdir(struct inode *dir, struct dentry *dentry)
340 352
341 err = -ENOTEMPTY; 353 err = -ENOTEMPTY;
342 if (nilfs_empty_dir(inode)) { 354 if (nilfs_empty_dir(inode)) {
343 err = nilfs_unlink(dir, dentry); 355 err = nilfs_do_unlink(dir, dentry);
344 if (!err) { 356 if (!err) {
345 inode->i_size = 0; 357 inode->i_size = 0;
346 inode_dec_link_count(inode); 358 drop_nlink(inode);
347 inode_dec_link_count(dir); 359 nilfs_mark_inode_dirty(inode);
360 drop_nlink(dir);
361 nilfs_mark_inode_dirty(dir);
348 } 362 }
349 } 363 }
350 if (!err) 364 if (!err)
@@ -372,7 +386,7 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry,
372 return err; 386 return err;
373 387
374 err = -ENOENT; 388 err = -ENOENT;
375 old_de = nilfs_find_entry(old_dir, old_dentry, &old_page); 389 old_de = nilfs_find_entry(old_dir, &old_dentry->d_name, &old_page);
376 if (!old_de) 390 if (!old_de)
377 goto out; 391 goto out;
378 392
@@ -392,45 +406,51 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry,
392 goto out_dir; 406 goto out_dir;
393 407
394 err = -ENOENT; 408 err = -ENOENT;
395 new_de = nilfs_find_entry(new_dir, new_dentry, &new_page); 409 new_de = nilfs_find_entry(new_dir, &new_dentry->d_name, &new_page);
396 if (!new_de) 410 if (!new_de)
397 goto out_dir; 411 goto out_dir;
398 inode_inc_link_count(old_inode); 412 inc_nlink(old_inode);
399 nilfs_set_link(new_dir, new_de, new_page, old_inode); 413 nilfs_set_link(new_dir, new_de, new_page, old_inode);
414 nilfs_mark_inode_dirty(new_dir);
400 new_inode->i_ctime = CURRENT_TIME; 415 new_inode->i_ctime = CURRENT_TIME;
401 if (dir_de) 416 if (dir_de)
402 drop_nlink(new_inode); 417 drop_nlink(new_inode);
403 inode_dec_link_count(new_inode); 418 drop_nlink(new_inode);
419 nilfs_mark_inode_dirty(new_inode);
404 } else { 420 } else {
405 if (dir_de) { 421 if (dir_de) {
406 err = -EMLINK; 422 err = -EMLINK;
407 if (new_dir->i_nlink >= NILFS_LINK_MAX) 423 if (new_dir->i_nlink >= NILFS_LINK_MAX)
408 goto out_dir; 424 goto out_dir;
409 } 425 }
410 inode_inc_link_count(old_inode); 426 inc_nlink(old_inode);
411 err = nilfs_add_link(new_dentry, old_inode); 427 err = nilfs_add_link(new_dentry, old_inode);
412 if (err) { 428 if (err) {
413 inode_dec_link_count(old_inode); 429 drop_nlink(old_inode);
430 nilfs_mark_inode_dirty(old_inode);
414 goto out_dir; 431 goto out_dir;
415 } 432 }
416 if (dir_de) 433 if (dir_de) {
417 inode_inc_link_count(new_dir); 434 inc_nlink(new_dir);
435 nilfs_mark_inode_dirty(new_dir);
436 }
418 } 437 }
419 438
420 /* 439 /*
421 * Like most other Unix systems, set the ctime for inodes on a 440 * Like most other Unix systems, set the ctime for inodes on a
422 * rename. 441 * rename.
423 * inode_dec_link_count() will mark the inode dirty.
424 */ 442 */
425 old_inode->i_ctime = CURRENT_TIME; 443 old_inode->i_ctime = CURRENT_TIME;
426 444
427 nilfs_delete_entry(old_de, old_page); 445 nilfs_delete_entry(old_de, old_page);
428 inode_dec_link_count(old_inode); 446 drop_nlink(old_inode);
429 447
430 if (dir_de) { 448 if (dir_de) {
431 nilfs_set_link(old_inode, dir_de, dir_page, new_dir); 449 nilfs_set_link(old_inode, dir_de, dir_page, new_dir);
432 inode_dec_link_count(old_dir); 450 drop_nlink(old_dir);
433 } 451 }
452 nilfs_mark_inode_dirty(old_dir);
453 nilfs_mark_inode_dirty(old_inode);
434 454
435 err = nilfs_transaction_commit(old_dir->i_sb); 455 err = nilfs_transaction_commit(old_dir->i_sb);
436 return err; 456 return err;
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index 4da6f67e9a91..8723e5bfd071 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -217,10 +217,10 @@ static inline int nilfs_init_acl(struct inode *inode, struct inode *dir)
217 217
218/* dir.c */ 218/* dir.c */
219extern int nilfs_add_link(struct dentry *, struct inode *); 219extern int nilfs_add_link(struct dentry *, struct inode *);
220extern ino_t nilfs_inode_by_name(struct inode *, struct dentry *); 220extern ino_t nilfs_inode_by_name(struct inode *, const struct qstr *);
221extern int nilfs_make_empty(struct inode *, struct inode *); 221extern int nilfs_make_empty(struct inode *, struct inode *);
222extern struct nilfs_dir_entry * 222extern struct nilfs_dir_entry *
223nilfs_find_entry(struct inode *, struct dentry *, struct page **); 223nilfs_find_entry(struct inode *, const struct qstr *, struct page **);
224extern int nilfs_delete_entry(struct nilfs_dir_entry *, struct page *); 224extern int nilfs_delete_entry(struct nilfs_dir_entry *, struct page *);
225extern int nilfs_empty_dir(struct inode *); 225extern int nilfs_empty_dir(struct inode *);
226extern struct nilfs_dir_entry *nilfs_dotdot(struct inode *, struct page **); 226extern struct nilfs_dir_entry *nilfs_dotdot(struct inode *, struct page **);
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index a2692bbc7b50..8de3e1e48130 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -29,6 +29,7 @@
29#include <linux/list.h> 29#include <linux/list.h>
30#include <linux/highmem.h> 30#include <linux/highmem.h>
31#include <linux/pagevec.h> 31#include <linux/pagevec.h>
32#include <linux/gfp.h>
32#include "nilfs.h" 33#include "nilfs.h"
33#include "page.h" 34#include "page.h"
34#include "mdt.h" 35#include "mdt.h"
@@ -292,7 +293,7 @@ void nilfs_free_private_page(struct page *page)
292 * @src: source page 293 * @src: source page
293 * @copy_dirty: flag whether to copy dirty states on the page's buffer heads. 294 * @copy_dirty: flag whether to copy dirty states on the page's buffer heads.
294 * 295 *
295 * This fuction is for both data pages and btnode pages. The dirty flag 296 * This function is for both data pages and btnode pages. The dirty flag
296 * should be treated by caller. The page must not be under i/o. 297 * should be treated by caller. The page must not be under i/o.
297 * Both src and dst page must be locked 298 * Both src and dst page must be locked
298 */ 299 */
@@ -388,7 +389,7 @@ repeat:
388} 389}
389 390
390/** 391/**
391 * nilfs_copy_back_pages -- copy back pages to orignal cache from shadow cache 392 * nilfs_copy_back_pages -- copy back pages to original cache from shadow cache
392 * @dmap: destination page cache 393 * @dmap: destination page cache
393 * @smap: source page cache 394 * @smap: source page cache
394 * 395 *
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
index 6dc83591d118..ba43146f3c30 100644
--- a/fs/nilfs2/recovery.c
+++ b/fs/nilfs2/recovery.c
@@ -23,6 +23,7 @@
23#include <linux/buffer_head.h> 23#include <linux/buffer_head.h>
24#include <linux/blkdev.h> 24#include <linux/blkdev.h>
25#include <linux/swap.h> 25#include <linux/swap.h>
26#include <linux/slab.h>
26#include <linux/crc32.h> 27#include <linux/crc32.h>
27#include "nilfs.h" 28#include "nilfs.h"
28#include "segment.h" 29#include "segment.h"
@@ -39,7 +40,6 @@ enum {
39 NILFS_SEG_FAIL_IO, 40 NILFS_SEG_FAIL_IO,
40 NILFS_SEG_FAIL_MAGIC, 41 NILFS_SEG_FAIL_MAGIC,
41 NILFS_SEG_FAIL_SEQ, 42 NILFS_SEG_FAIL_SEQ,
42 NILFS_SEG_FAIL_CHECKSUM_SEGSUM,
43 NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT, 43 NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT,
44 NILFS_SEG_FAIL_CHECKSUM_FULL, 44 NILFS_SEG_FAIL_CHECKSUM_FULL,
45 NILFS_SEG_FAIL_CONSISTENCY, 45 NILFS_SEG_FAIL_CONSISTENCY,
@@ -71,10 +71,6 @@ static int nilfs_warn_segment_error(int err)
71 printk(KERN_WARNING 71 printk(KERN_WARNING
72 "NILFS warning: Sequence number mismatch\n"); 72 "NILFS warning: Sequence number mismatch\n");
73 break; 73 break;
74 case NILFS_SEG_FAIL_CHECKSUM_SEGSUM:
75 printk(KERN_WARNING
76 "NILFS warning: Checksum error in segment summary\n");
77 break;
78 case NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT: 74 case NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT:
79 printk(KERN_WARNING 75 printk(KERN_WARNING
80 "NILFS warning: Checksum error in super root\n"); 76 "NILFS warning: Checksum error in super root\n");
@@ -206,19 +202,15 @@ int nilfs_read_super_root_block(struct super_block *sb, sector_t sr_block,
206 * @pseg_start: start disk block number of partial segment 202 * @pseg_start: start disk block number of partial segment
207 * @seg_seq: sequence number requested 203 * @seg_seq: sequence number requested
208 * @ssi: pointer to nilfs_segsum_info struct to store information 204 * @ssi: pointer to nilfs_segsum_info struct to store information
209 * @full_check: full check flag
210 * (0: only checks segment summary CRC, 1: data CRC)
211 */ 205 */
212static int 206static int
213load_segment_summary(struct nilfs_sb_info *sbi, sector_t pseg_start, 207load_segment_summary(struct nilfs_sb_info *sbi, sector_t pseg_start,
214 u64 seg_seq, struct nilfs_segsum_info *ssi, 208 u64 seg_seq, struct nilfs_segsum_info *ssi)
215 int full_check)
216{ 209{
217 struct buffer_head *bh_sum; 210 struct buffer_head *bh_sum;
218 struct nilfs_segment_summary *sum; 211 struct nilfs_segment_summary *sum;
219 unsigned long offset, nblock; 212 unsigned long nblock;
220 u64 check_bytes; 213 u32 crc;
221 u32 crc, crc_sum;
222 int ret = NILFS_SEG_FAIL_IO; 214 int ret = NILFS_SEG_FAIL_IO;
223 215
224 bh_sum = sb_bread(sbi->s_super, pseg_start); 216 bh_sum = sb_bread(sbi->s_super, pseg_start);
@@ -237,34 +229,24 @@ load_segment_summary(struct nilfs_sb_info *sbi, sector_t pseg_start,
237 ret = NILFS_SEG_FAIL_SEQ; 229 ret = NILFS_SEG_FAIL_SEQ;
238 goto failed; 230 goto failed;
239 } 231 }
240 if (full_check) {
241 offset = sizeof(sum->ss_datasum);
242 check_bytes =
243 ((u64)ssi->nblocks << sbi->s_super->s_blocksize_bits);
244 nblock = ssi->nblocks;
245 crc_sum = le32_to_cpu(sum->ss_datasum);
246 ret = NILFS_SEG_FAIL_CHECKSUM_FULL;
247 } else { /* only checks segment summary */
248 offset = sizeof(sum->ss_datasum) + sizeof(sum->ss_sumsum);
249 check_bytes = ssi->sumbytes;
250 nblock = ssi->nsumblk;
251 crc_sum = le32_to_cpu(sum->ss_sumsum);
252 ret = NILFS_SEG_FAIL_CHECKSUM_SEGSUM;
253 }
254 232
233 nblock = ssi->nblocks;
255 if (unlikely(nblock == 0 || 234 if (unlikely(nblock == 0 ||
256 nblock > sbi->s_nilfs->ns_blocks_per_segment)) { 235 nblock > sbi->s_nilfs->ns_blocks_per_segment)) {
257 /* This limits the number of blocks read in the CRC check */ 236 /* This limits the number of blocks read in the CRC check */
258 ret = NILFS_SEG_FAIL_CONSISTENCY; 237 ret = NILFS_SEG_FAIL_CONSISTENCY;
259 goto failed; 238 goto failed;
260 } 239 }
261 if (calc_crc_cont(sbi, bh_sum, &crc, offset, check_bytes, 240 if (calc_crc_cont(sbi, bh_sum, &crc, sizeof(sum->ss_datasum),
241 ((u64)nblock << sbi->s_super->s_blocksize_bits),
262 pseg_start, nblock)) { 242 pseg_start, nblock)) {
263 ret = NILFS_SEG_FAIL_IO; 243 ret = NILFS_SEG_FAIL_IO;
264 goto failed; 244 goto failed;
265 } 245 }
266 if (crc == crc_sum) 246 if (crc == le32_to_cpu(sum->ss_datasum))
267 ret = 0; 247 ret = 0;
248 else
249 ret = NILFS_SEG_FAIL_CHECKSUM_FULL;
268 failed: 250 failed:
269 brelse(bh_sum); 251 brelse(bh_sum);
270 out: 252 out:
@@ -598,7 +580,7 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
598 580
599 while (segnum != ri->ri_segnum || pseg_start <= ri->ri_pseg_start) { 581 while (segnum != ri->ri_segnum || pseg_start <= ri->ri_pseg_start) {
600 582
601 ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi, 1); 583 ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi);
602 if (ret) { 584 if (ret) {
603 if (ret == NILFS_SEG_FAIL_IO) { 585 if (ret == NILFS_SEG_FAIL_IO) {
604 err = -EIO; 586 err = -EIO;
@@ -770,14 +752,8 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs,
770 nilfs_finish_roll_forward(nilfs, sbi, ri); 752 nilfs_finish_roll_forward(nilfs, sbi, ri);
771 } 753 }
772 754
773 nilfs_detach_checkpoint(sbi);
774 return 0;
775
776 failed: 755 failed:
777 nilfs_detach_checkpoint(sbi); 756 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; 757 return err;
782} 758}
783 759
@@ -804,6 +780,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
804 struct nilfs_segsum_info ssi; 780 struct nilfs_segsum_info ssi;
805 sector_t pseg_start, pseg_end, sr_pseg_start = 0; 781 sector_t pseg_start, pseg_end, sr_pseg_start = 0;
806 sector_t seg_start, seg_end; /* range of full segment (block number) */ 782 sector_t seg_start, seg_end; /* range of full segment (block number) */
783 sector_t b, end;
807 u64 seg_seq; 784 u64 seg_seq;
808 __u64 segnum, nextnum = 0; 785 __u64 segnum, nextnum = 0;
809 __u64 cno; 786 __u64 cno;
@@ -819,9 +796,14 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
819 /* Calculate range of segment */ 796 /* Calculate range of segment */
820 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end); 797 nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end);
821 798
799 /* Read ahead segment */
800 b = seg_start;
801 while (b <= seg_end)
802 sb_breadahead(sbi->s_super, b++);
803
822 for (;;) { 804 for (;;) {
823 /* Load segment summary */ 805 /* Load segment summary */
824 ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi, 1); 806 ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi);
825 if (ret) { 807 if (ret) {
826 if (ret == NILFS_SEG_FAIL_IO) 808 if (ret == NILFS_SEG_FAIL_IO)
827 goto failed; 809 goto failed;
@@ -841,14 +823,20 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
841 ri->ri_nextnum = nextnum; 823 ri->ri_nextnum = nextnum;
842 empty_seg = 0; 824 empty_seg = 0;
843 825
826 if (!NILFS_SEG_HAS_SR(&ssi) && !scan_newer) {
827 /* This will never happen because a superblock
828 (last_segment) always points to a pseg
829 having a super root. */
830 ret = NILFS_SEG_FAIL_CONSISTENCY;
831 goto failed;
832 }
833
834 if (pseg_start == seg_start) {
835 nilfs_get_segment_range(nilfs, nextnum, &b, &end);
836 while (b <= end)
837 sb_breadahead(sbi->s_super, b++);
838 }
844 if (!NILFS_SEG_HAS_SR(&ssi)) { 839 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)) { 840 if (!ri->ri_lsegs_start && NILFS_SEG_LOGBGN(&ssi)) {
853 ri->ri_lsegs_start = pseg_start; 841 ri->ri_lsegs_start = pseg_start;
854 ri->ri_lsegs_start_seq = seg_seq; 842 ri->ri_lsegs_start_seq = seg_seq;
@@ -919,7 +907,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
919 907
920 super_root_found: 908 super_root_found:
921 /* Updating pointers relating to the latest checkpoint */ 909 /* Updating pointers relating to the latest checkpoint */
922 list_splice(&segments, ri->ri_used_segments.prev); 910 list_splice_tail(&segments, &ri->ri_used_segments);
923 nilfs->ns_last_pseg = sr_pseg_start; 911 nilfs->ns_last_pseg = sr_pseg_start;
924 nilfs->ns_last_seq = nilfs->ns_seg_seq; 912 nilfs->ns_last_seq = nilfs->ns_seg_seq;
925 nilfs->ns_last_cno = ri->ri_cno; 913 nilfs->ns_last_cno = ri->ri_cno;
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c
index e6d9e37fa241..17851f77f739 100644
--- a/fs/nilfs2/segbuf.c
+++ b/fs/nilfs2/segbuf.c
@@ -24,10 +24,28 @@
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>
28#include <linux/slab.h>
27#include "page.h" 29#include "page.h"
28#include "segbuf.h" 30#include "segbuf.h"
29 31
30 32
33struct nilfs_write_info {
34 struct the_nilfs *nilfs;
35 struct bio *bio;
36 int start, end; /* The region to be submitted */
37 int rest_blocks;
38 int max_pages;
39 int nr_vecs;
40 sector_t blocknr;
41};
42
43
44static int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
45 struct the_nilfs *nilfs);
46static int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf);
47
48
31static struct kmem_cache *nilfs_segbuf_cachep; 49static struct kmem_cache *nilfs_segbuf_cachep;
32 50
33static void nilfs_segbuf_init_once(void *obj) 51static void nilfs_segbuf_init_once(void *obj)
@@ -63,6 +81,11 @@ struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *sb)
63 INIT_LIST_HEAD(&segbuf->sb_list); 81 INIT_LIST_HEAD(&segbuf->sb_list);
64 INIT_LIST_HEAD(&segbuf->sb_segsum_buffers); 82 INIT_LIST_HEAD(&segbuf->sb_segsum_buffers);
65 INIT_LIST_HEAD(&segbuf->sb_payload_buffers); 83 INIT_LIST_HEAD(&segbuf->sb_payload_buffers);
84
85 init_completion(&segbuf->sb_bio_event);
86 atomic_set(&segbuf->sb_err, 0);
87 segbuf->sb_nbio = 0;
88
66 return segbuf; 89 return segbuf;
67} 90}
68 91
@@ -83,6 +106,22 @@ void nilfs_segbuf_map(struct nilfs_segment_buffer *segbuf, __u64 segnum,
83 segbuf->sb_fseg_end - segbuf->sb_pseg_start + 1; 106 segbuf->sb_fseg_end - segbuf->sb_pseg_start + 1;
84} 107}
85 108
109/**
110 * nilfs_segbuf_map_cont - map a new log behind a given log
111 * @segbuf: new segment buffer
112 * @prev: segment buffer containing a log to be continued
113 */
114void nilfs_segbuf_map_cont(struct nilfs_segment_buffer *segbuf,
115 struct nilfs_segment_buffer *prev)
116{
117 segbuf->sb_segnum = prev->sb_segnum;
118 segbuf->sb_fseg_start = prev->sb_fseg_start;
119 segbuf->sb_fseg_end = prev->sb_fseg_end;
120 segbuf->sb_pseg_start = prev->sb_pseg_start + prev->sb_sum.nblocks;
121 segbuf->sb_rest_blocks =
122 segbuf->sb_fseg_end - segbuf->sb_pseg_start + 1;
123}
124
86void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *segbuf, 125void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *segbuf,
87 __u64 nextnum, struct the_nilfs *nilfs) 126 __u64 nextnum, struct the_nilfs *nilfs)
88{ 127{
@@ -132,13 +171,11 @@ int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned flags,
132 segbuf->sb_sum.sumbytes = sizeof(struct nilfs_segment_summary); 171 segbuf->sb_sum.sumbytes = sizeof(struct nilfs_segment_summary);
133 segbuf->sb_sum.nfinfo = segbuf->sb_sum.nfileblk = 0; 172 segbuf->sb_sum.nfinfo = segbuf->sb_sum.nfileblk = 0;
134 segbuf->sb_sum.ctime = ctime; 173 segbuf->sb_sum.ctime = ctime;
135
136 segbuf->sb_io_error = 0;
137 return 0; 174 return 0;
138} 175}
139 176
140/* 177/*
141 * Setup segument summary 178 * Setup segment summary
142 */ 179 */
143void nilfs_segbuf_fill_in_segsum(struct nilfs_segment_buffer *segbuf) 180void nilfs_segbuf_fill_in_segsum(struct nilfs_segment_buffer *segbuf)
144{ 181{
@@ -219,7 +256,7 @@ void nilfs_segbuf_fill_in_data_crc(struct nilfs_segment_buffer *segbuf,
219 raw_sum->ss_datasum = cpu_to_le32(crc); 256 raw_sum->ss_datasum = cpu_to_le32(crc);
220} 257}
221 258
222void nilfs_release_buffers(struct list_head *list) 259static void nilfs_release_buffers(struct list_head *list)
223{ 260{
224 struct buffer_head *bh, *n; 261 struct buffer_head *bh, *n;
225 262
@@ -241,13 +278,69 @@ void nilfs_release_buffers(struct list_head *list)
241 } 278 }
242} 279}
243 280
281static void nilfs_segbuf_clear(struct nilfs_segment_buffer *segbuf)
282{
283 nilfs_release_buffers(&segbuf->sb_segsum_buffers);
284 nilfs_release_buffers(&segbuf->sb_payload_buffers);
285}
286
287/*
288 * Iterators for segment buffers
289 */
290void nilfs_clear_logs(struct list_head *logs)
291{
292 struct nilfs_segment_buffer *segbuf;
293
294 list_for_each_entry(segbuf, logs, sb_list)
295 nilfs_segbuf_clear(segbuf);
296}
297
298void nilfs_truncate_logs(struct list_head *logs,
299 struct nilfs_segment_buffer *last)
300{
301 struct nilfs_segment_buffer *n, *segbuf;
302
303 segbuf = list_prepare_entry(last, logs, sb_list);
304 list_for_each_entry_safe_continue(segbuf, n, logs, sb_list) {
305 list_del_init(&segbuf->sb_list);
306 nilfs_segbuf_clear(segbuf);
307 nilfs_segbuf_free(segbuf);
308 }
309}
310
311int nilfs_write_logs(struct list_head *logs, struct the_nilfs *nilfs)
312{
313 struct nilfs_segment_buffer *segbuf;
314 int ret = 0;
315
316 list_for_each_entry(segbuf, logs, sb_list) {
317 ret = nilfs_segbuf_write(segbuf, nilfs);
318 if (ret)
319 break;
320 }
321 return ret;
322}
323
324int nilfs_wait_on_logs(struct list_head *logs)
325{
326 struct nilfs_segment_buffer *segbuf;
327 int err, ret = 0;
328
329 list_for_each_entry(segbuf, logs, sb_list) {
330 err = nilfs_segbuf_wait(segbuf);
331 if (err && !ret)
332 ret = err;
333 }
334 return ret;
335}
336
244/* 337/*
245 * BIO operations 338 * BIO operations
246 */ 339 */
247static void nilfs_end_bio_write(struct bio *bio, int err) 340static void nilfs_end_bio_write(struct bio *bio, int err)
248{ 341{
249 const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); 342 const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
250 struct nilfs_write_info *wi = bio->bi_private; 343 struct nilfs_segment_buffer *segbuf = bio->bi_private;
251 344
252 if (err == -EOPNOTSUPP) { 345 if (err == -EOPNOTSUPP) {
253 set_bit(BIO_EOPNOTSUPP, &bio->bi_flags); 346 set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
@@ -256,21 +349,22 @@ static void nilfs_end_bio_write(struct bio *bio, int err)
256 } 349 }
257 350
258 if (!uptodate) 351 if (!uptodate)
259 atomic_inc(&wi->err); 352 atomic_inc(&segbuf->sb_err);
260 353
261 bio_put(bio); 354 bio_put(bio);
262 complete(&wi->bio_event); 355 complete(&segbuf->sb_bio_event);
263} 356}
264 357
265static int nilfs_submit_seg_bio(struct nilfs_write_info *wi, int mode) 358static int nilfs_segbuf_submit_bio(struct nilfs_segment_buffer *segbuf,
359 struct nilfs_write_info *wi, int mode)
266{ 360{
267 struct bio *bio = wi->bio; 361 struct bio *bio = wi->bio;
268 int err; 362 int err;
269 363
270 if (wi->nbio > 0 && bdi_write_congested(wi->bdi)) { 364 if (segbuf->sb_nbio > 0 && bdi_write_congested(wi->nilfs->ns_bdi)) {
271 wait_for_completion(&wi->bio_event); 365 wait_for_completion(&segbuf->sb_bio_event);
272 wi->nbio--; 366 segbuf->sb_nbio--;
273 if (unlikely(atomic_read(&wi->err))) { 367 if (unlikely(atomic_read(&segbuf->sb_err))) {
274 bio_put(bio); 368 bio_put(bio);
275 err = -EIO; 369 err = -EIO;
276 goto failed; 370 goto failed;
@@ -278,7 +372,7 @@ static int nilfs_submit_seg_bio(struct nilfs_write_info *wi, int mode)
278 } 372 }
279 373
280 bio->bi_end_io = nilfs_end_bio_write; 374 bio->bi_end_io = nilfs_end_bio_write;
281 bio->bi_private = wi; 375 bio->bi_private = segbuf;
282 bio_get(bio); 376 bio_get(bio);
283 submit_bio(mode, bio); 377 submit_bio(mode, bio);
284 if (bio_flagged(bio, BIO_EOPNOTSUPP)) { 378 if (bio_flagged(bio, BIO_EOPNOTSUPP)) {
@@ -286,7 +380,7 @@ static int nilfs_submit_seg_bio(struct nilfs_write_info *wi, int mode)
286 err = -EOPNOTSUPP; 380 err = -EOPNOTSUPP;
287 goto failed; 381 goto failed;
288 } 382 }
289 wi->nbio++; 383 segbuf->sb_nbio++;
290 bio_put(bio); 384 bio_put(bio);
291 385
292 wi->bio = NULL; 386 wi->bio = NULL;
@@ -301,17 +395,15 @@ static int nilfs_submit_seg_bio(struct nilfs_write_info *wi, int mode)
301} 395}
302 396
303/** 397/**
304 * nilfs_alloc_seg_bio - allocate a bio for writing segment. 398 * nilfs_alloc_seg_bio - allocate a new bio for writing log
305 * @sb: super block 399 * @nilfs: nilfs object
306 * @start: beginning disk block number of this BIO. 400 * @start: start block number of the bio
307 * @nr_vecs: request size of page vector. 401 * @nr_vecs: request size of page vector.
308 * 402 *
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. 403 * Return Value: On success, pointer to the struct bio is returned.
312 * On error, NULL is returned. 404 * On error, NULL is returned.
313 */ 405 */
314static struct bio *nilfs_alloc_seg_bio(struct super_block *sb, sector_t start, 406static struct bio *nilfs_alloc_seg_bio(struct the_nilfs *nilfs, sector_t start,
315 int nr_vecs) 407 int nr_vecs)
316{ 408{
317 struct bio *bio; 409 struct bio *bio;
@@ -322,36 +414,33 @@ static struct bio *nilfs_alloc_seg_bio(struct super_block *sb, sector_t start,
322 bio = bio_alloc(GFP_NOIO, nr_vecs); 414 bio = bio_alloc(GFP_NOIO, nr_vecs);
323 } 415 }
324 if (likely(bio)) { 416 if (likely(bio)) {
325 bio->bi_bdev = sb->s_bdev; 417 bio->bi_bdev = nilfs->ns_bdev;
326 bio->bi_sector = (sector_t)start << (sb->s_blocksize_bits - 9); 418 bio->bi_sector = start << (nilfs->ns_blocksize_bits - 9);
327 } 419 }
328 return bio; 420 return bio;
329} 421}
330 422
331void nilfs_segbuf_prepare_write(struct nilfs_segment_buffer *segbuf, 423static void nilfs_segbuf_prepare_write(struct nilfs_segment_buffer *segbuf,
332 struct nilfs_write_info *wi) 424 struct nilfs_write_info *wi)
333{ 425{
334 wi->bio = NULL; 426 wi->bio = NULL;
335 wi->rest_blocks = segbuf->sb_sum.nblocks; 427 wi->rest_blocks = segbuf->sb_sum.nblocks;
336 wi->max_pages = bio_get_nr_vecs(wi->sb->s_bdev); 428 wi->max_pages = bio_get_nr_vecs(wi->nilfs->ns_bdev);
337 wi->nr_vecs = min(wi->max_pages, wi->rest_blocks); 429 wi->nr_vecs = min(wi->max_pages, wi->rest_blocks);
338 wi->start = wi->end = 0; 430 wi->start = wi->end = 0;
339 wi->nbio = 0;
340 wi->blocknr = segbuf->sb_pseg_start; 431 wi->blocknr = segbuf->sb_pseg_start;
341
342 atomic_set(&wi->err, 0);
343 init_completion(&wi->bio_event);
344} 432}
345 433
346static int nilfs_submit_bh(struct nilfs_write_info *wi, struct buffer_head *bh, 434static int nilfs_segbuf_submit_bh(struct nilfs_segment_buffer *segbuf,
347 int mode) 435 struct nilfs_write_info *wi,
436 struct buffer_head *bh, int mode)
348{ 437{
349 int len, err; 438 int len, err;
350 439
351 BUG_ON(wi->nr_vecs <= 0); 440 BUG_ON(wi->nr_vecs <= 0);
352 repeat: 441 repeat:
353 if (!wi->bio) { 442 if (!wi->bio) {
354 wi->bio = nilfs_alloc_seg_bio(wi->sb, wi->blocknr + wi->end, 443 wi->bio = nilfs_alloc_seg_bio(wi->nilfs, wi->blocknr + wi->end,
355 wi->nr_vecs); 444 wi->nr_vecs);
356 if (unlikely(!wi->bio)) 445 if (unlikely(!wi->bio))
357 return -ENOMEM; 446 return -ENOMEM;
@@ -363,76 +452,83 @@ static int nilfs_submit_bh(struct nilfs_write_info *wi, struct buffer_head *bh,
363 return 0; 452 return 0;
364 } 453 }
365 /* bio is FULL */ 454 /* bio is FULL */
366 err = nilfs_submit_seg_bio(wi, mode); 455 err = nilfs_segbuf_submit_bio(segbuf, wi, mode);
367 /* never submit current bh */ 456 /* never submit current bh */
368 if (likely(!err)) 457 if (likely(!err))
369 goto repeat; 458 goto repeat;
370 return err; 459 return err;
371} 460}
372 461
373int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf, 462/**
374 struct nilfs_write_info *wi) 463 * nilfs_segbuf_write - submit write requests of a log
464 * @segbuf: buffer storing a log to be written
465 * @nilfs: nilfs object
466 *
467 * Return Value: On Success, 0 is returned. On Error, one of the following
468 * negative error code is returned.
469 *
470 * %-EIO - I/O error
471 *
472 * %-ENOMEM - Insufficient memory available.
473 */
474static int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
475 struct the_nilfs *nilfs)
375{ 476{
477 struct nilfs_write_info wi;
376 struct buffer_head *bh; 478 struct buffer_head *bh;
377 int res, rw = WRITE; 479 int res = 0, rw = WRITE;
480
481 wi.nilfs = nilfs;
482 nilfs_segbuf_prepare_write(segbuf, &wi);
378 483
379 list_for_each_entry(bh, &segbuf->sb_segsum_buffers, b_assoc_buffers) { 484 list_for_each_entry(bh, &segbuf->sb_segsum_buffers, b_assoc_buffers) {
380 res = nilfs_submit_bh(wi, bh, rw); 485 res = nilfs_segbuf_submit_bh(segbuf, &wi, bh, rw);
381 if (unlikely(res)) 486 if (unlikely(res))
382 goto failed_bio; 487 goto failed_bio;
383 } 488 }
384 489
385 list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) { 490 list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) {
386 res = nilfs_submit_bh(wi, bh, rw); 491 res = nilfs_segbuf_submit_bh(segbuf, &wi, bh, rw);
387 if (unlikely(res)) 492 if (unlikely(res))
388 goto failed_bio; 493 goto failed_bio;
389 } 494 }
390 495
391 if (wi->bio) { 496 if (wi.bio) {
392 /* 497 /*
393 * Last BIO is always sent through the following 498 * Last BIO is always sent through the following
394 * submission. 499 * submission.
395 */ 500 */
396 rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); 501 rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG);
397 res = nilfs_submit_seg_bio(wi, rw); 502 res = nilfs_segbuf_submit_bio(segbuf, &wi, rw);
398 if (unlikely(res))
399 goto failed_bio;
400 } 503 }
401 504
402 res = 0;
403 out:
404 return res;
405
406 failed_bio: 505 failed_bio:
407 atomic_inc(&wi->err); 506 return res;
408 goto out;
409} 507}
410 508
411/** 509/**
412 * nilfs_segbuf_wait - wait for completion of requested BIOs 510 * nilfs_segbuf_wait - wait for completion of requested BIOs
413 * @wi: nilfs_write_info 511 * @segbuf: segment buffer
414 * 512 *
415 * Return Value: On Success, 0 is returned. On Error, one of the following 513 * Return Value: On Success, 0 is returned. On Error, one of the following
416 * negative error code is returned. 514 * negative error code is returned.
417 * 515 *
418 * %-EIO - I/O error 516 * %-EIO - I/O error
419 */ 517 */
420int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf, 518static int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf)
421 struct nilfs_write_info *wi)
422{ 519{
423 int err = 0; 520 int err = 0;
424 521
425 if (!wi->nbio) 522 if (!segbuf->sb_nbio)
426 return 0; 523 return 0;
427 524
428 do { 525 do {
429 wait_for_completion(&wi->bio_event); 526 wait_for_completion(&segbuf->sb_bio_event);
430 } while (--wi->nbio > 0); 527 } while (--segbuf->sb_nbio > 0);
431 528
432 if (unlikely(atomic_read(&wi->err) > 0)) { 529 if (unlikely(atomic_read(&segbuf->sb_err) > 0)) {
433 printk(KERN_ERR "NILFS: IO error writing segment\n"); 530 printk(KERN_ERR "NILFS: IO error writing segment\n");
434 err = -EIO; 531 err = -EIO;
435 segbuf->sb_io_error = 1;
436 } 532 }
437 return err; 533 return err;
438} 534}
diff --git a/fs/nilfs2/segbuf.h b/fs/nilfs2/segbuf.h
index 0c3076f4e592..94dfd3517bc0 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,15 @@ 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 *); 169void nilfs_clear_logs(struct list_head *logs);
170void nilfs_truncate_logs(struct list_head *logs,
171 struct nilfs_segment_buffer *last);
172int nilfs_write_logs(struct list_head *logs, struct the_nilfs *nilfs);
173int nilfs_wait_on_logs(struct list_head *logs);
165 174
166static inline void nilfs_segbuf_clear(struct nilfs_segment_buffer *segbuf) 175static inline void nilfs_destroy_logs(struct list_head *logs)
167{ 176{
168 nilfs_release_buffers(&segbuf->sb_segsum_buffers); 177 nilfs_truncate_logs(logs, NULL);
169 nilfs_release_buffers(&segbuf->sb_payload_buffers);
170} 178}
171 179
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 */ 180#endif /* _NILFS_SEGBUF_H */
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 6eff66a070d5..6a7dbd8451db 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -32,6 +32,7 @@
32#include <linux/kthread.h> 32#include <linux/kthread.h>
33#include <linux/crc32.h> 33#include <linux/crc32.h>
34#include <linux/pagevec.h> 34#include <linux/pagevec.h>
35#include <linux/slab.h>
35#include "nilfs.h" 36#include "nilfs.h"
36#include "btnode.h" 37#include "btnode.h"
37#include "page.h" 38#include "page.h"
@@ -141,7 +142,7 @@ int nilfs_init_transaction_cache(void)
141} 142}
142 143
143/** 144/**
144 * nilfs_detroy_transaction_cache - destroy the cache for transaction info 145 * nilfs_destroy_transaction_cache - destroy the cache for transaction info
145 * 146 *
146 * nilfs_destroy_transaction_cache() frees the slab cache for the struct 147 * nilfs_destroy_transaction_cache() frees the slab cache for the struct
147 * nilfs_transaction_info. 148 * nilfs_transaction_info.
@@ -201,7 +202,7 @@ static int nilfs_prepare_segment_lock(struct nilfs_transaction_info *ti)
201 * This function allocates a nilfs_transaction_info struct to keep context 202 * This function allocates a nilfs_transaction_info struct to keep context
202 * information on it. It is initialized and hooked onto the current task in 203 * information on it. It is initialized and hooked onto the current task in
203 * the outermost call. If a pre-allocated struct is given to @ti, it is used 204 * the outermost call. If a pre-allocated struct is given to @ti, it is used
204 * instead; othewise a new struct is assigned from a slab. 205 * instead; otherwise a new struct is assigned from a slab.
205 * 206 *
206 * When @vacancy_check flag is set, this function will check the amount of 207 * When @vacancy_check flag is set, this function will check the amount of
207 * free space, and will wait for the GC to reclaim disk space if low capacity. 208 * free space, and will wait for the GC to reclaim disk space if low capacity.
@@ -974,12 +975,12 @@ static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci,
974 nilfs->ns_nongc_ctime : sci->sc_seg_ctime); 975 nilfs->ns_nongc_ctime : sci->sc_seg_ctime);
975 raw_sr->sr_flags = 0; 976 raw_sr->sr_flags = 0;
976 977
977 nilfs_mdt_write_inode_direct( 978 nilfs_write_inode_common(nilfs_dat_inode(nilfs), (void *)raw_sr +
978 nilfs_dat_inode(nilfs), bh_sr, NILFS_SR_DAT_OFFSET(isz)); 979 NILFS_SR_DAT_OFFSET(isz), 1);
979 nilfs_mdt_write_inode_direct( 980 nilfs_write_inode_common(nilfs->ns_cpfile, (void *)raw_sr +
980 nilfs->ns_cpfile, bh_sr, NILFS_SR_CPFILE_OFFSET(isz)); 981 NILFS_SR_CPFILE_OFFSET(isz), 1);
981 nilfs_mdt_write_inode_direct( 982 nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr +
982 nilfs->ns_sufile, bh_sr, NILFS_SR_SUFILE_OFFSET(isz)); 983 NILFS_SR_SUFILE_OFFSET(isz), 1);
983} 984}
984 985
985static void nilfs_redirty_inodes(struct list_head *head) 986static void nilfs_redirty_inodes(struct list_head *head)
@@ -1273,73 +1274,75 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
1273 return err; 1274 return err;
1274} 1275}
1275 1276
1276static int nilfs_touch_segusage(struct inode *sufile, __u64 segnum) 1277/**
1277{ 1278 * nilfs_segctor_begin_construction - setup segment buffer to make a new log
1278 struct buffer_head *bh_su; 1279 * @sci: nilfs_sc_info
1279 struct nilfs_segment_usage *raw_su; 1280 * @nilfs: nilfs object
1280 int err; 1281 */
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, 1282static int nilfs_segctor_begin_construction(struct nilfs_sc_info *sci,
1292 struct the_nilfs *nilfs) 1283 struct the_nilfs *nilfs)
1293{ 1284{
1294 struct nilfs_segment_buffer *segbuf, *n; 1285 struct nilfs_segment_buffer *segbuf, *prev;
1295 __u64 nextnum; 1286 __u64 nextnum;
1296 int err; 1287 int err, alloc = 0;
1297 1288
1298 if (list_empty(&sci->sc_segbufs)) { 1289 segbuf = nilfs_segbuf_new(sci->sc_super);
1299 segbuf = nilfs_segbuf_new(sci->sc_super); 1290 if (unlikely(!segbuf))
1300 if (unlikely(!segbuf)) 1291 return -ENOMEM;
1301 return -ENOMEM;
1302 list_add(&segbuf->sb_list, &sci->sc_segbufs);
1303 } else
1304 segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
1305 1292
1306 nilfs_segbuf_map(segbuf, nilfs->ns_segnum, nilfs->ns_pseg_offset, 1293 if (list_empty(&sci->sc_write_logs)) {
1307 nilfs); 1294 nilfs_segbuf_map(segbuf, nilfs->ns_segnum,
1295 nilfs->ns_pseg_offset, nilfs);
1296 if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) {
1297 nilfs_shift_to_next_segment(nilfs);
1298 nilfs_segbuf_map(segbuf, nilfs->ns_segnum, 0, nilfs);
1299 }
1300
1301 segbuf->sb_sum.seg_seq = nilfs->ns_seg_seq;
1302 nextnum = nilfs->ns_nextnum;
1308 1303
1309 if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) { 1304 if (nilfs->ns_segnum == nilfs->ns_nextnum)
1310 nilfs_shift_to_next_segment(nilfs); 1305 /* Start from the head of a new full segment */
1311 nilfs_segbuf_map(segbuf, nilfs->ns_segnum, 0, nilfs); 1306 alloc++;
1307 } else {
1308 /* Continue logs */
1309 prev = NILFS_LAST_SEGBUF(&sci->sc_write_logs);
1310 nilfs_segbuf_map_cont(segbuf, prev);
1311 segbuf->sb_sum.seg_seq = prev->sb_sum.seg_seq;
1312 nextnum = prev->sb_nextnum;
1313
1314 if (segbuf->sb_rest_blocks < NILFS_PSEG_MIN_BLOCKS) {
1315 nilfs_segbuf_map(segbuf, prev->sb_nextnum, 0, nilfs);
1316 segbuf->sb_sum.seg_seq++;
1317 alloc++;
1318 }
1312 } 1319 }
1313 sci->sc_segbuf_nblocks = segbuf->sb_rest_blocks;
1314 1320
1315 err = nilfs_touch_segusage(nilfs->ns_sufile, segbuf->sb_segnum); 1321 err = nilfs_sufile_mark_dirty(nilfs->ns_sufile, segbuf->sb_segnum);
1316 if (unlikely(err)) 1322 if (err)
1317 return err; 1323 goto failed;
1318 1324
1319 if (nilfs->ns_segnum == nilfs->ns_nextnum) { 1325 if (alloc) {
1320 /* Start from the head of a new full segment */
1321 err = nilfs_sufile_alloc(nilfs->ns_sufile, &nextnum); 1326 err = nilfs_sufile_alloc(nilfs->ns_sufile, &nextnum);
1322 if (unlikely(err)) 1327 if (err)
1323 return err; 1328 goto failed;
1324 } else 1329 }
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); 1330 nilfs_segbuf_set_next_segnum(segbuf, nextnum, nilfs);
1329 1331
1330 /* truncating segment buffers */ 1332 BUG_ON(!list_empty(&sci->sc_segbufs));
1331 list_for_each_entry_safe_continue(segbuf, n, &sci->sc_segbufs, 1333 list_add_tail(&segbuf->sb_list, &sci->sc_segbufs);
1332 sb_list) { 1334 sci->sc_segbuf_nblocks = segbuf->sb_rest_blocks;
1333 list_del_init(&segbuf->sb_list);
1334 nilfs_segbuf_free(segbuf);
1335 }
1336 return 0; 1335 return 0;
1336
1337 failed:
1338 nilfs_segbuf_free(segbuf);
1339 return err;
1337} 1340}
1338 1341
1339static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci, 1342static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci,
1340 struct the_nilfs *nilfs, int nadd) 1343 struct the_nilfs *nilfs, int nadd)
1341{ 1344{
1342 struct nilfs_segment_buffer *segbuf, *prev, *n; 1345 struct nilfs_segment_buffer *segbuf, *prev;
1343 struct inode *sufile = nilfs->ns_sufile; 1346 struct inode *sufile = nilfs->ns_sufile;
1344 __u64 nextnextnum; 1347 __u64 nextnextnum;
1345 LIST_HEAD(list); 1348 LIST_HEAD(list);
@@ -1352,7 +1355,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 1355 * 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. 1356 * and will pin the buffer on memory until the sufile is written.
1354 */ 1357 */
1355 err = nilfs_touch_segusage(sufile, prev->sb_nextnum); 1358 err = nilfs_sufile_mark_dirty(sufile, prev->sb_nextnum);
1356 if (unlikely(err)) 1359 if (unlikely(err))
1357 return err; 1360 return err;
1358 1361
@@ -1378,33 +1381,33 @@ static int nilfs_segctor_extend_segments(struct nilfs_sc_info *sci,
1378 list_add_tail(&segbuf->sb_list, &list); 1381 list_add_tail(&segbuf->sb_list, &list);
1379 prev = segbuf; 1382 prev = segbuf;
1380 } 1383 }
1381 list_splice(&list, sci->sc_segbufs.prev); 1384 list_splice_tail(&list, &sci->sc_segbufs);
1382 return 0; 1385 return 0;
1383 1386
1384 failed_segbuf: 1387 failed_segbuf:
1385 nilfs_segbuf_free(segbuf); 1388 nilfs_segbuf_free(segbuf);
1386 failed: 1389 failed:
1387 list_for_each_entry_safe(segbuf, n, &list, sb_list) { 1390 list_for_each_entry(segbuf, &list, sb_list) {
1388 ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum); 1391 ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1389 WARN_ON(ret); /* never fails */ 1392 WARN_ON(ret); /* never fails */
1390 list_del_init(&segbuf->sb_list);
1391 nilfs_segbuf_free(segbuf);
1392 } 1393 }
1394 nilfs_destroy_logs(&list);
1393 return err; 1395 return err;
1394} 1396}
1395 1397
1396static void nilfs_segctor_free_incomplete_segments(struct nilfs_sc_info *sci, 1398static void nilfs_free_incomplete_logs(struct list_head *logs,
1397 struct the_nilfs *nilfs) 1399 struct the_nilfs *nilfs)
1398{ 1400{
1399 struct nilfs_segment_buffer *segbuf; 1401 struct nilfs_segment_buffer *segbuf, *prev;
1400 int ret, done = 0; 1402 struct inode *sufile = nilfs->ns_sufile;
1403 int ret;
1401 1404
1402 segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs); 1405 segbuf = NILFS_FIRST_SEGBUF(logs);
1403 if (nilfs->ns_nextnum != segbuf->sb_nextnum) { 1406 if (nilfs->ns_nextnum != segbuf->sb_nextnum) {
1404 ret = nilfs_sufile_free(nilfs->ns_sufile, segbuf->sb_nextnum); 1407 ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1405 WARN_ON(ret); /* never fails */ 1408 WARN_ON(ret); /* never fails */
1406 } 1409 }
1407 if (segbuf->sb_io_error) { 1410 if (atomic_read(&segbuf->sb_err)) {
1408 /* Case 1: The first segment failed */ 1411 /* Case 1: The first segment failed */
1409 if (segbuf->sb_pseg_start != segbuf->sb_fseg_start) 1412 if (segbuf->sb_pseg_start != segbuf->sb_fseg_start)
1410 /* Case 1a: Partial segment appended into an existing 1413 /* Case 1a: Partial segment appended into an existing
@@ -1413,106 +1416,54 @@ static void nilfs_segctor_free_incomplete_segments(struct nilfs_sc_info *sci,
1413 segbuf->sb_fseg_end); 1416 segbuf->sb_fseg_end);
1414 else /* Case 1b: New full segment */ 1417 else /* Case 1b: New full segment */
1415 set_nilfs_discontinued(nilfs); 1418 set_nilfs_discontinued(nilfs);
1416 done++;
1417 } 1419 }
1418 1420
1419 list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) { 1421 prev = segbuf;
1420 ret = nilfs_sufile_free(nilfs->ns_sufile, segbuf->sb_nextnum); 1422 list_for_each_entry_continue(segbuf, logs, sb_list) {
1421 WARN_ON(ret); /* never fails */ 1423 if (prev->sb_nextnum != segbuf->sb_nextnum) {
1422 if (!done && segbuf->sb_io_error) { 1424 ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1423 if (segbuf->sb_segnum != nilfs->ns_nextnum) 1425 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 } 1426 }
1427 if (atomic_read(&segbuf->sb_err) &&
1428 segbuf->sb_segnum != nilfs->ns_nextnum)
1429 /* Case 2: extended segment (!= next) failed */
1430 nilfs_sufile_set_error(sufile, segbuf->sb_segnum);
1431 prev = segbuf;
1467 } 1432 }
1468 nilfs_segctor_clear_segment_buffers(sci);
1469} 1433}
1470 1434
1471static void nilfs_segctor_update_segusage(struct nilfs_sc_info *sci, 1435static void nilfs_segctor_update_segusage(struct nilfs_sc_info *sci,
1472 struct inode *sufile) 1436 struct inode *sufile)
1473{ 1437{
1474 struct nilfs_segment_buffer *segbuf; 1438 struct nilfs_segment_buffer *segbuf;
1475 struct buffer_head *bh_su;
1476 struct nilfs_segment_usage *raw_su;
1477 unsigned long live_blocks; 1439 unsigned long live_blocks;
1478 int ret; 1440 int ret;
1479 1441
1480 list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { 1442 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 + 1443 live_blocks = segbuf->sb_sum.nblocks +
1485 (segbuf->sb_pseg_start - segbuf->sb_fseg_start); 1444 (segbuf->sb_pseg_start - segbuf->sb_fseg_start);
1486 raw_su->su_lastmod = cpu_to_le64(sci->sc_seg_ctime); 1445 ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
1487 raw_su->su_nblocks = cpu_to_le32(live_blocks); 1446 live_blocks,
1488 nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum, 1447 sci->sc_seg_ctime);
1489 bh_su); 1448 WARN_ON(ret); /* always succeed because the segusage is dirty */
1490 } 1449 }
1491} 1450}
1492 1451
1493static void nilfs_segctor_cancel_segusage(struct nilfs_sc_info *sci, 1452static void nilfs_cancel_segusage(struct list_head *logs, struct inode *sufile)
1494 struct inode *sufile)
1495{ 1453{
1496 struct nilfs_segment_buffer *segbuf; 1454 struct nilfs_segment_buffer *segbuf;
1497 struct buffer_head *bh_su;
1498 struct nilfs_segment_usage *raw_su;
1499 int ret; 1455 int ret;
1500 1456
1501 segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs); 1457 segbuf = NILFS_FIRST_SEGBUF(logs);
1502 ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum, 1458 ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
1503 &raw_su, &bh_su); 1459 segbuf->sb_pseg_start -
1504 WARN_ON(ret); /* always succeed because bh_su is dirty */ 1460 segbuf->sb_fseg_start, 0);
1505 raw_su->su_nblocks = cpu_to_le32(segbuf->sb_pseg_start - 1461 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 1462
1509 list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) { 1463 list_for_each_entry_continue(segbuf, logs, sb_list) {
1510 ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum, 1464 ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
1511 &raw_su, &bh_su); 1465 0, 0);
1512 WARN_ON(ret); /* always succeed */ 1466 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 } 1467 }
1517} 1468}
1518 1469
@@ -1520,17 +1471,15 @@ static void nilfs_segctor_truncate_segments(struct nilfs_sc_info *sci,
1520 struct nilfs_segment_buffer *last, 1471 struct nilfs_segment_buffer *last,
1521 struct inode *sufile) 1472 struct inode *sufile)
1522{ 1473{
1523 struct nilfs_segment_buffer *segbuf = last, *n; 1474 struct nilfs_segment_buffer *segbuf = last;
1524 int ret; 1475 int ret;
1525 1476
1526 list_for_each_entry_safe_continue(segbuf, n, &sci->sc_segbufs, 1477 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; 1478 sci->sc_segbuf_nblocks -= segbuf->sb_rest_blocks;
1530 ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum); 1479 ret = nilfs_sufile_free(sufile, segbuf->sb_nextnum);
1531 WARN_ON(ret); 1480 WARN_ON(ret);
1532 nilfs_segbuf_free(segbuf);
1533 } 1481 }
1482 nilfs_truncate_logs(&sci->sc_segbufs, last);
1534} 1483}
1535 1484
1536 1485
@@ -1562,6 +1511,12 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
1562 if (mode != SC_LSEG_SR || sci->sc_stage.scnt < NILFS_ST_CPFILE) 1511 if (mode != SC_LSEG_SR || sci->sc_stage.scnt < NILFS_ST_CPFILE)
1563 break; 1512 break;
1564 1513
1514 nilfs_clear_logs(&sci->sc_segbufs);
1515
1516 err = nilfs_segctor_extend_segments(sci, nilfs, nadd);
1517 if (unlikely(err))
1518 return err;
1519
1565 if (sci->sc_stage.flags & NILFS_CF_SUFREED) { 1520 if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
1566 err = nilfs_sufile_cancel_freev(nilfs->ns_sufile, 1521 err = nilfs_sufile_cancel_freev(nilfs->ns_sufile,
1567 sci->sc_freesegs, 1522 sci->sc_freesegs,
@@ -1569,12 +1524,6 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
1569 NULL); 1524 NULL);
1570 WARN_ON(err); /* do not happen */ 1525 WARN_ON(err); /* do not happen */
1571 } 1526 }
1572 nilfs_segctor_clear_segment_buffers(sci);
1573
1574 err = nilfs_segctor_extend_segments(sci, nilfs, nadd);
1575 if (unlikely(err))
1576 return err;
1577
1578 nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA); 1527 nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA);
1579 sci->sc_stage = prev_stage; 1528 sci->sc_stage = prev_stage;
1580 } 1529 }
@@ -1814,26 +1763,13 @@ static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci,
1814} 1763}
1815 1764
1816static int nilfs_segctor_write(struct nilfs_sc_info *sci, 1765static int nilfs_segctor_write(struct nilfs_sc_info *sci,
1817 struct backing_dev_info *bdi) 1766 struct the_nilfs *nilfs)
1818{ 1767{
1819 struct nilfs_segment_buffer *segbuf; 1768 int ret;
1820 struct nilfs_write_info wi;
1821 int err, res;
1822
1823 wi.sb = sci->sc_super;
1824 wi.bh_sr = sci->sc_super_root;
1825 wi.bdi = bdi;
1826
1827 list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
1828 nilfs_segbuf_prepare_write(segbuf, &wi);
1829 err = nilfs_segbuf_write(segbuf, &wi);
1830 1769
1831 res = nilfs_segbuf_wait(segbuf, &wi); 1770 ret = nilfs_write_logs(&sci->sc_segbufs, nilfs);
1832 err = err ? : res; 1771 list_splice_tail_init(&sci->sc_segbufs, &sci->sc_write_logs);
1833 if (err) 1772 return ret;
1834 return err;
1835 }
1836 return 0;
1837} 1773}
1838 1774
1839static void __nilfs_end_page_io(struct page *page, int err) 1775static void __nilfs_end_page_io(struct page *page, int err)
@@ -1911,15 +1847,17 @@ static void nilfs_clear_copied_buffers(struct list_head *list, int err)
1911 } 1847 }
1912} 1848}
1913 1849
1914static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci, 1850static void nilfs_abort_logs(struct list_head *logs, struct page *failed_page,
1915 struct page *failed_page, int err) 1851 struct buffer_head *bh_sr, int err)
1916{ 1852{
1917 struct nilfs_segment_buffer *segbuf; 1853 struct nilfs_segment_buffer *segbuf;
1918 struct page *bd_page = NULL, *fs_page = NULL; 1854 struct page *bd_page = NULL, *fs_page = NULL;
1855 struct buffer_head *bh;
1919 1856
1920 list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { 1857 if (list_empty(logs))
1921 struct buffer_head *bh; 1858 return;
1922 1859
1860 list_for_each_entry(segbuf, logs, sb_list) {
1923 list_for_each_entry(bh, &segbuf->sb_segsum_buffers, 1861 list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
1924 b_assoc_buffers) { 1862 b_assoc_buffers) {
1925 if (bh->b_page != bd_page) { 1863 if (bh->b_page != bd_page) {
@@ -1931,7 +1869,7 @@ static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci,
1931 1869
1932 list_for_each_entry(bh, &segbuf->sb_payload_buffers, 1870 list_for_each_entry(bh, &segbuf->sb_payload_buffers,
1933 b_assoc_buffers) { 1871 b_assoc_buffers) {
1934 if (bh == sci->sc_super_root) { 1872 if (bh == bh_sr) {
1935 if (bh->b_page != bd_page) { 1873 if (bh->b_page != bd_page) {
1936 end_page_writeback(bd_page); 1874 end_page_writeback(bd_page);
1937 bd_page = bh->b_page; 1875 bd_page = bh->b_page;
@@ -1941,7 +1879,7 @@ static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci,
1941 if (bh->b_page != fs_page) { 1879 if (bh->b_page != fs_page) {
1942 nilfs_end_page_io(fs_page, err); 1880 nilfs_end_page_io(fs_page, err);
1943 if (fs_page && fs_page == failed_page) 1881 if (fs_page && fs_page == failed_page)
1944 goto done; 1882 return;
1945 fs_page = bh->b_page; 1883 fs_page = bh->b_page;
1946 } 1884 }
1947 } 1885 }
@@ -1950,8 +1888,33 @@ static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci,
1950 end_page_writeback(bd_page); 1888 end_page_writeback(bd_page);
1951 1889
1952 nilfs_end_page_io(fs_page, err); 1890 nilfs_end_page_io(fs_page, err);
1953 done: 1891}
1892
1893static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
1894 struct the_nilfs *nilfs, int err)
1895{
1896 LIST_HEAD(logs);
1897 int ret;
1898
1899 list_splice_tail_init(&sci->sc_write_logs, &logs);
1900 ret = nilfs_wait_on_logs(&logs);
1901 nilfs_abort_logs(&logs, NULL, sci->sc_super_root, ret ? : err);
1902
1903 list_splice_tail_init(&sci->sc_segbufs, &logs);
1904 nilfs_cancel_segusage(&logs, nilfs->ns_sufile);
1905 nilfs_free_incomplete_logs(&logs, nilfs);
1954 nilfs_clear_copied_buffers(&sci->sc_copied_buffers, err); 1906 nilfs_clear_copied_buffers(&sci->sc_copied_buffers, err);
1907
1908 if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
1909 ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile,
1910 sci->sc_freesegs,
1911 sci->sc_nfreesegs,
1912 NULL);
1913 WARN_ON(ret); /* do not happen */
1914 }
1915
1916 nilfs_destroy_logs(&logs);
1917 sci->sc_super_root = NULL;
1955} 1918}
1956 1919
1957static void nilfs_set_next_segment(struct the_nilfs *nilfs, 1920static void nilfs_set_next_segment(struct the_nilfs *nilfs,
@@ -1969,11 +1932,10 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
1969{ 1932{
1970 struct nilfs_segment_buffer *segbuf; 1933 struct nilfs_segment_buffer *segbuf;
1971 struct page *bd_page = NULL, *fs_page = NULL; 1934 struct page *bd_page = NULL, *fs_page = NULL;
1972 struct nilfs_sb_info *sbi = sci->sc_sbi; 1935 struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs;
1973 struct the_nilfs *nilfs = sbi->s_nilfs;
1974 int update_sr = (sci->sc_super_root != NULL); 1936 int update_sr = (sci->sc_super_root != NULL);
1975 1937
1976 list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { 1938 list_for_each_entry(segbuf, &sci->sc_write_logs, sb_list) {
1977 struct buffer_head *bh; 1939 struct buffer_head *bh;
1978 1940
1979 list_for_each_entry(bh, &segbuf->sb_segsum_buffers, 1941 list_for_each_entry(bh, &segbuf->sb_segsum_buffers,
@@ -2046,21 +2008,34 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
2046 2008
2047 sci->sc_nblk_inc += sci->sc_nblk_this_inc; 2009 sci->sc_nblk_inc += sci->sc_nblk_this_inc;
2048 2010
2049 segbuf = NILFS_LAST_SEGBUF(&sci->sc_segbufs); 2011 segbuf = NILFS_LAST_SEGBUF(&sci->sc_write_logs);
2050 nilfs_set_next_segment(nilfs, segbuf); 2012 nilfs_set_next_segment(nilfs, segbuf);
2051 2013
2052 if (update_sr) { 2014 if (update_sr) {
2053 nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start, 2015 nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start,
2054 segbuf->sb_sum.seg_seq, nilfs->ns_cno++); 2016 segbuf->sb_sum.seg_seq, nilfs->ns_cno++);
2055 sbi->s_super->s_dirt = 1; 2017 set_nilfs_sb_dirty(nilfs);
2056 2018
2057 clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags); 2019 clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags);
2058 clear_bit(NILFS_SC_DIRTY, &sci->sc_flags); 2020 clear_bit(NILFS_SC_DIRTY, &sci->sc_flags);
2059 set_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags); 2021 set_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags);
2022 nilfs_segctor_clear_metadata_dirty(sci);
2060 } else 2023 } else
2061 clear_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags); 2024 clear_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags);
2062} 2025}
2063 2026
2027static int nilfs_segctor_wait(struct nilfs_sc_info *sci)
2028{
2029 int ret;
2030
2031 ret = nilfs_wait_on_logs(&sci->sc_write_logs);
2032 if (!ret) {
2033 nilfs_segctor_complete_write(sci);
2034 nilfs_destroy_logs(&sci->sc_write_logs);
2035 }
2036 return ret;
2037}
2038
2064static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci, 2039static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci,
2065 struct nilfs_sb_info *sbi) 2040 struct nilfs_sb_info *sbi)
2066{ 2041{
@@ -2173,7 +2148,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
2173 /* Avoid empty segment */ 2148 /* Avoid empty segment */
2174 if (sci->sc_stage.scnt == NILFS_ST_DONE && 2149 if (sci->sc_stage.scnt == NILFS_ST_DONE &&
2175 NILFS_SEG_EMPTY(&sci->sc_curseg->sb_sum)) { 2150 NILFS_SEG_EMPTY(&sci->sc_curseg->sb_sum)) {
2176 nilfs_segctor_end_construction(sci, nilfs, 1); 2151 nilfs_segctor_abort_construction(sci, nilfs, 1);
2177 goto out; 2152 goto out;
2178 } 2153 }
2179 2154
@@ -2187,7 +2162,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
2187 if (has_sr) { 2162 if (has_sr) {
2188 err = nilfs_segctor_fill_in_checkpoint(sci); 2163 err = nilfs_segctor_fill_in_checkpoint(sci);
2189 if (unlikely(err)) 2164 if (unlikely(err))
2190 goto failed_to_make_up; 2165 goto failed_to_write;
2191 2166
2192 nilfs_segctor_fill_in_super_root(sci, nilfs); 2167 nilfs_segctor_fill_in_super_root(sci, nilfs);
2193 } 2168 }
@@ -2195,47 +2170,51 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
2195 2170
2196 /* Write partial segments */ 2171 /* Write partial segments */
2197 err = nilfs_segctor_prepare_write(sci, &failed_page); 2172 err = nilfs_segctor_prepare_write(sci, &failed_page);
2198 if (unlikely(err)) 2173 if (err) {
2174 nilfs_abort_logs(&sci->sc_segbufs, failed_page,
2175 sci->sc_super_root, err);
2199 goto failed_to_write; 2176 goto failed_to_write;
2200 2177 }
2201 nilfs_segctor_fill_in_checksums(sci, nilfs->ns_crc_seed); 2178 nilfs_segctor_fill_in_checksums(sci, nilfs->ns_crc_seed);
2202 2179
2203 err = nilfs_segctor_write(sci, nilfs->ns_bdi); 2180 err = nilfs_segctor_write(sci, nilfs);
2204 if (unlikely(err)) 2181 if (unlikely(err))
2205 goto failed_to_write; 2182 goto failed_to_write;
2206 2183
2207 nilfs_segctor_complete_write(sci); 2184 if (sci->sc_stage.scnt == NILFS_ST_DONE ||
2208 2185 nilfs->ns_blocksize_bits != PAGE_CACHE_SHIFT) {
2209 /* Commit segments */ 2186 /*
2210 if (has_sr) 2187 * At this point, we avoid double buffering
2211 nilfs_segctor_clear_metadata_dirty(sci); 2188 * for blocksize < pagesize because page dirty
2212 2189 * flag is turned off during write and dirty
2213 nilfs_segctor_end_construction(sci, nilfs, 0); 2190 * buffers are not properly collected for
2214 2191 * pages crossing over segments.
2192 */
2193 err = nilfs_segctor_wait(sci);
2194 if (err)
2195 goto failed_to_write;
2196 }
2215 } while (sci->sc_stage.scnt != NILFS_ST_DONE); 2197 } while (sci->sc_stage.scnt != NILFS_ST_DONE);
2216 2198
2199 sci->sc_super_root = NULL;
2200
2217 out: 2201 out:
2218 nilfs_segctor_destroy_segment_buffers(sci);
2219 nilfs_segctor_check_out_files(sci, sbi); 2202 nilfs_segctor_check_out_files(sci, sbi);
2220 return err; 2203 return err;
2221 2204
2222 failed_to_write: 2205 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) 2206 if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
2228 nilfs_redirty_inodes(&sci->sc_dirty_files); 2207 nilfs_redirty_inodes(&sci->sc_dirty_files);
2229 2208
2230 failed: 2209 failed:
2231 if (nilfs_doing_gc()) 2210 if (nilfs_doing_gc())
2232 nilfs_redirty_inodes(&sci->sc_gc_inodes); 2211 nilfs_redirty_inodes(&sci->sc_gc_inodes);
2233 nilfs_segctor_end_construction(sci, nilfs, err); 2212 nilfs_segctor_abort_construction(sci, nilfs, err);
2234 goto out; 2213 goto out;
2235} 2214}
2236 2215
2237/** 2216/**
2238 * nilfs_secgtor_start_timer - set timer of background write 2217 * nilfs_segctor_start_timer - set timer of background write
2239 * @sci: nilfs_sc_info 2218 * @sci: nilfs_sc_info
2240 * 2219 *
2241 * If the timer has already been set, it ignores the new request. 2220 * If the timer has already been set, it ignores the new request.
@@ -2440,43 +2419,43 @@ int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode,
2440 return err; 2419 return err;
2441} 2420}
2442 2421
2443struct nilfs_segctor_req {
2444 int mode;
2445 __u32 seq_accepted;
2446 int sc_err; /* construction failure */
2447 int sb_err; /* super block writeback failure */
2448};
2449
2450#define FLUSH_FILE_BIT (0x1) /* data file only */ 2422#define FLUSH_FILE_BIT (0x1) /* data file only */
2451#define FLUSH_DAT_BIT (1 << NILFS_DAT_INO) /* DAT only */ 2423#define FLUSH_DAT_BIT (1 << NILFS_DAT_INO) /* DAT only */
2452 2424
2453static void nilfs_segctor_accept(struct nilfs_sc_info *sci, 2425/**
2454 struct nilfs_segctor_req *req) 2426 * nilfs_segctor_accept - record accepted sequence count of log-write requests
2427 * @sci: segment constructor object
2428 */
2429static void nilfs_segctor_accept(struct nilfs_sc_info *sci)
2455{ 2430{
2456 req->sc_err = req->sb_err = 0;
2457 spin_lock(&sci->sc_state_lock); 2431 spin_lock(&sci->sc_state_lock);
2458 req->seq_accepted = sci->sc_seq_request; 2432 sci->sc_seq_accepted = sci->sc_seq_request;
2459 spin_unlock(&sci->sc_state_lock); 2433 spin_unlock(&sci->sc_state_lock);
2460 2434
2461 if (sci->sc_timer) 2435 if (sci->sc_timer)
2462 del_timer_sync(sci->sc_timer); 2436 del_timer_sync(sci->sc_timer);
2463} 2437}
2464 2438
2465static void nilfs_segctor_notify(struct nilfs_sc_info *sci, 2439/**
2466 struct nilfs_segctor_req *req) 2440 * nilfs_segctor_notify - notify the result of request to caller threads
2441 * @sci: segment constructor object
2442 * @mode: mode of log forming
2443 * @err: error code to be notified
2444 */
2445static void nilfs_segctor_notify(struct nilfs_sc_info *sci, int mode, int err)
2467{ 2446{
2468 /* Clear requests (even when the construction failed) */ 2447 /* Clear requests (even when the construction failed) */
2469 spin_lock(&sci->sc_state_lock); 2448 spin_lock(&sci->sc_state_lock);
2470 2449
2471 if (req->mode == SC_LSEG_SR) { 2450 if (mode == SC_LSEG_SR) {
2472 sci->sc_state &= ~NILFS_SEGCTOR_COMMIT; 2451 sci->sc_state &= ~NILFS_SEGCTOR_COMMIT;
2473 sci->sc_seq_done = req->seq_accepted; 2452 sci->sc_seq_done = sci->sc_seq_accepted;
2474 nilfs_segctor_wakeup(sci, req->sc_err ? : req->sb_err); 2453 nilfs_segctor_wakeup(sci, err);
2475 sci->sc_flush_request = 0; 2454 sci->sc_flush_request = 0;
2476 } else { 2455 } else {
2477 if (req->mode == SC_FLUSH_FILE) 2456 if (mode == SC_FLUSH_FILE)
2478 sci->sc_flush_request &= ~FLUSH_FILE_BIT; 2457 sci->sc_flush_request &= ~FLUSH_FILE_BIT;
2479 else if (req->mode == SC_FLUSH_DAT) 2458 else if (mode == SC_FLUSH_DAT)
2480 sci->sc_flush_request &= ~FLUSH_DAT_BIT; 2459 sci->sc_flush_request &= ~FLUSH_DAT_BIT;
2481 2460
2482 /* re-enable timer if checkpoint creation was not done */ 2461 /* re-enable timer if checkpoint creation was not done */
@@ -2487,30 +2466,37 @@ static void nilfs_segctor_notify(struct nilfs_sc_info *sci,
2487 spin_unlock(&sci->sc_state_lock); 2466 spin_unlock(&sci->sc_state_lock);
2488} 2467}
2489 2468
2490static int nilfs_segctor_construct(struct nilfs_sc_info *sci, 2469/**
2491 struct nilfs_segctor_req *req) 2470 * nilfs_segctor_construct - form logs and write them to disk
2471 * @sci: segment constructor object
2472 * @mode: mode of log forming
2473 */
2474static int nilfs_segctor_construct(struct nilfs_sc_info *sci, int mode)
2492{ 2475{
2493 struct nilfs_sb_info *sbi = sci->sc_sbi; 2476 struct nilfs_sb_info *sbi = sci->sc_sbi;
2494 struct the_nilfs *nilfs = sbi->s_nilfs; 2477 struct the_nilfs *nilfs = sbi->s_nilfs;
2495 int err = 0; 2478 int err = 0;
2496 2479
2480 nilfs_segctor_accept(sci);
2481
2497 if (nilfs_discontinued(nilfs)) 2482 if (nilfs_discontinued(nilfs))
2498 req->mode = SC_LSEG_SR; 2483 mode = SC_LSEG_SR;
2499 if (!nilfs_segctor_confirm(sci)) { 2484 if (!nilfs_segctor_confirm(sci))
2500 err = nilfs_segctor_do_construct(sci, req->mode); 2485 err = nilfs_segctor_do_construct(sci, mode);
2501 req->sc_err = err; 2486
2502 }
2503 if (likely(!err)) { 2487 if (likely(!err)) {
2504 if (req->mode != SC_FLUSH_DAT) 2488 if (mode != SC_FLUSH_DAT)
2505 atomic_set(&nilfs->ns_ndirtyblks, 0); 2489 atomic_set(&nilfs->ns_ndirtyblks, 0);
2506 if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) && 2490 if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) &&
2507 nilfs_discontinued(nilfs)) { 2491 nilfs_discontinued(nilfs)) {
2508 down_write(&nilfs->ns_sem); 2492 down_write(&nilfs->ns_sem);
2509 req->sb_err = nilfs_commit_super(sbi, 2493 err = nilfs_commit_super(
2510 nilfs_altsb_need_update(nilfs)); 2494 sbi, nilfs_altsb_need_update(nilfs));
2511 up_write(&nilfs->ns_sem); 2495 up_write(&nilfs->ns_sem);
2512 } 2496 }
2513 } 2497 }
2498
2499 nilfs_segctor_notify(sci, mode, err);
2514 return err; 2500 return err;
2515} 2501}
2516 2502
@@ -2541,7 +2527,6 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
2541 struct nilfs_sc_info *sci = NILFS_SC(sbi); 2527 struct nilfs_sc_info *sci = NILFS_SC(sbi);
2542 struct the_nilfs *nilfs = sbi->s_nilfs; 2528 struct the_nilfs *nilfs = sbi->s_nilfs;
2543 struct nilfs_transaction_info ti; 2529 struct nilfs_transaction_info ti;
2544 struct nilfs_segctor_req req = { .mode = SC_LSEG_SR };
2545 int err; 2530 int err;
2546 2531
2547 if (unlikely(!sci)) 2532 if (unlikely(!sci))
@@ -2559,13 +2544,11 @@ 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 err = nilfs_segctor_construct(sci, SC_LSEG_SR);
2566 err = nilfs_segctor_construct(sci, &req);
2567 nilfs_remove_written_gcinodes(nilfs, &sci->sc_gc_inodes); 2551 nilfs_remove_written_gcinodes(nilfs, &sci->sc_gc_inodes);
2568 nilfs_segctor_notify(sci, &req);
2569 2552
2570 if (likely(!err)) 2553 if (likely(!err))
2571 break; 2554 break;
@@ -2575,6 +2558,16 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
2575 set_current_state(TASK_INTERRUPTIBLE); 2558 set_current_state(TASK_INTERRUPTIBLE);
2576 schedule_timeout(sci->sc_interval); 2559 schedule_timeout(sci->sc_interval);
2577 } 2560 }
2561 if (nilfs_test_opt(sbi, DISCARD)) {
2562 int ret = nilfs_discard_segments(nilfs, sci->sc_freesegs,
2563 sci->sc_nfreesegs);
2564 if (ret) {
2565 printk(KERN_WARNING
2566 "NILFS warning: error %d on discard request, "
2567 "turning discards off for the device\n", ret);
2568 nilfs_clear_opt(sbi, DISCARD);
2569 }
2570 }
2578 2571
2579 out_unlock: 2572 out_unlock:
2580 sci->sc_freesegs = NULL; 2573 sci->sc_freesegs = NULL;
@@ -2588,13 +2581,9 @@ static void nilfs_segctor_thread_construct(struct nilfs_sc_info *sci, int mode)
2588{ 2581{
2589 struct nilfs_sb_info *sbi = sci->sc_sbi; 2582 struct nilfs_sb_info *sbi = sci->sc_sbi;
2590 struct nilfs_transaction_info ti; 2583 struct nilfs_transaction_info ti;
2591 struct nilfs_segctor_req req = { .mode = mode };
2592 2584
2593 nilfs_transaction_lock(sbi, &ti, 0); 2585 nilfs_transaction_lock(sbi, &ti, 0);
2594 2586 nilfs_segctor_construct(sci, mode);
2595 nilfs_segctor_accept(sci, &req);
2596 nilfs_segctor_construct(sci, &req);
2597 nilfs_segctor_notify(sci, &req);
2598 2587
2599 /* 2588 /*
2600 * Unclosed segment should be retried. We do this using sc_timer. 2589 * Unclosed segment should be retried. We do this using sc_timer.
@@ -2650,6 +2639,7 @@ static int nilfs_segctor_flush_mode(struct nilfs_sc_info *sci)
2650static int nilfs_segctor_thread(void *arg) 2639static int nilfs_segctor_thread(void *arg)
2651{ 2640{
2652 struct nilfs_sc_info *sci = (struct nilfs_sc_info *)arg; 2641 struct nilfs_sc_info *sci = (struct nilfs_sc_info *)arg;
2642 struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs;
2653 struct timer_list timer; 2643 struct timer_list timer;
2654 int timeout = 0; 2644 int timeout = 0;
2655 2645
@@ -2695,7 +2685,6 @@ static int nilfs_segctor_thread(void *arg)
2695 } else { 2685 } else {
2696 DEFINE_WAIT(wait); 2686 DEFINE_WAIT(wait);
2697 int should_sleep = 1; 2687 int should_sleep = 1;
2698 struct the_nilfs *nilfs;
2699 2688
2700 prepare_to_wait(&sci->sc_wait_daemon, &wait, 2689 prepare_to_wait(&sci->sc_wait_daemon, &wait,
2701 TASK_INTERRUPTIBLE); 2690 TASK_INTERRUPTIBLE);
@@ -2716,8 +2705,8 @@ static int nilfs_segctor_thread(void *arg)
2716 finish_wait(&sci->sc_wait_daemon, &wait); 2705 finish_wait(&sci->sc_wait_daemon, &wait);
2717 timeout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) && 2706 timeout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) &&
2718 time_after_eq(jiffies, sci->sc_timer->expires)); 2707 time_after_eq(jiffies, sci->sc_timer->expires));
2719 nilfs = sci->sc_sbi->s_nilfs; 2708
2720 if (sci->sc_super->s_dirt && nilfs_sb_need_update(nilfs)) 2709 if (nilfs_sb_dirty(nilfs) && nilfs_sb_need_update(nilfs))
2721 set_nilfs_discontinued(nilfs); 2710 set_nilfs_discontinued(nilfs);
2722 } 2711 }
2723 goto loop; 2712 goto loop;
@@ -2788,6 +2777,7 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi)
2788 spin_lock_init(&sci->sc_state_lock); 2777 spin_lock_init(&sci->sc_state_lock);
2789 INIT_LIST_HEAD(&sci->sc_dirty_files); 2778 INIT_LIST_HEAD(&sci->sc_dirty_files);
2790 INIT_LIST_HEAD(&sci->sc_segbufs); 2779 INIT_LIST_HEAD(&sci->sc_segbufs);
2780 INIT_LIST_HEAD(&sci->sc_write_logs);
2791 INIT_LIST_HEAD(&sci->sc_gc_inodes); 2781 INIT_LIST_HEAD(&sci->sc_gc_inodes);
2792 INIT_LIST_HEAD(&sci->sc_copied_buffers); 2782 INIT_LIST_HEAD(&sci->sc_copied_buffers);
2793 2783
@@ -2811,12 +2801,9 @@ static void nilfs_segctor_write_out(struct nilfs_sc_info *sci)
2811 do { 2801 do {
2812 struct nilfs_sb_info *sbi = sci->sc_sbi; 2802 struct nilfs_sb_info *sbi = sci->sc_sbi;
2813 struct nilfs_transaction_info ti; 2803 struct nilfs_transaction_info ti;
2814 struct nilfs_segctor_req req = { .mode = SC_LSEG_SR };
2815 2804
2816 nilfs_transaction_lock(sbi, &ti, 0); 2805 nilfs_transaction_lock(sbi, &ti, 0);
2817 nilfs_segctor_accept(sci, &req); 2806 ret = nilfs_segctor_construct(sci, SC_LSEG_SR);
2818 ret = nilfs_segctor_construct(sci, &req);
2819 nilfs_segctor_notify(sci, &req);
2820 nilfs_transaction_unlock(sbi); 2807 nilfs_transaction_unlock(sbi);
2821 2808
2822 } while (ret && retrycount-- > 0); 2809 } while (ret && retrycount-- > 0);
@@ -2843,7 +2830,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
2843 || sci->sc_seq_request != sci->sc_seq_done); 2830 || sci->sc_seq_request != sci->sc_seq_done);
2844 spin_unlock(&sci->sc_state_lock); 2831 spin_unlock(&sci->sc_state_lock);
2845 2832
2846 if (flag || nilfs_segctor_confirm(sci)) 2833 if (flag || !nilfs_segctor_confirm(sci))
2847 nilfs_segctor_write_out(sci); 2834 nilfs_segctor_write_out(sci);
2848 2835
2849 WARN_ON(!list_empty(&sci->sc_copied_buffers)); 2836 WARN_ON(!list_empty(&sci->sc_copied_buffers));
@@ -2855,6 +2842,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
2855 } 2842 }
2856 2843
2857 WARN_ON(!list_empty(&sci->sc_segbufs)); 2844 WARN_ON(!list_empty(&sci->sc_segbufs));
2845 WARN_ON(!list_empty(&sci->sc_write_logs));
2858 2846
2859 down_write(&sbi->s_nilfs->ns_segctor_sem); 2847 down_write(&sbi->s_nilfs->ns_segctor_sem);
2860 2848
@@ -2866,7 +2854,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
2866 * @sbi: nilfs_sb_info 2854 * @sbi: nilfs_sb_info
2867 * 2855 *
2868 * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info, 2856 * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info,
2869 * initilizes it, and starts the segment constructor. 2857 * initializes it, and starts the segment constructor.
2870 * 2858 *
2871 * Return Value: On success, 0 is returned. On error, one of the following 2859 * Return Value: On success, 0 is returned. On error, one of the following
2872 * negative error code is returned. 2860 * negative error code is returned.
@@ -2878,8 +2866,15 @@ int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi)
2878 struct the_nilfs *nilfs = sbi->s_nilfs; 2866 struct the_nilfs *nilfs = sbi->s_nilfs;
2879 int err; 2867 int err;
2880 2868
2881 /* Each field of nilfs_segctor is cleared through the initialization 2869 if (NILFS_SC(sbi)) {
2882 of super-block info */ 2870 /*
2871 * This happens if the filesystem was remounted
2872 * read/write after nilfs_error degenerated it into a
2873 * read-only mount.
2874 */
2875 nilfs_detach_segment_constructor(sbi);
2876 }
2877
2883 sbi->s_sc_info = nilfs_segctor_new(sbi); 2878 sbi->s_sc_info = nilfs_segctor_new(sbi);
2884 if (!sbi->s_sc_info) 2879 if (!sbi->s_sc_info)
2885 return -ENOMEM; 2880 return -ENOMEM;
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
index 0d2a475a741b..82dfd6a686b9 100644
--- a/fs/nilfs2/segment.h
+++ b/fs/nilfs2/segment.h
@@ -30,7 +30,7 @@
30#include "sb.h" 30#include "sb.h"
31 31
32/** 32/**
33 * struct nilfs_recovery_info - Recovery infomation 33 * struct nilfs_recovery_info - Recovery information
34 * @ri_need_recovery: Recovery status 34 * @ri_need_recovery: Recovery status
35 * @ri_super_root: Block number of the last super root 35 * @ri_super_root: Block number of the last super root
36 * @ri_ri_cno: Number of the last checkpoint 36 * @ri_ri_cno: Number of the last checkpoint
@@ -71,7 +71,7 @@ struct nilfs_recovery_info {
71 */ 71 */
72struct nilfs_cstage { 72struct nilfs_cstage {
73 int scnt; 73 int scnt;
74 unsigned flags; 74 unsigned flags;
75 struct nilfs_inode_info *dirty_file_ptr; 75 struct nilfs_inode_info *dirty_file_ptr;
76 struct nilfs_inode_info *gc_inode_ptr; 76 struct nilfs_inode_info *gc_inode_ptr;
77}; 77};
@@ -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
@@ -115,6 +116,7 @@ struct nilfs_segsum_pointer {
115 * @sc_wait_daemon: Daemon wait queue 116 * @sc_wait_daemon: Daemon wait queue
116 * @sc_wait_task: Start/end wait queue to control segctord task 117 * @sc_wait_task: Start/end wait queue to control segctord task
117 * @sc_seq_request: Request counter 118 * @sc_seq_request: Request counter
119 * @sc_seq_accept: Accepted request count
118 * @sc_seq_done: Completion counter 120 * @sc_seq_done: Completion counter
119 * @sc_sync: Request of explicit sync operation 121 * @sc_sync: Request of explicit sync operation
120 * @sc_interval: Timeout value of background construction 122 * @sc_interval: Timeout value of background construction
@@ -143,6 +145,7 @@ struct nilfs_sc_info {
143 145
144 /* Segment buffers */ 146 /* Segment buffers */
145 struct list_head sc_segbufs; 147 struct list_head sc_segbufs;
148 struct list_head sc_write_logs;
146 unsigned long sc_segbuf_nblocks; 149 unsigned long sc_segbuf_nblocks;
147 struct nilfs_segment_buffer *sc_curseg; 150 struct nilfs_segment_buffer *sc_curseg;
148 struct buffer_head *sc_super_root; 151 struct buffer_head *sc_super_root;
@@ -167,6 +170,7 @@ struct nilfs_sc_info {
167 wait_queue_head_t sc_wait_task; 170 wait_queue_head_t sc_wait_task;
168 171
169 __u32 sc_seq_request; 172 __u32 sc_seq_request;
173 __u32 sc_seq_accepted;
170 __u32 sc_seq_done; 174 __u32 sc_seq_done;
171 175
172 int sc_sync; 176 int sc_sync;
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
index 37994d4a59cc..3c6cc6005c2e 100644
--- a/fs/nilfs2/sufile.c
+++ b/fs/nilfs2/sufile.c
@@ -18,7 +18,7 @@
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * 19 *
20 * Written by Koji Sato <koji@osrg.net>. 20 * Written by Koji Sato <koji@osrg.net>.
21 * Rivised by Ryusuke Konishi <ryusuke@osrg.net>. 21 * Revised by Ryusuke Konishi <ryusuke@osrg.net>.
22 */ 22 */
23 23
24#include <linux/kernel.h> 24#include <linux/kernel.h>
@@ -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..0cdbc5e7655a 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -96,9 +96,6 @@ void nilfs_error(struct super_block *sb, const char *function,
96 if (!(sb->s_flags & MS_RDONLY)) { 96 if (!(sb->s_flags & MS_RDONLY)) {
97 struct the_nilfs *nilfs = sbi->s_nilfs; 97 struct the_nilfs *nilfs = sbi->s_nilfs;
98 98
99 if (!nilfs_test_opt(sbi, ERRORS_CONT))
100 nilfs_detach_segment_constructor(sbi);
101
102 down_write(&nilfs->ns_sem); 99 down_write(&nilfs->ns_sem);
103 if (!(nilfs->ns_mount_state & NILFS_ERROR_FS)) { 100 if (!(nilfs->ns_mount_state & NILFS_ERROR_FS)) {
104 nilfs->ns_mount_state |= NILFS_ERROR_FS; 101 nilfs->ns_mount_state |= NILFS_ERROR_FS;
@@ -301,7 +298,7 @@ int nilfs_commit_super(struct nilfs_sb_info *sbi, int dupsb)
301 memcpy(sbp[1], sbp[0], nilfs->ns_sbsize); 298 memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
302 nilfs->ns_sbwtime[1] = t; 299 nilfs->ns_sbwtime[1] = t;
303 } 300 }
304 sbi->s_super->s_dirt = 0; 301 clear_nilfs_sb_dirty(nilfs);
305 return nilfs_sync_super(sbi, dupsb); 302 return nilfs_sync_super(sbi, dupsb);
306} 303}
307 304
@@ -345,7 +342,7 @@ static int nilfs_sync_fs(struct super_block *sb, int wait)
345 err = nilfs_construct_segment(sb); 342 err = nilfs_construct_segment(sb);
346 343
347 down_write(&nilfs->ns_sem); 344 down_write(&nilfs->ns_sem);
348 if (sb->s_dirt) 345 if (nilfs_sb_dirty(nilfs))
349 nilfs_commit_super(sbi, 1); 346 nilfs_commit_super(sbi, 1);
350 up_write(&nilfs->ns_sem); 347 up_write(&nilfs->ns_sem);
351 348
@@ -363,14 +360,10 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno)
363 list_add(&sbi->s_list, &nilfs->ns_supers); 360 list_add(&sbi->s_list, &nilfs->ns_supers);
364 up_write(&nilfs->ns_super_sem); 361 up_write(&nilfs->ns_super_sem);
365 362
366 sbi->s_ifile = nilfs_mdt_new(nilfs, sbi->s_super, NILFS_IFILE_INO); 363 sbi->s_ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size);
367 if (!sbi->s_ifile) 364 if (!sbi->s_ifile)
368 return -ENOMEM; 365 return -ENOMEM;
369 366
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); 367 down_read(&nilfs->ns_segctor_sem);
375 err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp, 368 err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp,
376 &bh_cp); 369 &bh_cp);
@@ -411,7 +404,6 @@ void nilfs_detach_checkpoint(struct nilfs_sb_info *sbi)
411{ 404{
412 struct the_nilfs *nilfs = sbi->s_nilfs; 405 struct the_nilfs *nilfs = sbi->s_nilfs;
413 406
414 nilfs_mdt_clear(sbi->s_ifile);
415 nilfs_mdt_destroy(sbi->s_ifile); 407 nilfs_mdt_destroy(sbi->s_ifile);
416 sbi->s_ifile = NULL; 408 sbi->s_ifile = NULL;
417 down_write(&nilfs->ns_super_sem); 409 down_write(&nilfs->ns_super_sem);
@@ -419,22 +411,6 @@ void nilfs_detach_checkpoint(struct nilfs_sb_info *sbi)
419 up_write(&nilfs->ns_super_sem); 411 up_write(&nilfs->ns_super_sem);
420} 412}
421 413
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) 414static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf)
439{ 415{
440 struct super_block *sb = dentry->d_sb; 416 struct super_block *sb = dentry->d_sb;
@@ -460,7 +436,7 @@ static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf)
460 /* 436 /*
461 * Compute the overhead 437 * Compute the overhead
462 * 438 *
463 * When distributing meta data blocks outside semgent structure, 439 * When distributing meta data blocks outside segment structure,
464 * We must count them as the overhead. 440 * We must count them as the overhead.
465 */ 441 */
466 overhead = 0; 442 overhead = 0;
@@ -490,7 +466,7 @@ static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
490 struct nilfs_sb_info *sbi = NILFS_SB(sb); 466 struct nilfs_sb_info *sbi = NILFS_SB(sb);
491 467
492 if (!nilfs_test_opt(sbi, BARRIER)) 468 if (!nilfs_test_opt(sbi, BARRIER))
493 seq_printf(seq, ",barrier=off"); 469 seq_printf(seq, ",nobarrier");
494 if (nilfs_test_opt(sbi, SNAPSHOT)) 470 if (nilfs_test_opt(sbi, SNAPSHOT))
495 seq_printf(seq, ",cp=%llu", 471 seq_printf(seq, ",cp=%llu",
496 (unsigned long long int)sbi->s_snapshot_cno); 472 (unsigned long long int)sbi->s_snapshot_cno);
@@ -500,6 +476,10 @@ static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
500 seq_printf(seq, ",errors=panic"); 476 seq_printf(seq, ",errors=panic");
501 if (nilfs_test_opt(sbi, STRICT_ORDER)) 477 if (nilfs_test_opt(sbi, STRICT_ORDER))
502 seq_printf(seq, ",order=strict"); 478 seq_printf(seq, ",order=strict");
479 if (nilfs_test_opt(sbi, NORECOVERY))
480 seq_printf(seq, ",norecovery");
481 if (nilfs_test_opt(sbi, DISCARD))
482 seq_printf(seq, ",discard");
503 483
504 return 0; 484 return 0;
505} 485}
@@ -568,33 +548,22 @@ static const struct export_operations nilfs_export_ops = {
568 548
569enum { 549enum {
570 Opt_err_cont, Opt_err_panic, Opt_err_ro, 550 Opt_err_cont, Opt_err_panic, Opt_err_ro,
571 Opt_barrier, Opt_snapshot, Opt_order, 551 Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery,
572 Opt_err, 552 Opt_discard, Opt_err,
573}; 553};
574 554
575static match_table_t tokens = { 555static match_table_t tokens = {
576 {Opt_err_cont, "errors=continue"}, 556 {Opt_err_cont, "errors=continue"},
577 {Opt_err_panic, "errors=panic"}, 557 {Opt_err_panic, "errors=panic"},
578 {Opt_err_ro, "errors=remount-ro"}, 558 {Opt_err_ro, "errors=remount-ro"},
579 {Opt_barrier, "barrier=%s"}, 559 {Opt_nobarrier, "nobarrier"},
580 {Opt_snapshot, "cp=%u"}, 560 {Opt_snapshot, "cp=%u"},
581 {Opt_order, "order=%s"}, 561 {Opt_order, "order=%s"},
562 {Opt_norecovery, "norecovery"},
563 {Opt_discard, "discard"},
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,12 @@ 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;
617 case Opt_discard:
618 nilfs_set_opt(sbi, DISCARD);
619 break;
650 default: 620 default:
651 printk(KERN_ERR 621 printk(KERN_ERR
652 "NILFS: Unrecognized mount option \"%s\"\n", p); 622 "NILFS: Unrecognized mount option \"%s\"\n", p);
@@ -672,9 +642,7 @@ static int nilfs_setup_super(struct nilfs_sb_info *sbi)
672 int mnt_count = le16_to_cpu(sbp->s_mnt_count); 642 int mnt_count = le16_to_cpu(sbp->s_mnt_count);
673 643
674 /* nilfs->sem must be locked by the caller. */ 644 /* nilfs->sem must be locked by the caller. */
675 if (!(nilfs->ns_mount_state & NILFS_VALID_FS)) { 645 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 646 printk(KERN_WARNING
679 "NILFS warning: mounting fs with errors\n"); 647 "NILFS warning: mounting fs with errors\n");
680#if 0 648#if 0
@@ -782,11 +750,10 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
782 sb->s_root = NULL; 750 sb->s_root = NULL;
783 sb->s_time_gran = 1; 751 sb->s_time_gran = 1;
784 752
785 if (!nilfs_loaded(nilfs)) { 753 err = load_nilfs(nilfs, sbi);
786 err = load_nilfs(nilfs, sbi); 754 if (err)
787 if (err) 755 goto failed_sbi;
788 goto failed_sbi; 756
789 }
790 cno = nilfs_last_cno(nilfs); 757 cno = nilfs_last_cno(nilfs);
791 758
792 if (sb->s_flags & MS_RDONLY) { 759 if (sb->s_flags & MS_RDONLY) {
@@ -854,12 +821,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
854 up_write(&nilfs->ns_sem); 821 up_write(&nilfs->ns_sem);
855 } 822 }
856 823
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); 824 down_write(&nilfs->ns_super_sem);
864 if (!nilfs_test_opt(sbi, SNAPSHOT)) 825 if (!nilfs_test_opt(sbi, SNAPSHOT))
865 nilfs->ns_current = sbi; 826 nilfs->ns_current = sbi;
@@ -867,10 +828,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
867 828
868 return 0; 829 return 0;
869 830
870 failed_root:
871 dput(sb->s_root);
872 sb->s_root = NULL;
873
874 failed_segctor: 831 failed_segctor:
875 nilfs_detach_segment_constructor(sbi); 832 nilfs_detach_segment_constructor(sbi);
876 833
@@ -909,12 +866,20 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
909 if ((*flags & MS_RDONLY) && 866 if ((*flags & MS_RDONLY) &&
910 sbi->s_snapshot_cno != old_opts.snapshot_cno) { 867 sbi->s_snapshot_cno != old_opts.snapshot_cno) {
911 printk(KERN_WARNING "NILFS (device %s): couldn't " 868 printk(KERN_WARNING "NILFS (device %s): couldn't "
912 "remount to a different snapshot. \n", 869 "remount to a different snapshot.\n",
913 sb->s_id); 870 sb->s_id);
914 err = -EINVAL; 871 err = -EINVAL;
915 goto restore_opts; 872 goto restore_opts;
916 } 873 }
917 874
875 if (!nilfs_valid_fs(nilfs)) {
876 printk(KERN_WARNING "NILFS (device %s): couldn't "
877 "remount because the filesystem is in an "
878 "incomplete recovery state.\n", sb->s_id);
879 err = -EINVAL;
880 goto restore_opts;
881 }
882
918 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) 883 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
919 goto out; 884 goto out;
920 if (*flags & MS_RDONLY) { 885 if (*flags & MS_RDONLY) {
@@ -1156,8 +1121,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
1156 /* Abandoning the newly allocated superblock */ 1121 /* Abandoning the newly allocated superblock */
1157 mutex_unlock(&nilfs->ns_mount_mutex); 1122 mutex_unlock(&nilfs->ns_mount_mutex);
1158 put_nilfs(nilfs); 1123 put_nilfs(nilfs);
1159 up_write(&s->s_umount); 1124 deactivate_locked_super(s);
1160 deactivate_super(s);
1161 /* 1125 /*
1162 * deactivate_super() invokes close_bdev_exclusive(). 1126 * deactivate_super() invokes close_bdev_exclusive().
1163 * We must finish all post-cleaning before this call; 1127 * We must finish all post-cleaning before this call;
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index ad391a8c3e7e..33871f7e4f01 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;
321 }
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;
329 } 337 }
338 printk(KERN_INFO "NILFS: recovery complete.\n");
330 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);
@@ -368,7 +386,7 @@ static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
368 386
369 nilfs->ns_blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment); 387 nilfs->ns_blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment);
370 if (nilfs->ns_blocks_per_segment < NILFS_SEG_MIN_BLOCKS) { 388 if (nilfs->ns_blocks_per_segment < NILFS_SEG_MIN_BLOCKS) {
371 printk(KERN_ERR "NILFS: too short segment. \n"); 389 printk(KERN_ERR "NILFS: too short segment.\n");
372 return -EINVAL; 390 return -EINVAL;
373 } 391 }
374 392
@@ -628,34 +646,65 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data)
628 goto out; 646 goto out;
629} 647}
630 648
649int nilfs_discard_segments(struct the_nilfs *nilfs, __u64 *segnump,
650 size_t nsegs)
651{
652 sector_t seg_start, seg_end;
653 sector_t start = 0, nblocks = 0;
654 unsigned int sects_per_block;
655 __u64 *sn;
656 int ret = 0;
657
658 sects_per_block = (1 << nilfs->ns_blocksize_bits) /
659 bdev_logical_block_size(nilfs->ns_bdev);
660 for (sn = segnump; sn < segnump + nsegs; sn++) {
661 nilfs_get_segment_range(nilfs, *sn, &seg_start, &seg_end);
662
663 if (!nblocks) {
664 start = seg_start;
665 nblocks = seg_end - seg_start + 1;
666 } else if (start + nblocks == seg_start) {
667 nblocks += seg_end - seg_start + 1;
668 } else {
669 ret = blkdev_issue_discard(nilfs->ns_bdev,
670 start * sects_per_block,
671 nblocks * sects_per_block,
672 GFP_NOFS,
673 DISCARD_FL_BARRIER);
674 if (ret < 0)
675 return ret;
676 nblocks = 0;
677 }
678 }
679 if (nblocks)
680 ret = blkdev_issue_discard(nilfs->ns_bdev,
681 start * sects_per_block,
682 nblocks * sects_per_block,
683 GFP_NOFS, DISCARD_FL_BARRIER);
684 return ret;
685}
686
631int nilfs_count_free_blocks(struct the_nilfs *nilfs, sector_t *nblocks) 687int nilfs_count_free_blocks(struct the_nilfs *nilfs, sector_t *nblocks)
632{ 688{
633 struct inode *dat = nilfs_dat_inode(nilfs); 689 struct inode *dat = nilfs_dat_inode(nilfs);
634 unsigned long ncleansegs; 690 unsigned long ncleansegs;
635 int err;
636 691
637 down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ 692 down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
638 err = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile, &ncleansegs); 693 ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
639 up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ 694 up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
640 if (likely(!err)) 695 *nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment;
641 *nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment; 696 return 0;
642 return err;
643} 697}
644 698
645int nilfs_near_disk_full(struct the_nilfs *nilfs) 699int nilfs_near_disk_full(struct the_nilfs *nilfs)
646{ 700{
647 struct inode *sufile = nilfs->ns_sufile;
648 unsigned long ncleansegs, nincsegs; 701 unsigned long ncleansegs, nincsegs;
649 int ret;
650 702
651 ret = nilfs_sufile_get_ncleansegs(sufile, &ncleansegs); 703 ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
652 if (likely(!ret)) { 704 nincsegs = atomic_read(&nilfs->ns_ndirtyblks) /
653 nincsegs = atomic_read(&nilfs->ns_ndirtyblks) / 705 nilfs->ns_blocks_per_segment + 1;
654 nilfs->ns_blocks_per_segment + 1; 706
655 if (ncleansegs <= nilfs->ns_nrsvsegs + nincsegs) 707 return ncleansegs <= nilfs->ns_nrsvsegs + nincsegs;
656 ret++;
657 }
658 return ret;
659} 708}
660 709
661/** 710/**
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
index 20abd55881e0..1ab974533697 100644
--- a/fs/nilfs2/the_nilfs.h
+++ b/fs/nilfs2/the_nilfs.h
@@ -29,6 +29,7 @@
29#include <linux/fs.h> 29#include <linux/fs.h>
30#include <linux/blkdev.h> 30#include <linux/blkdev.h>
31#include <linux/backing-dev.h> 31#include <linux/backing-dev.h>
32#include <linux/slab.h>
32#include "sb.h" 33#include "sb.h"
33 34
34/* the_nilfs struct */ 35/* the_nilfs struct */
@@ -38,6 +39,7 @@ enum {
38 the latest checkpoint was loaded */ 39 the latest checkpoint was loaded */
39 THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */ 40 THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */
40 THE_NILFS_GC_RUNNING, /* gc process is running */ 41 THE_NILFS_GC_RUNNING, /* gc process is running */
42 THE_NILFS_SB_DIRTY, /* super block is dirty */
41}; 43};
42 44
43/** 45/**
@@ -197,6 +199,7 @@ THE_NILFS_FNS(INIT, init)
197THE_NILFS_FNS(LOADED, loaded) 199THE_NILFS_FNS(LOADED, loaded)
198THE_NILFS_FNS(DISCONTINUED, discontinued) 200THE_NILFS_FNS(DISCONTINUED, discontinued)
199THE_NILFS_FNS(GC_RUNNING, gc_running) 201THE_NILFS_FNS(GC_RUNNING, gc_running)
202THE_NILFS_FNS(SB_DIRTY, sb_dirty)
200 203
201/* Minimum interval of periodical update of superblocks (in seconds) */ 204/* Minimum interval of periodical update of superblocks (in seconds) */
202#define NILFS_SB_FREQ 10 205#define NILFS_SB_FREQ 10
@@ -221,6 +224,7 @@ struct the_nilfs *find_or_create_nilfs(struct block_device *);
221void put_nilfs(struct the_nilfs *); 224void put_nilfs(struct the_nilfs *);
222int init_nilfs(struct the_nilfs *, struct nilfs_sb_info *, char *); 225int init_nilfs(struct the_nilfs *, struct nilfs_sb_info *, char *);
223int load_nilfs(struct the_nilfs *, struct nilfs_sb_info *); 226int load_nilfs(struct the_nilfs *, struct nilfs_sb_info *);
227int nilfs_discard_segments(struct the_nilfs *, __u64 *, size_t);
224int nilfs_count_free_blocks(struct the_nilfs *, sector_t *); 228int nilfs_count_free_blocks(struct the_nilfs *, sector_t *);
225struct nilfs_sb_info *nilfs_find_sbinfo(struct the_nilfs *, int, __u64); 229struct nilfs_sb_info *nilfs_find_sbinfo(struct the_nilfs *, int, __u64);
226int nilfs_checkpoint_is_mounted(struct the_nilfs *, __u64, int); 230int nilfs_checkpoint_is_mounted(struct the_nilfs *, __u64, int);
@@ -258,6 +262,16 @@ static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi)
258 kfree(sbi); 262 kfree(sbi);
259} 263}
260 264
265static inline int nilfs_valid_fs(struct the_nilfs *nilfs)
266{
267 unsigned valid_fs;
268
269 down_read(&nilfs->ns_sem);
270 valid_fs = (nilfs->ns_mount_state & NILFS_VALID_FS);
271 up_read(&nilfs->ns_sem);
272 return valid_fs;
273}
274
261static inline void 275static inline void
262nilfs_get_segment_range(struct the_nilfs *nilfs, __u64 segnum, 276nilfs_get_segment_range(struct the_nilfs *nilfs, __u64 segnum,
263 sector_t *seg_start, sector_t *seg_end) 277 sector_t *seg_start, sector_t *seg_end)