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