diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-23 01:43:01 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-23 01:43:01 -0400 |
| commit | caebc160ce3f76761cc62ad96ef6d6f30f54e3dd (patch) | |
| tree | 6bedd4a62d65a4ba121a0c170d1ca657d922d352 | |
| parent | d798f7f080805ad7e15fc37a43d8c6f91edb6dda (diff) | |
| parent | 5fc7b14177b1a1c2f2511aed62a4ca870d0332e7 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2:
nilfs2: use mark_buffer_dirty to mark btnode or meta data dirty
nilfs2: always set back pointer to host inode in mapping->host
nilfs2: get rid of NILFS_I_NILFS
nilfs2: use list_first_entry
nilfs2: use empty_aops for gc-inodes
nilfs2: implement resize ioctl
nilfs2: add truncation routine of segment usage file
nilfs2: add routine to move secondary super block
nilfs2: add ioctl which limits range of segment to be allocated
nilfs2: zero fill unused portion of super root block
nilfs2: super root size should change depending on inode size
nilfs2: get rid of private page allocator
nilfs2: merge list_del()/list_add_tail() to list_move_tail()
| -rw-r--r-- | fs/nilfs2/alloc.c | 12 | ||||
| -rw-r--r-- | fs/nilfs2/bmap.c | 4 | ||||
| -rw-r--r-- | fs/nilfs2/btnode.c | 19 | ||||
| -rw-r--r-- | fs/nilfs2/btnode.h | 4 | ||||
| -rw-r--r-- | fs/nilfs2/btree.c | 38 | ||||
| -rw-r--r-- | fs/nilfs2/cpfile.c | 24 | ||||
| -rw-r--r-- | fs/nilfs2/dat.c | 4 | ||||
| -rw-r--r-- | fs/nilfs2/file.c | 1 | ||||
| -rw-r--r-- | fs/nilfs2/gcinode.c | 25 | ||||
| -rw-r--r-- | fs/nilfs2/ifile.c | 4 | ||||
| -rw-r--r-- | fs/nilfs2/inode.c | 23 | ||||
| -rw-r--r-- | fs/nilfs2/ioctl.c | 61 | ||||
| -rw-r--r-- | fs/nilfs2/mdt.c | 8 | ||||
| -rw-r--r-- | fs/nilfs2/mdt.h | 9 | ||||
| -rw-r--r-- | fs/nilfs2/nilfs.h | 7 | ||||
| -rw-r--r-- | fs/nilfs2/page.c | 79 | ||||
| -rw-r--r-- | fs/nilfs2/page.h | 7 | ||||
| -rw-r--r-- | fs/nilfs2/recovery.c | 12 | ||||
| -rw-r--r-- | fs/nilfs2/segbuf.c | 17 | ||||
| -rw-r--r-- | fs/nilfs2/segment.c | 190 | ||||
| -rw-r--r-- | fs/nilfs2/segment.h | 2 | ||||
| -rw-r--r-- | fs/nilfs2/sufile.c | 274 | ||||
| -rw-r--r-- | fs/nilfs2/sufile.h | 4 | ||||
| -rw-r--r-- | fs/nilfs2/super.c | 131 | ||||
| -rw-r--r-- | fs/nilfs2/the_nilfs.c | 24 | ||||
| -rw-r--r-- | fs/nilfs2/the_nilfs.h | 2 | ||||
| -rw-r--r-- | include/linux/nilfs2_fs.h | 4 |
27 files changed, 603 insertions, 386 deletions
diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c index f7684483785e..eed4d7b26249 100644 --- a/fs/nilfs2/alloc.c +++ b/fs/nilfs2/alloc.c | |||
| @@ -489,8 +489,8 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode, | |||
| 489 | void nilfs_palloc_commit_alloc_entry(struct inode *inode, | 489 | void nilfs_palloc_commit_alloc_entry(struct inode *inode, |
| 490 | struct nilfs_palloc_req *req) | 490 | struct nilfs_palloc_req *req) |
| 491 | { | 491 | { |
| 492 | nilfs_mdt_mark_buffer_dirty(req->pr_bitmap_bh); | 492 | mark_buffer_dirty(req->pr_bitmap_bh); |
| 493 | nilfs_mdt_mark_buffer_dirty(req->pr_desc_bh); | 493 | mark_buffer_dirty(req->pr_desc_bh); |
| 494 | nilfs_mdt_mark_dirty(inode); | 494 | nilfs_mdt_mark_dirty(inode); |
| 495 | 495 | ||
| 496 | brelse(req->pr_bitmap_bh); | 496 | brelse(req->pr_bitmap_bh); |
| @@ -527,8 +527,8 @@ void nilfs_palloc_commit_free_entry(struct inode *inode, | |||
| 527 | kunmap(req->pr_bitmap_bh->b_page); | 527 | kunmap(req->pr_bitmap_bh->b_page); |
| 528 | kunmap(req->pr_desc_bh->b_page); | 528 | kunmap(req->pr_desc_bh->b_page); |
| 529 | 529 | ||
| 530 | nilfs_mdt_mark_buffer_dirty(req->pr_desc_bh); | 530 | mark_buffer_dirty(req->pr_desc_bh); |
| 531 | nilfs_mdt_mark_buffer_dirty(req->pr_bitmap_bh); | 531 | mark_buffer_dirty(req->pr_bitmap_bh); |
| 532 | nilfs_mdt_mark_dirty(inode); | 532 | nilfs_mdt_mark_dirty(inode); |
| 533 | 533 | ||
| 534 | brelse(req->pr_bitmap_bh); | 534 | brelse(req->pr_bitmap_bh); |
| @@ -683,8 +683,8 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems) | |||
| 683 | kunmap(bitmap_bh->b_page); | 683 | kunmap(bitmap_bh->b_page); |
| 684 | kunmap(desc_bh->b_page); | 684 | kunmap(desc_bh->b_page); |
| 685 | 685 | ||
| 686 | nilfs_mdt_mark_buffer_dirty(desc_bh); | 686 | mark_buffer_dirty(desc_bh); |
| 687 | nilfs_mdt_mark_buffer_dirty(bitmap_bh); | 687 | mark_buffer_dirty(bitmap_bh); |
| 688 | nilfs_mdt_mark_dirty(inode); | 688 | nilfs_mdt_mark_dirty(inode); |
| 689 | 689 | ||
| 690 | brelse(bitmap_bh); | 690 | brelse(bitmap_bh); |
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c index 4723f04e9b12..aadbd0b5e3e8 100644 --- a/fs/nilfs2/bmap.c +++ b/fs/nilfs2/bmap.c | |||
| @@ -34,7 +34,9 @@ | |||
| 34 | 34 | ||
| 35 | struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap) | 35 | struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap) |
| 36 | { | 36 | { |
| 37 | return NILFS_I_NILFS(bmap->b_inode)->ns_dat; | 37 | struct the_nilfs *nilfs = bmap->b_inode->i_sb->s_fs_info; |
| 38 | |||
| 39 | return nilfs->ns_dat; | ||
| 38 | } | 40 | } |
| 39 | 41 | ||
| 40 | static int nilfs_bmap_convert_error(struct nilfs_bmap *bmap, | 42 | static int nilfs_bmap_convert_error(struct nilfs_bmap *bmap, |
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c index 609cd223eea8..a35ae35e6932 100644 --- a/fs/nilfs2/btnode.c +++ b/fs/nilfs2/btnode.c | |||
| @@ -34,12 +34,6 @@ | |||
| 34 | #include "page.h" | 34 | #include "page.h" |
| 35 | #include "btnode.h" | 35 | #include "btnode.h" |
| 36 | 36 | ||
| 37 | void nilfs_btnode_cache_init(struct address_space *btnc, | ||
| 38 | struct backing_dev_info *bdi) | ||
| 39 | { | ||
| 40 | nilfs_mapping_init(btnc, bdi); | ||
| 41 | } | ||
| 42 | |||
| 43 | void nilfs_btnode_cache_clear(struct address_space *btnc) | 37 | void nilfs_btnode_cache_clear(struct address_space *btnc) |
| 44 | { | 38 | { |
| 45 | invalidate_mapping_pages(btnc, 0, -1); | 39 | invalidate_mapping_pages(btnc, 0, -1); |
| @@ -62,7 +56,7 @@ nilfs_btnode_create_block(struct address_space *btnc, __u64 blocknr) | |||
| 62 | BUG(); | 56 | BUG(); |
| 63 | } | 57 | } |
| 64 | memset(bh->b_data, 0, 1 << inode->i_blkbits); | 58 | memset(bh->b_data, 0, 1 << inode->i_blkbits); |
| 65 | bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev; | 59 | bh->b_bdev = inode->i_sb->s_bdev; |
| 66 | bh->b_blocknr = blocknr; | 60 | bh->b_blocknr = blocknr; |
| 67 | set_buffer_mapped(bh); | 61 | set_buffer_mapped(bh); |
| 68 | set_buffer_uptodate(bh); | 62 | set_buffer_uptodate(bh); |
| @@ -94,10 +88,11 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr, | |||
| 94 | if (pblocknr == 0) { | 88 | if (pblocknr == 0) { |
| 95 | pblocknr = blocknr; | 89 | pblocknr = blocknr; |
| 96 | if (inode->i_ino != NILFS_DAT_INO) { | 90 | if (inode->i_ino != NILFS_DAT_INO) { |
| 97 | struct inode *dat = NILFS_I_NILFS(inode)->ns_dat; | 91 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; |
| 98 | 92 | ||
| 99 | /* blocknr is a virtual block number */ | 93 | /* blocknr is a virtual block number */ |
| 100 | err = nilfs_dat_translate(dat, blocknr, &pblocknr); | 94 | err = nilfs_dat_translate(nilfs->ns_dat, blocknr, |
| 95 | &pblocknr); | ||
| 101 | if (unlikely(err)) { | 96 | if (unlikely(err)) { |
| 102 | brelse(bh); | 97 | brelse(bh); |
| 103 | goto out_locked; | 98 | goto out_locked; |
| @@ -120,7 +115,7 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr, | |||
| 120 | goto found; | 115 | goto found; |
| 121 | } | 116 | } |
| 122 | set_buffer_mapped(bh); | 117 | set_buffer_mapped(bh); |
| 123 | bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev; | 118 | bh->b_bdev = inode->i_sb->s_bdev; |
| 124 | bh->b_blocknr = pblocknr; /* set block address for read */ | 119 | bh->b_blocknr = pblocknr; /* set block address for read */ |
| 125 | bh->b_end_io = end_buffer_read_sync; | 120 | bh->b_end_io = end_buffer_read_sync; |
| 126 | get_bh(bh); | 121 | get_bh(bh); |
| @@ -259,7 +254,7 @@ void nilfs_btnode_commit_change_key(struct address_space *btnc, | |||
| 259 | "invalid oldkey %lld (newkey=%lld)", | 254 | "invalid oldkey %lld (newkey=%lld)", |
| 260 | (unsigned long long)oldkey, | 255 | (unsigned long long)oldkey, |
| 261 | (unsigned long long)newkey); | 256 | (unsigned long long)newkey); |
| 262 | nilfs_btnode_mark_dirty(obh); | 257 | mark_buffer_dirty(obh); |
| 263 | 258 | ||
| 264 | spin_lock_irq(&btnc->tree_lock); | 259 | spin_lock_irq(&btnc->tree_lock); |
| 265 | radix_tree_delete(&btnc->page_tree, oldkey); | 260 | radix_tree_delete(&btnc->page_tree, oldkey); |
| @@ -271,7 +266,7 @@ void nilfs_btnode_commit_change_key(struct address_space *btnc, | |||
| 271 | unlock_page(opage); | 266 | unlock_page(opage); |
| 272 | } else { | 267 | } else { |
| 273 | nilfs_copy_buffer(nbh, obh); | 268 | nilfs_copy_buffer(nbh, obh); |
| 274 | nilfs_btnode_mark_dirty(nbh); | 269 | mark_buffer_dirty(nbh); |
| 275 | 270 | ||
| 276 | nbh->b_blocknr = newkey; | 271 | nbh->b_blocknr = newkey; |
| 277 | ctxt->bh = nbh; | 272 | ctxt->bh = nbh; |
diff --git a/fs/nilfs2/btnode.h b/fs/nilfs2/btnode.h index 1b8ebd888c28..3a4dd2d8d3fc 100644 --- a/fs/nilfs2/btnode.h +++ b/fs/nilfs2/btnode.h | |||
| @@ -37,7 +37,6 @@ struct nilfs_btnode_chkey_ctxt { | |||
| 37 | struct buffer_head *newbh; | 37 | struct buffer_head *newbh; |
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | void nilfs_btnode_cache_init(struct address_space *, struct backing_dev_info *); | ||
| 41 | void nilfs_btnode_cache_clear(struct address_space *); | 40 | void nilfs_btnode_cache_clear(struct address_space *); |
| 42 | struct buffer_head *nilfs_btnode_create_block(struct address_space *btnc, | 41 | struct buffer_head *nilfs_btnode_create_block(struct address_space *btnc, |
| 43 | __u64 blocknr); | 42 | __u64 blocknr); |
| @@ -51,7 +50,4 @@ void nilfs_btnode_commit_change_key(struct address_space *, | |||
| 51 | void nilfs_btnode_abort_change_key(struct address_space *, | 50 | void nilfs_btnode_abort_change_key(struct address_space *, |
| 52 | struct nilfs_btnode_chkey_ctxt *); | 51 | struct nilfs_btnode_chkey_ctxt *); |
| 53 | 52 | ||
| 54 | #define nilfs_btnode_mark_dirty(bh) nilfs_mark_buffer_dirty(bh) | ||
| 55 | |||
| 56 | |||
| 57 | #endif /* _NILFS_BTNODE_H */ | 53 | #endif /* _NILFS_BTNODE_H */ |
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c index d451ae0e0bf3..7eafe468a29c 100644 --- a/fs/nilfs2/btree.c +++ b/fs/nilfs2/btree.c | |||
| @@ -714,7 +714,7 @@ static void nilfs_btree_promote_key(struct nilfs_bmap *btree, | |||
| 714 | nilfs_btree_get_nonroot_node(path, level), | 714 | nilfs_btree_get_nonroot_node(path, level), |
| 715 | path[level].bp_index, key); | 715 | path[level].bp_index, key); |
| 716 | if (!buffer_dirty(path[level].bp_bh)) | 716 | if (!buffer_dirty(path[level].bp_bh)) |
| 717 | nilfs_btnode_mark_dirty(path[level].bp_bh); | 717 | mark_buffer_dirty(path[level].bp_bh); |
| 718 | } while ((path[level].bp_index == 0) && | 718 | } while ((path[level].bp_index == 0) && |
| 719 | (++level < nilfs_btree_height(btree) - 1)); | 719 | (++level < nilfs_btree_height(btree) - 1)); |
| 720 | } | 720 | } |
| @@ -739,7 +739,7 @@ static void nilfs_btree_do_insert(struct nilfs_bmap *btree, | |||
| 739 | nilfs_btree_node_insert(node, path[level].bp_index, | 739 | nilfs_btree_node_insert(node, path[level].bp_index, |
| 740 | *keyp, *ptrp, ncblk); | 740 | *keyp, *ptrp, ncblk); |
| 741 | if (!buffer_dirty(path[level].bp_bh)) | 741 | if (!buffer_dirty(path[level].bp_bh)) |
| 742 | nilfs_btnode_mark_dirty(path[level].bp_bh); | 742 | mark_buffer_dirty(path[level].bp_bh); |
| 743 | 743 | ||
| 744 | if (path[level].bp_index == 0) | 744 | if (path[level].bp_index == 0) |
| 745 | nilfs_btree_promote_key(btree, path, level + 1, | 745 | nilfs_btree_promote_key(btree, path, level + 1, |
| @@ -777,9 +777,9 @@ static void nilfs_btree_carry_left(struct nilfs_bmap *btree, | |||
| 777 | nilfs_btree_node_move_left(left, node, n, ncblk, ncblk); | 777 | nilfs_btree_node_move_left(left, node, n, ncblk, ncblk); |
| 778 | 778 | ||
| 779 | if (!buffer_dirty(path[level].bp_bh)) | 779 | if (!buffer_dirty(path[level].bp_bh)) |
| 780 | nilfs_btnode_mark_dirty(path[level].bp_bh); | 780 | mark_buffer_dirty(path[level].bp_bh); |
| 781 | if (!buffer_dirty(path[level].bp_sib_bh)) | 781 | if (!buffer_dirty(path[level].bp_sib_bh)) |
| 782 | nilfs_btnode_mark_dirty(path[level].bp_sib_bh); | 782 | mark_buffer_dirty(path[level].bp_sib_bh); |
| 783 | 783 | ||
| 784 | nilfs_btree_promote_key(btree, path, level + 1, | 784 | nilfs_btree_promote_key(btree, path, level + 1, |
| 785 | nilfs_btree_node_get_key(node, 0)); | 785 | nilfs_btree_node_get_key(node, 0)); |
| @@ -823,9 +823,9 @@ static void nilfs_btree_carry_right(struct nilfs_bmap *btree, | |||
| 823 | nilfs_btree_node_move_right(node, right, n, ncblk, ncblk); | 823 | nilfs_btree_node_move_right(node, right, n, ncblk, ncblk); |
| 824 | 824 | ||
| 825 | if (!buffer_dirty(path[level].bp_bh)) | 825 | if (!buffer_dirty(path[level].bp_bh)) |
| 826 | nilfs_btnode_mark_dirty(path[level].bp_bh); | 826 | mark_buffer_dirty(path[level].bp_bh); |
| 827 | if (!buffer_dirty(path[level].bp_sib_bh)) | 827 | if (!buffer_dirty(path[level].bp_sib_bh)) |
| 828 | nilfs_btnode_mark_dirty(path[level].bp_sib_bh); | 828 | mark_buffer_dirty(path[level].bp_sib_bh); |
| 829 | 829 | ||
| 830 | path[level + 1].bp_index++; | 830 | path[level + 1].bp_index++; |
| 831 | nilfs_btree_promote_key(btree, path, level + 1, | 831 | nilfs_btree_promote_key(btree, path, level + 1, |
| @@ -870,9 +870,9 @@ static void nilfs_btree_split(struct nilfs_bmap *btree, | |||
| 870 | nilfs_btree_node_move_right(node, right, n, ncblk, ncblk); | 870 | nilfs_btree_node_move_right(node, right, n, ncblk, ncblk); |
| 871 | 871 | ||
| 872 | if (!buffer_dirty(path[level].bp_bh)) | 872 | if (!buffer_dirty(path[level].bp_bh)) |
| 873 | nilfs_btnode_mark_dirty(path[level].bp_bh); | 873 | mark_buffer_dirty(path[level].bp_bh); |
| 874 | if (!buffer_dirty(path[level].bp_sib_bh)) | 874 | if (!buffer_dirty(path[level].bp_sib_bh)) |
| 875 | nilfs_btnode_mark_dirty(path[level].bp_sib_bh); | 875 | mark_buffer_dirty(path[level].bp_sib_bh); |
| 876 | 876 | ||
| 877 | newkey = nilfs_btree_node_get_key(right, 0); | 877 | newkey = nilfs_btree_node_get_key(right, 0); |
| 878 | newptr = path[level].bp_newreq.bpr_ptr; | 878 | newptr = path[level].bp_newreq.bpr_ptr; |
| @@ -919,7 +919,7 @@ static void nilfs_btree_grow(struct nilfs_bmap *btree, | |||
| 919 | nilfs_btree_node_set_level(root, level + 1); | 919 | nilfs_btree_node_set_level(root, level + 1); |
| 920 | 920 | ||
| 921 | if (!buffer_dirty(path[level].bp_sib_bh)) | 921 | if (!buffer_dirty(path[level].bp_sib_bh)) |
| 922 | nilfs_btnode_mark_dirty(path[level].bp_sib_bh); | 922 | mark_buffer_dirty(path[level].bp_sib_bh); |
| 923 | 923 | ||
| 924 | path[level].bp_bh = path[level].bp_sib_bh; | 924 | path[level].bp_bh = path[level].bp_sib_bh; |
| 925 | path[level].bp_sib_bh = NULL; | 925 | path[level].bp_sib_bh = NULL; |
| @@ -1194,7 +1194,7 @@ static void nilfs_btree_do_delete(struct nilfs_bmap *btree, | |||
| 1194 | nilfs_btree_node_delete(node, path[level].bp_index, | 1194 | nilfs_btree_node_delete(node, path[level].bp_index, |
| 1195 | keyp, ptrp, ncblk); | 1195 | keyp, ptrp, ncblk); |
| 1196 | if (!buffer_dirty(path[level].bp_bh)) | 1196 | if (!buffer_dirty(path[level].bp_bh)) |
| 1197 | nilfs_btnode_mark_dirty(path[level].bp_bh); | 1197 | mark_buffer_dirty(path[level].bp_bh); |
| 1198 | if (path[level].bp_index == 0) | 1198 | if (path[level].bp_index == 0) |
| 1199 | nilfs_btree_promote_key(btree, path, level + 1, | 1199 | nilfs_btree_promote_key(btree, path, level + 1, |
| 1200 | nilfs_btree_node_get_key(node, 0)); | 1200 | nilfs_btree_node_get_key(node, 0)); |
| @@ -1226,9 +1226,9 @@ static void nilfs_btree_borrow_left(struct nilfs_bmap *btree, | |||
| 1226 | nilfs_btree_node_move_right(left, node, n, ncblk, ncblk); | 1226 | nilfs_btree_node_move_right(left, node, n, ncblk, ncblk); |
| 1227 | 1227 | ||
| 1228 | if (!buffer_dirty(path[level].bp_bh)) | 1228 | if (!buffer_dirty(path[level].bp_bh)) |
| 1229 | nilfs_btnode_mark_dirty(path[level].bp_bh); | 1229 | mark_buffer_dirty(path[level].bp_bh); |
| 1230 | if (!buffer_dirty(path[level].bp_sib_bh)) | 1230 | if (!buffer_dirty(path[level].bp_sib_bh)) |
| 1231 | nilfs_btnode_mark_dirty(path[level].bp_sib_bh); | 1231 | mark_buffer_dirty(path[level].bp_sib_bh); |
| 1232 | 1232 | ||
| 1233 | nilfs_btree_promote_key(btree, path, level + 1, | 1233 | nilfs_btree_promote_key(btree, path, level + 1, |
| 1234 | nilfs_btree_node_get_key(node, 0)); | 1234 | nilfs_btree_node_get_key(node, 0)); |
| @@ -1258,9 +1258,9 @@ static void nilfs_btree_borrow_right(struct nilfs_bmap *btree, | |||
| 1258 | nilfs_btree_node_move_left(node, right, n, ncblk, ncblk); | 1258 | nilfs_btree_node_move_left(node, right, n, ncblk, ncblk); |
| 1259 | 1259 | ||
| 1260 | if (!buffer_dirty(path[level].bp_bh)) | 1260 | if (!buffer_dirty(path[level].bp_bh)) |
| 1261 | nilfs_btnode_mark_dirty(path[level].bp_bh); | 1261 | mark_buffer_dirty(path[level].bp_bh); |
| 1262 | if (!buffer_dirty(path[level].bp_sib_bh)) | 1262 | if (!buffer_dirty(path[level].bp_sib_bh)) |
| 1263 | nilfs_btnode_mark_dirty(path[level].bp_sib_bh); | 1263 | mark_buffer_dirty(path[level].bp_sib_bh); |
| 1264 | 1264 | ||
| 1265 | path[level + 1].bp_index++; | 1265 | path[level + 1].bp_index++; |
| 1266 | nilfs_btree_promote_key(btree, path, level + 1, | 1266 | nilfs_btree_promote_key(btree, path, level + 1, |
| @@ -1289,7 +1289,7 @@ static void nilfs_btree_concat_left(struct nilfs_bmap *btree, | |||
| 1289 | nilfs_btree_node_move_left(left, node, n, ncblk, ncblk); | 1289 | nilfs_btree_node_move_left(left, node, n, ncblk, ncblk); |
| 1290 | 1290 | ||
| 1291 | if (!buffer_dirty(path[level].bp_sib_bh)) | 1291 | if (!buffer_dirty(path[level].bp_sib_bh)) |
| 1292 | nilfs_btnode_mark_dirty(path[level].bp_sib_bh); | 1292 | mark_buffer_dirty(path[level].bp_sib_bh); |
| 1293 | 1293 | ||
| 1294 | nilfs_btnode_delete(path[level].bp_bh); | 1294 | nilfs_btnode_delete(path[level].bp_bh); |
| 1295 | path[level].bp_bh = path[level].bp_sib_bh; | 1295 | path[level].bp_bh = path[level].bp_sib_bh; |
| @@ -1315,7 +1315,7 @@ static void nilfs_btree_concat_right(struct nilfs_bmap *btree, | |||
| 1315 | nilfs_btree_node_move_left(node, right, n, ncblk, ncblk); | 1315 | nilfs_btree_node_move_left(node, right, n, ncblk, ncblk); |
| 1316 | 1316 | ||
| 1317 | if (!buffer_dirty(path[level].bp_bh)) | 1317 | if (!buffer_dirty(path[level].bp_bh)) |
| 1318 | nilfs_btnode_mark_dirty(path[level].bp_bh); | 1318 | mark_buffer_dirty(path[level].bp_bh); |
| 1319 | 1319 | ||
| 1320 | nilfs_btnode_delete(path[level].bp_sib_bh); | 1320 | nilfs_btnode_delete(path[level].bp_sib_bh); |
| 1321 | path[level].bp_sib_bh = NULL; | 1321 | path[level].bp_sib_bh = NULL; |
| @@ -1709,7 +1709,7 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *btree, | |||
| 1709 | nilfs_btree_node_init(node, 0, 1, n, ncblk, keys, ptrs); | 1709 | nilfs_btree_node_init(node, 0, 1, n, ncblk, keys, ptrs); |
| 1710 | nilfs_btree_node_insert(node, n, key, dreq->bpr_ptr, ncblk); | 1710 | nilfs_btree_node_insert(node, n, key, dreq->bpr_ptr, ncblk); |
| 1711 | if (!buffer_dirty(bh)) | 1711 | if (!buffer_dirty(bh)) |
| 1712 | nilfs_btnode_mark_dirty(bh); | 1712 | mark_buffer_dirty(bh); |
| 1713 | if (!nilfs_bmap_dirty(btree)) | 1713 | if (!nilfs_bmap_dirty(btree)) |
| 1714 | nilfs_bmap_set_dirty(btree); | 1714 | nilfs_bmap_set_dirty(btree); |
| 1715 | 1715 | ||
| @@ -1787,7 +1787,7 @@ static int nilfs_btree_propagate_p(struct nilfs_bmap *btree, | |||
| 1787 | { | 1787 | { |
| 1788 | while ((++level < nilfs_btree_height(btree) - 1) && | 1788 | while ((++level < nilfs_btree_height(btree) - 1) && |
| 1789 | !buffer_dirty(path[level].bp_bh)) | 1789 | !buffer_dirty(path[level].bp_bh)) |
| 1790 | nilfs_btnode_mark_dirty(path[level].bp_bh); | 1790 | mark_buffer_dirty(path[level].bp_bh); |
| 1791 | 1791 | ||
| 1792 | return 0; | 1792 | return 0; |
| 1793 | } | 1793 | } |
| @@ -2229,7 +2229,7 @@ static int nilfs_btree_mark(struct nilfs_bmap *btree, __u64 key, int level) | |||
| 2229 | } | 2229 | } |
| 2230 | 2230 | ||
| 2231 | if (!buffer_dirty(bh)) | 2231 | if (!buffer_dirty(bh)) |
| 2232 | nilfs_btnode_mark_dirty(bh); | 2232 | mark_buffer_dirty(bh); |
| 2233 | brelse(bh); | 2233 | brelse(bh); |
| 2234 | if (!nilfs_bmap_dirty(btree)) | 2234 | if (!nilfs_bmap_dirty(btree)) |
| 2235 | nilfs_bmap_set_dirty(btree); | 2235 | nilfs_bmap_set_dirty(btree); |
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c index 5ff15a8a1024..c9b342c8b503 100644 --- a/fs/nilfs2/cpfile.c +++ b/fs/nilfs2/cpfile.c | |||
| @@ -216,14 +216,14 @@ int nilfs_cpfile_get_checkpoint(struct inode *cpfile, | |||
| 216 | if (!nilfs_cpfile_is_in_first(cpfile, cno)) | 216 | if (!nilfs_cpfile_is_in_first(cpfile, cno)) |
| 217 | nilfs_cpfile_block_add_valid_checkpoints(cpfile, cp_bh, | 217 | nilfs_cpfile_block_add_valid_checkpoints(cpfile, cp_bh, |
| 218 | kaddr, 1); | 218 | kaddr, 1); |
| 219 | nilfs_mdt_mark_buffer_dirty(cp_bh); | 219 | mark_buffer_dirty(cp_bh); |
| 220 | 220 | ||
| 221 | kaddr = kmap_atomic(header_bh->b_page, KM_USER0); | 221 | kaddr = kmap_atomic(header_bh->b_page, KM_USER0); |
| 222 | header = nilfs_cpfile_block_get_header(cpfile, header_bh, | 222 | header = nilfs_cpfile_block_get_header(cpfile, header_bh, |
| 223 | kaddr); | 223 | kaddr); |
| 224 | le64_add_cpu(&header->ch_ncheckpoints, 1); | 224 | le64_add_cpu(&header->ch_ncheckpoints, 1); |
| 225 | kunmap_atomic(kaddr, KM_USER0); | 225 | kunmap_atomic(kaddr, KM_USER0); |
| 226 | nilfs_mdt_mark_buffer_dirty(header_bh); | 226 | mark_buffer_dirty(header_bh); |
| 227 | nilfs_mdt_mark_dirty(cpfile); | 227 | nilfs_mdt_mark_dirty(cpfile); |
| 228 | } | 228 | } |
| 229 | 229 | ||
| @@ -326,7 +326,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, | |||
| 326 | } | 326 | } |
| 327 | if (nicps > 0) { | 327 | if (nicps > 0) { |
| 328 | tnicps += nicps; | 328 | tnicps += nicps; |
| 329 | nilfs_mdt_mark_buffer_dirty(cp_bh); | 329 | mark_buffer_dirty(cp_bh); |
| 330 | nilfs_mdt_mark_dirty(cpfile); | 330 | nilfs_mdt_mark_dirty(cpfile); |
| 331 | if (!nilfs_cpfile_is_in_first(cpfile, cno)) { | 331 | if (!nilfs_cpfile_is_in_first(cpfile, cno)) { |
| 332 | count = | 332 | count = |
| @@ -358,7 +358,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, | |||
| 358 | header = nilfs_cpfile_block_get_header(cpfile, header_bh, | 358 | header = nilfs_cpfile_block_get_header(cpfile, header_bh, |
| 359 | kaddr); | 359 | kaddr); |
| 360 | le64_add_cpu(&header->ch_ncheckpoints, -(u64)tnicps); | 360 | le64_add_cpu(&header->ch_ncheckpoints, -(u64)tnicps); |
| 361 | nilfs_mdt_mark_buffer_dirty(header_bh); | 361 | mark_buffer_dirty(header_bh); |
| 362 | nilfs_mdt_mark_dirty(cpfile); | 362 | nilfs_mdt_mark_dirty(cpfile); |
| 363 | kunmap_atomic(kaddr, KM_USER0); | 363 | kunmap_atomic(kaddr, KM_USER0); |
| 364 | } | 364 | } |
| @@ -671,10 +671,10 @@ static int nilfs_cpfile_set_snapshot(struct inode *cpfile, __u64 cno) | |||
| 671 | le64_add_cpu(&header->ch_nsnapshots, 1); | 671 | le64_add_cpu(&header->ch_nsnapshots, 1); |
| 672 | kunmap_atomic(kaddr, KM_USER0); | 672 | kunmap_atomic(kaddr, KM_USER0); |
| 673 | 673 | ||
| 674 | nilfs_mdt_mark_buffer_dirty(prev_bh); | 674 | mark_buffer_dirty(prev_bh); |
| 675 | nilfs_mdt_mark_buffer_dirty(curr_bh); | 675 | mark_buffer_dirty(curr_bh); |
| 676 | nilfs_mdt_mark_buffer_dirty(cp_bh); | 676 | mark_buffer_dirty(cp_bh); |
| 677 | nilfs_mdt_mark_buffer_dirty(header_bh); | 677 | mark_buffer_dirty(header_bh); |
| 678 | nilfs_mdt_mark_dirty(cpfile); | 678 | nilfs_mdt_mark_dirty(cpfile); |
| 679 | 679 | ||
| 680 | brelse(prev_bh); | 680 | brelse(prev_bh); |
| @@ -774,10 +774,10 @@ static int nilfs_cpfile_clear_snapshot(struct inode *cpfile, __u64 cno) | |||
| 774 | le64_add_cpu(&header->ch_nsnapshots, -1); | 774 | le64_add_cpu(&header->ch_nsnapshots, -1); |
| 775 | kunmap_atomic(kaddr, KM_USER0); | 775 | kunmap_atomic(kaddr, KM_USER0); |
| 776 | 776 | ||
| 777 | nilfs_mdt_mark_buffer_dirty(next_bh); | 777 | mark_buffer_dirty(next_bh); |
| 778 | nilfs_mdt_mark_buffer_dirty(prev_bh); | 778 | mark_buffer_dirty(prev_bh); |
| 779 | nilfs_mdt_mark_buffer_dirty(cp_bh); | 779 | mark_buffer_dirty(cp_bh); |
| 780 | nilfs_mdt_mark_buffer_dirty(header_bh); | 780 | mark_buffer_dirty(header_bh); |
| 781 | nilfs_mdt_mark_dirty(cpfile); | 781 | nilfs_mdt_mark_dirty(cpfile); |
| 782 | 782 | ||
| 783 | brelse(prev_bh); | 783 | brelse(prev_bh); |
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c index 59e5fe742f7b..fcc2f869af16 100644 --- a/fs/nilfs2/dat.c +++ b/fs/nilfs2/dat.c | |||
| @@ -54,7 +54,7 @@ static int nilfs_dat_prepare_entry(struct inode *dat, | |||
| 54 | static void nilfs_dat_commit_entry(struct inode *dat, | 54 | static void nilfs_dat_commit_entry(struct inode *dat, |
| 55 | struct nilfs_palloc_req *req) | 55 | struct nilfs_palloc_req *req) |
| 56 | { | 56 | { |
| 57 | nilfs_mdt_mark_buffer_dirty(req->pr_entry_bh); | 57 | mark_buffer_dirty(req->pr_entry_bh); |
| 58 | nilfs_mdt_mark_dirty(dat); | 58 | nilfs_mdt_mark_dirty(dat); |
| 59 | brelse(req->pr_entry_bh); | 59 | brelse(req->pr_entry_bh); |
| 60 | } | 60 | } |
| @@ -361,7 +361,7 @@ int nilfs_dat_move(struct inode *dat, __u64 vblocknr, sector_t blocknr) | |||
| 361 | entry->de_blocknr = cpu_to_le64(blocknr); | 361 | entry->de_blocknr = cpu_to_le64(blocknr); |
| 362 | kunmap_atomic(kaddr, KM_USER0); | 362 | kunmap_atomic(kaddr, KM_USER0); |
| 363 | 363 | ||
| 364 | nilfs_mdt_mark_buffer_dirty(entry_bh); | 364 | mark_buffer_dirty(entry_bh); |
| 365 | nilfs_mdt_mark_dirty(dat); | 365 | nilfs_mdt_mark_dirty(dat); |
| 366 | 366 | ||
| 367 | brelse(entry_bh); | 367 | brelse(entry_bh); |
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c index 397e73258631..d7eeca62febd 100644 --- a/fs/nilfs2/file.c +++ b/fs/nilfs2/file.c | |||
| @@ -111,7 +111,6 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 111 | nilfs_transaction_commit(inode->i_sb); | 111 | nilfs_transaction_commit(inode->i_sb); |
| 112 | 112 | ||
| 113 | mapped: | 113 | mapped: |
| 114 | SetPageChecked(page); | ||
| 115 | wait_on_page_writeback(page); | 114 | wait_on_page_writeback(page); |
| 116 | return VM_FAULT_LOCKED; | 115 | return VM_FAULT_LOCKED; |
| 117 | } | 116 | } |
diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c index 1c2a3e23f8b2..08a07a218d26 100644 --- a/fs/nilfs2/gcinode.c +++ b/fs/nilfs2/gcinode.c | |||
| @@ -48,9 +48,6 @@ | |||
| 48 | #include "dat.h" | 48 | #include "dat.h" |
| 49 | #include "ifile.h" | 49 | #include "ifile.h" |
| 50 | 50 | ||
| 51 | static const struct address_space_operations def_gcinode_aops = { | ||
| 52 | }; | ||
| 53 | |||
| 54 | /* | 51 | /* |
| 55 | * nilfs_gccache_submit_read_data() - add data buffer and submit read request | 52 | * nilfs_gccache_submit_read_data() - add data buffer and submit read request |
| 56 | * @inode - gc inode | 53 | * @inode - gc inode |
| @@ -87,9 +84,9 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff, | |||
| 87 | goto out; | 84 | goto out; |
| 88 | 85 | ||
| 89 | if (pbn == 0) { | 86 | if (pbn == 0) { |
| 90 | struct inode *dat_inode = NILFS_I_NILFS(inode)->ns_dat; | 87 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; |
| 91 | /* use original dat, not gc dat. */ | 88 | |
| 92 | err = nilfs_dat_translate(dat_inode, vbn, &pbn); | 89 | err = nilfs_dat_translate(nilfs->ns_dat, vbn, &pbn); |
| 93 | if (unlikely(err)) { /* -EIO, -ENOMEM, -ENOENT */ | 90 | if (unlikely(err)) { /* -EIO, -ENOMEM, -ENOENT */ |
| 94 | brelse(bh); | 91 | brelse(bh); |
| 95 | goto failed; | 92 | goto failed; |
| @@ -103,7 +100,7 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff, | |||
| 103 | } | 100 | } |
| 104 | 101 | ||
| 105 | if (!buffer_mapped(bh)) { | 102 | if (!buffer_mapped(bh)) { |
| 106 | bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev; | 103 | bh->b_bdev = inode->i_sb->s_bdev; |
| 107 | set_buffer_mapped(bh); | 104 | set_buffer_mapped(bh); |
| 108 | } | 105 | } |
| 109 | bh->b_blocknr = pbn; | 106 | bh->b_blocknr = pbn; |
| @@ -160,15 +157,11 @@ int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *bh) | |||
| 160 | if (buffer_dirty(bh)) | 157 | if (buffer_dirty(bh)) |
| 161 | return -EEXIST; | 158 | return -EEXIST; |
| 162 | 159 | ||
| 163 | if (buffer_nilfs_node(bh)) { | 160 | if (buffer_nilfs_node(bh) && nilfs_btree_broken_node_block(bh)) { |
| 164 | if (nilfs_btree_broken_node_block(bh)) { | 161 | clear_buffer_uptodate(bh); |
| 165 | clear_buffer_uptodate(bh); | 162 | return -EIO; |
| 166 | return -EIO; | ||
| 167 | } | ||
| 168 | nilfs_btnode_mark_dirty(bh); | ||
| 169 | } else { | ||
| 170 | nilfs_mark_buffer_dirty(bh); | ||
| 171 | } | 163 | } |
| 164 | mark_buffer_dirty(bh); | ||
| 172 | return 0; | 165 | return 0; |
| 173 | } | 166 | } |
| 174 | 167 | ||
| @@ -178,7 +171,7 @@ int nilfs_init_gcinode(struct inode *inode) | |||
| 178 | 171 | ||
| 179 | inode->i_mode = S_IFREG; | 172 | inode->i_mode = S_IFREG; |
| 180 | mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); | 173 | mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); |
| 181 | inode->i_mapping->a_ops = &def_gcinode_aops; | 174 | inode->i_mapping->a_ops = &empty_aops; |
| 182 | inode->i_mapping->backing_dev_info = inode->i_sb->s_bdi; | 175 | inode->i_mapping->backing_dev_info = inode->i_sb->s_bdi; |
| 183 | 176 | ||
| 184 | ii->i_flags = 0; | 177 | ii->i_flags = 0; |
diff --git a/fs/nilfs2/ifile.c b/fs/nilfs2/ifile.c index bfc73d3a30ed..684d76300a80 100644 --- a/fs/nilfs2/ifile.c +++ b/fs/nilfs2/ifile.c | |||
| @@ -80,7 +80,7 @@ int nilfs_ifile_create_inode(struct inode *ifile, ino_t *out_ino, | |||
| 80 | return ret; | 80 | return ret; |
| 81 | } | 81 | } |
| 82 | nilfs_palloc_commit_alloc_entry(ifile, &req); | 82 | nilfs_palloc_commit_alloc_entry(ifile, &req); |
| 83 | nilfs_mdt_mark_buffer_dirty(req.pr_entry_bh); | 83 | mark_buffer_dirty(req.pr_entry_bh); |
| 84 | nilfs_mdt_mark_dirty(ifile); | 84 | nilfs_mdt_mark_dirty(ifile); |
| 85 | *out_ino = (ino_t)req.pr_entry_nr; | 85 | *out_ino = (ino_t)req.pr_entry_nr; |
| 86 | *out_bh = req.pr_entry_bh; | 86 | *out_bh = req.pr_entry_bh; |
| @@ -128,7 +128,7 @@ int nilfs_ifile_delete_inode(struct inode *ifile, ino_t ino) | |||
| 128 | raw_inode->i_flags = 0; | 128 | raw_inode->i_flags = 0; |
| 129 | kunmap_atomic(kaddr, KM_USER0); | 129 | kunmap_atomic(kaddr, KM_USER0); |
| 130 | 130 | ||
| 131 | nilfs_mdt_mark_buffer_dirty(req.pr_entry_bh); | 131 | mark_buffer_dirty(req.pr_entry_bh); |
| 132 | brelse(req.pr_entry_bh); | 132 | brelse(req.pr_entry_bh); |
| 133 | 133 | ||
| 134 | nilfs_palloc_commit_free_entry(ifile, &req); | 134 | nilfs_palloc_commit_free_entry(ifile, &req); |
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index c0aa27490c02..587f18432832 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
| @@ -74,14 +74,14 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff, | |||
| 74 | struct buffer_head *bh_result, int create) | 74 | struct buffer_head *bh_result, int create) |
| 75 | { | 75 | { |
| 76 | struct nilfs_inode_info *ii = NILFS_I(inode); | 76 | struct nilfs_inode_info *ii = NILFS_I(inode); |
| 77 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; | ||
| 77 | __u64 blknum = 0; | 78 | __u64 blknum = 0; |
| 78 | int err = 0, ret; | 79 | int err = 0, ret; |
| 79 | struct inode *dat = NILFS_I_NILFS(inode)->ns_dat; | ||
| 80 | unsigned maxblocks = bh_result->b_size >> inode->i_blkbits; | 80 | unsigned maxblocks = bh_result->b_size >> inode->i_blkbits; |
| 81 | 81 | ||
| 82 | down_read(&NILFS_MDT(dat)->mi_sem); | 82 | down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); |
| 83 | ret = nilfs_bmap_lookup_contig(ii->i_bmap, blkoff, &blknum, maxblocks); | 83 | ret = nilfs_bmap_lookup_contig(ii->i_bmap, blkoff, &blknum, maxblocks); |
| 84 | up_read(&NILFS_MDT(dat)->mi_sem); | 84 | up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); |
| 85 | if (ret >= 0) { /* found */ | 85 | if (ret >= 0) { /* found */ |
| 86 | map_bh(bh_result, inode->i_sb, blknum); | 86 | map_bh(bh_result, inode->i_sb, blknum); |
| 87 | if (ret > 0) | 87 | if (ret > 0) |
| @@ -596,6 +596,16 @@ void nilfs_write_inode_common(struct inode *inode, | |||
| 596 | raw_inode->i_flags = cpu_to_le32(ii->i_flags); | 596 | raw_inode->i_flags = cpu_to_le32(ii->i_flags); |
| 597 | raw_inode->i_generation = cpu_to_le32(inode->i_generation); | 597 | raw_inode->i_generation = cpu_to_le32(inode->i_generation); |
| 598 | 598 | ||
| 599 | if (NILFS_ROOT_METADATA_FILE(inode->i_ino)) { | ||
| 600 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; | ||
| 601 | |||
| 602 | /* zero-fill unused portion in the case of super root block */ | ||
| 603 | raw_inode->i_xattr = 0; | ||
| 604 | raw_inode->i_pad = 0; | ||
| 605 | memset((void *)raw_inode + sizeof(*raw_inode), 0, | ||
| 606 | nilfs->ns_inode_size - sizeof(*raw_inode)); | ||
| 607 | } | ||
| 608 | |||
| 599 | if (has_bmap) | 609 | if (has_bmap) |
| 600 | nilfs_bmap_write(ii->i_bmap, raw_inode); | 610 | nilfs_bmap_write(ii->i_bmap, raw_inode); |
| 601 | else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) | 611 | else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) |
| @@ -872,8 +882,7 @@ int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty) | |||
| 872 | return -EINVAL; /* NILFS_I_DIRTY may remain for | 882 | return -EINVAL; /* NILFS_I_DIRTY may remain for |
| 873 | freeing inode */ | 883 | freeing inode */ |
| 874 | } | 884 | } |
| 875 | list_del(&ii->i_dirty); | 885 | list_move_tail(&ii->i_dirty, &nilfs->ns_dirty_files); |
| 876 | list_add_tail(&ii->i_dirty, &nilfs->ns_dirty_files); | ||
| 877 | set_bit(NILFS_I_QUEUED, &ii->i_state); | 886 | set_bit(NILFS_I_QUEUED, &ii->i_state); |
| 878 | } | 887 | } |
| 879 | spin_unlock(&nilfs->ns_inode_lock); | 888 | spin_unlock(&nilfs->ns_inode_lock); |
| @@ -892,7 +901,7 @@ int nilfs_mark_inode_dirty(struct inode *inode) | |||
| 892 | return err; | 901 | return err; |
| 893 | } | 902 | } |
| 894 | nilfs_update_inode(inode, ibh); | 903 | nilfs_update_inode(inode, ibh); |
| 895 | nilfs_mdt_mark_buffer_dirty(ibh); | 904 | mark_buffer_dirty(ibh); |
| 896 | nilfs_mdt_mark_dirty(NILFS_I(inode)->i_root->ifile); | 905 | nilfs_mdt_mark_dirty(NILFS_I(inode)->i_root->ifile); |
| 897 | brelse(ibh); | 906 | brelse(ibh); |
| 898 | return 0; | 907 | return 0; |
| @@ -931,7 +940,7 @@ void nilfs_dirty_inode(struct inode *inode) | |||
| 931 | int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 940 | int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
| 932 | __u64 start, __u64 len) | 941 | __u64 start, __u64 len) |
| 933 | { | 942 | { |
| 934 | struct the_nilfs *nilfs = NILFS_I_NILFS(inode); | 943 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; |
| 935 | __u64 logical = 0, phys = 0, size = 0; | 944 | __u64 logical = 0, phys = 0, size = 0; |
| 936 | __u32 flags = 0; | 945 | __u32 flags = 0; |
| 937 | loff_t isize; | 946 | loff_t isize; |
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index f2469ba6246b..41d6743d303c 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c | |||
| @@ -698,6 +698,63 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp, | |||
| 698 | return 0; | 698 | return 0; |
| 699 | } | 699 | } |
| 700 | 700 | ||
| 701 | static int nilfs_ioctl_resize(struct inode *inode, struct file *filp, | ||
| 702 | void __user *argp) | ||
| 703 | { | ||
| 704 | __u64 newsize; | ||
| 705 | int ret = -EPERM; | ||
| 706 | |||
| 707 | if (!capable(CAP_SYS_ADMIN)) | ||
| 708 | goto out; | ||
| 709 | |||
| 710 | ret = mnt_want_write(filp->f_path.mnt); | ||
| 711 | if (ret) | ||
| 712 | goto out; | ||
| 713 | |||
| 714 | ret = -EFAULT; | ||
| 715 | if (copy_from_user(&newsize, argp, sizeof(newsize))) | ||
| 716 | goto out_drop_write; | ||
| 717 | |||
| 718 | ret = nilfs_resize_fs(inode->i_sb, newsize); | ||
| 719 | |||
| 720 | out_drop_write: | ||
| 721 | mnt_drop_write(filp->f_path.mnt); | ||
| 722 | out: | ||
| 723 | return ret; | ||
| 724 | } | ||
| 725 | |||
| 726 | static int nilfs_ioctl_set_alloc_range(struct inode *inode, void __user *argp) | ||
| 727 | { | ||
| 728 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; | ||
| 729 | __u64 range[2]; | ||
| 730 | __u64 minseg, maxseg; | ||
| 731 | unsigned long segbytes; | ||
| 732 | int ret = -EPERM; | ||
| 733 | |||
| 734 | if (!capable(CAP_SYS_ADMIN)) | ||
| 735 | goto out; | ||
| 736 | |||
| 737 | ret = -EFAULT; | ||
| 738 | if (copy_from_user(range, argp, sizeof(__u64[2]))) | ||
| 739 | goto out; | ||
| 740 | |||
| 741 | ret = -ERANGE; | ||
| 742 | if (range[1] > i_size_read(inode->i_sb->s_bdev->bd_inode)) | ||
| 743 | goto out; | ||
| 744 | |||
| 745 | segbytes = nilfs->ns_blocks_per_segment * nilfs->ns_blocksize; | ||
| 746 | |||
| 747 | minseg = range[0] + segbytes - 1; | ||
| 748 | do_div(minseg, segbytes); | ||
| 749 | maxseg = NILFS_SB2_OFFSET_BYTES(range[1]); | ||
| 750 | do_div(maxseg, segbytes); | ||
| 751 | maxseg--; | ||
| 752 | |||
| 753 | ret = nilfs_sufile_set_alloc_range(nilfs->ns_sufile, minseg, maxseg); | ||
| 754 | out: | ||
| 755 | return ret; | ||
| 756 | } | ||
| 757 | |||
| 701 | static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp, | 758 | static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp, |
| 702 | unsigned int cmd, void __user *argp, | 759 | unsigned int cmd, void __user *argp, |
| 703 | size_t membsz, | 760 | size_t membsz, |
| @@ -763,6 +820,10 @@ long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 763 | return nilfs_ioctl_clean_segments(inode, filp, cmd, argp); | 820 | return nilfs_ioctl_clean_segments(inode, filp, cmd, argp); |
| 764 | case NILFS_IOCTL_SYNC: | 821 | case NILFS_IOCTL_SYNC: |
| 765 | return nilfs_ioctl_sync(inode, filp, cmd, argp); | 822 | return nilfs_ioctl_sync(inode, filp, cmd, argp); |
| 823 | case NILFS_IOCTL_RESIZE: | ||
| 824 | return nilfs_ioctl_resize(inode, filp, argp); | ||
| 825 | case NILFS_IOCTL_SET_ALLOC_RANGE: | ||
| 826 | return nilfs_ioctl_set_alloc_range(inode, argp); | ||
| 766 | default: | 827 | default: |
| 767 | return -ENOTTY; | 828 | return -ENOTTY; |
| 768 | } | 829 | } |
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c index a649b05f7069..800e8d78a83b 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c | |||
| @@ -66,7 +66,7 @@ nilfs_mdt_insert_new_block(struct inode *inode, unsigned long block, | |||
| 66 | kunmap_atomic(kaddr, KM_USER0); | 66 | kunmap_atomic(kaddr, KM_USER0); |
| 67 | 67 | ||
| 68 | set_buffer_uptodate(bh); | 68 | set_buffer_uptodate(bh); |
| 69 | nilfs_mark_buffer_dirty(bh); | 69 | mark_buffer_dirty(bh); |
| 70 | nilfs_mdt_mark_dirty(inode); | 70 | nilfs_mdt_mark_dirty(inode); |
| 71 | return 0; | 71 | return 0; |
| 72 | } | 72 | } |
| @@ -355,7 +355,7 @@ int nilfs_mdt_mark_block_dirty(struct inode *inode, unsigned long block) | |||
| 355 | err = nilfs_mdt_read_block(inode, block, 0, &bh); | 355 | err = nilfs_mdt_read_block(inode, block, 0, &bh); |
| 356 | if (unlikely(err)) | 356 | if (unlikely(err)) |
| 357 | return err; | 357 | return err; |
| 358 | nilfs_mark_buffer_dirty(bh); | 358 | mark_buffer_dirty(bh); |
| 359 | nilfs_mdt_mark_dirty(inode); | 359 | nilfs_mdt_mark_dirty(inode); |
| 360 | brelse(bh); | 360 | brelse(bh); |
| 361 | return 0; | 361 | return 0; |
| @@ -450,9 +450,9 @@ int nilfs_mdt_setup_shadow_map(struct inode *inode, | |||
| 450 | 450 | ||
| 451 | INIT_LIST_HEAD(&shadow->frozen_buffers); | 451 | INIT_LIST_HEAD(&shadow->frozen_buffers); |
| 452 | address_space_init_once(&shadow->frozen_data); | 452 | address_space_init_once(&shadow->frozen_data); |
| 453 | nilfs_mapping_init(&shadow->frozen_data, bdi); | 453 | nilfs_mapping_init(&shadow->frozen_data, inode, bdi); |
| 454 | address_space_init_once(&shadow->frozen_btnodes); | 454 | address_space_init_once(&shadow->frozen_btnodes); |
| 455 | nilfs_mapping_init(&shadow->frozen_btnodes, bdi); | 455 | nilfs_mapping_init(&shadow->frozen_btnodes, inode, bdi); |
| 456 | mi->mi_shadow = shadow; | 456 | mi->mi_shadow = shadow; |
| 457 | return 0; | 457 | return 0; |
| 458 | } | 458 | } |
diff --git a/fs/nilfs2/mdt.h b/fs/nilfs2/mdt.h index ed68563ec708..ab20a4baa50f 100644 --- a/fs/nilfs2/mdt.h +++ b/fs/nilfs2/mdt.h | |||
| @@ -64,11 +64,6 @@ static inline struct nilfs_mdt_info *NILFS_MDT(const struct inode *inode) | |||
| 64 | return inode->i_private; | 64 | return inode->i_private; |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | static inline struct the_nilfs *NILFS_I_NILFS(struct inode *inode) | ||
| 68 | { | ||
| 69 | return inode->i_sb->s_fs_info; | ||
| 70 | } | ||
| 71 | |||
| 72 | /* Default GFP flags using highmem */ | 67 | /* Default GFP flags using highmem */ |
| 73 | #define NILFS_MDT_GFP (__GFP_WAIT | __GFP_IO | __GFP_HIGHMEM) | 68 | #define NILFS_MDT_GFP (__GFP_WAIT | __GFP_IO | __GFP_HIGHMEM) |
| 74 | 69 | ||
| @@ -93,8 +88,6 @@ int nilfs_mdt_freeze_buffer(struct inode *inode, struct buffer_head *bh); | |||
| 93 | struct buffer_head *nilfs_mdt_get_frozen_buffer(struct inode *inode, | 88 | struct buffer_head *nilfs_mdt_get_frozen_buffer(struct inode *inode, |
| 94 | struct buffer_head *bh); | 89 | struct buffer_head *bh); |
| 95 | 90 | ||
| 96 | #define nilfs_mdt_mark_buffer_dirty(bh) nilfs_mark_buffer_dirty(bh) | ||
| 97 | |||
| 98 | static inline void nilfs_mdt_mark_dirty(struct inode *inode) | 91 | static inline void nilfs_mdt_mark_dirty(struct inode *inode) |
| 99 | { | 92 | { |
| 100 | if (!test_bit(NILFS_I_DIRTY, &NILFS_I(inode)->i_state)) | 93 | if (!test_bit(NILFS_I_DIRTY, &NILFS_I(inode)->i_state)) |
| @@ -108,7 +101,7 @@ static inline void nilfs_mdt_clear_dirty(struct inode *inode) | |||
| 108 | 101 | ||
| 109 | static inline __u64 nilfs_mdt_cno(struct inode *inode) | 102 | static inline __u64 nilfs_mdt_cno(struct inode *inode) |
| 110 | { | 103 | { |
| 111 | return NILFS_I_NILFS(inode)->ns_cno; | 104 | return ((struct the_nilfs *)inode->i_sb->s_fs_info)->ns_cno; |
| 112 | } | 105 | } |
| 113 | 106 | ||
| 114 | #define nilfs_mdt_bgl_lock(inode, bg) \ | 107 | #define nilfs_mdt_bgl_lock(inode, bg) \ |
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index a8dd344303cb..a9c6a531f80c 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h | |||
| @@ -80,12 +80,6 @@ static inline struct inode *NILFS_BTNC_I(struct address_space *btnc) | |||
| 80 | return &ii->vfs_inode; | 80 | return &ii->vfs_inode; |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | static inline struct inode *NILFS_AS_I(struct address_space *mapping) | ||
| 84 | { | ||
| 85 | return (mapping->host) ? : | ||
| 86 | container_of(mapping, struct inode, i_data); | ||
| 87 | } | ||
| 88 | |||
| 89 | /* | 83 | /* |
| 90 | * Dynamic state flags of NILFS on-memory inode (i_state) | 84 | * Dynamic state flags of NILFS on-memory inode (i_state) |
| 91 | */ | 85 | */ |
| @@ -298,6 +292,7 @@ struct nilfs_super_block **nilfs_prepare_super(struct super_block *sb, | |||
| 298 | int flip); | 292 | int flip); |
| 299 | int nilfs_commit_super(struct super_block *sb, int flag); | 293 | int nilfs_commit_super(struct super_block *sb, int flag); |
| 300 | int nilfs_cleanup_super(struct super_block *sb); | 294 | int nilfs_cleanup_super(struct super_block *sb); |
| 295 | int nilfs_resize_fs(struct super_block *sb, __u64 newsize); | ||
| 301 | int nilfs_attach_checkpoint(struct super_block *sb, __u64 cno, int curr_mnt, | 296 | int nilfs_attach_checkpoint(struct super_block *sb, __u64 cno, int curr_mnt, |
| 302 | struct nilfs_root **root); | 297 | struct nilfs_root **root); |
| 303 | int nilfs_checkpoint_is_mounted(struct super_block *sb, __u64 cno); | 298 | int nilfs_checkpoint_is_mounted(struct super_block *sb, __u64 cno); |
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c index 1168059c7efd..65221a04c6f0 100644 --- a/fs/nilfs2/page.c +++ b/fs/nilfs2/page.c | |||
| @@ -37,8 +37,7 @@ | |||
| 37 | 37 | ||
| 38 | #define NILFS_BUFFER_INHERENT_BITS \ | 38 | #define NILFS_BUFFER_INHERENT_BITS \ |
| 39 | ((1UL << BH_Uptodate) | (1UL << BH_Mapped) | (1UL << BH_NILFS_Node) | \ | 39 | ((1UL << BH_Uptodate) | (1UL << BH_Mapped) | (1UL << BH_NILFS_Node) | \ |
| 40 | (1UL << BH_NILFS_Volatile) | (1UL << BH_NILFS_Allocated) | \ | 40 | (1UL << BH_NILFS_Volatile) | (1UL << BH_NILFS_Checked)) |
| 41 | (1UL << BH_NILFS_Checked)) | ||
| 42 | 41 | ||
| 43 | static struct buffer_head * | 42 | static struct buffer_head * |
| 44 | __nilfs_get_page_block(struct page *page, unsigned long block, pgoff_t index, | 43 | __nilfs_get_page_block(struct page *page, unsigned long block, pgoff_t index, |
| @@ -59,19 +58,6 @@ __nilfs_get_page_block(struct page *page, unsigned long block, pgoff_t index, | |||
| 59 | return bh; | 58 | return bh; |
| 60 | } | 59 | } |
| 61 | 60 | ||
| 62 | /* | ||
| 63 | * Since the page cache of B-tree node pages or data page cache of pseudo | ||
| 64 | * inodes does not have a valid mapping->host pointer, calling | ||
| 65 | * mark_buffer_dirty() for their buffers causes a NULL pointer dereference; | ||
| 66 | * it calls __mark_inode_dirty(NULL) through __set_page_dirty(). | ||
| 67 | * To avoid this problem, the old style mark_buffer_dirty() is used instead. | ||
| 68 | */ | ||
| 69 | void nilfs_mark_buffer_dirty(struct buffer_head *bh) | ||
| 70 | { | ||
| 71 | if (!buffer_dirty(bh) && !test_set_buffer_dirty(bh)) | ||
| 72 | __set_page_dirty_nobuffers(bh->b_page); | ||
| 73 | } | ||
| 74 | |||
| 75 | struct buffer_head *nilfs_grab_buffer(struct inode *inode, | 61 | struct buffer_head *nilfs_grab_buffer(struct inode *inode, |
| 76 | struct address_space *mapping, | 62 | struct address_space *mapping, |
| 77 | unsigned long blkoff, | 63 | unsigned long blkoff, |
| @@ -183,7 +169,7 @@ int nilfs_page_buffers_clean(struct page *page) | |||
| 183 | void nilfs_page_bug(struct page *page) | 169 | void nilfs_page_bug(struct page *page) |
| 184 | { | 170 | { |
| 185 | struct address_space *m; | 171 | struct address_space *m; |
| 186 | unsigned long ino = 0; | 172 | unsigned long ino; |
| 187 | 173 | ||
| 188 | if (unlikely(!page)) { | 174 | if (unlikely(!page)) { |
| 189 | printk(KERN_CRIT "NILFS_PAGE_BUG(NULL)\n"); | 175 | printk(KERN_CRIT "NILFS_PAGE_BUG(NULL)\n"); |
| @@ -191,11 +177,8 @@ void nilfs_page_bug(struct page *page) | |||
| 191 | } | 177 | } |
| 192 | 178 | ||
| 193 | m = page->mapping; | 179 | m = page->mapping; |
| 194 | if (m) { | 180 | ino = m ? m->host->i_ino : 0; |
| 195 | struct inode *inode = NILFS_AS_I(m); | 181 | |
| 196 | if (inode != NULL) | ||
| 197 | ino = inode->i_ino; | ||
| 198 | } | ||
| 199 | printk(KERN_CRIT "NILFS_PAGE_BUG(%p): cnt=%d index#=%llu flags=0x%lx " | 182 | printk(KERN_CRIT "NILFS_PAGE_BUG(%p): cnt=%d index#=%llu flags=0x%lx " |
| 200 | "mapping=%p ino=%lu\n", | 183 | "mapping=%p ino=%lu\n", |
| 201 | page, atomic_read(&page->_count), | 184 | page, atomic_read(&page->_count), |
| @@ -217,56 +200,6 @@ void nilfs_page_bug(struct page *page) | |||
| 217 | } | 200 | } |
| 218 | 201 | ||
| 219 | /** | 202 | /** |
| 220 | * nilfs_alloc_private_page - allocate a private page with buffer heads | ||
| 221 | * | ||
| 222 | * Return Value: On success, a pointer to the allocated page is returned. | ||
| 223 | * On error, NULL is returned. | ||
| 224 | */ | ||
| 225 | struct page *nilfs_alloc_private_page(struct block_device *bdev, int size, | ||
| 226 | unsigned long state) | ||
| 227 | { | ||
| 228 | struct buffer_head *bh, *head, *tail; | ||
| 229 | struct page *page; | ||
| 230 | |||
| 231 | page = alloc_page(GFP_NOFS); /* page_count of the returned page is 1 */ | ||
| 232 | if (unlikely(!page)) | ||
| 233 | return NULL; | ||
| 234 | |||
| 235 | lock_page(page); | ||
| 236 | head = alloc_page_buffers(page, size, 0); | ||
| 237 | if (unlikely(!head)) { | ||
| 238 | unlock_page(page); | ||
| 239 | __free_page(page); | ||
| 240 | return NULL; | ||
| 241 | } | ||
| 242 | |||
| 243 | bh = head; | ||
| 244 | do { | ||
| 245 | bh->b_state = (1UL << BH_NILFS_Allocated) | state; | ||
| 246 | tail = bh; | ||
| 247 | bh->b_bdev = bdev; | ||
| 248 | bh = bh->b_this_page; | ||
| 249 | } while (bh); | ||
| 250 | |||
| 251 | tail->b_this_page = head; | ||
| 252 | attach_page_buffers(page, head); | ||
| 253 | |||
| 254 | return page; | ||
| 255 | } | ||
| 256 | |||
| 257 | void nilfs_free_private_page(struct page *page) | ||
| 258 | { | ||
| 259 | BUG_ON(!PageLocked(page)); | ||
| 260 | BUG_ON(page->mapping); | ||
| 261 | |||
| 262 | if (page_has_buffers(page) && !try_to_free_buffers(page)) | ||
| 263 | NILFS_PAGE_BUG(page, "failed to free page"); | ||
| 264 | |||
| 265 | unlock_page(page); | ||
| 266 | __free_page(page); | ||
| 267 | } | ||
| 268 | |||
| 269 | /** | ||
| 270 | * nilfs_copy_page -- copy the page with buffers | 203 | * nilfs_copy_page -- copy the page with buffers |
| 271 | * @dst: destination page | 204 | * @dst: destination page |
| 272 | * @src: source page | 205 | * @src: source page |
| @@ -492,10 +425,10 @@ unsigned nilfs_page_count_clean_buffers(struct page *page, | |||
| 492 | return nc; | 425 | return nc; |
| 493 | } | 426 | } |
| 494 | 427 | ||
| 495 | void nilfs_mapping_init(struct address_space *mapping, | 428 | void nilfs_mapping_init(struct address_space *mapping, struct inode *inode, |
| 496 | struct backing_dev_info *bdi) | 429 | struct backing_dev_info *bdi) |
| 497 | { | 430 | { |
| 498 | mapping->host = NULL; | 431 | mapping->host = inode; |
| 499 | mapping->flags = 0; | 432 | mapping->flags = 0; |
| 500 | mapping_set_gfp_mask(mapping, GFP_NOFS); | 433 | mapping_set_gfp_mask(mapping, GFP_NOFS); |
| 501 | mapping->assoc_mapping = NULL; | 434 | mapping->assoc_mapping = NULL; |
diff --git a/fs/nilfs2/page.h b/fs/nilfs2/page.h index f06b79ad7493..fb7de71605a0 100644 --- a/fs/nilfs2/page.h +++ b/fs/nilfs2/page.h | |||
| @@ -38,14 +38,12 @@ enum { | |||
| 38 | BH_NILFS_Redirected, | 38 | BH_NILFS_Redirected, |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | BUFFER_FNS(NILFS_Allocated, nilfs_allocated) /* nilfs private buffers */ | ||
| 42 | BUFFER_FNS(NILFS_Node, nilfs_node) /* nilfs node buffers */ | 41 | BUFFER_FNS(NILFS_Node, nilfs_node) /* nilfs node buffers */ |
| 43 | BUFFER_FNS(NILFS_Volatile, nilfs_volatile) | 42 | BUFFER_FNS(NILFS_Volatile, nilfs_volatile) |
| 44 | BUFFER_FNS(NILFS_Checked, nilfs_checked) /* buffer is verified */ | 43 | BUFFER_FNS(NILFS_Checked, nilfs_checked) /* buffer is verified */ |
| 45 | BUFFER_FNS(NILFS_Redirected, nilfs_redirected) /* redirected to a copy */ | 44 | BUFFER_FNS(NILFS_Redirected, nilfs_redirected) /* redirected to a copy */ |
| 46 | 45 | ||
| 47 | 46 | ||
| 48 | void nilfs_mark_buffer_dirty(struct buffer_head *bh); | ||
| 49 | int __nilfs_clear_page_dirty(struct page *); | 47 | int __nilfs_clear_page_dirty(struct page *); |
| 50 | 48 | ||
| 51 | struct buffer_head *nilfs_grab_buffer(struct inode *, struct address_space *, | 49 | struct buffer_head *nilfs_grab_buffer(struct inode *, struct address_space *, |
| @@ -54,14 +52,11 @@ void nilfs_forget_buffer(struct buffer_head *); | |||
| 54 | void nilfs_copy_buffer(struct buffer_head *, struct buffer_head *); | 52 | void nilfs_copy_buffer(struct buffer_head *, struct buffer_head *); |
| 55 | int nilfs_page_buffers_clean(struct page *); | 53 | int nilfs_page_buffers_clean(struct page *); |
| 56 | void nilfs_page_bug(struct page *); | 54 | void nilfs_page_bug(struct page *); |
| 57 | struct page *nilfs_alloc_private_page(struct block_device *, int, | ||
| 58 | unsigned long); | ||
| 59 | void nilfs_free_private_page(struct page *); | ||
| 60 | 55 | ||
| 61 | int nilfs_copy_dirty_pages(struct address_space *, struct address_space *); | 56 | int nilfs_copy_dirty_pages(struct address_space *, struct address_space *); |
| 62 | void nilfs_copy_back_pages(struct address_space *, struct address_space *); | 57 | void nilfs_copy_back_pages(struct address_space *, struct address_space *); |
| 63 | void nilfs_clear_dirty_pages(struct address_space *); | 58 | void nilfs_clear_dirty_pages(struct address_space *); |
| 64 | void nilfs_mapping_init(struct address_space *mapping, | 59 | void nilfs_mapping_init(struct address_space *mapping, struct inode *inode, |
| 65 | struct backing_dev_info *bdi); | 60 | struct backing_dev_info *bdi); |
| 66 | unsigned nilfs_page_count_clean_buffers(struct page *, unsigned, unsigned); | 61 | unsigned nilfs_page_count_clean_buffers(struct page *, unsigned, unsigned); |
| 67 | unsigned long nilfs_find_uncommitted_extent(struct inode *inode, | 62 | unsigned long nilfs_find_uncommitted_extent(struct inode *inode, |
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c index ba4a64518f38..a604ac0331b2 100644 --- a/fs/nilfs2/recovery.c +++ b/fs/nilfs2/recovery.c | |||
| @@ -387,9 +387,9 @@ static int nilfs_scan_dsync_log(struct the_nilfs *nilfs, sector_t start_blocknr, | |||
| 387 | static void dispose_recovery_list(struct list_head *head) | 387 | static void dispose_recovery_list(struct list_head *head) |
| 388 | { | 388 | { |
| 389 | while (!list_empty(head)) { | 389 | while (!list_empty(head)) { |
| 390 | struct nilfs_recovery_block *rb | 390 | struct nilfs_recovery_block *rb; |
| 391 | = list_entry(head->next, | 391 | |
| 392 | struct nilfs_recovery_block, list); | 392 | rb = list_first_entry(head, struct nilfs_recovery_block, list); |
| 393 | list_del(&rb->list); | 393 | list_del(&rb->list); |
| 394 | kfree(rb); | 394 | kfree(rb); |
| 395 | } | 395 | } |
| @@ -416,9 +416,9 @@ static int nilfs_segment_list_add(struct list_head *head, __u64 segnum) | |||
| 416 | void nilfs_dispose_segment_list(struct list_head *head) | 416 | void nilfs_dispose_segment_list(struct list_head *head) |
| 417 | { | 417 | { |
| 418 | while (!list_empty(head)) { | 418 | while (!list_empty(head)) { |
| 419 | struct nilfs_segment_entry *ent | 419 | struct nilfs_segment_entry *ent; |
| 420 | = list_entry(head->next, | 420 | |
| 421 | struct nilfs_segment_entry, list); | 421 | ent = list_first_entry(head, struct nilfs_segment_entry, list); |
| 422 | list_del(&ent->list); | 422 | list_del(&ent->list); |
| 423 | kfree(ent); | 423 | kfree(ent); |
| 424 | } | 424 | } |
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c index 2853ff20f85a..850a7c0228fb 100644 --- a/fs/nilfs2/segbuf.c +++ b/fs/nilfs2/segbuf.c | |||
| @@ -239,12 +239,15 @@ nilfs_segbuf_fill_in_super_root_crc(struct nilfs_segment_buffer *segbuf, | |||
| 239 | u32 seed) | 239 | u32 seed) |
| 240 | { | 240 | { |
| 241 | struct nilfs_super_root *raw_sr; | 241 | struct nilfs_super_root *raw_sr; |
| 242 | struct the_nilfs *nilfs = segbuf->sb_super->s_fs_info; | ||
| 243 | unsigned srsize; | ||
| 242 | u32 crc; | 244 | u32 crc; |
| 243 | 245 | ||
| 244 | raw_sr = (struct nilfs_super_root *)segbuf->sb_super_root->b_data; | 246 | raw_sr = (struct nilfs_super_root *)segbuf->sb_super_root->b_data; |
| 247 | srsize = NILFS_SR_BYTES(nilfs->ns_inode_size); | ||
| 245 | crc = crc32_le(seed, | 248 | crc = crc32_le(seed, |
| 246 | (unsigned char *)raw_sr + sizeof(raw_sr->sr_sum), | 249 | (unsigned char *)raw_sr + sizeof(raw_sr->sr_sum), |
| 247 | NILFS_SR_BYTES - sizeof(raw_sr->sr_sum)); | 250 | srsize - sizeof(raw_sr->sr_sum)); |
| 248 | raw_sr->sr_sum = cpu_to_le32(crc); | 251 | raw_sr->sr_sum = cpu_to_le32(crc); |
| 249 | } | 252 | } |
| 250 | 253 | ||
| @@ -254,18 +257,6 @@ static void nilfs_release_buffers(struct list_head *list) | |||
| 254 | 257 | ||
| 255 | list_for_each_entry_safe(bh, n, list, b_assoc_buffers) { | 258 | list_for_each_entry_safe(bh, n, list, b_assoc_buffers) { |
| 256 | list_del_init(&bh->b_assoc_buffers); | 259 | list_del_init(&bh->b_assoc_buffers); |
| 257 | if (buffer_nilfs_allocated(bh)) { | ||
| 258 | struct page *clone_page = bh->b_page; | ||
| 259 | |||
| 260 | /* remove clone page */ | ||
| 261 | brelse(bh); | ||
| 262 | page_cache_release(clone_page); /* for each bh */ | ||
| 263 | if (page_count(clone_page) <= 2) { | ||
| 264 | lock_page(clone_page); | ||
| 265 | nilfs_free_private_page(clone_page); | ||
| 266 | } | ||
| 267 | continue; | ||
| 268 | } | ||
| 269 | brelse(bh); | 260 | brelse(bh); |
| 270 | } | 261 | } |
| 271 | } | 262 | } |
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index afe4f2183454..141646e88fb5 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
| @@ -655,13 +655,10 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode, | |||
| 655 | if (unlikely(page->index > last)) | 655 | if (unlikely(page->index > last)) |
| 656 | break; | 656 | break; |
| 657 | 657 | ||
| 658 | if (mapping->host) { | 658 | lock_page(page); |
| 659 | lock_page(page); | 659 | if (!page_has_buffers(page)) |
| 660 | if (!page_has_buffers(page)) | 660 | create_empty_buffers(page, 1 << inode->i_blkbits, 0); |
| 661 | create_empty_buffers(page, | 661 | unlock_page(page); |
| 662 | 1 << inode->i_blkbits, 0); | ||
| 663 | unlock_page(page); | ||
| 664 | } | ||
| 665 | 662 | ||
| 666 | bh = head = page_buffers(page); | 663 | bh = head = page_buffers(page); |
| 667 | do { | 664 | do { |
| @@ -809,7 +806,7 @@ static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci) | |||
| 809 | /* The following code is duplicated with cpfile. But, it is | 806 | /* The following code is duplicated with cpfile. But, it is |
| 810 | needed to collect the checkpoint even if it was not newly | 807 | needed to collect the checkpoint even if it was not newly |
| 811 | created */ | 808 | created */ |
| 812 | nilfs_mdt_mark_buffer_dirty(bh_cp); | 809 | mark_buffer_dirty(bh_cp); |
| 813 | nilfs_mdt_mark_dirty(nilfs->ns_cpfile); | 810 | nilfs_mdt_mark_dirty(nilfs->ns_cpfile); |
| 814 | nilfs_cpfile_put_checkpoint( | 811 | nilfs_cpfile_put_checkpoint( |
| 815 | nilfs->ns_cpfile, nilfs->ns_cno, bh_cp); | 812 | nilfs->ns_cpfile, nilfs->ns_cno, bh_cp); |
| @@ -889,12 +886,14 @@ static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci, | |||
| 889 | { | 886 | { |
| 890 | struct buffer_head *bh_sr; | 887 | struct buffer_head *bh_sr; |
| 891 | struct nilfs_super_root *raw_sr; | 888 | struct nilfs_super_root *raw_sr; |
| 892 | unsigned isz = nilfs->ns_inode_size; | 889 | unsigned isz, srsz; |
| 893 | 890 | ||
| 894 | bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root; | 891 | bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root; |
| 895 | raw_sr = (struct nilfs_super_root *)bh_sr->b_data; | 892 | raw_sr = (struct nilfs_super_root *)bh_sr->b_data; |
| 893 | isz = nilfs->ns_inode_size; | ||
| 894 | srsz = NILFS_SR_BYTES(isz); | ||
| 896 | 895 | ||
| 897 | raw_sr->sr_bytes = cpu_to_le16(NILFS_SR_BYTES); | 896 | raw_sr->sr_bytes = cpu_to_le16(srsz); |
| 898 | raw_sr->sr_nongc_ctime | 897 | raw_sr->sr_nongc_ctime |
| 899 | = cpu_to_le64(nilfs_doing_gc() ? | 898 | = cpu_to_le64(nilfs_doing_gc() ? |
| 900 | nilfs->ns_nongc_ctime : sci->sc_seg_ctime); | 899 | nilfs->ns_nongc_ctime : sci->sc_seg_ctime); |
| @@ -906,6 +905,7 @@ static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci, | |||
| 906 | NILFS_SR_CPFILE_OFFSET(isz), 1); | 905 | NILFS_SR_CPFILE_OFFSET(isz), 1); |
| 907 | nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr + | 906 | nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr + |
| 908 | NILFS_SR_SUFILE_OFFSET(isz), 1); | 907 | NILFS_SR_SUFILE_OFFSET(isz), 1); |
| 908 | memset((void *)raw_sr + srsz, 0, nilfs->ns_blocksize - srsz); | ||
| 909 | } | 909 | } |
| 910 | 910 | ||
| 911 | static void nilfs_redirty_inodes(struct list_head *head) | 911 | static void nilfs_redirty_inodes(struct list_head *head) |
| @@ -954,8 +954,8 @@ static int nilfs_segctor_apply_buffers(struct nilfs_sc_info *sci, | |||
| 954 | 954 | ||
| 955 | dispose_buffers: | 955 | dispose_buffers: |
| 956 | while (!list_empty(listp)) { | 956 | while (!list_empty(listp)) { |
| 957 | bh = list_entry(listp->next, struct buffer_head, | 957 | bh = list_first_entry(listp, struct buffer_head, |
| 958 | b_assoc_buffers); | 958 | b_assoc_buffers); |
| 959 | list_del_init(&bh->b_assoc_buffers); | 959 | list_del_init(&bh->b_assoc_buffers); |
| 960 | brelse(bh); | 960 | brelse(bh); |
| 961 | } | 961 | } |
| @@ -1500,10 +1500,7 @@ nilfs_segctor_update_payload_blocknr(struct nilfs_sc_info *sci, | |||
| 1500 | nblocks = le32_to_cpu(finfo->fi_nblocks); | 1500 | nblocks = le32_to_cpu(finfo->fi_nblocks); |
| 1501 | ndatablk = le32_to_cpu(finfo->fi_ndatablk); | 1501 | ndatablk = le32_to_cpu(finfo->fi_ndatablk); |
| 1502 | 1502 | ||
| 1503 | if (buffer_nilfs_node(bh)) | 1503 | inode = bh->b_page->mapping->host; |
| 1504 | inode = NILFS_BTNC_I(bh->b_page->mapping); | ||
| 1505 | else | ||
| 1506 | inode = NILFS_AS_I(bh->b_page->mapping); | ||
| 1507 | 1504 | ||
| 1508 | if (mode == SC_LSEG_DSYNC) | 1505 | if (mode == SC_LSEG_DSYNC) |
| 1509 | sc_op = &nilfs_sc_dsync_ops; | 1506 | sc_op = &nilfs_sc_dsync_ops; |
| @@ -1556,83 +1553,24 @@ static int nilfs_segctor_assign(struct nilfs_sc_info *sci, int mode) | |||
| 1556 | return 0; | 1553 | return 0; |
| 1557 | } | 1554 | } |
| 1558 | 1555 | ||
| 1559 | static int | 1556 | static void nilfs_begin_page_io(struct page *page) |
| 1560 | nilfs_copy_replace_page_buffers(struct page *page, struct list_head *out) | ||
| 1561 | { | ||
| 1562 | struct page *clone_page; | ||
| 1563 | struct buffer_head *bh, *head, *bh2; | ||
| 1564 | void *kaddr; | ||
| 1565 | |||
| 1566 | bh = head = page_buffers(page); | ||
| 1567 | |||
| 1568 | clone_page = nilfs_alloc_private_page(bh->b_bdev, bh->b_size, 0); | ||
| 1569 | if (unlikely(!clone_page)) | ||
| 1570 | return -ENOMEM; | ||
| 1571 | |||
| 1572 | bh2 = page_buffers(clone_page); | ||
| 1573 | kaddr = kmap_atomic(page, KM_USER0); | ||
| 1574 | do { | ||
| 1575 | if (list_empty(&bh->b_assoc_buffers)) | ||
| 1576 | continue; | ||
| 1577 | get_bh(bh2); | ||
| 1578 | page_cache_get(clone_page); /* for each bh */ | ||
| 1579 | memcpy(bh2->b_data, kaddr + bh_offset(bh), bh2->b_size); | ||
| 1580 | bh2->b_blocknr = bh->b_blocknr; | ||
| 1581 | list_replace(&bh->b_assoc_buffers, &bh2->b_assoc_buffers); | ||
| 1582 | list_add_tail(&bh->b_assoc_buffers, out); | ||
| 1583 | } while (bh = bh->b_this_page, bh2 = bh2->b_this_page, bh != head); | ||
| 1584 | kunmap_atomic(kaddr, KM_USER0); | ||
| 1585 | |||
| 1586 | if (!TestSetPageWriteback(clone_page)) | ||
| 1587 | account_page_writeback(clone_page); | ||
| 1588 | unlock_page(clone_page); | ||
| 1589 | |||
| 1590 | return 0; | ||
| 1591 | } | ||
| 1592 | |||
| 1593 | static int nilfs_test_page_to_be_frozen(struct page *page) | ||
| 1594 | { | ||
| 1595 | struct address_space *mapping = page->mapping; | ||
| 1596 | |||
| 1597 | if (!mapping || !mapping->host || S_ISDIR(mapping->host->i_mode)) | ||
| 1598 | return 0; | ||
| 1599 | |||
| 1600 | if (page_mapped(page)) { | ||
| 1601 | ClearPageChecked(page); | ||
| 1602 | return 1; | ||
| 1603 | } | ||
| 1604 | return PageChecked(page); | ||
| 1605 | } | ||
| 1606 | |||
| 1607 | static int nilfs_begin_page_io(struct page *page, struct list_head *out) | ||
| 1608 | { | 1557 | { |
| 1609 | if (!page || PageWriteback(page)) | 1558 | if (!page || PageWriteback(page)) |
| 1610 | /* For split b-tree node pages, this function may be called | 1559 | /* For split b-tree node pages, this function may be called |
| 1611 | twice. We ignore the 2nd or later calls by this check. */ | 1560 | twice. We ignore the 2nd or later calls by this check. */ |
| 1612 | return 0; | 1561 | return; |
| 1613 | 1562 | ||
| 1614 | lock_page(page); | 1563 | lock_page(page); |
| 1615 | clear_page_dirty_for_io(page); | 1564 | clear_page_dirty_for_io(page); |
| 1616 | set_page_writeback(page); | 1565 | set_page_writeback(page); |
| 1617 | unlock_page(page); | 1566 | unlock_page(page); |
| 1618 | |||
| 1619 | if (nilfs_test_page_to_be_frozen(page)) { | ||
| 1620 | int err = nilfs_copy_replace_page_buffers(page, out); | ||
| 1621 | if (unlikely(err)) | ||
| 1622 | return err; | ||
| 1623 | } | ||
| 1624 | return 0; | ||
| 1625 | } | 1567 | } |
| 1626 | 1568 | ||
| 1627 | static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci, | 1569 | static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci) |
| 1628 | struct page **failed_page) | ||
| 1629 | { | 1570 | { |
| 1630 | struct nilfs_segment_buffer *segbuf; | 1571 | struct nilfs_segment_buffer *segbuf; |
| 1631 | struct page *bd_page = NULL, *fs_page = NULL; | 1572 | struct page *bd_page = NULL, *fs_page = NULL; |
| 1632 | struct list_head *list = &sci->sc_copied_buffers; | ||
| 1633 | int err; | ||
| 1634 | 1573 | ||
| 1635 | *failed_page = NULL; | ||
| 1636 | list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { | 1574 | list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { |
| 1637 | struct buffer_head *bh; | 1575 | struct buffer_head *bh; |
| 1638 | 1576 | ||
| @@ -1662,11 +1600,7 @@ static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci, | |||
| 1662 | break; | 1600 | break; |
| 1663 | } | 1601 | } |
| 1664 | if (bh->b_page != fs_page) { | 1602 | if (bh->b_page != fs_page) { |
| 1665 | err = nilfs_begin_page_io(fs_page, list); | 1603 | nilfs_begin_page_io(fs_page); |
| 1666 | if (unlikely(err)) { | ||
| 1667 | *failed_page = fs_page; | ||
| 1668 | goto out; | ||
| 1669 | } | ||
| 1670 | fs_page = bh->b_page; | 1604 | fs_page = bh->b_page; |
| 1671 | } | 1605 | } |
| 1672 | } | 1606 | } |
| @@ -1677,11 +1611,7 @@ static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci, | |||
| 1677 | set_page_writeback(bd_page); | 1611 | set_page_writeback(bd_page); |
| 1678 | unlock_page(bd_page); | 1612 | unlock_page(bd_page); |
| 1679 | } | 1613 | } |
| 1680 | err = nilfs_begin_page_io(fs_page, list); | 1614 | nilfs_begin_page_io(fs_page); |
| 1681 | if (unlikely(err)) | ||
| 1682 | *failed_page = fs_page; | ||
| 1683 | out: | ||
| 1684 | return err; | ||
| 1685 | } | 1615 | } |
| 1686 | 1616 | ||
| 1687 | static int nilfs_segctor_write(struct nilfs_sc_info *sci, | 1617 | static int nilfs_segctor_write(struct nilfs_sc_info *sci, |
| @@ -1694,24 +1624,6 @@ static int nilfs_segctor_write(struct nilfs_sc_info *sci, | |||
| 1694 | return ret; | 1624 | return ret; |
| 1695 | } | 1625 | } |
| 1696 | 1626 | ||
| 1697 | static void __nilfs_end_page_io(struct page *page, int err) | ||
| 1698 | { | ||
| 1699 | if (!err) { | ||
| 1700 | if (!nilfs_page_buffers_clean(page)) | ||
| 1701 | __set_page_dirty_nobuffers(page); | ||
| 1702 | ClearPageError(page); | ||
| 1703 | } else { | ||
| 1704 | __set_page_dirty_nobuffers(page); | ||
| 1705 | SetPageError(page); | ||
| 1706 | } | ||
| 1707 | |||
| 1708 | if (buffer_nilfs_allocated(page_buffers(page))) { | ||
| 1709 | if (TestClearPageWriteback(page)) | ||
| 1710 | dec_zone_page_state(page, NR_WRITEBACK); | ||
| 1711 | } else | ||
| 1712 | end_page_writeback(page); | ||
| 1713 | } | ||
| 1714 | |||
| 1715 | static void nilfs_end_page_io(struct page *page, int err) | 1627 | static void nilfs_end_page_io(struct page *page, int err) |
| 1716 | { | 1628 | { |
| 1717 | if (!page) | 1629 | if (!page) |
| @@ -1738,40 +1650,19 @@ static void nilfs_end_page_io(struct page *page, int err) | |||
| 1738 | return; | 1650 | return; |
| 1739 | } | 1651 | } |
| 1740 | 1652 | ||
| 1741 | __nilfs_end_page_io(page, err); | 1653 | if (!err) { |
| 1742 | } | 1654 | if (!nilfs_page_buffers_clean(page)) |
| 1743 | 1655 | __set_page_dirty_nobuffers(page); | |
| 1744 | static void nilfs_clear_copied_buffers(struct list_head *list, int err) | 1656 | ClearPageError(page); |
| 1745 | { | 1657 | } else { |
| 1746 | struct buffer_head *bh, *head; | 1658 | __set_page_dirty_nobuffers(page); |
| 1747 | struct page *page; | 1659 | SetPageError(page); |
| 1748 | |||
| 1749 | while (!list_empty(list)) { | ||
| 1750 | bh = list_entry(list->next, struct buffer_head, | ||
| 1751 | b_assoc_buffers); | ||
| 1752 | page = bh->b_page; | ||
| 1753 | page_cache_get(page); | ||
| 1754 | head = bh = page_buffers(page); | ||
| 1755 | do { | ||
| 1756 | if (!list_empty(&bh->b_assoc_buffers)) { | ||
| 1757 | list_del_init(&bh->b_assoc_buffers); | ||
| 1758 | if (!err) { | ||
| 1759 | set_buffer_uptodate(bh); | ||
| 1760 | clear_buffer_dirty(bh); | ||
| 1761 | clear_buffer_delay(bh); | ||
| 1762 | clear_buffer_nilfs_volatile(bh); | ||
| 1763 | } | ||
| 1764 | brelse(bh); /* for b_assoc_buffers */ | ||
| 1765 | } | ||
| 1766 | } while ((bh = bh->b_this_page) != head); | ||
| 1767 | |||
| 1768 | __nilfs_end_page_io(page, err); | ||
| 1769 | page_cache_release(page); | ||
| 1770 | } | 1660 | } |
| 1661 | |||
| 1662 | end_page_writeback(page); | ||
| 1771 | } | 1663 | } |
| 1772 | 1664 | ||
| 1773 | static void nilfs_abort_logs(struct list_head *logs, struct page *failed_page, | 1665 | static void nilfs_abort_logs(struct list_head *logs, int err) |
| 1774 | int err) | ||
| 1775 | { | 1666 | { |
| 1776 | struct nilfs_segment_buffer *segbuf; | 1667 | struct nilfs_segment_buffer *segbuf; |
| 1777 | struct page *bd_page = NULL, *fs_page = NULL; | 1668 | struct page *bd_page = NULL, *fs_page = NULL; |
| @@ -1801,8 +1692,6 @@ static void nilfs_abort_logs(struct list_head *logs, struct page *failed_page, | |||
| 1801 | } | 1692 | } |
| 1802 | if (bh->b_page != fs_page) { | 1693 | if (bh->b_page != fs_page) { |
| 1803 | nilfs_end_page_io(fs_page, err); | 1694 | nilfs_end_page_io(fs_page, err); |
| 1804 | if (fs_page && fs_page == failed_page) | ||
| 1805 | return; | ||
| 1806 | fs_page = bh->b_page; | 1695 | fs_page = bh->b_page; |
| 1807 | } | 1696 | } |
| 1808 | } | 1697 | } |
| @@ -1821,12 +1710,11 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci, | |||
| 1821 | 1710 | ||
| 1822 | list_splice_tail_init(&sci->sc_write_logs, &logs); | 1711 | list_splice_tail_init(&sci->sc_write_logs, &logs); |
| 1823 | ret = nilfs_wait_on_logs(&logs); | 1712 | ret = nilfs_wait_on_logs(&logs); |
| 1824 | nilfs_abort_logs(&logs, NULL, ret ? : err); | 1713 | nilfs_abort_logs(&logs, ret ? : err); |
| 1825 | 1714 | ||
| 1826 | list_splice_tail_init(&sci->sc_segbufs, &logs); | 1715 | list_splice_tail_init(&sci->sc_segbufs, &logs); |
| 1827 | nilfs_cancel_segusage(&logs, nilfs->ns_sufile); | 1716 | nilfs_cancel_segusage(&logs, nilfs->ns_sufile); |
| 1828 | nilfs_free_incomplete_logs(&logs, nilfs); | 1717 | nilfs_free_incomplete_logs(&logs, nilfs); |
| 1829 | nilfs_clear_copied_buffers(&sci->sc_copied_buffers, err); | ||
| 1830 | 1718 | ||
| 1831 | if (sci->sc_stage.flags & NILFS_CF_SUFREED) { | 1719 | if (sci->sc_stage.flags & NILFS_CF_SUFREED) { |
| 1832 | ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile, | 1720 | ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile, |
| @@ -1920,8 +1808,6 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) | |||
| 1920 | 1808 | ||
| 1921 | nilfs_end_page_io(fs_page, 0); | 1809 | nilfs_end_page_io(fs_page, 0); |
| 1922 | 1810 | ||
| 1923 | nilfs_clear_copied_buffers(&sci->sc_copied_buffers, 0); | ||
| 1924 | |||
| 1925 | nilfs_drop_collected_inodes(&sci->sc_dirty_files); | 1811 | nilfs_drop_collected_inodes(&sci->sc_dirty_files); |
| 1926 | 1812 | ||
| 1927 | if (nilfs_doing_gc()) | 1813 | if (nilfs_doing_gc()) |
| @@ -1979,7 +1865,7 @@ static int nilfs_segctor_collect_dirty_files(struct nilfs_sc_info *sci, | |||
| 1979 | "failed to get inode block.\n"); | 1865 | "failed to get inode block.\n"); |
| 1980 | return err; | 1866 | return err; |
| 1981 | } | 1867 | } |
| 1982 | nilfs_mdt_mark_buffer_dirty(ibh); | 1868 | mark_buffer_dirty(ibh); |
| 1983 | nilfs_mdt_mark_dirty(ifile); | 1869 | nilfs_mdt_mark_dirty(ifile); |
| 1984 | spin_lock(&nilfs->ns_inode_lock); | 1870 | spin_lock(&nilfs->ns_inode_lock); |
| 1985 | if (likely(!ii->i_bh)) | 1871 | if (likely(!ii->i_bh)) |
| @@ -1991,8 +1877,7 @@ static int nilfs_segctor_collect_dirty_files(struct nilfs_sc_info *sci, | |||
| 1991 | 1877 | ||
| 1992 | clear_bit(NILFS_I_QUEUED, &ii->i_state); | 1878 | clear_bit(NILFS_I_QUEUED, &ii->i_state); |
| 1993 | set_bit(NILFS_I_BUSY, &ii->i_state); | 1879 | set_bit(NILFS_I_BUSY, &ii->i_state); |
| 1994 | list_del(&ii->i_dirty); | 1880 | list_move_tail(&ii->i_dirty, &sci->sc_dirty_files); |
| 1995 | list_add_tail(&ii->i_dirty, &sci->sc_dirty_files); | ||
| 1996 | } | 1881 | } |
| 1997 | spin_unlock(&nilfs->ns_inode_lock); | 1882 | spin_unlock(&nilfs->ns_inode_lock); |
| 1998 | 1883 | ||
| @@ -2014,8 +1899,7 @@ static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci, | |||
| 2014 | clear_bit(NILFS_I_BUSY, &ii->i_state); | 1899 | clear_bit(NILFS_I_BUSY, &ii->i_state); |
| 2015 | brelse(ii->i_bh); | 1900 | brelse(ii->i_bh); |
| 2016 | ii->i_bh = NULL; | 1901 | ii->i_bh = NULL; |
| 2017 | list_del(&ii->i_dirty); | 1902 | list_move_tail(&ii->i_dirty, &ti->ti_garbage); |
| 2018 | list_add_tail(&ii->i_dirty, &ti->ti_garbage); | ||
| 2019 | } | 1903 | } |
| 2020 | spin_unlock(&nilfs->ns_inode_lock); | 1904 | spin_unlock(&nilfs->ns_inode_lock); |
| 2021 | } | 1905 | } |
| @@ -2026,7 +1910,6 @@ static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci, | |||
| 2026 | static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | 1910 | static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) |
| 2027 | { | 1911 | { |
| 2028 | struct the_nilfs *nilfs = sci->sc_super->s_fs_info; | 1912 | struct the_nilfs *nilfs = sci->sc_super->s_fs_info; |
| 2029 | struct page *failed_page; | ||
| 2030 | int err; | 1913 | int err; |
| 2031 | 1914 | ||
| 2032 | sci->sc_stage.scnt = NILFS_ST_INIT; | 1915 | sci->sc_stage.scnt = NILFS_ST_INIT; |
| @@ -2081,11 +1964,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | |||
| 2081 | nilfs_segctor_update_segusage(sci, nilfs->ns_sufile); | 1964 | nilfs_segctor_update_segusage(sci, nilfs->ns_sufile); |
| 2082 | 1965 | ||
| 2083 | /* Write partial segments */ | 1966 | /* Write partial segments */ |
| 2084 | err = nilfs_segctor_prepare_write(sci, &failed_page); | 1967 | nilfs_segctor_prepare_write(sci); |
| 2085 | if (err) { | ||
| 2086 | nilfs_abort_logs(&sci->sc_segbufs, failed_page, err); | ||
| 2087 | goto failed_to_write; | ||
| 2088 | } | ||
| 2089 | 1968 | ||
| 2090 | nilfs_add_checksums_on_logs(&sci->sc_segbufs, | 1969 | nilfs_add_checksums_on_logs(&sci->sc_segbufs, |
| 2091 | nilfs->ns_crc_seed); | 1970 | nilfs->ns_crc_seed); |
| @@ -2687,7 +2566,6 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb, | |||
| 2687 | INIT_LIST_HEAD(&sci->sc_segbufs); | 2566 | INIT_LIST_HEAD(&sci->sc_segbufs); |
| 2688 | INIT_LIST_HEAD(&sci->sc_write_logs); | 2567 | INIT_LIST_HEAD(&sci->sc_write_logs); |
| 2689 | INIT_LIST_HEAD(&sci->sc_gc_inodes); | 2568 | INIT_LIST_HEAD(&sci->sc_gc_inodes); |
| 2690 | INIT_LIST_HEAD(&sci->sc_copied_buffers); | ||
| 2691 | init_timer(&sci->sc_timer); | 2569 | init_timer(&sci->sc_timer); |
| 2692 | 2570 | ||
| 2693 | sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT; | 2571 | sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT; |
| @@ -2741,8 +2619,6 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
| 2741 | if (flag || !nilfs_segctor_confirm(sci)) | 2619 | if (flag || !nilfs_segctor_confirm(sci)) |
| 2742 | nilfs_segctor_write_out(sci); | 2620 | nilfs_segctor_write_out(sci); |
| 2743 | 2621 | ||
| 2744 | WARN_ON(!list_empty(&sci->sc_copied_buffers)); | ||
| 2745 | |||
| 2746 | if (!list_empty(&sci->sc_dirty_files)) { | 2622 | if (!list_empty(&sci->sc_dirty_files)) { |
| 2747 | nilfs_warning(sci->sc_super, __func__, | 2623 | nilfs_warning(sci->sc_super, __func__, |
| 2748 | "dirty file(s) after the final construction\n"); | 2624 | "dirty file(s) after the final construction\n"); |
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h index 6c02a86745fb..38a1d0013314 100644 --- a/fs/nilfs2/segment.h +++ b/fs/nilfs2/segment.h | |||
| @@ -92,7 +92,6 @@ struct nilfs_segsum_pointer { | |||
| 92 | * @sc_nblk_inc: Block count of current generation | 92 | * @sc_nblk_inc: Block count of current generation |
| 93 | * @sc_dirty_files: List of files to be written | 93 | * @sc_dirty_files: List of files to be written |
| 94 | * @sc_gc_inodes: List of GC inodes having blocks to be written | 94 | * @sc_gc_inodes: List of GC inodes having blocks to be written |
| 95 | * @sc_copied_buffers: List of copied buffers (buffer heads) to freeze data | ||
| 96 | * @sc_freesegs: array of segment numbers to be freed | 95 | * @sc_freesegs: array of segment numbers to be freed |
| 97 | * @sc_nfreesegs: number of segments on @sc_freesegs | 96 | * @sc_nfreesegs: number of segments on @sc_freesegs |
| 98 | * @sc_dsync_inode: inode whose data pages are written for a sync operation | 97 | * @sc_dsync_inode: inode whose data pages are written for a sync operation |
| @@ -136,7 +135,6 @@ struct nilfs_sc_info { | |||
| 136 | 135 | ||
| 137 | struct list_head sc_dirty_files; | 136 | struct list_head sc_dirty_files; |
| 138 | struct list_head sc_gc_inodes; | 137 | struct list_head sc_gc_inodes; |
| 139 | struct list_head sc_copied_buffers; | ||
| 140 | 138 | ||
| 141 | __u64 *sc_freesegs; | 139 | __u64 *sc_freesegs; |
| 142 | size_t sc_nfreesegs; | 140 | size_t sc_nfreesegs; |
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c index 1d6f488ccae8..0a0aba617d8a 100644 --- a/fs/nilfs2/sufile.c +++ b/fs/nilfs2/sufile.c | |||
| @@ -33,7 +33,9 @@ | |||
| 33 | 33 | ||
| 34 | struct nilfs_sufile_info { | 34 | struct nilfs_sufile_info { |
| 35 | struct nilfs_mdt_info mi; | 35 | struct nilfs_mdt_info mi; |
| 36 | unsigned long ncleansegs; | 36 | unsigned long ncleansegs;/* number of clean segments */ |
| 37 | __u64 allocmin; /* lower limit of allocatable segment range */ | ||
| 38 | __u64 allocmax; /* upper limit of allocatable segment range */ | ||
| 37 | }; | 39 | }; |
| 38 | 40 | ||
| 39 | static inline struct nilfs_sufile_info *NILFS_SUI(struct inode *sufile) | 41 | static inline struct nilfs_sufile_info *NILFS_SUI(struct inode *sufile) |
| @@ -96,6 +98,13 @@ nilfs_sufile_get_segment_usage_block(struct inode *sufile, __u64 segnum, | |||
| 96 | create, NULL, bhp); | 98 | create, NULL, bhp); |
| 97 | } | 99 | } |
| 98 | 100 | ||
| 101 | static int nilfs_sufile_delete_segment_usage_block(struct inode *sufile, | ||
| 102 | __u64 segnum) | ||
| 103 | { | ||
| 104 | return nilfs_mdt_delete_block(sufile, | ||
| 105 | nilfs_sufile_get_blkoff(sufile, segnum)); | ||
| 106 | } | ||
| 107 | |||
| 99 | static void nilfs_sufile_mod_counter(struct buffer_head *header_bh, | 108 | static void nilfs_sufile_mod_counter(struct buffer_head *header_bh, |
| 100 | u64 ncleanadd, u64 ndirtyadd) | 109 | u64 ncleanadd, u64 ndirtyadd) |
| 101 | { | 110 | { |
| @@ -108,7 +117,7 @@ static void nilfs_sufile_mod_counter(struct buffer_head *header_bh, | |||
| 108 | le64_add_cpu(&header->sh_ndirtysegs, ndirtyadd); | 117 | le64_add_cpu(&header->sh_ndirtysegs, ndirtyadd); |
| 109 | kunmap_atomic(kaddr, KM_USER0); | 118 | kunmap_atomic(kaddr, KM_USER0); |
| 110 | 119 | ||
| 111 | nilfs_mdt_mark_buffer_dirty(header_bh); | 120 | mark_buffer_dirty(header_bh); |
| 112 | } | 121 | } |
| 113 | 122 | ||
| 114 | /** | 123 | /** |
| @@ -248,6 +257,35 @@ int nilfs_sufile_update(struct inode *sufile, __u64 segnum, int create, | |||
| 248 | } | 257 | } |
| 249 | 258 | ||
| 250 | /** | 259 | /** |
| 260 | * nilfs_sufile_set_alloc_range - limit range of segment to be allocated | ||
| 261 | * @sufile: inode of segment usage file | ||
| 262 | * @start: minimum segment number of allocatable region (inclusive) | ||
| 263 | * @end: maximum segment number of allocatable region (inclusive) | ||
| 264 | * | ||
| 265 | * Return Value: On success, 0 is returned. On error, one of the | ||
| 266 | * following negative error codes is returned. | ||
| 267 | * | ||
| 268 | * %-ERANGE - invalid segment region | ||
| 269 | */ | ||
| 270 | int nilfs_sufile_set_alloc_range(struct inode *sufile, __u64 start, __u64 end) | ||
| 271 | { | ||
| 272 | struct nilfs_sufile_info *sui = NILFS_SUI(sufile); | ||
| 273 | __u64 nsegs; | ||
| 274 | int ret = -ERANGE; | ||
| 275 | |||
| 276 | down_write(&NILFS_MDT(sufile)->mi_sem); | ||
| 277 | nsegs = nilfs_sufile_get_nsegments(sufile); | ||
| 278 | |||
| 279 | if (start <= end && end < nsegs) { | ||
| 280 | sui->allocmin = start; | ||
| 281 | sui->allocmax = end; | ||
| 282 | ret = 0; | ||
| 283 | } | ||
| 284 | up_write(&NILFS_MDT(sufile)->mi_sem); | ||
| 285 | return ret; | ||
| 286 | } | ||
| 287 | |||
| 288 | /** | ||
| 251 | * nilfs_sufile_alloc - allocate a segment | 289 | * nilfs_sufile_alloc - allocate a segment |
| 252 | * @sufile: inode of segment usage file | 290 | * @sufile: inode of segment usage file |
| 253 | * @segnump: pointer to segment number | 291 | * @segnump: pointer to segment number |
| @@ -269,11 +307,12 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump) | |||
| 269 | struct buffer_head *header_bh, *su_bh; | 307 | struct buffer_head *header_bh, *su_bh; |
| 270 | struct nilfs_sufile_header *header; | 308 | struct nilfs_sufile_header *header; |
| 271 | struct nilfs_segment_usage *su; | 309 | struct nilfs_segment_usage *su; |
| 310 | struct nilfs_sufile_info *sui = NILFS_SUI(sufile); | ||
| 272 | size_t susz = NILFS_MDT(sufile)->mi_entry_size; | 311 | size_t susz = NILFS_MDT(sufile)->mi_entry_size; |
| 273 | __u64 segnum, maxsegnum, last_alloc; | 312 | __u64 segnum, maxsegnum, last_alloc; |
| 274 | void *kaddr; | 313 | void *kaddr; |
| 275 | unsigned long nsegments, ncleansegs, nsus; | 314 | unsigned long nsegments, ncleansegs, nsus, cnt; |
| 276 | int ret, i, j; | 315 | int ret, j; |
| 277 | 316 | ||
| 278 | down_write(&NILFS_MDT(sufile)->mi_sem); | 317 | down_write(&NILFS_MDT(sufile)->mi_sem); |
| 279 | 318 | ||
| @@ -287,13 +326,31 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump) | |||
| 287 | kunmap_atomic(kaddr, KM_USER0); | 326 | kunmap_atomic(kaddr, KM_USER0); |
| 288 | 327 | ||
| 289 | nsegments = nilfs_sufile_get_nsegments(sufile); | 328 | nsegments = nilfs_sufile_get_nsegments(sufile); |
| 329 | maxsegnum = sui->allocmax; | ||
| 290 | segnum = last_alloc + 1; | 330 | segnum = last_alloc + 1; |
| 291 | maxsegnum = nsegments - 1; | 331 | if (segnum < sui->allocmin || segnum > sui->allocmax) |
| 292 | for (i = 0; i < nsegments; i += nsus) { | 332 | segnum = sui->allocmin; |
| 293 | if (segnum >= nsegments) { | 333 | |
| 294 | /* wrap around */ | 334 | for (cnt = 0; cnt < nsegments; cnt += nsus) { |
| 295 | segnum = 0; | 335 | if (segnum > maxsegnum) { |
| 296 | maxsegnum = last_alloc; | 336 | if (cnt < sui->allocmax - sui->allocmin + 1) { |
| 337 | /* | ||
| 338 | * wrap around in the limited region. | ||
| 339 | * if allocation started from | ||
| 340 | * sui->allocmin, this never happens. | ||
| 341 | */ | ||
| 342 | segnum = sui->allocmin; | ||
| 343 | maxsegnum = last_alloc; | ||
| 344 | } else if (segnum > sui->allocmin && | ||
| 345 | sui->allocmax + 1 < nsegments) { | ||
| 346 | segnum = sui->allocmax + 1; | ||
| 347 | maxsegnum = nsegments - 1; | ||
| 348 | } else if (sui->allocmin > 0) { | ||
| 349 | segnum = 0; | ||
| 350 | maxsegnum = sui->allocmin - 1; | ||
| 351 | } else { | ||
| 352 | break; /* never happens */ | ||
| 353 | } | ||
| 297 | } | 354 | } |
| 298 | ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 1, | 355 | ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 1, |
| 299 | &su_bh); | 356 | &su_bh); |
| @@ -319,9 +376,9 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump) | |||
| 319 | header->sh_last_alloc = cpu_to_le64(segnum); | 376 | header->sh_last_alloc = cpu_to_le64(segnum); |
| 320 | kunmap_atomic(kaddr, KM_USER0); | 377 | kunmap_atomic(kaddr, KM_USER0); |
| 321 | 378 | ||
| 322 | NILFS_SUI(sufile)->ncleansegs--; | 379 | sui->ncleansegs--; |
| 323 | nilfs_mdt_mark_buffer_dirty(header_bh); | 380 | mark_buffer_dirty(header_bh); |
| 324 | nilfs_mdt_mark_buffer_dirty(su_bh); | 381 | mark_buffer_dirty(su_bh); |
| 325 | nilfs_mdt_mark_dirty(sufile); | 382 | nilfs_mdt_mark_dirty(sufile); |
| 326 | brelse(su_bh); | 383 | brelse(su_bh); |
| 327 | *segnump = segnum; | 384 | *segnump = segnum; |
| @@ -364,7 +421,7 @@ void nilfs_sufile_do_cancel_free(struct inode *sufile, __u64 segnum, | |||
| 364 | nilfs_sufile_mod_counter(header_bh, -1, 1); | 421 | nilfs_sufile_mod_counter(header_bh, -1, 1); |
| 365 | NILFS_SUI(sufile)->ncleansegs--; | 422 | NILFS_SUI(sufile)->ncleansegs--; |
| 366 | 423 | ||
| 367 | nilfs_mdt_mark_buffer_dirty(su_bh); | 424 | mark_buffer_dirty(su_bh); |
| 368 | nilfs_mdt_mark_dirty(sufile); | 425 | nilfs_mdt_mark_dirty(sufile); |
| 369 | } | 426 | } |
| 370 | 427 | ||
| @@ -395,7 +452,7 @@ void nilfs_sufile_do_scrap(struct inode *sufile, __u64 segnum, | |||
| 395 | nilfs_sufile_mod_counter(header_bh, clean ? (u64)-1 : 0, dirty ? 0 : 1); | 452 | nilfs_sufile_mod_counter(header_bh, clean ? (u64)-1 : 0, dirty ? 0 : 1); |
| 396 | NILFS_SUI(sufile)->ncleansegs -= clean; | 453 | NILFS_SUI(sufile)->ncleansegs -= clean; |
| 397 | 454 | ||
| 398 | nilfs_mdt_mark_buffer_dirty(su_bh); | 455 | mark_buffer_dirty(su_bh); |
| 399 | nilfs_mdt_mark_dirty(sufile); | 456 | nilfs_mdt_mark_dirty(sufile); |
| 400 | } | 457 | } |
| 401 | 458 | ||
| @@ -421,7 +478,7 @@ void nilfs_sufile_do_free(struct inode *sufile, __u64 segnum, | |||
| 421 | sudirty = nilfs_segment_usage_dirty(su); | 478 | sudirty = nilfs_segment_usage_dirty(su); |
| 422 | nilfs_segment_usage_set_clean(su); | 479 | nilfs_segment_usage_set_clean(su); |
| 423 | kunmap_atomic(kaddr, KM_USER0); | 480 | kunmap_atomic(kaddr, KM_USER0); |
| 424 | nilfs_mdt_mark_buffer_dirty(su_bh); | 481 | mark_buffer_dirty(su_bh); |
| 425 | 482 | ||
| 426 | nilfs_sufile_mod_counter(header_bh, 1, sudirty ? (u64)-1 : 0); | 483 | nilfs_sufile_mod_counter(header_bh, 1, sudirty ? (u64)-1 : 0); |
| 427 | NILFS_SUI(sufile)->ncleansegs++; | 484 | NILFS_SUI(sufile)->ncleansegs++; |
| @@ -441,7 +498,7 @@ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum) | |||
| 441 | 498 | ||
| 442 | ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh); | 499 | ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh); |
| 443 | if (!ret) { | 500 | if (!ret) { |
| 444 | nilfs_mdt_mark_buffer_dirty(bh); | 501 | mark_buffer_dirty(bh); |
| 445 | nilfs_mdt_mark_dirty(sufile); | 502 | nilfs_mdt_mark_dirty(sufile); |
| 446 | brelse(bh); | 503 | brelse(bh); |
| 447 | } | 504 | } |
| @@ -476,7 +533,7 @@ int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum, | |||
| 476 | su->su_nblocks = cpu_to_le32(nblocks); | 533 | su->su_nblocks = cpu_to_le32(nblocks); |
| 477 | kunmap_atomic(kaddr, KM_USER0); | 534 | kunmap_atomic(kaddr, KM_USER0); |
| 478 | 535 | ||
| 479 | nilfs_mdt_mark_buffer_dirty(bh); | 536 | mark_buffer_dirty(bh); |
| 480 | nilfs_mdt_mark_dirty(sufile); | 537 | nilfs_mdt_mark_dirty(sufile); |
| 481 | brelse(bh); | 538 | brelse(bh); |
| 482 | 539 | ||
| @@ -505,7 +562,7 @@ int nilfs_sufile_get_stat(struct inode *sufile, struct nilfs_sustat *sustat) | |||
| 505 | { | 562 | { |
| 506 | struct buffer_head *header_bh; | 563 | struct buffer_head *header_bh; |
| 507 | struct nilfs_sufile_header *header; | 564 | struct nilfs_sufile_header *header; |
| 508 | struct the_nilfs *nilfs = NILFS_I_NILFS(sufile); | 565 | struct the_nilfs *nilfs = sufile->i_sb->s_fs_info; |
| 509 | void *kaddr; | 566 | void *kaddr; |
| 510 | int ret; | 567 | int ret; |
| 511 | 568 | ||
| @@ -555,11 +612,183 @@ void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum, | |||
| 555 | nilfs_sufile_mod_counter(header_bh, -1, 0); | 612 | nilfs_sufile_mod_counter(header_bh, -1, 0); |
| 556 | NILFS_SUI(sufile)->ncleansegs--; | 613 | NILFS_SUI(sufile)->ncleansegs--; |
| 557 | } | 614 | } |
| 558 | nilfs_mdt_mark_buffer_dirty(su_bh); | 615 | mark_buffer_dirty(su_bh); |
| 559 | nilfs_mdt_mark_dirty(sufile); | 616 | nilfs_mdt_mark_dirty(sufile); |
| 560 | } | 617 | } |
| 561 | 618 | ||
| 562 | /** | 619 | /** |
| 620 | * nilfs_sufile_truncate_range - truncate range of segment array | ||
| 621 | * @sufile: inode of segment usage file | ||
| 622 | * @start: start segment number (inclusive) | ||
| 623 | * @end: end segment number (inclusive) | ||
| 624 | * | ||
| 625 | * Return Value: On success, 0 is returned. On error, one of the | ||
| 626 | * following negative error codes is returned. | ||
| 627 | * | ||
| 628 | * %-EIO - I/O error. | ||
| 629 | * | ||
| 630 | * %-ENOMEM - Insufficient amount of memory available. | ||
| 631 | * | ||
| 632 | * %-EINVAL - Invalid number of segments specified | ||
| 633 | * | ||
| 634 | * %-EBUSY - Dirty or active segments are present in the range | ||
| 635 | */ | ||
| 636 | static int nilfs_sufile_truncate_range(struct inode *sufile, | ||
| 637 | __u64 start, __u64 end) | ||
| 638 | { | ||
| 639 | struct the_nilfs *nilfs = sufile->i_sb->s_fs_info; | ||
| 640 | struct buffer_head *header_bh; | ||
| 641 | struct buffer_head *su_bh; | ||
| 642 | struct nilfs_segment_usage *su, *su2; | ||
| 643 | size_t susz = NILFS_MDT(sufile)->mi_entry_size; | ||
| 644 | unsigned long segusages_per_block; | ||
| 645 | unsigned long nsegs, ncleaned; | ||
| 646 | __u64 segnum; | ||
| 647 | void *kaddr; | ||
| 648 | ssize_t n, nc; | ||
| 649 | int ret; | ||
| 650 | int j; | ||
| 651 | |||
| 652 | nsegs = nilfs_sufile_get_nsegments(sufile); | ||
| 653 | |||
| 654 | ret = -EINVAL; | ||
| 655 | if (start > end || start >= nsegs) | ||
| 656 | goto out; | ||
| 657 | |||
| 658 | ret = nilfs_sufile_get_header_block(sufile, &header_bh); | ||
| 659 | if (ret < 0) | ||
| 660 | goto out; | ||
| 661 | |||
| 662 | segusages_per_block = nilfs_sufile_segment_usages_per_block(sufile); | ||
| 663 | ncleaned = 0; | ||
| 664 | |||
| 665 | for (segnum = start; segnum <= end; segnum += n) { | ||
| 666 | n = min_t(unsigned long, | ||
| 667 | segusages_per_block - | ||
| 668 | nilfs_sufile_get_offset(sufile, segnum), | ||
| 669 | end - segnum + 1); | ||
| 670 | ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, | ||
| 671 | &su_bh); | ||
| 672 | if (ret < 0) { | ||
| 673 | if (ret != -ENOENT) | ||
| 674 | goto out_header; | ||
| 675 | /* hole */ | ||
| 676 | continue; | ||
| 677 | } | ||
| 678 | kaddr = kmap_atomic(su_bh->b_page, KM_USER0); | ||
| 679 | su = nilfs_sufile_block_get_segment_usage( | ||
| 680 | sufile, segnum, su_bh, kaddr); | ||
| 681 | su2 = su; | ||
| 682 | for (j = 0; j < n; j++, su = (void *)su + susz) { | ||
| 683 | if ((le32_to_cpu(su->su_flags) & | ||
| 684 | ~(1UL << NILFS_SEGMENT_USAGE_ERROR)) || | ||
| 685 | nilfs_segment_is_active(nilfs, segnum + j)) { | ||
| 686 | ret = -EBUSY; | ||
| 687 | kunmap_atomic(kaddr, KM_USER0); | ||
| 688 | brelse(su_bh); | ||
| 689 | goto out_header; | ||
| 690 | } | ||
| 691 | } | ||
| 692 | nc = 0; | ||
| 693 | for (su = su2, j = 0; j < n; j++, su = (void *)su + susz) { | ||
| 694 | if (nilfs_segment_usage_error(su)) { | ||
| 695 | nilfs_segment_usage_set_clean(su); | ||
| 696 | nc++; | ||
| 697 | } | ||
| 698 | } | ||
| 699 | kunmap_atomic(kaddr, KM_USER0); | ||
| 700 | if (nc > 0) { | ||
| 701 | mark_buffer_dirty(su_bh); | ||
| 702 | ncleaned += nc; | ||
| 703 | } | ||
| 704 | brelse(su_bh); | ||
| 705 | |||
| 706 | if (n == segusages_per_block) { | ||
| 707 | /* make hole */ | ||
| 708 | nilfs_sufile_delete_segment_usage_block(sufile, segnum); | ||
| 709 | } | ||
| 710 | } | ||
| 711 | ret = 0; | ||
| 712 | |||
| 713 | out_header: | ||
| 714 | if (ncleaned > 0) { | ||
| 715 | NILFS_SUI(sufile)->ncleansegs += ncleaned; | ||
| 716 | nilfs_sufile_mod_counter(header_bh, ncleaned, 0); | ||
| 717 | nilfs_mdt_mark_dirty(sufile); | ||
| 718 | } | ||
| 719 | brelse(header_bh); | ||
| 720 | out: | ||
| 721 | return ret; | ||
| 722 | } | ||
| 723 | |||
| 724 | /** | ||
| 725 | * nilfs_sufile_resize - resize segment array | ||
| 726 | * @sufile: inode of segment usage file | ||
| 727 | * @newnsegs: new number of segments | ||
| 728 | * | ||
| 729 | * Return Value: On success, 0 is returned. On error, one of the | ||
| 730 | * following negative error codes is returned. | ||
| 731 | * | ||
| 732 | * %-EIO - I/O error. | ||
| 733 | * | ||
| 734 | * %-ENOMEM - Insufficient amount of memory available. | ||
| 735 | * | ||
| 736 | * %-ENOSPC - Enough free space is not left for shrinking | ||
| 737 | * | ||
| 738 | * %-EBUSY - Dirty or active segments exist in the region to be truncated | ||
| 739 | */ | ||
| 740 | int nilfs_sufile_resize(struct inode *sufile, __u64 newnsegs) | ||
| 741 | { | ||
| 742 | struct the_nilfs *nilfs = sufile->i_sb->s_fs_info; | ||
| 743 | struct buffer_head *header_bh; | ||
| 744 | struct nilfs_sufile_header *header; | ||
| 745 | struct nilfs_sufile_info *sui = NILFS_SUI(sufile); | ||
| 746 | void *kaddr; | ||
| 747 | unsigned long nsegs, nrsvsegs; | ||
| 748 | int ret = 0; | ||
| 749 | |||
| 750 | down_write(&NILFS_MDT(sufile)->mi_sem); | ||
| 751 | |||
| 752 | nsegs = nilfs_sufile_get_nsegments(sufile); | ||
| 753 | if (nsegs == newnsegs) | ||
| 754 | goto out; | ||
| 755 | |||
| 756 | ret = -ENOSPC; | ||
| 757 | nrsvsegs = nilfs_nrsvsegs(nilfs, newnsegs); | ||
| 758 | if (newnsegs < nsegs && nsegs - newnsegs + nrsvsegs > sui->ncleansegs) | ||
| 759 | goto out; | ||
| 760 | |||
| 761 | ret = nilfs_sufile_get_header_block(sufile, &header_bh); | ||
| 762 | if (ret < 0) | ||
| 763 | goto out; | ||
| 764 | |||
| 765 | if (newnsegs > nsegs) { | ||
| 766 | sui->ncleansegs += newnsegs - nsegs; | ||
| 767 | } else /* newnsegs < nsegs */ { | ||
| 768 | ret = nilfs_sufile_truncate_range(sufile, newnsegs, nsegs - 1); | ||
| 769 | if (ret < 0) | ||
| 770 | goto out_header; | ||
| 771 | |||
| 772 | sui->ncleansegs -= nsegs - newnsegs; | ||
| 773 | } | ||
| 774 | |||
| 775 | kaddr = kmap_atomic(header_bh->b_page, KM_USER0); | ||
| 776 | header = kaddr + bh_offset(header_bh); | ||
| 777 | header->sh_ncleansegs = cpu_to_le64(sui->ncleansegs); | ||
| 778 | kunmap_atomic(kaddr, KM_USER0); | ||
| 779 | |||
| 780 | mark_buffer_dirty(header_bh); | ||
| 781 | nilfs_mdt_mark_dirty(sufile); | ||
| 782 | nilfs_set_nsegments(nilfs, newnsegs); | ||
| 783 | |||
| 784 | out_header: | ||
| 785 | brelse(header_bh); | ||
| 786 | out: | ||
| 787 | up_write(&NILFS_MDT(sufile)->mi_sem); | ||
| 788 | return ret; | ||
| 789 | } | ||
| 790 | |||
| 791 | /** | ||
| 563 | * nilfs_sufile_get_suinfo - | 792 | * nilfs_sufile_get_suinfo - |
| 564 | * @sufile: inode of segment usage file | 793 | * @sufile: inode of segment usage file |
| 565 | * @segnum: segment number to start looking | 794 | * @segnum: segment number to start looking |
| @@ -583,7 +812,7 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf, | |||
| 583 | struct nilfs_segment_usage *su; | 812 | struct nilfs_segment_usage *su; |
| 584 | struct nilfs_suinfo *si = buf; | 813 | struct nilfs_suinfo *si = buf; |
| 585 | size_t susz = NILFS_MDT(sufile)->mi_entry_size; | 814 | size_t susz = NILFS_MDT(sufile)->mi_entry_size; |
| 586 | struct the_nilfs *nilfs = NILFS_I_NILFS(sufile); | 815 | struct the_nilfs *nilfs = sufile->i_sb->s_fs_info; |
| 587 | void *kaddr; | 816 | void *kaddr; |
| 588 | unsigned long nsegs, segusages_per_block; | 817 | unsigned long nsegs, segusages_per_block; |
| 589 | ssize_t n; | 818 | ssize_t n; |
| @@ -679,6 +908,9 @@ int nilfs_sufile_read(struct super_block *sb, size_t susize, | |||
| 679 | kunmap_atomic(kaddr, KM_USER0); | 908 | kunmap_atomic(kaddr, KM_USER0); |
| 680 | brelse(header_bh); | 909 | brelse(header_bh); |
| 681 | 910 | ||
| 911 | sui->allocmax = nilfs_sufile_get_nsegments(sufile) - 1; | ||
| 912 | sui->allocmin = 0; | ||
| 913 | |||
| 682 | unlock_new_inode(sufile); | 914 | unlock_new_inode(sufile); |
| 683 | out: | 915 | out: |
| 684 | *inodep = sufile; | 916 | *inodep = sufile; |
diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h index a943fbacb45b..e84bc5b51fc1 100644 --- a/fs/nilfs2/sufile.h +++ b/fs/nilfs2/sufile.h | |||
| @@ -31,11 +31,12 @@ | |||
| 31 | 31 | ||
| 32 | static inline unsigned long nilfs_sufile_get_nsegments(struct inode *sufile) | 32 | static inline unsigned long nilfs_sufile_get_nsegments(struct inode *sufile) |
| 33 | { | 33 | { |
| 34 | return NILFS_I_NILFS(sufile)->ns_nsegments; | 34 | return ((struct the_nilfs *)sufile->i_sb->s_fs_info)->ns_nsegments; |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | unsigned long nilfs_sufile_get_ncleansegs(struct inode *sufile); | 37 | unsigned long nilfs_sufile_get_ncleansegs(struct inode *sufile); |
| 38 | 38 | ||
| 39 | int nilfs_sufile_set_alloc_range(struct inode *sufile, __u64 start, __u64 end); | ||
| 39 | int nilfs_sufile_alloc(struct inode *, __u64 *); | 40 | int nilfs_sufile_alloc(struct inode *, __u64 *); |
| 40 | int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum); | 41 | int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum); |
| 41 | int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum, | 42 | int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum, |
| @@ -61,6 +62,7 @@ void nilfs_sufile_do_cancel_free(struct inode *, __u64, struct buffer_head *, | |||
| 61 | void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *, | 62 | void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *, |
| 62 | struct buffer_head *); | 63 | struct buffer_head *); |
| 63 | 64 | ||
| 65 | int nilfs_sufile_resize(struct inode *sufile, __u64 newnsegs); | ||
| 64 | int nilfs_sufile_read(struct super_block *sb, size_t susize, | 66 | int nilfs_sufile_read(struct super_block *sb, size_t susize, |
| 65 | struct nilfs_inode *raw_inode, struct inode **inodep); | 67 | struct nilfs_inode *raw_inode, struct inode **inodep); |
| 66 | 68 | ||
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 062cca065195..8351c44a7320 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
| @@ -56,6 +56,7 @@ | |||
| 56 | #include "btnode.h" | 56 | #include "btnode.h" |
| 57 | #include "page.h" | 57 | #include "page.h" |
| 58 | #include "cpfile.h" | 58 | #include "cpfile.h" |
| 59 | #include "sufile.h" /* nilfs_sufile_resize(), nilfs_sufile_set_alloc_range() */ | ||
| 59 | #include "ifile.h" | 60 | #include "ifile.h" |
| 60 | #include "dat.h" | 61 | #include "dat.h" |
| 61 | #include "segment.h" | 62 | #include "segment.h" |
| @@ -165,7 +166,7 @@ struct inode *nilfs_alloc_inode(struct super_block *sb) | |||
| 165 | ii->i_state = 0; | 166 | ii->i_state = 0; |
| 166 | ii->i_cno = 0; | 167 | ii->i_cno = 0; |
| 167 | ii->vfs_inode.i_version = 1; | 168 | ii->vfs_inode.i_version = 1; |
| 168 | nilfs_btnode_cache_init(&ii->i_btnode_cache, sb->s_bdi); | 169 | nilfs_mapping_init(&ii->i_btnode_cache, &ii->vfs_inode, sb->s_bdi); |
| 169 | return &ii->vfs_inode; | 170 | return &ii->vfs_inode; |
| 170 | } | 171 | } |
| 171 | 172 | ||
| @@ -347,6 +348,134 @@ int nilfs_cleanup_super(struct super_block *sb) | |||
| 347 | return ret; | 348 | return ret; |
| 348 | } | 349 | } |
| 349 | 350 | ||
| 351 | /** | ||
| 352 | * nilfs_move_2nd_super - relocate secondary super block | ||
| 353 | * @sb: super block instance | ||
| 354 | * @sb2off: new offset of the secondary super block (in bytes) | ||
| 355 | */ | ||
| 356 | static int nilfs_move_2nd_super(struct super_block *sb, loff_t sb2off) | ||
| 357 | { | ||
| 358 | struct the_nilfs *nilfs = sb->s_fs_info; | ||
| 359 | struct buffer_head *nsbh; | ||
| 360 | struct nilfs_super_block *nsbp; | ||
| 361 | sector_t blocknr, newblocknr; | ||
| 362 | unsigned long offset; | ||
| 363 | int sb2i = -1; /* array index of the secondary superblock */ | ||
| 364 | int ret = 0; | ||
| 365 | |||
| 366 | /* nilfs->ns_sem must be locked by the caller. */ | ||
| 367 | if (nilfs->ns_sbh[1] && | ||
| 368 | nilfs->ns_sbh[1]->b_blocknr > nilfs->ns_first_data_block) { | ||
| 369 | sb2i = 1; | ||
| 370 | blocknr = nilfs->ns_sbh[1]->b_blocknr; | ||
| 371 | } else if (nilfs->ns_sbh[0]->b_blocknr > nilfs->ns_first_data_block) { | ||
| 372 | sb2i = 0; | ||
| 373 | blocknr = nilfs->ns_sbh[0]->b_blocknr; | ||
| 374 | } | ||
| 375 | if (sb2i >= 0 && (u64)blocknr << nilfs->ns_blocksize_bits == sb2off) | ||
| 376 | goto out; /* super block location is unchanged */ | ||
| 377 | |||
| 378 | /* Get new super block buffer */ | ||
| 379 | newblocknr = sb2off >> nilfs->ns_blocksize_bits; | ||
| 380 | offset = sb2off & (nilfs->ns_blocksize - 1); | ||
| 381 | nsbh = sb_getblk(sb, newblocknr); | ||
| 382 | if (!nsbh) { | ||
| 383 | printk(KERN_WARNING | ||
| 384 | "NILFS warning: unable to move secondary superblock " | ||
| 385 | "to block %llu\n", (unsigned long long)newblocknr); | ||
| 386 | ret = -EIO; | ||
| 387 | goto out; | ||
| 388 | } | ||
| 389 | nsbp = (void *)nsbh->b_data + offset; | ||
| 390 | memset(nsbp, 0, nilfs->ns_blocksize); | ||
| 391 | |||
| 392 | if (sb2i >= 0) { | ||
| 393 | memcpy(nsbp, nilfs->ns_sbp[sb2i], nilfs->ns_sbsize); | ||
| 394 | brelse(nilfs->ns_sbh[sb2i]); | ||
| 395 | nilfs->ns_sbh[sb2i] = nsbh; | ||
| 396 | nilfs->ns_sbp[sb2i] = nsbp; | ||
| 397 | } else if (nilfs->ns_sbh[0]->b_blocknr < nilfs->ns_first_data_block) { | ||
| 398 | /* secondary super block will be restored to index 1 */ | ||
| 399 | nilfs->ns_sbh[1] = nsbh; | ||
| 400 | nilfs->ns_sbp[1] = nsbp; | ||
| 401 | } else { | ||
| 402 | brelse(nsbh); | ||
| 403 | } | ||
| 404 | out: | ||
| 405 | return ret; | ||
| 406 | } | ||
| 407 | |||
| 408 | /** | ||
| 409 | * nilfs_resize_fs - resize the filesystem | ||
| 410 | * @sb: super block instance | ||
| 411 | * @newsize: new size of the filesystem (in bytes) | ||
| 412 | */ | ||
| 413 | int nilfs_resize_fs(struct super_block *sb, __u64 newsize) | ||
| 414 | { | ||
| 415 | struct the_nilfs *nilfs = sb->s_fs_info; | ||
| 416 | struct nilfs_super_block **sbp; | ||
| 417 | __u64 devsize, newnsegs; | ||
| 418 | loff_t sb2off; | ||
| 419 | int ret; | ||
| 420 | |||
| 421 | ret = -ERANGE; | ||
| 422 | devsize = i_size_read(sb->s_bdev->bd_inode); | ||
| 423 | if (newsize > devsize) | ||
| 424 | goto out; | ||
| 425 | |||
| 426 | /* | ||
| 427 | * Write lock is required to protect some functions depending | ||
| 428 | * on the number of segments, the number of reserved segments, | ||
| 429 | * and so forth. | ||
| 430 | */ | ||
| 431 | down_write(&nilfs->ns_segctor_sem); | ||
| 432 | |||
| 433 | sb2off = NILFS_SB2_OFFSET_BYTES(newsize); | ||
| 434 | newnsegs = sb2off >> nilfs->ns_blocksize_bits; | ||
| 435 | do_div(newnsegs, nilfs->ns_blocks_per_segment); | ||
| 436 | |||
| 437 | ret = nilfs_sufile_resize(nilfs->ns_sufile, newnsegs); | ||
| 438 | up_write(&nilfs->ns_segctor_sem); | ||
| 439 | if (ret < 0) | ||
| 440 | goto out; | ||
| 441 | |||
| 442 | ret = nilfs_construct_segment(sb); | ||
| 443 | if (ret < 0) | ||
| 444 | goto out; | ||
| 445 | |||
| 446 | down_write(&nilfs->ns_sem); | ||
| 447 | nilfs_move_2nd_super(sb, sb2off); | ||
| 448 | ret = -EIO; | ||
| 449 | sbp = nilfs_prepare_super(sb, 0); | ||
| 450 | if (likely(sbp)) { | ||
| 451 | nilfs_set_log_cursor(sbp[0], nilfs); | ||
| 452 | /* | ||
| 453 | * Drop NILFS_RESIZE_FS flag for compatibility with | ||
| 454 | * mount-time resize which may be implemented in a | ||
| 455 | * future release. | ||
| 456 | */ | ||
| 457 | sbp[0]->s_state = cpu_to_le16(le16_to_cpu(sbp[0]->s_state) & | ||
| 458 | ~NILFS_RESIZE_FS); | ||
| 459 | sbp[0]->s_dev_size = cpu_to_le64(newsize); | ||
| 460 | sbp[0]->s_nsegments = cpu_to_le64(nilfs->ns_nsegments); | ||
| 461 | if (sbp[1]) | ||
| 462 | memcpy(sbp[1], sbp[0], nilfs->ns_sbsize); | ||
| 463 | ret = nilfs_commit_super(sb, NILFS_SB_COMMIT_ALL); | ||
| 464 | } | ||
| 465 | up_write(&nilfs->ns_sem); | ||
| 466 | |||
| 467 | /* | ||
| 468 | * Reset the range of allocatable segments last. This order | ||
| 469 | * is important in the case of expansion because the secondary | ||
| 470 | * superblock must be protected from log write until migration | ||
| 471 | * completes. | ||
| 472 | */ | ||
| 473 | if (!ret) | ||
| 474 | nilfs_sufile_set_alloc_range(nilfs->ns_sufile, 0, newnsegs - 1); | ||
| 475 | out: | ||
| 476 | return ret; | ||
| 477 | } | ||
| 478 | |||
| 350 | static void nilfs_put_super(struct super_block *sb) | 479 | static void nilfs_put_super(struct super_block *sb) |
| 351 | { | 480 | { |
| 352 | struct the_nilfs *nilfs = sb->s_fs_info; | 481 | struct the_nilfs *nilfs = sb->s_fs_info; |
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index d2acd1a651f3..d32714094375 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c | |||
| @@ -363,6 +363,24 @@ static unsigned long long nilfs_max_size(unsigned int blkbits) | |||
| 363 | return res; | 363 | return res; |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | /** | ||
| 367 | * nilfs_nrsvsegs - calculate the number of reserved segments | ||
| 368 | * @nilfs: nilfs object | ||
| 369 | * @nsegs: total number of segments | ||
| 370 | */ | ||
| 371 | unsigned long nilfs_nrsvsegs(struct the_nilfs *nilfs, unsigned long nsegs) | ||
| 372 | { | ||
| 373 | return max_t(unsigned long, NILFS_MIN_NRSVSEGS, | ||
| 374 | DIV_ROUND_UP(nsegs * nilfs->ns_r_segments_percentage, | ||
| 375 | 100)); | ||
| 376 | } | ||
| 377 | |||
| 378 | void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs) | ||
| 379 | { | ||
| 380 | nilfs->ns_nsegments = nsegs; | ||
| 381 | nilfs->ns_nrsvsegs = nilfs_nrsvsegs(nilfs, nsegs); | ||
| 382 | } | ||
| 383 | |||
| 366 | static int nilfs_store_disk_layout(struct the_nilfs *nilfs, | 384 | static int nilfs_store_disk_layout(struct the_nilfs *nilfs, |
| 367 | struct nilfs_super_block *sbp) | 385 | struct nilfs_super_block *sbp) |
| 368 | { | 386 | { |
| @@ -389,13 +407,9 @@ static int nilfs_store_disk_layout(struct the_nilfs *nilfs, | |||
| 389 | } | 407 | } |
| 390 | 408 | ||
| 391 | nilfs->ns_first_data_block = le64_to_cpu(sbp->s_first_data_block); | 409 | nilfs->ns_first_data_block = le64_to_cpu(sbp->s_first_data_block); |
| 392 | nilfs->ns_nsegments = le64_to_cpu(sbp->s_nsegments); | ||
| 393 | nilfs->ns_r_segments_percentage = | 410 | nilfs->ns_r_segments_percentage = |
| 394 | le32_to_cpu(sbp->s_r_segments_percentage); | 411 | le32_to_cpu(sbp->s_r_segments_percentage); |
| 395 | nilfs->ns_nrsvsegs = | 412 | nilfs_set_nsegments(nilfs, le64_to_cpu(sbp->s_nsegments)); |
| 396 | max_t(unsigned long, NILFS_MIN_NRSVSEGS, | ||
| 397 | DIV_ROUND_UP(nilfs->ns_nsegments * | ||
| 398 | nilfs->ns_r_segments_percentage, 100)); | ||
| 399 | nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed); | 413 | nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed); |
| 400 | return 0; | 414 | return 0; |
| 401 | } | 415 | } |
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h index f4968145c2a3..9992b11312ff 100644 --- a/fs/nilfs2/the_nilfs.h +++ b/fs/nilfs2/the_nilfs.h | |||
| @@ -268,6 +268,8 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev); | |||
| 268 | void destroy_nilfs(struct the_nilfs *nilfs); | 268 | void destroy_nilfs(struct the_nilfs *nilfs); |
| 269 | int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data); | 269 | int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data); |
| 270 | int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb); | 270 | int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb); |
| 271 | unsigned long nilfs_nrsvsegs(struct the_nilfs *nilfs, unsigned long nsegs); | ||
| 272 | void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs); | ||
| 271 | int nilfs_discard_segments(struct the_nilfs *, __u64 *, size_t); | 273 | int nilfs_discard_segments(struct the_nilfs *, __u64 *, size_t); |
| 272 | int nilfs_count_free_blocks(struct the_nilfs *, sector_t *); | 274 | int nilfs_count_free_blocks(struct the_nilfs *, sector_t *); |
| 273 | struct nilfs_root *nilfs_lookup_root(struct the_nilfs *nilfs, __u64 cno); | 275 | struct nilfs_root *nilfs_lookup_root(struct the_nilfs *nilfs, __u64 cno); |
diff --git a/include/linux/nilfs2_fs.h b/include/linux/nilfs2_fs.h index 8768c469e93e..7454ad7451b4 100644 --- a/include/linux/nilfs2_fs.h +++ b/include/linux/nilfs2_fs.h | |||
| @@ -107,7 +107,7 @@ struct nilfs_super_root { | |||
| 107 | #define NILFS_SR_DAT_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 0) | 107 | #define NILFS_SR_DAT_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 0) |
| 108 | #define NILFS_SR_CPFILE_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 1) | 108 | #define NILFS_SR_CPFILE_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 1) |
| 109 | #define NILFS_SR_SUFILE_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 2) | 109 | #define NILFS_SR_SUFILE_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 2) |
| 110 | #define NILFS_SR_BYTES (sizeof(struct nilfs_super_root)) | 110 | #define NILFS_SR_BYTES(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 3) |
| 111 | 111 | ||
| 112 | /* | 112 | /* |
| 113 | * Maximal mount counts | 113 | * Maximal mount counts |
| @@ -845,5 +845,7 @@ struct nilfs_bdesc { | |||
| 845 | _IOR(NILFS_IOCTL_IDENT, 0x8A, __u64) | 845 | _IOR(NILFS_IOCTL_IDENT, 0x8A, __u64) |
| 846 | #define NILFS_IOCTL_RESIZE \ | 846 | #define NILFS_IOCTL_RESIZE \ |
| 847 | _IOW(NILFS_IOCTL_IDENT, 0x8B, __u64) | 847 | _IOW(NILFS_IOCTL_IDENT, 0x8B, __u64) |
| 848 | #define NILFS_IOCTL_SET_ALLOC_RANGE \ | ||
| 849 | _IOW(NILFS_IOCTL_IDENT, 0x8C, __u64[2]) | ||
| 848 | 850 | ||
| 849 | #endif /* _LINUX_NILFS_FS_H */ | 851 | #endif /* _LINUX_NILFS_FS_H */ |
