2
* online.c --- Do on-line resizing of the ext3 filesystem
4
* Copyright (C) 2006 by Theodore Ts'o
7
* This file may be redistributed under the terms of the GNU Public
12
#include "resize2fs.h"
13
#ifdef HAVE_SYS_IOCTL_H
14
#include <sys/ioctl.h>
19
extern char *program_name;
21
errcode_t online_resize_fs(ext2_filsys fs, const char *mtpt,
22
blk_t *new_size, int flags)
24
struct ext2_new_group_input input;
25
struct ext2_super_block *sb = fs->super;
30
int fd, r_frac, overhead;
32
printf(_("Filesystem at %s is mounted on %s; "
33
"on-line resizing required\n"), fs->device_name, mtpt);
35
if (*new_size < sb->s_blocks_count) {
36
printf(_("On-line shrinking from %u to %u not supported.\n"),
37
sb->s_blocks_count, *new_size);
41
fd = open(mtpt, O_RDONLY);
43
com_err(program_name, errno,
44
_("while trying to open mountpoint %s"), mtpt);
48
size=sb->s_blocks_count;
49
if (ioctl(fd, EXT2_IOC_GROUP_EXTEND, &size)) {
51
com_err(program_name, 0,
52
_("Permission denied to resize filesystem"));
53
else if (errno == ENOTTY)
54
com_err(program_name, 0,
55
_("Filesystem does not support online resizing"));
57
com_err(program_name, errno,
58
_("While checking for on-line resizing support"));
62
r_frac = ((100 * sb->s_r_blocks_count) + sb->s_blocks_count-1) /
65
retval = ext2fs_read_bitmaps(fs);
69
retval = ext2fs_dup_handle(fs, &new_fs);
73
retval = adjust_fs_info(new_fs, fs, *new_size);
77
printf(_("Performing an on-line resize of %s to %d (%dk) blocks.\n"),
78
fs->device_name, *new_size, fs->blocksize / 1024);
80
size = fs->group_desc_count * sb->s_blocks_per_group +
81
sb->s_first_data_block;
85
if (ioctl(fd, EXT2_IOC_GROUP_EXTEND, &size)) {
86
com_err(program_name, errno,
87
_("While trying to extend the last group"));
91
for (i = fs->group_desc_count;
92
i < new_fs->group_desc_count; i++) {
94
overhead = (int) (2 + new_fs->inode_blocks_per_group);
96
if (ext2fs_bg_has_super(new_fs, new_fs->group_desc_count - 1))
97
overhead += 1 + new_fs->desc_blocks +
98
new_fs->super->s_reserved_gdt_blocks;
101
input.block_bitmap = new_fs->group_desc[i].bg_block_bitmap;
102
input.inode_bitmap = new_fs->group_desc[i].bg_inode_bitmap;
103
input.inode_table = new_fs->group_desc[i].bg_inode_table;
104
input.blocks_count = sb->s_blocks_per_group;
105
if (i == new_fs->group_desc_count-1) {
106
input.blocks_count = new_fs->super->s_blocks_count -
107
sb->s_first_data_block -
108
(i * sb->s_blocks_per_group);
110
input.reserved_blocks = input.blocks_count * r_frac / 100;
113
printf("new block bitmap is at 0x%04x\n", input.block_bitmap);
114
printf("new inode bitmap is at 0x%04x\n", input.inode_bitmap);
115
printf("new inode table is at 0x%04x-0x%04x\n",
117
input.inode_table + new_fs->inode_blocks_per_group-1);
118
printf("new group has %d blocks\n", input.blocks_count);
119
printf("new group will reserve %d blocks\n",
120
input.reserved_blocks);
121
printf("new group has %d free blocks\n",
122
new_fs->group_desc[i].bg_free_blocks_count);
123
printf("new group has %d free inodes (%d blocks)\n",
124
new_fs->group_desc[i].bg_free_inodes_count,
125
new_fs->inode_blocks_per_group);
126
printf("Adding group #%d\n", input.group);
129
if (ioctl(fd, EXT2_IOC_GROUP_ADD, &input) < 0) {
130
com_err(program_name, errno,
131
_("While trying to add group #%d"),