summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2015-11-06 16:31:48 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-06 17:50:42 -0800
commit18c41b37f0f16a0d6e5b1a73563d0c1333e7ef70 (patch)
tree361af81ca044b6acaecfc58a83f0375abda7653b
parent4e9e63a671fbe13f448fb2e69dfdbb6c2a008368 (diff)
nilfs2: refactor nilfs_palloc_find_available_slot()
The current implementation of nilfs_palloc_find_available_slot() function is overkill. The underlying bit search routine is well optimized, so this uses it more simply in nilfs_palloc_find_available_slot(). Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/nilfs2/alloc.c48
1 files changed, 21 insertions, 27 deletions
diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c
index ff0d62ce165b..b15daf871f99 100644
--- a/fs/nilfs2/alloc.c
+++ b/fs/nilfs2/alloc.c
@@ -335,39 +335,33 @@ void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr,
*/
static int nilfs_palloc_find_available_slot(unsigned char *bitmap,
unsigned long target,
- int bsize,
+ unsigned bsize,
spinlock_t *lock)
{
- int curr, pos, end, i;
+ int pos, end = bsize;
- if (target > 0) {
- end = (target + BITS_PER_LONG - 1) & ~(BITS_PER_LONG - 1);
- if (end > bsize)
- end = bsize;
- pos = nilfs_find_next_zero_bit(bitmap, end, target);
- if (pos < end && !nilfs_set_bit_atomic(lock, pos, bitmap))
- return pos;
- } else {
- end = 0;
+ if (likely(target < bsize)) {
+ pos = target;
+ do {
+ pos = nilfs_find_next_zero_bit(bitmap, end, pos);
+ if (pos >= end)
+ break;
+ if (!nilfs_set_bit_atomic(lock, pos, bitmap))
+ return pos;
+ } while (++pos < end);
+
+ end = target;
}
- for (i = 0, curr = end;
- i < bsize;
- i += BITS_PER_LONG, curr += BITS_PER_LONG) {
- /* wrap around */
- if (curr >= bsize)
- curr = 0;
- while (*((unsigned long *)bitmap + curr / BITS_PER_LONG)
- != ~0UL) {
- end = curr + BITS_PER_LONG;
- if (end > bsize)
- end = bsize;
- pos = nilfs_find_next_zero_bit(bitmap, end, curr);
- if (pos < end &&
- !nilfs_set_bit_atomic(lock, pos, bitmap))
- return pos;
- }
+ /* wrap around */
+ for (pos = 0; pos < end; pos++) {
+ pos = nilfs_find_next_zero_bit(bitmap, end, pos);
+ if (pos >= end)
+ break;
+ if (!nilfs_set_bit_atomic(lock, pos, bitmap))
+ return pos;
}
+
return -ENOSPC;
}