Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
btnode.c
Go to the documentation of this file.
1 /*
2  * btnode.c - NILFS B-tree node cache
3  *
4  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  *
20  * This file was originally written by Seiji Kihara <[email protected]>
21  * and fully revised by Ryusuke Konishi <[email protected]> for
22  * stabilization and simplification.
23  *
24  */
25 
26 #include <linux/types.h>
27 #include <linux/buffer_head.h>
28 #include <linux/mm.h>
29 #include <linux/backing-dev.h>
30 #include <linux/gfp.h>
31 #include "nilfs.h"
32 #include "mdt.h"
33 #include "dat.h"
34 #include "page.h"
35 #include "btnode.h"
36 
38 {
39  invalidate_mapping_pages(btnc, 0, -1);
40  truncate_inode_pages(btnc, 0);
41 }
42 
43 struct buffer_head *
45 {
46  struct inode *inode = NILFS_BTNC_I(btnc);
47  struct buffer_head *bh;
48 
49  bh = nilfs_grab_buffer(inode, btnc, blocknr, 1 << BH_NILFS_Node);
50  if (unlikely(!bh))
51  return NULL;
52 
53  if (unlikely(buffer_mapped(bh) || buffer_uptodate(bh) ||
54  buffer_dirty(bh))) {
55  brelse(bh);
56  BUG();
57  }
58  memset(bh->b_data, 0, 1 << inode->i_blkbits);
59  bh->b_bdev = inode->i_sb->s_bdev;
60  bh->b_blocknr = blocknr;
61  set_buffer_mapped(bh);
62  set_buffer_uptodate(bh);
63 
64  unlock_page(bh->b_page);
65  page_cache_release(bh->b_page);
66  return bh;
67 }
68 
70  sector_t pblocknr, int mode,
71  struct buffer_head **pbh, sector_t *submit_ptr)
72 {
73  struct buffer_head *bh;
74  struct inode *inode = NILFS_BTNC_I(btnc);
75  struct page *page;
76  int err;
77 
78  bh = nilfs_grab_buffer(inode, btnc, blocknr, 1 << BH_NILFS_Node);
79  if (unlikely(!bh))
80  return -ENOMEM;
81 
82  err = -EEXIST; /* internal code */
83  page = bh->b_page;
84 
85  if (buffer_uptodate(bh) || buffer_dirty(bh))
86  goto found;
87 
88  if (pblocknr == 0) {
89  pblocknr = blocknr;
90  if (inode->i_ino != NILFS_DAT_INO) {
91  struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
92 
93  /* blocknr is a virtual block number */
94  err = nilfs_dat_translate(nilfs->ns_dat, blocknr,
95  &pblocknr);
96  if (unlikely(err)) {
97  brelse(bh);
98  goto out_locked;
99  }
100  }
101  }
102 
103  if (mode == READA) {
104  if (pblocknr != *submit_ptr + 1 || !trylock_buffer(bh)) {
105  err = -EBUSY; /* internal code */
106  brelse(bh);
107  goto out_locked;
108  }
109  } else { /* mode == READ */
110  lock_buffer(bh);
111  }
112  if (buffer_uptodate(bh)) {
113  unlock_buffer(bh);
114  err = -EEXIST; /* internal code */
115  goto found;
116  }
117  set_buffer_mapped(bh);
118  bh->b_bdev = inode->i_sb->s_bdev;
119  bh->b_blocknr = pblocknr; /* set block address for read */
120  bh->b_end_io = end_buffer_read_sync;
121  get_bh(bh);
122  submit_bh(mode, bh);
123  bh->b_blocknr = blocknr; /* set back to the given block address */
124  *submit_ptr = pblocknr;
125  err = 0;
126 found:
127  *pbh = bh;
128 
129 out_locked:
130  unlock_page(page);
131  page_cache_release(page);
132  return err;
133 }
134 
142 void nilfs_btnode_delete(struct buffer_head *bh)
143 {
144  struct address_space *mapping;
145  struct page *page = bh->b_page;
146  pgoff_t index = page_index(page);
147  int still_dirty;
148 
149  page_cache_get(page);
150  lock_page(page);
151  wait_on_page_writeback(page);
152 
154  still_dirty = PageDirty(page);
155  mapping = page->mapping;
156  unlock_page(page);
157  page_cache_release(page);
158 
159  if (!still_dirty && mapping)
160  invalidate_inode_pages2_range(mapping, index, index);
161 }
162 
171  struct nilfs_btnode_chkey_ctxt *ctxt)
172 {
173  struct buffer_head *obh, *nbh;
174  struct inode *inode = NILFS_BTNC_I(btnc);
175  __u64 oldkey = ctxt->oldkey, newkey = ctxt->newkey;
176  int err;
177 
178  if (oldkey == newkey)
179  return 0;
180 
181  obh = ctxt->bh;
182  ctxt->newbh = NULL;
183 
184  if (inode->i_blkbits == PAGE_CACHE_SHIFT) {
185  lock_page(obh->b_page);
186  /*
187  * We cannot call radix_tree_preload for the kernels older
188  * than 2.6.23, because it is not exported for modules.
189  */
190 retry:
192  if (err)
193  goto failed_unlock;
194  /* BUG_ON(oldkey != obh->b_page->index); */
195  if (unlikely(oldkey != obh->b_page->index))
196  NILFS_PAGE_BUG(obh->b_page,
197  "invalid oldkey %lld (newkey=%lld)",
198  (unsigned long long)oldkey,
199  (unsigned long long)newkey);
200 
201  spin_lock_irq(&btnc->tree_lock);
202  err = radix_tree_insert(&btnc->page_tree, newkey, obh->b_page);
203  spin_unlock_irq(&btnc->tree_lock);
204  /*
205  * Note: page->index will not change to newkey until
206  * nilfs_btnode_commit_change_key() will be called.
207  * To protect the page in intermediate state, the page lock
208  * is held.
209  */
210  radix_tree_preload_end();
211  if (!err)
212  return 0;
213  else if (err != -EEXIST)
214  goto failed_unlock;
215 
216  err = invalidate_inode_pages2_range(btnc, newkey, newkey);
217  if (!err)
218  goto retry;
219  /* fallback to copy mode */
220  unlock_page(obh->b_page);
221  }
222 
223  nbh = nilfs_btnode_create_block(btnc, newkey);
224  if (!nbh)
225  return -ENOMEM;
226 
227  BUG_ON(nbh == obh);
228  ctxt->newbh = nbh;
229  return 0;
230 
231  failed_unlock:
232  unlock_page(obh->b_page);
233  return err;
234 }
235 
241  struct nilfs_btnode_chkey_ctxt *ctxt)
242 {
243  struct buffer_head *obh = ctxt->bh, *nbh = ctxt->newbh;
244  __u64 oldkey = ctxt->oldkey, newkey = ctxt->newkey;
245  struct page *opage;
246 
247  if (oldkey == newkey)
248  return;
249 
250  if (nbh == NULL) { /* blocksize == pagesize */
251  opage = obh->b_page;
252  if (unlikely(oldkey != opage->index))
253  NILFS_PAGE_BUG(opage,
254  "invalid oldkey %lld (newkey=%lld)",
255  (unsigned long long)oldkey,
256  (unsigned long long)newkey);
257  mark_buffer_dirty(obh);
258 
259  spin_lock_irq(&btnc->tree_lock);
260  radix_tree_delete(&btnc->page_tree, oldkey);
261  radix_tree_tag_set(&btnc->page_tree, newkey,
263  spin_unlock_irq(&btnc->tree_lock);
264 
265  opage->index = obh->b_blocknr = newkey;
266  unlock_page(opage);
267  } else {
268  nilfs_copy_buffer(nbh, obh);
269  mark_buffer_dirty(nbh);
270 
271  nbh->b_blocknr = newkey;
272  ctxt->bh = nbh;
273  nilfs_btnode_delete(obh); /* will decrement bh->b_count */
274  }
275 }
276 
282  struct nilfs_btnode_chkey_ctxt *ctxt)
283 {
284  struct buffer_head *nbh = ctxt->newbh;
285  __u64 oldkey = ctxt->oldkey, newkey = ctxt->newkey;
286 
287  if (oldkey == newkey)
288  return;
289 
290  if (nbh == NULL) { /* blocksize == pagesize */
291  spin_lock_irq(&btnc->tree_lock);
292  radix_tree_delete(&btnc->page_tree, newkey);
293  spin_unlock_irq(&btnc->tree_lock);
294  unlock_page(ctxt->bh->b_page);
295  } else
296  brelse(nbh);
297 }