aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/btrfs_inode.h6
-rw-r--r--fs/btrfs/file-item.c4
-rw-r--r--fs/btrfs/file.c25
-rw-r--r--fs/btrfs/free-space-cache.c4
-rw-r--r--fs/btrfs/inode.c40
-rw-r--r--fs/btrfs/ioctl.c40
-rw-r--r--fs/btrfs/transaction.c4
-rw-r--r--fs/btrfs/xattr.c9
8 files changed, 98 insertions, 34 deletions
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 502b9e988679..d9f99a16edd6 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -176,7 +176,11 @@ static inline u64 btrfs_ino(struct inode *inode)
176{ 176{
177 u64 ino = BTRFS_I(inode)->location.objectid; 177 u64 ino = BTRFS_I(inode)->location.objectid;
178 178
179 if (ino <= BTRFS_FIRST_FREE_OBJECTID) 179 /*
180 * !ino: btree_inode
181 * type == BTRFS_ROOT_ITEM_KEY: subvol dir
182 */
183 if (!ino || BTRFS_I(inode)->location.type == BTRFS_ROOT_ITEM_KEY)
180 ino = inode->i_ino; 184 ino = inode->i_ino;
181 return ino; 185 return ino;
182} 186}
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index b910694f61ed..a1cb7821becd 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -183,8 +183,10 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
183 * read from the commit root and sidestep a nasty deadlock 183 * read from the commit root and sidestep a nasty deadlock
184 * between reading the free space cache and updating the csum tree. 184 * between reading the free space cache and updating the csum tree.
185 */ 185 */
186 if (btrfs_is_free_space_inode(root, inode)) 186 if (btrfs_is_free_space_inode(root, inode)) {
187 path->search_commit_root = 1; 187 path->search_commit_root = 1;
188 path->skip_locking = 1;
189 }
188 190
189 disk_bytenr = (u64)bio->bi_sector << 9; 191 disk_bytenr = (u64)bio->bi_sector << 9;
190 if (dio) 192 if (dio)
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index e7872e485f13..a381cd22f518 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1075,12 +1075,6 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file,
1075 start_pos = pos & ~((u64)root->sectorsize - 1); 1075 start_pos = pos & ~((u64)root->sectorsize - 1);
1076 last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT; 1076 last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT;
1077 1077
1078 if (start_pos > inode->i_size) {
1079 err = btrfs_cont_expand(inode, i_size_read(inode), start_pos);
1080 if (err)
1081 return err;
1082 }
1083
1084again: 1078again:
1085 for (i = 0; i < num_pages; i++) { 1079 for (i = 0; i < num_pages; i++) {
1086 pages[i] = find_or_create_page(inode->i_mapping, index + i, 1080 pages[i] = find_or_create_page(inode->i_mapping, index + i,
@@ -1338,6 +1332,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1338 struct inode *inode = fdentry(file)->d_inode; 1332 struct inode *inode = fdentry(file)->d_inode;
1339 struct btrfs_root *root = BTRFS_I(inode)->root; 1333 struct btrfs_root *root = BTRFS_I(inode)->root;
1340 loff_t *ppos = &iocb->ki_pos; 1334 loff_t *ppos = &iocb->ki_pos;
1335 u64 start_pos;
1341 ssize_t num_written = 0; 1336 ssize_t num_written = 0;
1342 ssize_t err = 0; 1337 ssize_t err = 0;
1343 size_t count, ocount; 1338 size_t count, ocount;
@@ -1386,6 +1381,15 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
1386 file_update_time(file); 1381 file_update_time(file);
1387 BTRFS_I(inode)->sequence++; 1382 BTRFS_I(inode)->sequence++;
1388 1383
1384 start_pos = round_down(pos, root->sectorsize);
1385 if (start_pos > i_size_read(inode)) {
1386 err = btrfs_cont_expand(inode, i_size_read(inode), start_pos);
1387 if (err) {
1388 mutex_unlock(&inode->i_mutex);
1389 goto out;
1390 }
1391 }
1392
1389 if (unlikely(file->f_flags & O_DIRECT)) { 1393 if (unlikely(file->f_flags & O_DIRECT)) {
1390 num_written = __btrfs_direct_write(iocb, iov, nr_segs, 1394 num_written = __btrfs_direct_write(iocb, iov, nr_segs,
1391 pos, ppos, count, ocount); 1395 pos, ppos, count, ocount);
@@ -1813,6 +1817,11 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin)
1813 goto out; 1817 goto out;
1814 case SEEK_DATA: 1818 case SEEK_DATA:
1815 case SEEK_HOLE: 1819 case SEEK_HOLE:
1820 if (offset >= i_size_read(inode)) {
1821 mutex_unlock(&inode->i_mutex);
1822 return -ENXIO;
1823 }
1824
1816 ret = find_desired_extent(inode, &offset, origin); 1825 ret = find_desired_extent(inode, &offset, origin);
1817 if (ret) { 1826 if (ret) {
1818 mutex_unlock(&inode->i_mutex); 1827 mutex_unlock(&inode->i_mutex);
@@ -1821,11 +1830,11 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin)
1821 } 1830 }
1822 1831
1823 if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) { 1832 if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) {
1824 ret = -EINVAL; 1833 offset = -EINVAL;
1825 goto out; 1834 goto out;
1826 } 1835 }
1827 if (offset > inode->i_sb->s_maxbytes) { 1836 if (offset > inode->i_sb->s_maxbytes) {
1828 ret = -EINVAL; 1837 offset = -EINVAL;
1829 goto out; 1838 goto out;
1830 } 1839 }
1831 1840
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 6a265b9f85f2..41ac927401d0 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -190,9 +190,11 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
190 struct btrfs_path *path, 190 struct btrfs_path *path,
191 struct inode *inode) 191 struct inode *inode)
192{ 192{
193 struct btrfs_block_rsv *rsv;
193 loff_t oldsize; 194 loff_t oldsize;
194 int ret = 0; 195 int ret = 0;
195 196
197 rsv = trans->block_rsv;
196 trans->block_rsv = root->orphan_block_rsv; 198 trans->block_rsv = root->orphan_block_rsv;
197 ret = btrfs_block_rsv_check(trans, root, 199 ret = btrfs_block_rsv_check(trans, root,
198 root->orphan_block_rsv, 200 root->orphan_block_rsv,
@@ -210,6 +212,8 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
210 */ 212 */
211 ret = btrfs_truncate_inode_items(trans, root, inode, 213 ret = btrfs_truncate_inode_items(trans, root, inode,
212 0, BTRFS_EXTENT_DATA_KEY); 214 0, BTRFS_EXTENT_DATA_KEY);
215
216 trans->block_rsv = rsv;
213 if (ret) { 217 if (ret) {
214 WARN_ON(1); 218 WARN_ON(1);
215 return ret; 219 return ret;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 0ccc7438ad34..b2d004ad66a0 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1786,7 +1786,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
1786 &ordered_extent->list); 1786 &ordered_extent->list);
1787 1787
1788 ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); 1788 ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent);
1789 if (!ret) { 1789 if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) {
1790 ret = btrfs_update_inode(trans, root, inode); 1790 ret = btrfs_update_inode(trans, root, inode);
1791 BUG_ON(ret); 1791 BUG_ON(ret);
1792 } 1792 }
@@ -3510,15 +3510,19 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
3510 err = btrfs_drop_extents(trans, inode, cur_offset, 3510 err = btrfs_drop_extents(trans, inode, cur_offset,
3511 cur_offset + hole_size, 3511 cur_offset + hole_size,
3512 &hint_byte, 1); 3512 &hint_byte, 1);
3513 if (err) 3513 if (err) {
3514 btrfs_end_transaction(trans, root);
3514 break; 3515 break;
3516 }
3515 3517
3516 err = btrfs_insert_file_extent(trans, root, 3518 err = btrfs_insert_file_extent(trans, root,
3517 btrfs_ino(inode), cur_offset, 0, 3519 btrfs_ino(inode), cur_offset, 0,
3518 0, hole_size, 0, hole_size, 3520 0, hole_size, 0, hole_size,
3519 0, 0, 0); 3521 0, 0, 0);
3520 if (err) 3522 if (err) {
3523 btrfs_end_transaction(trans, root);
3521 break; 3524 break;
3525 }
3522 3526
3523 btrfs_drop_extent_cache(inode, hole_start, 3527 btrfs_drop_extent_cache(inode, hole_start,
3524 last_byte - 1, 0); 3528 last_byte - 1, 0);
@@ -3952,7 +3956,6 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
3952 struct btrfs_root *root, int *new) 3956 struct btrfs_root *root, int *new)
3953{ 3957{
3954 struct inode *inode; 3958 struct inode *inode;
3955 int bad_inode = 0;
3956 3959
3957 inode = btrfs_iget_locked(s, location->objectid, root); 3960 inode = btrfs_iget_locked(s, location->objectid, root);
3958 if (!inode) 3961 if (!inode)
@@ -3968,15 +3971,12 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
3968 if (new) 3971 if (new)
3969 *new = 1; 3972 *new = 1;
3970 } else { 3973 } else {
3971 bad_inode = 1; 3974 unlock_new_inode(inode);
3975 iput(inode);
3976 inode = ERR_PTR(-ESTALE);
3972 } 3977 }
3973 } 3978 }
3974 3979
3975 if (bad_inode) {
3976 iput(inode);
3977 inode = ERR_PTR(-ESTALE);
3978 }
3979
3980 return inode; 3980 return inode;
3981} 3981}
3982 3982
@@ -4018,7 +4018,8 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
4018 memcpy(&location, dentry->d_fsdata, sizeof(struct btrfs_key)); 4018 memcpy(&location, dentry->d_fsdata, sizeof(struct btrfs_key));
4019 kfree(dentry->d_fsdata); 4019 kfree(dentry->d_fsdata);
4020 dentry->d_fsdata = NULL; 4020 dentry->d_fsdata = NULL;
4021 d_clear_need_lookup(dentry); 4021 /* This thing is hashed, drop it for now */
4022 d_drop(dentry);
4022 } else { 4023 } else {
4023 ret = btrfs_inode_by_name(dir, dentry, &location); 4024 ret = btrfs_inode_by_name(dir, dentry, &location);
4024 } 4025 }
@@ -4085,7 +4086,15 @@ static void btrfs_dentry_release(struct dentry *dentry)
4085static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, 4086static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
4086 struct nameidata *nd) 4087 struct nameidata *nd)
4087{ 4088{
4088 return d_splice_alias(btrfs_lookup_dentry(dir, dentry), dentry); 4089 struct dentry *ret;
4090
4091 ret = d_splice_alias(btrfs_lookup_dentry(dir, dentry), dentry);
4092 if (unlikely(d_need_lookup(dentry))) {
4093 spin_lock(&dentry->d_lock);
4094 dentry->d_flags &= ~DCACHE_NEED_LOOKUP;
4095 spin_unlock(&dentry->d_lock);
4096 }
4097 return ret;
4089} 4098}
4090 4099
4091unsigned char btrfs_filetype_table[] = { 4100unsigned char btrfs_filetype_table[] = {
@@ -4125,7 +4134,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
4125 4134
4126 /* special case for "." */ 4135 /* special case for "." */
4127 if (filp->f_pos == 0) { 4136 if (filp->f_pos == 0) {
4128 over = filldir(dirent, ".", 1, 1, btrfs_ino(inode), DT_DIR); 4137 over = filldir(dirent, ".", 1,
4138 filp->f_pos, btrfs_ino(inode), DT_DIR);
4129 if (over) 4139 if (over)
4130 return 0; 4140 return 0;
4131 filp->f_pos = 1; 4141 filp->f_pos = 1;
@@ -4134,7 +4144,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
4134 if (filp->f_pos == 1) { 4144 if (filp->f_pos == 1) {
4135 u64 pino = parent_ino(filp->f_path.dentry); 4145 u64 pino = parent_ino(filp->f_path.dentry);
4136 over = filldir(dirent, "..", 2, 4146 over = filldir(dirent, "..", 2,
4137 2, pino, DT_DIR); 4147 filp->f_pos, pino, DT_DIR);
4138 if (over) 4148 if (over)
4139 return 0; 4149 return 0;
4140 filp->f_pos = 2; 4150 filp->f_pos = 2;
@@ -5823,7 +5833,7 @@ again:
5823 5833
5824 add_pending_csums(trans, inode, ordered->file_offset, &ordered->list); 5834 add_pending_csums(trans, inode, ordered->file_offset, &ordered->list);
5825 ret = btrfs_ordered_update_i_size(inode, 0, ordered); 5835 ret = btrfs_ordered_update_i_size(inode, 0, ordered);
5826 if (!ret) 5836 if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags))
5827 btrfs_update_inode(trans, root, inode); 5837 btrfs_update_inode(trans, root, inode);
5828 ret = 0; 5838 ret = 0;
5829out_unlock: 5839out_unlock:
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 970977aab224..538f65a79ec5 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2177,6 +2177,11 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
2177 if (!(src_file->f_mode & FMODE_READ)) 2177 if (!(src_file->f_mode & FMODE_READ))
2178 goto out_fput; 2178 goto out_fput;
2179 2179
2180 /* don't make the dst file partly checksummed */
2181 if ((BTRFS_I(src)->flags & BTRFS_INODE_NODATASUM) !=
2182 (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM))
2183 goto out_fput;
2184
2180 ret = -EISDIR; 2185 ret = -EISDIR;
2181 if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode)) 2186 if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode))
2182 goto out_fput; 2187 goto out_fput;
@@ -2220,6 +2225,16 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
2220 !IS_ALIGNED(destoff, bs)) 2225 !IS_ALIGNED(destoff, bs))
2221 goto out_unlock; 2226 goto out_unlock;
2222 2227
2228 if (destoff > inode->i_size) {
2229 ret = btrfs_cont_expand(inode, inode->i_size, destoff);
2230 if (ret)
2231 goto out_unlock;
2232 }
2233
2234 /* truncate page cache pages from target inode range */
2235 truncate_inode_pages_range(&inode->i_data, destoff,
2236 PAGE_CACHE_ALIGN(destoff + len) - 1);
2237
2223 /* do any pending delalloc/csum calc on src, one way or 2238 /* do any pending delalloc/csum calc on src, one way or
2224 another, and lock file content */ 2239 another, and lock file content */
2225 while (1) { 2240 while (1) {
@@ -2236,10 +2251,6 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
2236 btrfs_wait_ordered_range(src, off, len); 2251 btrfs_wait_ordered_range(src, off, len);
2237 } 2252 }
2238 2253
2239 /* truncate page cache pages from target inode range */
2240 truncate_inode_pages_range(&inode->i_data, off,
2241 ALIGN(off + len, PAGE_CACHE_SIZE) - 1);
2242
2243 /* clone data */ 2254 /* clone data */
2244 key.objectid = btrfs_ino(src); 2255 key.objectid = btrfs_ino(src);
2245 key.type = BTRFS_EXTENT_DATA_KEY; 2256 key.type = BTRFS_EXTENT_DATA_KEY;
@@ -2317,7 +2328,12 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
2317 else 2328 else
2318 new_key.offset = destoff; 2329 new_key.offset = destoff;
2319 2330
2320 trans = btrfs_start_transaction(root, 1); 2331 /*
2332 * 1 - adjusting old extent (we may have to split it)
2333 * 1 - add new extent
2334 * 1 - inode update
2335 */
2336 trans = btrfs_start_transaction(root, 3);
2321 if (IS_ERR(trans)) { 2337 if (IS_ERR(trans)) {
2322 ret = PTR_ERR(trans); 2338 ret = PTR_ERR(trans);
2323 goto out; 2339 goto out;
@@ -2325,14 +2341,21 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
2325 2341
2326 if (type == BTRFS_FILE_EXTENT_REG || 2342 if (type == BTRFS_FILE_EXTENT_REG ||
2327 type == BTRFS_FILE_EXTENT_PREALLOC) { 2343 type == BTRFS_FILE_EXTENT_PREALLOC) {
2344 /*
2345 * a | --- range to clone ---| b
2346 * | ------------- extent ------------- |
2347 */
2348
2349 /* substract range b */
2350 if (key.offset + datal > off + len)
2351 datal = off + len - key.offset;
2352
2353 /* substract range a */
2328 if (off > key.offset) { 2354 if (off > key.offset) {
2329 datao += off - key.offset; 2355 datao += off - key.offset;
2330 datal -= off - key.offset; 2356 datal -= off - key.offset;
2331 } 2357 }
2332 2358
2333 if (key.offset + datal > off + len)
2334 datal = off + len - key.offset;
2335
2336 ret = btrfs_drop_extents(trans, inode, 2359 ret = btrfs_drop_extents(trans, inode,
2337 new_key.offset, 2360 new_key.offset,
2338 new_key.offset + datal, 2361 new_key.offset + datal,
@@ -2429,7 +2452,6 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
2429 if (endoff > inode->i_size) 2452 if (endoff > inode->i_size)
2430 btrfs_i_size_write(inode, endoff); 2453 btrfs_i_size_write(inode, endoff);
2431 2454
2432 BTRFS_I(inode)->flags = BTRFS_I(src)->flags;
2433 ret = btrfs_update_inode(trans, root, inode); 2455 ret = btrfs_update_inode(trans, root, inode);
2434 BUG_ON(ret); 2456 BUG_ON(ret);
2435 btrfs_end_transaction(trans, root); 2457 btrfs_end_transaction(trans, root);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 7dc36fab4afc..e24b7964a155 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -884,6 +884,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
884 struct btrfs_root *tree_root = fs_info->tree_root; 884 struct btrfs_root *tree_root = fs_info->tree_root;
885 struct btrfs_root *root = pending->root; 885 struct btrfs_root *root = pending->root;
886 struct btrfs_root *parent_root; 886 struct btrfs_root *parent_root;
887 struct btrfs_block_rsv *rsv;
887 struct inode *parent_inode; 888 struct inode *parent_inode;
888 struct dentry *parent; 889 struct dentry *parent;
889 struct dentry *dentry; 890 struct dentry *dentry;
@@ -895,6 +896,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
895 u64 objectid; 896 u64 objectid;
896 u64 root_flags; 897 u64 root_flags;
897 898
899 rsv = trans->block_rsv;
900
898 new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); 901 new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
899 if (!new_root_item) { 902 if (!new_root_item) {
900 pending->error = -ENOMEM; 903 pending->error = -ENOMEM;
@@ -1002,6 +1005,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
1002 btrfs_orphan_post_snapshot(trans, pending); 1005 btrfs_orphan_post_snapshot(trans, pending);
1003fail: 1006fail:
1004 kfree(new_root_item); 1007 kfree(new_root_item);
1008 trans->block_rsv = rsv;
1005 btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1); 1009 btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1);
1006 return 0; 1010 return 0;
1007} 1011}
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index d733b9cfea34..69565e5fc6a0 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -116,6 +116,12 @@ static int do_setxattr(struct btrfs_trans_handle *trans,
116 if (ret) 116 if (ret)
117 goto out; 117 goto out;
118 btrfs_release_path(path); 118 btrfs_release_path(path);
119
120 /*
121 * remove the attribute
122 */
123 if (!value)
124 goto out;
119 } 125 }
120 126
121again: 127again:
@@ -158,6 +164,9 @@ out:
158 return ret; 164 return ret;
159} 165}
160 166
167/*
168 * @value: "" makes the attribute to empty, NULL removes it
169 */
161int __btrfs_setxattr(struct btrfs_trans_handle *trans, 170int __btrfs_setxattr(struct btrfs_trans_handle *trans,
162 struct inode *inode, const char *name, 171 struct inode *inode, const char *name,
163 const void *value, size_t size, int flags) 172 const void *value, size_t size, int flags)