aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorIan Kent <raven@themaw.net>2009-12-15 19:45:45 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-16 10:19:58 -0500
commitaa952eb26d4344fdad44c104f3c298d3130c53da (patch)
tree4a49859b272d8d42ae7fa68c5d30f6aa2fd82742 /fs
parent36b6413ef301d30f60037e497ecb902897895473 (diff)
autofs4: use autofs_info for pending flag
Eliminate the use of the d_lock spin lock by using the autofs super block info spin lock. This reduces the number of spin locks we use by one and makes the code for the following patch (to redirect ->d_revalidate() to ->lookup()) a little simpler. Signed-off-by: Ian Kent <raven@themaw.net> Cc: Sage Weil <sage@newdream.net> Cc: Al Viro <viro@ZenIV.linux.org.uk> Cc: Andreas Dilger <adilger@sun.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: Yehuda Saheh <yehuda@newdream.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/autofs4/autofs_i.h3
-rw-r--r--fs/autofs4/expire.c2
-rw-r--r--fs/autofs4/root.c58
3 files changed, 35 insertions, 28 deletions
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index fe9fc235ee75..3d283abf67d7 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -97,6 +97,7 @@ struct autofs_info {
97 97
98#define AUTOFS_INF_EXPIRING (1<<0) /* dentry is in the process of expiring */ 98#define AUTOFS_INF_EXPIRING (1<<0) /* dentry is in the process of expiring */
99#define AUTOFS_INF_MOUNTPOINT (1<<1) /* mountpoint status for direct expire */ 99#define AUTOFS_INF_MOUNTPOINT (1<<1) /* mountpoint status for direct expire */
100#define AUTOFS_INF_PENDING (1<<2) /* dentry pending mount */
100 101
101struct autofs_wait_queue { 102struct autofs_wait_queue {
102 wait_queue_head_t queue; 103 wait_queue_head_t queue;
@@ -163,7 +164,7 @@ static inline int autofs4_ispending(struct dentry *dentry)
163{ 164{
164 struct autofs_info *inf = autofs4_dentry_ino(dentry); 165 struct autofs_info *inf = autofs4_dentry_ino(dentry);
165 166
166 if (dentry->d_flags & DCACHE_AUTOFS_PENDING) 167 if (inf->flags & AUTOFS_INF_PENDING)
167 return 1; 168 return 1;
168 169
169 if (inf->flags & AUTOFS_INF_EXPIRING) 170 if (inf->flags & AUTOFS_INF_EXPIRING)
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index 3da18d453488..a796c9417fb1 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -27,7 +27,7 @@ static inline int autofs4_can_expire(struct dentry *dentry,
27 return 0; 27 return 0;
28 28
29 /* No point expiring a pending mount */ 29 /* No point expiring a pending mount */
30 if (dentry->d_flags & DCACHE_AUTOFS_PENDING) 30 if (ino->flags & AUTOFS_INF_PENDING)
31 return 0; 31 return 0;
32 32
33 if (!do_now) { 33 if (!do_now) {
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index f6e8ca9ea56a..305136ba74b6 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -166,32 +166,32 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags)
166 166
167 /* Turn this into a real negative dentry? */ 167 /* Turn this into a real negative dentry? */
168 if (status == -ENOENT) { 168 if (status == -ENOENT) {
169 spin_lock(&dentry->d_lock); 169 spin_lock(&sbi->fs_lock);
170 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; 170 ino->flags &= ~AUTOFS_INF_PENDING;
171 spin_unlock(&dentry->d_lock); 171 spin_unlock(&sbi->fs_lock);
172 return status; 172 return status;
173 } else if (status) { 173 } else if (status) {
174 /* Return a negative dentry, but leave it "pending" */ 174 /* Return a negative dentry, but leave it "pending" */
175 return status; 175 return status;
176 } 176 }
177 /* Trigger mount for path component or follow link */ 177 /* Trigger mount for path component or follow link */
178 } else if (dentry->d_flags & DCACHE_AUTOFS_PENDING || 178 } else if (ino->flags & AUTOFS_INF_PENDING ||
179 autofs4_need_mount(flags) || 179 autofs4_need_mount(flags) ||
180 current->link_count) { 180 current->link_count) {
181 DPRINTK("waiting for mount name=%.*s", 181 DPRINTK("waiting for mount name=%.*s",
182 dentry->d_name.len, dentry->d_name.name); 182 dentry->d_name.len, dentry->d_name.name);
183 183
184 spin_lock(&dentry->d_lock); 184 spin_lock(&sbi->fs_lock);
185 dentry->d_flags |= DCACHE_AUTOFS_PENDING; 185 ino->flags |= AUTOFS_INF_PENDING;
186 spin_unlock(&dentry->d_lock); 186 spin_unlock(&sbi->fs_lock);
187 status = autofs4_wait(sbi, dentry, NFY_MOUNT); 187 status = autofs4_wait(sbi, dentry, NFY_MOUNT);
188 188
189 DPRINTK("mount done status=%d", status); 189 DPRINTK("mount done status=%d", status);
190 190
191 if (status) { 191 if (status) {
192 spin_lock(&dentry->d_lock); 192 spin_lock(&sbi->fs_lock);
193 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; 193 ino->flags &= ~AUTOFS_INF_PENDING;
194 spin_unlock(&dentry->d_lock); 194 spin_unlock(&sbi->fs_lock);
195 return status; 195 return status;
196 } 196 }
197 } 197 }
@@ -200,9 +200,9 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags)
200 if (ino) 200 if (ino)
201 ino->last_used = jiffies; 201 ino->last_used = jiffies;
202 202
203 spin_lock(&dentry->d_lock); 203 spin_lock(&sbi->fs_lock);
204 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; 204 ino->flags &= ~AUTOFS_INF_PENDING;
205 spin_unlock(&dentry->d_lock); 205 spin_unlock(&sbi->fs_lock);
206 206
207 return 0; 207 return 0;
208} 208}
@@ -243,18 +243,23 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
243 243
244 /* We trigger a mount for almost all flags */ 244 /* We trigger a mount for almost all flags */
245 lookup_type = autofs4_need_mount(nd->flags); 245 lookup_type = autofs4_need_mount(nd->flags);
246 if (!(lookup_type || dentry->d_flags & DCACHE_AUTOFS_PENDING)) 246 spin_lock(&sbi->fs_lock);
247 spin_lock(&dcache_lock);
248 if (!(lookup_type || ino->flags & AUTOFS_INF_PENDING)) {
249 spin_unlock(&dcache_lock);
250 spin_unlock(&sbi->fs_lock);
247 goto follow; 251 goto follow;
252 }
248 253
249 /* 254 /*
250 * If the dentry contains directories then it is an autofs 255 * If the dentry contains directories then it is an autofs
251 * multi-mount with no root mount offset. So don't try to 256 * multi-mount with no root mount offset. So don't try to
252 * mount it again. 257 * mount it again.
253 */ 258 */
254 spin_lock(&dcache_lock); 259 if (ino->flags & AUTOFS_INF_PENDING ||
255 if (dentry->d_flags & DCACHE_AUTOFS_PENDING ||
256 (!d_mountpoint(dentry) && __simple_empty(dentry))) { 260 (!d_mountpoint(dentry) && __simple_empty(dentry))) {
257 spin_unlock(&dcache_lock); 261 spin_unlock(&dcache_lock);
262 spin_unlock(&sbi->fs_lock);
258 263
259 status = try_to_fill_dentry(dentry, 0); 264 status = try_to_fill_dentry(dentry, 0);
260 if (status) 265 if (status)
@@ -263,6 +268,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
263 goto follow; 268 goto follow;
264 } 269 }
265 spin_unlock(&dcache_lock); 270 spin_unlock(&dcache_lock);
271 spin_unlock(&sbi->fs_lock);
266follow: 272follow:
267 /* 273 /*
268 * If there is no root mount it must be an autofs 274 * If there is no root mount it must be an autofs
@@ -525,9 +531,10 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
525 current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode); 531 current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode);
526 532
527 unhashed = autofs4_lookup_active(sbi, dentry->d_parent, &dentry->d_name); 533 unhashed = autofs4_lookup_active(sbi, dentry->d_parent, &dentry->d_name);
528 if (unhashed) 534 if (unhashed) {
529 dentry = unhashed; 535 dentry = unhashed;
530 else { 536 ino = autofs4_dentry_ino(dentry);
537 } else {
531 /* 538 /*
532 * Mark the dentry incomplete but don't hash it. We do this 539 * Mark the dentry incomplete but don't hash it. We do this
533 * to serialize our inode creation operations (symlink and 540 * to serialize our inode creation operations (symlink and
@@ -569,15 +576,14 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
569 * be quite complete but the directory has been removed 576 * be quite complete but the directory has been removed
570 * so it must have been successful, so just wait for it. 577 * so it must have been successful, so just wait for it.
571 */ 578 */
572 ino = autofs4_dentry_ino(expiring);
573 autofs4_expire_wait(expiring); 579 autofs4_expire_wait(expiring);
574 autofs4_del_expiring(expiring); 580 autofs4_del_expiring(expiring);
575 dput(expiring); 581 dput(expiring);
576 } 582 }
577 583
578 spin_lock(&dentry->d_lock); 584 spin_lock(&sbi->fs_lock);
579 dentry->d_flags |= DCACHE_AUTOFS_PENDING; 585 ino->flags |= AUTOFS_INF_PENDING;
580 spin_unlock(&dentry->d_lock); 586 spin_unlock(&sbi->fs_lock);
581 if (dentry->d_op && dentry->d_op->d_revalidate) 587 if (dentry->d_op && dentry->d_op->d_revalidate)
582 (dentry->d_op->d_revalidate)(dentry, nd); 588 (dentry->d_op->d_revalidate)(dentry, nd);
583 mutex_lock(&dir->i_mutex); 589 mutex_lock(&dir->i_mutex);
@@ -587,7 +593,7 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
587 * If we are still pending, check if we had to handle 593 * If we are still pending, check if we had to handle
588 * a signal. If so we can force a restart.. 594 * a signal. If so we can force a restart..
589 */ 595 */
590 if (dentry->d_flags & DCACHE_AUTOFS_PENDING) { 596 if (ino->flags & AUTOFS_INF_PENDING) {
591 /* See if we were interrupted */ 597 /* See if we were interrupted */
592 if (signal_pending(current)) { 598 if (signal_pending(current)) {
593 sigset_t *sigset = &current->pending.signal; 599 sigset_t *sigset = &current->pending.signal;
@@ -600,9 +606,9 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
600 } 606 }
601 } 607 }
602 if (!oz_mode) { 608 if (!oz_mode) {
603 spin_lock(&dentry->d_lock); 609 spin_lock(&sbi->fs_lock);
604 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; 610 ino->flags &= ~AUTOFS_INF_PENDING;
605 spin_unlock(&dentry->d_lock); 611 spin_unlock(&sbi->fs_lock);
606 } 612 }
607 } 613 }
608 614