[Ocfs2-tools-devel] [PATCH] Quota support for disabling inline-data feature

Joel Becker Joel.Becker at oracle.com
Tue Oct 13 16:18:50 PDT 2009


On Mon, Sep 07, 2009 at 11:28:49PM +0200, Jan Kara wrote:
> When disabling inline-data feature, space occupied by files changes
> and thus we have to update quota information accordingly.

<snip>

> diff --git a/Preamble.make b/Preamble.make
> index b9b4af0..3c34b0b 100644
> --- a/Preamble.make
> +++ b/Preamble.make
> @@ -28,7 +28,7 @@ DIST_RULES =
>  INCLUDES =
>  DEFINES = 
>  
> -CFLAGS += -pipe
> +CFLAGS += -pipe -static

	I don't think you meant to commit this, right?

> diff --git a/tunefs.ocfs2/feature_inline_data.c b/tunefs.ocfs2/feature_inline_data.c
> index 77ddb42..7b880dd 100644
> --- a/tunefs.ocfs2/feature_inline_data.c
> +++ b/tunefs.ocfs2/feature_inline_data.c
> @@ -170,32 +170,125 @@ static void empty_inline_data_context(struct inline_data_context *ctxt)
>  static errcode_t expand_inline_data(ocfs2_filesys *fs,
>  				    struct inline_data_context *ctxt)
>  {
> -	errcode_t ret = 0;
> +	errcode_t ret = 0, err;
>  	struct list_head *pos;
>  	struct inline_data_inode *idi;
>  	ocfs2_cached_inode *ci = NULL;
>  	struct tools_progress *prog;
> +	struct ocfs2_super_block *super = OCFS2_RAW_SB(fs->fs_super);
> +	int has_usrquota, has_grpquota;
> +	ocfs2_quota_hash *usrhash = NULL, *grphash = NULL;
> +	ocfs2_cached_dquot *udquot = NULL, *gdquot = NULL;
> +	uint32_t uid, gid;
> +	long long change;
>  
>  	prog = tools_progress_start("Expanding inline files", "expanding",
>  				    ctxt->more_clusters);
>  	if (!ctxt->prog)
>  		return TUNEFS_ET_NO_MEMORY;
>  
> +	has_usrquota = OCFS2_HAS_RO_COMPAT_FEATURE(super,
> +					OCFS2_FEATURE_RO_COMPAT_USRQUOTA);
> +	has_grpquota = OCFS2_HAS_RO_COMPAT_FEATURE(super,
> +					OCFS2_FEATURE_RO_COMPAT_GRPQUOTA);
> +	if (has_usrquota) {
> +		ret = ocfs2_init_fs_quota_info(fs, USRQUOTA);
> +		if (ret)
> +			goto out;
> +		ret = ocfs2_read_global_quota_info(fs, USRQUOTA);
> +		if (ret)
> +			goto out;
> +		ret = ocfs2_new_quota_hash(&usrhash);
> +		if (ret)
> +			goto out;
> +	}
> +	if (has_grpquota) {
> +		ret = ocfs2_init_fs_quota_info(fs, GRPQUOTA);
> +		if (ret)
> +			goto out;
> +		ret = ocfs2_read_global_quota_info(fs, GRPQUOTA);
> +		if (ret)
> +			goto out;
> +		ret = ocfs2_new_quota_hash(&grphash);
> +		if (ret)
> +			goto out;
> +	}
> +
>  	list_for_each(pos, &ctxt->inodes) {
>  		idi = list_entry(pos, struct inline_data_inode, list);
>  
>  		ret = ocfs2_read_cached_inode(fs, idi->blkno, &ci);
> -		if (!ret) {
> -			ret = ocfs2_convert_inline_data_to_extents(ci);
> -			ocfs2_free_cached_inode(fs, ci);
> -		}
> -
>  		if (ret)
>  			break;
>  
> +		ret = ocfs2_convert_inline_data_to_extents(ci);
> +		if (ret) {
> +			ocfs2_free_cached_inode(fs, ci);
> +			break;
> +		}
> +		if (ci->ci_inode->i_flags & OCFS2_SYSTEM_FL &&
> +		    idi->blkno != super->s_root_blkno) {
> +			ocfs2_free_cached_inode(fs, ci);
> +			goto next;
> +		}
> +		change = ocfs2_clusters_to_bytes(fs,
> +						 ci->ci_inode->i_clusters);
> +		uid = ci->ci_inode->i_uid;
> +		gid = ci->ci_inode->i_gid;
> +		ocfs2_free_cached_inode(fs, ci);
> +
> +		if (has_usrquota) {
> +			ret = ocfs2_find_quota_hash(usrhash, uid, &udquot);
> +			if (ret)
> +				break;
> +			if (!udquot) {
> +				ret = ocfs2_read_dquot(fs, USRQUOTA, uid,
> +						       &udquot);
> +				if (ret)
> +					break;
> +				ret = ocfs2_insert_quota_hash(usrhash, udquot);
> +				if (ret)
> +					break;
> +			}
> +			udquot->d_ddquot.dqb_curspace += change;
> +		}
> +		if (has_grpquota) {
> +			ret = ocfs2_find_quota_hash(grphash, gid, &gdquot);
> +			if (ret)
> +				break;
> +			if (!gdquot) {
> +				ret = ocfs2_read_dquot(fs, GRPQUOTA, gid,
> +						       &gdquot);
> +				if (ret)
> +					break;
> +				ret = ocfs2_insert_quota_hash(grphash, gdquot);
> +				if (ret)
> +					break;
> +			}
> +			gdquot->d_ddquot.dqb_curspace += change;
> +		}
> +next:
>  		tools_progress_step(prog, 1);
>  	}
>  
> +out:
> +	if (usrhash) {
> +		err = ocfs2_write_release_dquots(fs, USRQUOTA, usrhash);
> +		if (!ret)
> +			ret = err;
> +		err = ocfs2_free_quota_hash(usrhash);
> +		if (!ret)
> +			ret = err;
> +	}
> +	if (grphash) {
> +		err = ocfs2_write_release_dquots(fs, GRPQUOTA, grphash);
> +		if (!ret)
> +			ret = err;
> +		err = ocfs2_free_quota_hash(grphash);
> +		if (!ret)
> +			ret = err;
> +	}
> +

	Otherwise this looks good, though I wish there were a way to
wrap up the quota stuff in libocfs2.  Something like:

    ret = ocfs2_init_quota_change(fs, &usrhash, &grphash);
    while (doing stuff) {
        change = stuff;
        ret = ocfs2_apply_quota_change(fs, usrhash, grphash, uid, gid,
                                       change);
    }
    ret = ocfs2_commit_quota_change(fs, usrhash, grphash);

It looks like the mechanics of checking has_usr and reading and
writing dquots is all boilerplate.

Joel
-- 

"I don't know anything about music. In my line you don't have
 to."
        - Elvis Presley

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127



More information about the Ocfs2-tools-devel mailing list