Re: [PATCH 4/9] nilfs2: add function to modify su_nlive_blks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 24 Feb 2015 20:01:39 +0100, Andreas Rohner wrote:
> This patch adds a function to modify the su_nlive_blks field of the
> nilfs_segment_usage structure in the SUFILE. By using positive or
> negative integers, it is possible to add and substract any value from
> the su_nlive_blks field.
> 
> The use of a modification cache is optional and by passing a NULL
> pointer the value will be added or subtracted directly. Otherwise it is
> necessary to call nilfs_sufile_flush_nlive_blks() at some point to make
> the modifications persistent.
> 
> The modification cache is useful, because it allows for small values,
> like simple increments and decrements, to be added up before writing
> them to the SUFILE.
> 
> Signed-off-by: Andreas Rohner <andreas.rohner@xxxxxxx>
> ---
>  fs/nilfs2/sufile.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  fs/nilfs2/sufile.h |   5 ++
>  2 files changed, 143 insertions(+)
> 
> diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
> index ae08050..574a77e 100644
> --- a/fs/nilfs2/sufile.c
> +++ b/fs/nilfs2/sufile.c
> @@ -1380,6 +1380,144 @@ static inline int nilfs_sufile_mc_update(struct inode *sufile,
>  }
>  
>  /**
> + * nilfs_sufile_do_flush_nlive_blks - apply modification to su_nlive_blks
> + * @sufile: inode of segment usage file
> + * @mod: modification structure
> + * @header_bh: sufile header block
> + * @su_bh: block containing segment usage of m_segnum in @mod
> + *
> + * Description: nilfs_sufile_do_flush_nlive_blks() is a callback function
> + * used with nilfs_sufile_updatev(), that adds m_value in @mod to
> + * the su_nlive_blks field of the segment usage entry belonging to m_segnum.
> + */
> +static void nilfs_sufile_do_flush_nlive_blks(struct inode *sufile,
> +					     struct nilfs_sufile_mod *mod,
> +					     struct buffer_head *header_bh,
> +					     struct buffer_head *su_bh)
> +{
> +	struct the_nilfs *nilfs = sufile->i_sb->s_fs_info;
> +	struct nilfs_segment_usage *su;
> +	void *kaddr;
> +	__u32 nblocks, nlive_blocks;
> +	__u64 segnum = mod->m_segnum;
> +	__s64 value = mod->m_value;
> +
> +	if (!value)
> +		return;
> +
> +	kaddr = kmap_atomic(su_bh->b_page);
> +
> +	su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
> +	WARN_ON(nilfs_segment_usage_error(su));
> +
> +	nblocks = le32_to_cpu(su->su_nblocks);
> +	nlive_blocks = le32_to_cpu(su->su_nlive_blks);
> +
> +	value += nlive_blocks;
> +	if (value < 0)
> +		value = 0;
> +	else if (value > nblocks)
> +		value = nblocks;
> +
> +	/* do nothing if the value didn't change */
> +	if (value != nlive_blocks) {
> +		su->su_nlive_blks = cpu_to_le32(value);
> +		su->su_nlive_lastmod = cpu_to_le64(nilfs->ns_ctime);

ns_ctime should not be used because it is updated after writing
segment.  get_seconds() should be used.

> +	}
> +
> +	kunmap_atomic(kaddr);
> +
> +	if (value != nlive_blocks) {
> +		mark_buffer_dirty(su_bh);
> +		nilfs_mdt_mark_dirty(sufile);
> +	}
> +}
> +
> +/**
> + * nilfs_sufile_flush_nlive_blks - flush mod cache to su_nlive_blks
> + * @sufile: inode of segment usage file
> + * @mc: modification cache
> + *
> + * Description: nilfs_sufile_flush_nlive_blks() flushes the cached
> + * modifications in @mc, by applying them to the su_nlive_blks field of
> + * the corresponding segment usage entries. @mc can be NULL or empty. If
> + * the sufile extension needed to support su_nlive_blks is not supported the
> + * function will abort without error.
> + *
> + * Return Value: On success, zero is returned.  On error, one of the
> + * following negative error codes is returned.
> + *
> + * %-EIO - I/O error.
> + *
> + * %-ENOMEM - Insufficient amount of memory available.
> + *
> + * %-ENOENT - Given segment usage is in hole block
> + *
> + * %-EINVAL - Invalid segment usage number
> + */
> +int nilfs_sufile_flush_nlive_blks(struct inode *sufile,
> +				  struct nilfs_sufile_mod_cache *mc)
> +{
> +	int ret;
> +
> +	if (!mc || !mc->mc_size || !nilfs_sufile_ext_supported(sufile))
> +		return 0;
> +
> +	ret = nilfs_sufile_mc_flush(sufile, mc,
> +				    nilfs_sufile_do_flush_nlive_blks);
> +
> +	nilfs_sufile_mc_clear(mc);
> +
> +	return ret;
> +}
> +
> +/**
> + * nilfs_sufile_mod_nlive_blks - modifiy su_nlive_blks using mod cache
> + * @sufile: inode of segment usage file
> + * @mc: modification cache
> + * @segnum: segment number
> + * @value: signed value (can be positive and negative)
> + *
> + * Description: nilfs_sufile_mod_nlive_blks() adds @value to the su_nlive_blks
> + * field of the segment usage entry for @segnum. If @mc is not NULL it first
> + * accumulates all modifications in the cache and flushes it if it is full.
> + * Otherwise the change is applied directly.
> + *
> + * Return Value: On success, zero is returned.  On error, one of the
> + * following negative error codes is returned.
> + *
> + * %-EIO - I/O error.
> + *
> + * %-ENOMEM - Insufficient amount of memory available.
> + *
> + * %-ENOENT - Given segment usage is in hole block
> + *
> + * %-EINVAL - Invalid segment usage number
> + */
> +int nilfs_sufile_mod_nlive_blks(struct inode *sufile,
> +				struct nilfs_sufile_mod_cache *mc,
> +				__u64 segnum, __s64 value)
> +{
> +	int ret;
> +
> +	if (!value || !nilfs_sufile_ext_supported(sufile))
> +		return 0;
> +
> +	if (!mc)
> +		return nilfs_sufile_mc_update(sufile, segnum, value,
> +				nilfs_sufile_do_flush_nlive_blks);
> +
> +	if (!nilfs_sufile_mc_add(mc, segnum, value))
> +		return 0;
> +
> +	ret = nilfs_sufile_flush_nlive_blks(sufile, mc);
> +
> +	nilfs_sufile_mc_reset(mc, segnum, value);
> +
> +	return ret;
> +}
> +
> +/**
>   * nilfs_sufile_read - read or get sufile inode
>   * @sb: super block instance
>   * @susize: size of a segment usage entry
> diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h
> index d56498b..ae3c52a 100644
> --- a/fs/nilfs2/sufile.h
> +++ b/fs/nilfs2/sufile.h
> @@ -195,4 +195,9 @@ static inline void nilfs_sufile_mc_destroy(struct nilfs_sufile_mod_cache *mc)
>  	}
>  }
>  
> +int nilfs_sufile_flush_nlive_blks(struct inode *,
> +				  struct nilfs_sufile_mod_cache *);
> +int nilfs_sufile_mod_nlive_blks(struct inode *, struct nilfs_sufile_mod_cache *,
> +				__u64, __s64);
> +

Please add variable names to arguments of new declarations.
(You don't have to add variable names to unrelated declarations)

Regards,
Ryusuke Konishi

>  #endif	/* _NILFS_SUFILE_H */
> -- 
> 2.3.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-nilfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Filesystem Development]     [Linux BTRFS]     [Linux CIFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux