aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/btnode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2/btnode.c')
-rw-r--r--fs/nilfs2/btnode.c76
1 files changed, 34 insertions, 42 deletions
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index 84c25382f8e3..471e269536ae 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -68,9 +68,34 @@ void nilfs_btnode_cache_clear(struct address_space *btnc)
68 truncate_inode_pages(btnc, 0); 68 truncate_inode_pages(btnc, 0);
69} 69}
70 70
71struct buffer_head *
72nilfs_btnode_create_block(struct address_space *btnc, __u64 blocknr)
73{
74 struct inode *inode = NILFS_BTNC_I(btnc);
75 struct buffer_head *bh;
76
77 bh = nilfs_grab_buffer(inode, btnc, blocknr, 1 << BH_NILFS_Node);
78 if (unlikely(!bh))
79 return NULL;
80
81 if (unlikely(buffer_mapped(bh) || buffer_uptodate(bh) ||
82 buffer_dirty(bh))) {
83 brelse(bh);
84 BUG();
85 }
86 memset(bh->b_data, 0, 1 << inode->i_blkbits);
87 bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev;
88 bh->b_blocknr = blocknr;
89 set_buffer_mapped(bh);
90 set_buffer_uptodate(bh);
91
92 unlock_page(bh->b_page);
93 page_cache_release(bh->b_page);
94 return bh;
95}
96
71int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr, 97int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
72 sector_t pblocknr, struct buffer_head **pbh, 98 sector_t pblocknr, struct buffer_head **pbh)
73 int newblk)
74{ 99{
75 struct buffer_head *bh; 100 struct buffer_head *bh;
76 struct inode *inode = NILFS_BTNC_I(btnc); 101 struct inode *inode = NILFS_BTNC_I(btnc);
@@ -81,19 +106,6 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
81 return -ENOMEM; 106 return -ENOMEM;
82 107
83 err = -EEXIST; /* internal code */ 108 err = -EEXIST; /* internal code */
84 if (newblk) {
85 if (unlikely(buffer_mapped(bh) || buffer_uptodate(bh) ||
86 buffer_dirty(bh))) {
87 brelse(bh);
88 BUG();
89 }
90 memset(bh->b_data, 0, 1 << inode->i_blkbits);
91 bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev;
92 bh->b_blocknr = blocknr;
93 set_buffer_mapped(bh);
94 set_buffer_uptodate(bh);
95 goto found;
96 }
97 109
98 if (buffer_uptodate(bh) || buffer_dirty(bh)) 110 if (buffer_uptodate(bh) || buffer_dirty(bh))
99 goto found; 111 goto found;
@@ -135,27 +147,6 @@ out_locked:
135 return err; 147 return err;
136} 148}
137 149
138int nilfs_btnode_get(struct address_space *btnc, __u64 blocknr,
139 sector_t pblocknr, struct buffer_head **pbh, int newblk)
140{
141 struct buffer_head *bh;
142 int err;
143
144 err = nilfs_btnode_submit_block(btnc, blocknr, pblocknr, pbh, newblk);
145 if (err == -EEXIST) /* internal code (cache hit) */
146 return 0;
147 if (unlikely(err))
148 return err;
149
150 bh = *pbh;
151 wait_on_buffer(bh);
152 if (!buffer_uptodate(bh)) {
153 brelse(bh);
154 return -EIO;
155 }
156 return 0;
157}
158
159/** 150/**
160 * nilfs_btnode_delete - delete B-tree node buffer 151 * nilfs_btnode_delete - delete B-tree node buffer
161 * @bh: buffer to be deleted 152 * @bh: buffer to be deleted
@@ -244,12 +235,13 @@ retry:
244 unlock_page(obh->b_page); 235 unlock_page(obh->b_page);
245 } 236 }
246 237
247 err = nilfs_btnode_get(btnc, newkey, 0, &nbh, 1); 238 nbh = nilfs_btnode_create_block(btnc, newkey);
248 if (likely(!err)) { 239 if (!nbh)
249 BUG_ON(nbh == obh); 240 return -ENOMEM;
250 ctxt->newbh = nbh; 241
251 } 242 BUG_ON(nbh == obh);
252 return err; 243 ctxt->newbh = nbh;
244 return 0;
253 245
254 failed_unlock: 246 failed_unlock:
255 unlock_page(obh->b_page); 247 unlock_page(obh->b_page);