From da68991d5a924a3d7ed95893570cbd9da0e71d97 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 2 Sep 2004 03:53:00 -0700 Subject: [PATCH] [PATCH] NFS: fix problem of ESTALE errors on NFSv2 symlinks NFSv2: Fix another bad filehandle cast. NFSv2: The symlink operation does not return a valid filehandle. Signed-off-by: Trond Myklebust Signed-off-by: Linus Torvalds --- fs/nfs/inode.c | 14 +++++++++----- fs/nfs/proc.c | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index fb627a12d53b2..e2795ce27c3df 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1377,9 +1377,6 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type, /* Zero out the NFS state stuff */ init_nfsv4_state(server); - root = &server->fh; - nfs_copy_fh(root, (struct nfs_fh *) &data->root); - if (data->version != NFS_MOUNT_VERSION) { printk("nfs warning: mount version %s than kernel\n", data->version < NFS_MOUNT_VERSION ? "older" : "newer"); @@ -1389,18 +1386,25 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type, data->bsize = 0; if (data->version < 4) { data->flags &= ~NFS_MOUNT_VER3; - root->size = NFS2_FHSIZE; - memcpy(root->data, data->old_root.data, NFS2_FHSIZE); + data->root.size = NFS2_FHSIZE; + memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); } if (data->version < 5) data->flags &= ~NFS_MOUNT_SECFLAVOUR; } + root = &server->fh; + if (data->flags & NFS_MOUNT_VER3) + root->size = data->root.size; + else + root->size = NFS2_FHSIZE; if (root->size > sizeof(root->data)) { printk("nfs_get_sb: invalid root filehandle\n"); kfree(server); return ERR_PTR(-EINVAL); } + memcpy(root->data, data->root.data, root->size); + /* We now require that the mount process passes the remote address */ memcpy(&server->addr, &data->addr, sizeof(server->addr)); if (server->addr.sin_addr.s_addr == INADDR_ANY) { diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index b0cd8f0dd509b..ae9500199b2d0 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -391,6 +391,7 @@ nfs_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path, return -ENAMETOOLONG; dprintk("NFS call symlink %s -> %s\n", name->name, path->name); fattr->valid = 0; + fhandle->size = 0; status = rpc_call(NFS_CLIENT(dir), NFSPROC_SYMLINK, &arg, NULL, 0); dprintk("NFS reply symlink: %d\n", status); return status; -- 2.53.0