diff options
author | Sven Wegener <sven.wegener@stealer.net> | 2008-06-09 21:57:42 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:03 -0400 |
commit | 3b96362cc8d314c935c335d5c3c42eb93c23166b (patch) | |
tree | 6d69302c9589d64ccb76f61b833f1a7151f9c841 /fs/btrfs/inode.c | |
parent | 48ec2cf8738b0db53dc8361026cb7a328f7ad386 (diff) | |
download | lwn-3b96362cc8d314c935c335d5c3c42eb93c23166b.tar.gz lwn-3b96362cc8d314c935c335d5c3c42eb93c23166b.zip |
Btrfs: Invalidate dcache entry after creating snapshot and
We need to invalidate an existing dcache entry after creating a new
snapshot or subvolume, because a negative dache entry will stop us from
accessing the new snapshot or subvolume.
---
ctree.h | 23 +++++++++++++++++++++++
inode.c | 4 ++++
transaction.c | 4 ++++
3 files changed, 31 insertions(+)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
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) btrfs_throttle(root); } +/* + * Invalidate a single dcache entry at the root of the filesystem. + * Needed after creation of snapshot or subvolume. + */ +void btrfs_invalidate_dcache_root(struct btrfs_root *root, char *name, + int namelen) +{ + struct dentry *alias, *entry; + struct qstr qstr; + + alias = d_find_alias(root->fs_info->sb->s_root->d_inode); + if (alias) { + qstr.name = name; + qstr.len = namelen; + /* change me if btrfs ever gets a d_hash operation */ + qstr.hash = full_name_hash(qstr.name, qstr.len); + entry = d_lookup(alias, &qstr); + dput(alias); + if (entry) { + d_invalidate(entry); + dput(entry); + } + } +} + static int noinline create_subvol(struct btrfs_root *root, char *name, int namelen) { @@ -2761,6 +2786,10 @@ static int noinline create_subvol(struct btrfs_root *root, char *name, ret = btrfs_update_inode(trans, new_root, inode); if (ret) goto fail; + + /* Invalidate existing dcache entry for new subvolume. */ + btrfs_invalidate_dcache_root(root, name, namelen); + fail: nr = trans->blocks_used; err = btrfs_commit_transaction(trans, new_root); |