summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/Locking2
-rw-r--r--Documentation/filesystems/vfs.txt2
-rw-r--r--fs/autofs4/autofs_i.h5
-rw-r--r--fs/autofs4/dev-ioctl.c4
-rw-r--r--fs/autofs4/expire.c25
-rw-r--r--fs/autofs4/root.c61
-rw-r--r--fs/autofs4/waitq.c13
-rw-r--r--fs/dcache.c40
-rw-r--r--fs/mount.h6
-rw-r--r--fs/namei.c13
-rw-r--r--fs/namespace.c29
-rw-r--r--include/linux/dcache.h4
-rw-r--r--include/linux/mount.h2
13 files changed, 131 insertions, 75 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 1b5f15653b1b..4ca3a8d1349d 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -20,7 +20,7 @@ prototypes:
20 void (*d_iput)(struct dentry *, struct inode *); 20 void (*d_iput)(struct dentry *, struct inode *);
21 char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); 21 char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
22 struct vfsmount *(*d_automount)(struct path *path); 22 struct vfsmount *(*d_automount)(struct path *path);
23 int (*d_manage)(struct dentry *, bool); 23 int (*d_manage)(const struct path *, bool);
24 struct dentry *(*d_real)(struct dentry *, const struct inode *, 24 struct dentry *(*d_real)(struct dentry *, const struct inode *,
25 unsigned int); 25 unsigned int);
26 26
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index b5039a00caaf..3893f4d44cd4 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -948,7 +948,7 @@ struct dentry_operations {
948 void (*d_iput)(struct dentry *, struct inode *); 948 void (*d_iput)(struct dentry *, struct inode *);
949 char *(*d_dname)(struct dentry *, char *, int); 949 char *(*d_dname)(struct dentry *, char *, int);
950 struct vfsmount *(*d_automount)(struct path *); 950 struct vfsmount *(*d_automount)(struct path *);
951 int (*d_manage)(struct dentry *, bool); 951 int (*d_manage)(const struct path *, bool);
952 struct dentry *(*d_real)(struct dentry *, const struct inode *, 952 struct dentry *(*d_real)(struct dentry *, const struct inode *,
953 unsigned int); 953 unsigned int);
954}; 954};
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index a1fba4285277..c885daae68c8 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -145,7 +145,7 @@ void autofs4_free_ino(struct autofs_info *);
145 145
146/* Expiration */ 146/* Expiration */
147int is_autofs4_dentry(struct dentry *); 147int is_autofs4_dentry(struct dentry *);
148int autofs4_expire_wait(struct dentry *dentry, int rcu_walk); 148int autofs4_expire_wait(const struct path *path, int rcu_walk);
149int autofs4_expire_run(struct super_block *, struct vfsmount *, 149int autofs4_expire_run(struct super_block *, struct vfsmount *,
150 struct autofs_sb_info *, 150 struct autofs_sb_info *,
151 struct autofs_packet_expire __user *); 151 struct autofs_packet_expire __user *);
@@ -217,7 +217,8 @@ static inline int autofs_prepare_pipe(struct file *pipe)
217 217
218/* Queue management functions */ 218/* Queue management functions */
219 219
220int autofs4_wait(struct autofs_sb_info *, struct dentry *, enum autofs_notify); 220int autofs4_wait(struct autofs_sb_info *,
221 const struct path *, enum autofs_notify);
221int autofs4_wait_release(struct autofs_sb_info *, autofs_wqt_t, int); 222int autofs4_wait_release(struct autofs_sb_info *, autofs_wqt_t, int);
222void autofs4_catatonic_mode(struct autofs_sb_info *); 223void autofs4_catatonic_mode(struct autofs_sb_info *);
223 224
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
index dfc6f49ee597..6f48d670c941 100644
--- a/fs/autofs4/dev-ioctl.c
+++ b/fs/autofs4/dev-ioctl.c
@@ -468,7 +468,7 @@ static int autofs_dev_ioctl_requester(struct file *fp,
468 ino = autofs4_dentry_ino(path.dentry); 468 ino = autofs4_dentry_ino(path.dentry);
469 if (ino) { 469 if (ino) {
470 err = 0; 470 err = 0;
471 autofs4_expire_wait(path.dentry, 0); 471 autofs4_expire_wait(&path, 0);
472 spin_lock(&sbi->fs_lock); 472 spin_lock(&sbi->fs_lock);
473 param->requester.uid = 473 param->requester.uid =
474 from_kuid_munged(current_user_ns(), ino->uid); 474 from_kuid_munged(current_user_ns(), ino->uid);
@@ -575,7 +575,7 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
575 575
576 devid = new_encode_dev(dev); 576 devid = new_encode_dev(dev);
577 577
578 err = have_submounts(path.dentry); 578 err = path_has_submounts(&path);
579 579
580 if (follow_down_one(&path)) 580 if (follow_down_one(&path))
581 magic = path.dentry->d_sb->s_magic; 581 magic = path.dentry->d_sb->s_magic;
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index d8e6d421c27f..57725d4a8c59 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -310,26 +310,29 @@ struct dentry *autofs4_expire_direct(struct super_block *sb,
310 now = jiffies; 310 now = jiffies;
311 timeout = sbi->exp_timeout; 311 timeout = sbi->exp_timeout;
312 312
313 spin_lock(&sbi->fs_lock);
314 ino = autofs4_dentry_ino(root);
315 /* No point expiring a pending mount */
316 if (ino->flags & AUTOFS_INF_PENDING)
317 goto out;
318 if (!autofs4_direct_busy(mnt, root, timeout, do_now)) { 313 if (!autofs4_direct_busy(mnt, root, timeout, do_now)) {
314 spin_lock(&sbi->fs_lock);
315 ino = autofs4_dentry_ino(root);
316 /* No point expiring a pending mount */
317 if (ino->flags & AUTOFS_INF_PENDING) {
318 spin_unlock(&sbi->fs_lock);
319 goto out;
320 }
319 ino->flags |= AUTOFS_INF_WANT_EXPIRE; 321 ino->flags |= AUTOFS_INF_WANT_EXPIRE;
320 spin_unlock(&sbi->fs_lock); 322 spin_unlock(&sbi->fs_lock);
321 synchronize_rcu(); 323 synchronize_rcu();
322 spin_lock(&sbi->fs_lock);
323 if (!autofs4_direct_busy(mnt, root, timeout, do_now)) { 324 if (!autofs4_direct_busy(mnt, root, timeout, do_now)) {
325 spin_lock(&sbi->fs_lock);
324 ino->flags |= AUTOFS_INF_EXPIRING; 326 ino->flags |= AUTOFS_INF_EXPIRING;
325 init_completion(&ino->expire_complete); 327 init_completion(&ino->expire_complete);
326 spin_unlock(&sbi->fs_lock); 328 spin_unlock(&sbi->fs_lock);
327 return root; 329 return root;
328 } 330 }
331 spin_lock(&sbi->fs_lock);
329 ino->flags &= ~AUTOFS_INF_WANT_EXPIRE; 332 ino->flags &= ~AUTOFS_INF_WANT_EXPIRE;
333 spin_unlock(&sbi->fs_lock);
330 } 334 }
331out: 335out:
332 spin_unlock(&sbi->fs_lock);
333 dput(root); 336 dput(root);
334 337
335 return NULL; 338 return NULL;
@@ -495,8 +498,9 @@ found:
495 return expired; 498 return expired;
496} 499}
497 500
498int autofs4_expire_wait(struct dentry *dentry, int rcu_walk) 501int autofs4_expire_wait(const struct path *path, int rcu_walk)
499{ 502{
503 struct dentry *dentry = path->dentry;
500 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); 504 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
501 struct autofs_info *ino = autofs4_dentry_ino(dentry); 505 struct autofs_info *ino = autofs4_dentry_ino(dentry);
502 int status; 506 int status;
@@ -525,7 +529,7 @@ retry:
525 529
526 pr_debug("waiting for expire %p name=%pd\n", dentry, dentry); 530 pr_debug("waiting for expire %p name=%pd\n", dentry, dentry);
527 531
528 status = autofs4_wait(sbi, dentry, NFY_NONE); 532 status = autofs4_wait(sbi, path, NFY_NONE);
529 wait_for_completion(&ino->expire_complete); 533 wait_for_completion(&ino->expire_complete);
530 534
531 pr_debug("expire done status=%d\n", status); 535 pr_debug("expire done status=%d\n", status);
@@ -592,11 +596,12 @@ int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
592 596
593 if (dentry) { 597 if (dentry) {
594 struct autofs_info *ino = autofs4_dentry_ino(dentry); 598 struct autofs_info *ino = autofs4_dentry_ino(dentry);
599 const struct path path = { .mnt = mnt, .dentry = dentry };
595 600
596 /* This is synchronous because it makes the daemon a 601 /* This is synchronous because it makes the daemon a
597 * little easier 602 * little easier
598 */ 603 */
599 ret = autofs4_wait(sbi, dentry, NFY_EXPIRE); 604 ret = autofs4_wait(sbi, &path, NFY_EXPIRE);
600 605
601 spin_lock(&sbi->fs_lock); 606 spin_lock(&sbi->fs_lock);
602 /* avoid rapid-fire expire attempts if expiry fails */ 607 /* avoid rapid-fire expire attempts if expiry fails */
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index a11f73174877..82e8f6edfb48 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -32,7 +32,7 @@ static int autofs4_dir_open(struct inode *inode, struct file *file);
32static struct dentry *autofs4_lookup(struct inode *, 32static struct dentry *autofs4_lookup(struct inode *,
33 struct dentry *, unsigned int); 33 struct dentry *, unsigned int);
34static struct vfsmount *autofs4_d_automount(struct path *); 34static struct vfsmount *autofs4_d_automount(struct path *);
35static int autofs4_d_manage(struct dentry *, bool); 35static int autofs4_d_manage(const struct path *, bool);
36static void autofs4_dentry_release(struct dentry *); 36static void autofs4_dentry_release(struct dentry *);
37 37
38const struct file_operations autofs4_root_operations = { 38const struct file_operations autofs4_root_operations = {
@@ -123,7 +123,7 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
123 * it. 123 * it.
124 */ 124 */
125 spin_lock(&sbi->lookup_lock); 125 spin_lock(&sbi->lookup_lock);
126 if (!d_mountpoint(dentry) && simple_empty(dentry)) { 126 if (!path_is_mountpoint(&file->f_path) && simple_empty(dentry)) {
127 spin_unlock(&sbi->lookup_lock); 127 spin_unlock(&sbi->lookup_lock);
128 return -ENOENT; 128 return -ENOENT;
129 } 129 }
@@ -269,39 +269,41 @@ next:
269 return NULL; 269 return NULL;
270} 270}
271 271
272static int autofs4_mount_wait(struct dentry *dentry, bool rcu_walk) 272static int autofs4_mount_wait(const struct path *path, bool rcu_walk)
273{ 273{
274 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); 274 struct autofs_sb_info *sbi = autofs4_sbi(path->dentry->d_sb);
275 struct autofs_info *ino = autofs4_dentry_ino(dentry); 275 struct autofs_info *ino = autofs4_dentry_ino(path->dentry);
276 int status = 0; 276 int status = 0;
277 277
278 if (ino->flags & AUTOFS_INF_PENDING) { 278 if (ino->flags & AUTOFS_INF_PENDING) {
279 if (rcu_walk) 279 if (rcu_walk)
280 return -ECHILD; 280 return -ECHILD;
281 pr_debug("waiting for mount name=%pd\n", dentry); 281 pr_debug("waiting for mount name=%pd\n", path->dentry);
282 status = autofs4_wait(sbi, dentry, NFY_MOUNT); 282 status = autofs4_wait(sbi, path, NFY_MOUNT);
283 pr_debug("mount wait done status=%d\n", status); 283 pr_debug("mount wait done status=%d\n", status);
284 } 284 }
285 ino->last_used = jiffies; 285 ino->last_used = jiffies;
286 return status; 286 return status;
287} 287}
288 288
289static int do_expire_wait(struct dentry *dentry, bool rcu_walk) 289static int do_expire_wait(const struct path *path, bool rcu_walk)
290{ 290{
291 struct dentry *dentry = path->dentry;
291 struct dentry *expiring; 292 struct dentry *expiring;
292 293
293 expiring = autofs4_lookup_expiring(dentry, rcu_walk); 294 expiring = autofs4_lookup_expiring(dentry, rcu_walk);
294 if (IS_ERR(expiring)) 295 if (IS_ERR(expiring))
295 return PTR_ERR(expiring); 296 return PTR_ERR(expiring);
296 if (!expiring) 297 if (!expiring)
297 return autofs4_expire_wait(dentry, rcu_walk); 298 return autofs4_expire_wait(path, rcu_walk);
298 else { 299 else {
300 const struct path this = { .mnt = path->mnt, .dentry = expiring };
299 /* 301 /*
300 * If we are racing with expire the request might not 302 * If we are racing with expire the request might not
301 * be quite complete, but the directory has been removed 303 * be quite complete, but the directory has been removed
302 * so it must have been successful, just wait for it. 304 * so it must have been successful, just wait for it.
303 */ 305 */
304 autofs4_expire_wait(expiring, 0); 306 autofs4_expire_wait(&this, 0);
305 autofs4_del_expiring(expiring); 307 autofs4_del_expiring(expiring);
306 dput(expiring); 308 dput(expiring);
307 } 309 }
@@ -354,7 +356,7 @@ static struct vfsmount *autofs4_d_automount(struct path *path)
354 * and the directory was removed, so just go ahead and try 356 * and the directory was removed, so just go ahead and try
355 * the mount. 357 * the mount.
356 */ 358 */
357 status = do_expire_wait(dentry, 0); 359 status = do_expire_wait(path, 0);
358 if (status && status != -EAGAIN) 360 if (status && status != -EAGAIN)
359 return NULL; 361 return NULL;
360 362
@@ -362,7 +364,7 @@ static struct vfsmount *autofs4_d_automount(struct path *path)
362 spin_lock(&sbi->fs_lock); 364 spin_lock(&sbi->fs_lock);
363 if (ino->flags & AUTOFS_INF_PENDING) { 365 if (ino->flags & AUTOFS_INF_PENDING) {
364 spin_unlock(&sbi->fs_lock); 366 spin_unlock(&sbi->fs_lock);
365 status = autofs4_mount_wait(dentry, 0); 367 status = autofs4_mount_wait(path, 0);
366 if (status) 368 if (status)
367 return ERR_PTR(status); 369 return ERR_PTR(status);
368 goto done; 370 goto done;
@@ -370,28 +372,28 @@ static struct vfsmount *autofs4_d_automount(struct path *path)
370 372
371 /* 373 /*
372 * If the dentry is a symlink it's equivalent to a directory 374 * If the dentry is a symlink it's equivalent to a directory
373 * having d_mountpoint() true, so there's no need to call back 375 * having path_is_mountpoint() true, so there's no need to call
374 * to the daemon. 376 * back to the daemon.
375 */ 377 */
376 if (d_really_is_positive(dentry) && d_is_symlink(dentry)) { 378 if (d_really_is_positive(dentry) && d_is_symlink(dentry)) {
377 spin_unlock(&sbi->fs_lock); 379 spin_unlock(&sbi->fs_lock);
378 goto done; 380 goto done;
379 } 381 }
380 382
381 if (!d_mountpoint(dentry)) { 383 if (!path_is_mountpoint(path)) {
382 /* 384 /*
383 * It's possible that user space hasn't removed directories 385 * It's possible that user space hasn't removed directories
384 * after umounting a rootless multi-mount, although it 386 * after umounting a rootless multi-mount, although it
385 * should. For v5 have_submounts() is sufficient to handle 387 * should. For v5 path_has_submounts() is sufficient to
386 * this because the leaves of the directory tree under the 388 * handle this because the leaves of the directory tree under
387 * mount never trigger mounts themselves (they have an autofs 389 * the mount never trigger mounts themselves (they have an
388 * trigger mount mounted on them). But v4 pseudo direct mounts 390 * autofs trigger mount mounted on them). But v4 pseudo direct
389 * do need the leaves to trigger mounts. In this case we 391 * mounts do need the leaves to trigger mounts. In this case
390 * have no choice but to use the list_empty() check and 392 * we have no choice but to use the list_empty() check and
391 * require user space behave. 393 * require user space behave.
392 */ 394 */
393 if (sbi->version > 4) { 395 if (sbi->version > 4) {
394 if (have_submounts(dentry)) { 396 if (path_has_submounts(path)) {
395 spin_unlock(&sbi->fs_lock); 397 spin_unlock(&sbi->fs_lock);
396 goto done; 398 goto done;
397 } 399 }
@@ -403,7 +405,7 @@ static struct vfsmount *autofs4_d_automount(struct path *path)
403 } 405 }
404 ino->flags |= AUTOFS_INF_PENDING; 406 ino->flags |= AUTOFS_INF_PENDING;
405 spin_unlock(&sbi->fs_lock); 407 spin_unlock(&sbi->fs_lock);
406 status = autofs4_mount_wait(dentry, 0); 408 status = autofs4_mount_wait(path, 0);
407 spin_lock(&sbi->fs_lock); 409 spin_lock(&sbi->fs_lock);
408 ino->flags &= ~AUTOFS_INF_PENDING; 410 ino->flags &= ~AUTOFS_INF_PENDING;
409 if (status) { 411 if (status) {
@@ -421,8 +423,9 @@ done:
421 return NULL; 423 return NULL;
422} 424}
423 425
424static int autofs4_d_manage(struct dentry *dentry, bool rcu_walk) 426static int autofs4_d_manage(const struct path *path, bool rcu_walk)
425{ 427{
428 struct dentry *dentry = path->dentry;
426 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); 429 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
427 struct autofs_info *ino = autofs4_dentry_ino(dentry); 430 struct autofs_info *ino = autofs4_dentry_ino(dentry);
428 int status; 431 int status;
@@ -431,20 +434,20 @@ static int autofs4_d_manage(struct dentry *dentry, bool rcu_walk)
431 434
432 /* The daemon never waits. */ 435 /* The daemon never waits. */
433 if (autofs4_oz_mode(sbi)) { 436 if (autofs4_oz_mode(sbi)) {
434 if (!d_mountpoint(dentry)) 437 if (!path_is_mountpoint(path))
435 return -EISDIR; 438 return -EISDIR;
436 return 0; 439 return 0;
437 } 440 }
438 441
439 /* Wait for pending expires */ 442 /* Wait for pending expires */
440 if (do_expire_wait(dentry, rcu_walk) == -ECHILD) 443 if (do_expire_wait(path, rcu_walk) == -ECHILD)
441 return -ECHILD; 444 return -ECHILD;
442 445
443 /* 446 /*
444 * This dentry may be under construction so wait on mount 447 * This dentry may be under construction so wait on mount
445 * completion. 448 * completion.
446 */ 449 */
447 status = autofs4_mount_wait(dentry, rcu_walk); 450 status = autofs4_mount_wait(path, rcu_walk);
448 if (status) 451 if (status)
449 return status; 452 return status;
450 453
@@ -460,7 +463,7 @@ static int autofs4_d_manage(struct dentry *dentry, bool rcu_walk)
460 463
461 if (ino->flags & AUTOFS_INF_WANT_EXPIRE) 464 if (ino->flags & AUTOFS_INF_WANT_EXPIRE)
462 return 0; 465 return 0;
463 if (d_mountpoint(dentry)) 466 if (path_is_mountpoint(path))
464 return 0; 467 return 0;
465 inode = d_inode_rcu(dentry); 468 inode = d_inode_rcu(dentry);
466 if (inode && S_ISLNK(inode->i_mode)) 469 if (inode && S_ISLNK(inode->i_mode))
@@ -487,7 +490,7 @@ static int autofs4_d_manage(struct dentry *dentry, bool rcu_walk)
487 * we can avoid needless calls ->d_automount() and avoid 490 * we can avoid needless calls ->d_automount() and avoid
488 * an incorrect ELOOP error return. 491 * an incorrect ELOOP error return.
489 */ 492 */
490 if ((!d_mountpoint(dentry) && !simple_empty(dentry)) || 493 if ((!path_is_mountpoint(path) && !simple_empty(dentry)) ||
491 (d_really_is_positive(dentry) && d_is_symlink(dentry))) 494 (d_really_is_positive(dentry) && d_is_symlink(dentry)))
492 status = -EISDIR; 495 status = -EISDIR;
493 } 496 }
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index e44271dfceb6..1278335ce366 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -250,8 +250,9 @@ autofs4_find_wait(struct autofs_sb_info *sbi, const struct qstr *qstr)
250static int validate_request(struct autofs_wait_queue **wait, 250static int validate_request(struct autofs_wait_queue **wait,
251 struct autofs_sb_info *sbi, 251 struct autofs_sb_info *sbi,
252 const struct qstr *qstr, 252 const struct qstr *qstr,
253 struct dentry *dentry, enum autofs_notify notify) 253 const struct path *path, enum autofs_notify notify)
254{ 254{
255 struct dentry *dentry = path->dentry;
255 struct autofs_wait_queue *wq; 256 struct autofs_wait_queue *wq;
256 struct autofs_info *ino; 257 struct autofs_info *ino;
257 258
@@ -314,6 +315,7 @@ static int validate_request(struct autofs_wait_queue **wait,
314 */ 315 */
315 if (notify == NFY_MOUNT) { 316 if (notify == NFY_MOUNT) {
316 struct dentry *new = NULL; 317 struct dentry *new = NULL;
318 struct path this;
317 int valid = 1; 319 int valid = 1;
318 320
319 /* 321 /*
@@ -333,7 +335,9 @@ static int validate_request(struct autofs_wait_queue **wait,
333 dentry = new; 335 dentry = new;
334 } 336 }
335 } 337 }
336 if (have_submounts(dentry)) 338 this.mnt = path->mnt;
339 this.dentry = dentry;
340 if (path_has_submounts(&this))
337 valid = 0; 341 valid = 0;
338 342
339 if (new) 343 if (new)
@@ -345,8 +349,9 @@ static int validate_request(struct autofs_wait_queue **wait,
345} 349}
346 350
347int autofs4_wait(struct autofs_sb_info *sbi, 351int autofs4_wait(struct autofs_sb_info *sbi,
348 struct dentry *dentry, enum autofs_notify notify) 352 const struct path *path, enum autofs_notify notify)
349{ 353{
354 struct dentry *dentry = path->dentry;
350 struct autofs_wait_queue *wq; 355 struct autofs_wait_queue *wq;
351 struct qstr qstr; 356 struct qstr qstr;
352 char *name; 357 char *name;
@@ -405,7 +410,7 @@ int autofs4_wait(struct autofs_sb_info *sbi,
405 return -EINTR; 410 return -EINTR;
406 } 411 }
407 412
408 ret = validate_request(&wq, sbi, &qstr, dentry, notify); 413 ret = validate_request(&wq, sbi, &qstr, path, notify);
409 if (ret <= 0) { 414 if (ret <= 0) {
410 if (ret != -EINTR) 415 if (ret != -EINTR)
411 mutex_unlock(&sbi->wq_mutex); 416 mutex_unlock(&sbi->wq_mutex);
diff --git a/fs/dcache.c b/fs/dcache.c
index 5c7cc953ac81..252378359a8f 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1273,38 +1273,44 @@ rename_retry:
1273 goto again; 1273 goto again;
1274} 1274}
1275 1275
1276/* 1276struct check_mount {
1277 * Search for at least 1 mount point in the dentry's subdirs. 1277 struct vfsmount *mnt;
1278 * We descend to the next level whenever the d_subdirs 1278 unsigned int mounted;
1279 * list is non-empty and continue searching. 1279};
1280 */
1281 1280
1282static enum d_walk_ret check_mount(void *data, struct dentry *dentry) 1281static enum d_walk_ret path_check_mount(void *data, struct dentry *dentry)
1283{ 1282{
1284 int *ret = data; 1283 struct check_mount *info = data;
1285 if (d_mountpoint(dentry)) { 1284 struct path path = { .mnt = info->mnt, .dentry = dentry };
1286 *ret = 1; 1285
1286 if (likely(!d_mountpoint(dentry)))
1287 return D_WALK_CONTINUE;
1288 if (__path_is_mountpoint(&path)) {
1289 info->mounted = 1;
1287 return D_WALK_QUIT; 1290 return D_WALK_QUIT;
1288 } 1291 }
1289 return D_WALK_CONTINUE; 1292 return D_WALK_CONTINUE;
1290} 1293}
1291 1294
1292/** 1295/**
1293 * have_submounts - check for mounts over a dentry 1296 * path_has_submounts - check for mounts over a dentry in the
1294 * @parent: dentry to check. 1297 * current namespace.
1298 * @parent: path to check.
1295 * 1299 *
1296 * Return true if the parent or its subdirectories contain 1300 * Return true if the parent or its subdirectories contain
1297 * a mount point 1301 * a mount point in the current namespace.
1298 */ 1302 */
1299int have_submounts(struct dentry *parent) 1303int path_has_submounts(const struct path *parent)
1300{ 1304{
1301 int ret = 0; 1305 struct check_mount data = { .mnt = parent->mnt, .mounted = 0 };
1302 1306
1303 d_walk(parent, &ret, check_mount, NULL); 1307 read_seqlock_excl(&mount_lock);
1308 d_walk(parent->dentry, &data, path_check_mount, NULL);
1309 read_sequnlock_excl(&mount_lock);
1304 1310
1305 return ret; 1311 return data.mounted;
1306} 1312}
1307EXPORT_SYMBOL(have_submounts); 1313EXPORT_SYMBOL(path_has_submounts);
1308 1314
1309/* 1315/*
1310 * Called by mount code to set a mountpoint and check if the mountpoint is 1316 * Called by mount code to set a mountpoint and check if the mountpoint is
diff --git a/fs/mount.h b/fs/mount.h
index d2e25d7b64b3..2c856fc47ae3 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -94,6 +94,12 @@ extern struct mount *__lookup_mnt_last(struct vfsmount *, struct dentry *);
94extern int __legitimize_mnt(struct vfsmount *, unsigned); 94extern int __legitimize_mnt(struct vfsmount *, unsigned);
95extern bool legitimize_mnt(struct vfsmount *, unsigned); 95extern bool legitimize_mnt(struct vfsmount *, unsigned);
96 96
97static inline bool __path_is_mountpoint(const struct path *path)
98{
99 struct mount *m = __lookup_mnt(path->mnt, path->dentry);
100 return m && likely(!(m->mnt.mnt_flags & MNT_SYNC_UMOUNT));
101}
102
97extern void __detach_mounts(struct dentry *dentry); 103extern void __detach_mounts(struct dentry *dentry);
98 104
99static inline void detach_mounts(struct dentry *dentry) 105static inline void detach_mounts(struct dentry *dentry)
diff --git a/fs/namei.c b/fs/namei.c
index 1c8f4386b03f..47781b0d909d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1200,7 +1200,7 @@ static int follow_managed(struct path *path, struct nameidata *nd)
1200 if (managed & DCACHE_MANAGE_TRANSIT) { 1200 if (managed & DCACHE_MANAGE_TRANSIT) {
1201 BUG_ON(!path->dentry->d_op); 1201 BUG_ON(!path->dentry->d_op);
1202 BUG_ON(!path->dentry->d_op->d_manage); 1202 BUG_ON(!path->dentry->d_op->d_manage);
1203 ret = path->dentry->d_op->d_manage(path->dentry, false); 1203 ret = path->dentry->d_op->d_manage(path, false);
1204 if (ret < 0) 1204 if (ret < 0)
1205 break; 1205 break;
1206 } 1206 }
@@ -1263,10 +1263,10 @@ int follow_down_one(struct path *path)
1263} 1263}
1264EXPORT_SYMBOL(follow_down_one); 1264EXPORT_SYMBOL(follow_down_one);
1265 1265
1266static inline int managed_dentry_rcu(struct dentry *dentry) 1266static inline int managed_dentry_rcu(const struct path *path)
1267{ 1267{
1268 return (dentry->d_flags & DCACHE_MANAGE_TRANSIT) ? 1268 return (path->dentry->d_flags & DCACHE_MANAGE_TRANSIT) ?
1269 dentry->d_op->d_manage(dentry, true) : 0; 1269 path->dentry->d_op->d_manage(path, true) : 0;
1270} 1270}
1271 1271
1272/* 1272/*
@@ -1282,7 +1282,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
1282 * Don't forget we might have a non-mountpoint managed dentry 1282 * Don't forget we might have a non-mountpoint managed dentry
1283 * that wants to block transit. 1283 * that wants to block transit.
1284 */ 1284 */
1285 switch (managed_dentry_rcu(path->dentry)) { 1285 switch (managed_dentry_rcu(path)) {
1286 case -ECHILD: 1286 case -ECHILD:
1287 default: 1287 default:
1288 return false; 1288 return false;
@@ -1392,8 +1392,7 @@ int follow_down(struct path *path)
1392 if (managed & DCACHE_MANAGE_TRANSIT) { 1392 if (managed & DCACHE_MANAGE_TRANSIT) {
1393 BUG_ON(!path->dentry->d_op); 1393 BUG_ON(!path->dentry->d_op);
1394 BUG_ON(!path->dentry->d_op->d_manage); 1394 BUG_ON(!path->dentry->d_op->d_manage);
1395 ret = path->dentry->d_op->d_manage( 1395 ret = path->dentry->d_op->d_manage(path, false);
1396 path->dentry, false);
1397 if (ret < 0) 1396 if (ret < 0)
1398 return ret == -EISDIR ? 0 : ret; 1397 return ret == -EISDIR ? 0 : ret;
1399 } 1398 }
diff --git a/fs/namespace.c b/fs/namespace.c
index 9ad88a45b3e3..f7e28f8ea04d 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1159,6 +1159,35 @@ struct vfsmount *mntget(struct vfsmount *mnt)
1159} 1159}
1160EXPORT_SYMBOL(mntget); 1160EXPORT_SYMBOL(mntget);
1161 1161
1162/* path_is_mountpoint() - Check if path is a mount in the current
1163 * namespace.
1164 *
1165 * d_mountpoint() can only be used reliably to establish if a dentry is
1166 * not mounted in any namespace and that common case is handled inline.
1167 * d_mountpoint() isn't aware of the possibility there may be multiple
1168 * mounts using a given dentry in a different namespace. This function
1169 * checks if the passed in path is a mountpoint rather than the dentry
1170 * alone.
1171 */
1172bool path_is_mountpoint(const struct path *path)
1173{
1174 unsigned seq;
1175 bool res;
1176
1177 if (!d_mountpoint(path->dentry))
1178 return false;
1179
1180 rcu_read_lock();
1181 do {
1182 seq = read_seqbegin(&mount_lock);
1183 res = __path_is_mountpoint(path);
1184 } while (read_seqretry(&mount_lock, seq));
1185 rcu_read_unlock();
1186
1187 return res;
1188}
1189EXPORT_SYMBOL(path_is_mountpoint);
1190
1162struct vfsmount *mnt_clone_internal(const struct path *path) 1191struct vfsmount *mnt_clone_internal(const struct path *path)
1163{ 1192{
1164 struct mount *p; 1193 struct mount *p;
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 5beed7b30561..c965e4469499 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -139,7 +139,7 @@ struct dentry_operations {
139 void (*d_iput)(struct dentry *, struct inode *); 139 void (*d_iput)(struct dentry *, struct inode *);
140 char *(*d_dname)(struct dentry *, char *, int); 140 char *(*d_dname)(struct dentry *, char *, int);
141 struct vfsmount *(*d_automount)(struct path *); 141 struct vfsmount *(*d_automount)(struct path *);
142 int (*d_manage)(struct dentry *, bool); 142 int (*d_manage)(const struct path *, bool);
143 struct dentry *(*d_real)(struct dentry *, const struct inode *, 143 struct dentry *(*d_real)(struct dentry *, const struct inode *,
144 unsigned int); 144 unsigned int);
145} ____cacheline_aligned; 145} ____cacheline_aligned;
@@ -254,7 +254,7 @@ extern struct dentry *d_find_alias(struct inode *);
254extern void d_prune_aliases(struct inode *); 254extern void d_prune_aliases(struct inode *);
255 255
256/* test whether we have any submounts in a subdir tree */ 256/* test whether we have any submounts in a subdir tree */
257extern int have_submounts(struct dentry *); 257extern int path_has_submounts(const struct path *);
258 258
259/* 259/*
260 * This adds the entry to the hash queues. 260 * This adds the entry to the hash queues.
diff --git a/include/linux/mount.h b/include/linux/mount.h
index cf2b5784b649..c6f55158d5e5 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -98,4 +98,6 @@ extern dev_t name_to_dev_t(const char *name);
98 98
99extern unsigned int sysctl_mount_max; 99extern unsigned int sysctl_mount_max;
100 100
101extern bool path_is_mountpoint(const struct path *path);
102
101#endif /* _LINUX_MOUNT_H */ 103#endif /* _LINUX_MOUNT_H */