summaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-ioctl.c
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2017-01-16 16:05:59 -0500
committerMike Snitzer <snitzer@redhat.com>2017-06-19 11:03:49 -0400
commit93e6442c76a0d26ad028c5df9b4a1e3096d9c36b (patch)
tree50cb9b89d834e3b3c4e65189d0a3f1f85303cb0b /drivers/md/dm-ioctl.c
parent443bd90f2cca9dec3db9ef9460a9c2a6f095f789 (diff)
dm: add basic support for using the select or poll function
Add the ability to poll on the /dev/mapper/control device. The select or poll function waits until any event happens on any dm device since opening the /dev/mapper/control device. When select or poll returns the device as readable, we must close and reopen the device to wait for new dm events. Usage: 1. open the /dev/mapper/control device 2. scan the event numbers of all devices we are interested in and process them 3. call select, poll or epoll on the handle (it waits until some new event happens since opening the device) 4. close the /dev/mapper/control handle 5. go to step 1 The next commit allows to re-arm the polling without closing and reopening the device. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Andy Grover <agrover@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/dm-ioctl.c')
-rw-r--r--drivers/md/dm-ioctl.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 41852ae287a5..6b65a538d91d 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -23,6 +23,14 @@
23#define DM_MSG_PREFIX "ioctl" 23#define DM_MSG_PREFIX "ioctl"
24#define DM_DRIVER_EMAIL "dm-devel@redhat.com" 24#define DM_DRIVER_EMAIL "dm-devel@redhat.com"
25 25
26struct dm_file {
27 /*
28 * poll will wait until the global event number is greater than
29 * this value.
30 */
31 unsigned global_event_nr;
32};
33
26/*----------------------------------------------------------------- 34/*-----------------------------------------------------------------
27 * The ioctl interface needs to be able to look up devices by 35 * The ioctl interface needs to be able to look up devices by
28 * name or uuid. 36 * name or uuid.
@@ -1868,8 +1876,47 @@ static long dm_compat_ctl_ioctl(struct file *file, uint command, ulong u)
1868#define dm_compat_ctl_ioctl NULL 1876#define dm_compat_ctl_ioctl NULL
1869#endif 1877#endif
1870 1878
1879static int dm_open(struct inode *inode, struct file *filp)
1880{
1881 int r;
1882 struct dm_file *priv;
1883
1884 r = nonseekable_open(inode, filp);
1885 if (unlikely(r))
1886 return r;
1887
1888 priv = filp->private_data = kmalloc(sizeof(struct dm_file), GFP_KERNEL);
1889 if (!priv)
1890 return -ENOMEM;
1891
1892 priv->global_event_nr = atomic_read(&dm_global_event_nr);
1893
1894 return 0;
1895}
1896
1897static int dm_release(struct inode *inode, struct file *filp)
1898{
1899 kfree(filp->private_data);
1900 return 0;
1901}
1902
1903static unsigned dm_poll(struct file *filp, poll_table *wait)
1904{
1905 struct dm_file *priv = filp->private_data;
1906 unsigned mask = 0;
1907
1908 poll_wait(filp, &dm_global_eventq, wait);
1909
1910 if ((int)(atomic_read(&dm_global_event_nr) - priv->global_event_nr) > 0)
1911 mask |= POLLIN;
1912
1913 return mask;
1914}
1915
1871static const struct file_operations _ctl_fops = { 1916static const struct file_operations _ctl_fops = {
1872 .open = nonseekable_open, 1917 .open = dm_open,
1918 .release = dm_release,
1919 .poll = dm_poll,
1873 .unlocked_ioctl = dm_ctl_ioctl, 1920 .unlocked_ioctl = dm_ctl_ioctl,
1874 .compat_ioctl = dm_compat_ctl_ioctl, 1921 .compat_ioctl = dm_compat_ctl_ioctl,
1875 .owner = THIS_MODULE, 1922 .owner = THIS_MODULE,