diff options
author | J. Bruce Fields <bfields@citi.umich.edu> | 2009-06-15 21:08:07 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-06-15 21:08:07 -0400 |
commit | 7eef4091a653c243a87e5375c54504cc03bec4d8 (patch) | |
tree | f65b77f830b2c8f7d014512badfef5df0d591ee9 /fs/nfsd/nfs4xdr.c | |
parent | 0a93a47f042c459f0f46942c3a920e3c81878031 (diff) | |
parent | 07a2039b8eb0af4ff464efd3dfd95de5c02648c6 (diff) |
Merge commit 'v2.6.30' into for-2.6.31
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 254e5b21b915..d07f704a2ac9 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -2188,6 +2188,15 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, | |||
2188 | dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen); | 2188 | dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen); |
2189 | if (IS_ERR(dentry)) | 2189 | if (IS_ERR(dentry)) |
2190 | return nfserrno(PTR_ERR(dentry)); | 2190 | return nfserrno(PTR_ERR(dentry)); |
2191 | if (!dentry->d_inode) { | ||
2192 | /* | ||
2193 | * nfsd_buffered_readdir drops the i_mutex between | ||
2194 | * readdir and calling this callback, leaving a window | ||
2195 | * where this directory entry could have gone away. | ||
2196 | */ | ||
2197 | dput(dentry); | ||
2198 | return nfserr_noent; | ||
2199 | } | ||
2191 | 2200 | ||
2192 | exp_get(exp); | 2201 | exp_get(exp); |
2193 | /* | 2202 | /* |
@@ -2250,6 +2259,7 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | |||
2250 | struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); | 2259 | struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); |
2251 | int buflen; | 2260 | int buflen; |
2252 | __be32 *p = cd->buffer; | 2261 | __be32 *p = cd->buffer; |
2262 | __be32 *cookiep; | ||
2253 | __be32 nfserr = nfserr_toosmall; | 2263 | __be32 nfserr = nfserr_toosmall; |
2254 | 2264 | ||
2255 | /* In nfsv4, "." and ".." never make it onto the wire.. */ | 2265 | /* In nfsv4, "." and ".." never make it onto the wire.. */ |
@@ -2266,7 +2276,7 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | |||
2266 | goto fail; | 2276 | goto fail; |
2267 | 2277 | ||
2268 | *p++ = xdr_one; /* mark entry present */ | 2278 | *p++ = xdr_one; /* mark entry present */ |
2269 | cd->offset = p; /* remember pointer */ | 2279 | cookiep = p; |
2270 | p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */ | 2280 | p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */ |
2271 | p = xdr_encode_array(p, name, namlen); /* name length & name */ | 2281 | p = xdr_encode_array(p, name, namlen); /* name length & name */ |
2272 | 2282 | ||
@@ -2280,6 +2290,8 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | |||
2280 | goto fail; | 2290 | goto fail; |
2281 | case nfserr_dropit: | 2291 | case nfserr_dropit: |
2282 | goto fail; | 2292 | goto fail; |
2293 | case nfserr_noent: | ||
2294 | goto skip_entry; | ||
2283 | default: | 2295 | default: |
2284 | /* | 2296 | /* |
2285 | * If the client requested the RDATTR_ERROR attribute, | 2297 | * If the client requested the RDATTR_ERROR attribute, |
@@ -2298,6 +2310,8 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | |||
2298 | } | 2310 | } |
2299 | cd->buflen -= (p - cd->buffer); | 2311 | cd->buflen -= (p - cd->buffer); |
2300 | cd->buffer = p; | 2312 | cd->buffer = p; |
2313 | cd->offset = cookiep; | ||
2314 | skip_entry: | ||
2301 | cd->common.err = nfs_ok; | 2315 | cd->common.err = nfs_ok; |
2302 | return 0; | 2316 | return 0; |
2303 | fail: | 2317 | fail: |