diff options
Diffstat (limited to 'fs/nilfs2/segment.c')
| -rw-r--r-- | fs/nilfs2/segment.c | 121 | 
1 files changed, 42 insertions, 79 deletions
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 2bfb08052d39..aa5290cb7467 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -880,76 +880,6 @@ static void nilfs_segctor_clear_metadata_dirty(struct nilfs_sc_info *sci)  	nilfs_mdt_clear_dirty(nilfs->ns_dat);  } -static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci) -{ -	struct the_nilfs *nilfs = sci->sc_super->s_fs_info; -	struct buffer_head *bh_cp; -	struct nilfs_checkpoint *raw_cp; -	int err; - -	/* XXX: this interface will be changed */ -	err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, 1, -					  &raw_cp, &bh_cp); -	if (likely(!err)) { -		/* -		 * The following code is duplicated with cpfile.  But, it is -		 * needed to collect the checkpoint even if it was not newly -		 * created. -		 */ -		mark_buffer_dirty(bh_cp); -		nilfs_mdt_mark_dirty(nilfs->ns_cpfile); -		nilfs_cpfile_put_checkpoint( -			nilfs->ns_cpfile, nilfs->ns_cno, bh_cp); -	} else if (err == -EINVAL || err == -ENOENT) { -		nilfs_error(sci->sc_super, -			    "checkpoint creation failed due to metadata corruption."); -		err = -EIO; -	} -	return err; -} - -static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci) -{ -	struct the_nilfs *nilfs = sci->sc_super->s_fs_info; -	struct buffer_head *bh_cp; -	struct nilfs_checkpoint *raw_cp; -	int err; - -	err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, 0, -					  &raw_cp, &bh_cp); -	if (unlikely(err)) { -		if (err == -EINVAL || err == -ENOENT) { -			nilfs_error(sci->sc_super, -				    "checkpoint finalization failed due to metadata corruption."); -			err = -EIO; -		} -		goto failed_ibh; -	} -	raw_cp->cp_snapshot_list.ssl_next = 0; -	raw_cp->cp_snapshot_list.ssl_prev = 0; -	raw_cp->cp_inodes_count = -		cpu_to_le64(atomic64_read(&sci->sc_root->inodes_count)); -	raw_cp->cp_blocks_count = -		cpu_to_le64(atomic64_read(&sci->sc_root->blocks_count)); -	raw_cp->cp_nblk_inc = -		cpu_to_le64(sci->sc_nblk_inc + sci->sc_nblk_this_inc); -	raw_cp->cp_create = cpu_to_le64(sci->sc_seg_ctime); -	raw_cp->cp_cno = cpu_to_le64(nilfs->ns_cno); - -	if (test_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags)) -		nilfs_checkpoint_clear_minor(raw_cp); -	else -		nilfs_checkpoint_set_minor(raw_cp); - -	nilfs_write_inode_common(sci->sc_root->ifile, -				 &raw_cp->cp_ifile_inode, 1); -	nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, bh_cp); -	return 0; - - failed_ibh: -	return err; -} -  static void nilfs_fill_in_file_bmap(struct inode *ifile,  				    struct nilfs_inode_info *ii) @@ -963,7 +893,7 @@ static void nilfs_fill_in_file_bmap(struct inode *ifile,  		raw_inode = nilfs_ifile_map_inode(ifile, ii->vfs_inode.i_ino,  						  ibh);  		nilfs_bmap_write(ii->i_bmap, raw_inode); -		nilfs_ifile_unmap_inode(ifile, ii->vfs_inode.i_ino, ibh); +		nilfs_ifile_unmap_inode(raw_inode);  	}  } @@ -977,6 +907,33 @@ static void nilfs_segctor_fill_in_file_bmap(struct nilfs_sc_info *sci)  	}  } +/** + * nilfs_write_root_mdt_inode - export root metadata inode information to + *                              the on-disk inode + * @inode:     inode object of the root metadata file + * @raw_inode: on-disk inode + * + * nilfs_write_root_mdt_inode() writes inode information and bmap data of + * @inode to the inode area of the metadata file allocated on the super root + * block created to finalize the log.  Since super root blocks are configured + * each time, this function zero-fills the unused area of @raw_inode. + */ +static void nilfs_write_root_mdt_inode(struct inode *inode, +				       struct nilfs_inode *raw_inode) +{ +	struct the_nilfs *nilfs = inode->i_sb->s_fs_info; + +	nilfs_write_inode_common(inode, raw_inode); + +	/* zero-fill unused portion of raw_inode */ +	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)); + +	nilfs_bmap_write(NILFS_I(inode)->i_bmap, raw_inode); +} +  static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci,  					     struct the_nilfs *nilfs)  { @@ -998,12 +955,13 @@ static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci,  			      nilfs->ns_nongc_ctime : sci->sc_seg_ctime);  	raw_sr->sr_flags = 0; -	nilfs_write_inode_common(nilfs->ns_dat, (void *)raw_sr + -				 NILFS_SR_DAT_OFFSET(isz), 1); -	nilfs_write_inode_common(nilfs->ns_cpfile, (void *)raw_sr + -				 NILFS_SR_CPFILE_OFFSET(isz), 1); -	nilfs_write_inode_common(nilfs->ns_sufile, (void *)raw_sr + -				 NILFS_SR_SUFILE_OFFSET(isz), 1); +	nilfs_write_root_mdt_inode(nilfs->ns_dat, (void *)raw_sr + +				   NILFS_SR_DAT_OFFSET(isz)); +	nilfs_write_root_mdt_inode(nilfs->ns_cpfile, (void *)raw_sr + +				   NILFS_SR_CPFILE_OFFSET(isz)); +	nilfs_write_root_mdt_inode(nilfs->ns_sufile, (void *)raw_sr + +				   NILFS_SR_SUFILE_OFFSET(isz)); +  	memset((void *)raw_sr + srsz, 0, nilfs->ns_blocksize - srsz);  	set_buffer_uptodate(bh_sr);  	unlock_buffer(bh_sr); @@ -1230,7 +1188,8 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)  			break;  		nilfs_sc_cstage_inc(sci);  		/* Creating a checkpoint */ -		err = nilfs_segctor_create_checkpoint(sci); +		err = nilfs_cpfile_create_checkpoint(nilfs->ns_cpfile, +						     nilfs->ns_cno);  		if (unlikely(err))  			break;  		fallthrough; @@ -2101,7 +2060,11 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)  		if (mode == SC_LSEG_SR &&  		    nilfs_sc_cstage_get(sci) >= NILFS_ST_CPFILE) { -			err = nilfs_segctor_fill_in_checkpoint(sci); +			err = nilfs_cpfile_finalize_checkpoint( +				nilfs->ns_cpfile, nilfs->ns_cno, sci->sc_root, +				sci->sc_nblk_inc + sci->sc_nblk_this_inc, +				sci->sc_seg_ctime, +				!test_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags));  			if (unlikely(err))  				goto failed_to_write;  | 
