Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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()

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