1 /*
2 resizefs.c -- reiserfs filesystem resize program.
3 Copyright (C) 2001, 2002 Yury Umanets <torque@ukrpost.net>, see COPYING for
4 licensing and copyright details.
5 */
6
7 #ifdef HAVE_CONFIG_H
8 # include <config.h>
9 #endif
10
11 #include "getopt.h"
12
13 #include <stdio.h>
14 #include <string.h>
15 #include <errno.h>
16 #include <fcntl.h>
17
18 #include <dal/file.h>
19
20 #include <reiserfs/reiserfs.h>
21 #include <reiserfs/libprogs_tools.h>
22
23 #if ENABLE_NLS
24 # include <locale.h>
25 # include <libintl.h>
26 # define _(String) dgettext (PACKAGE, String)
27 #else
28 # define _(String) (String)
29 #endif
30
resizefs_print_usage(void)31 static void resizefs_print_usage(void) {
32 fprintf(stderr, _("Usage: resizefs.reiserfs [ options ] DEV [+|-]size[K|M|G]\n"
33 "Usage: resizefs.reiserfs [ options ] FILE start[K|M|G] end[K|M|G]\n"
34 "Options:\n"
35 " -v | --version prints current version\n"
36 " -u | --usage prints program usage\n"
37 " -j FILE | --journal-device=FILE journal device for separated journal\n"
38 " -n | --no-journal-available no journal device available now\n"
39 " -f | --force force resizer to resize partition anyway\n"
40 " -q | --quiet non-interactive mode\n"));
41 }
42
main(int argc,char * argv[])43 int main(int argc, char *argv[]) {
44 long dev_len;
45 long start = 0, end = 0;
46
47 int quiet = 0, force = 0;
48 int choice = 0, journal = 1, error = 0;
49
50 dal_t *host_dal = NULL, *journal_dal = NULL;
51 char *host_dev = NULL, *journal_dev = NULL;
52 char *start_str = NULL, *end_str = NULL;
53
54 reiserfs_fs_t *fs;
55 reiserfs_gauge_t *gauge = NULL;
56
57 static struct option long_options[] = {
58 {"version", no_argument, NULL, 'v'},
59 {"usage", no_argument, NULL, 'u'},
60 {"journal-device", required_argument, NULL, 'j'},
61 {"no-journal-available", required_argument, NULL, 'n'},
62 {"force", no_argument, NULL, 'f'},
63 {"quiet", no_argument, NULL, 'q'},
64 {0, 0, 0, 0}
65 };
66
67 #ifdef ENABLE_NLS
68 setlocale(LC_ALL, "");
69 bindtextdomain(PACKAGE, LOCALEDIR);
70 textdomain(PACKAGE);
71 #endif
72
73 while ((choice = getopt_long_only(argc, argv, "-uvj:nqf0123456789KMG",
74 long_options, (int *)0)) != EOF)
75 {
76 switch (choice) {
77 case 'u': {
78 resizefs_print_usage();
79 return 0;
80 }
81 case 'v': {
82 printf("%s %s\n", argv[0], VERSION);
83 return 0;
84 }
85 case 'n': {
86 journal = 0;
87 break;
88 }
89 case 'q': {
90 quiet = 1;
91 break;
92 }
93 case 'f': {
94 force = 1;
95 break;
96 }
97 case 'j': {
98 if (!progs_dev_check((journal_dev = optarg))) {
99 libreiserfs_exception_throw(EXCEPTION_ERROR, EXCEPTION_CANCEL,
100 _("Device %s doesn't exists or invalid."), journal_dev);
101 return 0;
102 }
103 }
104 case '0': case '1': case '2': case '3': case '4':
105 case '5': case '6': case '7': case '8': case '9':
106 case 'K': case 'M': case 'G': break;
107
108 case '?': {
109 resizefs_print_usage();
110 return 0xfe;
111 }
112 }
113 }
114
115 choice = argc - 1;
116 end_str = argv[choice--];
117
118 if (!progs_digit_check(end_str)) {
119 resizefs_print_usage();
120 return 0xfe;
121 }
122
123 start_str = argv[choice--];
124
125 if (!progs_digit_check(start_str)) {
126 libreiserfs_exception_fetch_all();
127 if (progs_dev_check(start_str)) {
128 libreiserfs_exception_leave_all();
129 host_dev = start_str;
130 start_str = NULL;
131 } else {
132 libreiserfs_exception_leave_all();
133 libreiserfs_exception_throw(EXCEPTION_ERROR, EXCEPTION_CANCEL,
134 _("Device %s doesn't exists or invalid."), start_str);
135 return 0xfe;
136 }
137 } else
138 host_dev = argv[choice];
139
140 /* Checking given device for validness */
141 if (!progs_dev_check(host_dev)) {
142 libreiserfs_exception_throw(EXCEPTION_ERROR, EXCEPTION_CANCEL,
143 _("Device %s doesn't exists or invalid."), host_dev);
144 return 0xfe;
145 }
146
147 /* Creating device abstraction layer */
148 if (!(host_dal = file_open(host_dev, DEFAULT_BLOCK_SIZE,
149 O_RDWR)))
150 {
151 libreiserfs_exception_throw(EXCEPTION_ERROR, EXCEPTION_CANCEL,
152 _("Couldn't open device %s. %s."), host_dev, strerror(errno));
153 goto error;
154 }
155
156 if (journal_dev) {
157 if (!strcmp(journal_dev, host_dev))
158 journal_dal = NULL;
159 else {
160 if (!(journal_dal = file_open(journal_dev, dal_get_blocksize(host_dal),
161 O_RDONLY)))
162 {
163 libreiserfs_exception_throw(EXCEPTION_ERROR, EXCEPTION_CANCEL,
164 _("Couldn't open device %s. %s."), journal_dev, strerror(errno));
165 goto error_free_host_dal;
166 }
167 }
168 }
169
170 if (!(fs = reiserfs_fs_open(host_dal,
171 (!journal ? NULL : (journal_dal ? journal_dal : host_dal)))))
172 {
173 libreiserfs_exception_throw(EXCEPTION_ERROR, EXCEPTION_CANCEL,
174 _("Couldn't open reiserfs on device %s."), host_dev);
175 goto error_free_journal_dal;
176 }
177
178 if ((start_str && !(start = progs_digit_parse(start_str,
179 reiserfs_fs_block_size(fs), &error)) && error) || start < 0)
180 {
181 libreiserfs_exception_throw(EXCEPTION_ERROR, EXCEPTION_CANCEL,
182 _("Invalid \"start\" modificator (%s)."), start_str);
183 goto error_free_fs;
184 }
185
186 if (!(end = progs_digit_parse(end_str,
187 reiserfs_fs_block_size(fs), &error)) && error)
188 {
189 libreiserfs_exception_throw(EXCEPTION_ERROR, EXCEPTION_CANCEL,
190 _("Invalid \"end\" modificator (%s)."), end_str);
191 goto error_free_fs;
192 }
193
194 if (end_str[0] == '-' || end_str[0] == '+')
195 end += reiserfs_fs_size(fs);
196
197 if (end < 0) {
198 libreiserfs_exception_throw(EXCEPTION_ERROR, EXCEPTION_CANCEL,
199 _("Invalid filesystem size (%d)."), end_str);
200 goto error_free_fs;
201 }
202
203 dev_len = dal_len(host_dal);
204
205 if (force) {
206 if (end > dev_len)
207 end = dev_len;
208
209 if ((blk_t)end < reiserfs_fs_min_size(fs))
210 end = reiserfs_fs_min_size(fs);
211 } else {
212 if (end > dev_len) {
213 libreiserfs_exception_throw(EXCEPTION_ERROR, EXCEPTION_CANCEL,
214 _("Can't resize filesystem outside the device."));
215 goto error_free_fs;
216 }
217 }
218
219 choice = 'y';
220 if (!quiet) {
221 if (!(choice = progs_choose("ynYN", _("Please select (y/n) "),
222 _("Are you ready (y/n) "))))
223 goto error_free_fs;
224 }
225
226 if (choice == 'n' || choice == 'N')
227 goto error_free_fs;
228
229 fprintf(stderr, _("Resizing %s\n"), host_dev);
230 fflush(stderr);
231
232 if (!(gauge = libreiserfs_gauge_create(REISERFS_GAUGE_PERCENTAGE, NULL, NULL)))
233 goto error_free_fs;
234
235 libreiserfs_set_gauge(gauge);
236
237 if (!(start == 0 ? reiserfs_fs_resize_dumb(fs, end) :
238 reiserfs_fs_resize_smart(fs, start, end)))
239 {
240 libreiserfs_exception_throw(EXCEPTION_ERROR, EXCEPTION_CANCEL,
241 _("Couldn't resize filesystem on %s to %lu - %lu blocks."), host_dev,
242 start, end);
243 goto error_free_gauge;
244 }
245
246 libreiserfs_gauge_free(gauge);
247 libreiserfs_set_gauge(NULL);
248
249 reiserfs_fs_close(fs);
250
251 if (!(gauge = libreiserfs_gauge_create(REISERFS_GAUGE_SILENT, _("syncing"), NULL)))
252 goto error_free_journal_dal;
253
254 libreiserfs_set_gauge(gauge);
255
256 if (journal_dal) {
257 if (!dal_sync(journal_dal)) {
258 libreiserfs_exception_throw(EXCEPTION_WARNING, EXCEPTION_OK,
259 "Can't synchronize device %s. %s.",
260 dal_name(journal_dal), dal_error(journal_dal));
261 }
262 file_close(journal_dal);
263 }
264
265 if (!dal_sync(host_dal)) {
266 libreiserfs_exception_throw(EXCEPTION_WARNING, EXCEPTION_OK,
267 "Can't synchronize device %s. %s.",
268 dal_name(host_dal), dal_error(host_dal));
269 }
270 file_close(host_dal);
271
272 libreiserfs_gauge_finish(gauge, 1);
273 libreiserfs_gauge_free(gauge);
274 libreiserfs_set_gauge(NULL);
275
276 return 0;
277
278 error_free_gauge:
279 libreiserfs_gauge_free(gauge);
280 libreiserfs_set_gauge(NULL);
281 error_free_fs:
282 reiserfs_fs_close(fs);
283 error_free_journal_dal:
284 if (journal_dal)
285 file_close(journal_dal);
286 error_free_host_dal:
287 file_close(host_dal);
288 error:
289 return 0xff;
290 }
291
292