Mercurial > illumos > illumos-gate
diff usr/src/uts/common/fs/zfs/zfs_ioctl.c @ 885:d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
6348409 'zfs rename' process hangs after assigning a very long name ...
6348464 a few DMU object type macros are misnamed
author | ahrens |
---|---|
date | Thu, 10 Nov 2005 18:43:50 -0800 |
parents | 8d799fd81a9b |
children | ce99098d6a9b |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/zfs_ioctl.c Thu Nov 10 17:51:31 2005 -0800 +++ b/usr/src/uts/common/fs/zfs/zfs_ioctl.c Thu Nov 10 18:43:50 2005 -0800 @@ -700,19 +700,28 @@ static int zfs_ioc_dataset_list_next(zfs_cmd_t *zc) { - dsl_dir_t *dd; - zap_cursor_t cursor; - zap_attribute_t attr; + objset_t *os; int error; char *p; - dd = dsl_dir_open(zc->zc_name, FTAG, NULL); - if (dd == NULL) - return (ESRCH); - - if (dd->dd_phys->dd_child_dir_zapobj == 0) { - dsl_dir_close(dd, FTAG); - return (ESRCH); +retry: + error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, + DS_MODE_STANDARD | DS_MODE_READONLY, &os); + if (error != 0) { + /* + * This is ugly: dmu_objset_open() can return EBUSY if + * the objset is held exclusively. Fortunately this hold is + * only for a short while, so we retry here. + * This avoids user code having to handle EBUSY, + * for example for a "zfs list". + */ + if (error == EBUSY) { + delay(1); + goto retry; + } + if (error == ENOENT) + error = ESRCH; + return (error); } p = strrchr(zc->zc_name, '/'); @@ -721,103 +730,67 @@ p = zc->zc_name + strlen(zc->zc_name); do { - zap_cursor_init_serialized(&cursor, dd->dd_pool->dp_meta_objset, - dd->dd_phys->dd_child_dir_zapobj, zc->zc_cookie); - - error = zap_cursor_retrieve(&cursor, &attr); + error = dmu_dir_list_next(os, + sizeof (zc->zc_name) - (p - zc->zc_name), p, + NULL, &zc->zc_cookie); if (error == ENOENT) error = ESRCH; - if (error != 0) { - dsl_dir_close(dd, FTAG); - *p = '\0'; - return (error); - } - - (void) strlcpy(p, attr.za_name, sizeof (zc->zc_name) - - (p - zc->zc_name)); - - zap_cursor_advance(&cursor); - zc->zc_cookie = zap_cursor_serialize(&cursor); - - } while (!INGLOBALZONE(curproc) && + } while (error == 0 && !INGLOBALZONE(curproc) && !zone_dataset_visible(zc->zc_name, NULL)); - dsl_dir_close(dd, FTAG); + /* + * If it's a hidden dataset (ie. with a '$' in its name), don't + * try to get stats for it. Userland will skip over it. + */ + if (error == 0 && strchr(zc->zc_name, '$') == NULL) + error = zfs_ioc_objset_stats(zc); /* fill in the stats */ - /* - * If it's a hidden dataset, don't try to get stats for it. - * User land will skip over it. - */ - if (strchr(zc->zc_name, '$') != NULL) - return (0); - - error = zfs_ioc_objset_stats(zc); /* will just fill in the stats */ + dmu_objset_close(os); return (error); } static int zfs_ioc_snapshot_list_next(zfs_cmd_t *zc) { - zap_cursor_t cursor; - zap_attribute_t attr; - dsl_dataset_t *ds; + objset_t *os; int error; retry: - error = dsl_dataset_open(zc->zc_name, - DS_MODE_STANDARD | DS_MODE_READONLY, FTAG, &ds); - if (error) { + error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, + DS_MODE_STANDARD | DS_MODE_READONLY, &os); + if (error != 0) { /* - * This is ugly: dsl_dataset_open() can return EBUSY if + * This is ugly: dmu_objset_open() can return EBUSY if * the objset is held exclusively. Fortunately this hold is * only for a short while, so we retry here. * This avoids user code having to handle EBUSY, - * for example for a "zfs list -s". + * for example for a "zfs list". */ if (error == EBUSY) { delay(1); goto retry; } if (error == ENOENT) - return (ESRCH); + error = ESRCH; return (error); } - /* - * If ds_snapnames_zapobj is 0, someone is trying to iterate over - * snapshots of a snapshot. In this case, pretend that it has no - * snapshots; otherwise zap_cursor_retrieve() will blow up. - */ - if (ds->ds_phys->ds_snapnames_zapobj == 0) { - error = ESRCH; - goto out; + if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >= + sizeof (zc->zc_name)) { + dmu_objset_close(os); + return (ENAMETOOLONG); } - zap_cursor_init_serialized(&cursor, - ds->ds_dir->dd_pool->dp_meta_objset, - ds->ds_phys->ds_snapnames_zapobj, zc->zc_cookie); - - error = zap_cursor_retrieve(&cursor, &attr); + error = dmu_snapshot_list_next(os, + sizeof (zc->zc_name) - strlen(zc->zc_name), + zc->zc_name + strlen(zc->zc_name), NULL, &zc->zc_cookie); if (error == ENOENT) error = ESRCH; - if (error != 0) - goto out; - if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >= - sizeof (zc->zc_name) || - strlcat(zc->zc_name, attr.za_name, sizeof (zc->zc_name)) >= - sizeof (zc->zc_name)) { - error = ENAMETOOLONG; - goto out; - } + if (error == 0) + error = zfs_ioc_objset_stats(zc); /* fill in the stats */ - zap_cursor_advance(&cursor); - zc->zc_cookie = zap_cursor_serialize(&cursor); - - error = zfs_ioc_objset_stats(zc); /* will just fill in the stats */ - -out: - dsl_dataset_close(ds, DS_MODE_STANDARD, FTAG); + dmu_objset_close(os); return (error); }