2 * Copyright (c) 2007-2016 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 static void hammer_strip_bigblock(int zone
, hammer_off_t offset
);
38 static void hammer_ask_yn(void);
41 hammer_cmd_strip(void)
43 struct volume_info
*vol
;
44 hammer_blockmap_t rootmap
;
45 hammer_blockmap_layer1_t layer1
;
46 hammer_blockmap_layer2_t layer2
;
47 struct buffer_info
*buffer1
= NULL
;
48 struct buffer_info
*buffer2
= NULL
;
49 hammer_off_t layer1_offset
;
50 hammer_off_t layer2_offset
;
51 hammer_off_t phys_offset
;
52 hammer_off_t block_offset
;
54 int i
, zone
= HAMMER_ZONE_FREEMAP_INDEX
;
58 vol
= get_root_volume();
59 rootmap
= &vol
->ondisk
->vol0_blockmap
[zone
];
60 assert(rootmap
->phys_offset
!= 0);
62 for (phys_offset
= HAMMER_ZONE_ENCODE(zone
, 0);
63 phys_offset
< HAMMER_ZONE_ENCODE(zone
, HAMMER_OFF_LONG_MASK
);
64 phys_offset
+= HAMMER_BLOCKMAP_LAYER2
) {
68 layer1_offset
= rootmap
->phys_offset
+
69 HAMMER_BLOCKMAP_LAYER1_OFFSET(phys_offset
);
70 layer1
= get_buffer_data(layer1_offset
, &buffer1
, 0);
72 if (layer1
->phys_offset
== HAMMER_BLOCKMAP_UNAVAIL
)
75 for (block_offset
= 0;
76 block_offset
< HAMMER_BLOCKMAP_LAYER2
;
77 block_offset
+= HAMMER_BIGBLOCK_SIZE
) {
78 offset
= phys_offset
+ block_offset
;
80 * Dive layer 2, each entry represents a big-block.
82 layer2_offset
= layer1
->phys_offset
+
83 HAMMER_BLOCKMAP_LAYER2_OFFSET(block_offset
);
84 layer2
= get_buffer_data(layer2_offset
, &buffer2
, 0);
86 if (layer2
->zone
== HAMMER_ZONE_BTREE_INDEX
||
87 layer2
->zone
== HAMMER_ZONE_META_INDEX
) {
88 hammer_strip_bigblock(layer2
->zone
, offset
);
89 layer2
->zone
= HAMMER_ZONE_UNAVAIL_INDEX
;
90 layer2
->append_off
= HAMMER_BIGBLOCK_SIZE
;
91 layer2
->bytes_free
= 0;
92 hammer_crc_set_layer2(layer2
);
93 buffer2
->cache
.modified
= 1;
94 } else if (layer2
->zone
== HAMMER_ZONE_UNAVAIL_INDEX
) {
102 for (i
= 0; i
< HAMMER_MAX_VOLUMES
; i
++) {
105 printf("%s\n", vol
->name
);
106 bzero(vol
->ondisk
, sizeof(*vol
->ondisk
));
107 memcpy(&vol
->ondisk
->vol_signature
, "STRIPPED", 8);
115 hammer_strip_bigblock(int zone
, hammer_off_t offset
)
117 struct buffer_info
*buffer
= NULL
;
120 assert(hammer_is_index_record(zone
));
121 assert((offset
& HAMMER_BIGBLOCK_MASK64
) == 0);
122 assert((offset
& HAMMER_BUFMASK
) == 0);
123 offset
= hammer_xlate_to_zoneX(zone
, offset
);
126 * This format is taken from hammer blockmap.
129 printf("%016jx zone=%-2d vol=%-3d L1#=%-6d L2#=%-6d L1=%-7lu L2=%-7lu\n",
132 HAMMER_VOL_DECODE(offset
),
133 HAMMER_BLOCKMAP_LAYER1_INDEX(offset
),
134 HAMMER_BLOCKMAP_LAYER2_INDEX(offset
),
135 HAMMER_BLOCKMAP_LAYER1_OFFSET(offset
),
136 HAMMER_BLOCKMAP_LAYER2_OFFSET(offset
));
138 printf("%016jx\n", offset
);
141 for (i
= 0; i
< HAMMER_BIGBLOCK_SIZE
; i
+= HAMMER_BUFSIZE
) {
142 get_buffer_data(offset
+ i
, &buffer
, 1);
150 struct volume_info
*vol
;
153 vol
= get_root_volume();
156 * This format is taken from hammer pfs-destroy.
158 printf("You have requested that HAMMER filesystem (%s) be stripped\n",
159 vol
->ondisk
->vol_label
);
160 printf("Do you really want to do this? [y/n] ");
164 errx(1, "No action taken");
166 printf("Stripping HAMMER filesystem (%s)", vol
->ondisk
->vol_label
);
172 for (i
= 5; i
; --i
) {
177 printf(".. starting destruction pass\n");