Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

autofs4: reorganize expire pending wait function calls

This patch re-orgnirzes the checking for and waiting on active expires and
elininates redundant checks.

Signed-off-by: Ian Kent <raven@themaw.net>
Cc: Jeff Moyer <jmoyer@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Ian Kent and committed by
Linus Torvalds
06a35985 ec6e8c7d

+40 -65
+1
fs/autofs4/autofs_i.h
··· 163 163 164 164 /* Expiration */ 165 165 int is_autofs4_dentry(struct dentry *); 166 + int autofs4_expire_wait(struct dentry *dentry); 166 167 int autofs4_expire_run(struct super_block *, struct vfsmount *, 167 168 struct autofs_sb_info *, 168 169 struct autofs_packet_expire __user *);
+29
fs/autofs4/expire.c
··· 402 402 return expired; 403 403 } 404 404 405 + int autofs4_expire_wait(struct dentry *dentry) 406 + { 407 + struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); 408 + struct autofs_info *ino = autofs4_dentry_ino(dentry); 409 + int status; 410 + 411 + /* Block on any pending expire */ 412 + spin_lock(&sbi->fs_lock); 413 + if (ino->flags & AUTOFS_INF_EXPIRING) { 414 + spin_unlock(&sbi->fs_lock); 415 + 416 + DPRINTK("waiting for expire %p name=%.*s", 417 + dentry, dentry->d_name.len, dentry->d_name.name); 418 + 419 + status = autofs4_wait(sbi, dentry, NFY_NONE); 420 + wait_for_completion(&ino->expire_complete); 421 + 422 + DPRINTK("expire done status=%d", status); 423 + 424 + if (d_unhashed(dentry)) 425 + return -EAGAIN; 426 + 427 + return status; 428 + } 429 + spin_unlock(&sbi->fs_lock); 430 + 431 + return 0; 432 + } 433 + 405 434 /* Perform an expiry operation */ 406 435 int autofs4_expire_run(struct super_block *sb, 407 436 struct vfsmount *mnt,
+10 -65
fs/autofs4/root.c
··· 130 130 struct autofs_info *ino = autofs4_dentry_ino(dentry); 131 131 int status; 132 132 133 - /* Block on any pending expiry here; invalidate the dentry 134 - when expiration is done to trigger mount request with a new 135 - dentry */ 136 - spin_lock(&sbi->fs_lock); 137 - if (ino->flags & AUTOFS_INF_EXPIRING) { 138 - spin_unlock(&sbi->fs_lock); 139 - 140 - DPRINTK("waiting for expire %p name=%.*s", 141 - dentry, dentry->d_name.len, dentry->d_name.name); 142 - 143 - status = autofs4_wait(sbi, dentry, NFY_NONE); 144 - wait_for_completion(&ino->expire_complete); 145 - 146 - DPRINTK("expire done status=%d", status); 147 - 148 - /* 149 - * If the directory still exists the mount request must 150 - * continue otherwise it can't be followed at the right 151 - * time during the walk. 152 - */ 153 - status = d_invalidate(dentry); 154 - if (status != -EBUSY) 155 - return -EAGAIN; 156 - 157 - goto cont; 158 - } 159 - spin_unlock(&sbi->fs_lock); 160 - cont: 161 133 DPRINTK("dentry=%p %.*s ino=%p", 162 134 dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); 163 135 ··· 220 248 } 221 249 222 250 /* If an expire request is pending everyone must wait. */ 223 - spin_lock(&sbi->fs_lock); 224 - if (ino->flags & AUTOFS_INF_EXPIRING) { 225 - spin_unlock(&sbi->fs_lock); 251 + autofs4_expire_wait(dentry); 226 252 227 - DPRINTK("waiting for active request %p name=%.*s", 228 - dentry, dentry->d_name.len, dentry->d_name.name); 229 - 230 - status = autofs4_wait(sbi, dentry, NFY_NONE); 231 - wait_for_completion(&ino->expire_complete); 232 - 233 - DPRINTK("request done status=%d", status); 234 - 235 - goto cont; 236 - } 237 - spin_unlock(&sbi->fs_lock); 238 - cont: 239 253 /* We trigger a mount for almost all flags */ 240 254 lookup_type = nd->flags & (TRIGGER_FLAGS | TRIGGER_INTENTS); 241 255 if (!(lookup_type || dentry->d_flags & DCACHE_AUTOFS_PENDING)) ··· 290 332 return 1; 291 333 292 334 /* 335 + * If the directory has gone away due to an expire 336 + * we have been called as ->d_revalidate() and so 337 + * we need to return false and proceed to ->lookup(). 338 + */ 339 + if (autofs4_expire_wait(dentry) == -EAGAIN) 340 + return 0; 341 + 342 + /* 293 343 * A zero status is success otherwise we have a 294 344 * negative error code. 295 345 */ 296 346 status = try_to_fill_dentry(dentry, flags); 297 347 if (status == 0) 298 348 return 1; 299 - 300 - /* 301 - * A status of EAGAIN here means that the dentry has gone 302 - * away while waiting for an expire to complete. If we are 303 - * racing with expire lookup will wait for it so this must 304 - * be a revalidate and we need to send it to lookup. 305 - */ 306 - if (status == -EAGAIN) 307 - return 0; 308 349 309 350 return status; 310 351 } ··· 514 557 * so it must have been successful, so just wait for it. 515 558 */ 516 559 ino = autofs4_dentry_ino(expiring); 517 - spin_lock(&sbi->fs_lock); 518 - if (ino->flags & AUTOFS_INF_EXPIRING) { 519 - spin_unlock(&sbi->fs_lock); 520 - DPRINTK("wait for incomplete expire %p name=%.*s", 521 - expiring, expiring->d_name.len, 522 - expiring->d_name.name); 523 - autofs4_wait(sbi, expiring, NFY_NONE); 524 - wait_for_completion(&ino->expire_complete); 525 - DPRINTK("request completed"); 526 - goto cont; 527 - } 528 - spin_unlock(&sbi->fs_lock); 529 - cont: 560 + autofs4_expire_wait(expiring); 530 561 spin_lock(&sbi->lookup_lock); 531 562 if (!list_empty(&ino->expiring)) 532 563 list_del_init(&ino->expiring);