NFSD: forget_delegations should use list_for_each_entry_safe
authorBryan Schumaker <bjschuma@netapp.com>
Wed, 14 Dec 2011 19:39:56 +0000 (14:39 -0500)
committerJ. Bruce Fields <bfields@redhat.com>
Wed, 14 Dec 2011 22:38:00 +0000 (17:38 -0500)
Otherwise the for loop could try to use a file recently removed from the
file_hashtbl list and oops.

Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
Tested-by: Casey Bodley <cbodley@citi.umich.edu>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfs4state.c

index 19ca9b5..7355fe4 100644 (file)
@@ -4505,18 +4505,19 @@ void nfsd_forget_openowners(u64 num)
 int nfsd_process_n_delegations(u64 num, void (*deleg_func)(struct nfs4_delegation *))
 {
        int i, count = 0;
-       struct nfs4_file *fp;
-       struct nfs4_delegation *dp, *next;
+       struct nfs4_file *fp, *fnext;
+       struct nfs4_delegation *dp, *dnext;
 
        for (i = 0; i < FILE_HASH_SIZE; i++) {
-               list_for_each_entry(fp, &file_hashtbl[i], fi_hash) {
-                       list_for_each_entry_safe(dp, next, &fp->fi_delegations, dl_perfile) {
+               list_for_each_entry_safe(fp, fnext, &file_hashtbl[i], fi_hash) {
+                       list_for_each_entry_safe(dp, dnext, &fp->fi_delegations, dl_perfile) {
                                deleg_func(dp);
                                if (++count == num)
                                        return count;
                        }
                }
        }
+
        return count;
 }