aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify/inotify/inotify_user.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/notify/inotify/inotify_user.c')
-rw-r--r--fs/notify/inotify/inotify_user.c51
1 files changed, 20 insertions, 31 deletions
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index dcd2040d330..a94e8bd8eb1 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -69,36 +69,30 @@ static int zero;
69 69
70ctl_table inotify_table[] = { 70ctl_table inotify_table[] = {
71 { 71 {
72 .ctl_name = INOTIFY_MAX_USER_INSTANCES,
73 .procname = "max_user_instances", 72 .procname = "max_user_instances",
74 .data = &inotify_max_user_instances, 73 .data = &inotify_max_user_instances,
75 .maxlen = sizeof(int), 74 .maxlen = sizeof(int),
76 .mode = 0644, 75 .mode = 0644,
77 .proc_handler = &proc_dointvec_minmax, 76 .proc_handler = proc_dointvec_minmax,
78 .strategy = &sysctl_intvec,
79 .extra1 = &zero, 77 .extra1 = &zero,
80 }, 78 },
81 { 79 {
82 .ctl_name = INOTIFY_MAX_USER_WATCHES,
83 .procname = "max_user_watches", 80 .procname = "max_user_watches",
84 .data = &inotify_max_user_watches, 81 .data = &inotify_max_user_watches,
85 .maxlen = sizeof(int), 82 .maxlen = sizeof(int),
86 .mode = 0644, 83 .mode = 0644,
87 .proc_handler = &proc_dointvec_minmax, 84 .proc_handler = proc_dointvec_minmax,
88 .strategy = &sysctl_intvec,
89 .extra1 = &zero, 85 .extra1 = &zero,
90 }, 86 },
91 { 87 {
92 .ctl_name = INOTIFY_MAX_QUEUED_EVENTS,
93 .procname = "max_queued_events", 88 .procname = "max_queued_events",
94 .data = &inotify_max_queued_events, 89 .data = &inotify_max_queued_events,
95 .maxlen = sizeof(int), 90 .maxlen = sizeof(int),
96 .mode = 0644, 91 .mode = 0644,
97 .proc_handler = &proc_dointvec_minmax, 92 .proc_handler = proc_dointvec_minmax,
98 .strategy = &sysctl_intvec,
99 .extra1 = &zero 93 .extra1 = &zero
100 }, 94 },
101 { .ctl_name = 0 } 95 { }
102}; 96};
103#endif /* CONFIG_SYSCTL */ 97#endif /* CONFIG_SYSCTL */
104 98
@@ -558,7 +552,7 @@ retry:
558 552
559 spin_lock(&group->inotify_data.idr_lock); 553 spin_lock(&group->inotify_data.idr_lock);
560 ret = idr_get_new_above(&group->inotify_data.idr, &tmp_ientry->fsn_entry, 554 ret = idr_get_new_above(&group->inotify_data.idr, &tmp_ientry->fsn_entry,
561 group->inotify_data.last_wd, 555 group->inotify_data.last_wd+1,
562 &tmp_ientry->wd); 556 &tmp_ientry->wd);
563 spin_unlock(&group->inotify_data.idr_lock); 557 spin_unlock(&group->inotify_data.idr_lock);
564 if (ret) { 558 if (ret) {
@@ -638,7 +632,7 @@ static struct fsnotify_group *inotify_new_group(struct user_struct *user, unsign
638 632
639 spin_lock_init(&group->inotify_data.idr_lock); 633 spin_lock_init(&group->inotify_data.idr_lock);
640 idr_init(&group->inotify_data.idr); 634 idr_init(&group->inotify_data.idr);
641 group->inotify_data.last_wd = 1; 635 group->inotify_data.last_wd = 0;
642 group->inotify_data.user = user; 636 group->inotify_data.user = user;
643 group->inotify_data.fa = NULL; 637 group->inotify_data.fa = NULL;
644 638
@@ -652,6 +646,7 @@ SYSCALL_DEFINE1(inotify_init1, int, flags)
652 struct fsnotify_group *group; 646 struct fsnotify_group *group;
653 struct user_struct *user; 647 struct user_struct *user;
654 struct file *filp; 648 struct file *filp;
649 struct path path;
655 int fd, ret; 650 int fd, ret;
656 651
657 /* Check the IN_* constants for consistency. */ 652 /* Check the IN_* constants for consistency. */
@@ -665,12 +660,6 @@ SYSCALL_DEFINE1(inotify_init1, int, flags)
665 if (fd < 0) 660 if (fd < 0)
666 return fd; 661 return fd;
667 662
668 filp = get_empty_filp();
669 if (!filp) {
670 ret = -ENFILE;
671 goto out_put_fd;
672 }
673
674 user = get_current_user(); 663 user = get_current_user();
675 if (unlikely(atomic_read(&user->inotify_devs) >= 664 if (unlikely(atomic_read(&user->inotify_devs) >=
676 inotify_max_user_instances)) { 665 inotify_max_user_instances)) {
@@ -685,24 +674,28 @@ SYSCALL_DEFINE1(inotify_init1, int, flags)
685 goto out_free_uid; 674 goto out_free_uid;
686 } 675 }
687 676
688 filp->f_op = &inotify_fops; 677 atomic_inc(&user->inotify_devs);
689 filp->f_path.mnt = mntget(inotify_mnt); 678
690 filp->f_path.dentry = dget(inotify_mnt->mnt_root); 679 path.mnt = inotify_mnt;
691 filp->f_mapping = filp->f_path.dentry->d_inode->i_mapping; 680 path.dentry = inotify_mnt->mnt_root;
692 filp->f_mode = FMODE_READ; 681 path_get(&path);
682 filp = alloc_file(&path, FMODE_READ, &inotify_fops);
683 if (!filp)
684 goto Enfile;
685
693 filp->f_flags = O_RDONLY | (flags & O_NONBLOCK); 686 filp->f_flags = O_RDONLY | (flags & O_NONBLOCK);
694 filp->private_data = group; 687 filp->private_data = group;
695 688
696 atomic_inc(&user->inotify_devs);
697
698 fd_install(fd, filp); 689 fd_install(fd, filp);
699 690
700 return fd; 691 return fd;
701 692
693Enfile:
694 ret = -ENFILE;
695 path_put(&path);
696 atomic_dec(&user->inotify_devs);
702out_free_uid: 697out_free_uid:
703 free_uid(user); 698 free_uid(user);
704 put_filp(filp);
705out_put_fd:
706 put_unused_fd(fd); 699 put_unused_fd(fd);
707 return ret; 700 return ret;
708} 701}
@@ -747,10 +740,6 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
747 740
748 /* create/update an inode mark */ 741 /* create/update an inode mark */
749 ret = inotify_update_watch(group, inode, mask); 742 ret = inotify_update_watch(group, inode, mask);
750 if (unlikely(ret))
751 goto path_put_and_out;
752
753path_put_and_out:
754 path_put(&path); 743 path_put(&path);
755fput_and_out: 744fput_and_out:
756 fput_light(filp, fput_needed); 745 fput_light(filp, fput_needed);