xref: /openbmc/linux/fs/nilfs2/btnode.c (revision 55e43d6abd078ed6d219902ce8cb4d68e3c993ba)
1  // SPDX-License-Identifier: GPL-2.0+
2  /*
3   * NILFS B-tree node cache
4   *
5   * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
6   *
7   * Originally written by Seiji Kihara.
8   * Fully revised by Ryusuke Konishi for stabilization and simplification.
9   *
10   */
11  
12  #include <linux/types.h>
13  #include <linux/buffer_head.h>
14  #include <linux/mm.h>
15  #include <linux/backing-dev.h>
16  #include <linux/gfp.h>
17  #include "nilfs.h"
18  #include "mdt.h"
19  #include "dat.h"
20  #include "page.h"
21  #include "btnode.h"
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   */
nilfs_init_btnc_inode(struct inode * btnc_inode)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  	btnc_inode->i_mapping->a_ops = &nilfs_buffer_cache_aops;
39  }
40  
nilfs_btnode_cache_clear(struct address_space * btnc)41  void nilfs_btnode_cache_clear(struct address_space *btnc)
42  {
43  	invalidate_mapping_pages(btnc, 0, -1);
44  	truncate_inode_pages(btnc, 0);
45  }
46  
47  struct buffer_head *
nilfs_btnode_create_block(struct address_space * btnc,__u64 blocknr)48  nilfs_btnode_create_block(struct address_space *btnc, __u64 blocknr)
49  {
50  	struct inode *inode = btnc->host;
51  	struct buffer_head *bh;
52  
53  	bh = nilfs_grab_buffer(inode, btnc, blocknr, BIT(BH_NILFS_Node));
54  	if (unlikely(!bh))
55  		return ERR_PTR(-ENOMEM);
56  
57  	if (unlikely(buffer_mapped(bh) || buffer_uptodate(bh) ||
58  		     buffer_dirty(bh))) {
59  		/*
60  		 * The block buffer at the specified new address was already
61  		 * in use.  This can happen if it is a virtual block number
62  		 * and has been reallocated due to corruption of the bitmap
63  		 * used to manage its allocation state (if not, the buffer
64  		 * clearing of an abandoned b-tree node is missing somewhere).
65  		 */
66  		nilfs_error(inode->i_sb,
67  			    "state inconsistency probably due to duplicate use of b-tree node block address %llu (ino=%lu)",
68  			    (unsigned long long)blocknr, inode->i_ino);
69  		goto failed;
70  	}
71  	memset(bh->b_data, 0, i_blocksize(inode));
72  	bh->b_blocknr = blocknr;
73  	set_buffer_mapped(bh);
74  	set_buffer_uptodate(bh);
75  
76  	unlock_page(bh->b_page);
77  	put_page(bh->b_page);
78  	return bh;
79  
80  failed:
81  	unlock_page(bh->b_page);
82  	put_page(bh->b_page);
83  	brelse(bh);
84  	return ERR_PTR(-EIO);
85  }
86  
nilfs_btnode_submit_block(struct address_space * btnc,__u64 blocknr,sector_t pblocknr,blk_opf_t opf,struct buffer_head ** pbh,sector_t * submit_ptr)87  int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
88  			      sector_t pblocknr, blk_opf_t opf,
89  			      struct buffer_head **pbh, sector_t *submit_ptr)
90  {
91  	struct buffer_head *bh;
92  	struct inode *inode = btnc->host;
93  	struct page *page;
94  	int err;
95  
96  	bh = nilfs_grab_buffer(inode, btnc, blocknr, BIT(BH_NILFS_Node));
97  	if (unlikely(!bh))
98  		return -ENOMEM;
99  
100  	err = -EEXIST; /* internal code */
101  	page = bh->b_page;
102  
103  	if (buffer_uptodate(bh) || buffer_dirty(bh))
104  		goto found;
105  
106  	if (pblocknr == 0) {
107  		pblocknr = blocknr;
108  		if (inode->i_ino != NILFS_DAT_INO) {
109  			struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
110  
111  			/* blocknr is a virtual block number */
112  			err = nilfs_dat_translate(nilfs->ns_dat, blocknr,
113  						  &pblocknr);
114  			if (unlikely(err)) {
115  				brelse(bh);
116  				goto out_locked;
117  			}
118  		}
119  	}
120  
121  	if (opf & REQ_RAHEAD) {
122  		if (pblocknr != *submit_ptr + 1 || !trylock_buffer(bh)) {
123  			err = -EBUSY; /* internal code */
124  			brelse(bh);
125  			goto out_locked;
126  		}
127  	} else { /* opf == REQ_OP_READ */
128  		lock_buffer(bh);
129  	}
130  	if (buffer_uptodate(bh)) {
131  		unlock_buffer(bh);
132  		err = -EEXIST; /* internal code */
133  		goto found;
134  	}
135  	set_buffer_mapped(bh);
136  	bh->b_blocknr = pblocknr; /* set block address for read */
137  	bh->b_end_io = end_buffer_read_sync;
138  	get_bh(bh);
139  	submit_bh(opf, bh);
140  	bh->b_blocknr = blocknr; /* set back to the given block address */
141  	*submit_ptr = pblocknr;
142  	err = 0;
143  found:
144  	*pbh = bh;
145  
146  out_locked:
147  	unlock_page(page);
148  	put_page(page);
149  	return err;
150  }
151  
152  /**
153   * nilfs_btnode_delete - delete B-tree node buffer
154   * @bh: buffer to be deleted
155   *
156   * nilfs_btnode_delete() invalidates the specified buffer and delete the page
157   * including the buffer if the page gets unbusy.
158   */
nilfs_btnode_delete(struct buffer_head * bh)159  void nilfs_btnode_delete(struct buffer_head *bh)
160  {
161  	struct address_space *mapping;
162  	struct page *page = bh->b_page;
163  	pgoff_t index = page_index(page);
164  	int still_dirty;
165  
166  	get_page(page);
167  	lock_page(page);
168  	wait_on_page_writeback(page);
169  
170  	nilfs_forget_buffer(bh);
171  	still_dirty = PageDirty(page);
172  	mapping = page->mapping;
173  	unlock_page(page);
174  	put_page(page);
175  
176  	if (!still_dirty && mapping)
177  		invalidate_inode_pages2_range(mapping, index, index);
178  }
179  
180  /**
181   * nilfs_btnode_prepare_change_key
182   *  prepare to move contents of the block for old key to one of new key.
183   *  the old buffer will not be removed, but might be reused for new buffer.
184   *  it might return -ENOMEM because of memory allocation errors,
185   *  and might return -EIO because of disk read errors.
186   */
nilfs_btnode_prepare_change_key(struct address_space * btnc,struct nilfs_btnode_chkey_ctxt * ctxt)187  int nilfs_btnode_prepare_change_key(struct address_space *btnc,
188  				    struct nilfs_btnode_chkey_ctxt *ctxt)
189  {
190  	struct buffer_head *obh, *nbh;
191  	struct inode *inode = btnc->host;
192  	__u64 oldkey = ctxt->oldkey, newkey = ctxt->newkey;
193  	int err;
194  
195  	if (oldkey == newkey)
196  		return 0;
197  
198  	obh = ctxt->bh;
199  	ctxt->newbh = NULL;
200  
201  	if (inode->i_blkbits == PAGE_SHIFT) {
202  		struct page *opage = obh->b_page;
203  		lock_page(opage);
204  retry:
205  		/* BUG_ON(oldkey != obh->b_folio->index); */
206  		if (unlikely(oldkey != opage->index))
207  			NILFS_PAGE_BUG(opage,
208  				       "invalid oldkey %lld (newkey=%lld)",
209  				       (unsigned long long)oldkey,
210  				       (unsigned long long)newkey);
211  
212  		xa_lock_irq(&btnc->i_pages);
213  		err = __xa_insert(&btnc->i_pages, newkey, opage, GFP_NOFS);
214  		xa_unlock_irq(&btnc->i_pages);
215  		/*
216  		 * Note: page->index will not change to newkey until
217  		 * nilfs_btnode_commit_change_key() will be called.
218  		 * To protect the page in intermediate state, the page lock
219  		 * is held.
220  		 */
221  		if (!err)
222  			return 0;
223  		else if (err != -EBUSY)
224  			goto failed_unlock;
225  
226  		err = invalidate_inode_pages2_range(btnc, newkey, newkey);
227  		if (!err)
228  			goto retry;
229  		/* fallback to copy mode */
230  		unlock_page(opage);
231  	}
232  
233  	nbh = nilfs_btnode_create_block(btnc, newkey);
234  	if (IS_ERR(nbh))
235  		return PTR_ERR(nbh);
236  
237  	BUG_ON(nbh == obh);
238  	ctxt->newbh = nbh;
239  	return 0;
240  
241   failed_unlock:
242  	unlock_page(obh->b_page);
243  	return err;
244  }
245  
246  /**
247   * nilfs_btnode_commit_change_key
248   *  commit the change_key operation prepared by prepare_change_key().
249   */
nilfs_btnode_commit_change_key(struct address_space * btnc,struct nilfs_btnode_chkey_ctxt * ctxt)250  void nilfs_btnode_commit_change_key(struct address_space *btnc,
251  				    struct nilfs_btnode_chkey_ctxt *ctxt)
252  {
253  	struct buffer_head *obh = ctxt->bh, *nbh = ctxt->newbh;
254  	__u64 oldkey = ctxt->oldkey, newkey = ctxt->newkey;
255  	struct page *opage;
256  
257  	if (oldkey == newkey)
258  		return;
259  
260  	if (nbh == NULL) {	/* blocksize == pagesize */
261  		opage = obh->b_page;
262  		if (unlikely(oldkey != opage->index))
263  			NILFS_PAGE_BUG(opage,
264  				       "invalid oldkey %lld (newkey=%lld)",
265  				       (unsigned long long)oldkey,
266  				       (unsigned long long)newkey);
267  		mark_buffer_dirty(obh);
268  
269  		xa_lock_irq(&btnc->i_pages);
270  		__xa_erase(&btnc->i_pages, oldkey);
271  		__xa_set_mark(&btnc->i_pages, newkey, PAGECACHE_TAG_DIRTY);
272  		xa_unlock_irq(&btnc->i_pages);
273  
274  		opage->index = obh->b_blocknr = newkey;
275  		unlock_page(opage);
276  	} else {
277  		nilfs_copy_buffer(nbh, obh);
278  		mark_buffer_dirty(nbh);
279  
280  		nbh->b_blocknr = newkey;
281  		ctxt->bh = nbh;
282  		nilfs_btnode_delete(obh); /* will decrement bh->b_count */
283  	}
284  }
285  
286  /**
287   * nilfs_btnode_abort_change_key
288   *  abort the change_key operation prepared by prepare_change_key().
289   */
nilfs_btnode_abort_change_key(struct address_space * btnc,struct nilfs_btnode_chkey_ctxt * ctxt)290  void nilfs_btnode_abort_change_key(struct address_space *btnc,
291  				   struct nilfs_btnode_chkey_ctxt *ctxt)
292  {
293  	struct buffer_head *nbh = ctxt->newbh;
294  	__u64 oldkey = ctxt->oldkey, newkey = ctxt->newkey;
295  
296  	if (oldkey == newkey)
297  		return;
298  
299  	if (nbh == NULL) {	/* blocksize == pagesize */
300  		xa_erase_irq(&btnc->i_pages, newkey);
301  		unlock_page(ctxt->bh->b_page);
302  	} else {
303  		/*
304  		 * When canceling a buffer that a prepare operation has
305  		 * allocated to copy a node block to another location, use
306  		 * nilfs_btnode_delete() to initialize and release the buffer
307  		 * so that the buffer flags will not be in an inconsistent
308  		 * state when it is reallocated.
309  		 */
310  		nilfs_btnode_delete(nbh);
311  	}
312  }
313