zfs_main.c (238422) | zfs_main.c (240415) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 290 unchanged lines hidden (view full) --- 299 "\t [<perm|@setname>[,...]] <filesystem|volume>\n" 300 "\tunallow [-rld] -e [<perm|@setname>[,...]] " 301 "<filesystem|volume>\n" 302 "\tunallow [-r] -c [<perm|@setname>[,...]] " 303 "<filesystem|volume>\n" 304 "\tunallow [-r] -s @setname [<perm|@setname>[,...]] " 305 "<filesystem|volume>\n")); 306 case HELP_USERSPACE: | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 290 unchanged lines hidden (view full) --- 299 "\t [<perm|@setname>[,...]] <filesystem|volume>\n" 300 "\tunallow [-rld] -e [<perm|@setname>[,...]] " 301 "<filesystem|volume>\n" 302 "\tunallow [-r] -c [<perm|@setname>[,...]] " 303 "<filesystem|volume>\n" 304 "\tunallow [-r] -s @setname [<perm|@setname>[,...]] " 305 "<filesystem|volume>\n")); 306 case HELP_USERSPACE: |
307 return (gettext("\tuserspace [-niHp] [-o field[,...]] " 308 "[-sS field] ... [-t type[,...]]\n" 309 "\t <filesystem|snapshot>\n")); | 307 return (gettext("\tuserspace [-Hinp] [-o field[,...]] " 308 "[-s field] ...\n\t[-S field] ... " 309 "[-t type[,...]] <filesystem|snapshot>\n")); |
310 case HELP_GROUPSPACE: | 310 case HELP_GROUPSPACE: |
311 return (gettext("\tgroupspace [-niHp] [-o field[,...]] " 312 "[-sS field] ... [-t type[,...]]\n" 313 "\t <filesystem|snapshot>\n")); | 311 return (gettext("\tgroupspace [-Hinp] [-o field[,...]] " 312 "[-s field] ...\n\t[-S field] ... " 313 "[-t type[,...]] <filesystem|snapshot>\n")); |
314 case HELP_HOLD: 315 return (gettext("\thold [-r] <tag> <snapshot> ...\n")); 316 case HELP_HOLDS: 317 return (gettext("\tholds [-r] <snapshot> ...\n")); 318 case HELP_RELEASE: 319 return (gettext("\trelease [-r] <tag> <snapshot> ...\n")); 320 case HELP_DIFF: 321 return (gettext("\tdiff [-FHt] <snapshot> " --- 1741 unchanged lines hidden (view full) --- 2063 (void) printf(gettext("All filesystems are " 2064 "formatted with the current version.\n")); 2065 } 2066 } 2067 2068 return (ret); 2069} 2070 | 314 case HELP_HOLD: 315 return (gettext("\thold [-r] <tag> <snapshot> ...\n")); 316 case HELP_HOLDS: 317 return (gettext("\tholds [-r] <snapshot> ...\n")); 318 case HELP_RELEASE: 319 return (gettext("\trelease [-r] <tag> <snapshot> ...\n")); 320 case HELP_DIFF: 321 return (gettext("\tdiff [-FHt] <snapshot> " --- 1741 unchanged lines hidden (view full) --- 2063 (void) printf(gettext("All filesystems are " 2064 "formatted with the current version.\n")); 2065 } 2066 } 2067 2068 return (ret); 2069} 2070 |
2071#define USTYPE_USR_BIT (0) 2072#define USTYPE_GRP_BIT (1) 2073#define USTYPE_PSX_BIT (2) 2074#define USTYPE_SMB_BIT (3) | 2071/* 2072 * zfs userspace [-Hinp] [-o field[,...]] [-s field [-s field]...] 2073 * [-S field [-S field]...] [-t type[,...]] filesystem | snapshot 2074 * zfs groupspace [-Hinp] [-o field[,...]] [-s field [-s field]...] 2075 * [-S field [-S field]...] [-t type[,...]] filesystem | snapshot 2076 * 2077 * -H Scripted mode; elide headers and separate columns by tabs. 2078 * -i Translate SID to POSIX ID. 2079 * -n Print numeric ID instead of user/group name. 2080 * -o Control which fields to display. 2081 * -p Use exact (parseable) numeric output. 2082 * -s Specify sort columns, descending order. 2083 * -S Specify sort columns, ascending order. 2084 * -t Control which object types to display. 2085 * 2086 * Displays space consumed by, and quotas on, each user in the specified 2087 * filesystem or snapshot. 2088 */ |
2075 | 2089 |
2076#define USTYPE_USR (1 << USTYPE_USR_BIT) 2077#define USTYPE_GRP (1 << USTYPE_GRP_BIT) | 2090/* us_field_types, us_field_hdr and us_field_names should be kept in sync */ 2091enum us_field_types { 2092 USFIELD_TYPE, 2093 USFIELD_NAME, 2094 USFIELD_USED, 2095 USFIELD_QUOTA 2096}; 2097static char *us_field_hdr[] = { "TYPE", "NAME", "USED", "QUOTA" }; 2098static char *us_field_names[] = { "type", "name", "used", "quota" }; 2099#define USFIELD_LAST (sizeof (us_field_names) / sizeof (char *)) |
2078 | 2100 |
2079#define USTYPE_PSX (1 << USTYPE_PSX_BIT) 2080#define USTYPE_SMB (1 << USTYPE_SMB_BIT) | 2101#define USTYPE_PSX_GRP (1 << 0) 2102#define USTYPE_PSX_USR (1 << 1) 2103#define USTYPE_SMB_GRP (1 << 2) 2104#define USTYPE_SMB_USR (1 << 3) 2105#define USTYPE_ALL \ 2106 (USTYPE_PSX_GRP | USTYPE_PSX_USR | USTYPE_SMB_GRP | USTYPE_SMB_USR) |
2081 | 2107 |
2082#define USTYPE_PSX_USR (USTYPE_PSX | USTYPE_USR) 2083#define USTYPE_SMB_USR (USTYPE_SMB | USTYPE_USR) 2084#define USTYPE_PSX_GRP (USTYPE_PSX | USTYPE_GRP) 2085#define USTYPE_SMB_GRP (USTYPE_SMB | USTYPE_GRP) 2086#define USTYPE_ALL (USTYPE_PSX_USR | USTYPE_SMB_USR \ 2087 | USTYPE_PSX_GRP | USTYPE_SMB_GRP) | 2108static int us_type_bits[] = { 2109 USTYPE_PSX_GRP, 2110 USTYPE_PSX_USR, 2111 USTYPE_SMB_GRP, 2112 USTYPE_SMB_USR, 2113 USTYPE_ALL 2114}; 2115static char *us_type_names[] = { "posixgroup", "posxiuser", "smbgroup", 2116 "smbuser", "all" }; |
2088 | 2117 |
2089 2090#define USPROP_USED_BIT (0) 2091#define USPROP_QUOTA_BIT (1) 2092 2093#define USPROP_USED (1 << USPROP_USED_BIT) 2094#define USPROP_QUOTA (1 << USPROP_QUOTA_BIT) 2095 | |
2096typedef struct us_node { 2097 nvlist_t *usn_nvl; 2098 uu_avl_node_t usn_avlnode; 2099 uu_list_node_t usn_listnode; 2100} us_node_t; 2101 2102typedef struct us_cbdata { | 2118typedef struct us_node { 2119 nvlist_t *usn_nvl; 2120 uu_avl_node_t usn_avlnode; 2121 uu_list_node_t usn_listnode; 2122} us_node_t; 2123 2124typedef struct us_cbdata { |
2103 nvlist_t **cb_nvlp; 2104 uu_avl_pool_t *cb_avl_pool; 2105 uu_avl_t *cb_avl; 2106 boolean_t cb_numname; 2107 boolean_t cb_nicenum; 2108 boolean_t cb_sid2posix; 2109 zfs_userquota_prop_t cb_prop; 2110 zfs_sort_column_t *cb_sortcol; 2111 size_t cb_max_typelen; 2112 size_t cb_max_namelen; 2113 size_t cb_max_usedlen; 2114 size_t cb_max_quotalen; | 2125 nvlist_t **cb_nvlp; 2126 uu_avl_pool_t *cb_avl_pool; 2127 uu_avl_t *cb_avl; 2128 boolean_t cb_numname; 2129 boolean_t cb_nicenum; 2130 boolean_t cb_sid2posix; 2131 zfs_userquota_prop_t cb_prop; 2132 zfs_sort_column_t *cb_sortcol; 2133 size_t cb_width[USFIELD_LAST]; |
2115} us_cbdata_t; 2116 | 2134} us_cbdata_t; 2135 |
2136static boolean_t us_populated = B_FALSE; 2137 |
|
2117typedef struct { 2118 zfs_sort_column_t *si_sortcol; | 2138typedef struct { 2139 zfs_sort_column_t *si_sortcol; |
2119 boolean_t si_num_name; 2120 boolean_t si_parsable; | 2140 boolean_t si_numname; |
2121} us_sort_info_t; 2122 2123static int | 2141} us_sort_info_t; 2142 2143static int |
2144us_field_index(char *field) 2145{ 2146 int i; 2147 2148 for (i = 0; i < USFIELD_LAST; i++) { 2149 if (strcmp(field, us_field_names[i]) == 0) 2150 return (i); 2151 } 2152 2153 return (-1); 2154} 2155 2156static int |
|
2124us_compare(const void *larg, const void *rarg, void *unused) 2125{ 2126 const us_node_t *l = larg; 2127 const us_node_t *r = rarg; | 2157us_compare(const void *larg, const void *rarg, void *unused) 2158{ 2159 const us_node_t *l = larg; 2160 const us_node_t *r = rarg; |
2128 int rc = 0; | |
2129 us_sort_info_t *si = (us_sort_info_t *)unused; 2130 zfs_sort_column_t *sortcol = si->si_sortcol; | 2161 us_sort_info_t *si = (us_sort_info_t *)unused; 2162 zfs_sort_column_t *sortcol = si->si_sortcol; |
2131 boolean_t num_name = si->si_num_name; | 2163 boolean_t numname = si->si_numname; |
2132 nvlist_t *lnvl = l->usn_nvl; 2133 nvlist_t *rnvl = r->usn_nvl; | 2164 nvlist_t *lnvl = l->usn_nvl; 2165 nvlist_t *rnvl = r->usn_nvl; |
2166 int rc = 0; 2167 boolean_t lvb, rvb; |
|
2134 2135 for (; sortcol != NULL; sortcol = sortcol->sc_next) { 2136 char *lvstr = ""; 2137 char *rvstr = ""; 2138 uint32_t lv32 = 0; 2139 uint32_t rv32 = 0; 2140 uint64_t lv64 = 0; 2141 uint64_t rv64 = 0; 2142 zfs_prop_t prop = sortcol->sc_prop; 2143 const char *propname = NULL; 2144 boolean_t reverse = sortcol->sc_reverse; 2145 2146 switch (prop) { 2147 case ZFS_PROP_TYPE: 2148 propname = "type"; 2149 (void) nvlist_lookup_uint32(lnvl, propname, &lv32); 2150 (void) nvlist_lookup_uint32(rnvl, propname, &rv32); 2151 if (rv32 != lv32) | 2168 2169 for (; sortcol != NULL; sortcol = sortcol->sc_next) { 2170 char *lvstr = ""; 2171 char *rvstr = ""; 2172 uint32_t lv32 = 0; 2173 uint32_t rv32 = 0; 2174 uint64_t lv64 = 0; 2175 uint64_t rv64 = 0; 2176 zfs_prop_t prop = sortcol->sc_prop; 2177 const char *propname = NULL; 2178 boolean_t reverse = sortcol->sc_reverse; 2179 2180 switch (prop) { 2181 case ZFS_PROP_TYPE: 2182 propname = "type"; 2183 (void) nvlist_lookup_uint32(lnvl, propname, &lv32); 2184 (void) nvlist_lookup_uint32(rnvl, propname, &rv32); 2185 if (rv32 != lv32) |
2152 rc = (rv32 > lv32) ? 1 : -1; | 2186 rc = (rv32 < lv32) ? 1 : -1; |
2153 break; 2154 case ZFS_PROP_NAME: 2155 propname = "name"; | 2187 break; 2188 case ZFS_PROP_NAME: 2189 propname = "name"; |
2156 if (num_name) { 2157 (void) nvlist_lookup_uint32(lnvl, propname, 2158 &lv32); 2159 (void) nvlist_lookup_uint32(rnvl, propname, 2160 &rv32); 2161 if (rv32 != lv32) 2162 rc = (rv32 > lv32) ? 1 : -1; | 2190 if (numname) { 2191 (void) nvlist_lookup_uint64(lnvl, propname, 2192 &lv64); 2193 (void) nvlist_lookup_uint64(rnvl, propname, 2194 &rv64); 2195 if (rv64 != lv64) 2196 rc = (rv64 < lv64) ? 1 : -1; |
2163 } else { 2164 (void) nvlist_lookup_string(lnvl, propname, 2165 &lvstr); 2166 (void) nvlist_lookup_string(rnvl, propname, 2167 &rvstr); 2168 rc = strcmp(lvstr, rvstr); 2169 } 2170 break; | 2197 } else { 2198 (void) nvlist_lookup_string(lnvl, propname, 2199 &lvstr); 2200 (void) nvlist_lookup_string(rnvl, propname, 2201 &rvstr); 2202 rc = strcmp(lvstr, rvstr); 2203 } 2204 break; |
2171 | |
2172 case ZFS_PROP_USED: 2173 case ZFS_PROP_QUOTA: | 2205 case ZFS_PROP_USED: 2206 case ZFS_PROP_QUOTA: |
2174 if (ZFS_PROP_USED == prop) | 2207 if (!us_populated) 2208 break; 2209 if (prop == ZFS_PROP_USED) |
2175 propname = "used"; 2176 else 2177 propname = "quota"; 2178 (void) nvlist_lookup_uint64(lnvl, propname, &lv64); 2179 (void) nvlist_lookup_uint64(rnvl, propname, &rv64); 2180 if (rv64 != lv64) | 2210 propname = "used"; 2211 else 2212 propname = "quota"; 2213 (void) nvlist_lookup_uint64(lnvl, propname, &lv64); 2214 (void) nvlist_lookup_uint64(rnvl, propname, &rv64); 2215 if (rv64 != lv64) |
2181 rc = (rv64 > lv64) ? 1 : -1; | 2216 rc = (rv64 < lv64) ? 1 : -1; 2217 break; |
2182 } 2183 | 2218 } 2219 |
2184 if (rc) | 2220 if (rc != 0) { |
2185 if (rc < 0) 2186 return (reverse ? 1 : -1); 2187 else 2188 return (reverse ? -1 : 1); | 2221 if (rc < 0) 2222 return (reverse ? 1 : -1); 2223 else 2224 return (reverse ? -1 : 1); |
2225 } |
|
2189 } 2190 | 2226 } 2227 |
2191 return (rc); | 2228 /* 2229 * If entries still seem to be the same, check if they are of the same 2230 * type (smbentity is added only if we are doing SID to POSIX ID 2231 * translation where we can have duplicate type/name combinations). 2232 */ 2233 if (nvlist_lookup_boolean_value(lnvl, "smbentity", &lvb) == 0 && 2234 nvlist_lookup_boolean_value(rnvl, "smbentity", &rvb) == 0 && 2235 lvb != rvb) 2236 return (lvb < rvb ? -1 : 1); 2237 2238 return (0); |
2192} 2193 2194static inline const char * 2195us_type2str(unsigned field_type) 2196{ 2197 switch (field_type) { 2198 case USTYPE_PSX_USR: 2199 return ("POSIX User"); 2200 case USTYPE_PSX_GRP: 2201 return ("POSIX Group"); 2202 case USTYPE_SMB_USR: 2203 return ("SMB User"); 2204 case USTYPE_SMB_GRP: 2205 return ("SMB Group"); 2206 default: 2207 return ("Undefined"); 2208 } 2209} 2210 | 2239} 2240 2241static inline const char * 2242us_type2str(unsigned field_type) 2243{ 2244 switch (field_type) { 2245 case USTYPE_PSX_USR: 2246 return ("POSIX User"); 2247 case USTYPE_PSX_GRP: 2248 return ("POSIX Group"); 2249 case USTYPE_SMB_USR: 2250 return ("SMB User"); 2251 case USTYPE_SMB_GRP: 2252 return ("SMB Group"); 2253 default: 2254 return ("Undefined"); 2255 } 2256} 2257 |
2211/* 2212 * zfs userspace 2213 */ | |
2214static int 2215userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space) 2216{ 2217 us_cbdata_t *cb = (us_cbdata_t *)arg; 2218 zfs_userquota_prop_t prop = cb->cb_prop; 2219 char *name = NULL; 2220 char *propname; | 2258static int 2259userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space) 2260{ 2261 us_cbdata_t *cb = (us_cbdata_t *)arg; 2262 zfs_userquota_prop_t prop = cb->cb_prop; 2263 char *name = NULL; 2264 char *propname; |
2221 char namebuf[32]; | |
2222 char sizebuf[32]; 2223 us_node_t *node; 2224 uu_avl_pool_t *avl_pool = cb->cb_avl_pool; 2225 uu_avl_t *avl = cb->cb_avl; 2226 uu_avl_index_t idx; 2227 nvlist_t *props; 2228 us_node_t *n; 2229 zfs_sort_column_t *sortcol = cb->cb_sortcol; 2230 unsigned type; 2231 const char *typestr; 2232 size_t namelen; 2233 size_t typelen; 2234 size_t sizelen; | 2265 char sizebuf[32]; 2266 us_node_t *node; 2267 uu_avl_pool_t *avl_pool = cb->cb_avl_pool; 2268 uu_avl_t *avl = cb->cb_avl; 2269 uu_avl_index_t idx; 2270 nvlist_t *props; 2271 us_node_t *n; 2272 zfs_sort_column_t *sortcol = cb->cb_sortcol; 2273 unsigned type; 2274 const char *typestr; 2275 size_t namelen; 2276 size_t typelen; 2277 size_t sizelen; |
2278 int typeidx, nameidx, sizeidx; |
|
2235 us_sort_info_t sortinfo = { sortcol, cb->cb_numname }; | 2279 us_sort_info_t sortinfo = { sortcol, cb->cb_numname }; |
2280 boolean_t smbentity = B_FALSE; |
|
2236 | 2281 |
2237 if (domain == NULL || domain[0] == '\0') { 2238 /* POSIX */ 2239 if (prop == ZFS_PROP_GROUPUSED || prop == ZFS_PROP_GROUPQUOTA) { 2240 type = USTYPE_PSX_GRP; 2241 struct group *g = getgrgid(rid); 2242 if (g) 2243 name = g->gr_name; 2244 } else { 2245 type = USTYPE_PSX_USR; 2246 struct passwd *p = getpwuid(rid); 2247 if (p) 2248 name = p->pw_name; 2249 } 2250 } else { 2251 char sid[ZFS_MAXNAMELEN+32]; | 2282 if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) 2283 nomem(); 2284 node = safe_malloc(sizeof (us_node_t)); 2285 uu_avl_node_init(node, &node->usn_avlnode, avl_pool); 2286 node->usn_nvl = props; 2287 2288 if (domain != NULL && domain[0] != '\0') { 2289 /* SMB */ 2290 char sid[ZFS_MAXNAMELEN + 32]; |
2252 uid_t id; 2253 uint64_t classes; 2254#ifdef sun | 2291 uid_t id; 2292 uint64_t classes; 2293#ifdef sun |
2255 int err = 0; | 2294 int err; |
2256 directory_error_t e; 2257#endif 2258 | 2295 directory_error_t e; 2296#endif 2297 |
2298 smbentity = B_TRUE; 2299 |
|
2259 (void) snprintf(sid, sizeof (sid), "%s-%u", domain, rid); | 2300 (void) snprintf(sid, sizeof (sid), "%s-%u", domain, rid); |
2260 /* SMB */ | 2301 |
2261 if (prop == ZFS_PROP_GROUPUSED || prop == ZFS_PROP_GROUPQUOTA) { 2262 type = USTYPE_SMB_GRP; 2263#ifdef sun 2264 err = sid_to_id(sid, B_FALSE, &id); 2265#endif 2266 } else { 2267 type = USTYPE_SMB_USR; 2268#ifdef sun 2269 err = sid_to_id(sid, B_TRUE, &id); 2270#endif 2271 } 2272 2273#ifdef sun 2274 if (err == 0) { 2275 rid = id; | 2302 if (prop == ZFS_PROP_GROUPUSED || prop == ZFS_PROP_GROUPQUOTA) { 2303 type = USTYPE_SMB_GRP; 2304#ifdef sun 2305 err = sid_to_id(sid, B_FALSE, &id); 2306#endif 2307 } else { 2308 type = USTYPE_SMB_USR; 2309#ifdef sun 2310 err = sid_to_id(sid, B_TRUE, &id); 2311#endif 2312 } 2313 2314#ifdef sun 2315 if (err == 0) { 2316 rid = id; |
2276 2277 e = directory_name_from_sid(NULL, sid, &name, &classes); 2278 if (e != NULL) { 2279 directory_error_free(e); 2280 return (NULL); | 2317 if (!cb->cb_sid2posix) { 2318 e = directory_name_from_sid(NULL, sid, &name, 2319 &classes); 2320 if (e != NULL) 2321 directory_error_free(e); 2322 if (name == NULL) 2323 name = sid; |
2281 } | 2324 } |
2282 2283 if (name == NULL) 2284 name = sid; | |
2285 } 2286#endif 2287 } 2288 | 2325 } 2326#endif 2327 } 2328 |
2289/* 2290 * if (prop == ZFS_PROP_GROUPUSED || prop == ZFS_PROP_GROUPQUOTA) 2291 * ug = "group"; 2292 * else 2293 * ug = "user"; 2294 */ | 2329 if (cb->cb_sid2posix || domain == NULL || domain[0] == '\0') { 2330 /* POSIX or -i */ 2331 if (prop == ZFS_PROP_GROUPUSED || prop == ZFS_PROP_GROUPQUOTA) { 2332 type = USTYPE_PSX_GRP; 2333 if (!cb->cb_numname) { 2334 struct group *g; |
2295 | 2335 |
2296 if (prop == ZFS_PROP_USERUSED || prop == ZFS_PROP_GROUPUSED) 2297 propname = "used"; 2298 else 2299 propname = "quota"; | 2336 if ((g = getgrgid(rid)) != NULL) 2337 name = g->gr_name; 2338 } 2339 } else { 2340 type = USTYPE_PSX_USR; 2341 if (!cb->cb_numname) { 2342 struct passwd *p; |
2300 | 2343 |
2301 (void) snprintf(namebuf, sizeof (namebuf), "%u", rid); 2302 if (name == NULL) 2303 name = namebuf; 2304 2305 if (cb->cb_nicenum) 2306 zfs_nicenum(space, sizebuf, sizeof (sizebuf)); 2307 else 2308 (void) sprintf(sizebuf, "%llu", space); 2309 2310 node = safe_malloc(sizeof (us_node_t)); 2311 uu_avl_node_init(node, &node->usn_avlnode, avl_pool); 2312 2313 if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) { 2314 free(node); 2315 return (-1); | 2344 if ((p = getpwuid(rid)) != NULL) 2345 name = p->pw_name; 2346 } 2347 } |
2316 } 2317 | 2348 } 2349 |
2350 /* 2351 * Make sure that the type/name combination is unique when doing 2352 * SID to POSIX ID translation (hence changing the type from SMB to 2353 * POSIX). 2354 */ 2355 if (cb->cb_sid2posix && 2356 nvlist_add_boolean_value(props, "smbentity", smbentity) != 0) 2357 nomem(); 2358 2359 /* Calculate/update width of TYPE field */ 2360 typestr = us_type2str(type); 2361 typelen = strlen(gettext(typestr)); 2362 typeidx = us_field_index("type"); 2363 if (typelen > cb->cb_width[typeidx]) 2364 cb->cb_width[typeidx] = typelen; |
|
2318 if (nvlist_add_uint32(props, "type", type) != 0) 2319 nomem(); 2320 | 2365 if (nvlist_add_uint32(props, "type", type) != 0) 2366 nomem(); 2367 |
2321 if (cb->cb_numname) { 2322 if (nvlist_add_uint32(props, "name", rid) != 0) | 2368 /* Calculate/update width of NAME field */ 2369 if ((cb->cb_numname && cb->cb_sid2posix) || name == NULL) { 2370 if (nvlist_add_uint64(props, "name", rid) != 0) |
2323 nomem(); | 2371 nomem(); |
2324 namelen = strlen(namebuf); | 2372 namelen = snprintf(NULL, 0, "%u", rid); |
2325 } else { 2326 if (nvlist_add_string(props, "name", name) != 0) 2327 nomem(); 2328 namelen = strlen(name); 2329 } | 2373 } else { 2374 if (nvlist_add_string(props, "name", name) != 0) 2375 nomem(); 2376 namelen = strlen(name); 2377 } |
2378 nameidx = us_field_index("name"); 2379 if (namelen > cb->cb_width[nameidx]) 2380 cb->cb_width[nameidx] = namelen; |
|
2330 | 2381 |
2331 typestr = us_type2str(type); 2332 typelen = strlen(gettext(typestr)); 2333 if (typelen > cb->cb_max_typelen) 2334 cb->cb_max_typelen = typelen; 2335 2336 if (namelen > cb->cb_max_namelen) 2337 cb->cb_max_namelen = namelen; 2338 2339 sizelen = strlen(sizebuf); 2340 if (0 == strcmp(propname, "used")) { 2341 if (sizelen > cb->cb_max_usedlen) 2342 cb->cb_max_usedlen = sizelen; 2343 } else { 2344 if (sizelen > cb->cb_max_quotalen) 2345 cb->cb_max_quotalen = sizelen; 2346 } 2347 2348 node->usn_nvl = props; 2349 2350 n = uu_avl_find(avl, node, &sortinfo, &idx); 2351 if (n == NULL) | 2382 /* 2383 * Check if this type/name combination is in the list and update it; 2384 * otherwise add new node to the list. 2385 */ 2386 if ((n = uu_avl_find(avl, node, &sortinfo, &idx)) == NULL) { |
2352 uu_avl_insert(avl, node, idx); | 2387 uu_avl_insert(avl, node, idx); |
2353 else { | 2388 } else { |
2354 nvlist_free(props); 2355 free(node); 2356 node = n; 2357 props = node->usn_nvl; 2358 } 2359 | 2389 nvlist_free(props); 2390 free(node); 2391 node = n; 2392 props = node->usn_nvl; 2393 } 2394 |
2395 /* Calculate/update width of USED/QUOTA fields */ 2396 if (cb->cb_nicenum) 2397 zfs_nicenum(space, sizebuf, sizeof (sizebuf)); 2398 else 2399 (void) snprintf(sizebuf, sizeof (sizebuf), "%llu", space); 2400 sizelen = strlen(sizebuf); 2401 if (prop == ZFS_PROP_USERUSED || prop == ZFS_PROP_GROUPUSED) { 2402 propname = "used"; 2403 if (!nvlist_exists(props, "quota")) 2404 (void) nvlist_add_uint64(props, "quota", 0); 2405 } else { 2406 propname = "quota"; 2407 if (!nvlist_exists(props, "used")) 2408 (void) nvlist_add_uint64(props, "used", 0); 2409 } 2410 sizeidx = us_field_index(propname); 2411 if (sizelen > cb->cb_width[sizeidx]) 2412 cb->cb_width[sizeidx] = sizelen; 2413 |
|
2360 if (nvlist_add_uint64(props, propname, space) != 0) 2361 nomem(); 2362 2363 return (0); 2364} 2365 | 2414 if (nvlist_add_uint64(props, propname, space) != 0) 2415 nomem(); 2416 2417 return (0); 2418} 2419 |
2366static inline boolean_t 2367usprop_check(zfs_userquota_prop_t p, unsigned types, unsigned props) 2368{ 2369 unsigned type; 2370 unsigned prop; 2371 2372 switch (p) { 2373 case ZFS_PROP_USERUSED: 2374 type = USTYPE_USR; 2375 prop = USPROP_USED; 2376 break; 2377 case ZFS_PROP_USERQUOTA: 2378 type = USTYPE_USR; 2379 prop = USPROP_QUOTA; 2380 break; 2381 case ZFS_PROP_GROUPUSED: 2382 type = USTYPE_GRP; 2383 prop = USPROP_USED; 2384 break; 2385 case ZFS_PROP_GROUPQUOTA: 2386 type = USTYPE_GRP; 2387 prop = USPROP_QUOTA; 2388 break; 2389 default: /* ALL */ 2390 return (B_TRUE); 2391 }; 2392 2393 return (type & types && prop & props); 2394} 2395 2396#define USFIELD_TYPE (1 << 0) 2397#define USFIELD_NAME (1 << 1) 2398#define USFIELD_USED (1 << 2) 2399#define USFIELD_QUOTA (1 << 3) 2400#define USFIELD_ALL (USFIELD_TYPE | USFIELD_NAME | USFIELD_USED | USFIELD_QUOTA) 2401 2402static int 2403parsefields(unsigned *fieldsp, char **names, unsigned *bits, size_t len) 2404{ 2405 char *field = optarg; 2406 char *delim; 2407 2408 do { 2409 int i; 2410 boolean_t found = B_FALSE; 2411 delim = strchr(field, ','); 2412 if (delim != NULL) 2413 *delim = '\0'; 2414 2415 for (i = 0; i < len; i++) 2416 if (0 == strcmp(field, names[i])) { 2417 found = B_TRUE; 2418 *fieldsp |= bits[i]; 2419 break; 2420 } 2421 2422 if (!found) { 2423 (void) fprintf(stderr, gettext("invalid type '%s'" 2424 "for -t option\n"), field); 2425 return (-1); 2426 } 2427 2428 field = delim + 1; 2429 } while (delim); 2430 2431 return (0); 2432} 2433 2434 2435static char *type_names[] = { "posixuser", "smbuser", "posixgroup", "smbgroup", 2436 "all" }; 2437static unsigned type_bits[] = { 2438 USTYPE_PSX_USR, 2439 USTYPE_SMB_USR, 2440 USTYPE_PSX_GRP, 2441 USTYPE_SMB_GRP, 2442 USTYPE_ALL 2443}; 2444 2445static char *us_field_names[] = { "type", "name", "used", "quota" }; 2446static unsigned us_field_bits[] = { 2447 USFIELD_TYPE, 2448 USFIELD_NAME, 2449 USFIELD_USED, 2450 USFIELD_QUOTA 2451}; 2452 | |
2453static void | 2420static void |
2454print_us_node(boolean_t scripted, boolean_t parseable, unsigned fields, 2455 size_t type_width, size_t name_width, size_t used_width, 2456 size_t quota_width, us_node_t *node) | 2421print_us_node(boolean_t scripted, boolean_t parsable, int *fields, int types, 2422 size_t *width, us_node_t *node) |
2457{ 2458 nvlist_t *nvl = node->usn_nvl; | 2423{ 2424 nvlist_t *nvl = node->usn_nvl; |
2459 nvpair_t *nvp = NULL; | |
2460 char valstr[ZFS_MAXNAMELEN]; 2461 boolean_t first = B_TRUE; | 2425 char valstr[ZFS_MAXNAMELEN]; 2426 boolean_t first = B_TRUE; |
2462 boolean_t quota_found = B_FALSE; | 2427 int cfield = 0; 2428 int field; 2429 uint32_t ustype; |
2463 | 2430 |
2464 if (fields & USFIELD_QUOTA && !nvlist_exists(nvl, "quota")) 2465 if (nvlist_add_string(nvl, "quota", "none") != 0) 2466 nomem(); | 2431 /* Check type */ 2432 (void) nvlist_lookup_uint32(nvl, "type", &ustype); 2433 if (!(ustype & types)) 2434 return; |
2467 | 2435 |
2468 while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { 2469 char *pname = nvpair_name(nvp); 2470 data_type_t type = nvpair_type(nvp); 2471 uint32_t val32 = 0; 2472 uint64_t val64 = 0; | 2436 while ((field = fields[cfield]) != USFIELD_LAST) { 2437 nvpair_t *nvp = NULL; 2438 data_type_t type; 2439 uint32_t val32; 2440 uint64_t val64; |
2473 char *strval = NULL; | 2441 char *strval = NULL; |
2474 unsigned field = 0; 2475 unsigned width = 0; 2476 int i; 2477 for (i = 0; i < 4; i++) { 2478 if (0 == strcmp(pname, us_field_names[i])) { 2479 field = us_field_bits[i]; | 2442 2443 while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { 2444 if (strcmp(nvpair_name(nvp), 2445 us_field_names[field]) == 0) |
2480 break; | 2446 break; |
2481 } | |
2482 } 2483 | 2447 } 2448 |
2484 if (!(field & fields)) 2485 continue; 2486 | 2449 type = nvpair_type(nvp); |
2487 switch (type) { 2488 case DATA_TYPE_UINT32: 2489 (void) nvpair_value_uint32(nvp, &val32); 2490 break; 2491 case DATA_TYPE_UINT64: 2492 (void) nvpair_value_uint64(nvp, &val64); 2493 break; 2494 case DATA_TYPE_STRING: 2495 (void) nvpair_value_string(nvp, &strval); 2496 break; 2497 default: | 2450 switch (type) { 2451 case DATA_TYPE_UINT32: 2452 (void) nvpair_value_uint32(nvp, &val32); 2453 break; 2454 case DATA_TYPE_UINT64: 2455 (void) nvpair_value_uint64(nvp, &val64); 2456 break; 2457 case DATA_TYPE_STRING: 2458 (void) nvpair_value_string(nvp, &strval); 2459 break; 2460 default: |
2498 (void) fprintf(stderr, "Invalid data type\n"); | 2461 (void) fprintf(stderr, "invalid data type\n"); |
2499 } 2500 | 2462 } 2463 |
2501 if (!first) 2502 if (scripted) 2503 (void) printf("\t"); 2504 else 2505 (void) printf(" "); 2506 | |
2507 switch (field) { 2508 case USFIELD_TYPE: 2509 strval = (char *)us_type2str(val32); | 2464 switch (field) { 2465 case USFIELD_TYPE: 2466 strval = (char *)us_type2str(val32); |
2510 width = type_width; | |
2511 break; 2512 case USFIELD_NAME: 2513 if (type == DATA_TYPE_UINT64) { 2514 (void) sprintf(valstr, "%llu", val64); 2515 strval = valstr; 2516 } | 2467 break; 2468 case USFIELD_NAME: 2469 if (type == DATA_TYPE_UINT64) { 2470 (void) sprintf(valstr, "%llu", val64); 2471 strval = valstr; 2472 } |
2517 width = name_width; | |
2518 break; 2519 case USFIELD_USED: 2520 case USFIELD_QUOTA: 2521 if (type == DATA_TYPE_UINT64) { | 2473 break; 2474 case USFIELD_USED: 2475 case USFIELD_QUOTA: 2476 if (type == DATA_TYPE_UINT64) { |
2522 (void) nvpair_value_uint64(nvp, &val64); 2523 if (parseable) | 2477 if (parsable) { |
2524 (void) sprintf(valstr, "%llu", val64); | 2478 (void) sprintf(valstr, "%llu", val64); |
2525 else | 2479 } else { |
2526 zfs_nicenum(val64, valstr, 2527 sizeof (valstr)); | 2480 zfs_nicenum(val64, valstr, 2481 sizeof (valstr)); |
2528 strval = valstr; | 2482 } 2483 if (field == USFIELD_QUOTA && 2484 strcmp(valstr, "0") == 0) 2485 strval = "none"; 2486 else 2487 strval = valstr; |
2529 } | 2488 } |
2530 2531 if (field == USFIELD_USED) 2532 width = used_width; 2533 else { 2534 quota_found = B_FALSE; 2535 width = quota_width; 2536 } 2537 | |
2538 break; 2539 } 2540 | 2489 break; 2490 } 2491 |
2541 if (field == USFIELD_QUOTA && !quota_found) 2542 (void) printf("%*s", width, strval); 2543 else { 2544 if (type == DATA_TYPE_STRING) 2545 (void) printf("%-*s", width, strval); | 2492 if (!first) { 2493 if (scripted) 2494 (void) printf("\t"); |
2546 else | 2495 else |
2547 (void) printf("%*s", width, strval); | 2496 (void) printf(" "); |
2548 } | 2497 } |
2498 if (scripted) 2499 (void) printf("%s", strval); 2500 else if (field == USFIELD_TYPE || field == USFIELD_NAME) 2501 (void) printf("%-*s", width[field], strval); 2502 else 2503 (void) printf("%*s", width[field], strval); |
|
2549 2550 first = B_FALSE; | 2504 2505 first = B_FALSE; |
2551 | 2506 cfield++; |
2552 } 2553 2554 (void) printf("\n"); 2555} 2556 2557static void | 2507 } 2508 2509 (void) printf("\n"); 2510} 2511 2512static void |
2558print_us(boolean_t scripted, boolean_t parsable, unsigned fields, 2559 unsigned type_width, unsigned name_width, unsigned used_width, 2560 unsigned quota_width, boolean_t rmnode, uu_avl_t *avl) | 2513print_us(boolean_t scripted, boolean_t parsable, int *fields, int types, 2514 size_t *width, boolean_t rmnode, uu_avl_t *avl) |
2561{ | 2515{ |
2562 static char *us_field_hdr[] = { "TYPE", "NAME", "USED", "QUOTA" }; | |
2563 us_node_t *node; 2564 const char *col; | 2516 us_node_t *node; 2517 const char *col; |
2565 int i; 2566 size_t width[4] = { type_width, name_width, used_width, quota_width }; | 2518 int cfield = 0; 2519 int field; |
2567 2568 if (!scripted) { 2569 boolean_t first = B_TRUE; | 2520 2521 if (!scripted) { 2522 boolean_t first = B_TRUE; |
2570 for (i = 0; i < 4; i++) { 2571 unsigned field = us_field_bits[i]; 2572 if (!(field & fields)) 2573 continue; | |
2574 | 2523 |
2575 col = gettext(us_field_hdr[i]); 2576 if (field == USFIELD_TYPE || field == USFIELD_NAME) 2577 (void) printf(first?"%-*s":" %-*s", width[i], 2578 col); 2579 else 2580 (void) printf(first?"%*s":" %*s", width[i], 2581 col); | 2524 while ((field = fields[cfield]) != USFIELD_LAST) { 2525 col = gettext(us_field_hdr[field]); 2526 if (field == USFIELD_TYPE || field == USFIELD_NAME) { 2527 (void) printf(first ? "%-*s" : " %-*s", 2528 width[field], col); 2529 } else { 2530 (void) printf(first ? "%*s" : " %*s", 2531 width[field], col); 2532 } |
2582 first = B_FALSE; | 2533 first = B_FALSE; |
2534 cfield++; |
|
2583 } 2584 (void) printf("\n"); 2585 } 2586 | 2535 } 2536 (void) printf("\n"); 2537 } 2538 |
2587 for (node = uu_avl_first(avl); node != NULL; 2588 node = uu_avl_next(avl, node)) { 2589 print_us_node(scripted, parsable, fields, type_width, 2590 name_width, used_width, used_width, node); | 2539 for (node = uu_avl_first(avl); node; node = uu_avl_next(avl, node)) { 2540 print_us_node(scripted, parsable, fields, types, width, node); |
2591 if (rmnode) 2592 nvlist_free(node->usn_nvl); 2593 } 2594} 2595 2596static int 2597zfs_do_userspace(int argc, char **argv) 2598{ 2599 zfs_handle_t *zhp; 2600 zfs_userquota_prop_t p; 2601 2602 uu_avl_pool_t *avl_pool; 2603 uu_avl_t *avl_tree; 2604 uu_avl_walk_t *walk; | 2541 if (rmnode) 2542 nvlist_free(node->usn_nvl); 2543 } 2544} 2545 2546static int 2547zfs_do_userspace(int argc, char **argv) 2548{ 2549 zfs_handle_t *zhp; 2550 zfs_userquota_prop_t p; 2551 2552 uu_avl_pool_t *avl_pool; 2553 uu_avl_t *avl_tree; 2554 uu_avl_walk_t *walk; |
2605 2606 char *cmd; | 2555 char *delim; 2556 char deffields[] = "type,name,used,quota"; 2557 char *ofield = NULL; 2558 char *tfield = NULL; 2559 int cfield = 0; 2560 int fields[256]; 2561 int i; |
2607 boolean_t scripted = B_FALSE; 2608 boolean_t prtnum = B_FALSE; | 2562 boolean_t scripted = B_FALSE; 2563 boolean_t prtnum = B_FALSE; |
2609 boolean_t parseable = B_FALSE; | 2564 boolean_t parsable = B_FALSE; |
2610 boolean_t sid2posix = B_FALSE; | 2565 boolean_t sid2posix = B_FALSE; |
2611 int error = 0; | 2566 int ret = 0; |
2612 int c; | 2567 int c; |
2613 zfs_sort_column_t *default_sortcol = NULL; | |
2614 zfs_sort_column_t *sortcol = NULL; | 2568 zfs_sort_column_t *sortcol = NULL; |
2615 unsigned types = USTYPE_PSX_USR | USTYPE_SMB_USR; 2616 unsigned fields = 0; 2617 unsigned props = USPROP_USED | USPROP_QUOTA; | 2569 int types = USTYPE_PSX_USR | USTYPE_SMB_USR; |
2618 us_cbdata_t cb; 2619 us_node_t *node; | 2570 us_cbdata_t cb; 2571 us_node_t *node; |
2620 boolean_t resort_avl = B_FALSE; | 2572 us_node_t *rmnode; 2573 uu_list_pool_t *listpool; 2574 uu_list_t *list; 2575 uu_avl_index_t idx = 0; 2576 uu_list_index_t idx2 = 0; |
2621 2622 if (argc < 2) 2623 usage(B_FALSE); 2624 | 2577 2578 if (argc < 2) 2579 usage(B_FALSE); 2580 |
2625 cmd = argv[0]; 2626 if (0 == strcmp(cmd, "groupspace")) 2627 /* toggle default group types */ | 2581 if (strcmp(argv[0], "groupspace") == 0) 2582 /* Toggle default group types */ |
2628 types = USTYPE_PSX_GRP | USTYPE_SMB_GRP; 2629 | 2583 types = USTYPE_PSX_GRP | USTYPE_SMB_GRP; 2584 |
2630 /* check options */ | |
2631 while ((c = getopt(argc, argv, "nHpo:s:S:t:i")) != -1) { 2632 switch (c) { 2633 case 'n': 2634 prtnum = B_TRUE; 2635 break; 2636 case 'H': 2637 scripted = B_TRUE; 2638 break; 2639 case 'p': | 2585 while ((c = getopt(argc, argv, "nHpo:s:S:t:i")) != -1) { 2586 switch (c) { 2587 case 'n': 2588 prtnum = B_TRUE; 2589 break; 2590 case 'H': 2591 scripted = B_TRUE; 2592 break; 2593 case 'p': |
2640 parseable = B_TRUE; | 2594 parsable = B_TRUE; |
2641 break; 2642 case 'o': | 2595 break; 2596 case 'o': |
2643 if (parsefields(&fields, us_field_names, us_field_bits, 2644 4) != 0) 2645 return (1); | 2597 ofield = optarg; |
2646 break; 2647 case 's': | 2598 break; 2599 case 's': |
2648 if (zfs_add_sort_column(&sortcol, optarg, 2649 B_FALSE) != 0) { 2650 (void) fprintf(stderr, 2651 gettext("invalid property '%s'\n"), optarg); 2652 usage(B_FALSE); 2653 } 2654 break; | |
2655 case 'S': 2656 if (zfs_add_sort_column(&sortcol, optarg, | 2600 case 'S': 2601 if (zfs_add_sort_column(&sortcol, optarg, |
2657 B_TRUE) != 0) { | 2602 c == 's' ? B_FALSE : B_TRUE) != 0) { |
2658 (void) fprintf(stderr, | 2603 (void) fprintf(stderr, |
2659 gettext("invalid property '%s'\n"), optarg); | 2604 gettext("invalid field '%s'\n"), optarg); |
2660 usage(B_FALSE); 2661 } 2662 break; 2663 case 't': | 2605 usage(B_FALSE); 2606 } 2607 break; 2608 case 't': |
2664 if (parsefields(&types, type_names, type_bits, 5)) 2665 return (1); | 2609 tfield = optarg; |
2666 break; 2667 case 'i': 2668 sid2posix = B_TRUE; 2669 break; 2670 case ':': 2671 (void) fprintf(stderr, gettext("missing argument for " 2672 "'%c' option\n"), optopt); 2673 usage(B_FALSE); 2674 break; 2675 case '?': 2676 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2677 optopt); 2678 usage(B_FALSE); 2679 } 2680 } 2681 2682 argc -= optind; 2683 argv += optind; 2684 | 2610 break; 2611 case 'i': 2612 sid2posix = B_TRUE; 2613 break; 2614 case ':': 2615 (void) fprintf(stderr, gettext("missing argument for " 2616 "'%c' option\n"), optopt); 2617 usage(B_FALSE); 2618 break; 2619 case '?': 2620 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2621 optopt); 2622 usage(B_FALSE); 2623 } 2624 } 2625 2626 argc -= optind; 2627 argv += optind; 2628 |
2685 /* ok, now we have sorted by default colums (type,name) avl tree */ 2686 if (sortcol) { 2687 zfs_sort_column_t *sc; 2688 for (sc = sortcol; sc; sc = sc->sc_next) { 2689 if (sc->sc_prop == ZFS_PROP_QUOTA) { 2690 resort_avl = B_TRUE; 2691 break; 2692 } 2693 } | 2629 if (argc < 1) { 2630 (void) fprintf(stderr, gettext("missing dataset name\n")); 2631 usage(B_FALSE); |
2694 } | 2632 } |
2633 if (argc > 1) { 2634 (void) fprintf(stderr, gettext("too many arguments\n")); 2635 usage(B_FALSE); 2636 } |
|
2695 | 2637 |
2696 if (!fields) 2697 fields = USFIELD_ALL; | 2638 /* Use default output fields if not specified using -o */ 2639 if (ofield == NULL) 2640 ofield = deffields; 2641 do { 2642 if ((delim = strchr(ofield, ',')) != NULL) 2643 *delim = '\0'; 2644 if ((fields[cfield++] = us_field_index(ofield)) == -1) { 2645 (void) fprintf(stderr, gettext("invalid type '%s' " 2646 "for -o option\n"), ofield); 2647 return (-1); 2648 } 2649 if (delim != NULL) 2650 ofield = delim + 1; 2651 } while (delim != NULL); 2652 fields[cfield] = USFIELD_LAST; |
2698 | 2653 |
2699 if ((zhp = zfs_open(g_zfs, argv[argc-1], ZFS_TYPE_DATASET)) == NULL) | 2654 /* Override output types (-t option) */ 2655 if (tfield != NULL) { 2656 types = 0; 2657 2658 do { 2659 boolean_t found = B_FALSE; 2660 2661 if ((delim = strchr(tfield, ',')) != NULL) 2662 *delim = '\0'; 2663 for (i = 0; i < sizeof (us_type_bits) / sizeof (int); 2664 i++) { 2665 if (strcmp(tfield, us_type_names[i]) == 0) { 2666 found = B_TRUE; 2667 types |= us_type_bits[i]; 2668 break; 2669 } 2670 } 2671 if (!found) { 2672 (void) fprintf(stderr, gettext("invalid type " 2673 "'%s' for -t option\n"), tfield); 2674 return (-1); 2675 } 2676 if (delim != NULL) 2677 tfield = delim + 1; 2678 } while (delim != NULL); 2679 } 2680 2681 if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET)) == NULL) |
2700 return (1); 2701 2702 if ((avl_pool = uu_avl_pool_create("us_avl_pool", sizeof (us_node_t), | 2682 return (1); 2683 2684 if ((avl_pool = uu_avl_pool_create("us_avl_pool", sizeof (us_node_t), |
2703 offsetof(us_node_t, usn_avlnode), 2704 us_compare, UU_DEFAULT)) == NULL) | 2685 offsetof(us_node_t, usn_avlnode), us_compare, UU_DEFAULT)) == NULL) |
2705 nomem(); 2706 if ((avl_tree = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL) 2707 nomem(); 2708 | 2686 nomem(); 2687 if ((avl_tree = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL) 2688 nomem(); 2689 |
2709 if (sortcol && !resort_avl) 2710 cb.cb_sortcol = sortcol; 2711 else { 2712 (void) zfs_add_sort_column(&default_sortcol, "type", B_FALSE); 2713 (void) zfs_add_sort_column(&default_sortcol, "name", B_FALSE); 2714 cb.cb_sortcol = default_sortcol; 2715 } | 2690 /* Always add default sorting columns */ 2691 (void) zfs_add_sort_column(&sortcol, "type", B_FALSE); 2692 (void) zfs_add_sort_column(&sortcol, "name", B_FALSE); 2693 2694 cb.cb_sortcol = sortcol; |
2716 cb.cb_numname = prtnum; | 2695 cb.cb_numname = prtnum; |
2717 cb.cb_nicenum = !parseable; | 2696 cb.cb_nicenum = !parsable; |
2718 cb.cb_avl_pool = avl_pool; 2719 cb.cb_avl = avl_tree; 2720 cb.cb_sid2posix = sid2posix; | 2697 cb.cb_avl_pool = avl_pool; 2698 cb.cb_avl = avl_tree; 2699 cb.cb_sid2posix = sid2posix; |
2721 cb.cb_max_typelen = strlen(gettext("TYPE")); 2722 cb.cb_max_namelen = strlen(gettext("NAME")); 2723 cb.cb_max_usedlen = strlen(gettext("USED")); 2724 cb.cb_max_quotalen = strlen(gettext("QUOTA")); | |
2725 | 2700 |
2701 for (i = 0; i < USFIELD_LAST; i++) 2702 cb.cb_width[i] = strlen(gettext(us_field_hdr[i])); 2703 |
|
2726 for (p = 0; p < ZFS_NUM_USERQUOTA_PROPS; p++) { | 2704 for (p = 0; p < ZFS_NUM_USERQUOTA_PROPS; p++) { |
2727 if (!usprop_check(p, types, props)) | 2705 if (((p == ZFS_PROP_USERUSED || p == ZFS_PROP_USERQUOTA) && 2706 !(types & (USTYPE_PSX_USR | USTYPE_SMB_USR))) || 2707 ((p == ZFS_PROP_GROUPUSED || p == ZFS_PROP_GROUPQUOTA) && 2708 !(types & (USTYPE_PSX_GRP | USTYPE_SMB_GRP)))) |
2728 continue; | 2709 continue; |
2729 | |
2730 cb.cb_prop = p; | 2710 cb.cb_prop = p; |
2731 error = zfs_userspace(zhp, p, userspace_cb, &cb); 2732 2733 if (error) 2734 break; | 2711 if ((ret = zfs_userspace(zhp, p, userspace_cb, &cb)) != 0) 2712 return (ret); |
2735 } 2736 | 2713 } 2714 |
2737 if (resort_avl) { 2738 us_node_t *node; 2739 us_node_t *rmnode; 2740 uu_list_pool_t *listpool; 2741 uu_list_t *list; 2742 uu_avl_index_t idx = 0; 2743 uu_list_index_t idx2 = 0; 2744 listpool = uu_list_pool_create("tmplist", sizeof (us_node_t), 2745 offsetof(us_node_t, usn_listnode), NULL, 2746 UU_DEFAULT); 2747 list = uu_list_create(listpool, NULL, UU_DEFAULT); | 2715 /* Sort the list */ 2716 if ((node = uu_avl_first(avl_tree)) == NULL) 2717 return (0); |
2748 | 2718 |
2749 node = uu_avl_first(avl_tree); 2750 uu_list_node_init(node, &node->usn_listnode, listpool); 2751 while (node != NULL) { 2752 rmnode = node; 2753 node = uu_avl_next(avl_tree, node); 2754 uu_avl_remove(avl_tree, rmnode); 2755 if (uu_list_find(list, rmnode, NULL, &idx2) == NULL) { 2756 uu_list_insert(list, rmnode, idx2); 2757 } 2758 } | 2719 us_populated = B_TRUE; |
2759 | 2720 |
2760 for (node = uu_list_first(list); node != NULL; 2761 node = uu_list_next(list, node)) { 2762 us_sort_info_t sortinfo = { sortcol, cb.cb_numname }; 2763 if (uu_avl_find(avl_tree, node, &sortinfo, &idx) == 2764 NULL) 2765 uu_avl_insert(avl_tree, node, idx); 2766 } | 2721 listpool = uu_list_pool_create("tmplist", sizeof (us_node_t), 2722 offsetof(us_node_t, usn_listnode), NULL, UU_DEFAULT); 2723 list = uu_list_create(listpool, NULL, UU_DEFAULT); 2724 uu_list_node_init(node, &node->usn_listnode, listpool); |
2767 | 2725 |
2768 uu_list_destroy(list); | 2726 while (node != NULL) { 2727 rmnode = node; 2728 node = uu_avl_next(avl_tree, node); 2729 uu_avl_remove(avl_tree, rmnode); 2730 if (uu_list_find(list, rmnode, NULL, &idx2) == NULL) 2731 uu_list_insert(list, rmnode, idx2); |
2769 } 2770 | 2732 } 2733 |
2771 /* print & free node`s nvlist memory */ 2772 print_us(scripted, parseable, fields, cb.cb_max_typelen, 2773 cb.cb_max_namelen, cb.cb_max_usedlen, 2774 cb.cb_max_quotalen, B_TRUE, cb.cb_avl); | 2734 for (node = uu_list_first(list); node != NULL; 2735 node = uu_list_next(list, node)) { 2736 us_sort_info_t sortinfo = { sortcol, cb.cb_numname }; |
2775 | 2737 |
2776 if (sortcol) 2777 zfs_free_sort_columns(sortcol); 2778 zfs_free_sort_columns(default_sortcol); | 2738 if (uu_avl_find(avl_tree, node, &sortinfo, &idx) == NULL) 2739 uu_avl_insert(avl_tree, node, idx); 2740 } |
2779 | 2741 |
2780 /* 2781 * Finally, clean up the AVL tree. 2782 */ | 2742 uu_list_destroy(list); 2743 uu_list_pool_destroy(listpool); 2744 2745 /* Print and free node nvlist memory */ 2746 print_us(scripted, parsable, fields, types, cb.cb_width, B_TRUE, 2747 cb.cb_avl); 2748 2749 zfs_free_sort_columns(sortcol); 2750 2751 /* Clean up the AVL tree */ |
2783 if ((walk = uu_avl_walk_start(cb.cb_avl, UU_WALK_ROBUST)) == NULL) 2784 nomem(); 2785 2786 while ((node = uu_avl_walk_next(walk)) != NULL) { 2787 uu_avl_remove(cb.cb_avl, node); 2788 free(node); 2789 } 2790 2791 uu_avl_walk_end(walk); 2792 uu_avl_destroy(avl_tree); 2793 uu_avl_pool_destroy(avl_pool); 2794 | 2752 if ((walk = uu_avl_walk_start(cb.cb_avl, UU_WALK_ROBUST)) == NULL) 2753 nomem(); 2754 2755 while ((node = uu_avl_walk_next(walk)) != NULL) { 2756 uu_avl_remove(cb.cb_avl, node); 2757 free(node); 2758 } 2759 2760 uu_avl_walk_end(walk); 2761 uu_avl_destroy(avl_tree); 2762 uu_avl_pool_destroy(avl_pool); 2763 |
2795 return (error); | 2764 return (ret); |
2796} 2797 2798/* 2799 * list [-r][-d max] [-H] [-o property[,property]...] [-t type[,type]...] 2800 * [-s property [-s property]...] [-S property [-S property]...] 2801 * <dataset> ... 2802 * 2803 * -r Recurse over all children --- 3901 unchanged lines hidden --- | 2765} 2766 2767/* 2768 * list [-r][-d max] [-H] [-o property[,property]...] [-t type[,type]...] 2769 * [-s property [-s property]...] [-S property [-S property]...] 2770 * <dataset> ... 2771 * 2772 * -r Recurse over all children --- 3901 unchanged lines hidden --- |