.. | .. |
---|
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 | | - } else |
---|
282 | | - brelse(nbh); |
---|
| 288 | + } else { |
---|
| 289 | + /* |
---|
| 290 | + * When canceling a buffer that a prepare operation has |
---|
| 291 | + * allocated to copy a node block to another location, use |
---|
| 292 | + * nilfs_btnode_delete() to initialize and release the buffer |
---|
| 293 | + * so that the buffer flags will not be in an inconsistent |
---|
| 294 | + * state when it is reallocated. |
---|
| 295 | + */ |
---|
| 296 | + nilfs_btnode_delete(nbh); |
---|
| 297 | + } |
---|
283 | 298 | } |
---|