diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-05-12 20:11:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-05-12 20:11:56 -0400 |
commit | 2ea3f868487dcee0bfd91055f1c42bb172efc507 (patch) | |
tree | ab8386aba340269f36c402c59ca77234ac1db7a6 /fs | |
parent | bfe3891a5f5d3b78146a45f40e435d14f5ae39dd (diff) | |
parent | 8daed1e549b55827758b3af7b8132a73fc51526f (diff) |
Merge branch 'for-2.6.30' of git://linux-nfs.org/~bfields/linux
* 'for-2.6.30' of git://linux-nfs.org/~bfields/linux:
nfsd: silence lockdep warning
lockd: fix list corruption on lockd restart
nfsd4: check for negative dentry before use in nfsv4 readdir
nfsd41: slots are freed with session
svcrdma: clean up error paths.
svcrdma: Fix dma map direction for rdma read targets
Diffstat (limited to 'fs')
-rw-r--r-- | fs/lockd/svc.c | 15 | ||||
-rw-r--r-- | fs/nfsd/nfs4recover.c | 4 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 1 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 16 |
4 files changed, 28 insertions, 8 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index abf83881f68a..1a54ae14a192 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -104,6 +104,16 @@ static void set_grace_period(void) | |||
104 | schedule_delayed_work(&grace_period_end, grace_period); | 104 | schedule_delayed_work(&grace_period_end, grace_period); |
105 | } | 105 | } |
106 | 106 | ||
107 | static void restart_grace(void) | ||
108 | { | ||
109 | if (nlmsvc_ops) { | ||
110 | cancel_delayed_work_sync(&grace_period_end); | ||
111 | locks_end_grace(&lockd_manager); | ||
112 | nlmsvc_invalidate_all(); | ||
113 | set_grace_period(); | ||
114 | } | ||
115 | } | ||
116 | |||
107 | /* | 117 | /* |
108 | * This is the lockd kernel thread | 118 | * This is the lockd kernel thread |
109 | */ | 119 | */ |
@@ -149,10 +159,7 @@ lockd(void *vrqstp) | |||
149 | 159 | ||
150 | if (signalled()) { | 160 | if (signalled()) { |
151 | flush_signals(current); | 161 | flush_signals(current); |
152 | if (nlmsvc_ops) { | 162 | restart_grace(); |
153 | nlmsvc_invalidate_all(); | ||
154 | set_grace_period(); | ||
155 | } | ||
156 | continue; | 163 | continue; |
157 | } | 164 | } |
158 | 165 | ||
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 c65a27b76a9d..3b711f5147a7 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -580,7 +580,6 @@ free_session(struct kref *kref) | |||
580 | struct nfsd4_cache_entry *e = &ses->se_slots[i].sl_cache_entry; | 580 | struct nfsd4_cache_entry *e = &ses->se_slots[i].sl_cache_entry; |
581 | nfsd4_release_respages(e->ce_respages, e->ce_resused); | 581 | nfsd4_release_respages(e->ce_respages, e->ce_resused); |
582 | } | 582 | } |
583 | kfree(ses->se_slots); | ||
584 | kfree(ses); | 583 | kfree(ses); |
585 | } | 584 | } |
586 | 585 | ||
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index b820c311931c..b73549d293be 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -2214,6 +2214,15 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, | |||
2214 | dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen); | 2214 | dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen); |
2215 | if (IS_ERR(dentry)) | 2215 | if (IS_ERR(dentry)) |
2216 | return nfserrno(PTR_ERR(dentry)); | 2216 | return nfserrno(PTR_ERR(dentry)); |
2217 | if (!dentry->d_inode) { | ||
2218 | /* | ||
2219 | * nfsd_buffered_readdir drops the i_mutex between | ||
2220 | * readdir and calling this callback, leaving a window | ||
2221 | * where this directory entry could have gone away. | ||
2222 | */ | ||
2223 | dput(dentry); | ||
2224 | return nfserr_noent; | ||
2225 | } | ||
2217 | 2226 | ||
2218 | exp_get(exp); | 2227 | exp_get(exp); |
2219 | /* | 2228 | /* |
@@ -2276,6 +2285,7 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | |||
2276 | struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); | 2285 | struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); |
2277 | int buflen; | 2286 | int buflen; |
2278 | __be32 *p = cd->buffer; | 2287 | __be32 *p = cd->buffer; |
2288 | __be32 *cookiep; | ||
2279 | __be32 nfserr = nfserr_toosmall; | 2289 | __be32 nfserr = nfserr_toosmall; |
2280 | 2290 | ||
2281 | /* In nfsv4, "." and ".." never make it onto the wire.. */ | 2291 | /* In nfsv4, "." and ".." never make it onto the wire.. */ |
@@ -2292,7 +2302,7 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | |||
2292 | goto fail; | 2302 | goto fail; |
2293 | 2303 | ||
2294 | *p++ = xdr_one; /* mark entry present */ | 2304 | *p++ = xdr_one; /* mark entry present */ |
2295 | cd->offset = p; /* remember pointer */ | 2305 | cookiep = p; |
2296 | p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */ | 2306 | p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */ |
2297 | p = xdr_encode_array(p, name, namlen); /* name length & name */ | 2307 | p = xdr_encode_array(p, name, namlen); /* name length & name */ |
2298 | 2308 | ||
@@ -2306,6 +2316,8 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | |||
2306 | goto fail; | 2316 | goto fail; |
2307 | case nfserr_dropit: | 2317 | case nfserr_dropit: |
2308 | goto fail; | 2318 | goto fail; |
2319 | case nfserr_noent: | ||
2320 | goto skip_entry; | ||
2309 | default: | 2321 | default: |
2310 | /* | 2322 | /* |
2311 | * If the client requested the RDATTR_ERROR attribute, | 2323 | * If the client requested the RDATTR_ERROR attribute, |
@@ -2324,6 +2336,8 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | |||
2324 | } | 2336 | } |
2325 | cd->buflen -= (p - cd->buffer); | 2337 | cd->buflen -= (p - cd->buffer); |
2326 | cd->buffer = p; | 2338 | cd->buffer = p; |
2339 | cd->offset = cookiep; | ||
2340 | skip_entry: | ||
2327 | cd->common.err = nfs_ok; | 2341 | cd->common.err = nfs_ok; |
2328 | return 0; | 2342 | return 0; |
2329 | fail: | 2343 | fail: |