Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Directory notifications for Linux.
0004  *
0005  * Copyright (C) 2000,2001,2002 Stephen Rothwell
0006  *
0007  * Copyright (C) 2009 Eric Paris <Red Hat Inc>
0008  * dnotify was largly rewritten to use the new fsnotify infrastructure
0009  */
0010 #include <linux/fs.h>
0011 #include <linux/module.h>
0012 #include <linux/sched.h>
0013 #include <linux/sched/signal.h>
0014 #include <linux/dnotify.h>
0015 #include <linux/init.h>
0016 #include <linux/security.h>
0017 #include <linux/spinlock.h>
0018 #include <linux/slab.h>
0019 #include <linux/fdtable.h>
0020 #include <linux/fsnotify_backend.h>
0021 
0022 static int dir_notify_enable __read_mostly = 1;
0023 #ifdef CONFIG_SYSCTL
0024 static struct ctl_table dnotify_sysctls[] = {
0025     {
0026         .procname   = "dir-notify-enable",
0027         .data       = &dir_notify_enable,
0028         .maxlen     = sizeof(int),
0029         .mode       = 0644,
0030         .proc_handler   = proc_dointvec,
0031     },
0032     {}
0033 };
0034 static void __init dnotify_sysctl_init(void)
0035 {
0036     register_sysctl_init("fs", dnotify_sysctls);
0037 }
0038 #else
0039 #define dnotify_sysctl_init() do { } while (0)
0040 #endif
0041 
0042 static struct kmem_cache *dnotify_struct_cache __read_mostly;
0043 static struct kmem_cache *dnotify_mark_cache __read_mostly;
0044 static struct fsnotify_group *dnotify_group __read_mostly;
0045 
0046 /*
0047  * dnotify will attach one of these to each inode (i_fsnotify_marks) which
0048  * is being watched by dnotify.  If multiple userspace applications are watching
0049  * the same directory with dnotify their information is chained in dn
0050  */
0051 struct dnotify_mark {
0052     struct fsnotify_mark fsn_mark;
0053     struct dnotify_struct *dn;
0054 };
0055 
0056 /*
0057  * When a process starts or stops watching an inode the set of events which
0058  * dnotify cares about for that inode may change.  This function runs the
0059  * list of everything receiving dnotify events about this directory and calculates
0060  * the set of all those events.  After it updates what dnotify is interested in
0061  * it calls the fsnotify function so it can update the set of all events relevant
0062  * to this inode.
0063  */
0064 static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark)
0065 {
0066     __u32 new_mask = 0;
0067     struct dnotify_struct *dn;
0068     struct dnotify_mark *dn_mark  = container_of(fsn_mark,
0069                              struct dnotify_mark,
0070                              fsn_mark);
0071 
0072     assert_spin_locked(&fsn_mark->lock);
0073 
0074     for (dn = dn_mark->dn; dn != NULL; dn = dn->dn_next)
0075         new_mask |= (dn->dn_mask & ~FS_DN_MULTISHOT);
0076     if (fsn_mark->mask == new_mask)
0077         return;
0078     fsn_mark->mask = new_mask;
0079 
0080     fsnotify_recalc_mask(fsn_mark->connector);
0081 }
0082 
0083 /*
0084  * Mains fsnotify call where events are delivered to dnotify.
0085  * Find the dnotify mark on the relevant inode, run the list of dnotify structs
0086  * on that mark and determine which of them has expressed interest in receiving
0087  * events of this type.  When found send the correct process and signal and
0088  * destroy the dnotify struct if it was not registered to receive multiple
0089  * events.
0090  */
0091 static int dnotify_handle_event(struct fsnotify_mark *inode_mark, u32 mask,
0092                 struct inode *inode, struct inode *dir,
0093                 const struct qstr *name, u32 cookie)
0094 {
0095     struct dnotify_mark *dn_mark;
0096     struct dnotify_struct *dn;
0097     struct dnotify_struct **prev;
0098     struct fown_struct *fown;
0099     __u32 test_mask = mask & ~FS_EVENT_ON_CHILD;
0100 
0101     /* not a dir, dnotify doesn't care */
0102     if (!dir && !(mask & FS_ISDIR))
0103         return 0;
0104 
0105     dn_mark = container_of(inode_mark, struct dnotify_mark, fsn_mark);
0106 
0107     spin_lock(&inode_mark->lock);
0108     prev = &dn_mark->dn;
0109     while ((dn = *prev) != NULL) {
0110         if ((dn->dn_mask & test_mask) == 0) {
0111             prev = &dn->dn_next;
0112             continue;
0113         }
0114         fown = &dn->dn_filp->f_owner;
0115         send_sigio(fown, dn->dn_fd, POLL_MSG);
0116         if (dn->dn_mask & FS_DN_MULTISHOT)
0117             prev = &dn->dn_next;
0118         else {
0119             *prev = dn->dn_next;
0120             kmem_cache_free(dnotify_struct_cache, dn);
0121             dnotify_recalc_inode_mask(inode_mark);
0122         }
0123     }
0124 
0125     spin_unlock(&inode_mark->lock);
0126 
0127     return 0;
0128 }
0129 
0130 static void dnotify_free_mark(struct fsnotify_mark *fsn_mark)
0131 {
0132     struct dnotify_mark *dn_mark = container_of(fsn_mark,
0133                             struct dnotify_mark,
0134                             fsn_mark);
0135 
0136     BUG_ON(dn_mark->dn);
0137 
0138     kmem_cache_free(dnotify_mark_cache, dn_mark);
0139 }
0140 
0141 static const struct fsnotify_ops dnotify_fsnotify_ops = {
0142     .handle_inode_event = dnotify_handle_event,
0143     .free_mark = dnotify_free_mark,
0144 };
0145 
0146 /*
0147  * Called every time a file is closed.  Looks first for a dnotify mark on the
0148  * inode.  If one is found run all of the ->dn structures attached to that
0149  * mark for one relevant to this process closing the file and remove that
0150  * dnotify_struct.  If that was the last dnotify_struct also remove the
0151  * fsnotify_mark.
0152  */
0153 void dnotify_flush(struct file *filp, fl_owner_t id)
0154 {
0155     struct fsnotify_mark *fsn_mark;
0156     struct dnotify_mark *dn_mark;
0157     struct dnotify_struct *dn;
0158     struct dnotify_struct **prev;
0159     struct inode *inode;
0160     bool free = false;
0161 
0162     inode = file_inode(filp);
0163     if (!S_ISDIR(inode->i_mode))
0164         return;
0165 
0166     fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, dnotify_group);
0167     if (!fsn_mark)
0168         return;
0169     dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark);
0170 
0171     fsnotify_group_lock(dnotify_group);
0172 
0173     spin_lock(&fsn_mark->lock);
0174     prev = &dn_mark->dn;
0175     while ((dn = *prev) != NULL) {
0176         if ((dn->dn_owner == id) && (dn->dn_filp == filp)) {
0177             *prev = dn->dn_next;
0178             kmem_cache_free(dnotify_struct_cache, dn);
0179             dnotify_recalc_inode_mask(fsn_mark);
0180             break;
0181         }
0182         prev = &dn->dn_next;
0183     }
0184 
0185     spin_unlock(&fsn_mark->lock);
0186 
0187     /* nothing else could have found us thanks to the dnotify_groups
0188        mark_mutex */
0189     if (dn_mark->dn == NULL) {
0190         fsnotify_detach_mark(fsn_mark);
0191         free = true;
0192     }
0193 
0194     fsnotify_group_unlock(dnotify_group);
0195 
0196     if (free)
0197         fsnotify_free_mark(fsn_mark);
0198     fsnotify_put_mark(fsn_mark);
0199 }
0200 
0201 /* this conversion is done only at watch creation */
0202 static __u32 convert_arg(unsigned long arg)
0203 {
0204     __u32 new_mask = FS_EVENT_ON_CHILD;
0205 
0206     if (arg & DN_MULTISHOT)
0207         new_mask |= FS_DN_MULTISHOT;
0208     if (arg & DN_DELETE)
0209         new_mask |= (FS_DELETE | FS_MOVED_FROM);
0210     if (arg & DN_MODIFY)
0211         new_mask |= FS_MODIFY;
0212     if (arg & DN_ACCESS)
0213         new_mask |= FS_ACCESS;
0214     if (arg & DN_ATTRIB)
0215         new_mask |= FS_ATTRIB;
0216     if (arg & DN_RENAME)
0217         new_mask |= FS_RENAME;
0218     if (arg & DN_CREATE)
0219         new_mask |= (FS_CREATE | FS_MOVED_TO);
0220 
0221     return new_mask;
0222 }
0223 
0224 /*
0225  * If multiple processes watch the same inode with dnotify there is only one
0226  * dnotify mark in inode->i_fsnotify_marks but we chain a dnotify_struct
0227  * onto that mark.  This function either attaches the new dnotify_struct onto
0228  * that list, or it |= the mask onto an existing dnofiy_struct.
0229  */
0230 static int attach_dn(struct dnotify_struct *dn, struct dnotify_mark *dn_mark,
0231              fl_owner_t id, int fd, struct file *filp, __u32 mask)
0232 {
0233     struct dnotify_struct *odn;
0234 
0235     odn = dn_mark->dn;
0236     while (odn != NULL) {
0237         /* adding more events to existing dnofiy_struct? */
0238         if ((odn->dn_owner == id) && (odn->dn_filp == filp)) {
0239             odn->dn_fd = fd;
0240             odn->dn_mask |= mask;
0241             return -EEXIST;
0242         }
0243         odn = odn->dn_next;
0244     }
0245 
0246     dn->dn_mask = mask;
0247     dn->dn_fd = fd;
0248     dn->dn_filp = filp;
0249     dn->dn_owner = id;
0250     dn->dn_next = dn_mark->dn;
0251     dn_mark->dn = dn;
0252 
0253     return 0;
0254 }
0255 
0256 /*
0257  * When a process calls fcntl to attach a dnotify watch to a directory it ends
0258  * up here.  Allocate both a mark for fsnotify to add and a dnotify_struct to be
0259  * attached to the fsnotify_mark.
0260  */
0261 int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
0262 {
0263     struct dnotify_mark *new_dn_mark, *dn_mark;
0264     struct fsnotify_mark *new_fsn_mark, *fsn_mark;
0265     struct dnotify_struct *dn;
0266     struct inode *inode;
0267     fl_owner_t id = current->files;
0268     struct file *f;
0269     int destroy = 0, error = 0;
0270     __u32 mask;
0271 
0272     /* we use these to tell if we need to kfree */
0273     new_fsn_mark = NULL;
0274     dn = NULL;
0275 
0276     if (!dir_notify_enable) {
0277         error = -EINVAL;
0278         goto out_err;
0279     }
0280 
0281     /* a 0 mask means we are explicitly removing the watch */
0282     if ((arg & ~DN_MULTISHOT) == 0) {
0283         dnotify_flush(filp, id);
0284         error = 0;
0285         goto out_err;
0286     }
0287 
0288     /* dnotify only works on directories */
0289     inode = file_inode(filp);
0290     if (!S_ISDIR(inode->i_mode)) {
0291         error = -ENOTDIR;
0292         goto out_err;
0293     }
0294 
0295     /*
0296      * convert the userspace DN_* "arg" to the internal FS_*
0297      * defined in fsnotify
0298      */
0299     mask = convert_arg(arg);
0300 
0301     error = security_path_notify(&filp->f_path, mask,
0302             FSNOTIFY_OBJ_TYPE_INODE);
0303     if (error)
0304         goto out_err;
0305 
0306     /* expect most fcntl to add new rather than augment old */
0307     dn = kmem_cache_alloc(dnotify_struct_cache, GFP_KERNEL);
0308     if (!dn) {
0309         error = -ENOMEM;
0310         goto out_err;
0311     }
0312 
0313     /* new fsnotify mark, we expect most fcntl calls to add a new mark */
0314     new_dn_mark = kmem_cache_alloc(dnotify_mark_cache, GFP_KERNEL);
0315     if (!new_dn_mark) {
0316         error = -ENOMEM;
0317         goto out_err;
0318     }
0319 
0320     /* set up the new_fsn_mark and new_dn_mark */
0321     new_fsn_mark = &new_dn_mark->fsn_mark;
0322     fsnotify_init_mark(new_fsn_mark, dnotify_group);
0323     new_fsn_mark->mask = mask;
0324     new_dn_mark->dn = NULL;
0325 
0326     /* this is needed to prevent the fcntl/close race described below */
0327     fsnotify_group_lock(dnotify_group);
0328 
0329     /* add the new_fsn_mark or find an old one. */
0330     fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, dnotify_group);
0331     if (fsn_mark) {
0332         dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark);
0333         spin_lock(&fsn_mark->lock);
0334     } else {
0335         error = fsnotify_add_inode_mark_locked(new_fsn_mark, inode, 0);
0336         if (error) {
0337             fsnotify_group_unlock(dnotify_group);
0338             goto out_err;
0339         }
0340         spin_lock(&new_fsn_mark->lock);
0341         fsn_mark = new_fsn_mark;
0342         dn_mark = new_dn_mark;
0343         /* we used new_fsn_mark, so don't free it */
0344         new_fsn_mark = NULL;
0345     }
0346 
0347     rcu_read_lock();
0348     f = lookup_fd_rcu(fd);
0349     rcu_read_unlock();
0350 
0351     /* if (f != filp) means that we lost a race and another task/thread
0352      * actually closed the fd we are still playing with before we grabbed
0353      * the dnotify_groups mark_mutex and fsn_mark->lock.  Since closing the
0354      * fd is the only time we clean up the marks we need to get our mark
0355      * off the list. */
0356     if (f != filp) {
0357         /* if we added ourselves, shoot ourselves, it's possible that
0358          * the flush actually did shoot this fsn_mark.  That's fine too
0359          * since multiple calls to destroy_mark is perfectly safe, if
0360          * we found a dn_mark already attached to the inode, just sod
0361          * off silently as the flush at close time dealt with it.
0362          */
0363         if (dn_mark == new_dn_mark)
0364             destroy = 1;
0365         error = 0;
0366         goto out;
0367     }
0368 
0369     __f_setown(filp, task_pid(current), PIDTYPE_TGID, 0);
0370 
0371     error = attach_dn(dn, dn_mark, id, fd, filp, mask);
0372     /* !error means that we attached the dn to the dn_mark, so don't free it */
0373     if (!error)
0374         dn = NULL;
0375     /* -EEXIST means that we didn't add this new dn and used an old one.
0376      * that isn't an error (and the unused dn should be freed) */
0377     else if (error == -EEXIST)
0378         error = 0;
0379 
0380     dnotify_recalc_inode_mask(fsn_mark);
0381 out:
0382     spin_unlock(&fsn_mark->lock);
0383 
0384     if (destroy)
0385         fsnotify_detach_mark(fsn_mark);
0386     fsnotify_group_unlock(dnotify_group);
0387     if (destroy)
0388         fsnotify_free_mark(fsn_mark);
0389     fsnotify_put_mark(fsn_mark);
0390 out_err:
0391     if (new_fsn_mark)
0392         fsnotify_put_mark(new_fsn_mark);
0393     if (dn)
0394         kmem_cache_free(dnotify_struct_cache, dn);
0395     return error;
0396 }
0397 
0398 static int __init dnotify_init(void)
0399 {
0400     dnotify_struct_cache = KMEM_CACHE(dnotify_struct,
0401                       SLAB_PANIC|SLAB_ACCOUNT);
0402     dnotify_mark_cache = KMEM_CACHE(dnotify_mark, SLAB_PANIC|SLAB_ACCOUNT);
0403 
0404     dnotify_group = fsnotify_alloc_group(&dnotify_fsnotify_ops,
0405                          FSNOTIFY_GROUP_NOFS);
0406     if (IS_ERR(dnotify_group))
0407         panic("unable to allocate fsnotify group for dnotify\n");
0408     dnotify_sysctl_init();
0409     return 0;
0410 }
0411 
0412 module_init(dnotify_init)