]>
Commit | Line | Data |
---|---|---|
f84329bc PG |
1 | diff -u --recursive --new-file linux-2.5.71/net/sunrpc/rpc_pipe.c linux-2.5.71-fix_rpcpipe/net/sunrpc/rpc_pipe.c |
2 | --- linux-2.5.71/net/sunrpc/rpc_pipe.c 2003-06-11 19:24:29.000000000 -0700 | |
3 | +++ linux-2.5.71-fix_rpcpipe/net/sunrpc/rpc_pipe.c 2003-06-14 16:58:21.000000000 -0700 | |
4 | @@ -472,30 +472,37 @@ | |
5 | rpc_depopulate(struct dentry *parent) | |
6 | { | |
7 | struct inode *dir = parent->d_inode; | |
8 | - HLIST_HEAD(head); | |
9 | struct list_head *pos, *next; | |
10 | - struct dentry *dentry; | |
11 | + struct dentry *dentry, *dvec[10]; | |
12 | + int n = 0; | |
13 | ||
14 | down(&dir->i_sem); | |
15 | +repeat: | |
16 | spin_lock(&dcache_lock); | |
17 | list_for_each_safe(pos, next, &parent->d_subdirs) { | |
18 | dentry = list_entry(pos, struct dentry, d_child); | |
19 | + spin_lock(&dentry->d_lock); | |
20 | if (!d_unhashed(dentry)) { | |
21 | dget_locked(dentry); | |
22 | __d_drop(dentry); | |
23 | - hlist_add_head(&dentry->d_hash, &head); | |
24 | - } | |
25 | + spin_unlock(&dentry->d_lock); | |
26 | + dvec[n++] = dentry; | |
27 | + if (n == ARRAY_SIZE(dvec)) | |
28 | + break; | |
29 | + } else | |
30 | + spin_unlock(&dentry->d_lock); | |
31 | } | |
32 | spin_unlock(&dcache_lock); | |
33 | - while (!hlist_empty(&head)) { | |
34 | - dentry = list_entry(head.first, struct dentry, d_hash); | |
35 | - /* Private list, so no dcache_lock needed and use __d_drop */ | |
36 | - __d_drop(dentry); | |
37 | - if (dentry->d_inode) { | |
38 | - rpc_inode_setowner(dentry->d_inode, NULL); | |
39 | - simple_unlink(dir, dentry); | |
40 | - } | |
41 | - dput(dentry); | |
42 | + if (n) { | |
43 | + do { | |
44 | + dentry = dvec[--n]; | |
45 | + if (dentry->d_inode) { | |
46 | + rpc_inode_setowner(dentry->d_inode, NULL); | |
47 | + simple_unlink(dir, dentry); | |
48 | + } | |
49 | + dput(dentry); | |
50 | + } while (n); | |
51 | + goto repeat; | |
52 | } | |
53 | up(&dir->i_sem); | |
54 | } | |
55 |