diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 1569fb864515..31aa4ba06fce 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -2642,6 +2642,31 @@ static void btrfs_truncate(struct inode *inode) | |||
2642 | btrfs_throttle(root); | 2642 | btrfs_throttle(root); |
2643 | } | 2643 | } |
2644 | 2644 | ||
2645 | /* | ||
2646 | * Invalidate a single dcache entry at the root of the filesystem. | ||
2647 | * Needed after creation of snapshot or subvolume. | ||
2648 | */ | ||
2649 | void btrfs_invalidate_dcache_root(struct btrfs_root *root, char *name, | ||
2650 | int namelen) | ||
2651 | { | ||
2652 | struct dentry *alias, *entry; | ||
2653 | struct qstr qstr; | ||
2654 | |||
2655 | alias = d_find_alias(root->fs_info->sb->s_root->d_inode); | ||
2656 | if (alias) { | ||
2657 | qstr.name = name; | ||
2658 | qstr.len = namelen; | ||
2659 | /* change me if btrfs ever gets a d_hash operation */ | ||
2660 | qstr.hash = full_name_hash(qstr.name, qstr.len); | ||
2661 | entry = d_lookup(alias, &qstr); | ||
2662 | dput(alias); | ||
2663 | if (entry) { | ||
2664 | d_invalidate(entry); | ||
2665 | dput(entry); | ||
2666 | } | ||
2667 | } | ||
2668 | } | ||
2669 | |||
2645 | static int noinline create_subvol(struct btrfs_root *root, char *name, | 2670 | static int noinline create_subvol(struct btrfs_root *root, char *name, |
2646 | int namelen) | 2671 | int namelen) |
2647 | { | 2672 | { |
@@ -2761,6 +2786,10 @@ static int noinline create_subvol(struct btrfs_root *root, char *name, | |||
2761 | ret = btrfs_update_inode(trans, new_root, inode); | 2786 | ret = btrfs_update_inode(trans, new_root, inode); |
2762 | if (ret) | 2787 | if (ret) |
2763 | goto fail; | 2788 | goto fail; |
2789 | |||
2790 | /* Invalidate existing dcache entry for new subvolume. */ | ||
2791 | btrfs_invalidate_dcache_root(root, name, namelen); | ||
2792 | |||
2764 | fail: | 2793 | fail: |
2765 | nr = trans->blocks_used; | 2794 | nr = trans->blocks_used; |
2766 | err = btrfs_commit_transaction(trans, new_root); | 2795 | err = btrfs_commit_transaction(trans, new_root); |