Print this page
9286 want refreservation=auto

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libzfs/common/libzfs_dataset.c
          +++ new/usr/src/lib/libzfs/common/libzfs_dataset.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  24      - * Copyright (c) 2013, Joyent, Inc. All rights reserved.
       24 + * Copyright (c) 2018, Joyent, Inc. All rights reserved.
  25   25   * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
  26   26   * Copyright (c) 2012 DEY Storage Systems, Inc.  All rights reserved.
  27   27   * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved.
  28   28   * Copyright (c) 2013 Martin Matuska. All rights reserved.
  29   29   * Copyright (c) 2013 Steven Hartland. All rights reserved.
  30   30   * Copyright (c) 2014 Integros [integros.com]
  31   31   * Copyright 2017 Nexenta Systems, Inc.
  32   32   * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
  33   33   * Copyright 2017 RackTop Systems.
  34   34   */
↓ open down ↓ 1346 lines elided ↑ open up ↑
1381 1381                  if (type == ZFS_TYPE_VOLUME && zhp != NULL) {
1382 1382                          uint64_t volsize = zfs_prop_get_int(zhp,
1383 1383                              ZFS_PROP_VOLSIZE);
1384 1384                          uint64_t blocksize = zfs_prop_get_int(zhp,
1385 1385                              ZFS_PROP_VOLBLOCKSIZE);
1386 1386                          char buf[64];
1387 1387  
1388 1388                          switch (prop) {
1389 1389                          case ZFS_PROP_RESERVATION:
1390 1390                          case ZFS_PROP_REFRESERVATION:
1391      -                                if (intval > volsize) {
     1391 +                                if (intval > volsize && intval != UINT64_MAX) {
1392 1392                                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1393 1393                                              "'%s' is greater than current "
1394 1394                                              "volume size"), propname);
1395 1395                                          (void) zfs_error(hdl, EZFS_BADPROP,
1396 1396                                              errbuf);
1397 1397                                          goto error;
1398 1398                                  }
1399 1399                                  break;
1400 1400  
1401 1401                          case ZFS_PROP_VOLSIZE:
↓ open down ↓ 90 lines elided ↑ open up ↑
1492 1492          fnvlist_free(props);
1493 1493  
1494 1494          if (nvlist_add_uint64(nvl, zfs_prop_to_name(resv_prop),
1495 1495              new_reservation) != 0) {
1496 1496                  (void) no_memory(zhp->zfs_hdl);
1497 1497                  return (-1);
1498 1498          }
1499 1499          return (1);
1500 1500  }
1501 1501  
     1502 +/*
     1503 + * Helper for 'zfs {set|clone} [ref]reservation=auto'.  Must be called after
     1504 + * zfs_valid_proplist(), as it is what sets the UINT64_MAX sentinal value.
     1505 + * Return codes must match zfs_add_synthetic_resv().
     1506 + */
     1507 +static int
     1508 +zfs_fix_auto_resv(zfs_handle_t *zhp, nvlist_t *nvl)
     1509 +{
     1510 +        uint64_t volsize;
     1511 +        uint64_t resvsize;
     1512 +        zfs_prop_t prop;
     1513 +        nvlist_t *props;
     1514 +
     1515 +        if (!ZFS_IS_VOLUME(zhp)) {
     1516 +                return (0);
     1517 +        }
     1518 +
     1519 +        if (zfs_which_resv_prop(zhp, &prop) != 0) {
     1520 +                return (-1);
     1521 +        }
     1522 +        if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(prop), &resvsize) != 0) {
     1523 +                /* No value being set, so it can't be "auto" */
     1524 +                return (0);
     1525 +        }
     1526 +        if (resvsize != UINT64_MAX) {
     1527 +                /* Being set to a value other than "auto" */
     1528 +                return (0);
     1529 +        }
     1530 +
     1531 +        props = fnvlist_alloc();
     1532 +
     1533 +        fnvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
     1534 +            zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE));
     1535 +
     1536 +        if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE),
     1537 +            &volsize) != 0) {
     1538 +                volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
     1539 +        }
     1540 +
     1541 +        resvsize = zvol_volsize_to_reservation(volsize, props);
     1542 +        fnvlist_free(props);
     1543 +
     1544 +        if (nvlist_add_uint64(nvl, zfs_prop_to_name(prop), resvsize) != 0) {
     1545 +                (void) no_memory(zhp->zfs_hdl);
     1546 +                return (-1);
     1547 +        }
     1548 +        return (1);
     1549 +}
     1550 +
