1 /* 2 * Copyright (c) 2011-2014 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthew Dillon <dillon@dragonflybsd.org> 6 * by Venkatesh Srinivas <vsrinivas@dragonflybsd.org> 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 3. Neither the name of The DragonFly Project nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific, prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 32 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 /* 36 * Ioctl Functions. 37 * 38 * WARNING! The ioctl functions which manipulate the connection state need 39 * to be able to run without deadlock on the volume's chain lock. 40 * Most of these functions use a separate lock. 41 */ 42 43 #include "hammer2.h" 44 45 static int hammer2_ioctl_version_get(hammer2_inode_t *ip, void *data); 46 static int hammer2_ioctl_recluster(hammer2_inode_t *ip, void *data); 47 static int hammer2_ioctl_remote_scan(hammer2_inode_t *ip, void *data); 48 static int hammer2_ioctl_remote_add(hammer2_inode_t *ip, void *data); 49 static int hammer2_ioctl_remote_del(hammer2_inode_t *ip, void *data); 50 static int hammer2_ioctl_remote_rep(hammer2_inode_t *ip, void *data); 51 static int hammer2_ioctl_socket_get(hammer2_inode_t *ip, void *data); 52 static int hammer2_ioctl_socket_set(hammer2_inode_t *ip, void *data); 53 static int hammer2_ioctl_pfs_get(hammer2_inode_t *ip, void *data); 54 static int hammer2_ioctl_pfs_lookup(hammer2_inode_t *ip, void *data); 55 static int hammer2_ioctl_pfs_create(hammer2_inode_t *ip, void *data); 56 static int hammer2_ioctl_pfs_snapshot(hammer2_inode_t *ip, void *data); 57 static int hammer2_ioctl_pfs_delete(hammer2_inode_t *ip, void *data); 58 static int hammer2_ioctl_inode_get(hammer2_inode_t *ip, void *data); 59 static int hammer2_ioctl_inode_set(hammer2_inode_t *ip, void *data); 60 static int hammer2_ioctl_debug_dump(hammer2_inode_t *ip); 61 //static int hammer2_ioctl_inode_comp_set(hammer2_inode_t *ip, void *data); 62 //static int hammer2_ioctl_inode_comp_rec_set(hammer2_inode_t *ip, void *data); 63 //static int hammer2_ioctl_inode_comp_rec_set2(hammer2_inode_t *ip, void *data); 64 65 int 66 hammer2_ioctl(hammer2_inode_t *ip, u_long com, void *data, int fflag, 67 struct ucred *cred) 68 { 69 int error; 70 71 /* 72 * Standard root cred checks, will be selectively ignored below 73 * for ioctls that do not require root creds. 74 */ 75 error = priv_check_cred(cred, PRIV_HAMMER_IOCTL, 0); 76 77 switch(com) { 78 case HAMMER2IOC_VERSION_GET: 79 error = hammer2_ioctl_version_get(ip, data); 80 break; 81 case HAMMER2IOC_RECLUSTER: 82 if (error == 0) 83 error = hammer2_ioctl_recluster(ip, data); 84 break; 85 case HAMMER2IOC_REMOTE_SCAN: 86 if (error == 0) 87 error = hammer2_ioctl_remote_scan(ip, data); 88 break; 89 case HAMMER2IOC_REMOTE_ADD: 90 if (error == 0) 91 error = hammer2_ioctl_remote_add(ip, data); 92 break; 93 case HAMMER2IOC_REMOTE_DEL: 94 if (error == 0) 95 error = hammer2_ioctl_remote_del(ip, data); 96 break; 97 case HAMMER2IOC_REMOTE_REP: 98 if (error == 0) 99 error = hammer2_ioctl_remote_rep(ip, data); 100 break; 101 case HAMMER2IOC_SOCKET_GET: 102 if (error == 0) 103 error = hammer2_ioctl_socket_get(ip, data); 104 break; 105 case HAMMER2IOC_SOCKET_SET: 106 if (error == 0) 107 error = hammer2_ioctl_socket_set(ip, data); 108 break; 109 case HAMMER2IOC_PFS_GET: 110 if (error == 0) 111 error = hammer2_ioctl_pfs_get(ip, data); 112 break; 113 case HAMMER2IOC_PFS_LOOKUP: 114 if (error == 0) 115 error = hammer2_ioctl_pfs_lookup(ip, data); 116 break; 117 case HAMMER2IOC_PFS_CREATE: 118 if (error == 0) 119 error = hammer2_ioctl_pfs_create(ip, data); 120 break; 121 case HAMMER2IOC_PFS_DELETE: 122 if (error == 0) 123 error = hammer2_ioctl_pfs_delete(ip, data); 124 break; 125 case HAMMER2IOC_PFS_SNAPSHOT: 126 if (error == 0) 127 error = hammer2_ioctl_pfs_snapshot(ip, data); 128 break; 129 case HAMMER2IOC_INODE_GET: 130 error = hammer2_ioctl_inode_get(ip, data); 131 break; 132 case HAMMER2IOC_INODE_SET: 133 if (error == 0) 134 error = hammer2_ioctl_inode_set(ip, data); 135 break; 136 /*case HAMMER2IOC_INODE_COMP_SET: 137 error = hammer2_ioctl_inode_comp_set(ip, data); 138 break; 139 case HAMMER2IOC_INODE_COMP_REC_SET: 140 error = hammer2_ioctl_inode_comp_rec_set(ip, data); 141 break; 142 case HAMMER2IOC_INODE_COMP_REC_SET2: 143 error = hammer2_ioctl_inode_comp_rec_set2(ip, data); 144 break;*/ 145 case HAMMER2IOC_DEBUG_DUMP: 146 error = hammer2_ioctl_debug_dump(ip); 147 break; 148 default: 149 error = EOPNOTSUPP; 150 break; 151 } 152 return (error); 153 } 154 155 /* 156 * Retrieve version and basic info 157 */ 158 static int 159 hammer2_ioctl_version_get(hammer2_inode_t *ip, void *data) 160 { 161 hammer2_mount_t *hmp = ip->pmp->iroot->cluster.focus->hmp; 162 hammer2_ioc_version_t *version = data; 163 164 version->version = hmp->voldata.version; 165 return 0; 166 } 167 168 static int 169 hammer2_ioctl_recluster(hammer2_inode_t *ip, void *data) 170 { 171 hammer2_ioc_recluster_t *recl = data; 172 struct file *fp; 173 174 fp = holdfp(curproc->p_fd, recl->fd, -1); 175 if (fp) { 176 kprintf("reconnect to cluster\n"); 177 hammer2_cluster_reconnect(ip->pmp, fp); 178 return 0; 179 } else { 180 return EINVAL; 181 } 182 } 183 184 /* 185 * Retrieve information about a remote 186 */ 187 static int 188 hammer2_ioctl_remote_scan(hammer2_inode_t *ip, void *data) 189 { 190 hammer2_mount_t *hmp = ip->pmp->iroot->cluster.focus->hmp; 191 hammer2_ioc_remote_t *remote = data; 192 int copyid = remote->copyid; 193 194 if (copyid < 0 || copyid >= HAMMER2_COPYID_COUNT) 195 return (EINVAL); 196 197 hammer2_voldata_lock(hmp); 198 remote->copy1 = hmp->voldata.copyinfo[copyid]; 199 hammer2_voldata_unlock(hmp); 200 201 /* 202 * Adjust nextid (GET only) 203 */ 204 while (++copyid < HAMMER2_COPYID_COUNT && 205 hmp->voldata.copyinfo[copyid].copyid == 0) { 206 ; 207 } 208 if (copyid == HAMMER2_COPYID_COUNT) 209 remote->nextid = -1; 210 else 211 remote->nextid = copyid; 212 213 return(0); 214 } 215 216 /* 217 * Add new remote entry 218 */ 219 static int 220 hammer2_ioctl_remote_add(hammer2_inode_t *ip, void *data) 221 { 222 hammer2_ioc_remote_t *remote = data; 223 hammer2_pfsmount_t *pmp = ip->pmp; 224 hammer2_mount_t *hmp; 225 int copyid = remote->copyid; 226 int error = 0; 227 228 if (copyid >= HAMMER2_COPYID_COUNT) 229 return (EINVAL); 230 231 hmp = pmp->iroot->cluster.focus->hmp; /* XXX */ 232 hammer2_voldata_lock(hmp); 233 if (copyid < 0) { 234 for (copyid = 1; copyid < HAMMER2_COPYID_COUNT; ++copyid) { 235 if (hmp->voldata.copyinfo[copyid].copyid == 0) 236 break; 237 } 238 if (copyid == HAMMER2_COPYID_COUNT) { 239 error = ENOSPC; 240 goto failed; 241 } 242 } 243 hammer2_voldata_modify(hmp); 244 remote->copy1.copyid = copyid; 245 hmp->voldata.copyinfo[copyid] = remote->copy1; 246 hammer2_volconf_update(pmp, copyid); 247 failed: 248 hammer2_voldata_unlock(hmp); 249 return (error); 250 } 251 252 /* 253 * Delete existing remote entry 254 */ 255 static int 256 hammer2_ioctl_remote_del(hammer2_inode_t *ip, void *data) 257 { 258 hammer2_ioc_remote_t *remote = data; 259 hammer2_pfsmount_t *pmp = ip->pmp; 260 hammer2_mount_t *hmp; 261 int copyid = remote->copyid; 262 int error = 0; 263 264 hmp = pmp->iroot->cluster.focus->hmp; /* XXX */ 265 if (copyid >= HAMMER2_COPYID_COUNT) 266 return (EINVAL); 267 remote->copy1.path[sizeof(remote->copy1.path) - 1] = 0; 268 hammer2_voldata_lock(hmp); 269 if (copyid < 0) { 270 for (copyid = 1; copyid < HAMMER2_COPYID_COUNT; ++copyid) { 271 if (hmp->voldata.copyinfo[copyid].copyid == 0) 272 continue; 273 if (strcmp(remote->copy1.path, 274 hmp->voldata.copyinfo[copyid].path) == 0) { 275 break; 276 } 277 } 278 if (copyid == HAMMER2_COPYID_COUNT) { 279 error = ENOENT; 280 goto failed; 281 } 282 } 283 hammer2_voldata_modify(hmp); 284 hmp->voldata.copyinfo[copyid].copyid = 0; 285 hammer2_volconf_update(pmp, copyid); 286 failed: 287 hammer2_voldata_unlock(hmp); 288 return (error); 289 } 290 291 /* 292 * Replace existing remote entry 293 */ 294 static int 295 hammer2_ioctl_remote_rep(hammer2_inode_t *ip, void *data) 296 { 297 hammer2_ioc_remote_t *remote = data; 298 hammer2_mount_t *hmp; 299 int copyid = remote->copyid; 300 301 hmp = ip->pmp->iroot->cluster.focus->hmp; /* XXX */ 302 303 if (copyid < 0 || copyid >= HAMMER2_COPYID_COUNT) 304 return (EINVAL); 305 306 hammer2_voldata_lock(hmp); 307 hammer2_voldata_modify(hmp); 308 /*hammer2_volconf_update(pmp, copyid);*/ 309 hammer2_voldata_unlock(hmp); 310 311 return(0); 312 } 313 314 /* 315 * Retrieve communications socket 316 */ 317 static int 318 hammer2_ioctl_socket_get(hammer2_inode_t *ip, void *data) 319 { 320 return (EOPNOTSUPP); 321 } 322 323 /* 324 * Set communications socket for connection 325 */ 326 static int 327 hammer2_ioctl_socket_set(hammer2_inode_t *ip, void *data) 328 { 329 hammer2_ioc_remote_t *remote = data; 330 hammer2_mount_t *hmp; 331 int copyid = remote->copyid; 332 333 hmp = ip->pmp->iroot->cluster.focus->hmp; /* XXX */ 334 if (copyid < 0 || copyid >= HAMMER2_COPYID_COUNT) 335 return (EINVAL); 336 337 hammer2_voldata_lock(hmp); 338 hammer2_voldata_unlock(hmp); 339 340 return(0); 341 } 342 343 /* 344 * Used to scan and retrieve PFS information. PFS's are directories under 345 * the super-root. 346 * 347 * To scan PFSs pass name_key=0. The function will scan for the next 348 * PFS and set all fields, as well as set name_next to the next key. 349 * When no PFSs remain, name_next is set to (hammer2_key_t)-1. 350 * 351 * To retrieve the PFS associated with the file descriptor, pass 352 * name_key set to (hammer2_key_t)-1. 353 */ 354 static int 355 hammer2_ioctl_pfs_get(hammer2_inode_t *ip, void *data) 356 { 357 const hammer2_inode_data_t *ipdata; 358 hammer2_mount_t *hmp; 359 hammer2_ioc_pfs_t *pfs; 360 hammer2_cluster_t *cparent; 361 hammer2_cluster_t *rcluster; 362 hammer2_cluster_t *cluster; 363 hammer2_key_t key_next; 364 int error; 365 int ddflag; 366 367 error = 0; 368 hmp = ip->pmp->iroot->cluster.focus->hmp; /* XXX */ 369 pfs = data; 370 cparent = hammer2_inode_lock_ex(hmp->spmp->iroot); 371 rcluster = hammer2_inode_lock_ex(ip->pmp->iroot); 372 373 /* 374 * Search for the first key or specific key. Remember that keys 375 * can be returned in any order. 376 */ 377 if (pfs->name_key == 0) { 378 cluster = hammer2_cluster_lookup(cparent, &key_next, 379 0, (hammer2_key_t)-1, 380 0, &ddflag); 381 } else if (pfs->name_key == (hammer2_key_t)-1) { 382 ipdata = &hammer2_cluster_data(rcluster)->ipdata; 383 cluster = hammer2_cluster_lookup(cparent, &key_next, 384 ipdata->name_key, 385 ipdata->name_key, 386 0, &ddflag); 387 ipdata = NULL; /* safety */ 388 } else { 389 cluster = hammer2_cluster_lookup(cparent, &key_next, 390 pfs->name_key, pfs->name_key, 391 0, &ddflag); 392 } 393 hammer2_inode_unlock_ex(ip->pmp->iroot, rcluster); 394 395 while (cluster && 396 hammer2_cluster_type(cluster) != HAMMER2_BREF_TYPE_INODE) { 397 cluster = hammer2_cluster_next(cparent, cluster, &key_next, 398 key_next, (hammer2_key_t)-1, 399 0); 400 } 401 if (cluster) { 402 /* 403 * Load the data being returned by the ioctl. 404 */ 405 ipdata = &hammer2_cluster_data(cluster)->ipdata; 406 pfs->name_key = ipdata->name_key; 407 pfs->pfs_type = ipdata->pfs_type; 408 pfs->pfs_clid = ipdata->pfs_clid; 409 pfs->pfs_fsid = ipdata->pfs_fsid; 410 KKASSERT(ipdata->name_len < sizeof(pfs->name)); 411 bcopy(ipdata->filename, pfs->name, ipdata->name_len); 412 pfs->name[ipdata->name_len] = 0; 413 ipdata = NULL; /* safety */ 414 415 /* 416 * Calculate the next field 417 */ 418 do { 419 cluster = hammer2_cluster_next(cparent, cluster, 420 &key_next, 421 0, (hammer2_key_t)-1, 422 0); 423 } while (cluster && 424 hammer2_cluster_type(cluster) != 425 HAMMER2_BREF_TYPE_INODE); 426 if (cluster) { 427 ipdata = &hammer2_cluster_data(cluster)->ipdata; 428 pfs->name_next = ipdata->name_key; 429 hammer2_cluster_unlock(cluster); 430 } else { 431 pfs->name_next = (hammer2_key_t)-1; 432 } 433 } else { 434 pfs->name_next = (hammer2_key_t)-1; 435 error = ENOENT; 436 } 437 hammer2_inode_unlock_ex(hmp->spmp->iroot, cparent); 438 439 return (error); 440 } 441 442 /* 443 * Find a specific PFS by name 444 */ 445 static int 446 hammer2_ioctl_pfs_lookup(hammer2_inode_t *ip, void *data) 447 { 448 const hammer2_inode_data_t *ipdata; 449 hammer2_mount_t *hmp; 450 hammer2_ioc_pfs_t *pfs; 451 hammer2_cluster_t *cparent; 452 hammer2_cluster_t *cluster; 453 hammer2_key_t key_next; 454 hammer2_key_t lhc; 455 int error; 456 int ddflag; 457 size_t len; 458 459 error = 0; 460 hmp = ip->pmp->iroot->cluster.focus->hmp; /* XXX */ 461 pfs = data; 462 cparent = hammer2_inode_lock_sh(hmp->spmp->iroot); 463 464 pfs->name[sizeof(pfs->name) - 1] = 0; 465 len = strlen(pfs->name); 466 lhc = hammer2_dirhash(pfs->name, len); 467 468 cluster = hammer2_cluster_lookup(cparent, &key_next, 469 lhc, lhc + HAMMER2_DIRHASH_LOMASK, 470 HAMMER2_LOOKUP_SHARED, &ddflag); 471 while (cluster) { 472 if (hammer2_cluster_type(cluster) == HAMMER2_BREF_TYPE_INODE) { 473 ipdata = &hammer2_cluster_data(cluster)->ipdata; 474 if (ipdata->name_len == len && 475 bcmp(ipdata->filename, pfs->name, len) == 0) { 476 break; 477 } 478 ipdata = NULL; /* safety */ 479 } 480 cluster = hammer2_cluster_next(cparent, cluster, &key_next, 481 key_next, 482 lhc + HAMMER2_DIRHASH_LOMASK, 483 HAMMER2_LOOKUP_SHARED); 484 } 485 486 /* 487 * Load the data being returned by the ioctl. 488 */ 489 if (cluster) { 490 ipdata = &hammer2_cluster_data(cluster)->ipdata; 491 pfs->name_key = ipdata->name_key; 492 pfs->pfs_type = ipdata->pfs_type; 493 pfs->pfs_clid = ipdata->pfs_clid; 494 pfs->pfs_fsid = ipdata->pfs_fsid; 495 ipdata = NULL; 496 497 hammer2_cluster_unlock(cluster); 498 } else { 499 error = ENOENT; 500 } 501 hammer2_inode_unlock_sh(hmp->spmp->iroot, cparent); 502 503 return (error); 504 } 505 506 /* 507 * Create a new PFS under the super-root 508 */ 509 static int 510 hammer2_ioctl_pfs_create(hammer2_inode_t *ip, void *data) 511 { 512 hammer2_inode_data_t *nipdata; 513 hammer2_mount_t *hmp; 514 hammer2_ioc_pfs_t *pfs; 515 hammer2_inode_t *nip; 516 hammer2_cluster_t *ncluster; 517 hammer2_trans_t trans; 518 int error; 519 520 hmp = ip->pmp->iroot->cluster.focus->hmp; /* XXX */ 521 pfs = data; 522 nip = NULL; 523 524 if (pfs->name[0] == 0) 525 return(EINVAL); 526 pfs->name[sizeof(pfs->name) - 1] = 0; /* ensure 0-termination */ 527 528 hammer2_trans_init(&trans, ip->pmp, HAMMER2_TRANS_NEWINODE); 529 nip = hammer2_inode_create(&trans, hmp->spmp->iroot, NULL, NULL, 530 pfs->name, strlen(pfs->name), 531 &ncluster, &error); 532 if (error == 0) { 533 nipdata = hammer2_cluster_modify_ip(&trans, nip, ncluster, 534 HAMMER2_MODIFY_ASSERTNOCOPY); 535 nipdata->pfs_type = pfs->pfs_type; 536 nipdata->pfs_clid = pfs->pfs_clid; 537 nipdata->pfs_fsid = pfs->pfs_fsid; 538 539 /* 540 * Do not allow compression on PFS's with the special name 541 * "boot", the boot loader can't decompress (yet). 542 */ 543 if (strcmp(pfs->name, "boot") == 0) 544 nipdata->comp_algo = HAMMER2_COMP_AUTOZERO; 545 hammer2_cluster_modsync(ncluster); 546 hammer2_inode_unlock_ex(nip, ncluster); 547 } 548 hammer2_trans_done(&trans); 549 550 return (error); 551 } 552 553 /* 554 * Destroy an existing PFS under the super-root 555 */ 556 static int 557 hammer2_ioctl_pfs_delete(hammer2_inode_t *ip, void *data) 558 { 559 hammer2_mount_t *hmp; 560 hammer2_ioc_pfs_t *pfs = data; 561 hammer2_trans_t trans; 562 int error; 563 564 hmp = ip->pmp->iroot->cluster.focus->hmp; /* XXX */ 565 hammer2_trans_init(&trans, ip->pmp, 0); 566 error = hammer2_unlink_file(&trans, hmp->spmp->iroot, 567 pfs->name, strlen(pfs->name), 568 2, NULL, NULL); 569 hammer2_trans_done(&trans); 570 571 return (error); 572 } 573 574 static int 575 hammer2_ioctl_pfs_snapshot(hammer2_inode_t *ip, void *data) 576 { 577 hammer2_ioc_pfs_t *pfs = data; 578 hammer2_trans_t trans; 579 hammer2_cluster_t *cparent; 580 int error; 581 582 if (pfs->name[0] == 0) 583 return(EINVAL); 584 if (pfs->name[sizeof(pfs->name)-1] != 0) 585 return(EINVAL); 586 587 hammer2_vfs_sync(ip->pmp->mp, MNT_WAIT); 588 589 hammer2_trans_init(&trans, ip->pmp, HAMMER2_TRANS_NEWINODE); 590 cparent = hammer2_inode_lock_ex(ip); 591 error = hammer2_cluster_snapshot(&trans, cparent, pfs); 592 hammer2_inode_unlock_ex(ip, cparent); 593 hammer2_trans_done(&trans); 594 595 return (error); 596 } 597 598 /* 599 * Retrieve the raw inode structure 600 */ 601 static int 602 hammer2_ioctl_inode_get(hammer2_inode_t *ip, void *data) 603 { 604 const hammer2_inode_data_t *ipdata; 605 hammer2_ioc_inode_t *ino; 606 hammer2_cluster_t *cparent; 607 608 ino = data; 609 610 cparent = hammer2_inode_lock_sh(ip); 611 ipdata = &hammer2_cluster_data(cparent)->ipdata; 612 ino->ip_data = *ipdata; 613 ino->kdata = ip; 614 hammer2_inode_unlock_sh(ip, cparent); 615 616 return (0); 617 } 618 619 /* 620 * Set various parameters in an inode which cannot be set through 621 * normal filesystem VNOPS. 622 */ 623 static int 624 hammer2_ioctl_inode_set(hammer2_inode_t *ip, void *data) 625 { 626 const hammer2_inode_data_t *ripdata; 627 hammer2_inode_data_t *wipdata; 628 hammer2_ioc_inode_t *ino = data; 629 hammer2_cluster_t *cparent; 630 hammer2_trans_t trans; 631 int error = 0; 632 int dosync = 0; 633 634 hammer2_trans_init(&trans, ip->pmp, 0); 635 cparent = hammer2_inode_lock_ex(ip); 636 ripdata = &hammer2_cluster_data(cparent)->ipdata; 637 638 if (ino->ip_data.comp_algo != ripdata->comp_algo) { 639 wipdata = hammer2_cluster_modify_ip(&trans, ip, cparent, 0); 640 wipdata->comp_algo = ino->ip_data.comp_algo; 641 ripdata = wipdata; /* safety */ 642 dosync = 1; 643 } 644 ino->kdata = ip; 645 646 /* Ignore these flags for now...*/ 647 if (ino->flags & HAMMER2IOC_INODE_FLAG_IQUOTA) { 648 } 649 if (ino->flags & HAMMER2IOC_INODE_FLAG_DQUOTA) { 650 } 651 if (ino->flags & HAMMER2IOC_INODE_FLAG_COPIES) { 652 } 653 if (dosync) 654 hammer2_cluster_modsync(cparent); 655 hammer2_trans_done(&trans); 656 hammer2_inode_unlock_ex(ip, cparent); 657 658 return (error); 659 } 660 661 static 662 int 663 hammer2_ioctl_debug_dump(hammer2_inode_t *ip) 664 { 665 hammer2_chain_t *chain; 666 int count = 1000; 667 int i; 668 669 for (i = 0; i < ip->cluster.nchains; ++i) { 670 chain = ip->cluster.array[i]; 671 if (chain == NULL) 672 continue; 673 hammer2_dump_chain(chain, 0, &count, 'i'); 674 } 675 return 0; 676 } 677