NFS: Make nfs_fhget() return appropriate error values
Currently it returns NULL, which usually gets interpreted as ENOMEM. In fact it can mean a host of issues. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
01d0ae8bea
commit
03f28e3a20
3 changed files with 13 additions and 14 deletions
10
fs/nfs/dir.c
10
fs/nfs/dir.c
|
@ -901,9 +901,9 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
|
||||||
res = ERR_PTR(error);
|
res = ERR_PTR(error);
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
res = ERR_PTR(-EACCES);
|
|
||||||
inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr);
|
inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr);
|
||||||
if (!inode)
|
res = (struct dentry *)inode;
|
||||||
|
if (IS_ERR(res))
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
no_entry:
|
no_entry:
|
||||||
res = d_add_unique(dentry, inode);
|
res = d_add_unique(dentry, inode);
|
||||||
|
@ -1096,7 +1096,7 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
|
||||||
return NULL;
|
return NULL;
|
||||||
dentry->d_op = NFS_PROTO(dir)->dentry_ops;
|
dentry->d_op = NFS_PROTO(dir)->dentry_ops;
|
||||||
inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr);
|
inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr);
|
||||||
if (!inode) {
|
if (IS_ERR(inode)) {
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1134,9 +1134,9 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
error = -ENOMEM;
|
|
||||||
inode = nfs_fhget(dentry->d_sb, fhandle, fattr);
|
inode = nfs_fhget(dentry->d_sb, fhandle, fattr);
|
||||||
if (inode == NULL)
|
error = PTR_ERR(inode);
|
||||||
|
if (IS_ERR(inode))
|
||||||
goto out_err;
|
goto out_err;
|
||||||
d_instantiate(dentry, inode);
|
d_instantiate(dentry, inode);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -241,7 +241,6 @@ static struct inode *
|
||||||
nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *fsinfo)
|
nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *fsinfo)
|
||||||
{
|
{
|
||||||
struct nfs_server *server = NFS_SB(sb);
|
struct nfs_server *server = NFS_SB(sb);
|
||||||
struct inode *rooti;
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = server->rpc_ops->getroot(server, rootfh, fsinfo);
|
error = server->rpc_ops->getroot(server, rootfh, fsinfo);
|
||||||
|
@ -250,10 +249,7 @@ nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *f
|
||||||
return ERR_PTR(error);
|
return ERR_PTR(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
rooti = nfs_fhget(sb, rootfh, fsinfo->fattr);
|
return nfs_fhget(sb, rootfh, fsinfo->fattr);
|
||||||
if (!rooti)
|
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
return rooti;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -853,7 +849,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
|
||||||
.fh = fh,
|
.fh = fh,
|
||||||
.fattr = fattr
|
.fattr = fattr
|
||||||
};
|
};
|
||||||
struct inode *inode = NULL;
|
struct inode *inode = ERR_PTR(-ENOENT);
|
||||||
unsigned long hash;
|
unsigned long hash;
|
||||||
|
|
||||||
if ((fattr->valid & NFS_ATTR_FATTR) == 0)
|
if ((fattr->valid & NFS_ATTR_FATTR) == 0)
|
||||||
|
@ -866,8 +862,11 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
|
||||||
|
|
||||||
hash = nfs_fattr_to_ino_t(fattr);
|
hash = nfs_fattr_to_ino_t(fattr);
|
||||||
|
|
||||||
if (!(inode = iget5_locked(sb, hash, nfs_find_actor, nfs_init_locked, &desc)))
|
inode = iget5_locked(sb, hash, nfs_find_actor, nfs_init_locked, &desc);
|
||||||
|
if (inode == NULL) {
|
||||||
|
inode = ERR_PTR(-ENOMEM);
|
||||||
goto out_no_inode;
|
goto out_no_inode;
|
||||||
|
}
|
||||||
|
|
||||||
if (inode->i_state & I_NEW) {
|
if (inode->i_state & I_NEW) {
|
||||||
struct nfs_inode *nfsi = NFS_I(inode);
|
struct nfs_inode *nfsi = NFS_I(inode);
|
||||||
|
@ -936,7 +935,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
|
||||||
return inode;
|
return inode;
|
||||||
|
|
||||||
out_no_inode:
|
out_no_inode:
|
||||||
printk("nfs_fhget: iget failed\n");
|
dprintk("nfs_fhget: iget failed with error %ld\n", PTR_ERR(inode));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -336,7 +336,7 @@ static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data
|
||||||
if (!(data->f_attr.valid & NFS_ATTR_FATTR))
|
if (!(data->f_attr.valid & NFS_ATTR_FATTR))
|
||||||
goto out;
|
goto out;
|
||||||
inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, &data->f_attr);
|
inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, &data->f_attr);
|
||||||
if (inode == NULL)
|
if (IS_ERR(inode))
|
||||||
goto out;
|
goto out;
|
||||||
state = nfs4_get_open_state(inode, data->owner);
|
state = nfs4_get_open_state(inode, data->owner);
|
||||||
if (state == NULL)
|
if (state == NULL)
|
||||||
|
|
Loading…
Reference in a new issue