From b680716ed28baf549f777fb125fc23ba975985c5 Mon Sep 17 00:00:00 2001 From: Robert Love Date: Mon, 25 Jul 2005 15:07:13 -0400 Subject: [PATCH] inotify: misc. cleanup Miscellaneous invariant clean up, comment fixes, and so on. Trivial stuff. Signed-off-by: Robert Love Signed-off-by: John McCutchan Signed-off-by: Linus Torvalds --- fs/inotify.c | 66 +++++++++++++++++++++++++++++------------------------------- 1 file changed, 32 insertions(+), 34 deletions(-) (limited to 'fs') diff --git a/fs/inotify.c b/fs/inotify.c index 54757be..a879265 100644 --- a/fs/inotify.c +++ b/fs/inotify.c @@ -62,8 +62,8 @@ int inotify_max_queued_events; * Lifetimes of the three main data structures--inotify_device, inode, and * inotify_watch--are managed by reference count. * - * inotify_device: Lifetime is from open until release. Additional references - * can bump the count via get_inotify_dev() and drop the count via + * inotify_device: Lifetime is from inotify_init() until release. Additional + * references can bump the count via get_inotify_dev() and drop the count via * put_inotify_dev(). * * inotify_watch: Lifetime is from create_watch() to destory_watch(). @@ -75,7 +75,7 @@ int inotify_max_queued_events; */ /* - * struct inotify_device - represents an open instance of an inotify device + * struct inotify_device - represents an inotify instance * * This structure is protected by the semaphore 'sem'. */ @@ -371,7 +371,7 @@ static int find_inode(const char __user *dirname, struct nameidata *nd) /* you can only watch an inode if you have read permissions on it */ error = permission(nd->dentry->d_inode, MAY_READ, NULL); if (error) - path_release (nd); + path_release(nd); return error; } @@ -387,7 +387,8 @@ static struct inotify_watch *create_watch(struct inotify_device *dev, struct inotify_watch *watch; int ret; - if (atomic_read(&dev->user->inotify_watches) >= inotify_max_user_watches) + if (atomic_read(&dev->user->inotify_watches) >= + inotify_max_user_watches) return ERR_PTR(-ENOSPC); watch = kmem_cache_alloc(watch_cachep, GFP_KERNEL); @@ -783,15 +784,14 @@ static int inotify_release(struct inode *ignored, struct file *file) inotify_dev_event_dequeue(dev); up(&dev->sem); - /* free this device: the put matching the get in inotify_open() */ + /* free this device: the put matching the get in inotify_init() */ put_inotify_dev(dev); return 0; } /* - * inotify_ignore - handle the INOTIFY_IGNORE ioctl, asking that a given wd be - * removed from the device. + * inotify_ignore - remove a given wd from this inotify instance. * * Can sleep. */ @@ -856,15 +856,12 @@ asmlinkage long sys_inotify_init(void) { struct inotify_device *dev; struct user_struct *user; - int ret = -ENOTTY; - int fd; - struct file *filp; + struct file *filp; + int fd, ret; fd = get_unused_fd(); - if (fd < 0) { - ret = fd; - goto out; - } + if (fd < 0) + return fd; filp = get_empty_filp(); if (!filp) { @@ -872,16 +869,11 @@ asmlinkage long sys_inotify_init(void) ret = -ENFILE; goto out; } - filp->f_op = &inotify_fops; - filp->f_vfsmnt = mntget(inotify_mnt); - filp->f_dentry = dget(inotify_mnt->mnt_root); - filp->f_mapping = filp->f_dentry->d_inode->i_mapping; - filp->f_mode = FMODE_READ; - filp->f_flags = O_RDONLY; user = get_uid(current->user); - if (unlikely(atomic_read(&user->inotify_devs) >= inotify_max_user_instances)) { + if (unlikely(atomic_read(&user->inotify_devs) >= + inotify_max_user_instances)) { ret = -EMFILE; goto out_err; } @@ -892,6 +884,14 @@ asmlinkage long sys_inotify_init(void) goto out_err; } + filp->f_op = &inotify_fops; + filp->f_vfsmnt = mntget(inotify_mnt); + filp->f_dentry = dget(inotify_mnt->mnt_root); + filp->f_mapping = filp->f_dentry->d_inode->i_mapping; + filp->f_mode = FMODE_READ; + filp->f_flags = O_RDONLY; + filp->private_data = dev; + idr_init(&dev->idr); INIT_LIST_HEAD(&dev->events); INIT_LIST_HEAD(&dev->watches); @@ -905,9 +905,8 @@ asmlinkage long sys_inotify_init(void) get_inotify_dev(dev); atomic_inc(&user->inotify_devs); + fd_install(fd, filp); - filp->private_data = dev; - fd_install (fd, filp); return fd; out_err: put_unused_fd (fd); @@ -917,7 +916,7 @@ out: return ret; } -asmlinkage long sys_inotify_add_watch(int fd, const char *path, u32 mask) +asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask) { struct inotify_watch *watch, *old; struct inode *inode; @@ -930,21 +929,20 @@ asmlinkage long sys_inotify_add_watch(int fd, const char *path, u32 mask) if (!filp) return -EBADF; - dev = filp->private_data; - - ret = find_inode((const char __user*) path, &nd); - if (ret) + ret = find_inode(path, &nd); + if (unlikely(ret)) goto fput_and_out; - /* Held in place by reference in nd */ + /* inode held in place by reference to nd; dev by fget on fd */ inode = nd.dentry->d_inode; + dev = filp->private_data; down(&inode->inotify_sem); down(&dev->sem); /* don't let user-space set invalid bits: we don't want flags set */ mask &= IN_ALL_EVENTS; - if (!mask) { + if (unlikely(!mask)) { ret = -EINVAL; goto out; } @@ -1009,11 +1007,11 @@ static struct file_system_type inotify_fs_type = { }; /* - * inotify_init - Our initialization function. Note that we cannnot return + * inotify_setup - Our initialization function. Note that we cannnot return * error because we have compiled-in VFS hooks. So an (unlikely) failure here * must result in panic(). */ -static int __init inotify_init(void) +static int __init inotify_setup(void) { register_filesystem(&inotify_fs_type); inotify_mnt = kern_mount(&inotify_fs_type); @@ -1034,4 +1032,4 @@ static int __init inotify_init(void) return 0; } -module_init(inotify_init); +module_init(inotify_setup); -- cgit v1.1 From 33ea2f52b8758ef62ae4a9d2f91821c47d999ee9 Mon Sep 17 00:00:00 2001 From: Robert Love Date: Mon, 25 Jul 2005 15:08:37 -0400 Subject: [PATCH] inotify: use fget_light As an optimization, use fget_light() and fput_light() where possible. Signed-off-by: Robert Love Signed-off-by: John McCutchan Signed-off-by: Linus Torvalds --- fs/inotify.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'fs') diff --git a/fs/inotify.c b/fs/inotify.c index a879265..807209f 100644 --- a/fs/inotify.c +++ b/fs/inotify.c @@ -923,10 +923,10 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask) struct inotify_device *dev; struct nameidata nd; struct file *filp; - int ret; + int ret, fput_needed; - filp = fget(fd); - if (!filp) + filp = fget_light(fd, &fput_needed); + if (unlikely(!filp)) return -EBADF; ret = find_inode(path, &nd); @@ -973,7 +973,7 @@ out: up(&dev->sem); up(&inode->inotify_sem); fput_and_out: - fput(filp); + fput_light(filp, fput_needed); return ret; } @@ -981,14 +981,14 @@ asmlinkage long sys_inotify_rm_watch(int fd, u32 wd) { struct file *filp; struct inotify_device *dev; - int ret; + int ret, fput_needed; - filp = fget(fd); - if (!filp) + filp = fget_light(fd, &fput_needed); + if (unlikely(!filp)) return -EBADF; dev = filp->private_data; ret = inotify_ignore(dev, wd); - fput(filp); + fput_light(filp, fput_needed); return ret; } -- cgit v1.1 From 783bc29bbc5d6625a4669d3eb1d989a8fb275d43 Mon Sep 17 00:00:00 2001 From: Robert Love Date: Mon, 25 Jul 2005 15:10:08 -0400 Subject: [PATCH] inotify: oops fix Bug fix: Ensure that the fd passed to inotify_add_watch() and inotify_rm_watch() belongs to inotify. Signed-off-by: Robert Love Signed-off-by: John McCutchan Signed-off-by: Linus Torvalds --- fs/inotify.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/inotify.c b/fs/inotify.c index 807209f..b55d6e4 100644 --- a/fs/inotify.c +++ b/fs/inotify.c @@ -929,6 +929,12 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask) if (unlikely(!filp)) return -EBADF; + /* verify that this is indeed an inotify instance */ + if (unlikely(filp->f_op != &inotify_fops)) { + ret = -EINVAL; + goto fput_and_out; + } + ret = find_inode(path, &nd); if (unlikely(ret)) goto fput_and_out; @@ -986,10 +992,18 @@ asmlinkage long sys_inotify_rm_watch(int fd, u32 wd) filp = fget_light(fd, &fput_needed); if (unlikely(!filp)) return -EBADF; + + /* verify that this is indeed an inotify instance */ + if (unlikely(filp->f_op != &inotify_fops)) { + ret = -EINVAL; + goto out; + } + dev = filp->private_data; ret = inotify_ignore(dev, wd); - fput_light(filp, fput_needed); +out: + fput_light(filp, fput_needed); return ret; } -- cgit v1.1 From 5eb22cbcdb849886c2584389faff5afb56c23876 Mon Sep 17 00:00:00 2001 From: Robert Love Date: Mon, 25 Jul 2005 15:12:19 -0400 Subject: [PATCH] inotify: exit path cleanups Handle error out paths better. Signed-off-by: Robert Love Signed-off-by: John McCutchan Signed-off-by: Linus Torvalds --- fs/inotify.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'fs') diff --git a/fs/inotify.c b/fs/inotify.c index b55d6e4..d41c53c 100644 --- a/fs/inotify.c +++ b/fs/inotify.c @@ -865,23 +865,21 @@ asmlinkage long sys_inotify_init(void) filp = get_empty_filp(); if (!filp) { - put_unused_fd(fd); ret = -ENFILE; - goto out; + goto out_put_fd; } user = get_uid(current->user); - if (unlikely(atomic_read(&user->inotify_devs) >= inotify_max_user_instances)) { ret = -EMFILE; - goto out_err; + goto out_free_uid; } dev = kmalloc(sizeof(struct inotify_device), GFP_KERNEL); if (unlikely(!dev)) { ret = -ENOMEM; - goto out_err; + goto out_free_uid; } filp->f_op = &inotify_fops; @@ -908,11 +906,11 @@ asmlinkage long sys_inotify_init(void) fd_install(fd, filp); return fd; -out_err: - put_unused_fd (fd); - put_filp (filp); +out_free_uid: free_uid(user); -out: + put_filp(filp); +out_put_fd: + put_unused_fd(fd); return ret; } @@ -975,9 +973,9 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask) list_add(&watch->i_list, &inode->inotify_watches); ret = watch->wd; out: - path_release (&nd); up(&dev->sem); up(&inode->inotify_sem); + path_release(&nd); fput_and_out: fput_light(filp, fput_needed); return ret; -- cgit v1.1 From 1b2ccf0cc15af717263c7cfe5d0aaf5ac057489e Mon Sep 17 00:00:00 2001 From: Robert Love Date: Mon, 25 Jul 2005 15:13:43 -0400 Subject: [PATCH] inotify: change default limits Change default inotify limits: Maximum instances per user to 128 and maximum events per queue to 16k. The max instances used to be 128; the change to 8 was a mistake. Memory consumption is fine. Signed-off-by: Robert Love Signed-off-by: John McCutchan Signed-off-by: Linus Torvalds --- fs/inotify.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/inotify.c b/fs/inotify.c index d41c53c..6a0ba2c 100644 --- a/fs/inotify.c +++ b/fs/inotify.c @@ -1028,8 +1028,8 @@ static int __init inotify_setup(void) register_filesystem(&inotify_fs_type); inotify_mnt = kern_mount(&inotify_fs_type); - inotify_max_queued_events = 8192; - inotify_max_user_instances = 8; + inotify_max_queued_events = 16384; + inotify_max_user_instances = 128; inotify_max_user_watches = 8192; atomic_set(&inotify_cookie, 0); -- cgit v1.1 From e5ca844a9d795e97c08bc7901c62a48c28469eb0 Mon Sep 17 00:00:00 2001 From: Robert Love Date: Mon, 25 Jul 2005 15:17:34 -0400 Subject: [PATCH] inotify: check retval in init Check for (unlikely) errors in the filesystem initialization stuff in our module_init() function. Signed-off-by: Robert Love Signed-off-by: John McCutchan Signed-off-by: Linus Torvalds --- fs/inotify.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/inotify.c b/fs/inotify.c index 6a0ba2c..cdfff90 100644 --- a/fs/inotify.c +++ b/fs/inotify.c @@ -1025,8 +1025,15 @@ static struct file_system_type inotify_fs_type = { */ static int __init inotify_setup(void) { - register_filesystem(&inotify_fs_type); + int ret; + + ret = register_filesystem(&inotify_fs_type); + if (unlikely(ret)) + panic("inotify: register_filesystem returned %d!\n", ret); + inotify_mnt = kern_mount(&inotify_fs_type); + if (unlikely(PTR_ERR(inotify_mnt))) + panic("inotify: kern_mount ret %ld!\n", PTR_ERR(inotify_mnt)); inotify_max_queued_events = 16384; inotify_max_user_instances = 128; -- cgit v1.1 From 89373de7dd010832d8b68cb37dabb33ff5a688bb Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 26 Jul 2005 14:08:38 -0700 Subject: [PATCH] inotify: fix oops fix Cc: Robert Love Cc: John McCutchan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/inotify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/inotify.c b/fs/inotify.c index cdfff90..a8a714e 100644 --- a/fs/inotify.c +++ b/fs/inotify.c @@ -1032,7 +1032,7 @@ static int __init inotify_setup(void) panic("inotify: register_filesystem returned %d!\n", ret); inotify_mnt = kern_mount(&inotify_fs_type); - if (unlikely(PTR_ERR(inotify_mnt))) + if (IS_ERR(inotify_mnt)) panic("inotify: kern_mount ret %ld!\n", PTR_ERR(inotify_mnt)); inotify_max_queued_events = 16384; -- cgit v1.1