xref: /dflybsd-src/sbin/hammer/cmd_reblock.c (revision 1d9f6aa1a944f07e4e87324c54d65d2d143403bb)
13f673d5cSMatthew Dillon /*
23f673d5cSMatthew Dillon  * Copyright (c) 2008 The DragonFly Project.  All rights reserved.
33f673d5cSMatthew Dillon  *
43f673d5cSMatthew Dillon  * This code is derived from software contributed to The DragonFly Project
53f673d5cSMatthew Dillon  * by Matthew Dillon <dillon@backplane.com>
63f673d5cSMatthew Dillon  *
73f673d5cSMatthew Dillon  * Redistribution and use in source and binary forms, with or without
83f673d5cSMatthew Dillon  * modification, are permitted provided that the following conditions
93f673d5cSMatthew Dillon  * are met:
103f673d5cSMatthew Dillon  *
113f673d5cSMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
123f673d5cSMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
133f673d5cSMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
143f673d5cSMatthew Dillon  *    notice, this list of conditions and the following disclaimer in
153f673d5cSMatthew Dillon  *    the documentation and/or other materials provided with the
163f673d5cSMatthew Dillon  *    distribution.
173f673d5cSMatthew Dillon  * 3. Neither the name of The DragonFly Project nor the names of its
183f673d5cSMatthew Dillon  *    contributors may be used to endorse or promote products derived
193f673d5cSMatthew Dillon  *    from this software without specific, prior written permission.
203f673d5cSMatthew Dillon  *
213f673d5cSMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
223f673d5cSMatthew Dillon  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
233f673d5cSMatthew Dillon  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
243f673d5cSMatthew Dillon  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
253f673d5cSMatthew Dillon  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
263f673d5cSMatthew Dillon  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
273f673d5cSMatthew Dillon  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
283f673d5cSMatthew Dillon  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
293f673d5cSMatthew Dillon  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
303f673d5cSMatthew Dillon  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
313f673d5cSMatthew Dillon  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
323f673d5cSMatthew Dillon  * SUCH DAMAGE.
333f673d5cSMatthew Dillon  *
34*1d9f6aa1SMatthew Dillon  * $DragonFly: src/sbin/hammer/cmd_reblock.c,v 1.8 2008/06/24 17:40:21 dillon Exp $
353f673d5cSMatthew Dillon  */
363f673d5cSMatthew Dillon 
373f673d5cSMatthew Dillon #include "hammer.h"
383f673d5cSMatthew Dillon 
393f673d5cSMatthew Dillon static void reblock_usage(int exit_code);
403f673d5cSMatthew Dillon 
413f673d5cSMatthew Dillon /*
423f673d5cSMatthew Dillon  * reblock <filesystem> [compaction_precentage] (default 90%)
433f673d5cSMatthew Dillon  */
443f673d5cSMatthew Dillon void
45ba7b52c9SMatthew Dillon hammer_cmd_reblock(char **av, int ac, int flags)
463f673d5cSMatthew Dillon {
473f673d5cSMatthew Dillon 	struct hammer_ioc_reblock reblock;
483f673d5cSMatthew Dillon 	const char *filesystem;
493f673d5cSMatthew Dillon 	int fd;
503f673d5cSMatthew Dillon 	int perc;
513f673d5cSMatthew Dillon 
523f673d5cSMatthew Dillon 	bzero(&reblock, sizeof(reblock));
5358c17893SMatthew Dillon 
54*1d9f6aa1SMatthew Dillon 	reblock.key_beg.localization = HAMMER_MIN_LOCALIZATION;
55*1d9f6aa1SMatthew Dillon 	reblock.key_beg.obj_id = HAMMER_MIN_OBJID;
56*1d9f6aa1SMatthew Dillon 	hammer_get_cycle(&reblock.key_beg.obj_id,
57*1d9f6aa1SMatthew Dillon 			 &reblock.key_beg.localization);
5858c17893SMatthew Dillon 
59*1d9f6aa1SMatthew Dillon 	reblock.key_end.localization = HAMMER_MAX_LOCALIZATION;
60*1d9f6aa1SMatthew Dillon 	reblock.key_end.obj_id = HAMMER_MAX_OBJID;
6158c17893SMatthew Dillon 
62ba7b52c9SMatthew Dillon 	reblock.head.flags = flags & HAMMER_IOC_DO_FLAGS;
633f673d5cSMatthew Dillon 
6458c17893SMatthew Dillon 	/*
6558c17893SMatthew Dillon 	 * Restrict the localization domain if asked to do inodes or data,
6658c17893SMatthew Dillon 	 * but not both.
6758c17893SMatthew Dillon 	 */
689e29c876SMatthew Dillon 	switch(flags & (HAMMER_IOC_DO_INODES|HAMMER_IOC_DO_DATA|HAMMER_IOC_DO_DIRS)) {
6958c17893SMatthew Dillon 	case HAMMER_IOC_DO_INODES:
70*1d9f6aa1SMatthew Dillon 		reblock.key_beg.localization = HAMMER_LOCALIZE_INODE;
71*1d9f6aa1SMatthew Dillon 		reblock.key_end.localization = HAMMER_LOCALIZE_INODE;
7258c17893SMatthew Dillon 		break;
739e29c876SMatthew Dillon 	case HAMMER_IOC_DO_DIRS:
7458c17893SMatthew Dillon 	case HAMMER_IOC_DO_DATA:
75*1d9f6aa1SMatthew Dillon 		reblock.key_beg.localization = HAMMER_LOCALIZE_MISC;
76*1d9f6aa1SMatthew Dillon 		reblock.key_end.localization = HAMMER_LOCALIZE_MISC;
7758c17893SMatthew Dillon 		break;
7858c17893SMatthew Dillon 	}
7958c17893SMatthew Dillon 
803f673d5cSMatthew Dillon 	if (ac == 0)
813f673d5cSMatthew Dillon 		reblock_usage(1);
823f673d5cSMatthew Dillon 	filesystem = av[0];
833f673d5cSMatthew Dillon 	if (ac == 1) {
849e29c876SMatthew Dillon 		perc = 100;
853f673d5cSMatthew Dillon 	} else {
863f673d5cSMatthew Dillon 		perc = strtol(av[1], NULL, 0);
873f673d5cSMatthew Dillon 		if (perc < 0 || perc > 100)
883f673d5cSMatthew Dillon 			reblock_usage(1);
893f673d5cSMatthew Dillon 	}
90ba7b52c9SMatthew Dillon 	reblock.free_level = (int)((int64_t)perc *
91ba7b52c9SMatthew Dillon 				   HAMMER_LARGEBLOCK_SIZE / 100);
923f673d5cSMatthew Dillon 	reblock.free_level = HAMMER_LARGEBLOCK_SIZE - reblock.free_level;
93ba7b52c9SMatthew Dillon 	if (reblock.free_level < 0)
94ba7b52c9SMatthew Dillon 		reblock.free_level = 0;
953f673d5cSMatthew Dillon 	printf("reblock free level %d\n", reblock.free_level);
963f673d5cSMatthew Dillon 
973f673d5cSMatthew Dillon 	fd = open(filesystem, O_RDONLY);
983f673d5cSMatthew Dillon 	if (fd < 0)
993f673d5cSMatthew Dillon 		err(1, "Unable to open %s", filesystem);
1000006adaeSMatthew Dillon 	if (ioctl(fd, HAMMERIOC_REBLOCK, &reblock) < 0) {
101d7ae405cSMatthew Dillon 		printf("Reblock %s failed: %s\n", filesystem, strerror(errno));
102d7ae405cSMatthew Dillon 	} else if (reblock.head.flags & HAMMER_IOC_HEAD_INTR) {
10358c17893SMatthew Dillon 		printf("Reblock %s interrupted by timer at %016llx %04x\n",
10458c17893SMatthew Dillon 			filesystem,
105*1d9f6aa1SMatthew Dillon 			reblock.key_cur.obj_id,
106*1d9f6aa1SMatthew Dillon 			reblock.key_cur.localization);
10758c17893SMatthew Dillon 		if (CyclePath) {
108*1d9f6aa1SMatthew Dillon 			hammer_set_cycle(reblock.key_cur.obj_id,
109*1d9f6aa1SMatthew Dillon 					 reblock.key_cur.localization);
11058c17893SMatthew Dillon 		}
1110006adaeSMatthew Dillon 	} else {
112d7ae405cSMatthew Dillon 		if (CyclePath)
113d7ae405cSMatthew Dillon 			hammer_reset_cycle();
1143f673d5cSMatthew Dillon 		printf("Reblock %s succeeded\n", filesystem);
1150006adaeSMatthew Dillon 	}
1163f673d5cSMatthew Dillon 	close(fd);
1173f673d5cSMatthew Dillon 	printf("Reblocked:\n"
1183f673d5cSMatthew Dillon 	       "    %lld/%lld btree nodes\n"
1193f673d5cSMatthew Dillon 	       "    %lld/%lld data elements\n"
1203f673d5cSMatthew Dillon 	       "    %lld/%lld data bytes\n",
1213f673d5cSMatthew Dillon 	       reblock.btree_moves, reblock.btree_count,
1223f673d5cSMatthew Dillon 	       reblock.data_moves, reblock.data_count,
1233f673d5cSMatthew Dillon 	       reblock.data_byte_moves, reblock.data_byte_count
1243f673d5cSMatthew Dillon 	);
1253f673d5cSMatthew Dillon }
1263f673d5cSMatthew Dillon 
1273f673d5cSMatthew Dillon static
1283f673d5cSMatthew Dillon void
1293f673d5cSMatthew Dillon reblock_usage(int exit_code)
1303f673d5cSMatthew Dillon {
13158c17893SMatthew Dillon 	fprintf(stderr, "hammer reblock <filesystem> [percentage]\n");
13258c17893SMatthew Dillon 	fprintf(stderr, "hammer reblock-btree <filesystem> [percentage]\n");
13358c17893SMatthew Dillon 	fprintf(stderr, "hammer reblock-inodes <filesystem> [percentage]\n");
1349e29c876SMatthew Dillon 	fprintf(stderr, "hammer reblock-dirs <filesystem> [percentage]\n");
13558c17893SMatthew Dillon 	fprintf(stderr, "hammer reblock-data <filesystem> [percentage]\n");
13658c17893SMatthew Dillon 	fprintf(stderr, "By default 90%% is used.  Use 100%% to defragment\n");
1373f673d5cSMatthew Dillon 	exit(exit_code);
1383f673d5cSMatthew Dillon }
1393f673d5cSMatthew Dillon 
140