]>
Commit | Line | Data |
---|---|---|
0509ec2a KT |
1 | diff -urN linux.orig/fs/lockd/svc.c linux/fs/lockd/svc.c |
2 | --- linux.orig/fs/lockd/svc.c Sun Mar 25 18:37:38 2001 | |
3 | +++ linux/fs/lockd/svc.c Sat Mar 9 19:03:43 2002 | |
4 | @@ -37,7 +37,7 @@ | |
5 | ||
6 | #define NLMDBG_FACILITY NLMDBG_SVC | |
7 | #define LOCKD_BUFSIZE (1024 + NLMSSVC_XDRSIZE) | |
8 | -#define ALLOWED_SIGS (sigmask(SIGKILL)) | |
9 | +#define ALLOWED_SIGS (sigmask(SIGKILL|SIGTERM)) | |
10 | ||
11 | extern struct svc_program nlmsvc_program; | |
12 | struct nlmsvc_binding * nlmsvc_ops = NULL; | |
13 | @@ -82,7 +82,7 @@ | |
14 | ||
15 | /* Process request with signals blocked. */ | |
16 | spin_lock_irq(¤t->sigmask_lock); | |
17 | - siginitsetinv(¤t->blocked, sigmask(SIGKILL)); | |
18 | + siginitsetinv(¤t->blocked, sigmask(SIGKILL|SIGTERM)); | |
19 | recalc_sigpending(current); | |
20 | spin_unlock_irq(¤t->sigmask_lock); | |
21 | ||
22 | @@ -115,7 +115,7 @@ | |
23 | * NFS mount or NFS daemon has gone away, and we've been sent a | |
24 | * signal, or else another process has taken over our job. | |
25 | */ | |
26 | - while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) | |
27 | + while ((nlmsvc_users>1 || !signalled()) && nlmsvc_pid == current->pid) | |
28 | { | |
29 | long timeout = MAX_SCHEDULE_TIMEOUT; | |
30 | if (signalled()) { | |
31 | @@ -180,6 +180,7 @@ | |
32 | if (!nlmsvc_pid || current->pid == nlmsvc_pid) { | |
33 | nlm_shutdown_hosts(); | |
34 | nlmsvc_pid = 0; | |
35 | + nlmsvc_users = 0; | |
36 | } else | |
37 | printk(KERN_DEBUG | |
38 | "lockd: new process, skipping host shutdown\n"); | |
39 | diff -urN linux.orig/fs/nfsd/nfsfh.c linux/fs/nfsd/nfsfh.c | |
40 | --- linux.orig/fs/nfsd/nfsfh.c Sat Mar 9 13:03:12 2002 | |
41 | +++ linux/fs/nfsd/nfsfh.c Sat Mar 9 18:58:42 2002 | |
42 | @@ -114,6 +114,37 @@ | |
43 | return error; | |
44 | } | |
45 | ||
46 | +/* Arrange a dentry for the given inode: | |
47 | + * 1. Prefer an existing connected dentry. | |
48 | + * 2. Settle for an existing disconnected dentry. | |
49 | + * 3. If necessary, create a (disconnected) dentry. | |
50 | + */ | |
51 | +static struct dentry *nfsd_arrange_dentry(struct inode *inode) | |
52 | +{ | |
53 | + struct list_head *lp; | |
54 | + struct dentry *result; | |
55 | + | |
56 | + result = NULL; | |
57 | + for (lp = inode->i_dentry.next; lp != &inode->i_dentry ; lp=lp->next) { | |
58 | + result = list_entry(lp,struct dentry, d_alias); | |
59 | + if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) | |
60 | + break; | |
61 | + } | |
62 | + if (result) { | |
63 | + dget(result); | |
64 | + iput(inode); | |
65 | + } else { | |
66 | + result = d_alloc_root(inode, NULL); | |
67 | + if (!result) { | |
68 | + iput(inode); | |
69 | + return ERR_PTR(-ENOMEM); | |
70 | + } | |
71 | + result->d_flags |= DCACHE_NFSD_DISCONNECTED; | |
72 | + d_rehash(result); /* so a dput won't loose it */ | |
73 | + } | |
74 | + return result; | |
75 | +} | |
76 | + | |
77 | /* this should be provided by each filesystem in an nfsd_operations interface as | |
78 | * iget isn't really the right interface | |
79 | */ | |
80 | @@ -128,8 +159,6 @@ | |
81 | * so a generation of 0 means "accept any" | |
82 | */ | |
83 | struct inode *inode; | |
84 | - struct list_head *lp; | |
85 | - struct dentry *result; | |
86 | inode = iget_in_use(sb, ino, &locality); | |
87 | if (!inode) { | |
88 | dprintk("nfsd_iget: failed to find ino: %lu on %s\n", | |
89 | @@ -149,25 +178,8 @@ | |
90 | iput(inode); | |
91 | return ERR_PTR(-ESTALE); | |
92 | } | |
93 | - /* now to find a dentry. | |
94 | - * If possible, get a well-connected one | |
95 | - */ | |
96 | - for (lp = inode->i_dentry.next; lp != &inode->i_dentry ; lp=lp->next) { | |
97 | - result = list_entry(lp,struct dentry, d_alias); | |
98 | - if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) { | |
99 | - dget(result); | |
100 | - iput(inode); | |
101 | - return result; | |
102 | - } | |
103 | - } | |
104 | - result = d_alloc_root(inode, NULL); | |
105 | - if (result == NULL) { | |
106 | - iput(inode); | |
107 | - return ERR_PTR(-ENOMEM); | |
108 | - } | |
109 | - result->d_flags |= DCACHE_NFSD_DISCONNECTED; | |
110 | - d_rehash(result); /* so a dput won't loose it */ | |
111 | - return result; | |
112 | + | |
113 | + return nfsd_arrange_dentry(inode); | |
114 | } | |
115 | ||
116 | /* this routine links an IS_ROOT dentry into the dcache tree. It gains "parent" | |
117 | @@ -227,45 +239,28 @@ | |
118 | */ | |
119 | struct dentry *nfsd_findparent(struct dentry *child) | |
120 | { | |
121 | - struct dentry *tdentry, *pdentry; | |
122 | - tdentry = d_alloc(child, &(const struct qstr) {"..", 2, 0}); | |
123 | - if (!tdentry) | |
124 | + struct dentry *dotdot, *parent; | |
125 | + | |
126 | + dotdot = d_alloc(child, &(const struct qstr) {"..", 2, 0}); | |
127 | + if (!dotdot) | |
128 | return ERR_PTR(-ENOMEM); | |
129 | ||
130 | /* I'm going to assume that if the returned dentry is different, then | |
131 | * it is well connected. But nobody returns different dentrys do they? | |
132 | */ | |
133 | - pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry); | |
134 | - d_drop(tdentry); /* we never want ".." hashed */ | |
135 | - if (!pdentry) { | |
136 | - /* I don't want to return a ".." dentry. | |
137 | - * I would prefer to return an unconnected "IS_ROOT" dentry, | |
138 | - * though a properly connected dentry is even better | |
139 | - */ | |
140 | - /* if first or last of alias list is not tdentry, use that | |
141 | - * else make a root dentry | |
142 | - */ | |
143 | - struct list_head *aliases = &tdentry->d_inode->i_dentry; | |
144 | - if (aliases->next != aliases) { | |
145 | - pdentry = list_entry(aliases->next, struct dentry, d_alias); | |
146 | - if (pdentry == tdentry) | |
147 | - pdentry = list_entry(aliases->prev, struct dentry, d_alias); | |
148 | - if (pdentry == tdentry) | |
149 | - pdentry = NULL; | |
150 | - if (pdentry) dget(pdentry); | |
151 | - } | |
152 | - if (pdentry == NULL) { | |
153 | - pdentry = d_alloc_root(igrab(tdentry->d_inode), NULL); | |
154 | - if (pdentry) { | |
155 | - pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED; | |
156 | - d_rehash(pdentry); | |
157 | - } | |
158 | - } | |
159 | - if (pdentry == NULL) | |
160 | - pdentry = ERR_PTR(-ENOMEM); | |
161 | + parent = child->d_inode->i_op->lookup(child->d_inode, dotdot); | |
162 | + d_drop(dotdot); /* we never want ".." hashed */ | |
163 | + | |
164 | + if (parent) | |
165 | + dput(dotdot); /* not hashed, thus discarded */ | |
166 | + else { | |
167 | + /* Discard the ".." dentry, then arrange for a better one */ | |
168 | + struct inode *inode = igrab(dotdot->d_inode); | |
169 | + dput(dotdot); /* not hashed, thus discarded */ | |
170 | + parent = nfsd_arrange_dentry(inode); | |
171 | + | |
172 | } | |
173 | - dput(tdentry); /* it is not hashed, it will be discarded */ | |
174 | - return pdentry; | |
175 | + return parent; | |
176 | } | |
177 | ||
178 | static struct dentry *splice(struct dentry *child, struct dentry *parent) |