diff options
Diffstat (limited to 'fs/nilfs2/btnode.c')
| -rw-r--r-- | fs/nilfs2/btnode.c | 76 |
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 | ||
| 71 | struct buffer_head * | ||
| 72 | nilfs_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 | |||
| 71 | int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr, | 97 | int 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 | ||
| 138 | int 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); |
