aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c29
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 */
2649void 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
2645static int noinline create_subvol(struct btrfs_root *root, char *name, 2670static 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
2764fail: 2793fail:
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);