diff options
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 227 |
1 files changed, 121 insertions, 106 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index e84ef60ffe35..9254b3d58dbe 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -239,23 +239,19 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
239 | u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; | 239 | u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; |
240 | u64 index = 0; | 240 | u64 index = 0; |
241 | 241 | ||
242 | ret = btrfs_find_free_objectid(NULL, root->fs_info->tree_root, | ||
243 | 0, &objectid); | ||
244 | if (ret) | ||
245 | return ret; | ||
242 | /* | 246 | /* |
243 | * 1 - inode item | 247 | * 1 - inode item |
244 | * 2 - refs | 248 | * 2 - refs |
245 | * 1 - root item | 249 | * 1 - root item |
246 | * 2 - dir items | 250 | * 2 - dir items |
247 | */ | 251 | */ |
248 | ret = btrfs_reserve_metadata_space(root, 6); | 252 | trans = btrfs_start_transaction(root, 6); |
249 | if (ret) | 253 | if (IS_ERR(trans)) |
250 | return ret; | 254 | return PTR_ERR(trans); |
251 | |||
252 | trans = btrfs_start_transaction(root, 1); | ||
253 | BUG_ON(!trans); | ||
254 | |||
255 | ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root, | ||
256 | 0, &objectid); | ||
257 | if (ret) | ||
258 | goto fail; | ||
259 | 255 | ||
260 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, | 256 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, |
261 | 0, objectid, NULL, 0, 0, 0); | 257 | 0, objectid, NULL, 0, 0, 0); |
@@ -345,13 +341,10 @@ fail: | |||
345 | err = btrfs_commit_transaction(trans, root); | 341 | err = btrfs_commit_transaction(trans, root); |
346 | if (err && !ret) | 342 | if (err && !ret) |
347 | ret = err; | 343 | ret = err; |
348 | |||
349 | btrfs_unreserve_metadata_space(root, 6); | ||
350 | return ret; | 344 | return ret; |
351 | } | 345 | } |
352 | 346 | ||
353 | static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, | 347 | static int create_snapshot(struct btrfs_root *root, struct dentry *dentry) |
354 | char *name, int namelen) | ||
355 | { | 348 | { |
356 | struct inode *inode; | 349 | struct inode *inode; |
357 | struct btrfs_pending_snapshot *pending_snapshot; | 350 | struct btrfs_pending_snapshot *pending_snapshot; |
@@ -361,40 +354,33 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, | |||
361 | if (!root->ref_cows) | 354 | if (!root->ref_cows) |
362 | return -EINVAL; | 355 | return -EINVAL; |
363 | 356 | ||
364 | /* | ||
365 | * 1 - inode item | ||
366 | * 2 - refs | ||
367 | * 1 - root item | ||
368 | * 2 - dir items | ||
369 | */ | ||
370 | ret = btrfs_reserve_metadata_space(root, 6); | ||
371 | if (ret) | ||
372 | goto fail; | ||
373 | |||
374 | pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); | 357 | pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); |
375 | if (!pending_snapshot) { | 358 | if (!pending_snapshot) |
376 | ret = -ENOMEM; | 359 | return -ENOMEM; |
377 | btrfs_unreserve_metadata_space(root, 6); | 360 | |
378 | goto fail; | 361 | btrfs_init_block_rsv(&pending_snapshot->block_rsv); |
379 | } | ||
380 | pending_snapshot->name = kmalloc(namelen + 1, GFP_NOFS); | ||
381 | if (!pending_snapshot->name) { | ||
382 | ret = -ENOMEM; | ||
383 | kfree(pending_snapshot); | ||
384 | btrfs_unreserve_metadata_space(root, 6); | ||
385 | goto fail; | ||
386 | } | ||
387 | memcpy(pending_snapshot->name, name, namelen); | ||
388 | pending_snapshot->name[namelen] = '\0'; | ||
389 | pending_snapshot->dentry = dentry; | 362 | pending_snapshot->dentry = dentry; |
390 | trans = btrfs_start_transaction(root, 1); | ||
391 | BUG_ON(!trans); | ||
392 | pending_snapshot->root = root; | 363 | pending_snapshot->root = root; |
364 | |||
365 | trans = btrfs_start_transaction(root->fs_info->extent_root, 5); | ||
366 | if (IS_ERR(trans)) { | ||
367 | ret = PTR_ERR(trans); | ||
368 | goto fail; | ||
369 | } | ||
370 | |||
371 | ret = btrfs_snap_reserve_metadata(trans, pending_snapshot); | ||
372 | BUG_ON(ret); | ||
373 | |||
393 | list_add(&pending_snapshot->list, | 374 | list_add(&pending_snapshot->list, |
394 | &trans->transaction->pending_snapshots); | 375 | &trans->transaction->pending_snapshots); |
395 | ret = btrfs_commit_transaction(trans, root); | 376 | ret = btrfs_commit_transaction(trans, root->fs_info->extent_root); |
396 | BUG_ON(ret); | 377 | BUG_ON(ret); |
397 | btrfs_unreserve_metadata_space(root, 6); | 378 | |
379 | ret = pending_snapshot->error; | ||
380 | if (ret) | ||
381 | goto fail; | ||
382 | |||
383 | btrfs_orphan_cleanup(pending_snapshot->snap); | ||
398 | 384 | ||
399 | inode = btrfs_lookup_dentry(dentry->d_parent->d_inode, dentry); | 385 | inode = btrfs_lookup_dentry(dentry->d_parent->d_inode, dentry); |
400 | if (IS_ERR(inode)) { | 386 | if (IS_ERR(inode)) { |
@@ -405,6 +391,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, | |||
405 | d_instantiate(dentry, inode); | 391 | d_instantiate(dentry, inode); |
406 | ret = 0; | 392 | ret = 0; |
407 | fail: | 393 | fail: |
394 | kfree(pending_snapshot); | ||
408 | return ret; | 395 | return ret; |
409 | } | 396 | } |
410 | 397 | ||
@@ -456,8 +443,7 @@ static noinline int btrfs_mksubvol(struct path *parent, | |||
456 | goto out_up_read; | 443 | goto out_up_read; |
457 | 444 | ||
458 | if (snap_src) { | 445 | if (snap_src) { |
459 | error = create_snapshot(snap_src, dentry, | 446 | error = create_snapshot(snap_src, dentry); |
460 | name, namelen); | ||
461 | } else { | 447 | } else { |
462 | error = create_subvol(BTRFS_I(dir)->root, dentry, | 448 | error = create_subvol(BTRFS_I(dir)->root, dentry, |
463 | name, namelen); | 449 | name, namelen); |
@@ -601,19 +587,9 @@ static int btrfs_defrag_file(struct file *file, | |||
601 | if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) | 587 | if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) |
602 | BTRFS_I(inode)->force_compress = 1; | 588 | BTRFS_I(inode)->force_compress = 1; |
603 | 589 | ||
604 | ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE); | 590 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); |
605 | if (ret) { | 591 | if (ret) |
606 | ret = -ENOSPC; | 592 | goto err_unlock; |
607 | break; | ||
608 | } | ||
609 | |||
610 | ret = btrfs_reserve_metadata_for_delalloc(root, inode, 1); | ||
611 | if (ret) { | ||
612 | btrfs_free_reserved_data_space(root, inode, | ||
613 | PAGE_CACHE_SIZE); | ||
614 | ret = -ENOSPC; | ||
615 | break; | ||
616 | } | ||
617 | again: | 593 | again: |
618 | if (inode->i_size == 0 || | 594 | if (inode->i_size == 0 || |
619 | i > ((inode->i_size - 1) >> PAGE_CACHE_SHIFT)) { | 595 | i > ((inode->i_size - 1) >> PAGE_CACHE_SHIFT)) { |
@@ -622,8 +598,10 @@ again: | |||
622 | } | 598 | } |
623 | 599 | ||
624 | page = grab_cache_page(inode->i_mapping, i); | 600 | page = grab_cache_page(inode->i_mapping, i); |
625 | if (!page) | 601 | if (!page) { |
602 | ret = -ENOMEM; | ||
626 | goto err_reservations; | 603 | goto err_reservations; |
604 | } | ||
627 | 605 | ||
628 | if (!PageUptodate(page)) { | 606 | if (!PageUptodate(page)) { |
629 | btrfs_readpage(NULL, page); | 607 | btrfs_readpage(NULL, page); |
@@ -631,6 +609,7 @@ again: | |||
631 | if (!PageUptodate(page)) { | 609 | if (!PageUptodate(page)) { |
632 | unlock_page(page); | 610 | unlock_page(page); |
633 | page_cache_release(page); | 611 | page_cache_release(page); |
612 | ret = -EIO; | ||
634 | goto err_reservations; | 613 | goto err_reservations; |
635 | } | 614 | } |
636 | } | 615 | } |
@@ -644,8 +623,7 @@ again: | |||
644 | wait_on_page_writeback(page); | 623 | wait_on_page_writeback(page); |
645 | 624 | ||
646 | if (PageDirty(page)) { | 625 | if (PageDirty(page)) { |
647 | btrfs_free_reserved_data_space(root, inode, | 626 | btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE); |
648 | PAGE_CACHE_SIZE); | ||
649 | goto loop_unlock; | 627 | goto loop_unlock; |
650 | } | 628 | } |
651 | 629 | ||
@@ -683,7 +661,6 @@ loop_unlock: | |||
683 | page_cache_release(page); | 661 | page_cache_release(page); |
684 | mutex_unlock(&inode->i_mutex); | 662 | mutex_unlock(&inode->i_mutex); |
685 | 663 | ||
686 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); | ||
687 | balance_dirty_pages_ratelimited_nr(inode->i_mapping, 1); | 664 | balance_dirty_pages_ratelimited_nr(inode->i_mapping, 1); |
688 | i++; | 665 | i++; |
689 | } | 666 | } |
@@ -713,9 +690,9 @@ loop_unlock: | |||
713 | return 0; | 690 | return 0; |
714 | 691 | ||
715 | err_reservations: | 692 | err_reservations: |
693 | btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE); | ||
694 | err_unlock: | ||
716 | mutex_unlock(&inode->i_mutex); | 695 | mutex_unlock(&inode->i_mutex); |
717 | btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE); | ||
718 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); | ||
719 | return ret; | 696 | return ret; |
720 | } | 697 | } |
721 | 698 | ||
@@ -811,7 +788,7 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root, | |||
811 | device->name, (unsigned long long)new_size); | 788 | device->name, (unsigned long long)new_size); |
812 | 789 | ||
813 | if (new_size > old_size) { | 790 | if (new_size > old_size) { |
814 | trans = btrfs_start_transaction(root, 1); | 791 | trans = btrfs_start_transaction(root, 0); |
815 | ret = btrfs_grow_device(trans, device, new_size); | 792 | ret = btrfs_grow_device(trans, device, new_size); |
816 | btrfs_commit_transaction(trans, root); | 793 | btrfs_commit_transaction(trans, root); |
817 | } else { | 794 | } else { |
@@ -1300,7 +1277,13 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
1300 | if (err) | 1277 | if (err) |
1301 | goto out_up_write; | 1278 | goto out_up_write; |
1302 | 1279 | ||
1303 | trans = btrfs_start_transaction(root, 1); | 1280 | trans = btrfs_start_transaction(root, 0); |
1281 | if (IS_ERR(trans)) { | ||
1282 | err = PTR_ERR(trans); | ||
1283 | goto out_up_write; | ||
1284 | } | ||
1285 | trans->block_rsv = &root->fs_info->global_block_rsv; | ||
1286 | |||
1304 | ret = btrfs_unlink_subvol(trans, root, dir, | 1287 | ret = btrfs_unlink_subvol(trans, root, dir, |
1305 | dest->root_key.objectid, | 1288 | dest->root_key.objectid, |
1306 | dentry->d_name.name, | 1289 | dentry->d_name.name, |
@@ -1314,10 +1297,12 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
1314 | dest->root_item.drop_level = 0; | 1297 | dest->root_item.drop_level = 0; |
1315 | btrfs_set_root_refs(&dest->root_item, 0); | 1298 | btrfs_set_root_refs(&dest->root_item, 0); |
1316 | 1299 | ||
1317 | ret = btrfs_insert_orphan_item(trans, | 1300 | if (!xchg(&dest->orphan_item_inserted, 1)) { |
1318 | root->fs_info->tree_root, | 1301 | ret = btrfs_insert_orphan_item(trans, |
1319 | dest->root_key.objectid); | 1302 | root->fs_info->tree_root, |
1320 | BUG_ON(ret); | 1303 | dest->root_key.objectid); |
1304 | BUG_ON(ret); | ||
1305 | } | ||
1321 | 1306 | ||
1322 | ret = btrfs_commit_transaction(trans, root); | 1307 | ret = btrfs_commit_transaction(trans, root); |
1323 | BUG_ON(ret); | 1308 | BUG_ON(ret); |
@@ -1358,8 +1343,10 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp) | |||
1358 | ret = -EPERM; | 1343 | ret = -EPERM; |
1359 | goto out; | 1344 | goto out; |
1360 | } | 1345 | } |
1361 | btrfs_defrag_root(root, 0); | 1346 | ret = btrfs_defrag_root(root, 0); |
1362 | btrfs_defrag_root(root->fs_info->extent_root, 0); | 1347 | if (ret) |
1348 | goto out; | ||
1349 | ret = btrfs_defrag_root(root->fs_info->extent_root, 0); | ||
1363 | break; | 1350 | break; |
1364 | case S_IFREG: | 1351 | case S_IFREG: |
1365 | if (!(file->f_mode & FMODE_WRITE)) { | 1352 | if (!(file->f_mode & FMODE_WRITE)) { |
@@ -1389,9 +1376,11 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp) | |||
1389 | /* the rest are all set to zero by kzalloc */ | 1376 | /* the rest are all set to zero by kzalloc */ |
1390 | range->len = (u64)-1; | 1377 | range->len = (u64)-1; |
1391 | } | 1378 | } |
1392 | btrfs_defrag_file(file, range); | 1379 | ret = btrfs_defrag_file(file, range); |
1393 | kfree(range); | 1380 | kfree(range); |
1394 | break; | 1381 | break; |
1382 | default: | ||
1383 | ret = -EINVAL; | ||
1395 | } | 1384 | } |
1396 | out: | 1385 | out: |
1397 | mnt_drop_write(file->f_path.mnt); | 1386 | mnt_drop_write(file->f_path.mnt); |
@@ -1469,7 +1458,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1469 | */ | 1458 | */ |
1470 | 1459 | ||
1471 | /* the destination must be opened for writing */ | 1460 | /* the destination must be opened for writing */ |
1472 | if (!(file->f_mode & FMODE_WRITE)) | 1461 | if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND)) |
1473 | return -EINVAL; | 1462 | return -EINVAL; |
1474 | 1463 | ||
1475 | ret = mnt_want_write(file->f_path.mnt); | 1464 | ret = mnt_want_write(file->f_path.mnt); |
@@ -1481,12 +1470,17 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1481 | ret = -EBADF; | 1470 | ret = -EBADF; |
1482 | goto out_drop_write; | 1471 | goto out_drop_write; |
1483 | } | 1472 | } |
1473 | |||
1484 | src = src_file->f_dentry->d_inode; | 1474 | src = src_file->f_dentry->d_inode; |
1485 | 1475 | ||
1486 | ret = -EINVAL; | 1476 | ret = -EINVAL; |
1487 | if (src == inode) | 1477 | if (src == inode) |
1488 | goto out_fput; | 1478 | goto out_fput; |
1489 | 1479 | ||
1480 | /* the src must be open for reading */ | ||
1481 | if (!(src_file->f_mode & FMODE_READ)) | ||
1482 | goto out_fput; | ||
1483 | |||
1490 | ret = -EISDIR; | 1484 | ret = -EISDIR; |
1491 | if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode)) | 1485 | if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode)) |
1492 | goto out_fput; | 1486 | goto out_fput; |
@@ -1517,7 +1511,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1517 | 1511 | ||
1518 | /* determine range to clone */ | 1512 | /* determine range to clone */ |
1519 | ret = -EINVAL; | 1513 | ret = -EINVAL; |
1520 | if (off >= src->i_size || off + len > src->i_size) | 1514 | if (off + len > src->i_size || off + len < off) |
1521 | goto out_unlock; | 1515 | goto out_unlock; |
1522 | if (len == 0) | 1516 | if (len == 0) |
1523 | olen = len = src->i_size - off; | 1517 | olen = len = src->i_size - off; |
@@ -1545,12 +1539,6 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1545 | btrfs_wait_ordered_range(src, off, off+len); | 1539 | btrfs_wait_ordered_range(src, off, off+len); |
1546 | } | 1540 | } |
1547 | 1541 | ||
1548 | trans = btrfs_start_transaction(root, 1); | ||
1549 | BUG_ON(!trans); | ||
1550 | |||
1551 | /* punch hole in destination first */ | ||
1552 | btrfs_drop_extents(trans, inode, off, off + len, &hint_byte, 1); | ||
1553 | |||
1554 | /* clone data */ | 1542 | /* clone data */ |
1555 | key.objectid = src->i_ino; | 1543 | key.objectid = src->i_ino; |
1556 | key.type = BTRFS_EXTENT_DATA_KEY; | 1544 | key.type = BTRFS_EXTENT_DATA_KEY; |
@@ -1561,7 +1549,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1561 | * note the key will change type as we walk through the | 1549 | * note the key will change type as we walk through the |
1562 | * tree. | 1550 | * tree. |
1563 | */ | 1551 | */ |
1564 | ret = btrfs_search_slot(trans, root, &key, path, 0, 0); | 1552 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
1565 | if (ret < 0) | 1553 | if (ret < 0) |
1566 | goto out; | 1554 | goto out; |
1567 | 1555 | ||
@@ -1590,6 +1578,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1590 | u64 disko = 0, diskl = 0; | 1578 | u64 disko = 0, diskl = 0; |
1591 | u64 datao = 0, datal = 0; | 1579 | u64 datao = 0, datal = 0; |
1592 | u8 comp; | 1580 | u8 comp; |
1581 | u64 endoff; | ||
1593 | 1582 | ||
1594 | size = btrfs_item_size_nr(leaf, slot); | 1583 | size = btrfs_item_size_nr(leaf, slot); |
1595 | read_extent_buffer(leaf, buf, | 1584 | read_extent_buffer(leaf, buf, |
@@ -1624,12 +1613,31 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1624 | new_key.objectid = inode->i_ino; | 1613 | new_key.objectid = inode->i_ino; |
1625 | new_key.offset = key.offset + destoff - off; | 1614 | new_key.offset = key.offset + destoff - off; |
1626 | 1615 | ||
1616 | trans = btrfs_start_transaction(root, 1); | ||
1617 | if (IS_ERR(trans)) { | ||
1618 | ret = PTR_ERR(trans); | ||
1619 | goto out; | ||
1620 | } | ||
1621 | |||
1627 | if (type == BTRFS_FILE_EXTENT_REG || | 1622 | if (type == BTRFS_FILE_EXTENT_REG || |
1628 | type == BTRFS_FILE_EXTENT_PREALLOC) { | 1623 | type == BTRFS_FILE_EXTENT_PREALLOC) { |
1624 | if (off > key.offset) { | ||
1625 | datao += off - key.offset; | ||
1626 | datal -= off - key.offset; | ||
1627 | } | ||
1628 | |||
1629 | if (key.offset + datal > off + len) | ||
1630 | datal = off + len - key.offset; | ||
1631 | |||
1632 | ret = btrfs_drop_extents(trans, inode, | ||
1633 | new_key.offset, | ||
1634 | new_key.offset + datal, | ||
1635 | &hint_byte, 1); | ||
1636 | BUG_ON(ret); | ||
1637 | |||
1629 | ret = btrfs_insert_empty_item(trans, root, path, | 1638 | ret = btrfs_insert_empty_item(trans, root, path, |
1630 | &new_key, size); | 1639 | &new_key, size); |
1631 | if (ret) | 1640 | BUG_ON(ret); |
1632 | goto out; | ||
1633 | 1641 | ||
1634 | leaf = path->nodes[0]; | 1642 | leaf = path->nodes[0]; |
1635 | slot = path->slots[0]; | 1643 | slot = path->slots[0]; |
@@ -1640,14 +1648,6 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1640 | extent = btrfs_item_ptr(leaf, slot, | 1648 | extent = btrfs_item_ptr(leaf, slot, |
1641 | struct btrfs_file_extent_item); | 1649 | struct btrfs_file_extent_item); |
1642 | 1650 | ||
1643 | if (off > key.offset) { | ||
1644 | datao += off - key.offset; | ||
1645 | datal -= off - key.offset; | ||
1646 | } | ||
1647 | |||
1648 | if (key.offset + datal > off + len) | ||
1649 | datal = off + len - key.offset; | ||
1650 | |||
1651 | /* disko == 0 means it's a hole */ | 1651 | /* disko == 0 means it's a hole */ |
1652 | if (!disko) | 1652 | if (!disko) |
1653 | datao = 0; | 1653 | datao = 0; |
@@ -1678,14 +1678,21 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1678 | 1678 | ||
1679 | if (comp && (skip || trim)) { | 1679 | if (comp && (skip || trim)) { |
1680 | ret = -EINVAL; | 1680 | ret = -EINVAL; |
1681 | btrfs_end_transaction(trans, root); | ||
1681 | goto out; | 1682 | goto out; |
1682 | } | 1683 | } |
1683 | size -= skip + trim; | 1684 | size -= skip + trim; |
1684 | datal -= skip + trim; | 1685 | datal -= skip + trim; |
1686 | |||
1687 | ret = btrfs_drop_extents(trans, inode, | ||
1688 | new_key.offset, | ||
1689 | new_key.offset + datal, | ||
1690 | &hint_byte, 1); | ||
1691 | BUG_ON(ret); | ||
1692 | |||
1685 | ret = btrfs_insert_empty_item(trans, root, path, | 1693 | ret = btrfs_insert_empty_item(trans, root, path, |
1686 | &new_key, size); | 1694 | &new_key, size); |
1687 | if (ret) | 1695 | BUG_ON(ret); |
1688 | goto out; | ||
1689 | 1696 | ||
1690 | if (skip) { | 1697 | if (skip) { |
1691 | u32 start = | 1698 | u32 start = |
@@ -1703,8 +1710,26 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
1703 | } | 1710 | } |
1704 | 1711 | ||
1705 | btrfs_mark_buffer_dirty(leaf); | 1712 | btrfs_mark_buffer_dirty(leaf); |
1706 | } | 1713 | btrfs_release_path(root, path); |
1714 | |||
1715 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
1707 | 1716 | ||
1717 | /* | ||
1718 | * we round up to the block size at eof when | ||
1719 | * determining which extents to clone above, | ||
1720 | * but shouldn't round up the file size | ||
1721 | */ | ||
1722 | endoff = new_key.offset + datal; | ||
1723 | if (endoff > off+olen) | ||
1724 | endoff = off+olen; | ||
1725 | if (endoff > inode->i_size) | ||
1726 | btrfs_i_size_write(inode, endoff); | ||
1727 | |||
1728 | BTRFS_I(inode)->flags = BTRFS_I(src)->flags; | ||
1729 | ret = btrfs_update_inode(trans, root, inode); | ||
1730 | BUG_ON(ret); | ||
1731 | btrfs_end_transaction(trans, root); | ||
1732 | } | ||
1708 | next: | 1733 | next: |
1709 | btrfs_release_path(root, path); | 1734 | btrfs_release_path(root, path); |
1710 | key.offset++; | 1735 | key.offset++; |
@@ -1712,17 +1737,7 @@ next: | |||
1712 | ret = 0; | 1737 | ret = 0; |
1713 | out: | 1738 | out: |
1714 | btrfs_release_path(root, path); | 1739 | btrfs_release_path(root, path); |
1715 | if (ret == 0) { | ||
1716 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
1717 | if (destoff + olen > inode->i_size) | ||
1718 | btrfs_i_size_write(inode, destoff + olen); | ||
1719 | BTRFS_I(inode)->flags = BTRFS_I(src)->flags; | ||
1720 | ret = btrfs_update_inode(trans, root, inode); | ||
1721 | } | ||
1722 | btrfs_end_transaction(trans, root); | ||
1723 | unlock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS); | 1740 | unlock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS); |
1724 | if (ret) | ||
1725 | vmtruncate(inode, 0); | ||
1726 | out_unlock: | 1741 | out_unlock: |
1727 | mutex_unlock(&src->i_mutex); | 1742 | mutex_unlock(&src->i_mutex); |
1728 | mutex_unlock(&inode->i_mutex); | 1743 | mutex_unlock(&inode->i_mutex); |
@@ -1840,7 +1855,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) | |||
1840 | dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); | 1855 | dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); |
1841 | di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path, | 1856 | di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path, |
1842 | dir_id, "default", 7, 1); | 1857 | dir_id, "default", 7, 1); |
1843 | if (!di) { | 1858 | if (IS_ERR_OR_NULL(di)) { |
1844 | btrfs_free_path(path); | 1859 | btrfs_free_path(path); |
1845 | btrfs_end_transaction(trans, root); | 1860 | btrfs_end_transaction(trans, root); |
1846 | printk(KERN_ERR "Umm, you don't have the default dir item, " | 1861 | printk(KERN_ERR "Umm, you don't have the default dir item, " |