Commit f688b1b8 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Nathan Scott

[XFS] handle nfs requesting ino 0 gracefully

SGI Modid: xfs-linux:xfs-kern:179624a
Signed-off-by: default avatarNathan Scott <nathans@sgi.com>
parent 2f1bf6ba
......@@ -225,26 +225,21 @@ linvfs_lookup(
struct dentry *dentry,
struct nameidata *nd)
{
struct inode *ip = NULL;
vnode_t *vp, *cvp = NULL;
struct vnode *vp = LINVFS_GET_VP(dir), *cvp;
int error;
if (dentry->d_name.len >= MAXNAMELEN)
return ERR_PTR(-ENAMETOOLONG);
vp = LINVFS_GET_VP(dir);
VOP_LOOKUP(vp, dentry, &cvp, 0, NULL, NULL, error);
if (!error) {
ASSERT(cvp);
ip = LINVFS_GET_IP(cvp);
if (!ip) {
VN_RELE(cvp);
return ERR_PTR(-EACCES);
}
}
if (error && (error != ENOENT))
if (error) {
if (unlikely(error != ENOENT))
return ERR_PTR(-error);
return d_splice_alias(ip, dentry);
d_add(dentry, NULL);
return NULL;
}
return d_splice_alias(LINVFS_GET_IP(cvp), dentry);
}
STATIC int
......
......@@ -570,7 +570,6 @@ linvfs_get_parent(
int error;
vnode_t *vp, *cvp;
struct dentry *parent;
struct inode *ip = NULL;
struct dentry dotdot;
dotdot.d_name.name = "..";
......@@ -580,21 +579,13 @@ linvfs_get_parent(
cvp = NULL;
vp = LINVFS_GET_VP(child->d_inode);
VOP_LOOKUP(vp, &dotdot, &cvp, 0, NULL, NULL, error);
if (!error) {
ASSERT(cvp);
ip = LINVFS_GET_IP(cvp);
if (!ip) {
VN_RELE(cvp);
return ERR_PTR(-EACCES);
}
}
if (error)
if (unlikely(error))
return ERR_PTR(-error);
parent = d_alloc_anon(ip);
if (!parent) {
parent = d_alloc_anon(LINVFS_GET_IP(cvp));
if (unlikely(!parent)) {
VN_RELE(cvp);
parent = ERR_PTR(-ENOMEM);
return ERR_PTR(-ENOMEM);
}
return parent;
}
......
......@@ -1582,31 +1582,35 @@ xfs_vget(
vnode_t **vpp,
fid_t *fidp)
{
xfs_fid_t *xfid;
xfs_mount_t *mp = XFS_BHVTOM(bdp);
xfs_fid_t *xfid = (struct xfs_fid *)fidp;
xfs_inode_t *ip;
int error;
xfs_ino_t ino;
unsigned int igen;
xfs_mount_t *mp;
xfid = (struct xfs_fid *)fidp;
if (xfid->xfs_fid_len == sizeof(*xfid) - sizeof(xfid->xfs_fid_len)) {
/*
* Invalid. Since handles can be created in user space and passed in
* via gethandle(), this is not cause for a panic.
*/
if (xfid->xfs_fid_len != sizeof(*xfid) - sizeof(xfid->xfs_fid_len))
return XFS_ERROR(EINVAL);
ino = xfid->xfs_fid_ino;
igen = xfid->xfs_fid_gen;
} else {
/*
* Invalid. Since handles can be created in user space
* and passed in via gethandle(), this is not cause for
* a panic.
* NFS can sometimes send requests for ino 0. Fail them gracefully.
*/
return XFS_ERROR(EINVAL);
}
mp = XFS_BHVTOM(bdp);
if (ino == 0)
return XFS_ERROR(ESTALE);
error = xfs_iget(mp, NULL, ino, XFS_ILOCK_SHARED, &ip, 0);
if (error) {
*vpp = NULL;
return error;
}
if (ip == NULL) {
*vpp = NULL;
return XFS_ERROR(EIO);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment