/** * nilfs_palloc_find_available_slot - find available slot in a group * @bitmap: bitmap of the group * @target: offset number of an entry in the group (start point) * @bsize: size in bits * @lock: spin lock protecting @bitmap */ static int nilfs_palloc_find_available_slot(unsigned char *bitmap, unsigned long target, unsigned int bsize, spinlock_t *lock) { int pos, end = bsize; 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; } /* 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; }
/** * nilfs_palloc_find_available_slot - find available slot in a group * @inode: inode of metadata file using this allocator * @group: group number * @target: offset number of an entry in the group (start point) * @bitmap: bitmap of the group * @bsize: size in bits */ static int nilfs_palloc_find_available_slot(struct inode *inode, unsigned long group, unsigned long target, unsigned char *bitmap, int bsize) { int curr, pos, end, i; 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( nilfs_mdt_bgl_lock(inode, group), pos, bitmap)) return pos; } else end = 0; 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( nilfs_mdt_bgl_lock(inode, group), pos, bitmap)) return pos; } } return -ENOSPC; }