Commit e2914cc26bbca67fd30fff02c6777e8477fc8a6a

Authored by Mikulas Patocka
Committed by Alasdair G Kergon
1 parent 5f01520415

dm ioctl: introduce ioctl_flags

This patch introduces flags for each ioctl function.

So far, one flag is defined, IOCTL_FLAGS_NO_PARAMS.  It is set if the
function processing the ioctl doesn't take or produce any parameters in
the section of the data buffer that has a variable size.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>

Showing 1 changed file with 41 additions and 23 deletions Side-by-side Diff

drivers/md/dm-ioctl.c
... ... @@ -1478,39 +1478,52 @@
1478 1478 return r;
1479 1479 }
1480 1480  
  1481 +/*
  1482 + * The ioctl parameter block consists of two parts, a dm_ioctl struct
  1483 + * followed by a data buffer. This flag is set if the second part,
  1484 + * which has a variable size, is not used by the function processing
  1485 + * the ioctl.
  1486 + */
  1487 +#define IOCTL_FLAGS_NO_PARAMS 1
  1488 +
1481 1489 /*-----------------------------------------------------------------
1482 1490 * Implementation of open/close/ioctl on the special char
1483 1491 * device.
1484 1492 *---------------------------------------------------------------*/
1485   -static ioctl_fn lookup_ioctl(unsigned int cmd)
  1493 +static ioctl_fn lookup_ioctl(unsigned int cmd, int *ioctl_flags)
1486 1494 {
1487 1495 static struct {
1488 1496 int cmd;
  1497 + int flags;
1489 1498 ioctl_fn fn;
1490 1499 } _ioctls[] = {
1491   - {DM_VERSION_CMD, NULL}, /* version is dealt with elsewhere */
1492   - {DM_REMOVE_ALL_CMD, remove_all},
1493   - {DM_LIST_DEVICES_CMD, list_devices},
  1500 + {DM_VERSION_CMD, 0, NULL}, /* version is dealt with elsewhere */
  1501 + {DM_REMOVE_ALL_CMD, IOCTL_FLAGS_NO_PARAMS, remove_all},
  1502 + {DM_LIST_DEVICES_CMD, 0, list_devices},
1494 1503  
1495   - {DM_DEV_CREATE_CMD, dev_create},
1496   - {DM_DEV_REMOVE_CMD, dev_remove},
1497   - {DM_DEV_RENAME_CMD, dev_rename},
1498   - {DM_DEV_SUSPEND_CMD, dev_suspend},
1499   - {DM_DEV_STATUS_CMD, dev_status},
1500   - {DM_DEV_WAIT_CMD, dev_wait},
  1504 + {DM_DEV_CREATE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_create},
  1505 + {DM_DEV_REMOVE_CMD, IOCTL_FLAGS_NO_PARAMS, dev_remove},
  1506 + {DM_DEV_RENAME_CMD, 0, dev_rename},
  1507 + {DM_DEV_SUSPEND_CMD, IOCTL_FLAGS_NO_PARAMS, dev_suspend},
  1508 + {DM_DEV_STATUS_CMD, IOCTL_FLAGS_NO_PARAMS, dev_status},
  1509 + {DM_DEV_WAIT_CMD, 0, dev_wait},
1501 1510  
1502   - {DM_TABLE_LOAD_CMD, table_load},
1503   - {DM_TABLE_CLEAR_CMD, table_clear},
1504   - {DM_TABLE_DEPS_CMD, table_deps},
1505   - {DM_TABLE_STATUS_CMD, table_status},
  1511 + {DM_TABLE_LOAD_CMD, 0, table_load},
  1512 + {DM_TABLE_CLEAR_CMD, IOCTL_FLAGS_NO_PARAMS, table_clear},
  1513 + {DM_TABLE_DEPS_CMD, 0, table_deps},
  1514 + {DM_TABLE_STATUS_CMD, 0, table_status},
1506 1515  
1507   - {DM_LIST_VERSIONS_CMD, list_versions},
  1516 + {DM_LIST_VERSIONS_CMD, 0, list_versions},
1508 1517  
1509   - {DM_TARGET_MSG_CMD, target_message},
1510   - {DM_DEV_SET_GEOMETRY_CMD, dev_set_geometry}
  1518 + {DM_TARGET_MSG_CMD, 0, target_message},
  1519 + {DM_DEV_SET_GEOMETRY_CMD, 0, dev_set_geometry}
1511 1520 };
1512 1521  
1513   - return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn;
  1522 + if (unlikely(cmd >= ARRAY_SIZE(_ioctls)))
  1523 + return NULL;
  1524 +
  1525 + *ioctl_flags = _ioctls[cmd].flags;
  1526 + return _ioctls[cmd].fn;
1514 1527 }
1515 1528  
1516 1529 /*
... ... @@ -1652,6 +1665,7 @@
1652 1665 static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
1653 1666 {
1654 1667 int r = 0;
  1668 + int ioctl_flags;
1655 1669 int param_flags;
1656 1670 unsigned int cmd;
1657 1671 struct dm_ioctl *uninitialized_var(param);
... ... @@ -1681,7 +1695,7 @@
1681 1695 if (cmd == DM_VERSION_CMD)
1682 1696 return 0;
1683 1697  
1684   - fn = lookup_ioctl(cmd);
  1698 + fn = lookup_ioctl(cmd, &ioctl_flags);
1685 1699 if (!fn) {
1686 1700 DMWARN("dm_ctl_ioctl: unknown command 0x%x", command);
1687 1701 return -ENOTTY;
... ... @@ -1702,6 +1716,10 @@
1702 1716  
1703 1717 param->data_size = sizeof(*param);
1704 1718 r = fn(param, input_param_size);
  1719 +
  1720 + if (unlikely(param->flags & DM_BUFFER_FULL_FLAG) &&
  1721 + unlikely(ioctl_flags & IOCTL_FLAGS_NO_PARAMS))
  1722 + DMERR("ioctl %d tried to output some data but has IOCTL_FLAGS_NO_PARAMS set", cmd);
1705 1723  
1706 1724 /*
1707 1725 * Copy the results back to userland.