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()
This commit is contained in:
commit
caebc160ce
|
@ -489,8 +489,8 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode,
|
|||
void nilfs_palloc_commit_alloc_entry(struct inode *inode,
|
||||
struct nilfs_palloc_req *req)
|
||||
{
|
||||
nilfs_mdt_mark_buffer_dirty(req->pr_bitmap_bh);
|
||||
nilfs_mdt_mark_buffer_dirty(req->pr_desc_bh);
|
||||
mark_buffer_dirty(req->pr_bitmap_bh);
|
||||
mark_buffer_dirty(req->pr_desc_bh);
|
||||
nilfs_mdt_mark_dirty(inode);
|
||||
|
||||
brelse(req->pr_bitmap_bh);
|
||||
|
@ -527,8 +527,8 @@ void nilfs_palloc_commit_free_entry(struct inode *inode,
|
|||
kunmap(req->pr_bitmap_bh->b_page);
|
||||
kunmap(req->pr_desc_bh->b_page);
|
||||
|
||||
nilfs_mdt_mark_buffer_dirty(req->pr_desc_bh);
|
||||
nilfs_mdt_mark_buffer_dirty(req->pr_bitmap_bh);
|
||||
mark_buffer_dirty(req->pr_desc_bh);
|
||||
mark_buffer_dirty(req->pr_bitmap_bh);
|
||||
nilfs_mdt_mark_dirty(inode);
|
||||
|
||||
brelse(req->pr_bitmap_bh);
|
||||
|
@ -683,8 +683,8 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
|
|||
kunmap(bitmap_bh->b_page);
|
||||
kunmap(desc_bh->b_page);
|
||||
|
||||
nilfs_mdt_mark_buffer_dirty(desc_bh);
|
||||
nilfs_mdt_mark_buffer_dirty(bitmap_bh);
|
||||
mark_buffer_dirty(desc_bh);
|
||||
mark_buffer_dirty(bitmap_bh);
|
||||
nilfs_mdt_mark_dirty(inode);
|
||||
|
||||
brelse(bitmap_bh);
|
||||
|
|
|
@ -34,7 +34,9 @@
|
|||
|
||||
struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap)
|
||||
{
|
||||
return NILFS_I_NILFS(bmap->b_inode)->ns_dat;
|
||||
struct the_nilfs *nilfs = bmap->b_inode->i_sb->s_fs_info;
|
||||
|
||||
return nilfs->ns_dat;
|
||||
}
|
||||
|
||||
static int nilfs_bmap_convert_error(struct nilfs_bmap *bmap,
|
||||
|
|
|
@ -34,12 +34,6 @@
|
|||
#include "page.h"
|
||||
#include "btnode.h"
|
||||
|
||||
void nilfs_btnode_cache_init(struct address_space *btnc,
|
||||
struct backing_dev_info *bdi)
|
||||
{
|
||||
nilfs_mapping_init(btnc, bdi);
|
||||
}
|
||||
|
||||
void nilfs_btnode_cache_clear(struct address_space *btnc)
|
||||
{
|
||||
invalidate_mapping_pages(btnc, 0, -1);
|
||||
|
@ -62,7 +56,7 @@ nilfs_btnode_create_block(struct address_space *btnc, __u64 blocknr)
|
|||
BUG();
|
||||
}
|
||||
memset(bh->b_data, 0, 1 << inode->i_blkbits);
|
||||
bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev;
|
||||
bh->b_bdev = inode->i_sb->s_bdev;
|
||||
bh->b_blocknr = blocknr;
|
||||
set_buffer_mapped(bh);
|
||||
set_buffer_uptodate(bh);
|
||||
|
@ -94,10 +88,11 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
|
|||
if (pblocknr == 0) {
|
||||
pblocknr = blocknr;
|
||||
if (inode->i_ino != NILFS_DAT_INO) {
|
||||
struct inode *dat = NILFS_I_NILFS(inode)->ns_dat;
|
||||
struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
|
||||
|
||||
/* blocknr is a virtual block number */
|
||||
err = nilfs_dat_translate(dat, blocknr, &pblocknr);
|
||||
err = nilfs_dat_translate(nilfs->ns_dat, blocknr,
|
||||
&pblocknr);
|
||||
if (unlikely(err)) {
|
||||
brelse(bh);
|
||||
goto out_locked;
|
||||
|
@ -120,7 +115,7 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
|
|||
goto found;
|
||||
}
|
||||
set_buffer_mapped(bh);
|
||||
bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev;
|
||||
bh->b_bdev = inode->i_sb->s_bdev;
|
||||
bh->b_blocknr = pblocknr; /* set block address for read */
|
||||
bh->b_end_io = end_buffer_read_sync;
|
||||
get_bh(bh);
|
||||
|
@ -259,7 +254,7 @@ void nilfs_btnode_commit_change_key(struct address_space *btnc,
|
|||
"invalid oldkey %lld (newkey=%lld)",
|
||||
(unsigned long long)oldkey,
|
||||
(unsigned long long)newkey);
|
||||
nilfs_btnode_mark_dirty(obh);
|
||||
mark_buffer_dirty(obh);
|
||||
|
||||
spin_lock_irq(&btnc->tree_lock);
|
||||
radix_tree_delete(&btnc->page_tree, oldkey);
|
||||
|
@ -271,7 +266,7 @@ void nilfs_btnode_commit_change_key(struct address_space *btnc,
|
|||
unlock_page(opage);
|
||||
} else {
|
||||
nilfs_copy_buffer(nbh, obh);
|
||||
nilfs_btnode_mark_dirty(nbh);
|
||||
mark_buffer_dirty(nbh);
|
||||
|
||||
nbh->b_blocknr = newkey;
|
||||
ctxt->bh = nbh;
|
||||
|
|
|
@ -37,7 +37,6 @@ struct nilfs_btnode_chkey_ctxt {
|
|||
struct buffer_head *newbh;
|
||||
};
|
||||
|
||||
void nilfs_btnode_cache_init(struct address_space *, struct backing_dev_info *);
|
||||
void nilfs_btnode_cache_clear(struct address_space *);
|
||||
struct buffer_head *nilfs_btnode_create_block(struct address_space *btnc,
|
||||
__u64 blocknr);
|
||||
|
@ -51,7 +50,4 @@ void nilfs_btnode_commit_change_key(struct address_space *,
|
|||
void nilfs_btnode_abort_change_key(struct address_space *,
|
||||
struct nilfs_btnode_chkey_ctxt *);
|
||||
|
||||
#define nilfs_btnode_mark_dirty(bh) nilfs_mark_buffer_dirty(bh)
|
||||
|
||||
|
||||
#endif /* _NILFS_BTNODE_H */
|
||||
|
|
|
@ -714,7 +714,7 @@ static void nilfs_btree_promote_key(struct nilfs_bmap *btree,
|
|||
nilfs_btree_get_nonroot_node(path, level),
|
||||
path[level].bp_index, key);
|
||||
if (!buffer_dirty(path[level].bp_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_bh);
|
||||
mark_buffer_dirty(path[level].bp_bh);
|
||||
} while ((path[level].bp_index == 0) &&
|
||||
(++level < nilfs_btree_height(btree) - 1));
|
||||
}
|
||||
|
@ -739,7 +739,7 @@ static void nilfs_btree_do_insert(struct nilfs_bmap *btree,
|
|||
nilfs_btree_node_insert(node, path[level].bp_index,
|
||||
*keyp, *ptrp, ncblk);
|
||||
if (!buffer_dirty(path[level].bp_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_bh);
|
||||
mark_buffer_dirty(path[level].bp_bh);
|
||||
|
||||
if (path[level].bp_index == 0)
|
||||
nilfs_btree_promote_key(btree, path, level + 1,
|
||||
|
@ -777,9 +777,9 @@ static void nilfs_btree_carry_left(struct nilfs_bmap *btree,
|
|||
nilfs_btree_node_move_left(left, node, n, ncblk, ncblk);
|
||||
|
||||
if (!buffer_dirty(path[level].bp_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_bh);
|
||||
mark_buffer_dirty(path[level].bp_bh);
|
||||
if (!buffer_dirty(path[level].bp_sib_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
|
||||
mark_buffer_dirty(path[level].bp_sib_bh);
|
||||
|
||||
nilfs_btree_promote_key(btree, path, level + 1,
|
||||
nilfs_btree_node_get_key(node, 0));
|
||||
|
@ -823,9 +823,9 @@ static void nilfs_btree_carry_right(struct nilfs_bmap *btree,
|
|||
nilfs_btree_node_move_right(node, right, n, ncblk, ncblk);
|
||||
|
||||
if (!buffer_dirty(path[level].bp_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_bh);
|
||||
mark_buffer_dirty(path[level].bp_bh);
|
||||
if (!buffer_dirty(path[level].bp_sib_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
|
||||
mark_buffer_dirty(path[level].bp_sib_bh);
|
||||
|
||||
path[level + 1].bp_index++;
|
||||
nilfs_btree_promote_key(btree, path, level + 1,
|
||||
|
@ -870,9 +870,9 @@ static void nilfs_btree_split(struct nilfs_bmap *btree,
|
|||
nilfs_btree_node_move_right(node, right, n, ncblk, ncblk);
|
||||
|
||||
if (!buffer_dirty(path[level].bp_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_bh);
|
||||
mark_buffer_dirty(path[level].bp_bh);
|
||||
if (!buffer_dirty(path[level].bp_sib_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
|
||||
mark_buffer_dirty(path[level].bp_sib_bh);
|
||||
|
||||
newkey = nilfs_btree_node_get_key(right, 0);
|
||||
newptr = path[level].bp_newreq.bpr_ptr;
|
||||
|
@ -919,7 +919,7 @@ static void nilfs_btree_grow(struct nilfs_bmap *btree,
|
|||
nilfs_btree_node_set_level(root, level + 1);
|
||||
|
||||
if (!buffer_dirty(path[level].bp_sib_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
|
||||
mark_buffer_dirty(path[level].bp_sib_bh);
|
||||
|
||||
path[level].bp_bh = path[level].bp_sib_bh;
|
||||
path[level].bp_sib_bh = NULL;
|
||||
|
@ -1194,7 +1194,7 @@ static void nilfs_btree_do_delete(struct nilfs_bmap *btree,
|
|||
nilfs_btree_node_delete(node, path[level].bp_index,
|
||||
keyp, ptrp, ncblk);
|
||||
if (!buffer_dirty(path[level].bp_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_bh);
|
||||
mark_buffer_dirty(path[level].bp_bh);
|
||||
if (path[level].bp_index == 0)
|
||||
nilfs_btree_promote_key(btree, path, level + 1,
|
||||
nilfs_btree_node_get_key(node, 0));
|
||||
|
@ -1226,9 +1226,9 @@ static void nilfs_btree_borrow_left(struct nilfs_bmap *btree,
|
|||
nilfs_btree_node_move_right(left, node, n, ncblk, ncblk);
|
||||
|
||||
if (!buffer_dirty(path[level].bp_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_bh);
|
||||
mark_buffer_dirty(path[level].bp_bh);
|
||||
if (!buffer_dirty(path[level].bp_sib_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
|
||||
mark_buffer_dirty(path[level].bp_sib_bh);
|
||||
|
||||
nilfs_btree_promote_key(btree, path, level + 1,
|
||||
nilfs_btree_node_get_key(node, 0));
|
||||
|
@ -1258,9 +1258,9 @@ static void nilfs_btree_borrow_right(struct nilfs_bmap *btree,
|
|||
nilfs_btree_node_move_left(node, right, n, ncblk, ncblk);
|
||||
|
||||
if (!buffer_dirty(path[level].bp_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_bh);
|
||||
mark_buffer_dirty(path[level].bp_bh);
|
||||
if (!buffer_dirty(path[level].bp_sib_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
|
||||
mark_buffer_dirty(path[level].bp_sib_bh);
|
||||
|
||||
path[level + 1].bp_index++;
|
||||
nilfs_btree_promote_key(btree, path, level + 1,
|
||||
|
@ -1289,7 +1289,7 @@ static void nilfs_btree_concat_left(struct nilfs_bmap *btree,
|
|||
nilfs_btree_node_move_left(left, node, n, ncblk, ncblk);
|
||||
|
||||
if (!buffer_dirty(path[level].bp_sib_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
|
||||
mark_buffer_dirty(path[level].bp_sib_bh);
|
||||
|
||||
nilfs_btnode_delete(path[level].bp_bh);
|
||||
path[level].bp_bh = path[level].bp_sib_bh;
|
||||
|
@ -1315,7 +1315,7 @@ static void nilfs_btree_concat_right(struct nilfs_bmap *btree,
|
|||
nilfs_btree_node_move_left(node, right, n, ncblk, ncblk);
|
||||
|
||||
if (!buffer_dirty(path[level].bp_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_bh);
|
||||
mark_buffer_dirty(path[level].bp_bh);
|
||||
|
||||
nilfs_btnode_delete(path[level].bp_sib_bh);
|
||||
path[level].bp_sib_bh = NULL;
|
||||
|
@ -1709,7 +1709,7 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *btree,
|
|||
nilfs_btree_node_init(node, 0, 1, n, ncblk, keys, ptrs);
|
||||
nilfs_btree_node_insert(node, n, key, dreq->bpr_ptr, ncblk);
|
||||
if (!buffer_dirty(bh))
|
||||
nilfs_btnode_mark_dirty(bh);
|
||||
mark_buffer_dirty(bh);
|
||||
if (!nilfs_bmap_dirty(btree))
|
||||
nilfs_bmap_set_dirty(btree);
|
||||
|
||||
|
@ -1787,7 +1787,7 @@ static int nilfs_btree_propagate_p(struct nilfs_bmap *btree,
|
|||
{
|
||||
while ((++level < nilfs_btree_height(btree) - 1) &&
|
||||
!buffer_dirty(path[level].bp_bh))
|
||||
nilfs_btnode_mark_dirty(path[level].bp_bh);
|
||||
mark_buffer_dirty(path[level].bp_bh);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2229,7 +2229,7 @@ static int nilfs_btree_mark(struct nilfs_bmap *btree, __u64 key, int level)
|
|||
}
|
||||
|
||||
if (!buffer_dirty(bh))
|
||||
nilfs_btnode_mark_dirty(bh);
|
||||
mark_buffer_dirty(bh);
|
||||
brelse(bh);
|
||||
if (!nilfs_bmap_dirty(btree))
|
||||
nilfs_bmap_set_dirty(btree);
|
||||
|
|
|
@ -216,14 +216,14 @@ int nilfs_cpfile_get_checkpoint(struct inode *cpfile,
|
|||
if (!nilfs_cpfile_is_in_first(cpfile, cno))
|
||||
nilfs_cpfile_block_add_valid_checkpoints(cpfile, cp_bh,
|
||||
kaddr, 1);
|
||||
nilfs_mdt_mark_buffer_dirty(cp_bh);
|
||||
mark_buffer_dirty(cp_bh);
|
||||
|
||||
kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
|
||||
header = nilfs_cpfile_block_get_header(cpfile, header_bh,
|
||||
kaddr);
|
||||
le64_add_cpu(&header->ch_ncheckpoints, 1);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
nilfs_mdt_mark_buffer_dirty(header_bh);
|
||||
mark_buffer_dirty(header_bh);
|
||||
nilfs_mdt_mark_dirty(cpfile);
|
||||
}
|
||||
|
||||
|
@ -326,7 +326,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile,
|
|||
}
|
||||
if (nicps > 0) {
|
||||
tnicps += nicps;
|
||||
nilfs_mdt_mark_buffer_dirty(cp_bh);
|
||||
mark_buffer_dirty(cp_bh);
|
||||
nilfs_mdt_mark_dirty(cpfile);
|
||||
if (!nilfs_cpfile_is_in_first(cpfile, cno)) {
|
||||
count =
|
||||
|
@ -358,7 +358,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile,
|
|||
header = nilfs_cpfile_block_get_header(cpfile, header_bh,
|
||||
kaddr);
|
||||
le64_add_cpu(&header->ch_ncheckpoints, -(u64)tnicps);
|
||||
nilfs_mdt_mark_buffer_dirty(header_bh);
|
||||
mark_buffer_dirty(header_bh);
|
||||
nilfs_mdt_mark_dirty(cpfile);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
}
|
||||
|
@ -671,10 +671,10 @@ static int nilfs_cpfile_set_snapshot(struct inode *cpfile, __u64 cno)
|
|||
le64_add_cpu(&header->ch_nsnapshots, 1);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
|
||||
nilfs_mdt_mark_buffer_dirty(prev_bh);
|
||||
nilfs_mdt_mark_buffer_dirty(curr_bh);
|
||||
nilfs_mdt_mark_buffer_dirty(cp_bh);
|
||||
nilfs_mdt_mark_buffer_dirty(header_bh);
|
||||
mark_buffer_dirty(prev_bh);
|
||||
mark_buffer_dirty(curr_bh);
|
||||
mark_buffer_dirty(cp_bh);
|
||||
mark_buffer_dirty(header_bh);
|
||||
nilfs_mdt_mark_dirty(cpfile);
|
||||
|
||||
brelse(prev_bh);
|
||||
|
@ -774,10 +774,10 @@ static int nilfs_cpfile_clear_snapshot(struct inode *cpfile, __u64 cno)
|
|||
le64_add_cpu(&header->ch_nsnapshots, -1);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
|
||||
nilfs_mdt_mark_buffer_dirty(next_bh);
|
||||
nilfs_mdt_mark_buffer_dirty(prev_bh);
|
||||
nilfs_mdt_mark_buffer_dirty(cp_bh);
|
||||
nilfs_mdt_mark_buffer_dirty(header_bh);
|
||||
mark_buffer_dirty(next_bh);
|
||||
mark_buffer_dirty(prev_bh);
|
||||
mark_buffer_dirty(cp_bh);
|
||||
mark_buffer_dirty(header_bh);
|
||||
nilfs_mdt_mark_dirty(cpfile);
|
||||
|
||||
brelse(prev_bh);
|
||||
|
|
|
@ -54,7 +54,7 @@ static int nilfs_dat_prepare_entry(struct inode *dat,
|
|||
static void nilfs_dat_commit_entry(struct inode *dat,
|
||||
struct nilfs_palloc_req *req)
|
||||
{
|
||||
nilfs_mdt_mark_buffer_dirty(req->pr_entry_bh);
|
||||
mark_buffer_dirty(req->pr_entry_bh);
|
||||
nilfs_mdt_mark_dirty(dat);
|
||||
brelse(req->pr_entry_bh);
|
||||
}
|
||||
|
@ -361,7 +361,7 @@ int nilfs_dat_move(struct inode *dat, __u64 vblocknr, sector_t blocknr)
|
|||
entry->de_blocknr = cpu_to_le64(blocknr);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
|
||||
nilfs_mdt_mark_buffer_dirty(entry_bh);
|
||||
mark_buffer_dirty(entry_bh);
|
||||
nilfs_mdt_mark_dirty(dat);
|
||||
|
||||
brelse(entry_bh);
|
||||
|
|
|
@ -111,7 +111,6 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|||
nilfs_transaction_commit(inode->i_sb);
|
||||
|
||||
mapped:
|
||||
SetPageChecked(page);
|
||||
wait_on_page_writeback(page);
|
||||
return VM_FAULT_LOCKED;
|
||||
}
|
||||
|
|
|
@ -48,9 +48,6 @@
|
|||
#include "dat.h"
|
||||
#include "ifile.h"
|
||||
|
||||
static const struct address_space_operations def_gcinode_aops = {
|
||||
};
|
||||
|
||||
/*
|
||||
* nilfs_gccache_submit_read_data() - add data buffer and submit read request
|
||||
* @inode - gc inode
|
||||
|
@ -87,9 +84,9 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff,
|
|||
goto out;
|
||||
|
||||
if (pbn == 0) {
|
||||
struct inode *dat_inode = NILFS_I_NILFS(inode)->ns_dat;
|
||||
/* use original dat, not gc dat. */
|
||||
err = nilfs_dat_translate(dat_inode, vbn, &pbn);
|
||||
struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
|
||||
|
||||
err = nilfs_dat_translate(nilfs->ns_dat, vbn, &pbn);
|
||||
if (unlikely(err)) { /* -EIO, -ENOMEM, -ENOENT */
|
||||
brelse(bh);
|
||||
goto failed;
|
||||
|
@ -103,7 +100,7 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff,
|
|||
}
|
||||
|
||||
if (!buffer_mapped(bh)) {
|
||||
bh->b_bdev = NILFS_I_NILFS(inode)->ns_bdev;
|
||||
bh->b_bdev = inode->i_sb->s_bdev;
|
||||
set_buffer_mapped(bh);
|
||||
}
|
||||
bh->b_blocknr = pbn;
|
||||
|
@ -160,15 +157,11 @@ int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *bh)
|
|||
if (buffer_dirty(bh))
|
||||
return -EEXIST;
|
||||
|
||||
if (buffer_nilfs_node(bh)) {
|
||||
if (nilfs_btree_broken_node_block(bh)) {
|
||||
clear_buffer_uptodate(bh);
|
||||
return -EIO;
|
||||
}
|
||||
nilfs_btnode_mark_dirty(bh);
|
||||
} else {
|
||||
nilfs_mark_buffer_dirty(bh);
|
||||
if (buffer_nilfs_node(bh) && nilfs_btree_broken_node_block(bh)) {
|
||||
clear_buffer_uptodate(bh);
|
||||
return -EIO;
|
||||
}
|
||||
mark_buffer_dirty(bh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -178,7 +171,7 @@ int nilfs_init_gcinode(struct inode *inode)
|
|||
|
||||
inode->i_mode = S_IFREG;
|
||||
mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
|
||||
inode->i_mapping->a_ops = &def_gcinode_aops;
|
||||
inode->i_mapping->a_ops = &empty_aops;
|
||||
inode->i_mapping->backing_dev_info = inode->i_sb->s_bdi;
|
||||
|
||||
ii->i_flags = 0;
|
||||
|
|
|
@ -80,7 +80,7 @@ int nilfs_ifile_create_inode(struct inode *ifile, ino_t *out_ino,
|
|||
return ret;
|
||||
}
|
||||
nilfs_palloc_commit_alloc_entry(ifile, &req);
|
||||
nilfs_mdt_mark_buffer_dirty(req.pr_entry_bh);
|
||||
mark_buffer_dirty(req.pr_entry_bh);
|
||||
nilfs_mdt_mark_dirty(ifile);
|
||||
*out_ino = (ino_t)req.pr_entry_nr;
|
||||
*out_bh = req.pr_entry_bh;
|
||||
|
@ -128,7 +128,7 @@ int nilfs_ifile_delete_inode(struct inode *ifile, ino_t ino)
|
|||
raw_inode->i_flags = 0;
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
|
||||
nilfs_mdt_mark_buffer_dirty(req.pr_entry_bh);
|
||||
mark_buffer_dirty(req.pr_entry_bh);
|
||||
brelse(req.pr_entry_bh);
|
||||
|
||||
nilfs_palloc_commit_free_entry(ifile, &req);
|
||||
|
|
|
@ -74,14 +74,14 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff,
|
|||
struct buffer_head *bh_result, int create)
|
||||
{
|
||||
struct nilfs_inode_info *ii = NILFS_I(inode);
|
||||
struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
|
||||
__u64 blknum = 0;
|
||||
int err = 0, ret;
|
||||
struct inode *dat = NILFS_I_NILFS(inode)->ns_dat;
|
||||
unsigned maxblocks = bh_result->b_size >> inode->i_blkbits;
|
||||
|
||||
down_read(&NILFS_MDT(dat)->mi_sem);
|
||||
down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
|
||||
ret = nilfs_bmap_lookup_contig(ii->i_bmap, blkoff, &blknum, maxblocks);
|
||||
up_read(&NILFS_MDT(dat)->mi_sem);
|
||||
up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
|
||||
if (ret >= 0) { /* found */
|
||||
map_bh(bh_result, inode->i_sb, blknum);
|
||||
if (ret > 0)
|
||||
|
@ -596,6 +596,16 @@ void nilfs_write_inode_common(struct inode *inode,
|
|||
raw_inode->i_flags = cpu_to_le32(ii->i_flags);
|
||||
raw_inode->i_generation = cpu_to_le32(inode->i_generation);
|
||||
|
||||
if (NILFS_ROOT_METADATA_FILE(inode->i_ino)) {
|
||||
struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
|
||||
|
||||
/* zero-fill unused portion in the case of super root block */
|
||||
raw_inode->i_xattr = 0;
|
||||
raw_inode->i_pad = 0;
|
||||
memset((void *)raw_inode + sizeof(*raw_inode), 0,
|
||||
nilfs->ns_inode_size - sizeof(*raw_inode));
|
||||
}
|
||||
|
||||
if (has_bmap)
|
||||
nilfs_bmap_write(ii->i_bmap, raw_inode);
|
||||
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)
|
|||
return -EINVAL; /* NILFS_I_DIRTY may remain for
|
||||
freeing inode */
|
||||
}
|
||||
list_del(&ii->i_dirty);
|
||||
list_add_tail(&ii->i_dirty, &nilfs->ns_dirty_files);
|
||||
list_move_tail(&ii->i_dirty, &nilfs->ns_dirty_files);
|
||||
set_bit(NILFS_I_QUEUED, &ii->i_state);
|
||||
}
|
||||
spin_unlock(&nilfs->ns_inode_lock);
|
||||
|
@ -892,7 +901,7 @@ int nilfs_mark_inode_dirty(struct inode *inode)
|
|||
return err;
|
||||
}
|
||||
nilfs_update_inode(inode, ibh);
|
||||
nilfs_mdt_mark_buffer_dirty(ibh);
|
||||
mark_buffer_dirty(ibh);
|
||||
nilfs_mdt_mark_dirty(NILFS_I(inode)->i_root->ifile);
|
||||
brelse(ibh);
|
||||
return 0;
|
||||
|
@ -931,7 +940,7 @@ void nilfs_dirty_inode(struct inode *inode)
|
|||
int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
||||
__u64 start, __u64 len)
|
||||
{
|
||||
struct the_nilfs *nilfs = NILFS_I_NILFS(inode);
|
||||
struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
|
||||
__u64 logical = 0, phys = 0, size = 0;
|
||||
__u32 flags = 0;
|
||||
loff_t isize;
|
||||
|
|
|
@ -698,6 +698,63 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int nilfs_ioctl_resize(struct inode *inode, struct file *filp,
|
||||
void __user *argp)
|
||||
{
|
||||
__u64 newsize;
|
||||
int ret = -EPERM;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
goto out;
|
||||
|
||||
ret = mnt_want_write(filp->f_path.mnt);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = -EFAULT;
|
||||
if (copy_from_user(&newsize, argp, sizeof(newsize)))
|
||||
goto out_drop_write;
|
||||
|
||||
ret = nilfs_resize_fs(inode->i_sb, newsize);
|
||||
|
||||
out_drop_write:
|
||||
mnt_drop_write(filp->f_path.mnt);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nilfs_ioctl_set_alloc_range(struct inode *inode, void __user *argp)
|
||||
{
|
||||
struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
|
||||
__u64 range[2];
|
||||
__u64 minseg, maxseg;
|
||||
unsigned long segbytes;
|
||||
int ret = -EPERM;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
goto out;
|
||||
|
||||
ret = -EFAULT;
|
||||
if (copy_from_user(range, argp, sizeof(__u64[2])))
|
||||
goto out;
|
||||
|
||||
ret = -ERANGE;
|
||||
if (range[1] > i_size_read(inode->i_sb->s_bdev->bd_inode))
|
||||
goto out;
|
||||
|
||||
segbytes = nilfs->ns_blocks_per_segment * nilfs->ns_blocksize;
|
||||
|
||||
minseg = range[0] + segbytes - 1;
|
||||
do_div(minseg, segbytes);
|
||||
maxseg = NILFS_SB2_OFFSET_BYTES(range[1]);
|
||||
do_div(maxseg, segbytes);
|
||||
maxseg--;
|
||||
|
||||
ret = nilfs_sufile_set_alloc_range(nilfs->ns_sufile, minseg, maxseg);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, void __user *argp,
|
||||
size_t membsz,
|
||||
|
@ -763,6 +820,10 @@ long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
return nilfs_ioctl_clean_segments(inode, filp, cmd, argp);
|
||||
case NILFS_IOCTL_SYNC:
|
||||
return nilfs_ioctl_sync(inode, filp, cmd, argp);
|
||||
case NILFS_IOCTL_RESIZE:
|
||||
return nilfs_ioctl_resize(inode, filp, argp);
|
||||
case NILFS_IOCTL_SET_ALLOC_RANGE:
|
||||
return nilfs_ioctl_set_alloc_range(inode, argp);
|
||||
default:
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ nilfs_mdt_insert_new_block(struct inode *inode, unsigned long block,
|
|||
kunmap_atomic(kaddr, KM_USER0);
|
||||
|
||||
set_buffer_uptodate(bh);
|
||||
nilfs_mark_buffer_dirty(bh);
|
||||
mark_buffer_dirty(bh);
|
||||
nilfs_mdt_mark_dirty(inode);
|
||||
return 0;
|
||||
}
|
||||
|
@ -355,7 +355,7 @@ int nilfs_mdt_mark_block_dirty(struct inode *inode, unsigned long block)
|
|||
err = nilfs_mdt_read_block(inode, block, 0, &bh);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
nilfs_mark_buffer_dirty(bh);
|
||||
mark_buffer_dirty(bh);
|
||||
nilfs_mdt_mark_dirty(inode);
|
||||
brelse(bh);
|
||||
return 0;
|
||||
|
@ -450,9 +450,9 @@ int nilfs_mdt_setup_shadow_map(struct inode *inode,
|
|||
|
||||
INIT_LIST_HEAD(&shadow->frozen_buffers);
|
||||
address_space_init_once(&shadow->frozen_data);
|
||||
nilfs_mapping_init(&shadow->frozen_data, bdi);
|
||||
nilfs_mapping_init(&shadow->frozen_data, inode, bdi);
|
||||
address_space_init_once(&shadow->frozen_btnodes);
|
||||
nilfs_mapping_init(&shadow->frozen_btnodes, bdi);
|
||||
nilfs_mapping_init(&shadow->frozen_btnodes, inode, bdi);
|
||||
mi->mi_shadow = shadow;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -64,11 +64,6 @@ static inline struct nilfs_mdt_info *NILFS_MDT(const struct inode *inode)
|
|||
return inode->i_private;
|
||||
}
|
||||
|
||||
static inline struct the_nilfs *NILFS_I_NILFS(struct inode *inode)
|
||||
{
|
||||
return inode->i_sb->s_fs_info;
|
||||
}
|
||||
|
||||
/* Default GFP flags using highmem */
|
||||
#define NILFS_MDT_GFP (__GFP_WAIT | __GFP_IO | __GFP_HIGHMEM)
|
||||
|
||||
|
@ -93,8 +88,6 @@ int nilfs_mdt_freeze_buffer(struct inode *inode, struct buffer_head *bh);
|
|||
struct buffer_head *nilfs_mdt_get_frozen_buffer(struct inode *inode,
|
||||
struct buffer_head *bh);
|
||||
|
||||
#define nilfs_mdt_mark_buffer_dirty(bh) nilfs_mark_buffer_dirty(bh)
|
||||
|
||||
static inline void nilfs_mdt_mark_dirty(struct inode *inode)
|
||||
{
|
||||
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)
|
|||
|
||||
static inline __u64 nilfs_mdt_cno(struct inode *inode)
|
||||
{
|
||||
return NILFS_I_NILFS(inode)->ns_cno;
|
||||
return ((struct the_nilfs *)inode->i_sb->s_fs_info)->ns_cno;
|
||||
}
|
||||
|
||||
#define nilfs_mdt_bgl_lock(inode, bg) \
|
||||
|
|
|
@ -80,12 +80,6 @@ static inline struct inode *NILFS_BTNC_I(struct address_space *btnc)
|
|||
return &ii->vfs_inode;
|
||||
}
|
||||
|
||||
static inline struct inode *NILFS_AS_I(struct address_space *mapping)
|
||||
{
|
||||
return (mapping->host) ? :
|
||||
container_of(mapping, struct inode, i_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dynamic state flags of NILFS on-memory inode (i_state)
|
||||
*/
|
||||
|
@ -298,6 +292,7 @@ struct nilfs_super_block **nilfs_prepare_super(struct super_block *sb,
|
|||
int flip);
|
||||
int nilfs_commit_super(struct super_block *sb, int flag);
|
||||
int nilfs_cleanup_super(struct super_block *sb);
|
||||
int nilfs_resize_fs(struct super_block *sb, __u64 newsize);
|
||||
int nilfs_attach_checkpoint(struct super_block *sb, __u64 cno, int curr_mnt,
|
||||
struct nilfs_root **root);
|
||||
int nilfs_checkpoint_is_mounted(struct super_block *sb, __u64 cno);
|
||||
|
|
|
@ -37,8 +37,7 @@
|
|||
|
||||
#define NILFS_BUFFER_INHERENT_BITS \
|
||||
((1UL << BH_Uptodate) | (1UL << BH_Mapped) | (1UL << BH_NILFS_Node) | \
|
||||
(1UL << BH_NILFS_Volatile) | (1UL << BH_NILFS_Allocated) | \
|
||||
(1UL << BH_NILFS_Checked))
|
||||
(1UL << BH_NILFS_Volatile) | (1UL << BH_NILFS_Checked))
|
||||
|
||||
static struct buffer_head *
|
||||
__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,
|
|||
return bh;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since the page cache of B-tree node pages or data page cache of pseudo
|
||||
* inodes does not have a valid mapping->host pointer, calling
|
||||
* mark_buffer_dirty() for their buffers causes a NULL pointer dereference;
|
||||
* it calls __mark_inode_dirty(NULL) through __set_page_dirty().
|
||||
* To avoid this problem, the old style mark_buffer_dirty() is used instead.
|
||||
*/
|
||||
void nilfs_mark_buffer_dirty(struct buffer_head *bh)
|
||||
{
|
||||
if (!buffer_dirty(bh) && !test_set_buffer_dirty(bh))
|
||||
__set_page_dirty_nobuffers(bh->b_page);
|
||||
}
|
||||
|
||||
struct buffer_head *nilfs_grab_buffer(struct inode *inode,
|
||||
struct address_space *mapping,
|
||||
unsigned long blkoff,
|
||||
|
@ -183,7 +169,7 @@ int nilfs_page_buffers_clean(struct page *page)
|
|||
void nilfs_page_bug(struct page *page)
|
||||
{
|
||||
struct address_space *m;
|
||||
unsigned long ino = 0;
|
||||
unsigned long ino;
|
||||
|
||||
if (unlikely(!page)) {
|
||||
printk(KERN_CRIT "NILFS_PAGE_BUG(NULL)\n");
|
||||
|
@ -191,11 +177,8 @@ void nilfs_page_bug(struct page *page)
|
|||
}
|
||||
|
||||
m = page->mapping;
|
||||
if (m) {
|
||||
struct inode *inode = NILFS_AS_I(m);
|
||||
if (inode != NULL)
|
||||
ino = inode->i_ino;
|
||||
}
|
||||
ino = m ? m->host->i_ino : 0;
|
||||
|
||||
printk(KERN_CRIT "NILFS_PAGE_BUG(%p): cnt=%d index#=%llu flags=0x%lx "
|
||||
"mapping=%p ino=%lu\n",
|
||||
page, atomic_read(&page->_count),
|
||||
|
@ -216,56 +199,6 @@ void nilfs_page_bug(struct page *page)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_alloc_private_page - allocate a private page with buffer heads
|
||||
*
|
||||
* Return Value: On success, a pointer to the allocated page is returned.
|
||||
* On error, NULL is returned.
|
||||
*/
|
||||
struct page *nilfs_alloc_private_page(struct block_device *bdev, int size,
|
||||
unsigned long state)
|
||||
{
|
||||
struct buffer_head *bh, *head, *tail;
|
||||
struct page *page;
|
||||
|
||||
page = alloc_page(GFP_NOFS); /* page_count of the returned page is 1 */
|
||||
if (unlikely(!page))
|
||||
return NULL;
|
||||
|
||||
lock_page(page);
|
||||
head = alloc_page_buffers(page, size, 0);
|
||||
if (unlikely(!head)) {
|
||||
unlock_page(page);
|
||||
__free_page(page);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bh = head;
|
||||
do {
|
||||
bh->b_state = (1UL << BH_NILFS_Allocated) | state;
|
||||
tail = bh;
|
||||
bh->b_bdev = bdev;
|
||||
bh = bh->b_this_page;
|
||||
} while (bh);
|
||||
|
||||
tail->b_this_page = head;
|
||||
attach_page_buffers(page, head);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
void nilfs_free_private_page(struct page *page)
|
||||
{
|
||||
BUG_ON(!PageLocked(page));
|
||||
BUG_ON(page->mapping);
|
||||
|
||||
if (page_has_buffers(page) && !try_to_free_buffers(page))
|
||||
NILFS_PAGE_BUG(page, "failed to free page");
|
||||
|
||||
unlock_page(page);
|
||||
__free_page(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_copy_page -- copy the page with buffers
|
||||
* @dst: destination page
|
||||
|
@ -492,10 +425,10 @@ unsigned nilfs_page_count_clean_buffers(struct page *page,
|
|||
return nc;
|
||||
}
|
||||
|
||||
void nilfs_mapping_init(struct address_space *mapping,
|
||||
void nilfs_mapping_init(struct address_space *mapping, struct inode *inode,
|
||||
struct backing_dev_info *bdi)
|
||||
{
|
||||
mapping->host = NULL;
|
||||
mapping->host = inode;
|
||||
mapping->flags = 0;
|
||||
mapping_set_gfp_mask(mapping, GFP_NOFS);
|
||||
mapping->assoc_mapping = NULL;
|
||||
|
|
|
@ -38,14 +38,12 @@ enum {
|
|||
BH_NILFS_Redirected,
|
||||
};
|
||||
|
||||
BUFFER_FNS(NILFS_Allocated, nilfs_allocated) /* nilfs private buffers */
|
||||
BUFFER_FNS(NILFS_Node, nilfs_node) /* nilfs node buffers */
|
||||
BUFFER_FNS(NILFS_Volatile, nilfs_volatile)
|
||||
BUFFER_FNS(NILFS_Checked, nilfs_checked) /* buffer is verified */
|
||||
BUFFER_FNS(NILFS_Redirected, nilfs_redirected) /* redirected to a copy */
|
||||
|
||||
|
||||
void nilfs_mark_buffer_dirty(struct buffer_head *bh);
|
||||
int __nilfs_clear_page_dirty(struct page *);
|
||||
|
||||
struct buffer_head *nilfs_grab_buffer(struct inode *, struct address_space *,
|
||||
|
@ -54,14 +52,11 @@ void nilfs_forget_buffer(struct buffer_head *);
|
|||
void nilfs_copy_buffer(struct buffer_head *, struct buffer_head *);
|
||||
int nilfs_page_buffers_clean(struct page *);
|
||||
void nilfs_page_bug(struct page *);
|
||||
struct page *nilfs_alloc_private_page(struct block_device *, int,
|
||||
unsigned long);
|
||||
void nilfs_free_private_page(struct page *);
|
||||
|
||||
int nilfs_copy_dirty_pages(struct address_space *, struct address_space *);
|
||||
void nilfs_copy_back_pages(struct address_space *, struct address_space *);
|
||||
void nilfs_clear_dirty_pages(struct address_space *);
|
||||
void nilfs_mapping_init(struct address_space *mapping,
|
||||
void nilfs_mapping_init(struct address_space *mapping, struct inode *inode,
|
||||
struct backing_dev_info *bdi);
|
||||
unsigned nilfs_page_count_clean_buffers(struct page *, unsigned, unsigned);
|
||||
unsigned long nilfs_find_uncommitted_extent(struct inode *inode,
|
||||
|
|
|
@ -387,9 +387,9 @@ static int nilfs_scan_dsync_log(struct the_nilfs *nilfs, sector_t start_blocknr,
|
|||
static void dispose_recovery_list(struct list_head *head)
|
||||
{
|
||||
while (!list_empty(head)) {
|
||||
struct nilfs_recovery_block *rb
|
||||
= list_entry(head->next,
|
||||
struct nilfs_recovery_block, list);
|
||||
struct nilfs_recovery_block *rb;
|
||||
|
||||
rb = list_first_entry(head, struct nilfs_recovery_block, list);
|
||||
list_del(&rb->list);
|
||||
kfree(rb);
|
||||
}
|
||||
|
@ -416,9 +416,9 @@ static int nilfs_segment_list_add(struct list_head *head, __u64 segnum)
|
|||
void nilfs_dispose_segment_list(struct list_head *head)
|
||||
{
|
||||
while (!list_empty(head)) {
|
||||
struct nilfs_segment_entry *ent
|
||||
= list_entry(head->next,
|
||||
struct nilfs_segment_entry, list);
|
||||
struct nilfs_segment_entry *ent;
|
||||
|
||||
ent = list_first_entry(head, struct nilfs_segment_entry, list);
|
||||
list_del(&ent->list);
|
||||
kfree(ent);
|
||||
}
|
||||
|
|
|
@ -239,12 +239,15 @@ nilfs_segbuf_fill_in_super_root_crc(struct nilfs_segment_buffer *segbuf,
|
|||
u32 seed)
|
||||
{
|
||||
struct nilfs_super_root *raw_sr;
|
||||
struct the_nilfs *nilfs = segbuf->sb_super->s_fs_info;
|
||||
unsigned srsize;
|
||||
u32 crc;
|
||||
|
||||
raw_sr = (struct nilfs_super_root *)segbuf->sb_super_root->b_data;
|
||||
srsize = NILFS_SR_BYTES(nilfs->ns_inode_size);
|
||||
crc = crc32_le(seed,
|
||||
(unsigned char *)raw_sr + sizeof(raw_sr->sr_sum),
|
||||
NILFS_SR_BYTES - sizeof(raw_sr->sr_sum));
|
||||
srsize - sizeof(raw_sr->sr_sum));
|
||||
raw_sr->sr_sum = cpu_to_le32(crc);
|
||||
}
|
||||
|
||||
|
@ -254,18 +257,6 @@ static void nilfs_release_buffers(struct list_head *list)
|
|||
|
||||
list_for_each_entry_safe(bh, n, list, b_assoc_buffers) {
|
||||
list_del_init(&bh->b_assoc_buffers);
|
||||
if (buffer_nilfs_allocated(bh)) {
|
||||
struct page *clone_page = bh->b_page;
|
||||
|
||||
/* remove clone page */
|
||||
brelse(bh);
|
||||
page_cache_release(clone_page); /* for each bh */
|
||||
if (page_count(clone_page) <= 2) {
|
||||
lock_page(clone_page);
|
||||
nilfs_free_private_page(clone_page);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
brelse(bh);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -655,13 +655,10 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode,
|
|||
if (unlikely(page->index > last))
|
||||
break;
|
||||
|
||||
if (mapping->host) {
|
||||
lock_page(page);
|
||||
if (!page_has_buffers(page))
|
||||
create_empty_buffers(page,
|
||||
1 << inode->i_blkbits, 0);
|
||||
unlock_page(page);
|
||||
}
|
||||
lock_page(page);
|
||||
if (!page_has_buffers(page))
|
||||
create_empty_buffers(page, 1 << inode->i_blkbits, 0);
|
||||
unlock_page(page);
|
||||
|
||||
bh = head = page_buffers(page);
|
||||
do {
|
||||
|
@ -809,7 +806,7 @@ static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci)
|
|||
/* The following code is duplicated with cpfile. But, it is
|
||||
needed to collect the checkpoint even if it was not newly
|
||||
created */
|
||||
nilfs_mdt_mark_buffer_dirty(bh_cp);
|
||||
mark_buffer_dirty(bh_cp);
|
||||
nilfs_mdt_mark_dirty(nilfs->ns_cpfile);
|
||||
nilfs_cpfile_put_checkpoint(
|
||||
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,
|
|||
{
|
||||
struct buffer_head *bh_sr;
|
||||
struct nilfs_super_root *raw_sr;
|
||||
unsigned isz = nilfs->ns_inode_size;
|
||||
unsigned isz, srsz;
|
||||
|
||||
bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root;
|
||||
raw_sr = (struct nilfs_super_root *)bh_sr->b_data;
|
||||
isz = nilfs->ns_inode_size;
|
||||
srsz = NILFS_SR_BYTES(isz);
|
||||
|
||||
raw_sr->sr_bytes = cpu_to_le16(NILFS_SR_BYTES);
|
||||
raw_sr->sr_bytes = cpu_to_le16(srsz);
|
||||
raw_sr->sr_nongc_ctime
|
||||
= cpu_to_le64(nilfs_doing_gc() ?
|
||||
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,
|
|||
NILFS_SR_CPFILE_OFFSET(isz), 1);
|
||||
nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr +
|
||||
NILFS_SR_SUFILE_OFFSET(isz), 1);
|
||||
memset((void *)raw_sr + srsz, 0, nilfs->ns_blocksize - srsz);
|
||||
}
|
||||
|
||||
static void nilfs_redirty_inodes(struct list_head *head)
|
||||
|
@ -954,8 +954,8 @@ static int nilfs_segctor_apply_buffers(struct nilfs_sc_info *sci,
|
|||
|
||||
dispose_buffers:
|
||||
while (!list_empty(listp)) {
|
||||
bh = list_entry(listp->next, struct buffer_head,
|
||||
b_assoc_buffers);
|
||||
bh = list_first_entry(listp, struct buffer_head,
|
||||
b_assoc_buffers);
|
||||
list_del_init(&bh->b_assoc_buffers);
|
||||
brelse(bh);
|
||||
}
|
||||
|
@ -1500,10 +1500,7 @@ nilfs_segctor_update_payload_blocknr(struct nilfs_sc_info *sci,
|
|||
nblocks = le32_to_cpu(finfo->fi_nblocks);
|
||||
ndatablk = le32_to_cpu(finfo->fi_ndatablk);
|
||||
|
||||
if (buffer_nilfs_node(bh))
|
||||
inode = NILFS_BTNC_I(bh->b_page->mapping);
|
||||
else
|
||||
inode = NILFS_AS_I(bh->b_page->mapping);
|
||||
inode = bh->b_page->mapping->host;
|
||||
|
||||
if (mode == SC_LSEG_DSYNC)
|
||||
sc_op = &nilfs_sc_dsync_ops;
|
||||
|
@ -1556,83 +1553,24 @@ static int nilfs_segctor_assign(struct nilfs_sc_info *sci, int mode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nilfs_copy_replace_page_buffers(struct page *page, struct list_head *out)
|
||||
{
|
||||
struct page *clone_page;
|
||||
struct buffer_head *bh, *head, *bh2;
|
||||
void *kaddr;
|
||||
|
||||
bh = head = page_buffers(page);
|
||||
|
||||
clone_page = nilfs_alloc_private_page(bh->b_bdev, bh->b_size, 0);
|
||||
if (unlikely(!clone_page))
|
||||
return -ENOMEM;
|
||||
|
||||
bh2 = page_buffers(clone_page);
|
||||
kaddr = kmap_atomic(page, KM_USER0);
|
||||
do {
|
||||
if (list_empty(&bh->b_assoc_buffers))
|
||||
continue;
|
||||
get_bh(bh2);
|
||||
page_cache_get(clone_page); /* for each bh */
|
||||
memcpy(bh2->b_data, kaddr + bh_offset(bh), bh2->b_size);
|
||||
bh2->b_blocknr = bh->b_blocknr;
|
||||
list_replace(&bh->b_assoc_buffers, &bh2->b_assoc_buffers);
|
||||
list_add_tail(&bh->b_assoc_buffers, out);
|
||||
} while (bh = bh->b_this_page, bh2 = bh2->b_this_page, bh != head);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
|
||||
if (!TestSetPageWriteback(clone_page))
|
||||
account_page_writeback(clone_page);
|
||||
unlock_page(clone_page);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nilfs_test_page_to_be_frozen(struct page *page)
|
||||
{
|
||||
struct address_space *mapping = page->mapping;
|
||||
|
||||
if (!mapping || !mapping->host || S_ISDIR(mapping->host->i_mode))
|
||||
return 0;
|
||||
|
||||
if (page_mapped(page)) {
|
||||
ClearPageChecked(page);
|
||||
return 1;
|
||||
}
|
||||
return PageChecked(page);
|
||||
}
|
||||
|
||||
static int nilfs_begin_page_io(struct page *page, struct list_head *out)
|
||||
static void nilfs_begin_page_io(struct page *page)
|
||||
{
|
||||
if (!page || PageWriteback(page))
|
||||
/* For split b-tree node pages, this function may be called
|
||||
twice. We ignore the 2nd or later calls by this check. */
|
||||
return 0;
|
||||
return;
|
||||
|
||||
lock_page(page);
|
||||
clear_page_dirty_for_io(page);
|
||||
set_page_writeback(page);
|
||||
unlock_page(page);
|
||||
|
||||
if (nilfs_test_page_to_be_frozen(page)) {
|
||||
int err = nilfs_copy_replace_page_buffers(page, out);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci,
|
||||
struct page **failed_page)
|
||||
static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci)
|
||||
{
|
||||
struct nilfs_segment_buffer *segbuf;
|
||||
struct page *bd_page = NULL, *fs_page = NULL;
|
||||
struct list_head *list = &sci->sc_copied_buffers;
|
||||
int err;
|
||||
|
||||
*failed_page = NULL;
|
||||
list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
|
||||
struct buffer_head *bh;
|
||||
|
||||
|
@ -1662,11 +1600,7 @@ static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci,
|
|||
break;
|
||||
}
|
||||
if (bh->b_page != fs_page) {
|
||||
err = nilfs_begin_page_io(fs_page, list);
|
||||
if (unlikely(err)) {
|
||||
*failed_page = fs_page;
|
||||
goto out;
|
||||
}
|
||||
nilfs_begin_page_io(fs_page);
|
||||
fs_page = bh->b_page;
|
||||
}
|
||||
}
|
||||
|
@ -1677,11 +1611,7 @@ static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci,
|
|||
set_page_writeback(bd_page);
|
||||
unlock_page(bd_page);
|
||||
}
|
||||
err = nilfs_begin_page_io(fs_page, list);
|
||||
if (unlikely(err))
|
||||
*failed_page = fs_page;
|
||||
out:
|
||||
return err;
|
||||
nilfs_begin_page_io(fs_page);
|
||||
}
|
||||
|
||||
static int nilfs_segctor_write(struct nilfs_sc_info *sci,
|
||||
|
@ -1694,24 +1624,6 @@ static int nilfs_segctor_write(struct nilfs_sc_info *sci,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void __nilfs_end_page_io(struct page *page, int err)
|
||||
{
|
||||
if (!err) {
|
||||
if (!nilfs_page_buffers_clean(page))
|
||||
__set_page_dirty_nobuffers(page);
|
||||
ClearPageError(page);
|
||||
} else {
|
||||
__set_page_dirty_nobuffers(page);
|
||||
SetPageError(page);
|
||||
}
|
||||
|
||||
if (buffer_nilfs_allocated(page_buffers(page))) {
|
||||
if (TestClearPageWriteback(page))
|
||||
dec_zone_page_state(page, NR_WRITEBACK);
|
||||
} else
|
||||
end_page_writeback(page);
|
||||
}
|
||||
|
||||
static void nilfs_end_page_io(struct page *page, int err)
|
||||
{
|
||||
if (!page)
|
||||
|
@ -1738,40 +1650,19 @@ static void nilfs_end_page_io(struct page *page, int err)
|
|||
return;
|
||||
}
|
||||
|
||||
__nilfs_end_page_io(page, err);
|
||||
}
|
||||
|
||||
static void nilfs_clear_copied_buffers(struct list_head *list, int err)
|
||||
{
|
||||
struct buffer_head *bh, *head;
|
||||
struct page *page;
|
||||
|
||||
while (!list_empty(list)) {
|
||||
bh = list_entry(list->next, struct buffer_head,
|
||||
b_assoc_buffers);
|
||||
page = bh->b_page;
|
||||
page_cache_get(page);
|
||||
head = bh = page_buffers(page);
|
||||
do {
|
||||
if (!list_empty(&bh->b_assoc_buffers)) {
|
||||
list_del_init(&bh->b_assoc_buffers);
|
||||
if (!err) {
|
||||
set_buffer_uptodate(bh);
|
||||
clear_buffer_dirty(bh);
|
||||
clear_buffer_delay(bh);
|
||||
clear_buffer_nilfs_volatile(bh);
|
||||
}
|
||||
brelse(bh); /* for b_assoc_buffers */
|
||||
}
|
||||
} while ((bh = bh->b_this_page) != head);
|
||||
|
||||
__nilfs_end_page_io(page, err);
|
||||
page_cache_release(page);
|
||||
if (!err) {
|
||||
if (!nilfs_page_buffers_clean(page))
|
||||
__set_page_dirty_nobuffers(page);
|
||||
ClearPageError(page);
|
||||
} else {
|
||||
__set_page_dirty_nobuffers(page);
|
||||
SetPageError(page);
|
||||
}
|
||||
|
||||
end_page_writeback(page);
|
||||
}
|
||||
|
||||
static void nilfs_abort_logs(struct list_head *logs, struct page *failed_page,
|
||||
int err)
|
||||
static void nilfs_abort_logs(struct list_head *logs, int err)
|
||||
{
|
||||
struct nilfs_segment_buffer *segbuf;
|
||||
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,
|
|||
}
|
||||
if (bh->b_page != fs_page) {
|
||||
nilfs_end_page_io(fs_page, err);
|
||||
if (fs_page && fs_page == failed_page)
|
||||
return;
|
||||
fs_page = bh->b_page;
|
||||
}
|
||||
}
|
||||
|
@ -1821,12 +1710,11 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
|
|||
|
||||
list_splice_tail_init(&sci->sc_write_logs, &logs);
|
||||
ret = nilfs_wait_on_logs(&logs);
|
||||
nilfs_abort_logs(&logs, NULL, ret ? : err);
|
||||
nilfs_abort_logs(&logs, ret ? : err);
|
||||
|
||||
list_splice_tail_init(&sci->sc_segbufs, &logs);
|
||||
nilfs_cancel_segusage(&logs, nilfs->ns_sufile);
|
||||
nilfs_free_incomplete_logs(&logs, nilfs);
|
||||
nilfs_clear_copied_buffers(&sci->sc_copied_buffers, err);
|
||||
|
||||
if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
|
||||
ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile,
|
||||
|
@ -1920,8 +1808,6 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
|
|||
|
||||
nilfs_end_page_io(fs_page, 0);
|
||||
|
||||
nilfs_clear_copied_buffers(&sci->sc_copied_buffers, 0);
|
||||
|
||||
nilfs_drop_collected_inodes(&sci->sc_dirty_files);
|
||||
|
||||
if (nilfs_doing_gc())
|
||||
|
@ -1979,7 +1865,7 @@ static int nilfs_segctor_collect_dirty_files(struct nilfs_sc_info *sci,
|
|||
"failed to get inode block.\n");
|
||||
return err;
|
||||
}
|
||||
nilfs_mdt_mark_buffer_dirty(ibh);
|
||||
mark_buffer_dirty(ibh);
|
||||
nilfs_mdt_mark_dirty(ifile);
|
||||
spin_lock(&nilfs->ns_inode_lock);
|
||||
if (likely(!ii->i_bh))
|
||||
|
@ -1991,8 +1877,7 @@ static int nilfs_segctor_collect_dirty_files(struct nilfs_sc_info *sci,
|
|||
|
||||
clear_bit(NILFS_I_QUEUED, &ii->i_state);
|
||||
set_bit(NILFS_I_BUSY, &ii->i_state);
|
||||
list_del(&ii->i_dirty);
|
||||
list_add_tail(&ii->i_dirty, &sci->sc_dirty_files);
|
||||
list_move_tail(&ii->i_dirty, &sci->sc_dirty_files);
|
||||
}
|
||||
spin_unlock(&nilfs->ns_inode_lock);
|
||||
|
||||
|
@ -2014,8 +1899,7 @@ static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci,
|
|||
clear_bit(NILFS_I_BUSY, &ii->i_state);
|
||||
brelse(ii->i_bh);
|
||||
ii->i_bh = NULL;
|
||||
list_del(&ii->i_dirty);
|
||||
list_add_tail(&ii->i_dirty, &ti->ti_garbage);
|
||||
list_move_tail(&ii->i_dirty, &ti->ti_garbage);
|
||||
}
|
||||
spin_unlock(&nilfs->ns_inode_lock);
|
||||
}
|
||||
|
@ -2026,7 +1910,6 @@ static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci,
|
|||
static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
|
||||
{
|
||||
struct the_nilfs *nilfs = sci->sc_super->s_fs_info;
|
||||
struct page *failed_page;
|
||||
int err;
|
||||
|
||||
sci->sc_stage.scnt = NILFS_ST_INIT;
|
||||
|
@ -2081,11 +1964,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
|
|||
nilfs_segctor_update_segusage(sci, nilfs->ns_sufile);
|
||||
|
||||
/* Write partial segments */
|
||||
err = nilfs_segctor_prepare_write(sci, &failed_page);
|
||||
if (err) {
|
||||
nilfs_abort_logs(&sci->sc_segbufs, failed_page, err);
|
||||
goto failed_to_write;
|
||||
}
|
||||
nilfs_segctor_prepare_write(sci);
|
||||
|
||||
nilfs_add_checksums_on_logs(&sci->sc_segbufs,
|
||||
nilfs->ns_crc_seed);
|
||||
|
@ -2687,7 +2566,6 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb,
|
|||
INIT_LIST_HEAD(&sci->sc_segbufs);
|
||||
INIT_LIST_HEAD(&sci->sc_write_logs);
|
||||
INIT_LIST_HEAD(&sci->sc_gc_inodes);
|
||||
INIT_LIST_HEAD(&sci->sc_copied_buffers);
|
||||
init_timer(&sci->sc_timer);
|
||||
|
||||
sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT;
|
||||
|
@ -2741,8 +2619,6 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
|
|||
if (flag || !nilfs_segctor_confirm(sci))
|
||||
nilfs_segctor_write_out(sci);
|
||||
|
||||
WARN_ON(!list_empty(&sci->sc_copied_buffers));
|
||||
|
||||
if (!list_empty(&sci->sc_dirty_files)) {
|
||||
nilfs_warning(sci->sc_super, __func__,
|
||||
"dirty file(s) after the final construction\n");
|
||||
|
|
|
@ -92,7 +92,6 @@ struct nilfs_segsum_pointer {
|
|||
* @sc_nblk_inc: Block count of current generation
|
||||
* @sc_dirty_files: List of files to be written
|
||||
* @sc_gc_inodes: List of GC inodes having blocks to be written
|
||||
* @sc_copied_buffers: List of copied buffers (buffer heads) to freeze data
|
||||
* @sc_freesegs: array of segment numbers to be freed
|
||||
* @sc_nfreesegs: number of segments on @sc_freesegs
|
||||
* @sc_dsync_inode: inode whose data pages are written for a sync operation
|
||||
|
@ -136,7 +135,6 @@ struct nilfs_sc_info {
|
|||
|
||||
struct list_head sc_dirty_files;
|
||||
struct list_head sc_gc_inodes;
|
||||
struct list_head sc_copied_buffers;
|
||||
|
||||
__u64 *sc_freesegs;
|
||||
size_t sc_nfreesegs;
|
||||
|
|
|
@ -33,7 +33,9 @@
|
|||
|
||||
struct nilfs_sufile_info {
|
||||
struct nilfs_mdt_info mi;
|
||||
unsigned long ncleansegs;
|
||||
unsigned long ncleansegs;/* number of clean segments */
|
||||
__u64 allocmin; /* lower limit of allocatable segment range */
|
||||
__u64 allocmax; /* upper limit of allocatable segment range */
|
||||
};
|
||||
|
||||
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,
|
|||
create, NULL, bhp);
|
||||
}
|
||||
|
||||
static int nilfs_sufile_delete_segment_usage_block(struct inode *sufile,
|
||||
__u64 segnum)
|
||||
{
|
||||
return nilfs_mdt_delete_block(sufile,
|
||||
nilfs_sufile_get_blkoff(sufile, segnum));
|
||||
}
|
||||
|
||||
static void nilfs_sufile_mod_counter(struct buffer_head *header_bh,
|
||||
u64 ncleanadd, u64 ndirtyadd)
|
||||
{
|
||||
|
@ -108,7 +117,7 @@ static void nilfs_sufile_mod_counter(struct buffer_head *header_bh,
|
|||
le64_add_cpu(&header->sh_ndirtysegs, ndirtyadd);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
|
||||
nilfs_mdt_mark_buffer_dirty(header_bh);
|
||||
mark_buffer_dirty(header_bh);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -247,6 +256,35 @@ int nilfs_sufile_update(struct inode *sufile, __u64 segnum, int create,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_sufile_set_alloc_range - limit range of segment to be allocated
|
||||
* @sufile: inode of segment usage file
|
||||
* @start: minimum segment number of allocatable region (inclusive)
|
||||
* @end: maximum segment number of allocatable region (inclusive)
|
||||
*
|
||||
* Return Value: On success, 0 is returned. On error, one of the
|
||||
* following negative error codes is returned.
|
||||
*
|
||||
* %-ERANGE - invalid segment region
|
||||
*/
|
||||
int nilfs_sufile_set_alloc_range(struct inode *sufile, __u64 start, __u64 end)
|
||||
{
|
||||
struct nilfs_sufile_info *sui = NILFS_SUI(sufile);
|
||||
__u64 nsegs;
|
||||
int ret = -ERANGE;
|
||||
|
||||
down_write(&NILFS_MDT(sufile)->mi_sem);
|
||||
nsegs = nilfs_sufile_get_nsegments(sufile);
|
||||
|
||||
if (start <= end && end < nsegs) {
|
||||
sui->allocmin = start;
|
||||
sui->allocmax = end;
|
||||
ret = 0;
|
||||
}
|
||||
up_write(&NILFS_MDT(sufile)->mi_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_sufile_alloc - allocate a segment
|
||||
* @sufile: inode of segment usage file
|
||||
|
@ -269,11 +307,12 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump)
|
|||
struct buffer_head *header_bh, *su_bh;
|
||||
struct nilfs_sufile_header *header;
|
||||
struct nilfs_segment_usage *su;
|
||||
struct nilfs_sufile_info *sui = NILFS_SUI(sufile);
|
||||
size_t susz = NILFS_MDT(sufile)->mi_entry_size;
|
||||
__u64 segnum, maxsegnum, last_alloc;
|
||||
void *kaddr;
|
||||
unsigned long nsegments, ncleansegs, nsus;
|
||||
int ret, i, j;
|
||||
unsigned long nsegments, ncleansegs, nsus, cnt;
|
||||
int ret, j;
|
||||
|
||||
down_write(&NILFS_MDT(sufile)->mi_sem);
|
||||
|
||||
|
@ -287,13 +326,31 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump)
|
|||
kunmap_atomic(kaddr, KM_USER0);
|
||||
|
||||
nsegments = nilfs_sufile_get_nsegments(sufile);
|
||||
maxsegnum = sui->allocmax;
|
||||
segnum = last_alloc + 1;
|
||||
maxsegnum = nsegments - 1;
|
||||
for (i = 0; i < nsegments; i += nsus) {
|
||||
if (segnum >= nsegments) {
|
||||
/* wrap around */
|
||||
segnum = 0;
|
||||
maxsegnum = last_alloc;
|
||||
if (segnum < sui->allocmin || segnum > sui->allocmax)
|
||||
segnum = sui->allocmin;
|
||||
|
||||
for (cnt = 0; cnt < nsegments; cnt += nsus) {
|
||||
if (segnum > maxsegnum) {
|
||||
if (cnt < sui->allocmax - sui->allocmin + 1) {
|
||||
/*
|
||||
* wrap around in the limited region.
|
||||
* if allocation started from
|
||||
* sui->allocmin, this never happens.
|
||||
*/
|
||||
segnum = sui->allocmin;
|
||||
maxsegnum = last_alloc;
|
||||
} else if (segnum > sui->allocmin &&
|
||||
sui->allocmax + 1 < nsegments) {
|
||||
segnum = sui->allocmax + 1;
|
||||
maxsegnum = nsegments - 1;
|
||||
} else if (sui->allocmin > 0) {
|
||||
segnum = 0;
|
||||
maxsegnum = sui->allocmin - 1;
|
||||
} else {
|
||||
break; /* never happens */
|
||||
}
|
||||
}
|
||||
ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 1,
|
||||
&su_bh);
|
||||
|
@ -319,9 +376,9 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump)
|
|||
header->sh_last_alloc = cpu_to_le64(segnum);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
|
||||
NILFS_SUI(sufile)->ncleansegs--;
|
||||
nilfs_mdt_mark_buffer_dirty(header_bh);
|
||||
nilfs_mdt_mark_buffer_dirty(su_bh);
|
||||
sui->ncleansegs--;
|
||||
mark_buffer_dirty(header_bh);
|
||||
mark_buffer_dirty(su_bh);
|
||||
nilfs_mdt_mark_dirty(sufile);
|
||||
brelse(su_bh);
|
||||
*segnump = segnum;
|
||||
|
@ -364,7 +421,7 @@ void nilfs_sufile_do_cancel_free(struct inode *sufile, __u64 segnum,
|
|||
nilfs_sufile_mod_counter(header_bh, -1, 1);
|
||||
NILFS_SUI(sufile)->ncleansegs--;
|
||||
|
||||
nilfs_mdt_mark_buffer_dirty(su_bh);
|
||||
mark_buffer_dirty(su_bh);
|
||||
nilfs_mdt_mark_dirty(sufile);
|
||||
}
|
||||
|
||||
|
@ -395,7 +452,7 @@ void nilfs_sufile_do_scrap(struct inode *sufile, __u64 segnum,
|
|||
nilfs_sufile_mod_counter(header_bh, clean ? (u64)-1 : 0, dirty ? 0 : 1);
|
||||
NILFS_SUI(sufile)->ncleansegs -= clean;
|
||||
|
||||
nilfs_mdt_mark_buffer_dirty(su_bh);
|
||||
mark_buffer_dirty(su_bh);
|
||||
nilfs_mdt_mark_dirty(sufile);
|
||||
}
|
||||
|
||||
|
@ -421,7 +478,7 @@ void nilfs_sufile_do_free(struct inode *sufile, __u64 segnum,
|
|||
sudirty = nilfs_segment_usage_dirty(su);
|
||||
nilfs_segment_usage_set_clean(su);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
nilfs_mdt_mark_buffer_dirty(su_bh);
|
||||
mark_buffer_dirty(su_bh);
|
||||
|
||||
nilfs_sufile_mod_counter(header_bh, 1, sudirty ? (u64)-1 : 0);
|
||||
NILFS_SUI(sufile)->ncleansegs++;
|
||||
|
@ -441,7 +498,7 @@ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
|
|||
|
||||
ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh);
|
||||
if (!ret) {
|
||||
nilfs_mdt_mark_buffer_dirty(bh);
|
||||
mark_buffer_dirty(bh);
|
||||
nilfs_mdt_mark_dirty(sufile);
|
||||
brelse(bh);
|
||||
}
|
||||
|
@ -476,7 +533,7 @@ int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
|
|||
su->su_nblocks = cpu_to_le32(nblocks);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
|
||||
nilfs_mdt_mark_buffer_dirty(bh);
|
||||
mark_buffer_dirty(bh);
|
||||
nilfs_mdt_mark_dirty(sufile);
|
||||
brelse(bh);
|
||||
|
||||
|
@ -505,7 +562,7 @@ int nilfs_sufile_get_stat(struct inode *sufile, struct nilfs_sustat *sustat)
|
|||
{
|
||||
struct buffer_head *header_bh;
|
||||
struct nilfs_sufile_header *header;
|
||||
struct the_nilfs *nilfs = NILFS_I_NILFS(sufile);
|
||||
struct the_nilfs *nilfs = sufile->i_sb->s_fs_info;
|
||||
void *kaddr;
|
||||
int ret;
|
||||
|
||||
|
@ -555,10 +612,182 @@ void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum,
|
|||
nilfs_sufile_mod_counter(header_bh, -1, 0);
|
||||
NILFS_SUI(sufile)->ncleansegs--;
|
||||
}
|
||||
nilfs_mdt_mark_buffer_dirty(su_bh);
|
||||
mark_buffer_dirty(su_bh);
|
||||
nilfs_mdt_mark_dirty(sufile);
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_sufile_truncate_range - truncate range of segment array
|
||||
* @sufile: inode of segment usage file
|
||||
* @start: start segment number (inclusive)
|
||||
* @end: end segment number (inclusive)
|
||||
*
|
||||
* Return Value: On success, 0 is returned. On error, one of the
|
||||
* following negative error codes is returned.
|
||||
*
|
||||
* %-EIO - I/O error.
|
||||
*
|
||||
* %-ENOMEM - Insufficient amount of memory available.
|
||||
*
|
||||
* %-EINVAL - Invalid number of segments specified
|
||||
*
|
||||
* %-EBUSY - Dirty or active segments are present in the range
|
||||
*/
|
||||
static int nilfs_sufile_truncate_range(struct inode *sufile,
|
||||
__u64 start, __u64 end)
|
||||
{
|
||||
struct the_nilfs *nilfs = sufile->i_sb->s_fs_info;
|
||||
struct buffer_head *header_bh;
|
||||
struct buffer_head *su_bh;
|
||||
struct nilfs_segment_usage *su, *su2;
|
||||
size_t susz = NILFS_MDT(sufile)->mi_entry_size;
|
||||
unsigned long segusages_per_block;
|
||||
unsigned long nsegs, ncleaned;
|
||||
__u64 segnum;
|
||||
void *kaddr;
|
||||
ssize_t n, nc;
|
||||
int ret;
|
||||
int j;
|
||||
|
||||
nsegs = nilfs_sufile_get_nsegments(sufile);
|
||||
|
||||
ret = -EINVAL;
|
||||
if (start > end || start >= nsegs)
|
||||
goto out;
|
||||
|
||||
ret = nilfs_sufile_get_header_block(sufile, &header_bh);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
segusages_per_block = nilfs_sufile_segment_usages_per_block(sufile);
|
||||
ncleaned = 0;
|
||||
|
||||
for (segnum = start; segnum <= end; segnum += n) {
|
||||
n = min_t(unsigned long,
|
||||
segusages_per_block -
|
||||
nilfs_sufile_get_offset(sufile, segnum),
|
||||
end - segnum + 1);
|
||||
ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0,
|
||||
&su_bh);
|
||||
if (ret < 0) {
|
||||
if (ret != -ENOENT)
|
||||
goto out_header;
|
||||
/* hole */
|
||||
continue;
|
||||
}
|
||||
kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
|
||||
su = nilfs_sufile_block_get_segment_usage(
|
||||
sufile, segnum, su_bh, kaddr);
|
||||
su2 = su;
|
||||
for (j = 0; j < n; j++, su = (void *)su + susz) {
|
||||
if ((le32_to_cpu(su->su_flags) &
|
||||
~(1UL << NILFS_SEGMENT_USAGE_ERROR)) ||
|
||||
nilfs_segment_is_active(nilfs, segnum + j)) {
|
||||
ret = -EBUSY;
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
brelse(su_bh);
|
||||
goto out_header;
|
||||
}
|
||||
}
|
||||
nc = 0;
|
||||
for (su = su2, j = 0; j < n; j++, su = (void *)su + susz) {
|
||||
if (nilfs_segment_usage_error(su)) {
|
||||
nilfs_segment_usage_set_clean(su);
|
||||
nc++;
|
||||
}
|
||||
}
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
if (nc > 0) {
|
||||
mark_buffer_dirty(su_bh);
|
||||
ncleaned += nc;
|
||||
}
|
||||
brelse(su_bh);
|
||||
|
||||
if (n == segusages_per_block) {
|
||||
/* make hole */
|
||||
nilfs_sufile_delete_segment_usage_block(sufile, segnum);
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
out_header:
|
||||
if (ncleaned > 0) {
|
||||
NILFS_SUI(sufile)->ncleansegs += ncleaned;
|
||||
nilfs_sufile_mod_counter(header_bh, ncleaned, 0);
|
||||
nilfs_mdt_mark_dirty(sufile);
|
||||
}
|
||||
brelse(header_bh);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_sufile_resize - resize segment array
|
||||
* @sufile: inode of segment usage file
|
||||
* @newnsegs: new number of segments
|
||||
*
|
||||
* Return Value: On success, 0 is returned. On error, one of the
|
||||
* following negative error codes is returned.
|
||||
*
|
||||
* %-EIO - I/O error.
|
||||
*
|
||||
* %-ENOMEM - Insufficient amount of memory available.
|
||||
*
|
||||
* %-ENOSPC - Enough free space is not left for shrinking
|
||||
*
|
||||
* %-EBUSY - Dirty or active segments exist in the region to be truncated
|
||||
*/
|
||||
int nilfs_sufile_resize(struct inode *sufile, __u64 newnsegs)
|
||||
{
|
||||
struct the_nilfs *nilfs = sufile->i_sb->s_fs_info;
|
||||
struct buffer_head *header_bh;
|
||||
struct nilfs_sufile_header *header;
|
||||
struct nilfs_sufile_info *sui = NILFS_SUI(sufile);
|
||||
void *kaddr;
|
||||
unsigned long nsegs, nrsvsegs;
|
||||
int ret = 0;
|
||||
|
||||
down_write(&NILFS_MDT(sufile)->mi_sem);
|
||||
|
||||
nsegs = nilfs_sufile_get_nsegments(sufile);
|
||||
if (nsegs == newnsegs)
|
||||
goto out;
|
||||
|
||||
ret = -ENOSPC;
|
||||
nrsvsegs = nilfs_nrsvsegs(nilfs, newnsegs);
|
||||
if (newnsegs < nsegs && nsegs - newnsegs + nrsvsegs > sui->ncleansegs)
|
||||
goto out;
|
||||
|
||||
ret = nilfs_sufile_get_header_block(sufile, &header_bh);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
if (newnsegs > nsegs) {
|
||||
sui->ncleansegs += newnsegs - nsegs;
|
||||
} else /* newnsegs < nsegs */ {
|
||||
ret = nilfs_sufile_truncate_range(sufile, newnsegs, nsegs - 1);
|
||||
if (ret < 0)
|
||||
goto out_header;
|
||||
|
||||
sui->ncleansegs -= nsegs - newnsegs;
|
||||
}
|
||||
|
||||
kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
|
||||
header = kaddr + bh_offset(header_bh);
|
||||
header->sh_ncleansegs = cpu_to_le64(sui->ncleansegs);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
|
||||
mark_buffer_dirty(header_bh);
|
||||
nilfs_mdt_mark_dirty(sufile);
|
||||
nilfs_set_nsegments(nilfs, newnsegs);
|
||||
|
||||
out_header:
|
||||
brelse(header_bh);
|
||||
out:
|
||||
up_write(&NILFS_MDT(sufile)->mi_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_sufile_get_suinfo -
|
||||
* @sufile: inode of segment usage file
|
||||
|
@ -583,7 +812,7 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf,
|
|||
struct nilfs_segment_usage *su;
|
||||
struct nilfs_suinfo *si = buf;
|
||||
size_t susz = NILFS_MDT(sufile)->mi_entry_size;
|
||||
struct the_nilfs *nilfs = NILFS_I_NILFS(sufile);
|
||||
struct the_nilfs *nilfs = sufile->i_sb->s_fs_info;
|
||||
void *kaddr;
|
||||
unsigned long nsegs, segusages_per_block;
|
||||
ssize_t n;
|
||||
|
@ -679,6 +908,9 @@ int nilfs_sufile_read(struct super_block *sb, size_t susize,
|
|||
kunmap_atomic(kaddr, KM_USER0);
|
||||
brelse(header_bh);
|
||||
|
||||
sui->allocmax = nilfs_sufile_get_nsegments(sufile) - 1;
|
||||
sui->allocmin = 0;
|
||||
|
||||
unlock_new_inode(sufile);
|
||||
out:
|
||||
*inodep = sufile;
|
||||
|
|
|
@ -31,11 +31,12 @@
|
|||
|
||||
static inline unsigned long nilfs_sufile_get_nsegments(struct inode *sufile)
|
||||
{
|
||||
return NILFS_I_NILFS(sufile)->ns_nsegments;
|
||||
return ((struct the_nilfs *)sufile->i_sb->s_fs_info)->ns_nsegments;
|
||||
}
|
||||
|
||||
unsigned long nilfs_sufile_get_ncleansegs(struct inode *sufile);
|
||||
|
||||
int nilfs_sufile_set_alloc_range(struct inode *sufile, __u64 start, __u64 end);
|
||||
int nilfs_sufile_alloc(struct inode *, __u64 *);
|
||||
int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum);
|
||||
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 *,
|
|||
void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *,
|
||||
struct buffer_head *);
|
||||
|
||||
int nilfs_sufile_resize(struct inode *sufile, __u64 newnsegs);
|
||||
int nilfs_sufile_read(struct super_block *sb, size_t susize,
|
||||
struct nilfs_inode *raw_inode, struct inode **inodep);
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "btnode.h"
|
||||
#include "page.h"
|
||||
#include "cpfile.h"
|
||||
#include "sufile.h" /* nilfs_sufile_resize(), nilfs_sufile_set_alloc_range() */
|
||||
#include "ifile.h"
|
||||
#include "dat.h"
|
||||
#include "segment.h"
|
||||
|
@ -165,7 +166,7 @@ struct inode *nilfs_alloc_inode(struct super_block *sb)
|
|||
ii->i_state = 0;
|
||||
ii->i_cno = 0;
|
||||
ii->vfs_inode.i_version = 1;
|
||||
nilfs_btnode_cache_init(&ii->i_btnode_cache, sb->s_bdi);
|
||||
nilfs_mapping_init(&ii->i_btnode_cache, &ii->vfs_inode, sb->s_bdi);
|
||||
return &ii->vfs_inode;
|
||||
}
|
||||
|
||||
|
@ -347,6 +348,134 @@ int nilfs_cleanup_super(struct super_block *sb)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_move_2nd_super - relocate secondary super block
|
||||
* @sb: super block instance
|
||||
* @sb2off: new offset of the secondary super block (in bytes)
|
||||
*/
|
||||
static int nilfs_move_2nd_super(struct super_block *sb, loff_t sb2off)
|
||||
{
|
||||
struct the_nilfs *nilfs = sb->s_fs_info;
|
||||
struct buffer_head *nsbh;
|
||||
struct nilfs_super_block *nsbp;
|
||||
sector_t blocknr, newblocknr;
|
||||
unsigned long offset;
|
||||
int sb2i = -1; /* array index of the secondary superblock */
|
||||
int ret = 0;
|
||||
|
||||
/* nilfs->ns_sem must be locked by the caller. */
|
||||
if (nilfs->ns_sbh[1] &&
|
||||
nilfs->ns_sbh[1]->b_blocknr > nilfs->ns_first_data_block) {
|
||||
sb2i = 1;
|
||||
blocknr = nilfs->ns_sbh[1]->b_blocknr;
|
||||
} else if (nilfs->ns_sbh[0]->b_blocknr > nilfs->ns_first_data_block) {
|
||||
sb2i = 0;
|
||||
blocknr = nilfs->ns_sbh[0]->b_blocknr;
|
||||
}
|
||||
if (sb2i >= 0 && (u64)blocknr << nilfs->ns_blocksize_bits == sb2off)
|
||||
goto out; /* super block location is unchanged */
|
||||
|
||||
/* Get new super block buffer */
|
||||
newblocknr = sb2off >> nilfs->ns_blocksize_bits;
|
||||
offset = sb2off & (nilfs->ns_blocksize - 1);
|
||||
nsbh = sb_getblk(sb, newblocknr);
|
||||
if (!nsbh) {
|
||||
printk(KERN_WARNING
|
||||
"NILFS warning: unable to move secondary superblock "
|
||||
"to block %llu\n", (unsigned long long)newblocknr);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
nsbp = (void *)nsbh->b_data + offset;
|
||||
memset(nsbp, 0, nilfs->ns_blocksize);
|
||||
|
||||
if (sb2i >= 0) {
|
||||
memcpy(nsbp, nilfs->ns_sbp[sb2i], nilfs->ns_sbsize);
|
||||
brelse(nilfs->ns_sbh[sb2i]);
|
||||
nilfs->ns_sbh[sb2i] = nsbh;
|
||||
nilfs->ns_sbp[sb2i] = nsbp;
|
||||
} else if (nilfs->ns_sbh[0]->b_blocknr < nilfs->ns_first_data_block) {
|
||||
/* secondary super block will be restored to index 1 */
|
||||
nilfs->ns_sbh[1] = nsbh;
|
||||
nilfs->ns_sbp[1] = nsbp;
|
||||
} else {
|
||||
brelse(nsbh);
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_resize_fs - resize the filesystem
|
||||
* @sb: super block instance
|
||||
* @newsize: new size of the filesystem (in bytes)
|
||||
*/
|
||||
int nilfs_resize_fs(struct super_block *sb, __u64 newsize)
|
||||
{
|
||||
struct the_nilfs *nilfs = sb->s_fs_info;
|
||||
struct nilfs_super_block **sbp;
|
||||
__u64 devsize, newnsegs;
|
||||
loff_t sb2off;
|
||||
int ret;
|
||||
|
||||
ret = -ERANGE;
|
||||
devsize = i_size_read(sb->s_bdev->bd_inode);
|
||||
if (newsize > devsize)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Write lock is required to protect some functions depending
|
||||
* on the number of segments, the number of reserved segments,
|
||||
* and so forth.
|
||||
*/
|
||||
down_write(&nilfs->ns_segctor_sem);
|
||||
|
||||
sb2off = NILFS_SB2_OFFSET_BYTES(newsize);
|
||||
newnsegs = sb2off >> nilfs->ns_blocksize_bits;
|
||||
do_div(newnsegs, nilfs->ns_blocks_per_segment);
|
||||
|
||||
ret = nilfs_sufile_resize(nilfs->ns_sufile, newnsegs);
|
||||
up_write(&nilfs->ns_segctor_sem);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = nilfs_construct_segment(sb);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
down_write(&nilfs->ns_sem);
|
||||
nilfs_move_2nd_super(sb, sb2off);
|
||||
ret = -EIO;
|
||||
sbp = nilfs_prepare_super(sb, 0);
|
||||
if (likely(sbp)) {
|
||||
nilfs_set_log_cursor(sbp[0], nilfs);
|
||||
/*
|
||||
* Drop NILFS_RESIZE_FS flag for compatibility with
|
||||
* mount-time resize which may be implemented in a
|
||||
* future release.
|
||||
*/
|
||||
sbp[0]->s_state = cpu_to_le16(le16_to_cpu(sbp[0]->s_state) &
|
||||
~NILFS_RESIZE_FS);
|
||||
sbp[0]->s_dev_size = cpu_to_le64(newsize);
|
||||
sbp[0]->s_nsegments = cpu_to_le64(nilfs->ns_nsegments);
|
||||
if (sbp[1])
|
||||
memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
|
||||
ret = nilfs_commit_super(sb, NILFS_SB_COMMIT_ALL);
|
||||
}
|
||||
up_write(&nilfs->ns_sem);
|
||||
|
||||
/*
|
||||
* Reset the range of allocatable segments last. This order
|
||||
* is important in the case of expansion because the secondary
|
||||
* superblock must be protected from log write until migration
|
||||
* completes.
|
||||
*/
|
||||
if (!ret)
|
||||
nilfs_sufile_set_alloc_range(nilfs->ns_sufile, 0, newnsegs - 1);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void nilfs_put_super(struct super_block *sb)
|
||||
{
|
||||
struct the_nilfs *nilfs = sb->s_fs_info;
|
||||
|
|
|
@ -363,6 +363,24 @@ static unsigned long long nilfs_max_size(unsigned int blkbits)
|
|||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* nilfs_nrsvsegs - calculate the number of reserved segments
|
||||
* @nilfs: nilfs object
|
||||
* @nsegs: total number of segments
|
||||
*/
|
||||
unsigned long nilfs_nrsvsegs(struct the_nilfs *nilfs, unsigned long nsegs)
|
||||
{
|
||||
return max_t(unsigned long, NILFS_MIN_NRSVSEGS,
|
||||
DIV_ROUND_UP(nsegs * nilfs->ns_r_segments_percentage,
|
||||
100));
|
||||
}
|
||||
|
||||
void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs)
|
||||
{
|
||||
nilfs->ns_nsegments = nsegs;
|
||||
nilfs->ns_nrsvsegs = nilfs_nrsvsegs(nilfs, nsegs);
|
||||
}
|
||||
|
||||
static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
|
||||
struct nilfs_super_block *sbp)
|
||||
{
|
||||
|
@ -389,13 +407,9 @@ static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
|
|||
}
|
||||
|
||||
nilfs->ns_first_data_block = le64_to_cpu(sbp->s_first_data_block);
|
||||
nilfs->ns_nsegments = le64_to_cpu(sbp->s_nsegments);
|
||||
nilfs->ns_r_segments_percentage =
|
||||
le32_to_cpu(sbp->s_r_segments_percentage);
|
||||
nilfs->ns_nrsvsegs =
|
||||
max_t(unsigned long, NILFS_MIN_NRSVSEGS,
|
||||
DIV_ROUND_UP(nilfs->ns_nsegments *
|
||||
nilfs->ns_r_segments_percentage, 100));
|
||||
nilfs_set_nsegments(nilfs, le64_to_cpu(sbp->s_nsegments));
|
||||
nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -268,6 +268,8 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev);
|
|||
void destroy_nilfs(struct the_nilfs *nilfs);
|
||||
int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data);
|
||||
int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb);
|
||||
unsigned long nilfs_nrsvsegs(struct the_nilfs *nilfs, unsigned long nsegs);
|
||||
void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs);
|
||||
int nilfs_discard_segments(struct the_nilfs *, __u64 *, size_t);
|
||||
int nilfs_count_free_blocks(struct the_nilfs *, sector_t *);
|
||||
struct nilfs_root *nilfs_lookup_root(struct the_nilfs *nilfs, __u64 cno);
|
||||
|
|
|
@ -107,7 +107,7 @@ struct nilfs_super_root {
|
|||
#define NILFS_SR_DAT_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 0)
|
||||
#define NILFS_SR_CPFILE_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 1)
|
||||
#define NILFS_SR_SUFILE_OFFSET(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 2)
|
||||
#define NILFS_SR_BYTES (sizeof(struct nilfs_super_root))
|
||||
#define NILFS_SR_BYTES(inode_size) NILFS_SR_MDT_OFFSET(inode_size, 3)
|
||||
|
||||
/*
|
||||
* Maximal mount counts
|
||||
|
@ -845,5 +845,7 @@ struct nilfs_bdesc {
|
|||
_IOR(NILFS_IOCTL_IDENT, 0x8A, __u64)
|
||||
#define NILFS_IOCTL_RESIZE \
|
||||
_IOW(NILFS_IOCTL_IDENT, 0x8B, __u64)
|
||||
#define NILFS_IOCTL_SET_ALLOC_RANGE \
|
||||
_IOW(NILFS_IOCTL_IDENT, 0x8C, __u64[2])
|
||||
|
||||
#endif /* _LINUX_NILFS_FS_H */
|
||||
|
|
Loading…
Reference in a new issue