Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 071ec54d authored by Ryusuke Konishi's avatar Ryusuke Konishi
Browse files

nilfs2: move routine to set segment usage into sufile



This adds nilfs_sufile_set_segment_usage() function in sufile to
replace direct access to the sufile metadata in log writer code.

Signed-off-by: default avatarRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
parent 61a189e9
Loading
Loading
Loading
Loading
+10 −22
Original line number Diff line number Diff line
@@ -1457,21 +1457,16 @@ static void nilfs_segctor_update_segusage(struct nilfs_sc_info *sci,
					  struct inode *sufile)
{
	struct nilfs_segment_buffer *segbuf;
	struct buffer_head *bh_su;
	struct nilfs_segment_usage *raw_su;
	unsigned long live_blocks;
	int ret;

	list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
		ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum,
						     &raw_su, &bh_su);
		WARN_ON(ret); /* always succeed because bh_su is dirty */
		live_blocks = segbuf->sb_sum.nblocks +
			(segbuf->sb_pseg_start - segbuf->sb_fseg_start);
		raw_su->su_lastmod = cpu_to_le64(sci->sc_seg_ctime);
		raw_su->su_nblocks = cpu_to_le32(live_blocks);
		nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum,
					       bh_su);
		ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
						     live_blocks,
						     sci->sc_seg_ctime);
		WARN_ON(ret); /* always succeed because the segusage is dirty */
	}
}

@@ -1479,25 +1474,18 @@ static void nilfs_segctor_cancel_segusage(struct nilfs_sc_info *sci,
					  struct inode *sufile)
{
	struct nilfs_segment_buffer *segbuf;
	struct buffer_head *bh_su;
	struct nilfs_segment_usage *raw_su;
	int ret;

	segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
	ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum,
					     &raw_su, &bh_su);
	WARN_ON(ret); /* always succeed because bh_su is dirty */
	raw_su->su_nblocks = cpu_to_le32(segbuf->sb_pseg_start -
					 segbuf->sb_fseg_start);
	nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum, bh_su);
	ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
					     segbuf->sb_pseg_start -
					     segbuf->sb_fseg_start, 0);
	WARN_ON(ret); /* always succeed because the segusage is dirty */

	list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) {
		ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum,
						     &raw_su, &bh_su);
		ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
						     0, 0);
		WARN_ON(ret); /* always succeed */
		raw_su->su_nblocks = 0;
		nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum,
					       bh_su);
	}
}

+37 −0
Original line number Diff line number Diff line
@@ -520,6 +520,43 @@ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
	return ret;
}

/**
 * nilfs_sufile_set_segment_usage - set usage of a segment
 * @sufile: inode of segment usage file
 * @segnum: segment number
 * @nblocks: number of live blocks in the segment
 * @modtime: modification time (option)
 */
int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
				   unsigned long nblocks, time_t modtime)
{
	struct buffer_head *bh;
	struct nilfs_segment_usage *su;
	void *kaddr;
	int ret;

	down_write(&NILFS_MDT(sufile)->mi_sem);
	ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh);
	if (ret < 0)
		goto out_sem;

	kaddr = kmap_atomic(bh->b_page, KM_USER0);
	su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);
	WARN_ON(nilfs_segment_usage_error(su));
	if (modtime)
		su->su_lastmod = cpu_to_le64(modtime);
	su->su_nblocks = cpu_to_le32(nblocks);
	kunmap_atomic(kaddr, KM_USER0);

	nilfs_mdt_mark_buffer_dirty(bh);
	nilfs_mdt_mark_dirty(sufile);
	brelse(bh);

 out_sem:
	up_write(&NILFS_MDT(sufile)->mi_sem);
	return ret;
}

/**
 * nilfs_sufile_get_stat - get segment usage statistics
 * @sufile: inode of segment usage file
+2 −0
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@ int nilfs_sufile_get_segment_usage(struct inode *, __u64,
void nilfs_sufile_put_segment_usage(struct inode *, __u64,
				    struct buffer_head *);
int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum);
int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
				   unsigned long nblocks, time_t modtime);
int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *);
ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned,
				size_t);