All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tahsin Erdogan <tahsin@google.com>
To: Andreas Dilger <adilger@dilger.ca>,
	"Darrick J . Wong" <darrick.wong@oracle.com>,
	Theodore Ts'o <tytso@mit.edu>,
	linux-ext4@vger.kernel.org
Cc: Tahsin Erdogan <tahsin@google.com>
Subject: [PATCH 05/12] e2fsck: generalize ea_refcount
Date: Mon, 26 Jun 2017 06:43:41 -0700	[thread overview]
Message-ID: <20170626134348.1240-5-tahsin@google.com> (raw)
In-Reply-To: <20170626134348.1240-1-tahsin@google.com>

Currently ea_refcount is only used to track ea block refcounts. By
generalizing it, we could use it for ea quota tracking and also
ea_inode refcounts.

Signed-off-by: Tahsin Erdogan <tahsin@google.com>
---
 e2fsck/e2fsck.h      |  21 ++++---
 e2fsck/ea_refcount.c | 160 +++++++++++++++++++++++++++------------------------
 e2fsck/pass1.c       |   4 +-
 3 files changed, 99 insertions(+), 86 deletions(-)

diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h
index c19cdfdd733e..f9285d01978c 100644
--- a/e2fsck/e2fsck.h
+++ b/e2fsck/e2fsck.h
@@ -466,18 +466,23 @@ extern int e2fsck_get_num_dx_dirinfo(e2fsck_t ctx);
 extern struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control);
 
 /* ea_refcount.c */
-extern errcode_t ea_refcount_create(int size, ext2_refcount_t *ret);
+typedef __u64 ea_key_t;
+typedef __u64 ea_value_t;
+
+extern errcode_t ea_refcount_create(size_t size, ext2_refcount_t *ret);
 extern void ea_refcount_free(ext2_refcount_t refcount);
-extern errcode_t ea_refcount_fetch(ext2_refcount_t refcount, blk64_t blk, int *ret);
+extern errcode_t ea_refcount_fetch(ext2_refcount_t refcount, ea_key_t ea_key,
+				   ea_value_t *ret);
 extern errcode_t ea_refcount_increment(ext2_refcount_t refcount,
-				       blk64_t blk, int *ret);
+				       ea_key_t ea_key, ea_value_t *ret);
 extern errcode_t ea_refcount_decrement(ext2_refcount_t refcount,
-				       blk64_t blk, int *ret);
-extern errcode_t ea_refcount_store(ext2_refcount_t refcount,
-				   blk64_t blk, int count);
-extern blk_t ext2fs_get_refcount_size(ext2_refcount_t refcount);
+				       ea_key_t ea_key, ea_value_t *ret);
+extern errcode_t ea_refcount_store(ext2_refcount_t refcount, ea_key_t ea_key,
+				   ea_value_t count);
+extern size_t ext2fs_get_refcount_size(ext2_refcount_t refcount);
 extern void ea_refcount_intr_begin(ext2_refcount_t refcount);
-extern blk64_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret);
+extern ea_key_t ea_refcount_intr_next(ext2_refcount_t refcount,
+				      ea_value_t *ret);
 
 /* ehandler.c */
 extern const char *ehandler_operation(const char *op);
diff --git a/e2fsck/ea_refcount.c b/e2fsck/ea_refcount.c
index fcfaf4970ece..ecb198640c69 100644
--- a/e2fsck/ea_refcount.c
+++ b/e2fsck/ea_refcount.c
@@ -25,14 +25,15 @@
  * checked, its bit is set in the block_ea_map bitmap.
  */
 struct ea_refcount_el {
-	blk64_t	ea_blk;
-	int	ea_count;
+	/* ea_key could either be an inode number or block number. */
+	ea_key_t	ea_key;
+	ea_value_t	ea_value;
 };
 
 struct ea_refcount {
-	blk_t		count;
-	blk_t		size;
-	blk_t		cursor;
+	size_t		count;
+	size_t		size;
+	size_t		cursor;
 	struct ea_refcount_el	*list;
 };
 
@@ -46,7 +47,7 @@ void ea_refcount_free(ext2_refcount_t refcount)
 	ext2fs_free_mem(&refcount);
 }
 
-errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
+errcode_t ea_refcount_create(size_t size, ext2_refcount_t *ret)
 {
 	ext2_refcount_t	refcount;
 	errcode_t	retval;
@@ -60,9 +61,9 @@ errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
 	if (!size)
 		size = 500;
 	refcount->size = size;
-	bytes = (size_t) (size * sizeof(struct ea_refcount_el));
+	bytes = size * sizeof(struct ea_refcount_el);
 #ifdef DEBUG
-	printf("Refcount allocated %d entries, %d bytes.\n",
+	printf("Refcount allocated %zu entries, %zu bytes.\n",
 	       refcount->size, bytes);
 #endif
 	retval = ext2fs_get_mem(bytes, &refcount->list);
@@ -92,14 +93,14 @@ static void refcount_collapse(ext2_refcount_t refcount)
 
 	list = refcount->list;
 	for (i = 0, j = 0; i < refcount->count; i++) {
-		if (list[i].ea_count) {
+		if (list[i].ea_value) {
 			if (i != j)
 				list[j] = list[i];
 			j++;
 		}
 	}
 #if defined(DEBUG) || defined(TEST_PROGRAM)
-	printf("Refcount_collapse: size was %d, now %d\n",
+	printf("Refcount_collapse: size was %zu, now %d\n",
 	       refcount->count, j);
 #endif
 	refcount->count = j;
@@ -111,11 +112,11 @@ static void refcount_collapse(ext2_refcount_t refcount)
  * 	specified position.
  */
 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
-						 blk64_t blk, int pos)
+						 ea_key_t ea_key, int pos)
 {
 	struct ea_refcount_el 	*el;
 	errcode_t		retval;
-	blk_t			new_size = 0;
+	size_t			new_size = 0;
 	int			num;
 
 	if (refcount->count >= refcount->size) {
@@ -141,8 +142,8 @@ static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
 	}
 	refcount->count++;
 	el = &refcount->list[pos];
-	el->ea_count = 0;
-	el->ea_blk = blk;
+	el->ea_key = ea_key;
+	el->ea_value = 0;
 	return el;
 }
 
@@ -153,7 +154,7 @@ static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
  * 	and we can't find an entry, create one in the sorted list.
  */
 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
-					      blk64_t blk, int create)
+					      ea_key_t ea_key, int create)
 {
 	int	low, high, mid;
 
@@ -163,11 +164,11 @@ retry:
 	low = 0;
 	high = (int) refcount->count-1;
 	if (create && ((refcount->count == 0) ||
-		       (blk > refcount->list[high].ea_blk))) {
+		       (ea_key > refcount->list[high].ea_key))) {
 		if (refcount->count >= refcount->size)
 			refcount_collapse(refcount);
 
-		return insert_refcount_el(refcount, blk,
+		return insert_refcount_el(refcount, ea_key,
 					  (unsigned) refcount->count);
 	}
 	if (refcount->count == 0)
@@ -175,18 +176,18 @@ retry:
 
 	if (refcount->cursor >= refcount->count)
 		refcount->cursor = 0;
-	if (blk == refcount->list[refcount->cursor].ea_blk)
+	if (ea_key == refcount->list[refcount->cursor].ea_key)
 		return &refcount->list[refcount->cursor++];
 #ifdef DEBUG
-	printf("Non-cursor get_refcount_el: %u\n", blk);
+	printf("Non-cursor get_refcount_el: %u\n", ea_key);
 #endif
 	while (low <= high) {
 		mid = (low+high)/2;
-		if (blk == refcount->list[mid].ea_blk) {
+		if (ea_key == refcount->list[mid].ea_key) {
 			refcount->cursor = mid+1;
 			return &refcount->list[mid];
 		}
-		if (blk < refcount->list[mid].ea_blk)
+		if (ea_key < refcount->list[mid].ea_key)
 			high = mid-1;
 		else
 			low = mid+1;
@@ -201,69 +202,72 @@ retry:
 			if (refcount->count < refcount->size)
 				goto retry;
 		}
-		return insert_refcount_el(refcount, blk, low);
+		return insert_refcount_el(refcount, ea_key, low);
 	}
 	return 0;
 }
 
-errcode_t ea_refcount_fetch(ext2_refcount_t refcount, blk64_t blk,
-				int *ret)
+errcode_t ea_refcount_fetch(ext2_refcount_t refcount, ea_key_t ea_key,
+			    ea_value_t *ret)
 {
 	struct ea_refcount_el	*el;
 
-	el = get_refcount_el(refcount, blk, 0);
+	el = get_refcount_el(refcount, ea_key, 0);
 	if (!el) {
 		*ret = 0;
 		return 0;
 	}
-	*ret = el->ea_count;
+	*ret = el->ea_value;
 	return 0;
 }
 
-errcode_t ea_refcount_increment(ext2_refcount_t refcount, blk64_t blk, int *ret)
+errcode_t ea_refcount_increment(ext2_refcount_t refcount, ea_key_t ea_key,
+				ea_value_t *ret)
 {
 	struct ea_refcount_el	*el;
 
-	el = get_refcount_el(refcount, blk, 1);
+	el = get_refcount_el(refcount, ea_key, 1);
 	if (!el)
 		return EXT2_ET_NO_MEMORY;
-	el->ea_count++;
+	el->ea_value++;
 
 	if (ret)
-		*ret = el->ea_count;
+		*ret = el->ea_value;
 	return 0;
 }
 
-errcode_t ea_refcount_decrement(ext2_refcount_t refcount, blk64_t blk, int *ret)
+errcode_t ea_refcount_decrement(ext2_refcount_t refcount, ea_key_t ea_key,
+				ea_value_t *ret)
 {
 	struct ea_refcount_el	*el;
 
-	el = get_refcount_el(refcount, blk, 0);
-	if (!el || el->ea_count == 0)
+	el = get_refcount_el(refcount, ea_key, 0);
+	if (!el || el->ea_value == 0)
 		return EXT2_ET_INVALID_ARGUMENT;
 
-	el->ea_count--;
+	el->ea_value--;
 
 	if (ret)
-		*ret = el->ea_count;
+		*ret = el->ea_value;
 	return 0;
 }
 
-errcode_t ea_refcount_store(ext2_refcount_t refcount, blk64_t blk, int count)
+errcode_t ea_refcount_store(ext2_refcount_t refcount, ea_key_t ea_key,
+			    ea_value_t ea_value)
 {
 	struct ea_refcount_el	*el;
 
 	/*
 	 * Get the refcount element
 	 */
-	el = get_refcount_el(refcount, blk, count ? 1 : 0);
+	el = get_refcount_el(refcount, ea_key, ea_value ? 1 : 0);
 	if (!el)
-		return count ? EXT2_ET_NO_MEMORY : 0;
-	el->ea_count = count;
+		return ea_value ? EXT2_ET_NO_MEMORY : 0;
+	el->ea_value = ea_value;
 	return 0;
 }
 
-blk_t ext2fs_get_refcount_size(ext2_refcount_t refcount)
+size_t ext2fs_get_refcount_size(ext2_refcount_t refcount)
 {
 	if (!refcount)
 		return 0;
@@ -276,9 +280,8 @@ void ea_refcount_intr_begin(ext2_refcount_t refcount)
 	refcount->cursor = 0;
 }
 
