| .. | .. |
|---|
| 20 | 20 | #include "page.h" |
|---|
| 21 | 21 | #include "btnode.h" |
|---|
| 22 | 22 | |
|---|
| 23 | + |
|---|
| 24 | +/** |
|---|
| 25 | + * nilfs_init_btnc_inode - initialize B-tree node cache inode |
|---|
| 26 | + * @btnc_inode: inode to be initialized |
|---|
| 27 | + * |
|---|
| 28 | + * nilfs_init_btnc_inode() sets up an inode for B-tree node cache. |
|---|
| 29 | + */ |
|---|
| 30 | +void nilfs_init_btnc_inode(struct inode *btnc_inode) |
|---|
| 31 | +{ |
|---|
| 32 | + struct nilfs_inode_info *ii = NILFS_I(btnc_inode); |
|---|
| 33 | + |
|---|
| 34 | + btnc_inode->i_mode = S_IFREG; |
|---|
| 35 | + ii->i_flags = 0; |
|---|
| 36 | + memset(&ii->i_bmap_data, 0, sizeof(struct nilfs_bmap)); |
|---|
| 37 | + mapping_set_gfp_mask(btnc_inode->i_mapping, GFP_NOFS); |
|---|
| 38 | +} |
|---|
| 39 | + |
|---|
| 23 | 40 | void nilfs_btnode_cache_clear(struct address_space *btnc) |
|---|
| 24 | 41 | { |
|---|
| 25 | 42 | invalidate_mapping_pages(btnc, 0, -1); |
|---|
| .. | .. |
|---|
| 29 | 46 | struct buffer_head * |
|---|
| 30 | 47 | nilfs_btnode_create_block(struct address_space *btnc, __u64 blocknr) |
|---|
| 31 | 48 | { |
|---|
| 32 | | - struct inode *inode = NILFS_BTNC_I(btnc); |
|---|
| 49 | + struct inode *inode = btnc->host; |
|---|
| 33 | 50 | struct buffer_head *bh; |
|---|
| 34 | 51 | |
|---|
| 35 | 52 | bh = nilfs_grab_buffer(inode, btnc, blocknr, BIT(BH_NILFS_Node)); |
|---|
| .. | .. |
|---|
| 57 | 74 | struct buffer_head **pbh, sector_t *submit_ptr) |
|---|
| 58 | 75 | { |
|---|
| 59 | 76 | struct buffer_head *bh; |
|---|
| 60 | | - struct inode *inode = NILFS_BTNC_I(btnc); |
|---|
| 77 | + struct inode *inode = btnc->host; |
|---|
| 61 | 78 | struct page *page; |
|---|
| 62 | 79 | int err; |
|---|
| 63 | 80 | |
|---|
| .. | .. |
|---|
| 157 | 174 | struct nilfs_btnode_chkey_ctxt *ctxt) |
|---|
| 158 | 175 | { |
|---|
| 159 | 176 | struct buffer_head *obh, *nbh; |
|---|
| 160 | | - struct inode *inode = NILFS_BTNC_I(btnc); |
|---|
| 177 | + struct inode *inode = btnc->host; |
|---|
| 161 | 178 | __u64 oldkey = ctxt->oldkey, newkey = ctxt->newkey; |
|---|
| 162 | 179 | int err; |
|---|
| 163 | 180 | |
|---|
| .. | .. |
|---|
| 168 | 185 | ctxt->newbh = NULL; |
|---|
| 169 | 186 | |
|---|
| 170 | 187 | if (inode->i_blkbits == PAGE_SHIFT) { |
|---|
| 171 | | - lock_page(obh->b_page); |
|---|
| 172 | | - /* |
|---|
| 173 | | - * We cannot call radix_tree_preload for the kernels older |
|---|
| 174 | | - * than 2.6.23, because it is not exported for modules. |
|---|
| 175 | | - */ |
|---|
| 188 | + struct page *opage = obh->b_page; |
|---|
| 189 | + lock_page(opage); |
|---|
| 176 | 190 | retry: |
|---|
| 177 | | - err = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM); |
|---|
| 178 | | - if (err) |
|---|
| 179 | | - goto failed_unlock; |
|---|
| 180 | 191 | /* BUG_ON(oldkey != obh->b_page->index); */ |
|---|
| 181 | | - if (unlikely(oldkey != obh->b_page->index)) |
|---|
| 182 | | - NILFS_PAGE_BUG(obh->b_page, |
|---|
| 192 | + if (unlikely(oldkey != opage->index)) |
|---|
| 193 | + NILFS_PAGE_BUG(opage, |
|---|
| 183 | 194 | "invalid oldkey %lld (newkey=%lld)", |
|---|
| 184 | 195 | (unsigned long long)oldkey, |
|---|
| 185 | 196 | (unsigned long long)newkey); |
|---|
| 186 | 197 | |
|---|
| 187 | 198 | xa_lock_irq(&btnc->i_pages); |
|---|
| 188 | | - err = radix_tree_insert(&btnc->i_pages, newkey, obh->b_page); |
|---|
| 199 | + err = __xa_insert(&btnc->i_pages, newkey, opage, GFP_NOFS); |
|---|
| 189 | 200 | xa_unlock_irq(&btnc->i_pages); |
|---|
| 190 | 201 | /* |
|---|
| 191 | 202 | * Note: page->index will not change to newkey until |
|---|
| .. | .. |
|---|
| 193 | 204 | * To protect the page in intermediate state, the page lock |
|---|
| 194 | 205 | * is held. |
|---|
| 195 | 206 | */ |
|---|
| 196 | | - radix_tree_preload_end(); |
|---|
| 197 | 207 | if (!err) |
|---|
| 198 | 208 | return 0; |
|---|
| 199 | | - else if (err != -EEXIST) |
|---|
| 209 | + else if (err != -EBUSY) |
|---|
| 200 | 210 | goto failed_unlock; |
|---|
| 201 | 211 | |
|---|
| 202 | 212 | err = invalidate_inode_pages2_range(btnc, newkey, newkey); |
|---|
| 203 | 213 | if (!err) |
|---|
| 204 | 214 | goto retry; |
|---|
| 205 | 215 | /* fallback to copy mode */ |
|---|
| 206 | | - unlock_page(obh->b_page); |
|---|
| 216 | + unlock_page(opage); |
|---|
| 207 | 217 | } |
|---|
| 208 | 218 | |
|---|
| 209 | 219 | nbh = nilfs_btnode_create_block(btnc, newkey); |
|---|
| .. | .. |
|---|
| 243 | 253 | mark_buffer_dirty(obh); |
|---|
| 244 | 254 | |
|---|
| 245 | 255 | xa_lock_irq(&btnc->i_pages); |
|---|
| 246 | | - radix_tree_delete(&btnc->i_pages, oldkey); |
|---|
| 247 | | - radix_tree_tag_set(&btnc->i_pages, newkey, |
|---|
| 248 | | - PAGECACHE_TAG_DIRTY); |
|---|
| 256 | + __xa_erase(&btnc->i_pages, oldkey); |
|---|
| 257 | + __xa_set_mark(&btnc->i_pages, newkey, PAGECACHE_TAG_DIRTY); |
|---|
| 249 | 258 | xa_unlock_irq(&btnc->i_pages); |
|---|
| 250 | 259 | |
|---|
| 251 | 260 | opage->index = obh->b_blocknr = newkey; |
|---|
| .. | .. |
|---|
| 274 | 283 | return; |
|---|
| 275 | 284 | |
|---|
| 276 | 285 | if (nbh == NULL) { /* blocksize == pagesize */ |
|---|
| 277 | | - xa_lock_irq(&btnc->i_pages); |
|---|
| 278 | | - radix_tree_delete(&btnc->i_pages, newkey); |
|---|
| 279 | | - xa_unlock_irq(&btnc->i_pages); |
|---|
| 286 | + xa_erase_irq(&btnc->i_pages, newkey); |
|---|
| 280 | 287 | unlock_page(ctxt->bh->b_page); |
|---|
| 281 | 288 | } else |
|---|
| 282 | 289 | brelse(nbh); |
|---|