aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2015-12-09 11:44:31 -0800
committerGreg Wallace <greg@gregtwallace.com>2016-01-19 22:02:20 -0500
commit3de0318a9a156f7b720a6b704c835b0c46240cc2 (patch)
treeea759307e3254d539fe992bf6e10eef5a02fd417
parent4cf9c57c6b52aabb38bde9f9c77652064c6937f1 (diff)
downloadandroid_external_f2fs-tools-3de0318a9a156f7b720a6b704c835b0c46240cc2.tar.gz
android_external_f2fs-tools-3de0318a9a156f7b720a6b704c835b0c46240cc2.tar.bz2
android_external_f2fs-tools-3de0318a9a156f7b720a6b704c835b0c46240cc2.zip
libf2fs: enhance the bit operations
This patch modifies the existing bit operations. Change-Id: Ib6c9ba77d5426b31ee31e0d811d45a85ac89cc57 Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fsck/fsck.c12
-rw-r--r--include/f2fs_fs.h23
-rw-r--r--lib/libf2fs.c104
3 files changed, 73 insertions, 66 deletions
diff --git a/fsck/fsck.c b/fsck/fsck.c
index c71f225..c81dde9 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -820,7 +820,7 @@ static void convert_encrypted_name(unsigned char *name, int len,
}
static void print_dentry(__u32 depth, __u8 *name,
- unsigned long *bitmap,
+ unsigned char *bitmap,
struct f2fs_dir_entry *dentry,
int max, int idx, int last_blk, int encrypted)
{
@@ -837,7 +837,7 @@ static void print_dentry(__u32 depth, __u8 *name,
name_len = le16_to_cpu(dentry[idx].name_len);
next_idx = idx + (name_len + F2FS_SLOT_LEN - 1) / F2FS_SLOT_LEN;
- bit_offset = find_next_bit(bitmap, max, next_idx);
+ bit_offset = find_next_bit_le(bitmap, max, next_idx);
if (bit_offset >= max && last_blk)
last_de = 1;
@@ -889,7 +889,7 @@ static int f2fs_check_hash_code(struct f2fs_dir_entry *dentry,
}
static int __chk_dentries(struct f2fs_sb_info *sbi, struct child_info *child,
- unsigned long *bitmap,
+ unsigned char *bitmap,
struct f2fs_dir_entry *dentry,
__u8 (*filenames)[F2FS_SLOT_LEN],
int max, int last_blk, int encrypted)
@@ -946,7 +946,7 @@ static int __chk_dentries(struct f2fs_sb_info *sbi, struct child_info *child,
ftype = dentry[i].file_type;
if ((ftype <= F2FS_FT_UNKNOWN || ftype > F2FS_FT_LAST_FILE_TYPE)) {
- ASSERT_MSG("Bad dentry 0x%x with unexpected ftype 0x%x", i, ftype);
+ ASSERT_MSG("Bad dentry 0x%x with unexpected ftype 0x%x", ino, ftype);
if (config.fix_on) {
FIX_MSG("Clear bad dentry 0x%x with bad ftype 0x%x",
i, ftype);
@@ -1036,7 +1036,7 @@ int fsck_chk_inline_dentries(struct f2fs_sb_info *sbi,
fsck->dentry_depth++;
dentries = __chk_dentries(sbi, child,
- (unsigned long *)de_blk->dentry_bitmap,
+ de_blk->dentry_bitmap,
de_blk->dentry, de_blk->filename,
NR_INLINE_DENTRY, 1,
file_is_encrypt(node_blk->i.i_advise));
@@ -1068,7 +1068,7 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
fsck->dentry_depth++;
dentries = __chk_dentries(sbi, child,
- (unsigned long *)de_blk->dentry_bitmap,
+ de_blk->dentry_bitmap,
de_blk->dentry, de_blk->filename,
NR_DENTRY_IN_BLOCK, last_blk, encrypted);
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 4dceeb7..5732bb5 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -345,6 +345,23 @@ struct f2fs_configuration {
})
/*
+ * Copied from include/linux/kernel.h
+ */
+#define __round_mask(x, y) ((__typeof__(x))((y)-1))
+#define round_down(x, y) ((x) & ~__round_mask(x, y))
+#define min(x, y) ({ \
+ typeof(x) _min1 = (x); \
+ typeof(y) _min2 = (y); \
+ (void) (&_min1 == &_min2); \
+ _min1 < _min2 ? _min1 : _min2; })
+
+#define max(x, y) ({ \
+ typeof(x) _max1 = (x); \
+ typeof(y) _max2 = (y); \
+ (void) (&_max1 == &_max2); \
+ _max1 > _max2 ? _max1 : _max2; })
+
+/*
* Copied from fs/f2fs/f2fs.h
*/
#define NR_CURSEG_DATA_TYPE (3)
@@ -859,8 +876,10 @@ extern int test_bit(unsigned int nr, const void * addr);
extern int f2fs_test_bit(unsigned int, const char *);
extern int f2fs_set_bit(unsigned int, char *);
extern int f2fs_clear_bit(unsigned int, char *);
-extern unsigned long find_next_bit(const unsigned long *,
- unsigned long, unsigned long);
+extern unsigned long find_next_bit_le(const unsigned char *, unsigned long,
+ unsigned long);
+extern unsigned long find_next_zero_bit_le(const unsigned char *, unsigned long,
+ unsigned long);
extern u_int32_t f2fs_cal_crc32(u_int32_t, void *, int);
extern int f2fs_crc_valid(u_int32_t blk_crc, void *buf, int len);
diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index 8e10e6a..e80cae0 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -77,10 +77,10 @@ int get_bits_in_byte(unsigned char n)
return bits_in_byte[n];
}
-int set_bit(unsigned int nr,void * addr)
+int set_bit(unsigned int nr, void *addr)
{
- int mask, retval;
- unsigned char *ADDR = (unsigned char *) addr;
+ int mask, retval;
+ unsigned char *ADDR = (unsigned char *)addr;
ADDR += nr >> 3;
mask = 1 << ((nr & 0x07));
@@ -89,10 +89,10 @@ int set_bit(unsigned int nr,void * addr)
return retval;
}
-int clear_bit(unsigned int nr, void * addr)
+int clear_bit(unsigned int nr, void *addr)
{
- int mask, retval;
- unsigned char *ADDR = (unsigned char *) addr;
+ int mask, retval;
+ unsigned char *ADDR = (unsigned char *)addr;
ADDR += nr >> 3;
mask = 1 << ((nr & 0x07));
@@ -101,7 +101,7 @@ int clear_bit(unsigned int nr, void * addr)
return retval;
}
-int test_bit(unsigned int nr, const void * addr)
+int test_bit(unsigned int nr, const void *addr)
{
const __u32 *p = (const __u32 *)addr;
@@ -144,24 +144,10 @@ int f2fs_clear_bit(unsigned int nr, char *addr)
return ret;
}
-static inline unsigned long __ffs(unsigned long word)
+static inline unsigned long __ffs(unsigned char word)
{
int num = 0;
-#if BITS_PER_LONG == 64
- if ((word & 0xffffffff) == 0) {
- num += 32;
- word >>= 32;
- }
-#endif
- if ((word & 0xffff) == 0) {
- num += 16;
- word >>= 16;
- }
- if ((word & 0xff) == 0) {
- num += 8;
- word >>= 8;
- }
if ((word & 0xf) == 0) {
num += 4;
word >>= 4;
@@ -175,43 +161,45 @@ static inline unsigned long __ffs(unsigned long word)
return num;
}
-unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
- unsigned long offset)
+/* Copied from linux/lib/find_bit.c */
+#define BITMAP_FIRST_BYTE_MASK(start) (0xff << ((start) & (BITS_PER_BYTE - 1)))
+
+static unsigned long _find_next_bit_le(const unsigned char *addr,
+ unsigned long nbits, unsigned long start, char invert)
+{
+ unsigned char tmp;
+
+ if (!nbits || start >= nbits)
+ return nbits;
+
+ tmp = addr[start / BITS_PER_BYTE] ^ invert;
+
+ /* Handle 1st word. */
+ tmp &= BITMAP_FIRST_BYTE_MASK(start);
+ start = round_down(start, BITS_PER_BYTE);
+
+ while (!tmp) {
+ start += BITS_PER_BYTE;
+ if (start >= nbits)
+ return nbits;
+
+ tmp = addr[start / BITS_PER_BYTE] ^ invert;
+ }
+
+ return min(start + __ffs(tmp), nbits);
+}
+
+unsigned long find_next_bit_le(const unsigned char *addr, unsigned long size,
+ unsigned long offset)
+{
+ return _find_next_bit_le(addr, size, offset, 0);
+}
+
+
+unsigned long find_next_zero_bit_le(const unsigned char *addr,
+ unsigned long size, unsigned long offset)
{
- const unsigned long *p = addr + BIT_WORD(offset);
- unsigned long result = offset & ~(BITS_PER_LONG-1);
- unsigned long tmp;
-
- if (offset >= size)
- return size;
- size -= result;
- offset %= BITS_PER_LONG;
- if (offset) {
- tmp = *(p++);
- tmp &= (~0UL << offset);
- if (size < BITS_PER_LONG)
- goto found_first;
- if (tmp)
- goto found_middle;
- size -= BITS_PER_LONG;
- result += BITS_PER_LONG;
- }
- while (size & ~(BITS_PER_LONG-1)) {
- if ((tmp = *(p++)))
- goto found_middle;
- result += BITS_PER_LONG;
- size -= BITS_PER_LONG;
- }
- if (!size)
- return result;
- tmp = *p;
-
-found_first:
- tmp &= (~0UL >> (BITS_PER_LONG - size));
- if (tmp == 0UL) /* Are any bits set? */
- return result + size; /* Nope. */
-found_middle:
- return result + __ffs(tmp);
+ return _find_next_bit_le(addr, size, offset, 0xff);
}
/*