diff options
Diffstat (limited to 'fs/nfsd/nfs3xdr.c')
-rw-r--r-- | fs/nfsd/nfs3xdr.c | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 9147b8524d05..243d94b9653a 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
@@ -154,37 +154,34 @@ decode_sattr3(u32 *p, struct iattr *iap) | |||
154 | } | 154 | } |
155 | 155 | ||
156 | static inline u32 * | 156 | static inline u32 * |
157 | encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) | 157 | encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp, |
158 | struct kstat *stat) | ||
158 | { | 159 | { |
159 | struct vfsmount *mnt = fhp->fh_export->ex_mnt; | ||
160 | struct dentry *dentry = fhp->fh_dentry; | 160 | struct dentry *dentry = fhp->fh_dentry; |
161 | struct kstat stat; | ||
162 | struct timespec time; | 161 | struct timespec time; |
163 | 162 | ||
164 | vfs_getattr(mnt, dentry, &stat); | 163 | *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); |
165 | 164 | *p++ = htonl((u32) stat->mode); | |
166 | *p++ = htonl(nfs3_ftypes[(stat.mode & S_IFMT) >> 12]); | 165 | *p++ = htonl((u32) stat->nlink); |
167 | *p++ = htonl((u32) stat.mode); | 166 | *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid)); |
168 | *p++ = htonl((u32) stat.nlink); | 167 | *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid)); |
169 | *p++ = htonl((u32) nfsd_ruid(rqstp, stat.uid)); | 168 | if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) { |
170 | *p++ = htonl((u32) nfsd_rgid(rqstp, stat.gid)); | ||
171 | if (S_ISLNK(stat.mode) && stat.size > NFS3_MAXPATHLEN) { | ||
172 | p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN); | 169 | p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN); |
173 | } else { | 170 | } else { |
174 | p = xdr_encode_hyper(p, (u64) stat.size); | 171 | p = xdr_encode_hyper(p, (u64) stat->size); |
175 | } | 172 | } |
176 | p = xdr_encode_hyper(p, ((u64)stat.blocks) << 9); | 173 | p = xdr_encode_hyper(p, ((u64)stat->blocks) << 9); |
177 | *p++ = htonl((u32) MAJOR(stat.rdev)); | 174 | *p++ = htonl((u32) MAJOR(stat->rdev)); |
178 | *p++ = htonl((u32) MINOR(stat.rdev)); | 175 | *p++ = htonl((u32) MINOR(stat->rdev)); |
179 | if (is_fsid(fhp, rqstp->rq_reffh)) | 176 | if (is_fsid(fhp, rqstp->rq_reffh)) |
180 | p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid); | 177 | p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid); |
181 | else | 178 | else |
182 | p = xdr_encode_hyper(p, (u64) huge_encode_dev(stat.dev)); | 179 | p = xdr_encode_hyper(p, (u64) huge_encode_dev(stat->dev)); |
183 | p = xdr_encode_hyper(p, (u64) stat.ino); | 180 | p = xdr_encode_hyper(p, (u64) stat->ino); |
184 | p = encode_time3(p, &stat.atime); | 181 | p = encode_time3(p, &stat->atime); |
185 | lease_get_mtime(dentry->d_inode, &time); | 182 | lease_get_mtime(dentry->d_inode, &time); |
186 | p = encode_time3(p, &time); | 183 | p = encode_time3(p, &time); |
187 | p = encode_time3(p, &stat.ctime); | 184 | p = encode_time3(p, &stat->ctime); |
188 | 185 | ||
189 | return p; | 186 | return p; |
190 | } | 187 | } |
@@ -232,8 +229,14 @@ encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) | |||
232 | { | 229 | { |
233 | struct dentry *dentry = fhp->fh_dentry; | 230 | struct dentry *dentry = fhp->fh_dentry; |
234 | if (dentry && dentry->d_inode != NULL) { | 231 | if (dentry && dentry->d_inode != NULL) { |
235 | *p++ = xdr_one; /* attributes follow */ | 232 | int err; |
236 | return encode_fattr3(rqstp, p, fhp); | 233 | struct kstat stat; |
234 | |||
235 | err = vfs_getattr(fhp->fh_export->ex_mnt, dentry, &stat); | ||
236 | if (!err) { | ||
237 | *p++ = xdr_one; /* attributes follow */ | ||
238 | return encode_fattr3(rqstp, p, fhp, &stat); | ||
239 | } | ||
237 | } | 240 | } |
238 | *p++ = xdr_zero; | 241 | *p++ = xdr_zero; |
239 | return p; | 242 | return p; |
@@ -616,7 +619,7 @@ nfs3svc_encode_attrstat(struct svc_rqst *rqstp, u32 *p, | |||
616 | struct nfsd3_attrstat *resp) | 619 | struct nfsd3_attrstat *resp) |
617 | { | 620 | { |
618 | if (resp->status == 0) | 621 | if (resp->status == 0) |
619 | p = encode_fattr3(rqstp, p, &resp->fh); | 622 | p = encode_fattr3(rqstp, p, &resp->fh, &resp->stat); |
620 | return xdr_ressize_check(rqstp, p); | 623 | return xdr_ressize_check(rqstp, p); |
621 | } | 624 | } |
622 | 625 | ||