LCOV - code coverage report
Current view: top level - block - disk-events.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 172 0.0 %
Date: 2023-04-06 08:38:28 Functions: 0 21 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Disk events - monitor disk events like media change and eject request.
       4             :  */
       5             : #include <linux/export.h>
       6             : #include <linux/moduleparam.h>
       7             : #include <linux/blkdev.h>
       8             : #include "blk.h"
       9             : 
      10             : struct disk_events {
      11             :         struct list_head        node;           /* all disk_event's */
      12             :         struct gendisk          *disk;          /* the associated disk */
      13             :         spinlock_t              lock;
      14             : 
      15             :         struct mutex            block_mutex;    /* protects blocking */
      16             :         int                     block;          /* event blocking depth */
      17             :         unsigned int            pending;        /* events already sent out */
      18             :         unsigned int            clearing;       /* events being cleared */
      19             : 
      20             :         long                    poll_msecs;     /* interval, -1 for default */
      21             :         struct delayed_work     dwork;
      22             : };
      23             : 
      24             : static const char *disk_events_strs[] = {
      25             :         [ilog2(DISK_EVENT_MEDIA_CHANGE)]        = "media_change",
      26             :         [ilog2(DISK_EVENT_EJECT_REQUEST)]       = "eject_request",
      27             : };
      28             : 
      29             : static char *disk_uevents[] = {
      30             :         [ilog2(DISK_EVENT_MEDIA_CHANGE)]        = "DISK_MEDIA_CHANGE=1",
      31             :         [ilog2(DISK_EVENT_EJECT_REQUEST)]       = "DISK_EJECT_REQUEST=1",
      32             : };
      33             : 
      34             : /* list of all disk_events */
      35             : static DEFINE_MUTEX(disk_events_mutex);
      36             : static LIST_HEAD(disk_events);
      37             : 
      38             : /* disable in-kernel polling by default */
      39             : static unsigned long disk_events_dfl_poll_msecs;
      40             : 
      41           0 : static unsigned long disk_events_poll_jiffies(struct gendisk *disk)
      42             : {
      43           0 :         struct disk_events *ev = disk->ev;
      44           0 :         long intv_msecs = 0;
      45             : 
      46             :         /*
      47             :          * If device-specific poll interval is set, always use it.  If
      48             :          * the default is being used, poll if the POLL flag is set.
      49             :          */
      50           0 :         if (ev->poll_msecs >= 0)
      51             :                 intv_msecs = ev->poll_msecs;
      52           0 :         else if (disk->event_flags & DISK_EVENT_FLAG_POLL)
      53           0 :                 intv_msecs = disk_events_dfl_poll_msecs;
      54             : 
      55           0 :         return msecs_to_jiffies(intv_msecs);
      56             : }
      57             : 
      58             : /**
      59             :  * disk_block_events - block and flush disk event checking
      60             :  * @disk: disk to block events for
      61             :  *
      62             :  * On return from this function, it is guaranteed that event checking
      63             :  * isn't in progress and won't happen until unblocked by
      64             :  * disk_unblock_events().  Events blocking is counted and the actual
      65             :  * unblocking happens after the matching number of unblocks are done.
      66             :  *
      67             :  * Note that this intentionally does not block event checking from
      68             :  * disk_clear_events().
      69             :  *
      70             :  * CONTEXT:
      71             :  * Might sleep.
      72             :  */
      73           0 : void disk_block_events(struct gendisk *disk)
      74             : {
      75           0 :         struct disk_events *ev = disk->ev;
      76             :         unsigned long flags;
      77             :         bool cancel;
      78             : 
      79           0 :         if (!ev)
      80             :                 return;
      81             : 
      82             :         /*
      83             :          * Outer mutex ensures that the first blocker completes canceling
      84             :          * the event work before further blockers are allowed to finish.
      85             :          */
      86           0 :         mutex_lock(&ev->block_mutex);
      87             : 
      88           0 :         spin_lock_irqsave(&ev->lock, flags);
      89           0 :         cancel = !ev->block++;
      90           0 :         spin_unlock_irqrestore(&ev->lock, flags);
      91             : 
      92           0 :         if (cancel)
      93           0 :                 cancel_delayed_work_sync(&disk->ev->dwork);
      94             : 
      95           0 :         mutex_unlock(&ev->block_mutex);
      96             : }
      97             : 
      98           0 : static void __disk_unblock_events(struct gendisk *disk, bool check_now)
      99             : {
     100           0 :         struct disk_events *ev = disk->ev;
     101             :         unsigned long intv;
     102             :         unsigned long flags;
     103             : 
     104           0 :         spin_lock_irqsave(&ev->lock, flags);
     105             : 
     106           0 :         if (WARN_ON_ONCE(ev->block <= 0))
     107             :                 goto out_unlock;
     108             : 
     109           0 :         if (--ev->block)
     110             :                 goto out_unlock;
     111             : 
     112           0 :         intv = disk_events_poll_jiffies(disk);
     113           0 :         if (check_now)
     114           0 :                 queue_delayed_work(system_freezable_power_efficient_wq,
     115             :                                 &ev->dwork, 0);
     116           0 :         else if (intv)
     117           0 :                 queue_delayed_work(system_freezable_power_efficient_wq,
     118             :                                 &ev->dwork, intv);
     119             : out_unlock:
     120           0 :         spin_unlock_irqrestore(&ev->lock, flags);
     121           0 : }
     122             : 
     123             : /**
     124             :  * disk_unblock_events - unblock disk event checking
     125             :  * @disk: disk to unblock events for
     126             :  *
     127             :  * Undo disk_block_events().  When the block count reaches zero, it
     128             :  * starts events polling if configured.
     129             :  *
     130             :  * CONTEXT:
     131             :  * Don't care.  Safe to call from irq context.
     132             :  */
     133           0 : void disk_unblock_events(struct gendisk *disk)
     134             : {
     135           0 :         if (disk->ev)
     136           0 :                 __disk_unblock_events(disk, false);
     137           0 : }
     138             : 
     139             : /**
     140             :  * disk_flush_events - schedule immediate event checking and flushing
     141             :  * @disk: disk to check and flush events for
     142             :  * @mask: events to flush
     143             :  *
     144             :  * Schedule immediate event checking on @disk if not blocked.  Events in
     145             :  * @mask are scheduled to be cleared from the driver.  Note that this
     146             :  * doesn't clear the events from @disk->ev.
     147             :  *
     148             :  * CONTEXT:
     149             :  * If @mask is non-zero must be called with disk->open_mutex held.
     150             :  */
     151           0 : void disk_flush_events(struct gendisk *disk, unsigned int mask)
     152             : {
     153           0 :         struct disk_events *ev = disk->ev;
     154             : 
     155           0 :         if (!ev)
     156             :                 return;
     157             : 
     158           0 :         spin_lock_irq(&ev->lock);
     159           0 :         ev->clearing |= mask;
     160           0 :         if (!ev->block)
     161           0 :                 mod_delayed_work(system_freezable_power_efficient_wq,
     162             :                                 &ev->dwork, 0);
     163           0 :         spin_unlock_irq(&ev->lock);
     164             : }
     165             : 
     166             : /*
     167             :  * Tell userland about new events.  Only the events listed in @disk->events are
     168             :  * reported, and only if DISK_EVENT_FLAG_UEVENT is set.  Otherwise, events are
     169             :  * processed internally but never get reported to userland.
     170             :  */
     171           0 : static void disk_event_uevent(struct gendisk *disk, unsigned int events)
     172             : {
     173           0 :         char *envp[ARRAY_SIZE(disk_uevents) + 1] = { };
     174           0 :         int nr_events = 0, i;
     175             : 
     176           0 :         for (i = 0; i < ARRAY_SIZE(disk_uevents); i++)
     177           0 :                 if (events & disk->events & (1 << i))
     178           0 :                         envp[nr_events++] = disk_uevents[i];
     179             : 
     180           0 :         if (nr_events)
     181           0 :                 kobject_uevent_env(&disk_to_dev(disk)->kobj, KOBJ_CHANGE, envp);
     182           0 : }
     183             : 
     184           0 : static void disk_check_events(struct disk_events *ev,
     185             :                               unsigned int *clearing_ptr)
     186             : {
     187           0 :         struct gendisk *disk = ev->disk;
     188           0 :         unsigned int clearing = *clearing_ptr;
     189             :         unsigned int events;
     190             :         unsigned long intv;
     191             : 
     192             :         /* check events */
     193           0 :         events = disk->fops->check_events(disk, clearing);
     194             : 
     195             :         /* accumulate pending events and schedule next poll if necessary */
     196           0 :         spin_lock_irq(&ev->lock);
     197             : 
     198           0 :         events &= ~ev->pending;
     199           0 :         ev->pending |= events;
     200           0 :         *clearing_ptr &= ~clearing;
     201             : 
     202           0 :         intv = disk_events_poll_jiffies(disk);
     203           0 :         if (!ev->block && intv)
     204           0 :                 queue_delayed_work(system_freezable_power_efficient_wq,
     205             :                                 &ev->dwork, intv);
     206             : 
     207           0 :         spin_unlock_irq(&ev->lock);
     208             : 
     209           0 :         if (events & DISK_EVENT_MEDIA_CHANGE)
     210           0 :                 inc_diskseq(disk);
     211             : 
     212           0 :         if (disk->event_flags & DISK_EVENT_FLAG_UEVENT)
     213           0 :                 disk_event_uevent(disk, events);
     214           0 : }
     215             : 
     216             : /**
     217             :  * disk_clear_events - synchronously check, clear and return pending events
     218             :  * @disk: disk to fetch and clear events from
     219             :  * @mask: mask of events to be fetched and cleared
     220             :  *
     221             :  * Disk events are synchronously checked and pending events in @mask
     222             :  * are cleared and returned.  This ignores the block count.
     223             :  *
     224             :  * CONTEXT:
     225             :  * Might sleep.
     226             :  */
     227           0 : static unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask)
     228             : {
     229           0 :         struct disk_events *ev = disk->ev;
     230             :         unsigned int pending;
     231           0 :         unsigned int clearing = mask;
     232             : 
     233           0 :         if (!ev)
     234             :                 return 0;
     235             : 
     236           0 :         disk_block_events(disk);
     237             : 
     238             :         /*
     239             :          * store the union of mask and ev->clearing on the stack so that the
     240             :          * race with disk_flush_events does not cause ambiguity (ev->clearing
     241             :          * can still be modified even if events are blocked).
     242             :          */
     243           0 :         spin_lock_irq(&ev->lock);
     244           0 :         clearing |= ev->clearing;
     245           0 :         ev->clearing = 0;
     246           0 :         spin_unlock_irq(&ev->lock);
     247             : 
     248           0 :         disk_check_events(ev, &clearing);
     249             :         /*
     250             :          * if ev->clearing is not 0, the disk_flush_events got called in the
     251             :          * middle of this function, so we want to run the workfn without delay.
     252             :          */
     253           0 :         __disk_unblock_events(disk, ev->clearing ? true : false);
     254             : 
     255             :         /* then, fetch and clear pending events */
     256           0 :         spin_lock_irq(&ev->lock);
     257           0 :         pending = ev->pending & mask;
     258           0 :         ev->pending &= ~mask;
     259           0 :         spin_unlock_irq(&ev->lock);
     260           0 :         WARN_ON_ONCE(clearing & mask);
     261             : 
     262             :         return pending;
     263             : }
     264             : 
     265             : /**
     266             :  * bdev_check_media_change - check if a removable media has been changed
     267             :  * @bdev: block device to check
     268             :  *
     269             :  * Check whether a removable media has been changed, and attempt to free all
     270             :  * dentries and inodes and invalidates all block device page cache entries in
     271             :  * that case.
     272             :  *
     273             :  * Returns %true if the block device changed, or %false if not.
     274             :  */
     275           0 : bool bdev_check_media_change(struct block_device *bdev)
     276             : {
     277             :         unsigned int events;
     278             : 
     279           0 :         events = disk_clear_events(bdev->bd_disk, DISK_EVENT_MEDIA_CHANGE |
     280             :                                    DISK_EVENT_EJECT_REQUEST);
     281           0 :         if (!(events & DISK_EVENT_MEDIA_CHANGE))
     282             :                 return false;
     283             : 
     284           0 :         if (__invalidate_device(bdev, true))
     285           0 :                 pr_warn("VFS: busy inodes on changed media %s\n",
     286             :                         bdev->bd_disk->disk_name);
     287           0 :         set_bit(GD_NEED_PART_SCAN, &bdev->bd_disk->state);
     288           0 :         return true;
     289             : }
     290             : EXPORT_SYMBOL(bdev_check_media_change);
     291             : 
     292             : /**
     293             :  * disk_force_media_change - force a media change event
     294             :  * @disk: the disk which will raise the event
     295             :  * @events: the events to raise
     296             :  *
     297             :  * Generate uevents for the disk. If DISK_EVENT_MEDIA_CHANGE is present,
     298             :  * attempt to free all dentries and inodes and invalidates all block
     299             :  * device page cache entries in that case.
     300             :  *
     301             :  * Returns %true if DISK_EVENT_MEDIA_CHANGE was raised, or %false if not.
     302             :  */
     303           0 : bool disk_force_media_change(struct gendisk *disk, unsigned int events)
     304             : {
     305           0 :         disk_event_uevent(disk, events);
     306             : 
     307           0 :         if (!(events & DISK_EVENT_MEDIA_CHANGE))
     308             :                 return false;
     309             : 
     310           0 :         if (__invalidate_device(disk->part0, true))
     311           0 :                 pr_warn("VFS: busy inodes on changed media %s\n",
     312             :                         disk->disk_name);
     313           0 :         set_bit(GD_NEED_PART_SCAN, &disk->state);
     314           0 :         return true;
     315             : }
     316             : EXPORT_SYMBOL_GPL(disk_force_media_change);
     317             : 
     318             : /*
     319             :  * Separate this part out so that a different pointer for clearing_ptr can be
     320             :  * passed in for disk_clear_events.
     321             :  */
     322           0 : static void disk_events_workfn(struct work_struct *work)
     323             : {
     324           0 :         struct delayed_work *dwork = to_delayed_work(work);
     325           0 :         struct disk_events *ev = container_of(dwork, struct disk_events, dwork);
     326             : 
     327           0 :         disk_check_events(ev, &ev->clearing);
     328           0 : }
     329             : 
     330             : /*
     331             :  * A disk events enabled device has the following sysfs nodes under
     332             :  * its /sys/block/X/ directory.
     333             :  *
     334             :  * events               : list of all supported events
     335             :  * events_async         : list of events which can be detected w/o polling
     336             :  *                        (always empty, only for backwards compatibility)
     337             :  * events_poll_msecs    : polling interval, 0: disable, -1: system default
     338             :  */
     339           0 : static ssize_t __disk_events_show(unsigned int events, char *buf)
     340             : {
     341           0 :         const char *delim = "";
     342           0 :         ssize_t pos = 0;
     343             :         int i;
     344             : 
     345           0 :         for (i = 0; i < ARRAY_SIZE(disk_events_strs); i++)
     346           0 :                 if (events & (1 << i)) {
     347           0 :                         pos += sprintf(buf + pos, "%s%s",
     348             :                                        delim, disk_events_strs[i]);
     349           0 :                         delim = " ";
     350             :                 }
     351           0 :         if (pos)
     352           0 :                 pos += sprintf(buf + pos, "\n");
     353           0 :         return pos;
     354             : }
     355             : 
     356           0 : static ssize_t disk_events_show(struct device *dev,
     357             :                                 struct device_attribute *attr, char *buf)
     358             : {
     359           0 :         struct gendisk *disk = dev_to_disk(dev);
     360             : 
     361           0 :         if (!(disk->event_flags & DISK_EVENT_FLAG_UEVENT))
     362             :                 return 0;
     363           0 :         return __disk_events_show(disk->events, buf);
     364             : }
     365             : 
     366           0 : static ssize_t disk_events_async_show(struct device *dev,
     367             :                                       struct device_attribute *attr, char *buf)
     368             : {
     369           0 :         return 0;
     370             : }
     371             : 
     372           0 : static ssize_t disk_events_poll_msecs_show(struct device *dev,
     373             :                                            struct device_attribute *attr,
     374             :                                            char *buf)
     375             : {
     376           0 :         struct gendisk *disk = dev_to_disk(dev);
     377             : 
     378           0 :         if (!disk->ev)
     379           0 :                 return sprintf(buf, "-1\n");
     380           0 :         return sprintf(buf, "%ld\n", disk->ev->poll_msecs);
     381             : }
     382             : 
     383           0 : static ssize_t disk_events_poll_msecs_store(struct device *dev,
     384             :                                             struct device_attribute *attr,
     385             :                                             const char *buf, size_t count)
     386             : {
     387           0 :         struct gendisk *disk = dev_to_disk(dev);
     388             :         long intv;
     389             : 
     390           0 :         if (!count || !sscanf(buf, "%ld", &intv))
     391             :                 return -EINVAL;
     392             : 
     393           0 :         if (intv < 0 && intv != -1)
     394             :                 return -EINVAL;
     395             : 
     396           0 :         if (!disk->ev)
     397             :                 return -ENODEV;
     398             : 
     399           0 :         disk_block_events(disk);
     400           0 :         disk->ev->poll_msecs = intv;
     401           0 :         __disk_unblock_events(disk, true);
     402           0 :         return count;
     403             : }
     404             : 
     405             : DEVICE_ATTR(events, 0444, disk_events_show, NULL);
     406             : DEVICE_ATTR(events_async, 0444, disk_events_async_show, NULL);
     407             : DEVICE_ATTR(events_poll_msecs, 0644, disk_events_poll_msecs_show,
     408             :             disk_events_poll_msecs_store);
     409             : 
     410             : /*
     411             :  * The default polling interval can be specified by the kernel
     412             :  * parameter block.events_dfl_poll_msecs which defaults to 0
     413             :  * (disable).  This can also be modified runtime by writing to
     414             :  * /sys/module/block/parameters/events_dfl_poll_msecs.
     415             :  */
     416           0 : static int disk_events_set_dfl_poll_msecs(const char *val,
     417             :                                           const struct kernel_param *kp)
     418             : {
     419             :         struct disk_events *ev;
     420             :         int ret;
     421             : 
     422           0 :         ret = param_set_ulong(val, kp);
     423           0 :         if (ret < 0)
     424             :                 return ret;
     425             : 
     426           0 :         mutex_lock(&disk_events_mutex);
     427           0 :         list_for_each_entry(ev, &disk_events, node)
     428           0 :                 disk_flush_events(ev->disk, 0);
     429           0 :         mutex_unlock(&disk_events_mutex);
     430           0 :         return 0;
     431             : }
     432             : 
     433             : static const struct kernel_param_ops disk_events_dfl_poll_msecs_param_ops = {
     434             :         .set    = disk_events_set_dfl_poll_msecs,
     435             :         .get    = param_get_ulong,
     436             : };
     437             : 
     438             : #undef MODULE_PARAM_PREFIX
     439             : #define MODULE_PARAM_PREFIX     "block."
     440             : 
     441             : module_param_cb(events_dfl_poll_msecs, &disk_events_dfl_poll_msecs_param_ops,
     442             :                 &disk_events_dfl_poll_msecs, 0644);
     443             : 
     444             : /*
     445             :  * disk_{alloc|add|del|release}_events - initialize and destroy disk_events.
     446             :  */
     447           0 : int disk_alloc_events(struct gendisk *disk)
     448             : {
     449             :         struct disk_events *ev;
     450             : 
     451           0 :         if (!disk->fops->check_events || !disk->events)
     452             :                 return 0;
     453             : 
     454           0 :         ev = kzalloc(sizeof(*ev), GFP_KERNEL);
     455           0 :         if (!ev) {
     456           0 :                 pr_warn("%s: failed to initialize events\n", disk->disk_name);
     457           0 :                 return -ENOMEM;
     458             :         }
     459             : 
     460           0 :         INIT_LIST_HEAD(&ev->node);
     461           0 :         ev->disk = disk;
     462           0 :         spin_lock_init(&ev->lock);
     463           0 :         mutex_init(&ev->block_mutex);
     464           0 :         ev->block = 1;
     465           0 :         ev->poll_msecs = -1;
     466           0 :         INIT_DELAYED_WORK(&ev->dwork, disk_events_workfn);
     467             : 
     468           0 :         disk->ev = ev;
     469           0 :         return 0;
     470             : }
     471             : 
     472           0 : void disk_add_events(struct gendisk *disk)
     473             : {
     474           0 :         if (!disk->ev)
     475             :                 return;
     476             : 
     477           0 :         mutex_lock(&disk_events_mutex);
     478           0 :         list_add_tail(&disk->ev->node, &disk_events);
     479           0 :         mutex_unlock(&disk_events_mutex);
     480             : 
     481             :         /*
     482             :          * Block count is initialized to 1 and the following initial
     483             :          * unblock kicks it into action.
     484             :          */
     485           0 :         __disk_unblock_events(disk, true);
     486             : }
     487             : 
     488           0 : void disk_del_events(struct gendisk *disk)
     489             : {
     490           0 :         if (disk->ev) {
     491           0 :                 disk_block_events(disk);
     492             : 
     493           0 :                 mutex_lock(&disk_events_mutex);
     494           0 :                 list_del_init(&disk->ev->node);
     495           0 :                 mutex_unlock(&disk_events_mutex);
     496             :         }
     497           0 : }
     498             : 
     499           0 : void disk_release_events(struct gendisk *disk)
     500             : {
     501             :         /* the block count should be 1 from disk_del_events() */
     502           0 :         WARN_ON_ONCE(disk->ev && disk->ev->block != 1);
     503           0 :         kfree(disk->ev);
     504           0 : }

Generated by: LCOV version 1.14