aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2009-06-15 21:08:07 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-06-15 21:08:07 -0400
commit7eef4091a653c243a87e5375c54504cc03bec4d8 (patch)
treef65b77f830b2c8f7d014512badfef5df0d591ee9 /fs/nfsd
parent0a93a47f042c459f0f46942c3a920e3c81878031 (diff)
parent07a2039b8eb0af4ff464efd3dfd95de5c02648c6 (diff)
Merge commit 'v2.6.30' into for-2.6.31
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4recover.c4
-rw-r--r--fs/nfsd/nfs4state.c1
-rw-r--r--fs/nfsd/nfs4xdr.c16
-rw-r--r--fs/nfsd/vfs.c6
4 files changed, 20 insertions, 7 deletions
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 5275097a7565..b5348405046b 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -229,7 +229,7 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
229 goto out; 229 goto out;
230 status = vfs_readdir(filp, nfsd4_build_namelist, &names); 230 status = vfs_readdir(filp, nfsd4_build_namelist, &names);
231 fput(filp); 231 fput(filp);
232 mutex_lock(&dir->d_inode->i_mutex); 232 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
233 while (!list_empty(&names)) { 233 while (!list_empty(&names)) {
234 entry = list_entry(names.next, struct name_list, list); 234 entry = list_entry(names.next, struct name_list, list);
235 235
@@ -264,7 +264,7 @@ nfsd4_unlink_clid_dir(char *name, int namlen)
264 264
265 dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name); 265 dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
266 266
267 mutex_lock(&rec_dir.dentry->d_inode->i_mutex); 267 mutex_lock_nested(&rec_dir.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
268 dentry = lookup_one_len(name, rec_dir.dentry, namlen); 268 dentry = lookup_one_len(name, rec_dir.dentry, namlen);
269 if (IS_ERR(dentry)) { 269 if (IS_ERR(dentry)) {
270 status = PTR_ERR(dentry); 270 status = PTR_ERR(dentry);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index b276624be66e..89d9ac55c034 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -578,7 +578,6 @@ free_session(struct kref *kref)
578 struct nfsd4_cache_entry *e = &ses->se_slots[i].sl_cache_entry; 578 struct nfsd4_cache_entry *e = &ses->se_slots[i].sl_cache_entry;
579 nfsd4_release_respages(e->ce_respages, e->ce_resused); 579 nfsd4_release_respages(e->ce_respages, e->ce_resused);
580 } 580 }
581 kfree(ses->se_slots);
582 kfree(ses); 581 kfree(ses);
583} 582}
584 583
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;
2314skip_entry:
2301 cd->common.err = nfs_ok; 2315 cd->common.err = nfs_ok;
2302 return 0; 2316 return 0;
2303fail: 2317fail:
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 6c68ffd6b4bb..b660435978d2 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1015,6 +1015,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
1015 host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset); 1015 host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset);
1016 set_fs(oldfs); 1016 set_fs(oldfs);
1017 if (host_err >= 0) { 1017 if (host_err >= 0) {
1018 *cnt = host_err;
1018 nfsdstats.io_write += host_err; 1019 nfsdstats.io_write += host_err;
1019 fsnotify_modify(file->f_path.dentry); 1020 fsnotify_modify(file->f_path.dentry);
1020 } 1021 }
@@ -1060,10 +1061,9 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
1060 } 1061 }
1061 1062
1062 dprintk("nfsd: write complete host_err=%d\n", host_err); 1063 dprintk("nfsd: write complete host_err=%d\n", host_err);
1063 if (host_err >= 0) { 1064 if (host_err >= 0)
1064 err = 0; 1065 err = 0;
1065 *cnt = host_err; 1066 else
1066 } else
1067 err = nfserrno(host_err); 1067 err = nfserrno(host_err);
1068out: 1068out:
1069 return err; 1069 return err;