]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-nfs-fixes.patch
- [2.4.2x, 2.6.x] don't recursively crash in die() on CHRP/PReP machines
[packages/kernel.git] / kernel-nfs-fixes.patch
CommitLineData
0509ec2a
KT
1diff -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(&current->sigmask_lock);
17- siginitsetinv(&current->blocked, sigmask(SIGKILL));
18+ siginitsetinv(&current->blocked, sigmask(SIGKILL|SIGTERM));
19 recalc_sigpending(current);
20 spin_unlock_irq(&current->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");
39diff -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)
This page took 0.274383 seconds and 4 git commands to generate.