hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/fs/autofs/expire.c
....@@ -1,14 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
34 * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org>
45 * Copyright 2001-2006 Ian Kent <raven@themaw.net>
5
- *
6
- * This file is part of the Linux kernel and is made available under
7
- * the terms of the GNU General Public License, version 2, or at your
8
- * option, any later version, incorporated herein by reference.
96 */
107
11
-#include <linux/delay.h>
128 #include "autofs_i.h"
139
1410 /* Check if a dentry can be expired */
....@@ -74,6 +70,27 @@
7470 return status;
7571 }
7672
73
+/* p->d_lock held */
74
+static struct dentry *positive_after(struct dentry *p, struct dentry *child)
75
+{
76
+ if (child)
77
+ child = list_next_entry(child, d_child);
78
+ else
79
+ child = list_first_entry(&p->d_subdirs, struct dentry, d_child);
80
+
81
+ list_for_each_entry_from(child, &p->d_subdirs, d_child) {
82
+ spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);
83
+ if (simple_positive(child)) {
84
+ dget_dlock(child);
85
+ spin_unlock(&child->d_lock);
86
+ return child;
87
+ }
88
+ spin_unlock(&child->d_lock);
89
+ }
90
+
91
+ return NULL;
92
+}
93
+
7794 /*
7895 * Calculate and dget next entry in the subdirs list under root.
7996 */
....@@ -81,43 +98,14 @@
8198 struct dentry *root)
8299 {
83100 struct autofs_sb_info *sbi = autofs_sbi(root->d_sb);
84
- struct list_head *next;
85101 struct dentry *q;
86102
87103 spin_lock(&sbi->lookup_lock);
88104 spin_lock(&root->d_lock);
89
-
90
- if (prev)
91
- next = prev->d_child.next;
92
- else {
93
- prev = dget_dlock(root);
94
- next = prev->d_subdirs.next;
95
- }
96
-
97
-cont:
98
- if (next == &root->d_subdirs) {
99
- spin_unlock(&root->d_lock);
100
- spin_unlock(&sbi->lookup_lock);
101
- dput(prev);
102
- return NULL;
103
- }
104
-
105
- q = list_entry(next, struct dentry, d_child);
106
-
107
- spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED);
108
- /* Already gone or negative dentry (under construction) - try next */
109
- if (!d_count(q) || !simple_positive(q)) {
110
- spin_unlock(&q->d_lock);
111
- next = q->d_child.next;
112
- goto cont;
113
- }
114
- dget_dlock(q);
115
- spin_unlock(&q->d_lock);
105
+ q = positive_after(root, prev);
116106 spin_unlock(&root->d_lock);
117107 spin_unlock(&sbi->lookup_lock);
118
-
119108 dput(prev);
120
-
121109 return q;
122110 }
123111
....@@ -128,59 +116,28 @@
128116 struct dentry *root)
129117 {
130118 struct autofs_sb_info *sbi = autofs_sbi(root->d_sb);
131
- struct list_head *next;
132
- struct dentry *p, *ret;
119
+ struct dentry *p = prev, *ret = NULL, *d = NULL;
133120
134121 if (prev == NULL)
135122 return dget(root);
136123
137124 spin_lock(&sbi->lookup_lock);
138
-relock:
139
- p = prev;
140125 spin_lock(&p->d_lock);
141
-again:
142
- next = p->d_subdirs.next;
143
- if (next == &p->d_subdirs) {
144
- while (1) {
145
- struct dentry *parent;
126
+ while (1) {
127
+ struct dentry *parent;
146128
147
- if (p == root) {
148
- spin_unlock(&p->d_lock);
149
- spin_unlock(&sbi->lookup_lock);
150
- dput(prev);
151
- return NULL;
152
- }
153
-
154
- parent = p->d_parent;
155
- if (!spin_trylock(&parent->d_lock)) {
156
- spin_unlock(&p->d_lock);
157
- cpu_chill();
158
- goto relock;
159
- }
160
- spin_unlock(&p->d_lock);
161
- next = p->d_child.next;
162
- p = parent;
163
- if (next != &parent->d_subdirs)
164
- break;
165
- }
166
- }
167
- ret = list_entry(next, struct dentry, d_child);
168
-
169
- spin_lock_nested(&ret->d_lock, DENTRY_D_LOCK_NESTED);
170
- /* Negative dentry - try next */
171
- if (!simple_positive(ret)) {
129
+ ret = positive_after(p, d);
130
+ if (ret || p == root)
131
+ break;
132
+ parent = p->d_parent;
172133 spin_unlock(&p->d_lock);
173
- lock_set_subclass(&ret->d_lock.dep_map, 0, _RET_IP_);
174
- p = ret;
175
- goto again;
134
+ spin_lock(&parent->d_lock);
135
+ d = p;
136
+ p = parent;
176137 }
177
- dget_dlock(ret);
178
- spin_unlock(&ret->d_lock);
179138 spin_unlock(&p->d_lock);
180139 spin_unlock(&sbi->lookup_lock);
181
-
182140 dput(prev);
183
-
184141 return ret;
185142 }
186143
....@@ -254,7 +211,7 @@
254211 }
255212 } else {
256213 struct autofs_info *ino = autofs_dentry_ino(p);
257
- unsigned int ino_count = atomic_read(&ino->count);
214
+ unsigned int ino_count = READ_ONCE(ino->count);
258215
259216 /* allow for dget above and top is already dgot */
260217 if (p == top)
....@@ -422,7 +379,7 @@
422379 /* Not a forced expire? */
423380 if (!(how & AUTOFS_EXP_FORCED)) {
424381 /* ref-walk currently on this dentry? */
425
- ino_count = atomic_read(&ino->count) + 1;
382
+ ino_count = READ_ONCE(ino->count) + 1;
426383 if (d_count(dentry) > ino_count)
427384 return NULL;
428385 }
....@@ -439,7 +396,7 @@
439396 /* Not a forced expire? */
440397 if (!(how & AUTOFS_EXP_FORCED)) {
441398 /* ref-walk currently on this dentry? */
442
- ino_count = atomic_read(&ino->count) + 1;
399
+ ino_count = READ_ONCE(ino->count) + 1;
443400 if (d_count(dentry) > ino_count)
444401 return NULL;
445402 }