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

Jan Kara jack at suse.cz
Wed Oct 14 05:35:34 PDT 2009


On Tue 13-10-09 16:18:50, Joel Becker wrote:
> 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>
  Thanks for the review.

> > 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?
  Yes, I didn't mean this :) I just compile the tools as static because of
easy testing and I forgot to remove the change...

> > 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.
  OK, good suggestion, it should be possible to wrap quite some code
into common libocfs2 functions. I'll send you an updated patch which
implements needed things in libocfs2.

								Honza
-- 
Jan Kara <jack at suse.cz>
SUSE Labs, CR



More information about the Ocfs2-tools-devel mailing list