diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 22:02:39 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 22:02:39 -0400 |
| commit | bbd9d6f7fbb0305c9a592bf05a32e87eb364a4ff (patch) | |
| tree | 12b2bb4202b05f6ae6a43c6ce830a0472043dbe5 /fs/btrfs | |
| parent | 8e204874db000928e37199c2db82b7eb8966cc3c (diff) | |
| parent | 5a9a43646cf709312d71eca71cef90ad802f28f9 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (107 commits)
vfs: use ERR_CAST for err-ptr tossing in lookup_instantiate_filp
isofs: Remove global fs lock
jffs2: fix IN_DELETE_SELF on overwriting rename() killing a directory
fix IN_DELETE_SELF on overwriting rename() on ramfs et.al.
mm/truncate.c: fix build for CONFIG_BLOCK not enabled
fs:update the NOTE of the file_operations structure
Remove dead code in dget_parent()
AFS: Fix silly characters in a comment
switch d_add_ci() to d_splice_alias() in "found negative" case as well
simplify gfs2_lookup()
jfs_lookup(): don't bother with . or ..
get rid of useless dget_parent() in btrfs rename() and link()
get rid of useless dget_parent() in fs/btrfs/ioctl.c
fs: push i_mutex and filemap_write_and_wait down into ->fsync() handlers
drivers: fix up various ->llseek() implementations
fs: handle SEEK_HOLE/SEEK_DATA properly in all fs's that define their own llseek
Ext4: handle SEEK_HOLE/SEEK_DATA generically
Btrfs: implement our own ->llseek
fs: add SEEK_HOLE and SEEK_DATA flags
reiserfs: make reiserfs default to barrier=flush
...
Fix up trivial conflicts in fs/xfs/linux-2.6/xfs_super.c due to the new
shrinker callout for the inode cache, that clashed with the xfs code to
start the periodic workers later.
Diffstat (limited to 'fs/btrfs')
| -rw-r--r-- | fs/btrfs/acl.c | 5 | ||||
| -rw-r--r-- | fs/btrfs/ctree.h | 9 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 15 | ||||
| -rw-r--r-- | fs/btrfs/file.c | 169 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 25 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.c | 16 |
6 files changed, 189 insertions, 50 deletions
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index f66fc9959733..9f62ab2a7282 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
| @@ -195,14 +195,13 @@ out: | |||
| 195 | return ret; | 195 | return ret; |
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | int btrfs_check_acl(struct inode *inode, int mask, unsigned int flags) | 198 | int btrfs_check_acl(struct inode *inode, int mask) |
| 199 | { | 199 | { |
| 200 | int error = -EAGAIN; | 200 | int error = -EAGAIN; |
| 201 | 201 | ||
| 202 | if (flags & IPERM_FLAG_RCU) { | 202 | if (mask & MAY_NOT_BLOCK) { |
| 203 | if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) | 203 | if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) |
| 204 | error = -ECHILD; | 204 | error = -ECHILD; |
| 205 | |||
| 206 | } else { | 205 | } else { |
| 207 | struct posix_acl *acl; | 206 | struct posix_acl *acl; |
| 208 | acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS); | 207 | acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS); |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 3b859a3e6a0e..82be74efbb26 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -1219,7 +1219,7 @@ struct btrfs_root { | |||
| 1219 | * right now this just gets used so that a root has its own devid | 1219 | * right now this just gets used so that a root has its own devid |
| 1220 | * for stat. It may be used for more later | 1220 | * for stat. It may be used for more later |
| 1221 | */ | 1221 | */ |
| 1222 | struct super_block anon_super; | 1222 | dev_t anon_dev; |
| 1223 | }; | 1223 | }; |
| 1224 | 1224 | ||
| 1225 | struct btrfs_ioctl_defrag_range_args { | 1225 | struct btrfs_ioctl_defrag_range_args { |
| @@ -2510,6 +2510,9 @@ int btrfs_csum_truncate(struct btrfs_trans_handle *trans, | |||
| 2510 | int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, | 2510 | int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, |
| 2511 | struct list_head *list, int search_commit); | 2511 | struct list_head *list, int search_commit); |
| 2512 | /* inode.c */ | 2512 | /* inode.c */ |
| 2513 | struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *page, | ||
| 2514 | size_t pg_offset, u64 start, u64 len, | ||
| 2515 | int create); | ||
| 2513 | 2516 | ||
| 2514 | /* RHEL and EL kernels have a patch that renames PG_checked to FsMisc */ | 2517 | /* RHEL and EL kernels have a patch that renames PG_checked to FsMisc */ |
| 2515 | #if defined(ClearPageFsMisc) && !defined(ClearPageChecked) | 2518 | #if defined(ClearPageFsMisc) && !defined(ClearPageChecked) |
| @@ -2602,7 +2605,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, | |||
| 2602 | int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans, | 2605 | int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans, |
| 2603 | struct inode *inode); | 2606 | struct inode *inode); |
| 2604 | int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info); | 2607 | int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info); |
| 2605 | int btrfs_sync_file(struct file *file, int datasync); | 2608 | int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync); |
| 2606 | int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | 2609 | int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, |
| 2607 | int skip_pinned); | 2610 | int skip_pinned); |
| 2608 | extern const struct file_operations btrfs_file_operations; | 2611 | extern const struct file_operations btrfs_file_operations; |
| @@ -2642,7 +2645,7 @@ do { \ | |||
| 2642 | 2645 | ||
| 2643 | /* acl.c */ | 2646 | /* acl.c */ |
| 2644 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL | 2647 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL |
| 2645 | int btrfs_check_acl(struct inode *inode, int mask, unsigned int flags); | 2648 | int btrfs_check_acl(struct inode *inode, int mask); |
| 2646 | #else | 2649 | #else |
| 2647 | #define btrfs_check_acl NULL | 2650 | #define btrfs_check_acl NULL |
| 2648 | #endif | 2651 | #endif |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 1ac8db5dc0a3..b231ae13b269 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -1077,12 +1077,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
| 1077 | init_completion(&root->kobj_unregister); | 1077 | init_completion(&root->kobj_unregister); |
| 1078 | root->defrag_running = 0; | 1078 | root->defrag_running = 0; |
| 1079 | root->root_key.objectid = objectid; | 1079 | root->root_key.objectid = objectid; |
| 1080 | root->anon_super.s_root = NULL; | 1080 | root->anon_dev = 0; |
| 1081 | root->anon_super.s_dev = 0; | ||
| 1082 | INIT_LIST_HEAD(&root->anon_super.s_list); | ||
| 1083 | INIT_LIST_HEAD(&root->anon_super.s_instances); | ||
| 1084 | init_rwsem(&root->anon_super.s_umount); | ||
| 1085 | |||
| 1086 | return 0; | 1081 | return 0; |
| 1087 | } | 1082 | } |
| 1088 | 1083 | ||
| @@ -1311,7 +1306,7 @@ again: | |||
| 1311 | spin_lock_init(&root->cache_lock); | 1306 | spin_lock_init(&root->cache_lock); |
| 1312 | init_waitqueue_head(&root->cache_wait); | 1307 | init_waitqueue_head(&root->cache_wait); |
| 1313 | 1308 | ||
| 1314 | ret = set_anon_super(&root->anon_super, NULL); | 1309 | ret = get_anon_bdev(&root->anon_dev); |
| 1315 | if (ret) | 1310 | if (ret) |
| 1316 | goto fail; | 1311 | goto fail; |
| 1317 | 1312 | ||
| @@ -2393,10 +2388,8 @@ static void free_fs_root(struct btrfs_root *root) | |||
| 2393 | { | 2388 | { |
| 2394 | iput(root->cache_inode); | 2389 | iput(root->cache_inode); |
| 2395 | WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree)); | 2390 | WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree)); |
| 2396 | if (root->anon_super.s_dev) { | 2391 | if (root->anon_dev) |
| 2397 | down_write(&root->anon_super.s_umount); | 2392 | free_anon_bdev(root->anon_dev); |
| 2398 | kill_anon_super(&root->anon_super); | ||
| 2399 | } | ||
| 2400 | free_extent_buffer(root->node); | 2393 | free_extent_buffer(root->node); |
| 2401 | free_extent_buffer(root->commit_root); | 2394 | free_extent_buffer(root->commit_root); |
| 2402 | kfree(root->free_ino_ctl); | 2395 | kfree(root->free_ino_ctl); |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index fa4ef18b66b1..59cbdb120ad0 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -1452,7 +1452,7 @@ int btrfs_release_file(struct inode *inode, struct file *filp) | |||
| 1452 | * important optimization for directories because holding the mutex prevents | 1452 | * important optimization for directories because holding the mutex prevents |
| 1453 | * new operations on the dir while we write to disk. | 1453 | * new operations on the dir while we write to disk. |
| 1454 | */ | 1454 | */ |
| 1455 | int btrfs_sync_file(struct file *file, int datasync) | 1455 | int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) |
| 1456 | { | 1456 | { |
| 1457 | struct dentry *dentry = file->f_path.dentry; | 1457 | struct dentry *dentry = file->f_path.dentry; |
| 1458 | struct inode *inode = dentry->d_inode; | 1458 | struct inode *inode = dentry->d_inode; |
| @@ -1462,9 +1462,13 @@ int btrfs_sync_file(struct file *file, int datasync) | |||
| 1462 | 1462 | ||
| 1463 | trace_btrfs_sync_file(file, datasync); | 1463 | trace_btrfs_sync_file(file, datasync); |
| 1464 | 1464 | ||
| 1465 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); | ||
| 1466 | if (ret) | ||
| 1467 | return ret; | ||
| 1468 | mutex_lock(&inode->i_mutex); | ||
| 1469 | |||
| 1465 | /* we wait first, since the writeback may change the inode */ | 1470 | /* we wait first, since the writeback may change the inode */ |
| 1466 | root->log_batch++; | 1471 | root->log_batch++; |
| 1467 | /* the VFS called filemap_fdatawrite for us */ | ||
| 1468 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | 1472 | btrfs_wait_ordered_range(inode, 0, (u64)-1); |
| 1469 | root->log_batch++; | 1473 | root->log_batch++; |
| 1470 | 1474 | ||
| @@ -1472,8 +1476,10 @@ int btrfs_sync_file(struct file *file, int datasync) | |||
| 1472 | * check the transaction that last modified this inode | 1476 | * check the transaction that last modified this inode |
| 1473 | * and see if its already been committed | 1477 | * and see if its already been committed |
| 1474 | */ | 1478 | */ |
| 1475 | if (!BTRFS_I(inode)->last_trans) | 1479 | if (!BTRFS_I(inode)->last_trans) { |
| 1480 | mutex_unlock(&inode->i_mutex); | ||
| 1476 | goto out; | 1481 | goto out; |
| 1482 | } | ||
| 1477 | 1483 | ||
| 1478 | /* | 1484 | /* |
| 1479 | * if the last transaction that changed this file was before | 1485 | * if the last transaction that changed this file was before |
| @@ -1484,6 +1490,7 @@ int btrfs_sync_file(struct file *file, int datasync) | |||
| 1484 | if (BTRFS_I(inode)->last_trans <= | 1490 | if (BTRFS_I(inode)->last_trans <= |
| 1485 | root->fs_info->last_trans_committed) { | 1491 | root->fs_info->last_trans_committed) { |
| 1486 | BTRFS_I(inode)->last_trans = 0; | 1492 | BTRFS_I(inode)->last_trans = 0; |
| 1493 | mutex_unlock(&inode->i_mutex); | ||
| 1487 | goto out; | 1494 | goto out; |
| 1488 | } | 1495 | } |
| 1489 | 1496 | ||
| @@ -1496,12 +1503,15 @@ int btrfs_sync_file(struct file *file, int datasync) | |||
| 1496 | trans = btrfs_start_transaction(root, 0); | 1503 | trans = btrfs_start_transaction(root, 0); |
| 1497 | if (IS_ERR(trans)) { | 1504 | if (IS_ERR(trans)) { |
| 1498 | ret = PTR_ERR(trans); | 1505 | ret = PTR_ERR(trans); |
| 1506 | mutex_unlock(&inode->i_mutex); | ||
| 1499 | goto out; | 1507 | goto out; |
| 1500 | } | 1508 | } |
| 1501 | 1509 | ||
| 1502 | ret = btrfs_log_dentry_safe(trans, root, dentry); | 1510 | ret = btrfs_log_dentry_safe(trans, root, dentry); |
| 1503 | if (ret < 0) | 1511 | if (ret < 0) { |
| 1512 | mutex_unlock(&inode->i_mutex); | ||
| 1504 | goto out; | 1513 | goto out; |
| 1514 | } | ||
| 1505 | 1515 | ||
| 1506 | /* we've logged all the items and now have a consistent | 1516 | /* we've logged all the items and now have a consistent |
| 1507 | * version of the file in the log. It is possible that | 1517 | * version of the file in the log. It is possible that |
| @@ -1513,7 +1523,7 @@ int btrfs_sync_file(struct file *file, int datasync) | |||
| 1513 | * file again, but that will end up using the synchronization | 1523 | * file again, but that will end up using the synchronization |
| 1514 | * inside btrfs_sync_log to keep things safe. | 1524 | * inside btrfs_sync_log to keep things safe. |
| 1515 | */ | 1525 | */ |
| 1516 | mutex_unlock(&dentry->d_inode->i_mutex); | 1526 | mutex_unlock(&inode->i_mutex); |
| 1517 | 1527 | ||
| 1518 | if (ret != BTRFS_NO_LOG_SYNC) { | 1528 | if (ret != BTRFS_NO_LOG_SYNC) { |
| 1519 | if (ret > 0) { | 1529 | if (ret > 0) { |
| @@ -1528,7 +1538,6 @@ int btrfs_sync_file(struct file *file, int datasync) | |||
| 1528 | } else { | 1538 | } else { |
| 1529 | ret = btrfs_end_transaction(trans, root); | 1539 | ret = btrfs_end_transaction(trans, root); |
| 1530 | } | 1540 | } |
| 1531 | mutex_lock(&dentry->d_inode->i_mutex); | ||
| 1532 | out: | 1541 | out: |
| 1533 | return ret > 0 ? -EIO : ret; | 1542 | return ret > 0 ? -EIO : ret; |
| 1534 | } | 1543 | } |
| @@ -1664,8 +1673,154 @@ out: | |||
| 1664 | return ret; | 1673 | return ret; |
| 1665 | } | 1674 | } |
| 1666 | 1675 | ||
| 1676 | static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) | ||
| 1677 | { | ||
| 1678 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
| 1679 | struct extent_map *em; | ||
| 1680 | struct extent_state *cached_state = NULL; | ||
| 1681 | u64 lockstart = *offset; | ||
| 1682 | u64 lockend = i_size_read(inode); | ||
| 1683 | u64 start = *offset; | ||
| 1684 | u64 orig_start = *offset; | ||
| 1685 | u64 len = i_size_read(inode); | ||
| 1686 | u64 last_end = 0; | ||
| 1687 | int ret = 0; | ||
| 1688 | |||
| 1689 | lockend = max_t(u64, root->sectorsize, lockend); | ||
| 1690 | if (lockend <= lockstart) | ||
| 1691 | lockend = lockstart + root->sectorsize; | ||
| 1692 | |||
| 1693 | len = lockend - lockstart + 1; | ||
| 1694 | |||
| 1695 | len = max_t(u64, len, root->sectorsize); | ||
| 1696 | if (inode->i_size == 0) | ||
| 1697 | return -ENXIO; | ||
| 1698 | |||
| 1699 | lock_extent_bits(&BTRFS_I(inode)->io_tree, lockstart, lockend, 0, | ||
| 1700 | &cached_state, GFP_NOFS); | ||
| 1701 | |||
| 1702 | /* | ||
| 1703 | * Delalloc is such a pain. If we have a hole and we have pending | ||
| 1704 | * delalloc for a portion of the hole we will get back a hole that | ||
| 1705 | * exists for the entire range since it hasn't been actually written | ||
| 1706 | * yet. So to take care of this case we need to look for an extent just | ||
| 1707 | * before the position we want in case there is outstanding delalloc | ||
| 1708 | * going on here. | ||
| 1709 | */ | ||
| 1710 | if (origin == SEEK_HOLE && start != 0) { | ||
| 1711 | if (start <= root->sectorsize) | ||
| 1712 | em = btrfs_get_extent_fiemap(inode, NULL, 0, 0, | ||
| 1713 | root->sectorsize, 0); | ||
| 1714 | else | ||
| 1715 | em = btrfs_get_extent_fiemap(inode, NULL, 0, | ||
| 1716 | start - root->sectorsize, | ||
| 1717 | root->sectorsize, 0); | ||
| 1718 | if (IS_ERR(em)) { | ||
| 1719 | ret = -ENXIO; | ||
| 1720 | goto out; | ||
| 1721 | } | ||
| 1722 | last_end = em->start + em->len; | ||
| 1723 | if (em->block_start == EXTENT_MAP_DELALLOC) | ||
| 1724 | last_end = min_t(u64, last_end, inode->i_size); | ||
| 1725 | free_extent_map(em); | ||
| 1726 | } | ||
| 1727 | |||
| 1728 | while (1) { | ||
| 1729 | em = btrfs_get_extent_fiemap(inode, NULL, 0, start, len, 0); | ||
| 1730 | if (IS_ERR(em)) { | ||
| 1731 | ret = -ENXIO; | ||
| 1732 | break; | ||
| 1733 | } | ||
| 1734 | |||
| 1735 | if (em->block_start == EXTENT_MAP_HOLE) { | ||
| 1736 | if (test_bit(EXTENT_FLAG_VACANCY, &em->flags)) { | ||
| 1737 | if (last_end <= orig_start) { | ||
| 1738 | free_extent_map(em); | ||
| 1739 | ret = -ENXIO; | ||
| 1740 | break; | ||
| 1741 | } | ||
| 1742 | } | ||
| 1743 | |||
| 1744 | if (origin == SEEK_HOLE) { | ||
| 1745 | *offset = start; | ||
| 1746 | free_extent_map(em); | ||
| 1747 | break; | ||
| 1748 | } | ||
| 1749 | } else { | ||
| 1750 | if (origin == SEEK_DATA) { | ||
| 1751 | if (em->block_start == EXTENT_MAP_DELALLOC) { | ||
| 1752 | if (start >= inode->i_size) { | ||
| 1753 | free_extent_map(em); | ||
| 1754 | ret = -ENXIO; | ||
| 1755 | break; | ||
| 1756 | } | ||
| 1757 | } | ||
| 1758 | |||
| 1759 | *offset = start; | ||
| 1760 | free_extent_map(em); | ||
| 1761 | break; | ||
| 1762 | } | ||
| 1763 | } | ||
| 1764 | |||
| 1765 | start = em->start + em->len; | ||
| 1766 | last_end = em->start + em->len; | ||
| 1767 | |||
| 1768 | if (em->block_start == EXTENT_MAP_DELALLOC) | ||
| 1769 | last_end = min_t(u64, last_end, inode->i_size); | ||
| 1770 | |||
| 1771 | if (test_bit(EXTENT_FLAG_VACANCY, &em->flags)) { | ||
| 1772 | free_extent_map(em); | ||
| 1773 | ret = -ENXIO; | ||
| 1774 | break; | ||
| 1775 | } | ||
| 1776 | free_extent_map(em); | ||
| 1777 | cond_resched(); | ||
| 1778 | } | ||
| 1779 | if (!ret) | ||
| 1780 | *offset = min(*offset, inode->i_size); | ||
| 1781 | out: | ||
| 1782 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend, | ||
| 1783 | &cached_state, GFP_NOFS); | ||
| 1784 | return ret; | ||
| 1785 | } | ||
| 1786 | |||
| 1787 | static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin) | ||
| 1788 | { | ||
| 1789 | struct inode *inode = file->f_mapping->host; | ||
| 1790 | int ret; | ||
| 1791 | |||
| 1792 | mutex_lock(&inode->i_mutex); | ||
| 1793 | switch (origin) { | ||
| 1794 | case SEEK_END: | ||
| 1795 | case SEEK_CUR: | ||
| 1796 | offset = generic_file_llseek_unlocked(file, offset, origin); | ||
| 1797 | goto out; | ||
| 1798 | case SEEK_DATA: | ||
| 1799 | case SEEK_HOLE: | ||
| 1800 | ret = find_desired_extent(inode, &offset, origin); | ||
| 1801 | if (ret) { | ||
| 1802 | mutex_unlock(&inode->i_mutex); | ||
| 1803 | return ret; | ||
| 1804 | } | ||
| 1805 | } | ||
| 1806 | |||
| 1807 | if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) | ||
| 1808 | return -EINVAL; | ||
| 1809 | if (offset > inode->i_sb->s_maxbytes) | ||
| 1810 | return -EINVAL; | ||
| 1811 | |||
| 1812 | /* Special lock needed here? */ | ||
| 1813 | if (offset != file->f_pos) { | ||
| 1814 | file->f_pos = offset; | ||
| 1815 | file->f_version = 0; | ||
| 1816 | } | ||
| 1817 | out: | ||
| 1818 | mutex_unlock(&inode->i_mutex); | ||
| 1819 | return offset; | ||
| 1820 | } | ||
| 1821 | |||
| 1667 | const struct file_operations btrfs_file_operations = { | 1822 | const struct file_operations btrfs_file_operations = { |
| 1668 | .llseek = generic_file_llseek, | 1823 | .llseek = btrfs_file_llseek, |
| 1669 | .read = do_sync_read, | 1824 | .read = do_sync_read, |
| 1670 | .write = do_sync_write, | 1825 | .write = do_sync_write, |
| 1671 | .aio_read = generic_file_aio_read, | 1826 | .aio_read = generic_file_aio_read, |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3601f0aebddf..2548a04a0230 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -4079,13 +4079,7 @@ static int btrfs_dentry_delete(const struct dentry *dentry) | |||
| 4079 | static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, | 4079 | static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, |
| 4080 | struct nameidata *nd) | 4080 | struct nameidata *nd) |
| 4081 | { | 4081 | { |
| 4082 | struct inode *inode; | 4082 | return d_splice_alias(btrfs_lookup_dentry(dir, dentry), dentry); |
| 4083 | |||
| 4084 | inode = btrfs_lookup_dentry(dir, dentry); | ||
| 4085 | if (IS_ERR(inode)) | ||
| 4086 | return ERR_CAST(inode); | ||
| 4087 | |||
| 4088 | return d_splice_alias(inode, dentry); | ||
| 4089 | } | 4083 | } |
| 4090 | 4084 | ||
| 4091 | unsigned char btrfs_filetype_table[] = { | 4085 | unsigned char btrfs_filetype_table[] = { |
| @@ -4772,11 +4766,10 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 4772 | if (err) { | 4766 | if (err) { |
| 4773 | drop_inode = 1; | 4767 | drop_inode = 1; |
| 4774 | } else { | 4768 | } else { |
| 4775 | struct dentry *parent = dget_parent(dentry); | 4769 | struct dentry *parent = dentry->d_parent; |
| 4776 | err = btrfs_update_inode(trans, root, inode); | 4770 | err = btrfs_update_inode(trans, root, inode); |
| 4777 | BUG_ON(err); | 4771 | BUG_ON(err); |
| 4778 | btrfs_log_new_name(trans, inode, NULL, parent); | 4772 | btrfs_log_new_name(trans, inode, NULL, parent); |
| 4779 | dput(parent); | ||
| 4780 | } | 4773 | } |
| 4781 | 4774 | ||
| 4782 | nr = trans->blocks_used; | 4775 | nr = trans->blocks_used; |
| @@ -6900,7 +6893,7 @@ static int btrfs_getattr(struct vfsmount *mnt, | |||
| 6900 | { | 6893 | { |
| 6901 | struct inode *inode = dentry->d_inode; | 6894 | struct inode *inode = dentry->d_inode; |
| 6902 | generic_fillattr(inode, stat); | 6895 | generic_fillattr(inode, stat); |
| 6903 | stat->dev = BTRFS_I(inode)->root->anon_super.s_dev; | 6896 | stat->dev = BTRFS_I(inode)->root->anon_dev; |
| 6904 | stat->blksize = PAGE_CACHE_SIZE; | 6897 | stat->blksize = PAGE_CACHE_SIZE; |
| 6905 | stat->blocks = (inode_get_bytes(inode) + | 6898 | stat->blocks = (inode_get_bytes(inode) + |
| 6906 | BTRFS_I(inode)->delalloc_bytes) >> 9; | 6899 | BTRFS_I(inode)->delalloc_bytes) >> 9; |
| @@ -7068,9 +7061,8 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 7068 | BUG_ON(ret); | 7061 | BUG_ON(ret); |
| 7069 | 7062 | ||
| 7070 | if (old_ino != BTRFS_FIRST_FREE_OBJECTID) { | 7063 | if (old_ino != BTRFS_FIRST_FREE_OBJECTID) { |
| 7071 | struct dentry *parent = dget_parent(new_dentry); | 7064 | struct dentry *parent = new_dentry->d_parent; |
| 7072 | btrfs_log_new_name(trans, old_inode, old_dir, parent); | 7065 | btrfs_log_new_name(trans, old_inode, old_dir, parent); |
| 7073 | dput(parent); | ||
| 7074 | btrfs_end_log_trans(root); | 7066 | btrfs_end_log_trans(root); |
| 7075 | } | 7067 | } |
| 7076 | out_fail: | 7068 | out_fail: |
| @@ -7331,7 +7323,7 @@ static int btrfs_set_page_dirty(struct page *page) | |||
| 7331 | return __set_page_dirty_nobuffers(page); | 7323 | return __set_page_dirty_nobuffers(page); |
| 7332 | } | 7324 | } |
| 7333 | 7325 | ||
| 7334 | static int btrfs_permission(struct inode *inode, int mask, unsigned int flags) | 7326 | static int btrfs_permission(struct inode *inode, int mask) |
| 7335 | { | 7327 | { |
| 7336 | struct btrfs_root *root = BTRFS_I(inode)->root; | 7328 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 7337 | 7329 | ||
| @@ -7339,7 +7331,7 @@ static int btrfs_permission(struct inode *inode, int mask, unsigned int flags) | |||
| 7339 | return -EROFS; | 7331 | return -EROFS; |
| 7340 | if ((BTRFS_I(inode)->flags & BTRFS_INODE_READONLY) && (mask & MAY_WRITE)) | 7332 | if ((BTRFS_I(inode)->flags & BTRFS_INODE_READONLY) && (mask & MAY_WRITE)) |
| 7341 | return -EACCES; | 7333 | return -EACCES; |
| 7342 | return generic_permission(inode, mask, flags, btrfs_check_acl); | 7334 | return generic_permission(inode, mask); |
| 7343 | } | 7335 | } |
| 7344 | 7336 | ||
| 7345 | static const struct inode_operations btrfs_dir_inode_operations = { | 7337 | static const struct inode_operations btrfs_dir_inode_operations = { |
| @@ -7359,10 +7351,12 @@ static const struct inode_operations btrfs_dir_inode_operations = { | |||
| 7359 | .listxattr = btrfs_listxattr, | 7351 | .listxattr = btrfs_listxattr, |
| 7360 | .removexattr = btrfs_removexattr, | 7352 | .removexattr = btrfs_removexattr, |
| 7361 | .permission = btrfs_permission, | 7353 | .permission = btrfs_permission, |
| 7354 | .check_acl = btrfs_check_acl, | ||
| 7362 | }; | 7355 | }; |
| 7363 | static const struct inode_operations btrfs_dir_ro_inode_operations = { | 7356 | static const struct inode_operations btrfs_dir_ro_inode_operations = { |
| 7364 | .lookup = btrfs_lookup, | 7357 | .lookup = btrfs_lookup, |
| 7365 | .permission = btrfs_permission, | 7358 | .permission = btrfs_permission, |
| 7359 | .check_acl = btrfs_check_acl, | ||
| 7366 | }; | 7360 | }; |
| 7367 | 7361 | ||
| 7368 | static const struct file_operations btrfs_dir_file_operations = { | 7362 | static const struct file_operations btrfs_dir_file_operations = { |
| @@ -7431,6 +7425,7 @@ static const struct inode_operations btrfs_file_inode_operations = { | |||
| 7431 | .removexattr = btrfs_removexattr, | 7425 | .removexattr = btrfs_removexattr, |
| 7432 | .permission = btrfs_permission, | 7426 | .permission = btrfs_permission, |
| 7433 | .fiemap = btrfs_fiemap, | 7427 | .fiemap = btrfs_fiemap, |
| 7428 | .check_acl = btrfs_check_acl, | ||
| 7434 | }; | 7429 | }; |
| 7435 | static const struct inode_operations btrfs_special_inode_operations = { | 7430 | static const struct inode_operations btrfs_special_inode_operations = { |
| 7436 | .getattr = btrfs_getattr, | 7431 | .getattr = btrfs_getattr, |
| @@ -7440,6 +7435,7 @@ static const struct inode_operations btrfs_special_inode_operations = { | |||
| 7440 | .getxattr = btrfs_getxattr, | 7435 | .getxattr = btrfs_getxattr, |
| 7441 | .listxattr = btrfs_listxattr, | 7436 | .listxattr = btrfs_listxattr, |
| 7442 | .removexattr = btrfs_removexattr, | 7437 | .removexattr = btrfs_removexattr, |
| 7438 | .check_acl = btrfs_check_acl, | ||
| 7443 | }; | 7439 | }; |
| 7444 | static const struct inode_operations btrfs_symlink_inode_operations = { | 7440 | static const struct inode_operations btrfs_symlink_inode_operations = { |
| 7445 | .readlink = generic_readlink, | 7441 | .readlink = generic_readlink, |
| @@ -7451,6 +7447,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { | |||
| 7451 | .getxattr = btrfs_getxattr, | 7447 | .getxattr = btrfs_getxattr, |
| 7452 | .listxattr = btrfs_listxattr, | 7448 | .listxattr = btrfs_listxattr, |
| 7453 | .removexattr = btrfs_removexattr, | 7449 | .removexattr = btrfs_removexattr, |
| 7450 | .check_acl = btrfs_check_acl, | ||
| 7454 | }; | 7451 | }; |
| 7455 | 7452 | ||
| 7456 | const struct dentry_operations btrfs_dentry_operations = { | 7453 | const struct dentry_operations btrfs_dentry_operations = { |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index a3c4751e07db..622543309eb2 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -323,7 +323,7 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 323 | struct btrfs_inode_item *inode_item; | 323 | struct btrfs_inode_item *inode_item; |
| 324 | struct extent_buffer *leaf; | 324 | struct extent_buffer *leaf; |
| 325 | struct btrfs_root *new_root; | 325 | struct btrfs_root *new_root; |
| 326 | struct dentry *parent = dget_parent(dentry); | 326 | struct dentry *parent = dentry->d_parent; |
| 327 | struct inode *dir; | 327 | struct inode *dir; |
| 328 | int ret; | 328 | int ret; |
| 329 | int err; | 329 | int err; |
| @@ -332,10 +332,8 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 332 | u64 index = 0; | 332 | u64 index = 0; |
| 333 | 333 | ||
| 334 | ret = btrfs_find_free_objectid(root->fs_info->tree_root, &objectid); | 334 | ret = btrfs_find_free_objectid(root->fs_info->tree_root, &objectid); |
| 335 | if (ret) { | 335 | if (ret) |
| 336 | dput(parent); | ||
| 337 | return ret; | 336 | return ret; |
| 338 | } | ||
| 339 | 337 | ||
| 340 | dir = parent->d_inode; | 338 | dir = parent->d_inode; |
| 341 | 339 | ||
| @@ -346,10 +344,8 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 346 | * 2 - dir items | 344 | * 2 - dir items |
| 347 | */ | 345 | */ |
| 348 | trans = btrfs_start_transaction(root, 6); | 346 | trans = btrfs_start_transaction(root, 6); |
| 349 | if (IS_ERR(trans)) { | 347 | if (IS_ERR(trans)) |
| 350 | dput(parent); | ||
| 351 | return PTR_ERR(trans); | 348 | return PTR_ERR(trans); |
| 352 | } | ||
| 353 | 349 | ||
| 354 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, | 350 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, |
| 355 | 0, objectid, NULL, 0, 0, 0); | 351 | 0, objectid, NULL, 0, 0, 0); |
| @@ -439,7 +435,6 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 439 | 435 | ||
| 440 | d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry)); | 436 | d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry)); |
| 441 | fail: | 437 | fail: |
| 442 | dput(parent); | ||
| 443 | if (async_transid) { | 438 | if (async_transid) { |
| 444 | *async_transid = trans->transid; | 439 | *async_transid = trans->transid; |
| 445 | err = btrfs_commit_transaction_async(trans, root, 1); | 440 | err = btrfs_commit_transaction_async(trans, root, 1); |
| @@ -456,7 +451,6 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, | |||
| 456 | bool readonly) | 451 | bool readonly) |
| 457 | { | 452 | { |
| 458 | struct inode *inode; | 453 | struct inode *inode; |
| 459 | struct dentry *parent; | ||
| 460 | struct btrfs_pending_snapshot *pending_snapshot; | 454 | struct btrfs_pending_snapshot *pending_snapshot; |
| 461 | struct btrfs_trans_handle *trans; | 455 | struct btrfs_trans_handle *trans; |
| 462 | int ret; | 456 | int ret; |
| @@ -504,9 +498,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, | |||
| 504 | if (ret) | 498 | if (ret) |
| 505 | goto fail; | 499 | goto fail; |
| 506 | 500 | ||
| 507 | parent = dget_parent(dentry); | 501 | inode = btrfs_lookup_dentry(dentry->d_parent->d_inode, dentry); |
| 508 | inode = btrfs_lookup_dentry(parent->d_inode, dentry); | ||
| 509 | dput(parent); | ||
| 510 | if (IS_ERR(inode)) { | 502 | if (IS_ERR(inode)) { |
| 511 | ret = PTR_ERR(inode); | 503 | ret = PTR_ERR(inode); |
| 512 | goto fail; | 504 | goto fail; |
