libf2fs: enhance the bit operations

This patch modifies the existing bit operations.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
Jaegeuk Kim 2015-12-09 11:44:31 -08:00
parent 85aa525057
commit 1ea31c47f4
3 changed files with 71 additions and 64 deletions

View File

@ -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);

View File

@ -319,6 +319,23 @@ struct f2fs_configuration {
t; \
})
/*
* 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
*/
@ -834,8 +851,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);

View File

@ -75,10 +75,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));
@ -87,10 +87,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));
@ -99,7 +99,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;
@ -142,24 +142,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;
@ -173,43 +159,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)
{
const unsigned long *p = addr + BIT_WORD(offset);
unsigned long result = offset & ~(BITS_PER_LONG-1);
unsigned long tmp;
unsigned char 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;
if (!nbits || start >= nbits)
return nbits;
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);
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)
{
return _find_next_bit_le(addr, size, offset, 0xff);
}
/*