diff options
Diffstat (limited to 'fs/notify/inotify')
-rw-r--r-- | fs/notify/inotify/inotify.c | 88 |
1 files changed, 14 insertions, 74 deletions
diff --git a/fs/notify/inotify/inotify.c b/fs/notify/inotify/inotify.c index 40b1cf914ccb..27b75ebc7460 100644 --- a/fs/notify/inotify/inotify.c +++ b/fs/notify/inotify/inotify.c | |||
@@ -110,14 +110,10 @@ EXPORT_SYMBOL_GPL(get_inotify_watch); | |||
110 | int pin_inotify_watch(struct inotify_watch *watch) | 110 | int pin_inotify_watch(struct inotify_watch *watch) |
111 | { | 111 | { |
112 | struct super_block *sb = watch->inode->i_sb; | 112 | struct super_block *sb = watch->inode->i_sb; |
113 | spin_lock(&sb_lock); | 113 | if (atomic_inc_not_zero(&sb->s_active)) { |
114 | if (sb->s_count >= S_BIAS) { | ||
115 | atomic_inc(&sb->s_active); | ||
116 | spin_unlock(&sb_lock); | ||
117 | atomic_inc(&watch->count); | 114 | atomic_inc(&watch->count); |
118 | return 1; | 115 | return 1; |
119 | } | 116 | } |
120 | spin_unlock(&sb_lock); | ||
121 | return 0; | 117 | return 0; |
122 | } | 118 | } |
123 | 119 | ||
@@ -515,34 +511,8 @@ EXPORT_SYMBOL_GPL(inotify_init_watch); | |||
515 | * done. Cleanup is just deactivate_super(). However, that leaves a messy | 511 | * done. Cleanup is just deactivate_super(). However, that leaves a messy |
516 | * case - what if we *are* racing with umount() and active references to | 512 | * case - what if we *are* racing with umount() and active references to |
517 | * superblock can't be acquired anymore? We can bump ->s_count, grab | 513 | * superblock can't be acquired anymore? We can bump ->s_count, grab |
518 | * ->s_umount, which will almost certainly wait until the superblock is shut | 514 | * ->s_umount, which will wait until the superblock is shut down and the |
519 | * down and the watch in question is pining for fjords. That's fine, but | 515 | * watch in question is pining for fjords. |
520 | * there is a problem - we might have hit the window between ->s_active | ||
521 | * getting to 0 / ->s_count - below S_BIAS (i.e. the moment when superblock | ||
522 | * is past the point of no return and is heading for shutdown) and the | ||
523 | * moment when deactivate_super() acquires ->s_umount. We could just do | ||
524 | * drop_super() yield() and retry, but that's rather antisocial and this | ||
525 | * stuff is luser-triggerable. OTOH, having grabbed ->s_umount and having | ||
526 | * found that we'd got there first (i.e. that ->s_root is non-NULL) we know | ||
527 | * that we won't race with inotify_umount_inodes(). So we could grab a | ||
528 | * reference to watch and do the rest as above, just with drop_super() instead | ||
529 | * of deactivate_super(), right? Wrong. We had to drop ih->mutex before we | ||
530 | * could grab ->s_umount. So the watch could've been gone already. | ||
531 | * | ||
532 | * That still can be dealt with - we need to save watch->wd, do idr_find() | ||
533 | * and compare its result with our pointer. If they match, we either have | ||
534 | * the damn thing still alive or we'd lost not one but two races at once, | ||
535 | * the watch had been killed and a new one got created with the same ->wd | ||
536 | * at the same address. That couldn't have happened in inotify_destroy(), | ||
537 | * but inotify_rm_wd() could run into that. Still, "new one got created" | ||
538 | * is not a problem - we have every right to kill it or leave it alone, | ||
539 | * whatever's more convenient. | ||
540 | * | ||
541 | * So we can use idr_find(...) == watch && watch->inode->i_sb == sb as | ||
542 | * "grab it and kill it" check. If it's been our original watch, we are | ||
543 | * fine, if it's a newcomer - nevermind, just pretend that we'd won the | ||
544 | * race and kill the fscker anyway; we are safe since we know that its | ||
545 | * superblock won't be going away. | ||
546 | * | 516 | * |
547 | * And yes, this is far beyond mere "not very pretty"; so's the entire | 517 | * And yes, this is far beyond mere "not very pretty"; so's the entire |
548 | * concept of inotify to start with. | 518 | * concept of inotify to start with. |
@@ -556,57 +526,31 @@ EXPORT_SYMBOL_GPL(inotify_init_watch); | |||
556 | * Called with ih->mutex held, drops it. Possible return values: | 526 | * Called with ih->mutex held, drops it. Possible return values: |
557 | * 0 - nothing to do, it has died | 527 | * 0 - nothing to do, it has died |
558 | * 1 - remove it, drop the reference and deactivate_super() | 528 | * 1 - remove it, drop the reference and deactivate_super() |
559 | * 2 - remove it, drop the reference and drop_super(); we tried hard to avoid | ||
560 | * that variant, since it involved a lot of PITA, but that's the best that | ||
561 | * could've been done. | ||
562 | */ | 529 | */ |
563 | static int pin_to_kill(struct inotify_handle *ih, struct inotify_watch *watch) | 530 | static int pin_to_kill(struct inotify_handle *ih, struct inotify_watch *watch) |
564 | { | 531 | { |
565 | struct super_block *sb = watch->inode->i_sb; | 532 | struct super_block *sb = watch->inode->i_sb; |
566 | s32 wd = watch->wd; | ||
567 | 533 | ||
568 | spin_lock(&sb_lock); | 534 | if (atomic_inc_not_zero(&sb->s_active)) { |
569 | if (sb->s_count >= S_BIAS) { | ||
570 | atomic_inc(&sb->s_active); | ||
571 | spin_unlock(&sb_lock); | ||
572 | get_inotify_watch(watch); | 535 | get_inotify_watch(watch); |
573 | mutex_unlock(&ih->mutex); | 536 | mutex_unlock(&ih->mutex); |
574 | return 1; /* the best outcome */ | 537 | return 1; /* the best outcome */ |
575 | } | 538 | } |
539 | spin_lock(&sb_lock); | ||
576 | sb->s_count++; | 540 | sb->s_count++; |
577 | spin_unlock(&sb_lock); | 541 | spin_unlock(&sb_lock); |
578 | mutex_unlock(&ih->mutex); /* can't grab ->s_umount under it */ | 542 | mutex_unlock(&ih->mutex); /* can't grab ->s_umount under it */ |
579 | down_read(&sb->s_umount); | 543 | down_read(&sb->s_umount); |
580 | if (likely(!sb->s_root)) { | 544 | /* fs is already shut down; the watch is dead */ |
581 | /* fs is already shut down; the watch is dead */ | 545 | drop_super(sb); |
582 | drop_super(sb); | 546 | return 0; |
583 | return 0; | ||
584 | } | ||
585 | /* raced with the final deactivate_super() */ | ||
586 | mutex_lock(&ih->mutex); | ||
587 | if (idr_find(&ih->idr, wd) != watch || watch->inode->i_sb != sb) { | ||
588 | /* the watch is dead */ | ||
589 | mutex_unlock(&ih->mutex); | ||
590 | drop_super(sb); | ||
591 | return 0; | ||
592 | } | ||
593 | /* still alive or freed and reused with the same sb and wd; kill */ | ||
594 | get_inotify_watch(watch); | ||
595 | mutex_unlock(&ih->mutex); | ||
596 | return 2; | ||
597 | } | 547 | } |
598 | 548 | ||
599 | static void unpin_and_kill(struct inotify_watch *watch, int how) | 549 | static void unpin_and_kill(struct inotify_watch *watch) |
600 | { | 550 | { |
601 | struct super_block *sb = watch->inode->i_sb; | 551 | struct super_block *sb = watch->inode->i_sb; |
602 | put_inotify_watch(watch); | 552 | put_inotify_watch(watch); |
603 | switch (how) { | 553 | deactivate_super(sb); |
604 | case 1: | ||
605 | deactivate_super(sb); | ||
606 | break; | ||
607 | case 2: | ||
608 | drop_super(sb); | ||
609 | } | ||
610 | } | 554 | } |
611 | 555 | ||
612 | /** | 556 | /** |
@@ -628,7 +572,6 @@ void inotify_destroy(struct inotify_handle *ih) | |||
628 | struct list_head *watches; | 572 | struct list_head *watches; |
629 | struct super_block *sb; | 573 | struct super_block *sb; |
630 | struct inode *inode; | 574 | struct inode *inode; |
631 | int how; | ||
632 | 575 | ||
633 | mutex_lock(&ih->mutex); | 576 | mutex_lock(&ih->mutex); |
634 | watches = &ih->watches; | 577 | watches = &ih->watches; |
@@ -638,8 +581,7 @@ void inotify_destroy(struct inotify_handle *ih) | |||
638 | } | 581 | } |
639 | watch = list_first_entry(watches, struct inotify_watch, h_list); | 582 | watch = list_first_entry(watches, struct inotify_watch, h_list); |
640 | sb = watch->inode->i_sb; | 583 | sb = watch->inode->i_sb; |
641 | how = pin_to_kill(ih, watch); | 584 | if (!pin_to_kill(ih, watch)) |
642 | if (!how) | ||
643 | continue; | 585 | continue; |
644 | 586 | ||
645 | inode = watch->inode; | 587 | inode = watch->inode; |
@@ -654,7 +596,7 @@ void inotify_destroy(struct inotify_handle *ih) | |||
654 | 596 | ||
655 | mutex_unlock(&ih->mutex); | 597 | mutex_unlock(&ih->mutex); |
656 | mutex_unlock(&inode->inotify_mutex); | 598 | mutex_unlock(&inode->inotify_mutex); |
657 | unpin_and_kill(watch, how); | 599 | unpin_and_kill(watch); |
658 | } | 600 | } |
659 | 601 | ||
660 | /* free this handle: the put matching the get in inotify_init() */ | 602 | /* free this handle: the put matching the get in inotify_init() */ |
@@ -857,7 +799,6 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd) | |||
857 | struct inotify_watch *watch; | 799 | struct inotify_watch *watch; |
858 | struct super_block *sb; | 800 | struct super_block *sb; |
859 | struct inode *inode; | 801 | struct inode *inode; |
860 | int how; | ||
861 | 802 | ||
862 | mutex_lock(&ih->mutex); | 803 | mutex_lock(&ih->mutex); |
863 | watch = idr_find(&ih->idr, wd); | 804 | watch = idr_find(&ih->idr, wd); |
@@ -866,8 +807,7 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd) | |||
866 | return -EINVAL; | 807 | return -EINVAL; |
867 | } | 808 | } |
868 | sb = watch->inode->i_sb; | 809 | sb = watch->inode->i_sb; |
869 | how = pin_to_kill(ih, watch); | 810 | if (!pin_to_kill(ih, watch)) |
870 | if (!how) | ||
871 | return 0; | 811 | return 0; |
872 | 812 | ||
873 | inode = watch->inode; | 813 | inode = watch->inode; |
@@ -881,7 +821,7 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd) | |||
881 | 821 | ||
882 | mutex_unlock(&ih->mutex); | 822 | mutex_unlock(&ih->mutex); |
883 | mutex_unlock(&inode->inotify_mutex); | 823 | mutex_unlock(&inode->inotify_mutex); |
884 | unpin_and_kill(watch, how); | 824 | unpin_and_kill(watch); |
885 | 825 | ||
886 | return 0; | 826 | return 0; |
887 | } | 827 | } |