ext2_ino_t cursor;
struct ext2_icount_el *list;
struct ext2_icount_el *last_lookup;
+#ifdef CONFIG_TDB
char *tdb_fn;
TDB_CONTEXT *tdb;
+#endif
+ __u16 *fullmap;
};
/*
ext2fs_free_inode_bitmap(icount->single);
if (icount->multiple)
ext2fs_free_inode_bitmap(icount->multiple);
+#ifdef CONFIG_TDB
if (icount->tdb)
tdb_close(icount->tdb);
if (icount->tdb_fn) {
- unlink(icount->tdb_fn);
+ (void) unlink(icount->tdb_fn);
free(icount->tdb_fn);
}
+#endif
+
+ if (icount->fullmap)
+ ext2fs_free_mem(&icount->fullmap);
ext2fs_free_mem(&icount);
}
if (retval)
return retval;
memset(icount, 0, sizeof(struct ext2_icount));
+ icount->magic = EXT2_ET_MAGIC_ICOUNT;
+ icount->num_inodes = fs->super->s_inodes_count;
+
+ if ((flags & EXT2_ICOUNT_OPT_FULLMAP) &&
+ (flags & EXT2_ICOUNT_OPT_INCREMENT)) {
+ unsigned sz = sizeof(*icount->fullmap) * icount->num_inodes;
+
+ retval = ext2fs_get_mem(sz, &icount->fullmap);
+ /* If we can't allocate, fall back */
+ if (!retval) {
+ memset(icount->fullmap, 0, sz);
+ *ret = icount;
+ return 0;
+ }
+ }
retval = ext2fs_allocate_inode_bitmap(fs, "icount", &icount->single);
if (retval)
&icount->multiple);
if (retval)
goto errout;
- } else
+ } else {
icount->multiple = 0;
-
- icount->magic = EXT2_ET_MAGIC_ICOUNT;
- icount->num_inodes = fs->super->s_inodes_count;
+ }
*ret = icount;
return 0;
return(retval);
}
+#ifdef CONFIG_TDB
struct uuid {
__u32 time_low;
__u16 time_mid;
uuid.node[0], uuid.node[1], uuid.node[2],
uuid.node[3], uuid.node[4], uuid.node[5]);
}
+#endif
-errcode_t ext2fs_create_icount_tdb(ext2_filsys fs, char *tdb_dir,
- int flags, ext2_icount_t *ret)
+errcode_t ext2fs_create_icount_tdb(ext2_filsys fs EXT2FS_NO_TDB_UNUSED,
+ char *tdb_dir EXT2FS_NO_TDB_UNUSED,
+ int flags EXT2FS_NO_TDB_UNUSED,
+ ext2_icount_t *ret EXT2FS_NO_TDB_UNUSED)
{
+#ifdef CONFIG_TDB
ext2_icount_t icount;
errcode_t retval;
char *fn, uuid[40];
ext2_ino_t num_inodes;
+ mode_t save_umask;
int fd;
retval = alloc_icount(fs, flags, &icount);
goto errout;
uuid_unparse(fs->super->s_uuid, uuid);
sprintf(fn, "%s/%s-icount-XXXXXX", tdb_dir, uuid);
- icount->tdb_fn = fn;
+ save_umask = umask(077);
fd = mkstemp(fn);
if (fd < 0) {
retval = errno;
+ ext2fs_free_mem(&fn);
goto errout;
}
+ icount->tdb_fn = fn;
+ umask(save_umask);
/*
* This is an overestimate of the size that we will need; the
* ideal value is the number of used inodes with a count
errout:
ext2fs_free_icount(icount);
return(retval);
+#else
+ return EXT2_ET_UNIMPLEMENTED;
+#endif
}
errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags, unsigned int size,
if (retval)
return retval;
+ if (icount->fullmap)
+ goto successout;
+
if (size) {
icount->size = size;
} else {
icount->count = hint->count;
}
+successout:
*ret = icount;
return 0;
__u32 count)
{
struct ext2_icount_el *el;
+#ifdef CONFIG_TDB
TDB_DATA key, data;
if (icount->tdb) {
}
return 0;
}
+#endif
+ if (icount->fullmap) {
+ icount->fullmap[ino] = icount_16_xlate(count);
+ return 0;
+ }
el = get_icount_el(icount, ino, 1);
if (!el)
__u32 *count)
{
struct ext2_icount_el *el;
+#ifdef CONFIG_TDB
TDB_DATA key, data;
if (icount->tdb) {
free(data.dptr);
return 0;
}
+#endif
+ if (icount->fullmap) {
+ *count = icount->fullmap[ino];
+ return 0;
+ }
+
el = get_icount_el(icount, ino, 0);
if (!el) {
*count = 0;
return 0;
}
+int ext2fs_icount_is_set(ext2_icount_t icount, ext2_ino_t ino)
+{
+ __u16 result;
+
+ if (ext2fs_test_inode_bitmap2(icount->single, ino))
+ return 1;
+ else if (icount->multiple) {
+ if (ext2fs_test_inode_bitmap2(icount->multiple, ino))
+ return 1;
+ return 0;
+ }
+ ext2fs_icount_fetch(icount, ino, &result);
+ if (result)
+ return 1;
+ return 0;
+}
+
errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *out)
{
errcode_t ret = 0;
if (!ino || (ino > icount->num_inodes))
return EXT2_ET_INVALID_ARGUMENT;
- if (ext2fs_test_inode_bitmap2(icount->single, ino)) {
- *ret = 1;
- return 0;
- }
- if (icount->multiple &&
- !ext2fs_test_inode_bitmap2(icount->multiple, ino)) {
- *ret = 0;
- return 0;
+ if (!icount->fullmap) {
+ if (ext2fs_test_inode_bitmap2(icount->single, ino)) {
+ *ret = 1;
+ return 0;
+ }
+ if (icount->multiple &&
+ !ext2fs_test_inode_bitmap2(icount->multiple, ino)) {
+ *ret = 0;
+ return 0;
+ }
}
get_inode_count(icount, ino, &val);
*ret = icount_16_xlate(val);
if (!ino || (ino > icount->num_inodes))
return EXT2_ET_INVALID_ARGUMENT;
- if (ext2fs_test_inode_bitmap2(icount->single, ino)) {
+ if (icount->fullmap) {
+ curr_value = icount_16_xlate(icount->fullmap[ino] + 1);
+ icount->fullmap[ino] = curr_value;
+ } else if (ext2fs_test_inode_bitmap2(icount->single, ino)) {
/*
* If the existing count is 1, then we know there is
* no entry in the list.
EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
+ if (icount->fullmap) {
+ if (!icount->fullmap[ino])
+ return EXT2_ET_INVALID_ARGUMENT;
+
+ curr_value = --icount->fullmap[ino];
+ if (ret)
+ *ret = icount_16_xlate(curr_value);
+ return 0;
+ }
+
if (ext2fs_test_inode_bitmap2(icount->single, ino)) {
ext2fs_unmark_inode_bitmap2(icount->single, ino);
if (icount->multiple)
EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
+ if (icount->fullmap)
+ return set_inode_count(icount, ino, count);
+
if (count == 1) {
ext2fs_mark_inode_bitmap2(icount->single, ino);
if (icount->multiple)
int problem = 0;
if (dir) {
+#ifdef CONFIG_TDB
retval = ext2fs_create_icount_tdb(test_fs, dir,
flags, &icount);
if (retval) {
"while creating icount using tdb");
exit(1);
}
+#else
+ printf("Skipped\n");
+ return 0;
+#endif
} else {
retval = ext2fs_create_icount2(test_fs, flags, size, 0,
&icount);