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( ...@@ -225,26 +225,21 @@ linvfs_lookup(
struct dentry *dentry, struct dentry *dentry,
struct nameidata *nd) struct nameidata *nd)
{ {
struct inode *ip = NULL; struct vnode *vp = LINVFS_GET_VP(dir), *cvp;
vnode_t *vp, *cvp = NULL;
int error; int error;
if (dentry->d_name.len >= MAXNAMELEN) if (dentry->d_name.len >= MAXNAMELEN)
return ERR_PTR(-ENAMETOOLONG); return ERR_PTR(-ENAMETOOLONG);
vp = LINVFS_GET_VP(dir);
VOP_LOOKUP(vp, dentry, &cvp, 0, NULL, NULL, error); VOP_LOOKUP(vp, dentry, &cvp, 0, NULL, NULL, error);
if (!error) { if (error) {
ASSERT(cvp); if (unlikely(error != ENOENT))
ip = LINVFS_GET_IP(cvp); return ERR_PTR(-error);
if (!ip) { d_add(dentry, NULL);
VN_RELE(cvp); return NULL;
return ERR_PTR(-EACCES);
}
} }
if (error && (error != ENOENT))
return ERR_PTR(-error); return d_splice_alias(LINVFS_GET_IP(cvp), dentry);
return d_splice_alias(ip, dentry);
} }
STATIC int STATIC int
......
...@@ -570,7 +570,6 @@ linvfs_get_parent( ...@@ -570,7 +570,6 @@ linvfs_get_parent(
int error; int error;
vnode_t *vp, *cvp; vnode_t *vp, *cvp;
struct dentry *parent; struct dentry *parent;
struct inode *ip = NULL;
struct dentry dotdot; struct dentry dotdot;
dotdot.d_name.name = ".."; dotdot.d_name.name = "..";
...@@ -580,21 +579,13 @@ linvfs_get_parent( ...@@ -580,21 +579,13 @@ linvfs_get_parent(
cvp = NULL; cvp = NULL;
vp = LINVFS_GET_VP(child->d_inode); vp = LINVFS_GET_VP(child->d_inode);
VOP_LOOKUP(vp, &dotdot, &cvp, 0, NULL, NULL, error); VOP_LOOKUP(vp, &dotdot, &cvp, 0, NULL, NULL, error);
if (unlikely(error))
if (!error) {
ASSERT(cvp);
ip = LINVFS_GET_IP(cvp);
if (!ip) {
VN_RELE(cvp);
return ERR_PTR(-EACCES);
}
}
if (error)
return ERR_PTR(-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); VN_RELE(cvp);
parent = ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
return parent; return parent;
} }
......
...@@ -1582,31 +1582,35 @@ xfs_vget( ...@@ -1582,31 +1582,35 @@ xfs_vget(
vnode_t **vpp, vnode_t **vpp,
fid_t *fidp) 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; xfs_inode_t *ip;
int error; int error;
xfs_ino_t ino; xfs_ino_t ino;
unsigned int igen; 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
ino = xfid->xfs_fid_ino; * via gethandle(), this is not cause for a panic.
igen = xfid->xfs_fid_gen; */
} else { 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.
*/
return XFS_ERROR(EINVAL); return XFS_ERROR(EINVAL);
}
mp = XFS_BHVTOM(bdp); ino = xfid->xfs_fid_ino;
igen = xfid->xfs_fid_gen;
/*
* NFS can sometimes send requests for ino 0. Fail them gracefully.
*/
if (ino == 0)
return XFS_ERROR(ESTALE);
error = xfs_iget(mp, NULL, ino, XFS_ILOCK_SHARED, &ip, 0); error = xfs_iget(mp, NULL, ino, XFS_ILOCK_SHARED, &ip, 0);
if (error) { if (error) {
*vpp = NULL; *vpp = NULL;
return error; return error;
} }
if (ip == NULL) { if (ip == NULL) {
*vpp = NULL; *vpp = NULL;
return XFS_ERROR(EIO); 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