-
-blk64_t ea_refcount_intr_next(ext2_refcount_t refcount,
-				int *ret)
+ea_key_t ea_refcount_intr_next(ext2_refcount_t refcount,
+				ea_value_t *ret)
 {
 	struct ea_refcount_el	*list;
 
@@ -286,10 +289,10 @@ blk64_t ea_refcount_intr_next(ext2_refcount_t refcount,
 		if (refcount->cursor >= refcount->count)
 			return 0;
 		list = refcount->list;
-		if (list[refcount->cursor].ea_count) {
+		if (list[refcount->cursor].ea_value) {
 			if (ret)
-				*ret = list[refcount->cursor].ea_count;
-			return list[refcount->cursor++].ea_blk;
+				*ret = list[refcount->cursor].ea_value;
+			return list[refcount->cursor++].ea_key;
 		}
 		refcount->cursor++;
 	}
@@ -309,11 +312,11 @@ errcode_t ea_refcount_validate(ext2_refcount_t refcount, FILE *out)
 		return EXT2_ET_INVALID_ARGUMENT;
 	}
 	for (i=1; i < refcount->count; i++) {
-		if (refcount->list[i-1].ea_blk >= refcount->list[i].ea_blk) {
+		if (refcount->list[i-1].ea_key >= refcount->list[i].ea_key) {
 			fprintf(out,
-				"%s: list[%d].blk=%llu, list[%d].blk=%llu\n",
-				bad, i-1, refcount->list[i-1].ea_blk,
-				i, refcount->list[i].ea_blk);
+				"%s: list[%d].ea_key=%llu, list[%d].ea_key=%llu\n",
+				bad, i-1, refcount->list[i-1].ea_key, i,
+				refcount->list[i].ea_key);
 			ret = EXT2_ET_INVALID_ARGUMENT;
 		}
 	}
@@ -370,8 +373,9 @@ int main(int argc, char **argv)
 {
 	int	i = 0;
 	ext2_refcount_t refcount;
-	int		size, arg;
-	blk64_t		blk;
+	size_t		size;
+	ea_key_t	ea_key;
+	ea_value_t	arg;
 	errcode_t	retval;
 
 	while (1) {
@@ -383,10 +387,10 @@ int main(int argc, char **argv)
 			retval = ea_refcount_create(size, &refcount);
 			if (retval) {
 				com_err("ea_refcount_create", retval,
-					"while creating size %d", size);
+					"while creating size %zu", size);
 				exit(1);
 			} else
-				printf("Creating refcount with size %d\n",
+				printf("Creating refcount with size %zu\n",
 				       size);
 			break;
 		case BCODE_FREE:
@@ -395,43 +399,46 @@ int main(int argc, char **argv)
 			printf("Freeing refcount\n");
 			break;
 		case BCODE_STORE:
-			blk = (blk_t) bcode_program[i++];
+			ea_key = (size_t) bcode_program[i++];
 			arg = bcode_program[i++];
-			printf("Storing blk %llu with value %d\n", blk, arg);
-			retval = ea_refcount_store(refcount, blk, arg);
+			printf("Storing ea_key %llu with value %llu\n", ea_key,
+			       arg);
+			retval = ea_refcount_store(refcount, ea_key, arg);
 			if (retval)
 				com_err("ea_refcount_store", retval,
-					"while storing blk %llu", blk);
+					"while storing ea_key %llu", ea_key);
 			break;
 		case BCODE_FETCH:
-			blk = (blk_t) bcode_program[i++];
-			retval = ea_refcount_fetch(refcount, blk, &arg);
+			ea_key = (size_t) bcode_program[i++];
+			retval = ea_refcount_fetch(refcount, ea_key, &arg);
 			if (retval)
 				com_err("ea_refcount_fetch", retval,
-					"while fetching blk %llu", blk);
+					"while fetching ea_key %llu", ea_key);
 			else
-				printf("bcode_fetch(%llu) returns %d\n",
-				       blk, arg);
+				printf("bcode_fetch(%llu) returns %llu\n",
+				       ea_key, arg);
 			break;
 		case BCODE_INCR:
-			blk = (blk_t) bcode_program[i++];
-			retval = ea_refcount_increment(refcount, blk, &arg);
+			ea_key = (size_t) bcode_program[i++];
+			retval = ea_refcount_increment(refcount, ea_key, &arg);
 			if (retval)
 				com_err("ea_refcount_increment", retval,
-					"while incrementing blk %llu", blk);
+					"while incrementing ea_key %llu",
+					ea_key);
 			else
-				printf("bcode_increment(%llu) returns %d\n",
-				       blk, arg);
+				printf("bcode_increment(%llu) returns %llu\n",
+				       ea_key, arg);
 			break;
 		case BCODE_DECR:
-			blk = (blk_t) bcode_program[i++];
-			retval = ea_refcount_decrement(refcount, blk, &arg);
+			ea_key = (size_t) bcode_program[i++];
+			retval = ea_refcount_decrement(refcount, ea_key, &arg);
 			if (retval)
 				com_err("ea_refcount_decrement", retval,
-					"while decrementing blk %llu", blk);
+					"while decrementing ea_key %llu",
+					ea_key);
 			else
