247 getcomponent(const char *path, char *component, const char **nextp) |
247 getcomponent(const char *path, char *component, const char **nextp) |
248 { |
248 { |
249 char *p; |
249 char *p; |
250 |
250 |
251 if ((path == NULL) || (path[0] == '\0')) |
251 if ((path == NULL) || (path[0] == '\0')) |
252 return (ENOENT); |
252 return (SET_ERROR(ENOENT)); |
253 /* This would be a good place to reserve some namespace... */ |
253 /* This would be a good place to reserve some namespace... */ |
254 p = strpbrk(path, "/@"); |
254 p = strpbrk(path, "/@"); |
255 if (p && (p[1] == '/' || p[1] == '@')) { |
255 if (p && (p[1] == '/' || p[1] == '@')) { |
256 /* two separators in a row */ |
256 /* two separators in a row */ |
257 return (EINVAL); |
257 return (SET_ERROR(EINVAL)); |
258 } |
258 } |
259 if (p == NULL || p == path) { |
259 if (p == NULL || p == path) { |
260 /* |
260 /* |
261 * if the first thing is an @ or /, it had better be an |
261 * if the first thing is an @ or /, it had better be an |
262 * @ and it had better not have any more ats or slashes, |
262 * @ and it had better not have any more ats or slashes, |
263 * and it had better have something after the @. |
263 * and it had better have something after the @. |
264 */ |
264 */ |
265 if (p != NULL && |
265 if (p != NULL && |
266 (p[0] != '@' || strpbrk(path+1, "/@") || p[1] == '\0')) |
266 (p[0] != '@' || strpbrk(path+1, "/@") || p[1] == '\0')) |
267 return (EINVAL); |
267 return (SET_ERROR(EINVAL)); |
268 if (strlen(path) >= MAXNAMELEN) |
268 if (strlen(path) >= MAXNAMELEN) |
269 return (ENAMETOOLONG); |
269 return (SET_ERROR(ENAMETOOLONG)); |
270 (void) strcpy(component, path); |
270 (void) strcpy(component, path); |
271 p = NULL; |
271 p = NULL; |
272 } else if (p[0] == '/') { |
272 } else if (p[0] == '/') { |
273 if (p - path >= MAXNAMELEN) |
273 if (p - path >= MAXNAMELEN) |
274 return (ENAMETOOLONG); |
274 return (SET_ERROR(ENAMETOOLONG)); |
275 (void) strncpy(component, path, p - path); |
275 (void) strncpy(component, path, p - path); |
276 component[p - path] = '\0'; |
276 component[p - path] = '\0'; |
277 p++; |
277 p++; |
278 } else if (p[0] == '@') { |
278 } else if (p[0] == '@') { |
279 /* |
279 /* |
280 * if the next separator is an @, there better not be |
280 * if the next separator is an @, there better not be |
281 * any more slashes. |
281 * any more slashes. |
282 */ |
282 */ |
283 if (strchr(path, '/')) |
283 if (strchr(path, '/')) |
284 return (EINVAL); |
284 return (SET_ERROR(EINVAL)); |
285 if (p - path >= MAXNAMELEN) |
285 if (p - path >= MAXNAMELEN) |
286 return (ENAMETOOLONG); |
286 return (SET_ERROR(ENAMETOOLONG)); |
287 (void) strncpy(component, path, p - path); |
287 (void) strncpy(component, path, p - path); |
288 component[p - path] = '\0'; |
288 component[p - path] = '\0'; |
289 } else { |
289 } else { |
290 panic("invalid p=%p", (void *)p); |
290 panic("invalid p=%p", (void *)p); |
291 } |
291 } |
315 return (err); |
315 return (err); |
316 |
316 |
317 /* Make sure the name is in the specified pool. */ |
317 /* Make sure the name is in the specified pool. */ |
318 spaname = spa_name(dp->dp_spa); |
318 spaname = spa_name(dp->dp_spa); |
319 if (strcmp(buf, spaname) != 0) |
319 if (strcmp(buf, spaname) != 0) |
320 return (EINVAL); |
320 return (SET_ERROR(EINVAL)); |
321 |
321 |
322 ASSERT(dsl_pool_config_held(dp)); |
322 ASSERT(dsl_pool_config_held(dp)); |
323 |
323 |
324 err = dsl_dir_hold_obj(dp, dp->dp_root_dir_obj, NULL, tag, &dd); |
324 err = dsl_dir_hold_obj(dp, dp->dp_root_dir_obj, NULL, tag, &dd); |
325 if (err != 0) { |
325 if (err != 0) { |
675 dprintf_dd(dd, "failing: used=%lluK inflight = %lluK " |
675 dprintf_dd(dd, "failing: used=%lluK inflight = %lluK " |
676 "quota=%lluK tr=%lluK err=%d\n", |
676 "quota=%lluK tr=%lluK err=%d\n", |
677 used_on_disk>>10, est_inflight>>10, |
677 used_on_disk>>10, est_inflight>>10, |
678 quota>>10, asize>>10, retval); |
678 quota>>10, asize>>10, retval); |
679 mutex_exit(&dd->dd_lock); |
679 mutex_exit(&dd->dd_lock); |
680 return (retval); |
680 return (SET_ERROR(retval)); |
681 } |
681 } |
682 |
682 |
683 /* We need to up our estimated delta before dropping dd_lock */ |
683 /* We need to up our estimated delta before dropping dd_lock */ |
684 dd->dd_tempreserved[txgidx] += asize; |
684 dd->dd_tempreserved[txgidx] += asize; |
685 |
685 |
948 */ |
948 */ |
949 towrite = dsl_dir_space_towrite(ds->ds_dir); |
949 towrite = dsl_dir_space_towrite(ds->ds_dir); |
950 if ((dmu_tx_is_syncing(tx) || towrite == 0) && |
950 if ((dmu_tx_is_syncing(tx) || towrite == 0) && |
951 (newval < ds->ds_dir->dd_phys->dd_reserved || |
951 (newval < ds->ds_dir->dd_phys->dd_reserved || |
952 newval < ds->ds_dir->dd_phys->dd_used_bytes + towrite)) { |
952 newval < ds->ds_dir->dd_phys->dd_used_bytes + towrite)) { |
953 error = ENOSPC; |
953 error = SET_ERROR(ENOSPC); |
954 } |
954 } |
955 mutex_exit(&ds->ds_dir->dd_lock); |
955 mutex_exit(&ds->ds_dir->dd_lock); |
956 dsl_dataset_rele(ds, FTAG); |
956 dsl_dataset_rele(ds, FTAG); |
957 return (error); |
957 return (error); |
958 } |
958 } |
1181 |
1181 |
1182 /* can't rename to different pool */ |
1182 /* can't rename to different pool */ |
1183 if (dd->dd_pool != newparent->dd_pool) { |
1183 if (dd->dd_pool != newparent->dd_pool) { |
1184 dsl_dir_rele(newparent, FTAG); |
1184 dsl_dir_rele(newparent, FTAG); |
1185 dsl_dir_rele(dd, FTAG); |
1185 dsl_dir_rele(dd, FTAG); |
1186 return (ENXIO); |
1186 return (SET_ERROR(ENXIO)); |
1187 } |
1187 } |
1188 |
1188 |
1189 /* new name should not already exist */ |
1189 /* new name should not already exist */ |
1190 if (mynewname == NULL) { |
1190 if (mynewname == NULL) { |
1191 dsl_dir_rele(newparent, FTAG); |
1191 dsl_dir_rele(newparent, FTAG); |
1192 dsl_dir_rele(dd, FTAG); |
1192 dsl_dir_rele(dd, FTAG); |
1193 return (EEXIST); |
1193 return (SET_ERROR(EEXIST)); |
1194 } |
1194 } |
1195 |
1195 |
1196 /* if the name length is growing, validate child name lengths */ |
1196 /* if the name length is growing, validate child name lengths */ |
1197 if (delta > 0) { |
1197 if (delta > 0) { |
1198 error = dmu_objset_find_dp(dp, dd->dd_object, dsl_valid_rename, |
1198 error = dmu_objset_find_dp(dp, dd->dd_object, dsl_valid_rename, |
1211 |
1211 |
1212 /* no rename into our descendant */ |
1212 /* no rename into our descendant */ |
1213 if (closest_common_ancestor(dd, newparent) == dd) { |
1213 if (closest_common_ancestor(dd, newparent) == dd) { |
1214 dsl_dir_rele(newparent, FTAG); |
1214 dsl_dir_rele(newparent, FTAG); |
1215 dsl_dir_rele(dd, FTAG); |
1215 dsl_dir_rele(dd, FTAG); |
1216 return (EINVAL); |
1216 return (SET_ERROR(EINVAL)); |
1217 } |
1217 } |
1218 |
1218 |
1219 error = dsl_dir_transfer_possible(dd->dd_parent, |
1219 error = dsl_dir_transfer_possible(dd->dd_parent, |
1220 newparent, myspace); |
1220 newparent, myspace); |
1221 if (error != 0) { |
1221 if (error != 0) { |