hammer2 - more dmsg/separation work
[dragonfly.git] / sys / vfs / hammer2 / hammer2_ioctl.c
CommitLineData
2910a90c 1/*
8138a154 2 * Copyright (c) 2011-2014 The DragonFly Project. All rights reserved.
2910a90c
MD
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
ae183399 45static int hammer2_ioctl_version_get(hammer2_inode_t *ip, void *data);
1a34728c
MD
46static int hammer2_ioctl_recluster(hammer2_inode_t *ip, void *data);
47static int hammer2_ioctl_remote_scan(hammer2_inode_t *ip, void *data);
ae183399
MD
48static int hammer2_ioctl_remote_add(hammer2_inode_t *ip, void *data);
49static int hammer2_ioctl_remote_del(hammer2_inode_t *ip, void *data);
50static int hammer2_ioctl_remote_rep(hammer2_inode_t *ip, void *data);
51static int hammer2_ioctl_socket_get(hammer2_inode_t *ip, void *data);
52static int hammer2_ioctl_socket_set(hammer2_inode_t *ip, void *data);
53static int hammer2_ioctl_pfs_get(hammer2_inode_t *ip, void *data);
458ecb1b 54static int hammer2_ioctl_pfs_lookup(hammer2_inode_t *ip, void *data);
ae183399 55static int hammer2_ioctl_pfs_create(hammer2_inode_t *ip, void *data);
a864c5d9 56static int hammer2_ioctl_pfs_snapshot(hammer2_inode_t *ip, void *data);
ae183399 57static int hammer2_ioctl_pfs_delete(hammer2_inode_t *ip, void *data);
344d4f82
MD
58static int hammer2_ioctl_inode_get(hammer2_inode_t *ip, void *data);
59static int hammer2_ioctl_inode_set(hammer2_inode_t *ip, void *data);
03188ed8 60static int hammer2_ioctl_debug_dump(hammer2_inode_t *ip);
355d67fc
MD
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);
2910a90c
MD
64
65int
66hammer2_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) {
ae183399
MD
78 case HAMMER2IOC_VERSION_GET:
79 error = hammer2_ioctl_version_get(ip, data);
2910a90c 80 break;
1a34728c 81 case HAMMER2IOC_RECLUSTER:
2910a90c 82 if (error == 0)
1a34728c
MD
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);
2910a90c 88 break;
ae183399 89 case HAMMER2IOC_REMOTE_ADD:
2910a90c 90 if (error == 0)
ae183399 91 error = hammer2_ioctl_remote_add(ip, data);
2910a90c 92 break;
ae183399 93 case HAMMER2IOC_REMOTE_DEL:
2910a90c 94 if (error == 0)
ae183399 95 error = hammer2_ioctl_remote_del(ip, data);
2910a90c 96 break;
ae183399 97 case HAMMER2IOC_REMOTE_REP:
2910a90c 98 if (error == 0)
ae183399 99 error = hammer2_ioctl_remote_rep(ip, data);
2910a90c 100 break;
ae183399 101 case HAMMER2IOC_SOCKET_GET:
2910a90c 102 if (error == 0)
ae183399 103 error = hammer2_ioctl_socket_get(ip, data);
2910a90c 104 break;
ae183399
MD
105 case HAMMER2IOC_SOCKET_SET:
106 if (error == 0)
107 error = hammer2_ioctl_socket_set(ip, data);
108 break;
109 case HAMMER2IOC_PFS_GET:
2910a90c 110 if (error == 0)
ae183399
MD
111 error = hammer2_ioctl_pfs_get(ip, data);
112 break;
458ecb1b
MD
113 case HAMMER2IOC_PFS_LOOKUP:
114 if (error == 0)
115 error = hammer2_ioctl_pfs_lookup(ip, data);
116 break;
ae183399
MD
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);
2910a90c 124 break;
a864c5d9
MD
125 case HAMMER2IOC_PFS_SNAPSHOT:
126 if (error == 0)
127 error = hammer2_ioctl_pfs_snapshot(ip, data);
128 break;
344d4f82
MD
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;
355d67fc
MD
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;*/
03188ed8
MD
145 case HAMMER2IOC_DEBUG_DUMP:
146 error = hammer2_ioctl_debug_dump(ip);
147 break;
2910a90c
MD
148 default:
149 error = EOPNOTSUPP;
150 break;
151 }
152 return (error);
153}
154
155/*
156 * Retrieve version and basic info
157 */
158static int
ae183399 159hammer2_ioctl_version_get(hammer2_inode_t *ip, void *data)
2910a90c 160{
58e43599 161 hammer2_mount_t *hmp = ip->pmp->iroot->cluster.focus->hmp;
2910a90c
MD
162 hammer2_ioc_version_t *version = data;
163
164 version->version = hmp->voldata.version;
165 return 0;
166}
167
1a34728c
MD
168static int
169hammer2_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
2910a90c
MD
184/*
185 * Retrieve information about a remote
186 */
187static int
1a34728c 188hammer2_ioctl_remote_scan(hammer2_inode_t *ip, void *data)
2910a90c 189{
58e43599 190 hammer2_mount_t *hmp = ip->pmp->iroot->cluster.focus->hmp;
2910a90c
MD
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];
50456506 199 hammer2_voldata_unlock(hmp);
2910a90c
MD
200
201 /*
202 * Adjust nextid (GET only)
203 */
204 while (++copyid < HAMMER2_COPYID_COUNT &&
205 hmp->voldata.copyinfo[copyid].copyid == 0) {
1a34728c 206 ;
2910a90c
MD
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 */
219static int
ae183399 220hammer2_ioctl_remote_add(hammer2_inode_t *ip, void *data)
2910a90c 221{
2910a90c 222 hammer2_ioc_remote_t *remote = data;
a5913bdf
MD
223 hammer2_pfsmount_t *pmp = ip->pmp;
224 hammer2_mount_t *hmp;
2910a90c
MD
225 int copyid = remote->copyid;
226 int error = 0;
227
228 if (copyid >= HAMMER2_COPYID_COUNT)
229 return (EINVAL);
230
58e43599 231 hmp = pmp->iroot->cluster.focus->hmp; /* XXX */
2910a90c
MD
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 }
50456506 243 hammer2_voldata_modify(hmp);
2910a90c
MD
244 remote->copy1.copyid = copyid;
245 hmp->voldata.copyinfo[copyid] = remote->copy1;
1a34728c 246 hammer2_volconf_update(pmp, copyid);
2910a90c 247failed:
50456506 248 hammer2_voldata_unlock(hmp);
2910a90c
MD
249 return (error);
250}
251
252/*
253 * Delete existing remote entry
254 */
255static int
ae183399 256hammer2_ioctl_remote_del(hammer2_inode_t *ip, void *data)
2910a90c 257{
2910a90c 258 hammer2_ioc_remote_t *remote = data;
a5913bdf
MD
259 hammer2_pfsmount_t *pmp = ip->pmp;
260 hammer2_mount_t *hmp;
2910a90c
MD
261 int copyid = remote->copyid;
262 int error = 0;
263
58e43599 264 hmp = pmp->iroot->cluster.focus->hmp; /* XXX */
2910a90c
MD
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 }
50456506 283 hammer2_voldata_modify(hmp);
2910a90c 284 hmp->voldata.copyinfo[copyid].copyid = 0;
1a34728c 285 hammer2_volconf_update(pmp, copyid);
2910a90c 286failed:
50456506 287 hammer2_voldata_unlock(hmp);
2910a90c
MD
288 return (error);
289}
290
291/*
292 * Replace existing remote entry
293 */
294static int
ae183399 295hammer2_ioctl_remote_rep(hammer2_inode_t *ip, void *data)
2910a90c 296{
2910a90c 297 hammer2_ioc_remote_t *remote = data;
a5913bdf 298 hammer2_mount_t *hmp;
2910a90c
MD
299 int copyid = remote->copyid;
300
58e43599 301 hmp = ip->pmp->iroot->cluster.focus->hmp; /* XXX */
a5913bdf 302
2910a90c
MD
303 if (copyid < 0 || copyid >= HAMMER2_COPYID_COUNT)
304 return (EINVAL);
305
306 hammer2_voldata_lock(hmp);
50456506 307 hammer2_voldata_modify(hmp);
1a34728c 308 /*hammer2_volconf_update(pmp, copyid);*/
50456506 309 hammer2_voldata_unlock(hmp);
2910a90c
MD
310
311 return(0);
312}
313
314/*
315 * Retrieve communications socket
316 */
317static int
ae183399 318hammer2_ioctl_socket_get(hammer2_inode_t *ip, void *data)
2910a90c
MD
319{
320 return (EOPNOTSUPP);
321}
322
323/*
324 * Set communications socket for connection
325 */
326static int
ae183399 327hammer2_ioctl_socket_set(hammer2_inode_t *ip, void *data)
2910a90c 328{
2910a90c 329 hammer2_ioc_remote_t *remote = data;
a5913bdf 330 hammer2_mount_t *hmp;
2910a90c
MD
331 int copyid = remote->copyid;
332
58e43599 333 hmp = ip->pmp->iroot->cluster.focus->hmp; /* XXX */
2910a90c
MD
334 if (copyid < 0 || copyid >= HAMMER2_COPYID_COUNT)
335 return (EINVAL);
336
337 hammer2_voldata_lock(hmp);
50456506 338 hammer2_voldata_unlock(hmp);
2910a90c
MD
339
340 return(0);
341}
ae183399
MD
342
343/*
a864c5d9
MD
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.
ae183399
MD
353 */
354static int
355hammer2_ioctl_pfs_get(hammer2_inode_t *ip, void *data)
356{
6a5f4fe6 357 const hammer2_inode_data_t *ipdata;
476d2aad
MD
358 hammer2_mount_t *hmp;
359 hammer2_ioc_pfs_t *pfs;
278ab2b2
MD
360 hammer2_cluster_t *cparent;
361 hammer2_cluster_t *rcluster;
362 hammer2_cluster_t *cluster;
1897c66e 363 hammer2_key_t key_next;
476d2aad 364 int error;
278ab2b2 365 int ddflag;
ae183399 366
476d2aad 367 error = 0;
58e43599 368 hmp = ip->pmp->iroot->cluster.focus->hmp; /* XXX */
476d2aad 369 pfs = data;
50456506 370 cparent = hammer2_inode_lock_ex(hmp->spmp->iroot);
278ab2b2 371 rcluster = hammer2_inode_lock_ex(ip->pmp->iroot);
ae183399
MD
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) {
278ab2b2
MD
378 cluster = hammer2_cluster_lookup(cparent, &key_next,
379 0, (hammer2_key_t)-1,
380 0, &ddflag);
a864c5d9 381 } else if (pfs->name_key == (hammer2_key_t)-1) {
278ab2b2
MD
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 */
ae183399 388 } else {
278ab2b2
MD
389 cluster = hammer2_cluster_lookup(cparent, &key_next,
390 pfs->name_key, pfs->name_key,
391 0, &ddflag);
ae183399 392 }
278ab2b2 393 hammer2_inode_unlock_ex(ip->pmp->iroot, rcluster);
9b6b3df4 394
278ab2b2
MD
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);
ae183399 400 }
278ab2b2 401 if (cluster) {
ae183399
MD
402 /*
403 * Load the data being returned by the ioctl.
404 */
278ab2b2 405 ipdata = &hammer2_cluster_data(cluster)->ipdata;
476d2aad
MD
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 */
ae183399
MD
414
415 /*
416 * Calculate the next field
417 */
418 do {
278ab2b2
MD
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);
ae183399
MD
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 }
50456506 437 hammer2_inode_unlock_ex(hmp->spmp->iroot, cparent);
0dea3156 438
ae183399
MD
439 return (error);
440}
441
458ecb1b
MD
442/*
443 * Find a specific PFS by name
444 */
445static int
446hammer2_ioctl_pfs_lookup(hammer2_inode_t *ip, void *data)
447{
6a5f4fe6 448 const hammer2_inode_data_t *ipdata;
476d2aad
MD
449 hammer2_mount_t *hmp;
450 hammer2_ioc_pfs_t *pfs;
278ab2b2
MD
451 hammer2_cluster_t *cparent;
452 hammer2_cluster_t *cluster;
1897c66e 453 hammer2_key_t key_next;
458ecb1b 454 hammer2_key_t lhc;
476d2aad 455 int error;
278ab2b2 456 int ddflag;
458ecb1b
MD
457 size_t len;
458
476d2aad 459 error = 0;
58e43599 460 hmp = ip->pmp->iroot->cluster.focus->hmp; /* XXX */
476d2aad 461 pfs = data;
50456506 462 cparent = hammer2_inode_lock_sh(hmp->spmp->iroot);
458ecb1b
MD
463
464 pfs->name[sizeof(pfs->name) - 1] = 0;
465 len = strlen(pfs->name);
466 lhc = hammer2_dirhash(pfs->name, len);
467
278ab2b2
MD
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 */
458ecb1b 479 }
278ab2b2 480 cluster = hammer2_cluster_next(cparent, cluster, &key_next,
1897c66e
MD
481 key_next,
482 lhc + HAMMER2_DIRHASH_LOMASK,
278ab2b2 483 HAMMER2_LOOKUP_SHARED);
458ecb1b
MD
484 }
485
486 /*
487 * Load the data being returned by the ioctl.
488 */
278ab2b2
MD
489 if (cluster) {
490 ipdata = &hammer2_cluster_data(cluster)->ipdata;
476d2aad
MD
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;
458ecb1b 496
278ab2b2 497 hammer2_cluster_unlock(cluster);
458ecb1b
MD
498 } else {
499 error = ENOENT;
500 }
50456506 501 hammer2_inode_unlock_sh(hmp->spmp->iroot, cparent);
7bed8d7e 502
458ecb1b
MD
503 return (error);
504}
505
ae183399
MD
506/*
507 * Create a new PFS under the super-root
508 */
509static int
510hammer2_ioctl_pfs_create(hammer2_inode_t *ip, void *data)
511{
476d2aad
MD
512 hammer2_inode_data_t *nipdata;
513 hammer2_mount_t *hmp;
514 hammer2_ioc_pfs_t *pfs;
515 hammer2_inode_t *nip;
278ab2b2 516 hammer2_cluster_t *ncluster;
0dea3156 517 hammer2_trans_t trans;
ae183399
MD
518 int error;
519
58e43599 520 hmp = ip->pmp->iroot->cluster.focus->hmp; /* XXX */
476d2aad
MD
521 pfs = data;
522 nip = NULL;
523
a864c5d9
MD
524 if (pfs->name[0] == 0)
525 return(EINVAL);
ae183399 526 pfs->name[sizeof(pfs->name) - 1] = 0; /* ensure 0-termination */
10252dc7 527
50456506
MD
528 hammer2_trans_init(&trans, ip->pmp, HAMMER2_TRANS_NEWINODE);
529 nip = hammer2_inode_create(&trans, hmp->spmp->iroot, NULL, NULL,
ae183399 530 pfs->name, strlen(pfs->name),
278ab2b2 531 &ncluster, &error);
ae183399 532 if (error == 0) {
278ab2b2 533 nipdata = hammer2_cluster_modify_ip(&trans, nip, ncluster,
4a59bd3e 534 HAMMER2_MODIFY_ASSERTNOCOPY);
476d2aad
MD
535 nipdata->pfs_type = pfs->pfs_type;
536 nipdata->pfs_clid = pfs->pfs_clid;
537 nipdata->pfs_fsid = pfs->pfs_fsid;
cdfd0a3e
MD
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;
6a5f4fe6 545 hammer2_cluster_modsync(ncluster);
278ab2b2 546 hammer2_inode_unlock_ex(nip, ncluster);
ae183399 547 }
0dea3156 548 hammer2_trans_done(&trans);
278ab2b2 549
ae183399
MD
550 return (error);
551}
552
553/*
554 * Destroy an existing PFS under the super-root
555 */
556static int
557hammer2_ioctl_pfs_delete(hammer2_inode_t *ip, void *data)
558{
a5913bdf 559 hammer2_mount_t *hmp;
ae183399 560 hammer2_ioc_pfs_t *pfs = data;
0dea3156 561 hammer2_trans_t trans;
ae183399
MD
562 int error;
563
58e43599 564 hmp = ip->pmp->iroot->cluster.focus->hmp; /* XXX */
50456506
MD
565 hammer2_trans_init(&trans, ip->pmp, 0);
566 error = hammer2_unlink_file(&trans, hmp->spmp->iroot,
9797e933 567 pfs->name, strlen(pfs->name),
044541cd 568 2, NULL, NULL);
a864c5d9
MD
569 hammer2_trans_done(&trans);
570
571 return (error);
572}
573
574static int
575hammer2_ioctl_pfs_snapshot(hammer2_inode_t *ip, void *data)
576{
a864c5d9
MD
577 hammer2_ioc_pfs_t *pfs = data;
578 hammer2_trans_t trans;
278ab2b2 579 hammer2_cluster_t *cparent;
a864c5d9
MD
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
a7720be7
MD
587 hammer2_vfs_sync(ip->pmp->mp, MNT_WAIT);
588
50456506 589 hammer2_trans_init(&trans, ip->pmp, HAMMER2_TRANS_NEWINODE);
278ab2b2
MD
590 cparent = hammer2_inode_lock_ex(ip);
591 error = hammer2_cluster_snapshot(&trans, cparent, pfs);
592 hammer2_inode_unlock_ex(ip, cparent);
0dea3156
MD
593 hammer2_trans_done(&trans);
594
ae183399
MD
595 return (error);
596}
344d4f82
MD
597
598/*
599 * Retrieve the raw inode structure
600 */
601static int
602hammer2_ioctl_inode_get(hammer2_inode_t *ip, void *data)
603{
6a5f4fe6
MD
604 const hammer2_inode_data_t *ipdata;
605 hammer2_ioc_inode_t *ino;
278ab2b2 606 hammer2_cluster_t *cparent;
344d4f82 607
6a5f4fe6
MD
608 ino = data;
609
278ab2b2
MD
610 cparent = hammer2_inode_lock_sh(ip);
611 ipdata = &hammer2_cluster_data(cparent)->ipdata;
612 ino->ip_data = *ipdata;
26b047fa 613 ino->kdata = ip;
278ab2b2 614 hammer2_inode_unlock_sh(ip, cparent);
0dea3156 615
344d4f82
MD
616 return (0);
617}
618
f481450f
MD
619/*
620 * Set various parameters in an inode which cannot be set through
621 * normal filesystem VNOPS.
622 */
344d4f82
MD
623static int
624hammer2_ioctl_inode_set(hammer2_inode_t *ip, void *data)
625{
6a5f4fe6
MD
626 const hammer2_inode_data_t *ripdata;
627 hammer2_inode_data_t *wipdata;
344d4f82 628 hammer2_ioc_inode_t *ino = data;
278ab2b2 629 hammer2_cluster_t *cparent;
355d67fc 630 hammer2_trans_t trans;
f481450f 631 int error = 0;
6a5f4fe6 632 int dosync = 0;
344d4f82 633
50456506 634 hammer2_trans_init(&trans, ip->pmp, 0);
278ab2b2 635 cparent = hammer2_inode_lock_ex(ip);
6a5f4fe6 636 ripdata = &hammer2_cluster_data(cparent)->ipdata;
f481450f 637
6a5f4fe6
MD
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;
f481450f 643 }
355d67fc
MD
644 ino->kdata = ip;
645
f481450f 646 /* Ignore these flags for now...*/
344d4f82
MD
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 }
6a5f4fe6
MD
653 if (dosync)
654 hammer2_cluster_modsync(cparent);
355d67fc 655 hammer2_trans_done(&trans);
278ab2b2 656 hammer2_inode_unlock_ex(ip, cparent);
0dea3156 657
344d4f82
MD
658 return (error);
659}
03188ed8
MD
660
661static
662int
663hammer2_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}