[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