diff options
author | Josef Bacik <josef@redhat.com> | 2010-11-17 18:54:54 +0000 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2010-11-21 22:26:08 -0500 |
commit | 2ede0daf01549cecf4bb0962c46dc47382047523 (patch) | |
tree | 3d02b4445b8657ac402a64772dd80ca517967557 /fs/btrfs/inode.c | |
parent | 0410c94aff109c02b6774a0ed00114987cda7ce5 (diff) | |
download | talos-op-linux-2ede0daf01549cecf4bb0962c46dc47382047523.tar.gz talos-op-linux-2ede0daf01549cecf4bb0962c46dc47382047523.zip |
Btrfs: handle NFS lookups properly
People kept reporting NFS issues, specifically getting ESTALE alot. I figured
out how to reproduce the problem
SERVER
mkfs.btrfs /dev/sda1
mount /dev/sda1 /mnt/btrfs-test
<add /mnt/btrfs-test to /etc/exports>
btrfs subvol create /mnt/btrfs-test/foo
service nfs start
CLIENT
mount server:/mnt/btrfs /mnt/test
cd /mnt/test/foo
ls
SERVER
echo 3 > /proc/sys/vm/drop_caches
CLIENT
ls <-- get an ESTALE here
This is because the standard way to lookup a name in nfsd is to use readdir, and
what it does is do a readdir on the parent directory looking for the inode of
the child. So in this case the parent being / and the child being foo. Well
subvols all have the same inode number, so doing a readdir of / looking for
inode 256 will return '.', which obviously doesn't match foo. So instead we
need to have our own .get_name so that we can find the right name.
Our .get_name will either lookup the inode backref or the root backref,
whichever we're looking for, and return the name we find. Running the above
reproducer with this patch results in everything acting the way its supposed to.
Thanks,
Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
0 files changed, 0 insertions, 0 deletions