Loading fs/inotify.c +32 −34 Original line number Diff line number Diff line Loading @@ -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(). Loading @@ -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'. */ Loading Loading @@ -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); Loading Loading @@ -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. */ Loading Loading @@ -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; 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) { Loading @@ -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; } Loading @@ -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); Loading @@ -905,9 +905,8 @@ asmlinkage long sys_inotify_init(void) get_inotify_dev(dev); atomic_inc(&user->inotify_devs); filp->private_data = dev; fd_install(fd, filp); return fd; out_err: put_unused_fd (fd); Loading @@ -917,7 +916,7 @@ asmlinkage long sys_inotify_init(void) 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; Loading @@ -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; } Loading Loading @@ -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); Loading @@ -1034,4 +1032,4 @@ static int __init inotify_init(void) return 0; } module_init(inotify_init); module_init(inotify_setup); Loading
fs/inotify.c +32 −34 Original line number Diff line number Diff line Loading @@ -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(). Loading @@ -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'. */ Loading Loading @@ -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); Loading Loading @@ -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. */ Loading Loading @@ -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; 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) { Loading @@ -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; } Loading @@ -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); Loading @@ -905,9 +905,8 @@ asmlinkage long sys_inotify_init(void) get_inotify_dev(dev); atomic_inc(&user->inotify_devs); filp->private_data = dev; fd_install(fd, filp); return fd; out_err: put_unused_fd (fd); Loading @@ -917,7 +916,7 @@ asmlinkage long sys_inotify_init(void) 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; Loading @@ -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; } Loading Loading @@ -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); Loading @@ -1034,4 +1032,4 @@ static int __init inotify_init(void) return 0; } module_init(inotify_init); module_init(inotify_setup);