~daniel-mehrmann/e2fsprogs/master

« back to all changes in this revision

Viewing changes to e2fsck/pass3.c

  • Committer: Daniel Mehrmann
  • Date: 2014-12-16 09:16:59 UTC
  • mfrom: (1.2.25)
  • Revision ID: daniel.mehrmann@gmx.de-20141216091659-ymhbl4ualba43vuc
Tags: 1.43-SN-2014-12-16-0ubuntu1
* Merge in snapshot from the maint branch 

Show diffs side-by-side

added added

removed removed

Lines of Context:
205
205
        ext2fs_mark_bb_dirty(fs);
206
206
 
207
207
        /*
208
 
         * Now let's create the actual data block for the inode
 
208
         * Set up the inode structure
 
209
         */
 
210
        memset(&inode, 0, sizeof(inode));
 
211
        inode.i_mode = 040755;
 
212
        inode.i_size = fs->blocksize;
 
213
        inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
 
214
        inode.i_links_count = 2;
 
215
        ext2fs_iblk_set(fs, &inode, 1);
 
216
        inode.i_block[0] = blk;
 
217
 
 
218
        /*
 
219
         * Write out the inode.
 
220
         */
 
221
        pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
 
222
        if (pctx.errcode) {
 
223
                pctx.str = "ext2fs_write_inode";
 
224
                fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
 
225
                ctx->flags |= E2F_FLAG_ABORT;
 
226
                return;
 
227
        }
 
228
 
 
229
        /*
 
230
         * Now let's create the actual data block for the inode.
 
231
         * Due to metadata_csum, we must write the dir blocks AFTER
 
232
         * the inode has been written to disk!
209
233
         */
210
234
        pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
211
235
                                            &block);
216
240
                return;
217
241
        }
218
242
 
219
 
        pctx.errcode = ext2fs_write_dir_block3(fs, blk, block, 0);
220
 
        if (pctx.errcode) {
221
 
                pctx.str = "ext2fs_write_dir_block3";
222
 
                fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
223
 
                ctx->flags |= E2F_FLAG_ABORT;
224
 
                return;
225
 
        }
 
243
        pctx.errcode = ext2fs_write_dir_block4(fs, blk, block, 0,
 
244
                                               EXT2_ROOT_INO);
226
245
        ext2fs_free_mem(&block);
227
 
 
228
 
        /*
229
 
         * Set up the inode structure
230
 
         */
231
 
        memset(&inode, 0, sizeof(inode));
232
 
        inode.i_mode = 040755;
233
 
        inode.i_size = fs->blocksize;
234
 
        inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
235
 
        inode.i_links_count = 2;
236
 
        ext2fs_iblk_set(fs, &inode, 1);
237
 
        inode.i_block[0] = blk;
238
 
 
239
 
        /*
240
 
         * Write out the inode.
241
 
         */
242
 
        pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
243
246
        if (pctx.errcode) {
244
 
                pctx.str = "ext2fs_write_inode";
 
247
                pctx.str = "ext2fs_write_dir_block4";
245
248
                fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
246
249
                ctx->flags |= E2F_FLAG_ABORT;
247
250
                return;
381
384
        char *                  block;
382
385
        static const char       name[] = "lost+found";
383
386
        struct  problem_context pctx;
 
387
        int                     will_rehash, flags;
384
388
 
385
389
        if (ctx->lost_and_found)
386
390
                return ctx->lost_and_found;
387
391
 
388
392
        clear_problem_context(&pctx);
389
393
 
 
394
        will_rehash = e2fsck_dir_will_be_rehashed(ctx, EXT2_ROOT_INO);
 
395
        if (will_rehash) {
 
396
                flags = ctx->fs->flags;
 
397
                ctx->fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
 
398
        }
390
399
        retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
391
400
                               sizeof(name)-1, 0, &ino);
 
401
        if (will_rehash)
 
402
                ctx->fs->flags = (flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) |
 
403
                        (ctx->fs->flags & ~EXT2_FLAG_IGNORE_CSUM_ERRORS);
392
404
        if (retval && !fix)
393
405
                return 0;
394
406
        if (!retval) {
395
 
                if (ext2fs_test_inode_bitmap2(ctx->inode_dir_map, ino)) {
 
407
                /* Lost+found shouldn't have inline data */
 
408
                retval = ext2fs_read_inode(fs, ino, &inode);
 
409
                if (fix && retval)
 
410
                        return 0;
 
411
 
 
412
                if (fix && (inode.i_flags & EXT4_INLINE_DATA_FL)) {
 
413
                        if (!fix_problem(ctx, PR_3_LPF_INLINE_DATA, &pctx))
 
414
                                return 0;
 
415
                        goto unlink;
 
416
                }
 
417
 
 
418
                if (ext2fs_check_directory(fs, ino) == 0) {
396
419
                        ctx->lost_and_found = ino;
397
420
                        return ino;
398
421
                }
404
427
                if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
405
428
                        return 0;
406
429
 
 
430
unlink:
407
431
                /* OK, unlink the old /lost+found file. */
408
432
                pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
409
433
                if (pctx.errcode) {
435
459
                goto skip_new_block;
436
460
        }
437
461
        retval = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
 
462
        if (retval == EXT2_ET_BLOCK_ALLOC_FAIL &&
 
463
            fix_problem(ctx, PR_3_LPF_NO_SPACE, &pctx)) {
 
464
                fix_problem(ctx, PR_3_NO_SPACE_TO_RECOVER, &pctx);
 
465
                ctx->lost_and_found = EXT2_ROOT_INO;
 
466
                return 0;
 
467
        }
438
468
        if (retval) {
439
469
                pctx.errcode = retval;
440
470
                fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
449
479
         */
450
480
        retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
451
481
                                  ctx->inode_used_map, &ino);
 
482
        if (retval == EXT2_ET_INODE_ALLOC_FAIL &&
 
483
            fix_problem(ctx, PR_3_LPF_NO_SPACE, &pctx)) {
 
484
                fix_problem(ctx, PR_3_NO_SPACE_TO_RECOVER, &pctx);
 
485
                ctx->lost_and_found = EXT2_ROOT_INO;
 
486
                return 0;
 
487
        }
452
488
        if (retval) {
453
489
                pctx.errcode = retval;
454
490
                fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
459
495
        ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
460
496
 
461
497
        /*
462
 
         * Now let's create the actual data block for the inode
 
498
         * Set up the inode structure
 
499
         */
 
500
        memset(&inode, 0, sizeof(inode));
 
501
        inode.i_mode = 040700;
 
502
        inode.i_size = fs->blocksize;
 
503
        inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
 
504
        inode.i_links_count = 2;
 
505
        ext2fs_iblk_set(fs, &inode, 1);
 
506
        inode.i_block[0] = blk;
 
507
 
 
508
        /*
 
509
         * Next, write out the inode.
 
510
         */
 
511
        pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
 
512
        if (pctx.errcode) {
 
513
                pctx.str = "ext2fs_write_inode";
 
514
                fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
 
515
                return 0;
 
516
        }
 
517
 
 
518
        /*
 
519
         * Now let's create the actual data block for the inode.
 
520
         * Due to metadata_csum, the directory block MUST be written
 
521
         * after the inode is written to disk!
463
522
         */
464
523
        retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
465
524
        if (retval) {
468
527
                return 0;
469
528
        }
470
529
 
471
 
        retval = ext2fs_write_dir_block3(fs, blk, block, 0);
 
530
        retval = ext2fs_write_dir_block4(fs, blk, block, 0, ino);
472
531
        ext2fs_free_mem(&block);
473
532
        if (retval) {
474
533
                pctx.errcode = retval;
477
536
        }
478
537
 
479
538
        /*
480
 
         * Set up the inode structure
481
 
         */
482
 
        memset(&inode, 0, sizeof(inode));
483
 
        inode.i_mode = 040700;
484
 
        inode.i_size = fs->blocksize;
485
 
        inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
486
 
        inode.i_links_count = 2;
487
 
        ext2fs_iblk_set(fs, &inode, 1);
488
 
        inode.i_block[0] = blk;
489
 
 
490
 
        /*
491
 
         * Next, write out the inode.
492
 
         */
493
 
        pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
494
 
        if (pctx.errcode) {
495
 
                pctx.str = "ext2fs_write_inode";
496
 
                fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
497
 
                return 0;
498
 
        }
499
 
        /*
500
539
         * Finally, create the directory link
501
540
         */
502
541
        pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
 
542
        if (pctx.errcode == EXT2_ET_DIR_NO_SPACE) {
 
543
                pctx.errcode = ext2fs_expand_dir(fs, EXT2_ROOT_INO);
 
544
                if (pctx.errcode)
 
545
                        goto link_error;
 
546
                pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino,
 
547
                                           EXT2_FT_DIR);
 
548
        }
503
549
        if (pctx.errcode) {
 
550
link_error:
504
551
                pctx.str = "ext2fs_link";
505
552
                fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
506
553
                return 0;
635
682
        errcode_t       retval;
636
683
        struct problem_context pctx;
637
684
 
638
 
        if ((dirent->name_len & 0xFF) != 2)
 
685
        if (ext2fs_dirent_name_len(dirent) != 2)
639
686
                return 0;
640
687
        if (strncmp(dirent->name, "..", 2))
641
688
                return 0;
655
702
        dirent->inode = fp->parent;
656
703
        if (fp->ctx->fs->super->s_feature_incompat &
657
704
            EXT2_FEATURE_INCOMPAT_FILETYPE)
658
 
                dirent->name_len = (dirent->name_len & 0xFF) |
659
 
                        (EXT2_FT_DIR << 8);
 
705
                ext2fs_dirent_set_file_type(dirent, EXT2_FT_DIR);
660
706
        else
661
 
                dirent->name_len = dirent->name_len & 0xFF;
 
707
                ext2fs_dirent_set_file_type(dirent, EXT2_FT_UNKNOWN);
662
708
 
663
709
        fp->done++;
664
710
        return DIRENT_ABORT | DIRENT_CHANGED;
670
716
        errcode_t       retval;
671
717
        struct fix_dotdot_struct fp;
672
718
        struct problem_context pctx;
 
719
        int             flags, will_rehash;
673
720
 
674
721
        fp.fs = fs;
675
722
        fp.parent = parent;
682
729
 
683
730
        clear_problem_context(&pctx);
684
731
        pctx.ino = ino;
 
732
        will_rehash = e2fsck_dir_will_be_rehashed(ctx, ino);
 
733
        if (will_rehash) {
 
734
                flags = ctx->fs->flags;
 
735
                ctx->fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
 
736
        }
685
737
        retval = ext2fs_dir_iterate(fs, ino, DIRENT_FLAG_INCLUDE_EMPTY,
686
738
                                    0, fix_dotdot_proc, &fp);
 
739
        if (will_rehash)
 
740
                ctx->fs->flags = (flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) |
 
741
                        (ctx->fs->flags & ~EXT2_FLAG_IGNORE_CSUM_ERRORS);
687
742
        if (retval || !fp.done) {
688
743
                pctx.errcode = retval;
689
744
                fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
709
764
        blk64_t                 last_block;
710
765
        errcode_t               err;
711
766
        e2fsck_t                ctx;
 
767
        ext2_ino_t              dir;
712
768
};
713
769
 
714
770
static int expand_dir_proc(ext2_filsys fs,
760
816
                        return BLOCK_ABORT;
761
817
                }
762
818
                es->num--;
763
 
                retval = ext2fs_write_dir_block3(fs, new_blk, block, 0);
764
 
        } else {
765
 
                retval = ext2fs_get_mem(fs->blocksize, &block);
766
 
                if (retval) {
767
 
                        es->err = retval;
768
 
                        return BLOCK_ABORT;
769
 
                }
770
 
                memset(block, 0, fs->blocksize);
771
 
                retval = io_channel_write_blk64(fs->io, new_blk, 1, block);
772
 
        }
 
819
                retval = ext2fs_write_dir_block4(fs, new_blk, block, 0,
 
820
                                                 es->dir);
 
821
                ext2fs_free_mem(&block);
 
822
        } else
 
823
                retval = ext2fs_zero_blocks2(fs, new_blk, 1, NULL, NULL);
773
824
        if (retval) {
774
825
                es->err = retval;
775
826
                return BLOCK_ABORT;
776
827
        }
777
 
        ext2fs_free_mem(&block);
778
828
        *blocknr = new_blk;
779
829
        ext2fs_mark_block_bitmap2(ctx->block_found_map, new_blk);
780
830
 
791
841
        errcode_t       retval;
792
842
        struct expand_dir_struct es;
793
843
        struct ext2_inode       inode;
794
 
        blk64_t         sz, before, after;
 
844
        blk64_t         sz;
795
845
 
796
846
        if (!(fs->flags & EXT2_FLAG_RW))
797
847
                return EXT2_ET_RO_FILSYS;
812
862
        es.err = 0;
813
863
        es.newblocks = 0;
814
864
        es.ctx = ctx;
 
865
        es.dir = dir;
815
866
 
816
867
        retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_APPEND,
817
868
                                       0, expand_dir_proc, &es);