Loading fs/btrfs/extent-tree.c +4 −2 Original line number Diff line number Diff line Loading @@ -3997,7 +3997,7 @@ static int reserve_metadata_bytes(struct btrfs_root *root, * We make the other tasks wait for the flush only when we can flush * all things. */ if (ret && flush == BTRFS_RESERVE_FLUSH_ALL) { if (ret && flush != BTRFS_RESERVE_NO_FLUSH) { flushing = true; space_info->flush = 1; } Loading Loading @@ -5560,7 +5560,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, int empty_cluster = 2 * 1024 * 1024; struct btrfs_space_info *space_info; int loop = 0; int index = 0; int index = __get_raid_index(data); int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? RESERVE_ALLOC_NO_ACCOUNT : RESERVE_ALLOC; bool found_uncached_bg = false; Loading Loading @@ -6788,11 +6788,13 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, &wc->flags[level]); if (ret < 0) { btrfs_tree_unlock_rw(eb, path->locks[level]); path->locks[level] = 0; return ret; } BUG_ON(wc->refs[level] == 0); if (wc->refs[level] == 1) { btrfs_tree_unlock_rw(eb, path->locks[level]); path->locks[level] = 0; return 1; } } Loading fs/btrfs/file.c +7 −3 Original line number Diff line number Diff line Loading @@ -2242,6 +2242,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) if (lockend <= lockstart) lockend = lockstart + root->sectorsize; lockend--; len = lockend - lockstart + 1; len = max_t(u64, len, root->sectorsize); Loading Loading @@ -2308,11 +2309,14 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) } } if (!test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) { *offset = start; free_extent_map(em); break; } } } start = em->start + em->len; last_end = em->start + em->len; Loading fs/btrfs/inode.c +61 −21 Original line number Diff line number Diff line Loading @@ -88,7 +88,7 @@ static unsigned char btrfs_type_by_mode[S_IFMT >> S_SHIFT] = { [S_IFLNK >> S_SHIFT] = BTRFS_FT_SYMLINK, }; static int btrfs_setsize(struct inode *inode, loff_t newsize); static int btrfs_setsize(struct inode *inode, struct iattr *attr); static int btrfs_truncate(struct inode *inode); static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent); static noinline int cow_file_range(struct inode *inode, Loading Loading @@ -2478,6 +2478,18 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) continue; } nr_truncate++; /* 1 for the orphan item deletion. */ trans = btrfs_start_transaction(root, 1); if (IS_ERR(trans)) { ret = PTR_ERR(trans); goto out; } ret = btrfs_orphan_add(trans, inode); btrfs_end_transaction(trans, root); if (ret) goto out; ret = btrfs_truncate(inode); } else { nr_unlink++; Loading Loading @@ -3665,6 +3677,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) block_end - cur_offset, 0); if (IS_ERR(em)) { err = PTR_ERR(em); em = NULL; break; } last_byte = min(extent_map_end(em), block_end); Loading Loading @@ -3748,16 +3761,27 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) return err; } static int btrfs_setsize(struct inode *inode, loff_t newsize) static int btrfs_setsize(struct inode *inode, struct iattr *attr) { struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_trans_handle *trans; loff_t oldsize = i_size_read(inode); loff_t newsize = attr->ia_size; int mask = attr->ia_valid; int ret; if (newsize == oldsize) return 0; /* * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a * special case where we need to update the times despite not having * these flags set. For all other operations the VFS set these flags * explicitly if it wants a timestamp update. */ if (newsize != oldsize && (!(mask & (ATTR_CTIME | ATTR_MTIME)))) inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); if (newsize > oldsize) { truncate_pagecache(inode, oldsize, newsize); ret = btrfs_cont_expand(inode, oldsize, newsize); Loading @@ -3783,9 +3807,34 @@ static int btrfs_setsize(struct inode *inode, loff_t newsize) set_bit(BTRFS_INODE_ORDERED_DATA_CLOSE, &BTRFS_I(inode)->runtime_flags); /* * 1 for the orphan item we're going to add * 1 for the orphan item deletion. */ trans = btrfs_start_transaction(root, 2); if (IS_ERR(trans)) return PTR_ERR(trans); /* * We need to do this in case we fail at _any_ point during the * actual truncate. Once we do the truncate_setsize we could * invalidate pages which forces any outstanding ordered io to * be instantly completed which will give us extents that need * to be truncated. If we fail to get an orphan inode down we * could have left over extents that were never meant to live, * so we need to garuntee from this point on that everything * will be consistent. */ ret = btrfs_orphan_add(trans, inode); btrfs_end_transaction(trans, root); if (ret) return ret; /* we don't support swapfiles, so vmtruncate shouldn't fail */ truncate_setsize(inode, newsize); ret = btrfs_truncate(inode); if (ret && inode->i_nlink) btrfs_orphan_del(NULL, inode); } return ret; Loading @@ -3805,7 +3854,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) return err; if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { err = btrfs_setsize(inode, attr->ia_size); err = btrfs_setsize(inode, attr); if (err) return err; } Loading Loading @@ -5586,10 +5635,13 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag return em; if (em) { /* * if our em maps to a hole, there might * actually be delalloc bytes behind it * if our em maps to * - a hole or * - a pre-alloc extent, * there might actually be delalloc bytes behind it. */ if (em->block_start != EXTENT_MAP_HOLE) if (em->block_start != EXTENT_MAP_HOLE && !test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) return em; else hole_em = em; Loading Loading @@ -5671,6 +5723,8 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag */ em->block_start = hole_em->block_start; em->block_len = hole_len; if (test_bit(EXTENT_FLAG_PREALLOC, &hole_em->flags)) set_bit(EXTENT_FLAG_PREALLOC, &em->flags); } else { em->start = range_start; em->len = found; Loading Loading @@ -6929,11 +6983,9 @@ static int btrfs_truncate(struct inode *inode) /* * 1 for the truncate slack space * 1 for the orphan item we're going to add * 1 for the orphan item deletion * 1 for updating the inode. */ trans = btrfs_start_transaction(root, 4); trans = btrfs_start_transaction(root, 2); if (IS_ERR(trans)) { err = PTR_ERR(trans); goto out; Loading @@ -6944,12 +6996,6 @@ static int btrfs_truncate(struct inode *inode) min_size); BUG_ON(ret); ret = btrfs_orphan_add(trans, inode); if (ret) { btrfs_end_transaction(trans, root); goto out; } /* * setattr is responsible for setting the ordered_data_close flag, * but that is only tested during the last file release. That Loading Loading @@ -7018,12 +7064,6 @@ static int btrfs_truncate(struct inode *inode) ret = btrfs_orphan_del(trans, inode); if (ret) err = ret; } else if (ret && inode->i_nlink > 0) { /* * Failed to do the truncate, remove us from the in memory * orphan list. */ ret = btrfs_orphan_del(NULL, inode); } if (trans) { Loading fs/btrfs/ioctl.c +15 −7 Original line number Diff line number Diff line Loading @@ -1339,6 +1339,7 @@ static noinline int btrfs_ioctl_resize(struct file *file, if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, 1)) { pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n"); mnt_drop_write_file(file); return -EINPROGRESS; } Loading @@ -1362,6 +1363,7 @@ static noinline int btrfs_ioctl_resize(struct file *file, printk(KERN_INFO "btrfs: resizing devid %llu\n", (unsigned long long)devid); } device = btrfs_find_device(root->fs_info, devid, NULL, NULL); if (!device) { printk(KERN_INFO "btrfs: resizer unable to find device %llu\n", Loading @@ -1369,9 +1371,10 @@ static noinline int btrfs_ioctl_resize(struct file *file, ret = -EINVAL; goto out_free; } if (device->fs_devices && device->fs_devices->seeding) { if (!device->writeable) { printk(KERN_INFO "btrfs: resizer unable to apply on " "seeding device %llu\n", "readonly device %llu\n", (unsigned long long)devid); ret = -EINVAL; goto out_free; Loading Loading @@ -2095,12 +2098,12 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, err = inode_permission(inode, MAY_WRITE | MAY_EXEC); if (err) goto out_dput; } /* check if subvolume may be deleted by a non-root user */ /* check if subvolume may be deleted by a user */ err = btrfs_may_delete(dir, dentry, 1); if (err) goto out_dput; } if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) { err = -EINVAL; Loading Loading @@ -3698,6 +3701,11 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg) goto drop_write; } if (!sa->qgroupid) { ret = -EINVAL; goto out; } trans = btrfs_join_transaction(root); if (IS_ERR(trans)) { ret = PTR_ERR(trans); Loading fs/btrfs/send.c +3 −1 Original line number Diff line number Diff line Loading @@ -1814,8 +1814,10 @@ static int name_cache_insert(struct send_ctx *sctx, (unsigned long)nce->ino); if (!nce_head) { nce_head = kmalloc(sizeof(*nce_head), GFP_NOFS); if (!nce_head) if (!nce_head) { kfree(nce); return -ENOMEM; } INIT_LIST_HEAD(nce_head); ret = radix_tree_insert(&sctx->name_cache, nce->ino, nce_head); Loading Loading
fs/btrfs/extent-tree.c +4 −2 Original line number Diff line number Diff line Loading @@ -3997,7 +3997,7 @@ static int reserve_metadata_bytes(struct btrfs_root *root, * We make the other tasks wait for the flush only when we can flush * all things. */ if (ret && flush == BTRFS_RESERVE_FLUSH_ALL) { if (ret && flush != BTRFS_RESERVE_NO_FLUSH) { flushing = true; space_info->flush = 1; } Loading Loading @@ -5560,7 +5560,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, int empty_cluster = 2 * 1024 * 1024; struct btrfs_space_info *space_info; int loop = 0; int index = 0; int index = __get_raid_index(data); int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? RESERVE_ALLOC_NO_ACCOUNT : RESERVE_ALLOC; bool found_uncached_bg = false; Loading Loading @@ -6788,11 +6788,13 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, &wc->flags[level]); if (ret < 0) { btrfs_tree_unlock_rw(eb, path->locks[level]); path->locks[level] = 0; return ret; } BUG_ON(wc->refs[level] == 0); if (wc->refs[level] == 1) { btrfs_tree_unlock_rw(eb, path->locks[level]); path->locks[level] = 0; return 1; } } Loading
fs/btrfs/file.c +7 −3 Original line number Diff line number Diff line Loading @@ -2242,6 +2242,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) if (lockend <= lockstart) lockend = lockstart + root->sectorsize; lockend--; len = lockend - lockstart + 1; len = max_t(u64, len, root->sectorsize); Loading Loading @@ -2308,11 +2309,14 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) } } if (!test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) { *offset = start; free_extent_map(em); break; } } } start = em->start + em->len; last_end = em->start + em->len; Loading
fs/btrfs/inode.c +61 −21 Original line number Diff line number Diff line Loading @@ -88,7 +88,7 @@ static unsigned char btrfs_type_by_mode[S_IFMT >> S_SHIFT] = { [S_IFLNK >> S_SHIFT] = BTRFS_FT_SYMLINK, }; static int btrfs_setsize(struct inode *inode, loff_t newsize); static int btrfs_setsize(struct inode *inode, struct iattr *attr); static int btrfs_truncate(struct inode *inode); static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent); static noinline int cow_file_range(struct inode *inode, Loading Loading @@ -2478,6 +2478,18 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) continue; } nr_truncate++; /* 1 for the orphan item deletion. */ trans = btrfs_start_transaction(root, 1); if (IS_ERR(trans)) { ret = PTR_ERR(trans); goto out; } ret = btrfs_orphan_add(trans, inode); btrfs_end_transaction(trans, root); if (ret) goto out; ret = btrfs_truncate(inode); } else { nr_unlink++; Loading Loading @@ -3665,6 +3677,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) block_end - cur_offset, 0); if (IS_ERR(em)) { err = PTR_ERR(em); em = NULL; break; } last_byte = min(extent_map_end(em), block_end); Loading Loading @@ -3748,16 +3761,27 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) return err; } static int btrfs_setsize(struct inode *inode, loff_t newsize) static int btrfs_setsize(struct inode *inode, struct iattr *attr) { struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_trans_handle *trans; loff_t oldsize = i_size_read(inode); loff_t newsize = attr->ia_size; int mask = attr->ia_valid; int ret; if (newsize == oldsize) return 0; /* * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a * special case where we need to update the times despite not having * these flags set. For all other operations the VFS set these flags * explicitly if it wants a timestamp update. */ if (newsize != oldsize && (!(mask & (ATTR_CTIME | ATTR_MTIME)))) inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); if (newsize > oldsize) { truncate_pagecache(inode, oldsize, newsize); ret = btrfs_cont_expand(inode, oldsize, newsize); Loading @@ -3783,9 +3807,34 @@ static int btrfs_setsize(struct inode *inode, loff_t newsize) set_bit(BTRFS_INODE_ORDERED_DATA_CLOSE, &BTRFS_I(inode)->runtime_flags); /* * 1 for the orphan item we're going to add * 1 for the orphan item deletion. */ trans = btrfs_start_transaction(root, 2); if (IS_ERR(trans)) return PTR_ERR(trans); /* * We need to do this in case we fail at _any_ point during the * actual truncate. Once we do the truncate_setsize we could * invalidate pages which forces any outstanding ordered io to * be instantly completed which will give us extents that need * to be truncated. If we fail to get an orphan inode down we * could have left over extents that were never meant to live, * so we need to garuntee from this point on that everything * will be consistent. */ ret = btrfs_orphan_add(trans, inode); btrfs_end_transaction(trans, root); if (ret) return ret; /* we don't support swapfiles, so vmtruncate shouldn't fail */ truncate_setsize(inode, newsize); ret = btrfs_truncate(inode); if (ret && inode->i_nlink) btrfs_orphan_del(NULL, inode); } return ret; Loading @@ -3805,7 +3854,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) return err; if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { err = btrfs_setsize(inode, attr->ia_size); err = btrfs_setsize(inode, attr); if (err) return err; } Loading Loading @@ -5586,10 +5635,13 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag return em; if (em) { /* * if our em maps to a hole, there might * actually be delalloc bytes behind it * if our em maps to * - a hole or * - a pre-alloc extent, * there might actually be delalloc bytes behind it. */ if (em->block_start != EXTENT_MAP_HOLE) if (em->block_start != EXTENT_MAP_HOLE && !test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) return em; else hole_em = em; Loading Loading @@ -5671,6 +5723,8 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag */ em->block_start = hole_em->block_start; em->block_len = hole_len; if (test_bit(EXTENT_FLAG_PREALLOC, &hole_em->flags)) set_bit(EXTENT_FLAG_PREALLOC, &em->flags); } else { em->start = range_start; em->len = found; Loading Loading @@ -6929,11 +6983,9 @@ static int btrfs_truncate(struct inode *inode) /* * 1 for the truncate slack space * 1 for the orphan item we're going to add * 1 for the orphan item deletion * 1 for updating the inode. */ trans = btrfs_start_transaction(root, 4); trans = btrfs_start_transaction(root, 2); if (IS_ERR(trans)) { err = PTR_ERR(trans); goto out; Loading @@ -6944,12 +6996,6 @@ static int btrfs_truncate(struct inode *inode) min_size); BUG_ON(ret); ret = btrfs_orphan_add(trans, inode); if (ret) { btrfs_end_transaction(trans, root); goto out; } /* * setattr is responsible for setting the ordered_data_close flag, * but that is only tested during the last file release. That Loading Loading @@ -7018,12 +7064,6 @@ static int btrfs_truncate(struct inode *inode) ret = btrfs_orphan_del(trans, inode); if (ret) err = ret; } else if (ret && inode->i_nlink > 0) { /* * Failed to do the truncate, remove us from the in memory * orphan list. */ ret = btrfs_orphan_del(NULL, inode); } if (trans) { Loading
fs/btrfs/ioctl.c +15 −7 Original line number Diff line number Diff line Loading @@ -1339,6 +1339,7 @@ static noinline int btrfs_ioctl_resize(struct file *file, if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, 1)) { pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n"); mnt_drop_write_file(file); return -EINPROGRESS; } Loading @@ -1362,6 +1363,7 @@ static noinline int btrfs_ioctl_resize(struct file *file, printk(KERN_INFO "btrfs: resizing devid %llu\n", (unsigned long long)devid); } device = btrfs_find_device(root->fs_info, devid, NULL, NULL); if (!device) { printk(KERN_INFO "btrfs: resizer unable to find device %llu\n", Loading @@ -1369,9 +1371,10 @@ static noinline int btrfs_ioctl_resize(struct file *file, ret = -EINVAL; goto out_free; } if (device->fs_devices && device->fs_devices->seeding) { if (!device->writeable) { printk(KERN_INFO "btrfs: resizer unable to apply on " "seeding device %llu\n", "readonly device %llu\n", (unsigned long long)devid); ret = -EINVAL; goto out_free; Loading Loading @@ -2095,12 +2098,12 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, err = inode_permission(inode, MAY_WRITE | MAY_EXEC); if (err) goto out_dput; } /* check if subvolume may be deleted by a non-root user */ /* check if subvolume may be deleted by a user */ err = btrfs_may_delete(dir, dentry, 1); if (err) goto out_dput; } if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) { err = -EINVAL; Loading Loading @@ -3698,6 +3701,11 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg) goto drop_write; } if (!sa->qgroupid) { ret = -EINVAL; goto out; } trans = btrfs_join_transaction(root); if (IS_ERR(trans)) { ret = PTR_ERR(trans); Loading
fs/btrfs/send.c +3 −1 Original line number Diff line number Diff line Loading @@ -1814,8 +1814,10 @@ static int name_cache_insert(struct send_ctx *sctx, (unsigned long)nce->ino); if (!nce_head) { nce_head = kmalloc(sizeof(*nce_head), GFP_NOFS); if (!nce_head) if (!nce_head) { kfree(nce); return -ENOMEM; } INIT_LIST_HEAD(nce_head); ret = radix_tree_insert(&sctx->name_cache, nce->ino, nce_head); Loading