/* decode raw bytes as received by the hardware, and push them to the ir-core * layer */ static void ite_decode_bytes(struct ite_dev *dev, const u8 * data, int length) { u32 sample_period; unsigned long *ldata; unsigned int next_one, next_zero, size; DEFINE_IR_RAW_EVENT(ev); if (length == 0) return; sample_period = dev->params.sample_period; ldata = (unsigned long *)data; size = length << 3; next_one = find_next_bit_le(ldata, size, 0); if (next_one > 0) { ev.pulse = true; ev.duration = ITE_BITS_TO_NS(next_one, sample_period); ir_raw_event_store_with_filter(dev->rdev, &ev); } while (next_one < size) { next_zero = find_next_zero_bit_le(ldata, size, next_one + 1); ev.pulse = false; ev.duration = ITE_BITS_TO_NS(next_zero - next_one, sample_period); ir_raw_event_store_with_filter(dev->rdev, &ev); if (next_zero < size) { next_one = find_next_bit_le(ldata, size, next_zero + 1); ev.pulse = true; ev.duration = ITE_BITS_TO_NS(next_one - next_zero, sample_period); ir_raw_event_store_with_filter (dev->rdev, &ev); } else next_one = size; } ir_raw_event_handle(dev->rdev); ite_dbg_verbose("decoded %d bytes.", length); }
static int room_for_filename(const u8 *bitmap, int slots, int max_slots) { int bit_start = 0; int zero_start, zero_end; next: zero_start = find_next_zero_bit_le(bitmap, max_slots, bit_start); if (zero_start >= max_slots) return max_slots; zero_end = find_next_bit_le(bitmap, max_slots, zero_start + 1); if (zero_end - zero_start >= slots) return zero_start; bit_start = zero_end; goto next; }
static int core_get_resync_work(struct dm_dirty_log *log, region_t *region) { struct log_c *lc = (struct log_c *) log->context; if (lc->sync_search >= lc->region_count) return 0; do { *region = find_next_zero_bit_le(lc->sync_bits, lc->region_count, lc->sync_search); lc->sync_search = *region + 1; if (*region >= lc->region_count) return 0; } while (log_test_bit(lc->recovering_bits, *region)); log_set_bit(lc, lc->recovering_bits, *region); return 1; }
static int room_for_filename(struct f2fs_dentry_block *dentry_blk, int slots) { int bit_start = 0; int zero_start, zero_end; next: zero_start = find_next_zero_bit_le(&dentry_blk->dentry_bitmap, NR_DENTRY_IN_BLOCK, bit_start); if (zero_start >= NR_DENTRY_IN_BLOCK) return NR_DENTRY_IN_BLOCK; zero_end = find_next_bit_le(&dentry_blk->dentry_bitmap, NR_DENTRY_IN_BLOCK, zero_start); if (zero_end - zero_start >= slots) return zero_start; bit_start = zero_end + 1; if (zero_end + 1 >= NR_DENTRY_IN_BLOCK) return NR_DENTRY_IN_BLOCK; goto next; }
int all_set(u8 *bitmap, unsigned start, unsigned count) { #if 1 /* Bitmap must be array of "unsigned long" */ unsigned limit = start + count; /* Find zero bit in range. If not found, all are non-zero. */ return find_next_zero_bit_le(bitmap, limit, start) == limit; #else unsigned limit = start + count; unsigned lmask = (-1 << (start & 7)) & 0xff; /* little endian!!! */ unsigned rmask = ~(-1 << (limit & 7)) & 0xff; /* little endian!!! */ unsigned loff = start >> 3, roff = limit >> 3; if (loff == roff) { unsigned mask = lmask & rmask; return (bitmap[loff] & mask) == mask; } for (unsigned i = loff + 1; i < roff; i++) if (bitmap[i] != 0xff) return 0; return (bitmap[loff] & lmask) == lmask && (!rmask || (bitmap[roff] & rmask) == rmask); #endif }
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ Function :me2fsAllocNewInode Input :struct inode *dir < vfs inode of directory > umode_t mode < file mode > const struct qstr *qstr < entry name for new inode > Output :void Return :struct inode* < new allocated inode > Description :allocate new inode _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ struct inode* me2fsAllocNewInode( struct inode *dir, umode_t mode, const struct qstr *qstr ) { struct super_block *sb; struct buffer_head *bitmap_bh; struct buffer_head *bh_gdesc; struct inode *inode; /* new inode */ ino_t ino; struct ext2_group_desc *gdesc; struct ext2_super_block *esb; struct me2fs_inode_info *mi; struct me2fs_sb_info *msi; unsigned long group; int i; int err; /* ------------------------------------------------------------------------ */ /* allocate vfs new inode */ /* ------------------------------------------------------------------------ */ sb = dir->i_sb; if( !( inode = new_inode( sb ) ) ) { return( ERR_PTR( -ENOMEM ) ); } bitmap_bh = NULL; ino = 0; msi = ME2FS_SB( sb ); if( S_ISDIR( mode ) ) { group = findDirectoryGroup( sb, dir ); } else { /* -------------------------------------------------------------------- */ /* as for now allocating inode for file is not support */ /* -------------------------------------------------------------------- */ err = -ENOSPC; goto fail; } if( group == -1 ) { err = -ENOSPC; goto fail; } for( i = 0 ; i < msi->s_groups_count ; i++ ) { brelse( bitmap_bh ); if( !( bitmap_bh = readInodeBitmap( sb, group ) ) ) { err = -EIO; goto fail; } ino = 0; /* -------------------------------------------------------------------- */ /* find free inode */ /* -------------------------------------------------------------------- */ repeat_in_this_group: ino = find_next_zero_bit_le( ( unsigned long* )bitmap_bh->b_data, msi->s_inodes_per_group, ino ); if( ME2FS_SB( sb )->s_inodes_per_group <= ino ) { /* cannot find ino. bitmap is already full */ group++; if( group <= msi->s_groups_count ) { group = 0; } continue; } /* -------------------------------------------------------------------- */ /* allocate inode atomically */ /* -------------------------------------------------------------------- */ if( ext2_set_bit_atomic( getSbBlockGroupLock( msi, group ), ( int )ino, bitmap_bh->b_data ) ) { /* ---------------------------------------------------------------- */ /* already set the bitmap */ /* ---------------------------------------------------------------- */ ino++; if( msi->s_inodes_per_group <= ino ) { /* the group has no entry, try next */ group++; if( msi->s_groups_count <= group ) { group = 0; } continue; } /* try to find in the same group */ goto repeat_in_this_group; } goto got; } /* ------------------------------------------------------------------------ */ /* cannot find free inode */ /* ------------------------------------------------------------------------ */ err = -ENOSPC; goto fail; /* ------------------------------------------------------------------------ */ /* found free inode */ /* ------------------------------------------------------------------------ */ got: mi = ME2FS_I( inode ); esb = msi->s_esb; mark_buffer_dirty( bitmap_bh ); if( sb->s_flags & MS_SYNCHRONOUS ) { sync_dirty_buffer( bitmap_bh ); } brelse( bitmap_bh ); /* ------------------------------------------------------------------------ */ /* get absolute inode number */ /* ------------------------------------------------------------------------ */ ino += ( group * ME2FS_SB( sb )->s_inodes_per_group ) + 1; if( ( ino < msi->s_first_ino ) || ( le32_to_cpu( esb->s_inodes_count ) < ino ) ) { ME2FS_ERROR( "<ME2FS>%s:insane inode number. ino=%lu,group=%lu\n", __func__, ( unsigned long )ino, group ); err = -EIO; goto fail; } /* ------------------------------------------------------------------------ */ /* update group descriptor */ /* ------------------------------------------------------------------------ */ gdesc = me2fsGetGroupDescriptor( sb, group ); bh_gdesc = me2fsGetGdescBufferCache( sb, group ); percpu_counter_add( &msi->s_freeinodes_counter, -1 ); if( S_ISDIR( mode ) ) { percpu_counter_inc( &msi->s_dirs_counter ); } spin_lock( getSbBlockGroupLock( msi, group ) ); { le16_add_cpu( &gdesc->bg_free_inodes_count, -1 ); if( S_ISDIR( mode ) ) { le16_add_cpu( &gdesc->bg_used_dirs_count, 1 ); } } spin_unlock( getSbBlockGroupLock( msi, group ) ); mark_buffer_dirty( bh_gdesc ); /* ------------------------------------------------------------------------ */ /* initialize vfs inode */ /* ------------------------------------------------------------------------ */ inode_init_owner( inode, dir, mode ); inode->i_ino = ino; inode->i_blocks = 0; inode->i_mtime = CURRENT_TIME_SEC; inode->i_atime = inode->i_mtime; inode->i_ctime = inode->i_mtime; /* ------------------------------------------------------------------------ */ /* initialize me2fs inode information */ /* ------------------------------------------------------------------------ */ memset( mi->i_data, 0, sizeof( mi->i_data ) ); mi->i_flags = ME2FS_I( dir )->i_flags & EXT2_FL_INHERITED; if( S_ISDIR( mode ) ) { /* do nothing */ } else if( S_ISREG( mode ) ) { mi->i_flags &= EXT2_REG_FLMASK; } else { mi->i_flags &= EXT2_OTHER_FLMASK; } mi->i_faddr = 0; mi->i_frag_no = 0; mi->i_frag_size = 0; mi->i_file_acl = 0; mi->i_dir_acl = 0; mi->i_dtime = 0; //mi->i_block_alloc_info = NULL; mi->i_state = EXT2_STATE_NEW; me2fsSetVfsInodeFlags( inode ); /* insert vfs inode to hash table */ if( insert_inode_locked( inode ) < 0 ) { ME2FS_ERROR( "<ME2FS>%s:inode number already in use[%lu]\n", __func__, ( unsigned long )ino ); err = -EIO; goto fail; } /* initialize quota */ #if 0 // quota dquot_initialize( inode ); if( dquot_alloc_inode( inode ) ) { goto fail_drop; } #endif #if 0 // acl /* initialize acl */ if( me2fsInitAcl( inde, dir ) ) { goto fail_free_drop; } #endif #if 0 // security /* initialize security */ if( me2fsInitSecurity( inode, dir, qstr ) ) { goto fail_free_drop; } #endif mark_inode_dirty( inode ); DBGPRINT( "<ME2FS>allocating new inode %lu\n", ( unsigned long )inode->i_ino ); #if 0 // preread me2fsPrereadInode( inode ); #endif return( inode ); /* ------------------------------------------------------------------------ */ /* allocation of new inode is failed */ /* ------------------------------------------------------------------------ */ fail: make_bad_inode( inode ); iput( inode ); return( ERR_PTR( err ) ); }
EXPORT_FOR_TESTS int convert_free_space_to_extents(struct btrfs_trans_handle *trans, struct btrfs_block_group_cache *block_group, struct btrfs_path *path) { struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_root *root = fs_info->free_space_root; struct btrfs_free_space_info *info; struct btrfs_key key, found_key; struct extent_buffer *leaf; unsigned long *bitmap; u64 start, end; u32 bitmap_size, flags, expected_extent_count; unsigned long nrbits, start_bit, end_bit; u32 extent_count = 0; int done = 0, nr; int ret; bitmap_size = free_space_bitmap_size(block_group->key.offset, fs_info->sectorsize); bitmap = alloc_bitmap(bitmap_size); if (!bitmap) { ret = -ENOMEM; goto out; } start = block_group->key.objectid; end = block_group->key.objectid + block_group->key.offset; key.objectid = end - 1; key.type = (u8)-1; key.offset = (u64)-1; while (!done) { ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1); if (ret) goto out; leaf = path->nodes[0]; nr = 0; path->slots[0]++; while (path->slots[0] > 0) { btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1); if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) { ASSERT(found_key.objectid == block_group->key.objectid); ASSERT(found_key.offset == block_group->key.offset); done = 1; break; } else if (found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) { unsigned long ptr; char *bitmap_cursor; u32 bitmap_pos, data_size; ASSERT(found_key.objectid >= start); ASSERT(found_key.objectid < end); ASSERT(found_key.objectid + found_key.offset <= end); bitmap_pos = div_u64(found_key.objectid - start, fs_info->sectorsize * BITS_PER_BYTE); bitmap_cursor = ((char *)bitmap) + bitmap_pos; data_size = free_space_bitmap_size(found_key.offset, fs_info->sectorsize); ptr = btrfs_item_ptr_offset(leaf, path->slots[0] - 1); read_extent_buffer(leaf, bitmap_cursor, ptr, data_size); nr++; path->slots[0]--; } else { ASSERT(0); } } ret = btrfs_del_items(trans, root, path, path->slots[0], nr); if (ret) goto out; btrfs_release_path(path); } info = search_free_space_info(trans, fs_info, block_group, path, 1); if (IS_ERR(info)) { ret = PTR_ERR(info); goto out; } leaf = path->nodes[0]; flags = btrfs_free_space_flags(leaf, info); flags &= ~BTRFS_FREE_SPACE_USING_BITMAPS; btrfs_set_free_space_flags(leaf, info, flags); expected_extent_count = btrfs_free_space_extent_count(leaf, info); btrfs_mark_buffer_dirty(leaf); btrfs_release_path(path); nrbits = div_u64(block_group->key.offset, block_group->fs_info->sectorsize); start_bit = find_next_bit_le(bitmap, nrbits, 0); while (start_bit < nrbits) { end_bit = find_next_zero_bit_le(bitmap, nrbits, start_bit); ASSERT(start_bit < end_bit); key.objectid = start + start_bit * block_group->fs_info->sectorsize; key.type = BTRFS_FREE_SPACE_EXTENT_KEY; key.offset = (end_bit - start_bit) * block_group->fs_info->sectorsize; ret = btrfs_insert_empty_item(trans, root, path, &key, 0); if (ret) goto out; btrfs_release_path(path); extent_count++; start_bit = find_next_bit_le(bitmap, nrbits, end_bit); } if (extent_count != expected_extent_count) { btrfs_err(fs_info, "incorrect extent count for %llu; counted %u, expected %u", block_group->key.objectid, extent_count, expected_extent_count); ASSERT(0); ret = -EIO; goto out; } ret = 0; out: kvfree(bitmap); if (ret) btrfs_abort_transaction(trans, ret); return ret; }