1502 1551  void
1503 1552  zfs_setprop_error(libzfs_handle_t *hdl, zfs_prop_t prop, int err,
1504 1553      char *errbuf)
1505 1554  {
1506 1555          switch (err) {
1507 1556  
1508 1557          case ENOSPC:
1509 1558                  /*
1510 1559                   * For quotas and reservations, ENOSPC indicates
1511 1560                   * something different; setting a quota or reservation
↓ open down ↓ 145 lines elided ↑ open up ↑
1657 1706           * before computing the length of the nvlist.
1658 1707           */
1659 1708          for (nvpair_t *elem = nvlist_next_nvpair(nvl, NULL);
1660 1709              elem != NULL;
1661 1710              elem = nvlist_next_nvpair(nvl, elem)) {
1662 1711                  if (zfs_name_to_prop(nvpair_name(elem)) == ZFS_PROP_VOLSIZE &&
1663 1712                      (added_resv = zfs_add_synthetic_resv(zhp, nvl)) == -1) {
1664 1713                          goto error;
1665 1714                  }
1666 1715          }
     1716 +
     1717 +        if (added_resv != 1 &&
     1718 +            (added_resv = zfs_fix_auto_resv(zhp, nvl)) == -1) {
     1719 +                goto error;
     1720 +        }
     1721 +
1667 1722          /*
1668 1723           * Check how many properties we're setting and allocate an array to
1669 1724           * store changelist pointers for postfix().
1670 1725           */
1671 1726          nvl_len = 0;
1672 1727          for (nvpair_t *elem = nvlist_next_nvpair(nvl, NULL);
1673 1728              elem != NULL;
1674 1729              elem = nvlist_next_nvpair(nvl, elem))
1675 1730                  nvl_len++;
1676 1731          if ((cls = calloc(nvl_len, sizeof (prop_changelist_t *))) == NULL)
↓ open down ↓ 1982 lines elided ↑ open up ↑
3659 3714          /* validate parents exist */
3660 3715          if (check_parents(hdl, target, &zoned, B_FALSE, NULL) != 0)
3661 3716                  return (-1);
3662 3717  
3663 3718          (void) parent_name(target, parent, sizeof (parent));
3664 3719  
3665 3720          /* do the clone */
3666 3721  
3667 3722          if (props) {
3668 3723                  zfs_type_t type;
     3724 +
3669 3725                  if (ZFS_IS_VOLUME(zhp)) {
3670 3726                          type = ZFS_TYPE_VOLUME;
3671 3727                  } else {
3672 3728                          type = ZFS_TYPE_FILESYSTEM;
3673 3729                  }
3674 3730                  if ((props = zfs_valid_proplist(hdl, type, props, zoned,
3675 3731                      zhp, zhp->zpool_hdl, errbuf)) == NULL)
3676 3732                          return (-1);
     3733 +                if (zfs_fix_auto_resv(zhp, props) == -1) {
     3734 +                        nvlist_free(props);
     3735 +                        return (-1);
     3736 +                }
3677 3737          }
3678 3738  
3679 3739          ret = lzc_clone(target, zhp->zfs_name, props);
3680 3740          nvlist_free(props);
3681 3741  
3682 3742          if (ret != 0) {
3683 3743                  switch (errno) {
3684 3744  
3685 3745                  case ENOENT:
3686 3746                          /*
↓ open down ↓ 1310 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX