1
2
3
4
5
6
7
8
9
10
11
12#define EXT4FS_DEBUG
13
14#include <linux/ext4_jbd2.h>
15
16#include <linux/errno.h>
17#include <linux/slab.h>
18
19#include "group.h"
20
21#define outside(b, first, last) ((b) < (first) || (b) >= (last))
22#define inside(b, first, last) ((b) >= (first) && (b) < (last))
23
24static int verify_group_input(struct super_block *sb,
25 struct ext4_new_group_data *input)
26{
27 struct ext4_sb_info *sbi = EXT4_SB(sb);
28 struct ext4_super_block *es = sbi->s_es;
29 ext4_fsblk_t start = ext4_blocks_count(es);
30 ext4_fsblk_t end = start + input->blocks_count;
31 unsigned group = input->group;
32 ext4_fsblk_t itend = input->inode_table + sbi->s_itb_per_group;
33 unsigned overhead = ext4_bg_has_super(sb, group) ?
34 (1 + ext4_bg_num_gdb(sb, group) +
35 le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
36 ext4_fsblk_t metaend = start + overhead;
37 struct buffer_head *bh = NULL;
38 ext4_grpblk_t free_blocks_count, offset;
39 int err = -EINVAL;
40
41 input->free_blocks_count = free_blocks_count =
42 input->blocks_count - 2 - overhead - sbi->s_itb_per_group;
43
44 if (test_opt(sb, DEBUG))
45 printk(KERN_DEBUG "EXT4-fs: adding %s group %u: %u blocks "
46 "(%d free, %u reserved)\n",
47 ext4_bg_has_super(sb, input->group) ? "normal" :
48 "no-super", input->group, input->blocks_count,
49 free_blocks_count, input->reserved_blocks);
50
51 ext4_get_group_no_and_offset(sb, start, NULL, &offset);
52 if (group != sbi->s_groups_count)
53 ext4_warning(sb, __FUNCTION__,
54 "Cannot add at group %u (only %lu groups)",
55 input->group, sbi->s_groups_count);
56 else if (offset != 0)
57 ext4_warning(sb, __FUNCTION__, "Last group not full");
58 else if (input->reserved_blocks > input->blocks_count / 5)
59 ext4_warning(sb, __FUNCTION__, "Reserved blocks too high (%u)",
60 input->reserved_blocks);
61 else if (free_blocks_count < 0)
62 ext4_warning(sb, __FUNCTION__, "Bad blocks count %u",
63 input->blocks_count);
64 else if (!(bh = sb_bread(sb, end - 1)))
65 ext4_warning(sb, __FUNCTION__,
66 "Cannot read last block (%llu)",
67 end - 1);
68 else if (outside(input->block_bitmap, start, end))
69 ext4_warning(sb, __FUNCTION__,
70 "Block bitmap not in group (block %llu)",
71 (unsigned long long)input->block_bitmap);
72 else if (outside(input->inode_bitmap, start, end))
73 ext4_warning(sb, __FUNCTION__,
74 "Inode bitmap not in group (block %llu)",
75 (unsigned long long)input->inode_bitmap);
76 else if (outside(input->inode_table, start, end) ||
77 outside(itend - 1, start, end))
78 ext4_warning(sb, __FUNCTION__,
79 "Inode table not in group (blocks %llu-%llu)",
80 (unsigned long long)input->inode_table, itend - 1);
81 else if (input->inode_bitmap == input->block_bitmap)
82 ext4_warning(sb, __FUNCTION__,
83 "Block bitmap same as inode bitmap (%llu)",
84 (unsigned long long)input->block_bitmap);
85 else if (inside(input->block_bitmap, input->inode_table, itend))
86 ext4_warning(sb, __FUNCTION__,
87 "Block bitmap (%llu) in inode table (%llu-%llu)",
88 (unsigned long long)input->block_bitmap,
89 (unsigned long long)input->inode_table, itend - 1);
90 else if (inside(input->inode_bitmap, input->inode_table, itend))
91 ext4_warning(sb, __FUNCTION__,
92 "Inode bitmap (%llu) in inode table (%llu-%llu)",
93 (unsigned long long)input->inode_bitmap,
94 (unsigned long long)input->inode_table, itend - 1);
95 else if (inside(input->block_bitmap, start, metaend))
96 ext4_warning(sb, __FUNCTION__,
97 "Block bitmap (%llu) in GDT table"
98 " (%llu-%llu)",
99 (unsigned long long)input->block_bitmap,
100 start, metaend - 1);
101 else if (inside(input->inode_bitmap, start, metaend))
102 ext4_warning(sb, __FUNCTION__,
103 "Inode bitmap (%llu) in GDT table"
104 " (%llu-%llu)",
105 (unsigned long long)input->inode_bitmap,
106 start, metaend - 1);
107 else if (inside(input->inode_table, start, metaend) ||
108 inside(itend - 1, start, metaend))
109 ext4_warning(sb, __FUNCTION__,
110 "Inode table (%llu-%llu) overlaps"
111 "GDT table (%llu-%llu)",
112 (unsigned long long)input->inode_table,
113 itend - 1, start, metaend - 1);
114 else
115 err = 0;
116 brelse(bh);
117
118 return err;
119}
120
121static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
122 ext4_fsblk_t blk)
123{
124 struct buffer_head *bh;
125 int err;
126
127 bh = sb_getblk(sb, blk);
128 if (!bh)
129 return ERR_PTR(-EIO);
130 if ((err = ext4_journal_get_write_access(handle, bh))) {
131 brelse(bh);
132 bh = ERR_PTR(err);
133 } else {
134 lock_buffer(bh);
135 memset(bh->b_data, 0, sb->s_blocksize);
136 set_buffer_uptodate(bh);
137 unlock_buffer(bh);
138 }
139
140 return bh;
141}
142
143
144
145
146
147
148static int extend_or_restart_transaction(handle_t *handle, int thresh,
149 struct buffer_head *bh)
150{
151 int err;
152
153 if (handle->h_buffer_credits >= thresh)
154 return 0;
155
156 err = ext4_journal_extend(handle, EXT4_MAX_TRANS_DATA);
157 if (err < 0)
158 return err;
159 if (err) {
160 if ((err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA)))
161 return err;
162 if ((err = ext4_journal_get_write_access(handle, bh)))
163 return err;
164 }
165
166 return 0;
167}
168
169
170
171
172
173
174
175
176static int setup_new_group_blocks(struct super_block *sb,
177 struct ext4_new_group_data *input)
178{
179 struct ext4_sb_info *sbi = EXT4_SB(sb);
180 ext4_fsblk_t start = ext4_group_first_block_no(sb, input->group);
181 int reserved_gdb = ext4_bg_has_super(sb, input->group) ?
182 le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) : 0;
183 unsigned long gdblocks = ext4_bg_num_gdb(sb, input->group);
184 struct buffer_head *bh;
185 handle_t *handle;
186 ext4_fsblk_t block;
187 ext4_grpblk_t bit;
188 int i;
189 int err = 0, err2;
190
191
192 handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA);
193
194 if (IS_ERR(handle))
195 return PTR_ERR(handle);
196
197 lock_super(sb);
198 if (input->group != sbi->s_groups_count) {
199 err = -EBUSY;
200 goto exit_journal;
201 }
202
203 if (IS_ERR(bh = bclean(handle, sb, input->block_bitmap))) {
204 err = PTR_ERR(bh);
205 goto exit_journal;
206 }
207
208 if (ext4_bg_has_super(sb, input->group)) {
209 ext4_debug("mark backup superblock %#04lx (+0)\n", start);
210 ext4_set_bit(0, bh->b_data);
211 }
212
213
214 for (i = 0, bit = 1, block = start + 1;
215 i < gdblocks; i++, block++, bit++) {
216 struct buffer_head *gdb;
217
218 ext4_debug("update backup group %#04lx (+%d)\n", block, bit);
219
220 if ((err = extend_or_restart_transaction(handle, 1, bh)))
221 goto exit_bh;
222
223 gdb = sb_getblk(sb, block);
224 if (!gdb) {
225 err = -EIO;
226 goto exit_bh;
227 }
228 if ((err = ext4_journal_get_write_access(handle, gdb))) {
229 brelse(gdb);
230 goto exit_bh;
231 }
232 lock_buffer(gdb);
233 memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size);
234 set_buffer_uptodate(gdb);
235 unlock_buffer(gdb);
236 ext4_journal_dirty_metadata(handle, gdb);
237 ext4_set_bit(bit, bh->b_data);
238 brelse(gdb);
239 }
240
241
242 for (i = 0, bit = gdblocks + 1, block = start + bit;
243 i < reserved_gdb; i++, block++, bit++) {
244 struct buffer_head *gdb;
245
246 ext4_debug("clear reserved block %#04lx (+%d)\n", block, bit);
247
248 if ((err = extend_or_restart_transaction(handle, 1, bh)))
249 goto exit_bh;
250
251 if (IS_ERR(gdb = bclean(handle, sb, block))) {
252 err = PTR_ERR(bh);
253 goto exit_bh;
254 }
255 ext4_journal_dirty_metadata(handle, gdb);
256 ext4_set_bit(bit, bh->b_data);
257 brelse(gdb);
258 }
259 ext4_debug("mark block bitmap %#04x (+%ld)\n", input->block_bitmap,
260 input->block_bitmap - start);
261 ext4_set_bit(input->block_bitmap - start, bh->b_data);
262 ext4_debug("mark inode bitmap %#04x (+%ld)\n", input->inode_bitmap,
263 input->inode_bitmap - start);
264 ext4_set_bit(input->inode_bitmap - start, bh->b_data);
265
266
267 for (i = 0, block = input->inode_table, bit = block - start;
268 i < sbi->s_itb_per_group; i++, bit++, block++) {
269 struct buffer_head *it;
270
271 ext4_debug("clear inode block %#04lx (+%d)\n", block, bit);
272
273 if ((err = extend_or_restart_transaction(handle, 1, bh)))
274 goto exit_bh;
275
276 if (IS_ERR(it = bclean(handle, sb, block))) {
277 err = PTR_ERR(it);
278 goto exit_bh;
279 }
280 ext4_journal_dirty_metadata(handle, it);
281 brelse(it);
282 ext4_set_bit(bit, bh->b_data);
283 }
284
285 if ((err = extend_or_restart_transaction(handle, 2, bh)))
286 goto exit_bh;
287
288 mark_bitmap_end(input->blocks_count, EXT4_BLOCKS_PER_GROUP(sb),
289 bh->b_data);
290 ext4_journal_dirty_metadata(handle, bh);
291 brelse(bh);
292
293
294 ext4_debug("clear inode bitmap %#04x (+%ld)\n",
295 input->inode_bitmap, input->inode_bitmap - start);
296 if (IS_ERR(bh = bclean(handle, sb, input->inode_bitmap))) {
297 err = PTR_ERR(bh);
298 goto exit_journal;
299 }
300
301 mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), EXT4_BLOCKS_PER_GROUP(sb),
302 bh->b_data);
303 ext4_journal_dirty_metadata(handle, bh);
304exit_bh:
305 brelse(bh);
306
307exit_journal:
308 unlock_super(sb);
309 if ((err2 = ext4_journal_stop(handle)) && !err)
310 err = err2;
311
312 return err;
313}
314
315
316
317
318
319
320
321
322static unsigned ext4_list_backups(struct super_block *sb, unsigned *three,
323 unsigned *five, unsigned *seven)
324{
325 unsigned *min = three;
326 int mult = 3;
327 unsigned ret;
328
329 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
330 EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
331 ret = *min;
332 *min += 1;
333 return ret;
334 }
335
336 if (*five < *min) {
337 min = five;
338 mult = 5;
339 }
340 if (*seven < *min) {
341 min = seven;
342 mult = 7;
343 }
344
345 ret = *min;
346 *min *= mult;
347
348 return ret;
349}
350
351
352
353
354
355
356static int verify_reserved_gdb(struct super_block *sb,
357 struct buffer_head *primary)
358{
359 const ext4_fsblk_t blk = primary->b_blocknr;
360 const unsigned long end = EXT4_SB(sb)->s_groups_count;
361 unsigned three = 1;
362 unsigned five = 5;
363 unsigned seven = 7;
364 unsigned grp;
365 __le32 *p = (__le32 *)primary->b_data;
366 int gdbackups = 0;
367
368 while ((grp = ext4_list_backups(sb, &three, &five, &seven)) < end) {
369 if (le32_to_cpu(*p++) !=
370 grp * EXT4_BLOCKS_PER_GROUP(sb) + blk){
371 ext4_warning(sb, __FUNCTION__,
372 "reserved GDT %llu"
373 " missing grp %d (%llu)",
374 blk, grp,
375 grp *
376 (ext4_fsblk_t)EXT4_BLOCKS_PER_GROUP(sb) +
377 blk);
378 return -EINVAL;
379 }
380 if (++gdbackups > EXT4_ADDR_PER_BLOCK(sb))
381 return -EFBIG;
382 }
383
384 return gdbackups;
385}
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400static int add_new_gdb(handle_t *handle, struct inode *inode,
401 struct ext4_new_group_data *input,
402 struct buffer_head **primary)
403{
404 struct super_block *sb = inode->i_sb;
405 struct ext4_super_block *es = EXT4_SB(sb)->s_es;
406 unsigned long gdb_num = input->group / EXT4_DESC_PER_BLOCK(sb);
407 ext4_fsblk_t gdblock = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + gdb_num;
408 struct buffer_head **o_group_desc, **n_group_desc;
409 struct buffer_head *dind;
410 int gdbackups;
411 struct ext4_iloc iloc;
412 __le32 *data;
413 int err;
414
415 if (test_opt(sb, DEBUG))
416 printk(KERN_DEBUG
417 "EXT4-fs: ext4_add_new_gdb: adding group block %lu\n",
418 gdb_num);
419
420
421
422
423
424
425 if (EXT4_SB(sb)->s_sbh->b_blocknr !=
426 le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) {
427 ext4_warning(sb, __FUNCTION__,
428 "won't resize using backup superblock at %llu",
429 (unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr);
430 return -EPERM;
431 }
432
433 *primary = sb_bread(sb, gdblock);
434 if (!*primary)
435 return -EIO;
436
437 if ((gdbackups = verify_reserved_gdb(sb, *primary)) < 0) {
438 err = gdbackups;
439 goto exit_bh;
440 }
441
442 data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK;
443 dind = sb_bread(sb, le32_to_cpu(*data));
444 if (!dind) {
445 err = -EIO;
446 goto exit_bh;
447 }
448
449 data = (__le32 *)dind->b_data;
450 if (le32_to_cpu(data[gdb_num % EXT4_ADDR_PER_BLOCK(sb)]) != gdblock) {
451 ext4_warning(sb, __FUNCTION__,
452 "new group %u GDT block %llu not reserved",
453 input->group, gdblock);
454 err = -EINVAL;
455 goto exit_dind;
456 }
457
458 if ((err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh)))
459 goto exit_dind;
460
461 if ((err = ext4_journal_get_write_access(handle, *primary)))
462 goto exit_sbh;
463
464 if ((err = ext4_journal_get_write_access(handle, dind)))
465 goto exit_primary;
466
467
468 if ((err = ext4_reserve_inode_write(handle, inode, &iloc)))
469 goto exit_dindj;
470
471 n_group_desc = kmalloc((gdb_num + 1) * sizeof(struct buffer_head *),
472 GFP_KERNEL);
473 if (!n_group_desc) {
474 err = -ENOMEM;
475 ext4_warning (sb, __FUNCTION__,
476 "not enough memory for %lu groups", gdb_num + 1);
477 goto exit_inode;
478 }
479
480
481
482
483
484
485
486
487
488
489 data[gdb_num % EXT4_ADDR_PER_BLOCK(sb)] = 0;
490 ext4_journal_dirty_metadata(handle, dind);
491 brelse(dind);
492 inode->i_blocks -= (gdbackups + 1) * sb->s_blocksize >> 9;
493 ext4_mark_iloc_dirty(handle, inode, &iloc);
494 memset((*primary)->b_data, 0, sb->s_blocksize);
495 ext4_journal_dirty_metadata(handle, *primary);
496
497 o_group_desc = EXT4_SB(sb)->s_group_desc;
498 memcpy(n_group_desc, o_group_desc,
499 EXT4_SB(sb)->s_gdb_count * sizeof(struct buffer_head *));
500 n_group_desc[gdb_num] = *primary;
501 EXT4_SB(sb)->s_group_desc = n_group_desc;
502 EXT4_SB(sb)->s_gdb_count++;
503 kfree(o_group_desc);
504
505 es->s_reserved_gdt_blocks =
506 cpu_to_le16(le16_to_cpu(es->s_reserved_gdt_blocks) - 1);
507 ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
508
509 return 0;
510
511exit_inode:
512
513 brelse(iloc.bh);
514exit_dindj:
515
516exit_primary:
517
518exit_sbh:
519
520exit_dind:
521 brelse(dind);
522exit_bh:
523 brelse(*primary);
524
525 ext4_debug("leaving with error %d\n", err);
526 return err;
527}
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542static int reserve_backup_gdb(handle_t *handle, struct inode *inode,
543 struct ext4_new_group_data *input)
544{
545 struct super_block *sb = inode->i_sb;
546 int reserved_gdb =le16_to_cpu(EXT4_SB(sb)->s_es->s_reserved_gdt_blocks);
547 struct buffer_head **primary;
548 struct buffer_head *dind;
549 struct ext4_iloc iloc;
550 ext4_fsblk_t blk;
551 __le32 *data, *end;
552 int gdbackups = 0;
553 int res, i;
554 int err;
555
556 primary = kmalloc(reserved_gdb * sizeof(*primary), GFP_KERNEL);
557 if (!primary)
558 return -ENOMEM;
559
560 data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK;
561 dind = sb_bread(sb, le32_to_cpu(*data));
562 if (!dind) {
563 err = -EIO;
564 goto exit_free;
565 }
566
567 blk = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + EXT4_SB(sb)->s_gdb_count;
568 data = (__le32 *)dind->b_data + EXT4_SB(sb)->s_gdb_count;
569 end = (__le32 *)dind->b_data + EXT4_ADDR_PER_BLOCK(sb);
570
571
572 for (res = 0; res < reserved_gdb; res++, blk++) {
573 if (le32_to_cpu(*data) != blk) {
574 ext4_warning(sb, __FUNCTION__,
575 "reserved block %llu"
576 " not at offset %ld",
577 blk,
578 (long)(data - (__le32 *)dind->b_data));
579 err = -EINVAL;
580 goto exit_bh;
581 }
582 primary[res] = sb_bread(sb, blk);
583 if (!primary[res]) {
584 err = -EIO;
585 goto exit_bh;
586 }
587 if ((gdbackups = verify_reserved_gdb(sb, primary[res])) < 0) {
588 brelse(primary[res]);
589 err = gdbackups;
590 goto exit_bh;
591 }
592 if (++data >= end)
593 data = (__le32 *)dind->b_data;
594 }
595
596 for (i = 0; i < reserved_gdb; i++) {
597 if ((err = ext4_journal_get_write_access(handle, primary[i]))) {
598
599
600
601
602
603 goto exit_bh;
604 }
605 }
606
607 if ((err = ext4_reserve_inode_write(handle, inode, &iloc)))
608 goto exit_bh;
609
610
611
612
613
614 blk = input->group * EXT4_BLOCKS_PER_GROUP(sb);
615 for (i = 0; i < reserved_gdb; i++) {
616 int err2;
617 data = (__le32 *)primary[i]->b_data;
618
619
620
621 data[gdbackups] = cpu_to_le32(blk + primary[i]->b_blocknr);
622 err2 = ext4_journal_dirty_metadata(handle, primary[i]);
623 if (!err)
624 err = err2;
625 }
626 inode->i_blocks += reserved_gdb * sb->s_blocksize >> 9;
627 ext4_mark_iloc_dirty(handle, inode, &iloc);
628
629exit_bh:
630 while (--res >= 0)
631 brelse(primary[res]);
632 brelse(dind);
633
634exit_free:
635 kfree(primary);
636
637 return err;
638}
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655static void update_backups(struct super_block *sb,
656 int blk_off, char *data, int size)
657{
658 struct ext4_sb_info *sbi = EXT4_SB(sb);
659 const unsigned long last = sbi->s_groups_count;
660 const int bpg = EXT4_BLOCKS_PER_GROUP(sb);
661 unsigned three = 1;
662 unsigned five = 5;
663 unsigned seven = 7;
664 unsigned group;
665 int rest = sb->s_blocksize - size;
666 handle_t *handle;
667 int err = 0, err2;
668
669 handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA);
670 if (IS_ERR(handle)) {
671 group = 1;
672 err = PTR_ERR(handle);
673 goto exit_err;
674 }
675
676 while ((group = ext4_list_backups(sb, &three, &five, &seven)) < last) {
677 struct buffer_head *bh;
678
679
680 if (handle->h_buffer_credits == 0 &&
681 ext4_journal_extend(handle, EXT4_MAX_TRANS_DATA) &&
682 (err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA)))
683 break;
684
685 bh = sb_getblk(sb, group * bpg + blk_off);
686 if (!bh) {
687 err = -EIO;
688 break;
689 }
690 ext4_debug("update metadata backup %#04lx\n",
691 (unsigned long)bh->b_blocknr);
692 if ((err = ext4_journal_get_write_access(handle, bh)))
693 break;
694 lock_buffer(bh);
695 memcpy(bh->b_data, data, size);
696 if (rest)
697 memset(bh->b_data + size, 0, rest);
698 set_buffer_uptodate(bh);
699 unlock_buffer(bh);
700 ext4_journal_dirty_metadata(handle, bh);
701 brelse(bh);
702 }
703 if ((err2 = ext4_journal_stop(handle)) && !err)
704 err = err2;
705
706
707
708
709
710
711
712
713
714
715
716exit_err:
717 if (err) {
718 ext4_warning(sb, __FUNCTION__,
719 "can't update backup for group %d (err %d), "
720 "forcing fsck on next reboot", group, err);
721 sbi->s_mount_state &= ~EXT4_VALID_FS;
722 sbi->s_es->s_state &= cpu_to_le16(~EXT4_VALID_FS);
723 mark_buffer_dirty(sbi->s_sbh);
724 }
725}
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
741{
742 struct ext4_sb_info *sbi = EXT4_SB(sb);
743 struct ext4_super_block *es = sbi->s_es;
744 int reserved_gdb = ext4_bg_has_super(sb, input->group) ?
745 le16_to_cpu(es->s_reserved_gdt_blocks) : 0;
746 struct buffer_head *primary = NULL;
747 struct ext4_group_desc *gdp;
748 struct inode *inode = NULL;
749 handle_t *handle;
750 int gdb_off, gdb_num;
751 int err, err2;
752
753 gdb_num = input->group / EXT4_DESC_PER_BLOCK(sb);
754 gdb_off = input->group % EXT4_DESC_PER_BLOCK(sb);
755
756 if (gdb_off == 0 && !EXT4_HAS_RO_COMPAT_FEATURE(sb,
757 EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
758 ext4_warning(sb, __FUNCTION__,
759 "Can't resize non-sparse filesystem further");
760 return -EPERM;
761 }
762
763 if (ext4_blocks_count(es) + input->blocks_count <
764 ext4_blocks_count(es)) {
765 ext4_warning(sb, __FUNCTION__, "blocks_count overflow\n");
766 return -EINVAL;
767 }
768
769 if (le32_to_cpu(es->s_inodes_count) + EXT4_INODES_PER_GROUP(sb) <
770 le32_to_cpu(es->s_inodes_count)) {
771 ext4_warning(sb, __FUNCTION__, "inodes_count overflow\n");
772 return -EINVAL;
773 }
774
775 if (reserved_gdb || gdb_off == 0) {
776 if (!EXT4_HAS_COMPAT_FEATURE(sb,
777 EXT4_FEATURE_COMPAT_RESIZE_INODE)){
778 ext4_warning(sb, __FUNCTION__,
779 "No reserved GDT blocks, can't resize");
780 return -EPERM;
781 }
782 inode = iget(sb, EXT4_RESIZE_INO);
783 if (!inode || is_bad_inode(inode)) {
784 ext4_warning(sb, __FUNCTION__,
785 "Error opening resize inode");
786 iput(inode);
787 return -ENOENT;
788 }
789 }
790
791 if ((err = verify_group_input(sb, input)))
792 goto exit_put;
793
794 if ((err = setup_new_group_blocks(sb, input)))
795 goto exit_put;
796
797
798
799
800
801
802
803
804 handle = ext4_journal_start_sb(sb,
805 ext4_bg_has_super(sb, input->group) ?
806 3 + reserved_gdb : 4);
807 if (IS_ERR(handle)) {
808 err = PTR_ERR(handle);
809 goto exit_put;
810 }
811
812 lock_super(sb);
813 if (input->group != sbi->s_groups_count) {
814 ext4_warning(sb, __FUNCTION__,
815 "multiple resizers run on filesystem!");
816 err = -EBUSY;
817 goto exit_journal;
818 }
819
820 if ((err = ext4_journal_get_write_access(handle, sbi->s_sbh)))
821 goto exit_journal;
822
823
824
825
826
827
828
829 if (gdb_off) {
830 primary = sbi->s_group_desc[gdb_num];
831 if ((err = ext4_journal_get_write_access(handle, primary)))
832 goto exit_journal;
833
834 if (reserved_gdb && ext4_bg_num_gdb(sb, input->group) &&
835 (err = reserve_backup_gdb(handle, inode, input)))
836 goto exit_journal;
837 } else if ((err = add_new_gdb(handle, inode, input, &primary)))
838 goto exit_journal;
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860 gdp = (struct ext4_group_desc *)primary->b_data + gdb_off;
861
862 ext4_block_bitmap_set(sb, gdp, input->block_bitmap);
863 ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap);
864 ext4_inode_table_set(sb, gdp, input->inode_table);
865 gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count);
866 gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb));
867 gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp);
868
869
870
871
872
873
874
875
876
877
878
879 ext4_blocks_count_set(es, ext4_blocks_count(es) +
880 input->blocks_count);
881 es->s_inodes_count = cpu_to_le32(le32_to_cpu(es->s_inodes_count) +
882 EXT4_INODES_PER_GROUP(sb));
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906 smp_wmb();
907
908
909 sbi->s_groups_count++;
910
911 ext4_journal_dirty_metadata(handle, primary);
912
913
914
915 ext4_r_blocks_count_set(es, ext4_r_blocks_count(es) +
916 input->reserved_blocks);
917
918
919 percpu_counter_add(&sbi->s_freeblocks_counter,
920 input->free_blocks_count);
921 percpu_counter_add(&sbi->s_freeinodes_counter,
922 EXT4_INODES_PER_GROUP(sb));
923
924 ext4_journal_dirty_metadata(handle, sbi->s_sbh);
925 sb->s_dirt = 1;
926
927exit_journal:
928 unlock_super(sb);
929 if ((err2 = ext4_journal_stop(handle)) && !err)
930 err = err2;
931 if (!err) {
932 update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
933 sizeof(struct ext4_super_block));
934 update_backups(sb, primary->b_blocknr, primary->b_data,
935 primary->b_size);
936 }
937exit_put:
938 iput(inode);
939 return err;
940}
941
942
943
944
945
946
947
948
949
950
951int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
952 ext4_fsblk_t n_blocks_count)
953{
954 ext4_fsblk_t o_blocks_count;
955 unsigned long o_groups_count;
956 ext4_grpblk_t last;
957 ext4_grpblk_t add;
958 struct buffer_head * bh;
959 handle_t *handle;
960 int err;
961 unsigned long freed_blocks;
962
963
964
965
966 o_blocks_count = ext4_blocks_count(es);
967 o_groups_count = EXT4_SB(sb)->s_groups_count;
968
969 if (test_opt(sb, DEBUG))
970 printk(KERN_DEBUG "EXT4-fs: extending last group from %llu uto %llu blocks\n",
971 o_blocks_count, n_blocks_count);
972
973 if (n_blocks_count == 0 || n_blocks_count == o_blocks_count)
974 return 0;
975
976 if (n_blocks_count > (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {
977 printk(KERN_ERR "EXT4-fs: filesystem on %s:"
978 " too large to resize to %llu blocks safely\n",
979 sb->s_id, n_blocks_count);
980 if (sizeof(sector_t) < 8)
981 ext4_warning(sb, __FUNCTION__,
982 "CONFIG_LBD not enabled\n");
983 return -EINVAL;
984 }
985
986 if (n_blocks_count < o_blocks_count) {
987 ext4_warning(sb, __FUNCTION__,
988 "can't shrink FS - resize aborted");
989 return -EBUSY;
990 }
991
992
993 ext4_get_group_no_and_offset(sb, o_blocks_count, NULL, &last);
994
995 if (last == 0) {
996 ext4_warning(sb, __FUNCTION__,
997 "need to use ext2online to resize further");
998 return -EPERM;
999 }
1000
1001 add = EXT4_BLOCKS_PER_GROUP(sb) - last;
1002
1003 if (o_blocks_count + add < o_blocks_count) {
1004 ext4_warning(sb, __FUNCTION__, "blocks_count overflow");
1005 return -EINVAL;
1006 }
1007
1008 if (o_blocks_count + add > n_blocks_count)
1009 add = n_blocks_count - o_blocks_count;
1010
1011 if (o_blocks_count + add < n_blocks_count)
1012 ext4_warning(sb, __FUNCTION__,
1013 "will only finish group (%llu"
1014 " blocks, %u new)",
1015 o_blocks_count + add, add);
1016
1017
1018 bh = sb_bread(sb, o_blocks_count + add -1);
1019 if (!bh) {
1020 ext4_warning(sb, __FUNCTION__,
1021 "can't read last block, resize aborted");
1022 return -ENOSPC;
1023 }
1024 brelse(bh);
1025
1026
1027
1028
1029 handle = ext4_journal_start_sb(sb, 3);
1030 if (IS_ERR(handle)) {
1031 err = PTR_ERR(handle);
1032 ext4_warning(sb, __FUNCTION__, "error %d on journal start",err);
1033 goto exit_put;
1034 }
1035
1036 lock_super(sb);
1037 if (o_blocks_count != ext4_blocks_count(es)) {
1038 ext4_warning(sb, __FUNCTION__,
1039 "multiple resizers run on filesystem!");
1040 unlock_super(sb);
1041 err = -EBUSY;
1042 goto exit_put;
1043 }
1044
1045 if ((err = ext4_journal_get_write_access(handle,
1046 EXT4_SB(sb)->s_sbh))) {
1047 ext4_warning(sb, __FUNCTION__,
1048 "error %d on journal write access", err);
1049 unlock_super(sb);
1050 ext4_journal_stop(handle);
1051 goto exit_put;
1052 }
1053 ext4_blocks_count_set(es, o_blocks_count + add);
1054 ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
1055 sb->s_dirt = 1;
1056 unlock_super(sb);
1057 ext4_debug("freeing blocks %lu through %llu\n", o_blocks_count,
1058 o_blocks_count + add);
1059 ext4_free_blocks_sb(handle, sb, o_blocks_count, add, &freed_blocks);
1060 ext4_debug("freed blocks %llu through %llu\n", o_blocks_count,
1061 o_blocks_count + add);
1062 if ((err = ext4_journal_stop(handle)))
1063 goto exit_put;
1064 if (test_opt(sb, DEBUG))
1065 printk(KERN_DEBUG "EXT4-fs: extended group to %llu blocks\n",
1066 ext4_blocks_count(es));
1067 update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr, (char *)es,
1068 sizeof(struct ext4_super_block));
1069exit_put:
1070 return err;
1071}
1072