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

Jan Kara jack at suse.cz
Mon Sep 7 14:28:56 PDT 2009


When disabling inline-data feature, space occupied by files changes
and thus we have to update quota information accordingly.

Signed-off-by: Jan Kara <jack at suse.cz>
---
 Preamble.make                      |    2 +-
 tunefs.ocfs2/feature_inline_data.c |  105 +++++++++++++++++++++++++++++++++--
 2 files changed, 100 insertions(+), 7 deletions(-)

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
 # protect with configure?
 CDEPFLAGS = -MD -MP -MF $(@D)/.$(basename $(@F)).d
 
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;
+	}
+
 	tools_progress_stop(prog);
 
 	return ret;
-- 
1.6.0.2




More information about the Ocfs2-tools-devel mailing list