This patch enhances the existing bit operation when f2fs allocates SSR
blocks.

Signed-off-by: Jaegeuk Kim <[email protected]>
---
 fs/f2fs/segment.c | 50 ++++++++++++++++++++------------------------------
 1 file changed, 20 insertions(+), 30 deletions(-)

diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 74c4748..5fa519f 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -132,47 +132,37 @@ static unsigned long __find_rev_next_zero_bit(const 
unsigned long *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 result = size;
        unsigned long tmp;
 
        if (offset >= size)
                return size;
 
-       size -= result;
+       size -= (offset & ~(BITS_PER_LONG - 1));
        offset %= BITS_PER_LONG;
-       if (!offset)
-               goto aligned;
-
-       tmp = __reverse_ulong((unsigned char *)p);
-       tmp |= ~((~0UL << offset) >> offset);
-
-       if (size < BITS_PER_LONG)
-               goto found_first;
-       if (tmp != ~0UL)
-               goto found_middle;
-
-       size -= BITS_PER_LONG;
-       result += BITS_PER_LONG;
-       p++;
-aligned:
-       while (size & ~(BITS_PER_LONG - 1)) {
+
+       while (1) {
+               if (*p == ~0UL)
+                       goto pass;
+
                tmp = __reverse_ulong((unsigned char *)p);
+
+               if (offset)
+                       tmp |= ~0UL << (BITS_PER_LONG - offset);
+               if (size < BITS_PER_LONG)
+                       tmp |= ~0UL >> size;
                if (tmp != ~0UL)
-                       goto found_middle;
-               result += BITS_PER_LONG;
+                       goto found;
+pass:
+               if (size <= BITS_PER_LONG)
+                       break;
                size -= BITS_PER_LONG;
+               offset = 0;
                p++;
        }
-       if (!size)
-               return result;
-
-       tmp = __reverse_ulong((unsigned char *)p);
-found_first:
-       tmp |= ~(~0UL << (BITS_PER_LONG - size));
-       if (tmp == ~0UL)        /* Are any bits zero? */
-               return result + size;   /* Nope. */
-found_middle:
-       return result + __reverse_ffz(tmp);
+       return result;
+found:
+       return result - size + __reverse_ffz(tmp);
 }
 
 void register_inmem_page(struct inode *inode, struct page *page)
-- 
2.4.9 (Apple Git-60)

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to