-				printf("bcode_decrement(%llu) returns %d\n",
-				       blk, arg);
+				printf("bcode_decrement(%llu) returns %llu\n",
+				       ea_key, arg);
 			break;
 		case BCODE_VALIDATE:
 			retval = ea_refcount_validate(refcount, stderr);
@@ -444,10 +451,11 @@ int main(int argc, char **argv)
 		case BCODE_LIST:
 			ea_refcount_intr_begin(refcount);
 			while (1) {
-				blk = ea_refcount_intr_next(refcount, &arg);
-				if (!blk)
+				ea_key = ea_refcount_intr_next(refcount, &arg);
+				if (!ea_key)
 					break;
-				printf("\tblk=%llu, count=%d\n", blk, arg);
+				printf("\tea_key=%llu, count=%llu\n", ea_key,
+				       arg);
 			}
 			break;
 		case BCODE_COLLAPSE:
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 1532fd2067f2..9ee2c5e89a61 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -2269,7 +2269,7 @@ static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
 	ext2_filsys			fs = ctx->fs;
 	blk64_t				blk;
 	__u32				should_be;
-	int				count;
+	ea_value_t			count;
 
 	clear_problem_context(&pctx);
 
@@ -2286,7 +2286,7 @@ static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
 		}
 		header = (struct ext2_ext_attr_header *) block_buf;
 		pctx.blkcount = header->h_refcount;
-		should_be = header->h_refcount + adjust_sign * count;
+		should_be = header->h_refcount + adjust_sign * (int)count;
 		pctx.num = should_be;
 		if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
 			header->h_refcount = should_be;
-- 
2.13.1.611.g7e3b11ae1-goog

  parent reply	other threads:[~2017-06-26 13:44 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-26 13:43 [PATCH 01/12] e2fsck: add support for large xattrs in external inodes Tahsin Erdogan
2017-06-26 13:43 ` [PATCH 02/12] tune2fs: do not allow disabling ea_inode feature Tahsin Erdogan
2017-06-26 13:43 ` [PATCH 03/12] e2fsck: ea_inode hash validation Tahsin Erdogan
2017-06-26 21:21   ` Andreas Dilger
2017-06-28  1:41     ` [PATCH v2 " Tahsin Erdogan
2017-06-28  1:47       ` Tahsin Erdogan
2017-06-26 13:43 ` [PATCH 04/12] e2fsck: do not early terminate extra space check Tahsin Erdogan
2017-06-26 21:23   ` Andreas Dilger
2017-06-26 23:57     ` Tahsin Erdogan
2017-06-26 13:43 ` Tahsin Erdogan [this message]
2017-06-26 13:43 ` [PATCH 06/12] e2fsck: update i_blocks accounting for ea_inode feature Tahsin Erdogan
2017-06-26 21:36   ` Andreas Dilger
2017-06-27 11:37     ` Tahsin Erdogan
2017-06-30  1:39       ` Tahsin Erdogan
2017-06-26 13:43 ` [PATCH 07/12] e2fsck: track ea_inode references Tahsin Erdogan
2017-06-26 21:45   ` Andreas Dilger
2017-06-27  1:25     ` Tahsin Erdogan
2017-06-27 18:43       ` Andreas Dilger
2017-06-28  1:26         ` Tahsin Erdogan
2017-06-26 13:43 ` [PATCH 08/12] e2fsck: add test for ea_inode feature Tahsin Erdogan
2017-06-26 13:43 ` [PATCH 09/12] tune2fs: update ea_inode hashes when fs uuid changes Tahsin Erdogan
2017-06-26 13:43 ` [PATCH 10/12] fuse2fs: refuse to mount fs with ea_inode feature Tahsin Erdogan
2017-06-26 13:43 ` [PATCH 11/12] mke2fs: ea_inode is not supported for hurd Tahsin Erdogan
2017-06-26 13:43 ` [PATCH 12/12] resize2fs: moving xattr inodes is not supported Tahsin Erdogan
2017-07-05  4:04 ` [PATCH 01/12] e2fsck: add support for large xattrs in external inodes Theodore Ts'o

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170626134348.1240-5-tahsin@google.com \
    --to=tahsin@google.com \
    --cc=adilger@dilger.ca \
    --cc=darrick.wong@oracle.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.