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
next prev 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.