User: | Jiri Slaby |
Error type: | Double Lock |
Error type description: | Some lock is locked twice unintentionally in a sequence |
File location: | fs/inotify.c |
Line in file: | 646 |
Project: | Linux Kernel |
Project version: | 2.6.28 |
Tools: |
Clang Static Analyzer
(3.0)
Smatch (1.59) |
Entered: | 2012-04-17 12:29:30 UTC |
616{ 617 /* 618 * Destroy all of the watches for this handle. Unfortunately, not very 619 * pretty. We cannot do a simple iteration over the list, because we 620 * do not know the inode until we iterate to the watch. But we need to 621 * hold inode->inotify_mutex before ih->mutex. The following works. 622 * 623 * AV: it had to become even uglier to start working ;-/ 624 */ 625 while (1) { 626 struct inotify_watch *watch; 627 struct list_head *watches; 628 struct super_block *sb; 629 struct inode *inode; 630 int how; 631 632 mutex_lock(&ih->mutex); 633 watches = &ih->watches; 634 if (list_empty(watches)) { 635 mutex_unlock(&ih->mutex); 636 break; 637 } 638 watch = list_first_entry(watches, struct inotify_watch, h_list); 639 sb = watch->inode->i_sb; 640 how = pin_to_kill(ih, watch); 641 if (!how) 642 continue; 643 644 inode = watch->inode; 645 mutex_lock(&inode->inotify_mutex); 646 mutex_lock(&ih->mutex); 647 648 /* make sure we didn't race with another list removal */ 649 if (likely(idr_find(&ih->idr, watch->wd))) { 650 remove_watch_no_event(watch, ih); 651 put_inotify_watch(watch); 652 } 653 654 mutex_unlock(&ih->mutex); 655 mutex_unlock(&inode->inotify_mutex); 656 unpin_and_kill(watch, how);