Loading fs/btrfs/extent-tree.c +13 −12 Original line number Diff line number Diff line Loading @@ -171,6 +171,7 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) struct btrfs_header *header; struct buffer_head *bh; if (!pending) { bh = sb_find_get_block(root->fs_info->sb, blocknr); if (bh) { header = btrfs_buffer_header(bh); Loading @@ -181,10 +182,10 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) } brelse(bh); } if (pending) err = set_radix_bit(&root->fs_info->pending_del_radix, blocknr); else err = set_radix_bit(&root->fs_info->pinned_radix, blocknr); } else { err = set_radix_bit(&root->fs_info->pending_del_radix, blocknr); } BUG_ON(err); return 0; } Loading Loading @@ -223,6 +224,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root BUG_ON(ei->refs == 0); refs = btrfs_extent_refs(ei) - 1; btrfs_set_extent_refs(ei, refs); mark_buffer_dirty(path.nodes[0]); if (refs == 0) { u64 super_blocks_used; Loading @@ -240,7 +242,6 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root if (ret) BUG(); } mark_buffer_dirty(path.nodes[0]); btrfs_release_path(extent_root, &path); finish_current_insert(trans, extent_root); return ret; Loading fs/btrfs/super.c +101 −6 Original line number Diff line number Diff line Loading @@ -28,11 +28,15 @@ static void btrfs_read_locked_inode(struct inode *inode) struct btrfs_inode_item *inode_item; struct btrfs_root *root = btrfs_sb(inode->i_sb); int ret; btrfs_init_path(&path); mutex_lock(&root->fs_info->fs_mutex); ret = btrfs_lookup_inode(NULL, root, &path, inode->i_ino, 0); if (ret) { make_bad_inode(inode); btrfs_release_path(root, &path); mutex_unlock(&root->fs_info->fs_mutex); make_bad_inode(inode); return; } inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), Loading @@ -53,6 +57,7 @@ static void btrfs_read_locked_inode(struct inode *inode) inode->i_blocks = btrfs_inode_nblocks(inode_item); inode->i_generation = btrfs_inode_generation(inode_item); btrfs_release_path(root, &path); mutex_unlock(&root->fs_info->fs_mutex); switch (inode->i_mode & S_IFMT) { #if 0 default: Loading Loading @@ -151,20 +156,85 @@ static int btrfs_free_inode(struct btrfs_trans_handle *trans, return ret; } static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct inode *inode) { int ret; struct btrfs_path path; struct btrfs_key key; struct btrfs_disk_key *found_key; struct btrfs_leaf *leaf; struct btrfs_file_extent_item *fi; u64 extent_start; u64 extent_num_blocks; /* FIXME, add redo link to tree so we don't leak on crash */ key.objectid = inode->i_ino; key.offset = (u64)-1; key.flags = 0; btrfs_set_key_type(&key, BTRFS_EXTENT_DATA_KEY); while(1) { btrfs_init_path(&path); ret = btrfs_search_slot(trans, root, &key, &path, -1, 1); if (ret < 0) { btrfs_release_path(root, &path); goto error; } if (ret > 0) { BUG_ON(path.slots[0] == 0); path.slots[0]--; } leaf = btrfs_buffer_leaf(path.nodes[0]); found_key = &leaf->items[path.slots[0]].key; if (btrfs_disk_key_objectid(found_key) != inode->i_ino) break; if (btrfs_disk_key_type(found_key) != BTRFS_EXTENT_DATA_KEY) break; if (btrfs_disk_key_offset(found_key) < inode->i_size) break; /* FIXME: add extent truncation */ if (btrfs_disk_key_offset(found_key) < inode->i_size) break; fi = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], struct btrfs_file_extent_item); extent_start = btrfs_file_extent_disk_blocknr(fi); extent_num_blocks = btrfs_file_extent_disk_num_blocks(fi); key.offset = btrfs_disk_key_offset(found_key) - 1; ret = btrfs_del_item(trans, root, &path); BUG_ON(ret); inode->i_blocks -= btrfs_file_extent_num_blocks(fi) >> 9; btrfs_release_path(root, &path); ret = btrfs_free_extent(trans, root, extent_start, extent_num_blocks, 0); BUG_ON(ret); if (btrfs_disk_key_offset(found_key) == 0) break; } btrfs_release_path(root, &path); ret = 0; error: return ret; } static void btrfs_delete_inode(struct inode *inode) { struct btrfs_trans_handle *trans; struct btrfs_root *root = btrfs_sb(inode->i_sb); int ret; truncate_inode_pages(&inode->i_data, 0); if (is_bad_inode(inode)) { goto no_delete; } inode->i_size = 0; if (inode->i_blocks) WARN_ON(1); mutex_lock(&root->fs_info->fs_mutex); trans = btrfs_start_transaction(root, 1); if (S_ISREG(inode->i_mode)) { ret = btrfs_truncate_in_trans(trans, root, inode); BUG_ON(ret); } btrfs_free_inode(trans, root, inode); btrfs_end_transaction(trans, root); mutex_unlock(&root->fs_info->fs_mutex); Loading @@ -173,7 +243,6 @@ static void btrfs_delete_inode(struct inode *inode) clear_inode(inode); } static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry, ino_t *ino) { Loading Loading @@ -688,6 +757,8 @@ static int btrfs_get_block(struct inode *inode, sector_t iblock, err = ret; goto out; } inode->i_blocks += inode->i_sb->s_blocksize >> 9; set_buffer_new(result); map_bh(result, inode->i_sb, blocknr); out: Loading Loading @@ -724,6 +795,30 @@ static int btrfs_writepage(struct page *page, struct writeback_control *wbc) return nobh_writepage(page, btrfs_get_block, wbc); } static void btrfs_truncate(struct inode *inode) { struct btrfs_root *root = btrfs_sb(inode->i_sb); int ret; struct btrfs_trans_handle *trans; if (!S_ISREG(inode->i_mode)) return; if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) return; nobh_truncate_page(inode->i_mapping, inode->i_size); /* FIXME, add redo link to tree so we don't leak on crash */ mutex_lock(&root->fs_info->fs_mutex); trans = btrfs_start_transaction(root, 1); ret = btrfs_truncate_in_trans(trans, root, inode); BUG_ON(ret); ret = btrfs_end_transaction(trans, root); BUG_ON(ret); mutex_unlock(&root->fs_info->fs_mutex); mark_inode_dirty(inode); } static int btrfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt) { Loading Loading @@ -772,7 +867,7 @@ static struct address_space_operations btrfs_aops = { }; static struct inode_operations btrfs_file_inode_operations = { .truncate = NULL, .truncate = btrfs_truncate, }; static struct file_operations btrfs_file_operations = { Loading Loading
fs/btrfs/extent-tree.c +13 −12 Original line number Diff line number Diff line Loading @@ -171,6 +171,7 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) struct btrfs_header *header; struct buffer_head *bh; if (!pending) { bh = sb_find_get_block(root->fs_info->sb, blocknr); if (bh) { header = btrfs_buffer_header(bh); Loading @@ -181,10 +182,10 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) } brelse(bh); } if (pending) err = set_radix_bit(&root->fs_info->pending_del_radix, blocknr); else err = set_radix_bit(&root->fs_info->pinned_radix, blocknr); } else { err = set_radix_bit(&root->fs_info->pending_del_radix, blocknr); } BUG_ON(err); return 0; } Loading Loading @@ -223,6 +224,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root BUG_ON(ei->refs == 0); refs = btrfs_extent_refs(ei) - 1; btrfs_set_extent_refs(ei, refs); mark_buffer_dirty(path.nodes[0]); if (refs == 0) { u64 super_blocks_used; Loading @@ -240,7 +242,6 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root if (ret) BUG(); } mark_buffer_dirty(path.nodes[0]); btrfs_release_path(extent_root, &path); finish_current_insert(trans, extent_root); return ret; Loading
fs/btrfs/super.c +101 −6 Original line number Diff line number Diff line Loading @@ -28,11 +28,15 @@ static void btrfs_read_locked_inode(struct inode *inode) struct btrfs_inode_item *inode_item; struct btrfs_root *root = btrfs_sb(inode->i_sb); int ret; btrfs_init_path(&path); mutex_lock(&root->fs_info->fs_mutex); ret = btrfs_lookup_inode(NULL, root, &path, inode->i_ino, 0); if (ret) { make_bad_inode(inode); btrfs_release_path(root, &path); mutex_unlock(&root->fs_info->fs_mutex); make_bad_inode(inode); return; } inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), Loading @@ -53,6 +57,7 @@ static void btrfs_read_locked_inode(struct inode *inode) inode->i_blocks = btrfs_inode_nblocks(inode_item); inode->i_generation = btrfs_inode_generation(inode_item); btrfs_release_path(root, &path); mutex_unlock(&root->fs_info->fs_mutex); switch (inode->i_mode & S_IFMT) { #if 0 default: Loading Loading @@ -151,20 +156,85 @@ static int btrfs_free_inode(struct btrfs_trans_handle *trans, return ret; } static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct inode *inode) { int ret; struct btrfs_path path; struct btrfs_key key; struct btrfs_disk_key *found_key; struct btrfs_leaf *leaf; struct btrfs_file_extent_item *fi; u64 extent_start; u64 extent_num_blocks; /* FIXME, add redo link to tree so we don't leak on crash */ key.objectid = inode->i_ino; key.offset = (u64)-1; key.flags = 0; btrfs_set_key_type(&key, BTRFS_EXTENT_DATA_KEY); while(1) { btrfs_init_path(&path); ret = btrfs_search_slot(trans, root, &key, &path, -1, 1); if (ret < 0) { btrfs_release_path(root, &path); goto error; } if (ret > 0) { BUG_ON(path.slots[0] == 0); path.slots[0]--; } leaf = btrfs_buffer_leaf(path.nodes[0]); found_key = &leaf->items[path.slots[0]].key; if (btrfs_disk_key_objectid(found_key) != inode->i_ino) break; if (btrfs_disk_key_type(found_key) != BTRFS_EXTENT_DATA_KEY) break; if (btrfs_disk_key_offset(found_key) < inode->i_size) break; /* FIXME: add extent truncation */ if (btrfs_disk_key_offset(found_key) < inode->i_size) break; fi = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0], struct btrfs_file_extent_item); extent_start = btrfs_file_extent_disk_blocknr(fi); extent_num_blocks = btrfs_file_extent_disk_num_blocks(fi); key.offset = btrfs_disk_key_offset(found_key) - 1; ret = btrfs_del_item(trans, root, &path); BUG_ON(ret); inode->i_blocks -= btrfs_file_extent_num_blocks(fi) >> 9; btrfs_release_path(root, &path); ret = btrfs_free_extent(trans, root, extent_start, extent_num_blocks, 0); BUG_ON(ret); if (btrfs_disk_key_offset(found_key) == 0) break; } btrfs_release_path(root, &path); ret = 0; error: return ret; } static void btrfs_delete_inode(struct inode *inode) { struct btrfs_trans_handle *trans; struct btrfs_root *root = btrfs_sb(inode->i_sb); int ret; truncate_inode_pages(&inode->i_data, 0); if (is_bad_inode(inode)) { goto no_delete; } inode->i_size = 0; if (inode->i_blocks) WARN_ON(1); mutex_lock(&root->fs_info->fs_mutex); trans = btrfs_start_transaction(root, 1); if (S_ISREG(inode->i_mode)) { ret = btrfs_truncate_in_trans(trans, root, inode); BUG_ON(ret); } btrfs_free_inode(trans, root, inode); btrfs_end_transaction(trans, root); mutex_unlock(&root->fs_info->fs_mutex); Loading @@ -173,7 +243,6 @@ static void btrfs_delete_inode(struct inode *inode) clear_inode(inode); } static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry, ino_t *ino) { Loading Loading @@ -688,6 +757,8 @@ static int btrfs_get_block(struct inode *inode, sector_t iblock, err = ret; goto out; } inode->i_blocks += inode->i_sb->s_blocksize >> 9; set_buffer_new(result); map_bh(result, inode->i_sb, blocknr); out: Loading Loading @@ -724,6 +795,30 @@ static int btrfs_writepage(struct page *page, struct writeback_control *wbc) return nobh_writepage(page, btrfs_get_block, wbc); } static void btrfs_truncate(struct inode *inode) { struct btrfs_root *root = btrfs_sb(inode->i_sb); int ret; struct btrfs_trans_handle *trans; if (!S_ISREG(inode->i_mode)) return; if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) return; nobh_truncate_page(inode->i_mapping, inode->i_size); /* FIXME, add redo link to tree so we don't leak on crash */ mutex_lock(&root->fs_info->fs_mutex); trans = btrfs_start_transaction(root, 1); ret = btrfs_truncate_in_trans(trans, root, inode); BUG_ON(ret); ret = btrfs_end_transaction(trans, root); BUG_ON(ret); mutex_unlock(&root->fs_info->fs_mutex); mark_inode_dirty(inode); } static int btrfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt) { Loading Loading @@ -772,7 +867,7 @@ static struct address_space_operations btrfs_aops = { }; static struct inode_operations btrfs_file_inode_operations = { .truncate = NULL, .truncate = btrfs_truncate, }; static struct file_operations btrfs_file_operations = { Loading