~ubuntu-branches/ubuntu/edgy/e2fsprogs/edgy-updates

« back to all changes in this revision

Viewing changes to resize/online.c

  • Committer: Bazaar Package Importer
  • Author(s): Theodore Y. Ts'o
  • Date: 2006-05-29 11:07:53 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20060529110753-uvkuaxqr96y31kqy
Tags: 1.39-1
* New upstream version
* Fix debugfs's dump_unused command so it will not core dump on
  filesystems with a 64k blocksize
* Clarified and improved man pages, including spelling errors
  (Closes: #368392, #368393, #368394, #368179)
* New filesystems are now created with directory indexing and
  on-line resizing enabled by default
* Fix previously mangled wording in an older Debian changelog entry
* Fix doc-base pointer to the top-level html file (Closes: #362544, #362970)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * online.c --- Do on-line resizing of the ext3 filesystem
 
3
 *
 
4
 * Copyright (C) 2006 by Theodore Ts'o 
 
5
 * 
 
6
 * %Begin-Header%
 
7
 * This file may be redistributed under the terms of the GNU Public
 
8
 * License.
 
9
 * %End-Header%
 
10
 */
 
11
 
 
12
#include "resize2fs.h"
 
13
#ifdef HAVE_SYS_IOCTL_H
 
14
#include <sys/ioctl.h>
 
15
#endif
 
16
#include <sys/stat.h>
 
17
#include <fcntl.h>
 
18
 
 
19
extern char *program_name;
 
20
 
 
21
errcode_t online_resize_fs(ext2_filsys fs, const char *mtpt, 
 
22
                           blk_t *new_size, int flags)
 
23
{
 
24
        struct ext2_new_group_input input;
 
25
        struct ext2_super_block *sb = fs->super;
 
26
        ext2_filsys             new_fs;
 
27
        errcode_t               retval;
 
28
        dgrp_t                  i;
 
29
        blk_t                   size;
 
30
        int                     fd, r_frac, overhead;
 
31
 
 
32
        printf(_("Filesystem at %s is mounted on %s; "
 
33
                 "on-line resizing required\n"), fs->device_name, mtpt);
 
34
 
 
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);
 
38
                exit(1);
 
39
        }
 
40
 
 
41
        fd = open(mtpt, O_RDONLY);
 
42
        if (fd < 0) {
 
43
                com_err(program_name, errno, 
 
44
                        _("while trying to open mountpoint %s"), mtpt);
 
45
                exit(1);
 
46
        }
 
47
 
 
48
        size=sb->s_blocks_count;
 
49
        if (ioctl(fd, EXT2_IOC_GROUP_EXTEND, &size)) {
 
50
                if (errno == EPERM)
 
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"));
 
56
                else 
 
57
                        com_err(program_name, errno, 
 
58
                        _("While checking for on-line resizing support"));
 
59
                exit(1);
 
60
        }
 
61
 
 
62
        r_frac = ((100 * sb->s_r_blocks_count) + sb->s_blocks_count-1) /
 
63
                sb->s_blocks_count;
 
64
 
 
65
        retval = ext2fs_read_bitmaps(fs);
 
66
        if (retval)
 
67
                return retval;
 
68
 
 
69
        retval = ext2fs_dup_handle(fs, &new_fs);
 
70
        if (retval)
 
71
                return retval;
 
72
 
 
73
        retval = adjust_fs_info(new_fs, fs, *new_size);
 
74
        if (retval)
 
75
                return retval;
 
76
 
 
77
        printf(_("Performing an on-line resize of %s to %d (%dk) blocks.\n"), 
 
78
               fs->device_name, *new_size, fs->blocksize / 1024);
 
79
 
 
80
        size = fs->group_desc_count * sb->s_blocks_per_group + 
 
81
                sb->s_first_data_block;
 
82
        if (size > *new_size)
 
83
                size = *new_size;
 
84
 
 
85
        if (ioctl(fd, EXT2_IOC_GROUP_EXTEND, &size)) {
 
86
                com_err(program_name, errno, 
 
87
                        _("While trying to extend the last group"));
 
88
                exit(1);
 
89
        }
 
90
 
 
91
        for (i = fs->group_desc_count;
 
92
             i < new_fs->group_desc_count; i++) {
 
93
 
 
94
                overhead = (int) (2 + new_fs->inode_blocks_per_group);
 
95
 
 
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;
 
99
 
 
100
                input.group = i;
 
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);
 
109
                }
 
110
                input.reserved_blocks = input.blocks_count * r_frac / 100;
 
111
 
 
112
#if 0
 
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", 
 
116
                       input.inode_table,
 
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);
 
127
#endif
 
128
 
 
129
                if (ioctl(fd, EXT2_IOC_GROUP_ADD, &input) < 0) {
 
130
                        com_err(program_name, errno, 
 
131
                                _("While trying to add group #%d"), 
 
132
                                input.group);
 
133
                        exit(1);
 
134
                }
 
135
        }
 
136
 
 
137
        ext2fs_free(new_fs);
 
138
        close(fd);
 
139
 
 
140
        return 0;
 
141
}