[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20170626134348.1240-5-tahsin@google.com>
Date: Mon, 26 Jun 2017 06:43:41 -0700
From: Tahsin Erdogan <tahsin@...gle.com>
To: Andreas Dilger <adilger@...ger.ca>,
"Darrick J . Wong" <darrick.wong@...cle.com>,
Theodore Ts'o <tytso@....edu>, linux-ext4@...r.kernel.org
Cc: Tahsin Erdogan <tahsin@...gle.com>
Subject: [PATCH 05/12] e2fsck: generalize ea_refcount
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@...gle.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
Powered by blists - more mailing lists