Commit 4f4a4fad authored by J. Bruce Fields's avatar J. Bruce Fields Committed by Al Viro

nfsd: handle vfs_getattr errors in acl protocol

We're currently ignoring errors from vfs_getattr.

The correct thing to do is to do the stat in the main service procedure
not in the response encoding.
Reported-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 3dadecce
...@@ -45,6 +45,10 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp, ...@@ -45,6 +45,10 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp,
RETURN_STATUS(nfserr_inval); RETURN_STATUS(nfserr_inval);
resp->mask = argp->mask; resp->mask = argp->mask;
nfserr = fh_getattr(fh, &resp->stat);
if (nfserr)
goto fail;
if (resp->mask & (NFS_ACL|NFS_ACLCNT)) { if (resp->mask & (NFS_ACL|NFS_ACLCNT)) {
acl = nfsd_get_posix_acl(fh, ACL_TYPE_ACCESS); acl = nfsd_get_posix_acl(fh, ACL_TYPE_ACCESS);
if (IS_ERR(acl)) { if (IS_ERR(acl)) {
...@@ -115,6 +119,9 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst * rqstp, ...@@ -115,6 +119,9 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst * rqstp,
nfserr = nfserrno( nfsd_set_posix_acl( nfserr = nfserrno( nfsd_set_posix_acl(
fh, ACL_TYPE_DEFAULT, argp->acl_default) ); fh, ACL_TYPE_DEFAULT, argp->acl_default) );
} }
if (!nfserr) {
nfserr = fh_getattr(fh, &resp->stat);
}
/* argp->acl_{access,default} may have been allocated in /* argp->acl_{access,default} may have been allocated in
nfssvc_decode_setaclargs. */ nfssvc_decode_setaclargs. */
...@@ -129,10 +136,15 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst * rqstp, ...@@ -129,10 +136,15 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst * rqstp,
static __be32 nfsacld_proc_getattr(struct svc_rqst * rqstp, static __be32 nfsacld_proc_getattr(struct svc_rqst * rqstp,
struct nfsd_fhandle *argp, struct nfsd_attrstat *resp) struct nfsd_fhandle *argp, struct nfsd_attrstat *resp)
{ {
__be32 nfserr;
dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh)); dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh));
fh_copy(&resp->fh, &argp->fh); fh_copy(&resp->fh, &argp->fh);
return fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP); nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP);
if (nfserr)
return nfserr;
nfserr = fh_getattr(&resp->fh, &resp->stat);
return nfserr;
} }
/* /*
...@@ -150,6 +162,9 @@ static __be32 nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessarg ...@@ -150,6 +162,9 @@ static __be32 nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessarg
fh_copy(&resp->fh, &argp->fh); fh_copy(&resp->fh, &argp->fh);
resp->access = argp->access; resp->access = argp->access;
nfserr = nfsd_access(rqstp, &resp->fh, &resp->access, NULL); nfserr = nfsd_access(rqstp, &resp->fh, &resp->access, NULL);
if (nfserr)
return nfserr;
nfserr = fh_getattr(&resp->fh, &resp->stat);
return nfserr; return nfserr;
} }
...@@ -243,7 +258,7 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, ...@@ -243,7 +258,7 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p,
return 0; return 0;
inode = dentry->d_inode; inode = dentry->d_inode;
p = nfs2svc_encode_fattr(rqstp, p, &resp->fh); p = nfs2svc_encode_fattr(rqstp, p, &resp->fh, &resp->stat);
*p++ = htonl(resp->mask); *p++ = htonl(resp->mask);
if (!xdr_ressize_check(rqstp, p)) if (!xdr_ressize_check(rqstp, p))
return 0; return 0;
...@@ -274,7 +289,7 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, ...@@ -274,7 +289,7 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p,
static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, __be32 *p, static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, __be32 *p,
struct nfsd_attrstat *resp) struct nfsd_attrstat *resp)
{ {
p = nfs2svc_encode_fattr(rqstp, p, &resp->fh); p = nfs2svc_encode_fattr(rqstp, p, &resp->fh, &resp->stat);
return xdr_ressize_check(rqstp, p); return xdr_ressize_check(rqstp, p);
} }
...@@ -282,7 +297,7 @@ static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, __be32 *p, ...@@ -282,7 +297,7 @@ static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, __be32 *p,
static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, __be32 *p, static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, __be32 *p,
struct nfsd3_accessres *resp) struct nfsd3_accessres *resp)
{ {
p = nfs2svc_encode_fattr(rqstp, p, &resp->fh); p = nfs2svc_encode_fattr(rqstp, p, &resp->fh, &resp->stat);
*p++ = htonl(resp->access); *p++ = htonl(resp->access);
return xdr_ressize_check(rqstp, p); return xdr_ressize_check(rqstp, p);
} }
......
...@@ -195,11 +195,9 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, ...@@ -195,11 +195,9 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
} }
/* Helper function for NFSv2 ACL code */ /* Helper function for NFSv2 ACL code */
__be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, struct kstat *stat)
{ {
struct kstat stat; return encode_fattr(rqstp, p, fhp, stat);
fh_getattr(fhp, &stat); /* BUG */
return encode_fattr(rqstp, p, fhp, &stat);
} }
/* /*
......
...@@ -167,7 +167,7 @@ int nfssvc_encode_entry(void *, const char *name, ...@@ -167,7 +167,7 @@ int nfssvc_encode_entry(void *, const char *name,
int nfssvc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); int nfssvc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *);
/* Helper functions for NFSv2 ACL code */ /* Helper functions for NFSv2 ACL code */
__be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp); __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, struct kstat *stat);
__be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp); __be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp);
#endif /* LINUX_NFSD_H */ #endif /* LINUX_NFSD_H */
...@@ -136,6 +136,7 @@ struct nfsd3_accessres { ...@@ -136,6 +136,7 @@ struct nfsd3_accessres {
__be32 status; __be32 status;
struct svc_fh fh; struct svc_fh fh;
__u32 access; __u32 access;
struct kstat stat;
}; };
struct nfsd3_readlinkres { struct nfsd3_readlinkres {
...@@ -225,6 +226,7 @@ struct nfsd3_getaclres { ...@@ -225,6 +226,7 @@ struct nfsd3_getaclres {
int mask; int mask;
struct posix_acl *acl_access; struct posix_acl *acl_access;
struct posix_acl *acl_default; struct posix_acl *acl_default;
struct kstat stat;
}; };
/* dummy type for release */ /* dummy type for release */
......
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