diff options
author | David Shaw <dshaw@jabberwocky.com> | 2006-01-06 03:19:58 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 11:33:59 -0500 |
commit | a334de28665b14f0a33df82699fa9a78cfeedf31 (patch) | |
tree | 21749c30159b1e0bf4cae7e174ec1bdcf3859ef4 /fs/nfsd/nfsxdr.c | |
parent | 93fbf1a5de8afde08988dda3735669099dee84d0 (diff) |
[PATCH] knfsd: check error status from vfs_getattr and i_op->fsync
Both vfs_getattr and i_op->fsync return error statuses which nfsd was
largely ignoring. This as noticed when exporting directories using fuse.
This patch cleans up most of the offences, which involves moving the call
to vfs_getattr out of the xdr encoding routines (where it is too late to
report an error) into the main NFS procedure handling routines.
There is still a called to vfs_gettattr (related to the ACL code) where the
status is ignored, and called to nfsd_sync_dir don't check return status
either.
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/nfsd/nfsxdr.c')
-rw-r--r-- | fs/nfsd/nfsxdr.c | 48 |
1 files changed, 24 insertions, 24 deletions
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index b45999ff33e6..aa7bb41b293d 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c | |||
@@ -152,46 +152,44 @@ decode_sattr(u32 *p, struct iattr *iap) | |||
152 | } | 152 | } |
153 | 153 | ||
154 | static inline u32 * | 154 | static inline u32 * |
155 | encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) | 155 | encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp, |
156 | struct kstat *stat) | ||
156 | { | 157 | { |
157 | struct vfsmount *mnt = fhp->fh_export->ex_mnt; | ||
158 | struct dentry *dentry = fhp->fh_dentry; | 158 | struct dentry *dentry = fhp->fh_dentry; |
159 | struct kstat stat; | ||
160 | int type; | 159 | int type; |
161 | struct timespec time; | 160 | struct timespec time; |
162 | 161 | ||
163 | vfs_getattr(mnt, dentry, &stat); | 162 | type = (stat->mode & S_IFMT); |
164 | type = (stat.mode & S_IFMT); | ||
165 | 163 | ||
166 | *p++ = htonl(nfs_ftypes[type >> 12]); | 164 | *p++ = htonl(nfs_ftypes[type >> 12]); |
167 | *p++ = htonl((u32) stat.mode); | 165 | *p++ = htonl((u32) stat->mode); |
168 | *p++ = htonl((u32) stat.nlink); | 166 | *p++ = htonl((u32) stat->nlink); |
169 | *p++ = htonl((u32) nfsd_ruid(rqstp, stat.uid)); | 167 | *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid)); |
170 | *p++ = htonl((u32) nfsd_rgid(rqstp, stat.gid)); | 168 | *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid)); |
171 | 169 | ||
172 | if (S_ISLNK(type) && stat.size > NFS_MAXPATHLEN) { | 170 | if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) { |
173 | *p++ = htonl(NFS_MAXPATHLEN); | 171 | *p++ = htonl(NFS_MAXPATHLEN); |
174 | } else { | 172 | } else { |
175 | *p++ = htonl((u32) stat.size); | 173 | *p++ = htonl((u32) stat->size); |
176 | } | 174 | } |
177 | *p++ = htonl((u32) stat.blksize); | 175 | *p++ = htonl((u32) stat->blksize); |
178 | if (S_ISCHR(type) || S_ISBLK(type)) | 176 | if (S_ISCHR(type) || S_ISBLK(type)) |
179 | *p++ = htonl(new_encode_dev(stat.rdev)); | 177 | *p++ = htonl(new_encode_dev(stat->rdev)); |
180 | else | 178 | else |
181 | *p++ = htonl(0xffffffff); | 179 | *p++ = htonl(0xffffffff); |
182 | *p++ = htonl((u32) stat.blocks); | 180 | *p++ = htonl((u32) stat->blocks); |
183 | if (is_fsid(fhp, rqstp->rq_reffh)) | 181 | if (is_fsid(fhp, rqstp->rq_reffh)) |
184 | *p++ = htonl((u32) fhp->fh_export->ex_fsid); | 182 | *p++ = htonl((u32) fhp->fh_export->ex_fsid); |
185 | else | 183 | else |
186 | *p++ = htonl(new_encode_dev(stat.dev)); | 184 | *p++ = htonl(new_encode_dev(stat->dev)); |
187 | *p++ = htonl((u32) stat.ino); | 185 | *p++ = htonl((u32) stat->ino); |
188 | *p++ = htonl((u32) stat.atime.tv_sec); | 186 | *p++ = htonl((u32) stat->atime.tv_sec); |
189 | *p++ = htonl(stat.atime.tv_nsec ? stat.atime.tv_nsec / 1000 : 0); | 187 | *p++ = htonl(stat->atime.tv_nsec ? stat->atime.tv_nsec / 1000 : 0); |
190 | lease_get_mtime(dentry->d_inode, &time); | 188 | lease_get_mtime(dentry->d_inode, &time); |
191 | *p++ = htonl((u32) time.tv_sec); | 189 | *p++ = htonl((u32) time.tv_sec); |
192 | *p++ = htonl(time.tv_nsec ? time.tv_nsec / 1000 : 0); | 190 | *p++ = htonl(time.tv_nsec ? time.tv_nsec / 1000 : 0); |
193 | *p++ = htonl((u32) stat.ctime.tv_sec); | 191 | *p++ = htonl((u32) stat->ctime.tv_sec); |
194 | *p++ = htonl(stat.ctime.tv_nsec ? stat.ctime.tv_nsec / 1000 : 0); | 192 | *p++ = htonl(stat->ctime.tv_nsec ? stat->ctime.tv_nsec / 1000 : 0); |
195 | 193 | ||
196 | return p; | 194 | return p; |
197 | } | 195 | } |
@@ -199,7 +197,9 @@ encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) | |||
199 | /* Helper function for NFSv2 ACL code */ | 197 | /* Helper function for NFSv2 ACL code */ |
200 | u32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) | 198 | u32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) |
201 | { | 199 | { |
202 | return encode_fattr(rqstp, p, fhp); | 200 | struct kstat stat; |
201 | vfs_getattr(fhp->fh_export->ex_mnt, fhp->fh_dentry, &stat); | ||
202 | return encode_fattr(rqstp, p, fhp, &stat); | ||
203 | } | 203 | } |
204 | 204 | ||
205 | /* | 205 | /* |
@@ -394,7 +394,7 @@ int | |||
394 | nfssvc_encode_attrstat(struct svc_rqst *rqstp, u32 *p, | 394 | nfssvc_encode_attrstat(struct svc_rqst *rqstp, u32 *p, |
395 | struct nfsd_attrstat *resp) | 395 | struct nfsd_attrstat *resp) |
396 | { | 396 | { |
397 | p = encode_fattr(rqstp, p, &resp->fh); | 397 | p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); |
398 | return xdr_ressize_check(rqstp, p); | 398 | return xdr_ressize_check(rqstp, p); |
399 | } | 399 | } |
400 | 400 | ||
@@ -403,7 +403,7 @@ nfssvc_encode_diropres(struct svc_rqst *rqstp, u32 *p, | |||
403 | struct nfsd_diropres *resp) | 403 | struct nfsd_diropres *resp) |
404 | { | 404 | { |
405 | p = encode_fh(p, &resp->fh); | 405 | p = encode_fh(p, &resp->fh); |
406 | p = encode_fattr(rqstp, p, &resp->fh); | 406 | p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); |
407 | return xdr_ressize_check(rqstp, p); | 407 | return xdr_ressize_check(rqstp, p); |
408 | } | 408 | } |
409 | 409 | ||
@@ -428,7 +428,7 @@ int | |||
428 | nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p, | 428 | nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p, |
429 | struct nfsd_readres *resp) | 429 | struct nfsd_readres *resp) |
430 | { | 430 | { |
431 | p = encode_fattr(rqstp, p, &resp->fh); | 431 | p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); |
432 | *p++ = htonl(resp->count); | 432 | *p++ = htonl(resp->count); |
433 | xdr_ressize_check(rqstp, p); | 433 | xdr_ressize_check(rqstp, p); |
434 | 434 | ||