Whamcloud - gitweb
e2fsck: port fc changes from kernel's recovery.c to e2fsck
[tools/e2fsprogs.git] / e2fsck / journal.c
1 /*
2  * journal.c --- code for handling the "ext3" journal
3  *
4  * Copyright (C) 2000 Andreas Dilger
5  * Copyright (C) 2000 Theodore Ts'o
6  *
7  * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
8  * Copyright (C) 1999 Red Hat Software
9  *
10  * This file may be redistributed under the terms of the
11  * GNU General Public License version 2 or at your discretion
12  * any later version.
13  */
14
15 #include "config.h"
16 #ifdef HAVE_SYS_MOUNT_H
17 #include <sys/param.h>
18 #include <sys/mount.h>
19 #define MNT_FL (MS_MGC_VAL | MS_RDONLY)
20 #endif
21 #ifdef HAVE_SYS_STAT_H
22 #include <sys/stat.h>
23 #endif
24
25 #define E2FSCK_INCLUDE_INLINE_FUNCS
26 #include "jfs_user.h"
27 #include "problem.h"
28 #include "uuid/uuid.h"
29
30 #ifdef CONFIG_JBD_DEBUG         /* Enabled by configure --enable-jfs-debug */
31 static int bh_count = 0;
32 #endif
33
34 /*
35  * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
36  * This creates a larger static binary, and a smaller binary using
37  * shared libraries.  It's also probably slightly less CPU-efficient,
38  * which is why it's not on by default.  But, it's a good way of
39  * testing the functions in inode_io.c and fileio.c.
40  */
41 #undef USE_INODE_IO
42
43 /* Checksumming functions */
44 static int e2fsck_journal_verify_csum_type(journal_t *j,
45                                            journal_superblock_t *jsb)
46 {
47         if (!jbd2_journal_has_csum_v2or3(j))
48                 return 1;
49
50         return jsb->s_checksum_type == JBD2_CRC32C_CHKSUM;
51 }
52
53 static __u32 e2fsck_journal_sb_csum(journal_superblock_t *jsb)
54 {
55         __u32 crc, old_crc;
56
57         old_crc = jsb->s_checksum;
58         jsb->s_checksum = 0;
59         crc = ext2fs_crc32c_le(~0, (unsigned char *)jsb,
60                                sizeof(journal_superblock_t));
61         jsb->s_checksum = old_crc;
62
63         return crc;
64 }
65
66 static int e2fsck_journal_sb_csum_verify(journal_t *j,
67                                          journal_superblock_t *jsb)
68 {
69         __u32 provided, calculated;
70
71         if (!jbd2_journal_has_csum_v2or3(j))
72                 return 1;
73
74         provided = ext2fs_be32_to_cpu(jsb->s_checksum);
75         calculated = e2fsck_journal_sb_csum(jsb);
76
77         return provided == calculated;
78 }
79
80 static errcode_t e2fsck_journal_sb_csum_set(journal_t *j,
81                                             journal_superblock_t *jsb)
82 {
83         __u32 crc;
84
85         if (!jbd2_journal_has_csum_v2or3(j))
86                 return 0;
87
88         crc = e2fsck_journal_sb_csum(jsb);
89         jsb->s_checksum = ext2fs_cpu_to_be32(crc);
90         return 0;
91 }
92
93 /* Kernel compatibility functions for handling the journal.  These allow us
94  * to use the recovery.c file virtually unchanged from the kernel, so we
95  * don't have to do much to keep kernel and user recovery in sync.
96  */
97 int jbd2_journal_bmap(journal_t *journal, unsigned long block,
98                       unsigned long long *phys)
99 {
100 #ifdef USE_INODE_IO
101         *phys = block;
102         return 0;
103 #else
104         struct inode    *inode = journal->j_inode;
105         errcode_t       retval;
106         blk64_t         pblk;
107
108         if (!inode) {
109                 *phys = block;
110                 return 0;
111         }
112
113         retval= ext2fs_bmap2(inode->i_ctx->fs, inode->i_ino,
114                              &inode->i_ext2, NULL, 0, (blk64_t) block,
115                              0, &pblk);
116         *phys = pblk;
117         return -1 * ((int) retval);
118 #endif
119 }
120
121 struct buffer_head *getblk(kdev_t kdev, unsigned long long blocknr,
122                            int blocksize)
123 {
124         struct buffer_head *bh;
125         int bufsize = sizeof(*bh) + kdev->k_ctx->fs->blocksize -
126                 sizeof(bh->b_data);
127
128         bh = e2fsck_allocate_memory(kdev->k_ctx, bufsize, "block buffer");
129         if (!bh)
130                 return NULL;
131
132 #ifdef CONFIG_JBD_DEBUG
133         if (journal_enable_debug >= 3)
134                 bh_count++;
135 #endif
136         jfs_debug(4, "getblk for block %llu (%d bytes)(total %d)\n",
137                   blocknr, blocksize, bh_count);
138
139         bh->b_ctx = kdev->k_ctx;
140         if (kdev->k_dev == K_DEV_FS)
141                 bh->b_io = kdev->k_ctx->fs->io;
142         else
143                 bh->b_io = kdev->k_ctx->journal_io;
144         bh->b_size = blocksize;
145         bh->b_blocknr = blocknr;
146
147         return bh;
148 }
149
150 int sync_blockdev(kdev_t kdev)
151 {
152         io_channel      io;
153
154         if (kdev->k_dev == K_DEV_FS)
155                 io = kdev->k_ctx->fs->io;
156         else
157                 io = kdev->k_ctx->journal_io;
158
159         return io_channel_flush(io) ? -EIO : 0;
160 }
161
162 void ll_rw_block(int rw, int op_flags, int nr, struct buffer_head *bhp[])
163 {
164         errcode_t retval;
165         struct buffer_head *bh;
166
167         for (; nr > 0; --nr) {
168                 bh = *bhp++;
169                 if (rw == REQ_OP_READ && !bh->b_uptodate) {
170                         jfs_debug(3, "reading block %llu/%p\n",
171                                   bh->b_blocknr, (void *) bh);
172                         retval = io_channel_read_blk64(bh->b_io,
173                                                      bh->b_blocknr,
174                                                      1, bh->b_data);
175                         if (retval) {
176                                 com_err(bh->b_ctx->device_name, retval,
177                                         "while reading block %llu\n",
178                                         bh->b_blocknr);
179                                 bh->b_err = (int) retval;
180                                 continue;
181                         }
182                         bh->b_uptodate = 1;
183                 } else if (rw == REQ_OP_WRITE && bh->b_dirty) {
184                         jfs_debug(3, "writing block %llu/%p\n",
185                                   bh->b_blocknr,
186                                   (void *) bh);
187                         retval = io_channel_write_blk64(bh->b_io,
188                                                       bh->b_blocknr,
189                                                       1, bh->b_data);
190                         if (retval) {
191                                 com_err(bh->b_ctx->device_name, retval,
192                                         "while writing block %llu\n",
193                                         bh->b_blocknr);
194                                 bh->b_err = (int) retval;
195                                 continue;
196                         }
197                         bh->b_dirty = 0;
198                         bh->b_uptodate = 1;
199                 } else {
200                         jfs_debug(3, "no-op %s for block %llu\n",
201                                   rw == REQ_OP_READ ? "read" : "write",
202                                   bh->b_blocknr);
203                 }
204         }
205 }
206
207 void mark_buffer_dirty(struct buffer_head *bh)
208 {
209         bh->b_dirty = 1;
210 }
211
212 static void mark_buffer_clean(struct buffer_head * bh)
213 {
214         bh->b_dirty = 0;
215 }
216
217 void brelse(struct buffer_head *bh)
218 {
219         if (bh->b_dirty)
220                 ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
221         jfs_debug(3, "freeing block %llu/%p (total %d)\n",
222                   bh->b_blocknr, (void *) bh, --bh_count);
223         ext2fs_free_mem(&bh);
224 }
225
226 int buffer_uptodate(struct buffer_head *bh)
227 {
228         return bh->b_uptodate;
229 }
230
231 void mark_buffer_uptodate(struct buffer_head *bh, int val)
232 {
233         bh->b_uptodate = val;
234 }
235
236 void wait_on_buffer(struct buffer_head *bh)
237 {
238         if (!bh->b_uptodate)
239                 ll_rw_block(REQ_OP_READ, 0, 1, &bh);
240 }
241
242
243 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
244 {
245         ext2fs_clear_feature_journal_needs_recovery(ctx->fs->super);
246
247         /* if we had an error doing journal recovery, we need a full fsck */
248         if (error)
249                 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
250         ext2fs_mark_super_dirty(ctx->fs);
251 }
252
253 /*
254  * This is a helper function to check the validity of the journal.
255  */
256 struct process_block_struct {
257         e2_blkcnt_t     last_block;
258 };
259
260 static int process_journal_block(ext2_filsys fs,
261                                  blk64_t        *block_nr,
262                                  e2_blkcnt_t blockcnt,
263                                  blk64_t ref_block EXT2FS_ATTR((unused)),
264                                  int ref_offset EXT2FS_ATTR((unused)),
265                                  void *priv_data)
266 {
267         struct process_block_struct *p;
268         blk64_t blk = *block_nr;
269
270         p = (struct process_block_struct *) priv_data;
271
272         if (!blk || blk < fs->super->s_first_data_block ||
273             blk >= ext2fs_blocks_count(fs->super))
274                 return BLOCK_ABORT;
275
276         if (blockcnt >= 0)
277                 p->last_block = blockcnt;
278         return 0;
279 }
280
281 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
282 {
283         struct process_block_struct pb;
284         struct ext2_super_block *sb = ctx->fs->super;
285         struct ext2_super_block jsuper;
286         struct problem_context  pctx;
287         struct buffer_head      *bh;
288         struct inode            *j_inode = NULL;
289         struct kdev_s           *dev_fs = NULL, *dev_journal;
290         const char              *journal_name = 0;
291         journal_t               *journal = NULL;
292         errcode_t               retval = 0;
293         io_manager              io_ptr = 0;
294         unsigned long long      start = 0;
295         int                     ret;
296         int                     ext_journal = 0;
297         int                     tried_backup_jnl = 0;
298
299         clear_problem_context(&pctx);
300
301         journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
302         if (!journal) {
303                 return EXT2_ET_NO_MEMORY;
304         }
305
306         dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
307         if (!dev_fs) {
308                 retval = EXT2_ET_NO_MEMORY;
309                 goto errout;
310         }
311         dev_journal = dev_fs+1;
312
313         dev_fs->k_ctx = dev_journal->k_ctx = ctx;
314         dev_fs->k_dev = K_DEV_FS;
315         dev_journal->k_dev = K_DEV_JOURNAL;
316
317         journal->j_dev = dev_journal;
318         journal->j_fs_dev = dev_fs;
319         journal->j_inode = NULL;
320         journal->j_blocksize = ctx->fs->blocksize;
321
322         if (uuid_is_null(sb->s_journal_uuid)) {
323                 if (!sb->s_journal_inum) {
324                         retval = EXT2_ET_BAD_INODE_NUM;
325                         goto errout;
326                 }
327                 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
328                                                  "journal inode");
329                 if (!j_inode) {
330                         retval = EXT2_ET_NO_MEMORY;
331                         goto errout;
332                 }
333
334                 j_inode->i_ctx = ctx;
335                 j_inode->i_ino = sb->s_journal_inum;
336
337                 if ((retval = ext2fs_read_inode(ctx->fs,
338                                                 sb->s_journal_inum,
339                                                 &j_inode->i_ext2))) {
340                 try_backup_journal:
341                         if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
342                             tried_backup_jnl)
343                                 goto errout;
344                         memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
345                         memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
346                                EXT2_N_BLOCKS*4);
347                         j_inode->i_ext2.i_size_high = sb->s_jnl_blocks[15];
348                         j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
349                         j_inode->i_ext2.i_links_count = 1;
350                         j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
351                         e2fsck_use_inode_shortcuts(ctx, 1);
352                         ctx->stashed_ino = j_inode->i_ino;
353                         ctx->stashed_inode = &j_inode->i_ext2;
354                         tried_backup_jnl++;
355                 }
356                 if (!j_inode->i_ext2.i_links_count ||
357                     !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
358                         retval = EXT2_ET_NO_JOURNAL;
359                         goto try_backup_journal;
360                 }
361                 if (EXT2_I_SIZE(&j_inode->i_ext2) / journal->j_blocksize <
362                     JBD2_MIN_JOURNAL_BLOCKS) {
363                         retval = EXT2_ET_JOURNAL_TOO_SMALL;
364                         goto try_backup_journal;
365                 }
366                 pb.last_block = -1;
367                 retval = ext2fs_block_iterate3(ctx->fs, j_inode->i_ino,
368                                                BLOCK_FLAG_HOLE, 0,
369                                                process_journal_block, &pb);
370                 if ((pb.last_block + 1) * ctx->fs->blocksize <
371                     (int) EXT2_I_SIZE(&j_inode->i_ext2)) {
372                         retval = EXT2_ET_JOURNAL_TOO_SMALL;
373                         goto try_backup_journal;
374                 }
375                 if (tried_backup_jnl && !(ctx->options & E2F_OPT_READONLY)) {
376                         retval = ext2fs_write_inode(ctx->fs, sb->s_journal_inum,
377                                                     &j_inode->i_ext2);
378                         if (retval)
379                                 goto errout;
380                 }
381
382                 journal->j_total_len = EXT2_I_SIZE(&j_inode->i_ext2) /
383                         journal->j_blocksize;
384
385 #ifdef USE_INODE_IO
386                 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
387                                                  &j_inode->i_ext2,
388                                                  &journal_name);
389                 if (retval)
390                         goto errout;
391
392                 io_ptr = inode_io_manager;
393 #else
394                 journal->j_inode = j_inode;
395                 ctx->journal_io = ctx->fs->io;
396                 if ((ret = jbd2_journal_bmap(journal, 0, &start)) != 0) {
397                         retval = (errcode_t) (-1 * ret);
398                         goto errout;
399                 }
400 #endif
401         } else {
402                 ext_journal = 1;
403                 if (!ctx->journal_name) {
404                         char uuid[37];
405
406                         uuid_unparse(sb->s_journal_uuid, uuid);
407                         ctx->journal_name = blkid_get_devname(ctx->blkid,
408                                                               "UUID", uuid);
409                         if (!ctx->journal_name)
410                                 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
411                 }
412                 journal_name = ctx->journal_name;
413
414                 if (!journal_name) {
415                         fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
416                         retval = EXT2_ET_LOAD_EXT_JOURNAL;
417                         goto errout;
418                 }
419
420                 jfs_debug(1, "Using journal file %s\n", journal_name);
421                 io_ptr = unix_io_manager;
422         }
423
424 #if 0
425         test_io_backing_manager = io_ptr;
426         io_ptr = test_io_manager;
427 #endif
428 #ifndef USE_INODE_IO
429         if (ext_journal)
430 #endif
431         {
432                 int flags = IO_FLAG_RW;
433                 if (!(ctx->mount_flags & EXT2_MF_ISROOT &&
434                       ctx->mount_flags & EXT2_MF_READONLY))
435                         flags |= IO_FLAG_EXCLUSIVE;
436                 if ((ctx->mount_flags & EXT2_MF_READONLY) &&
437                     (ctx->options & E2F_OPT_FORCE))
438                         flags &= ~IO_FLAG_EXCLUSIVE;
439
440
441                 retval = io_ptr->open(journal_name, flags,
442                                       &ctx->journal_io);
443         }
444         if (retval)
445                 goto errout;
446
447         io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
448
449         if (ext_journal) {
450                 blk64_t maxlen;
451
452                 start = ext2fs_journal_sb_start(ctx->fs->blocksize) - 1;
453                 bh = getblk(dev_journal, start, ctx->fs->blocksize);
454                 if (!bh) {
455                         retval = EXT2_ET_NO_MEMORY;
456                         goto errout;
457                 }
458                 ll_rw_block(REQ_OP_READ, 0, 1, &bh);
459                 if ((retval = bh->b_err) != 0) {
460                         brelse(bh);
461                         goto errout;
462                 }
463                 memcpy(&jsuper, start ? bh->b_data :  bh->b_data + SUPERBLOCK_OFFSET,
464                        sizeof(jsuper));
465 #ifdef WORDS_BIGENDIAN
466                 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
467                         ext2fs_swap_super(&jsuper);
468 #endif
469                 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
470                     !ext2fs_has_feature_journal_dev(&jsuper)) {
471                         fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
472                         retval = EXT2_ET_LOAD_EXT_JOURNAL;
473                         brelse(bh);
474                         goto errout;
475                 }
476                 /* Make sure the journal UUID is correct */
477                 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
478                            sizeof(jsuper.s_uuid))) {
479                         fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
480                         retval = EXT2_ET_LOAD_EXT_JOURNAL;
481                         brelse(bh);
482                         goto errout;
483                 }
484
485                 /* Check the superblock checksum */
486                 if (ext2fs_has_feature_metadata_csum(&jsuper)) {
487                         struct struct_ext2_filsys fsx;
488                         struct ext2_super_block superx;
489                         void *p;
490
491                         p = start ? bh->b_data : bh->b_data + SUPERBLOCK_OFFSET;
492                         memcpy(&fsx, ctx->fs, sizeof(fsx));
493                         memcpy(&superx, ctx->fs->super, sizeof(superx));
494                         fsx.super = &superx;
495                         ext2fs_set_feature_metadata_csum(fsx.super);
496                         if (!ext2fs_superblock_csum_verify(&fsx, p) &&
497                             fix_problem(ctx, PR_0_EXT_JOURNAL_SUPER_CSUM_INVALID,
498                                         &pctx)) {
499                                 ext2fs_superblock_csum_set(&fsx, p);
500                                 mark_buffer_dirty(bh);
501                         }
502                 }
503                 brelse(bh);
504
505                 maxlen = ext2fs_blocks_count(&jsuper);
506                 journal->j_total_len = (maxlen < 1ULL << 32) ? maxlen : (1ULL << 32) - 1;
507                 start++;
508         }
509
510         if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
511                 retval = EXT2_ET_NO_MEMORY;
512                 goto errout;
513         }
514
515         journal->j_sb_buffer = bh;
516         journal->j_superblock = (journal_superblock_t *)bh->b_data;
517
518 #ifdef USE_INODE_IO
519         if (j_inode)
520                 ext2fs_free_mem(&j_inode);
521 #endif
522
523         *ret_journal = journal;
524         e2fsck_use_inode_shortcuts(ctx, 0);
525         return 0;
526
527 errout:
528         e2fsck_use_inode_shortcuts(ctx, 0);
529         if (dev_fs)
530                 ext2fs_free_mem(&dev_fs);
531         if (j_inode)
532                 ext2fs_free_mem(&j_inode);
533         if (journal)
534                 ext2fs_free_mem(&journal);
535         return retval;
536 }
537
538 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
539                                               struct problem_context *pctx)
540 {
541         struct ext2_super_block *sb = ctx->fs->super;
542         int recover = ext2fs_has_feature_journal_needs_recovery(ctx->fs->super);
543         int has_journal = ext2fs_has_feature_journal(ctx->fs->super);
544
545         if (has_journal || sb->s_journal_inum) {
546                 /* The journal inode is bogus, remove and force full fsck */
547                 pctx->ino = sb->s_journal_inum;
548                 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
549                         if (has_journal && sb->s_journal_inum)
550                                 printf("*** journal has been deleted ***\n\n");
551                         ext2fs_clear_feature_journal(sb);
552                         sb->s_journal_inum = 0;
553                         memset(sb->s_jnl_blocks, 0, sizeof(sb->s_jnl_blocks));
554                         ctx->flags |= E2F_FLAG_JOURNAL_INODE;
555                         ctx->fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
556                         e2fsck_clear_recover(ctx, 1);
557                         return 0;
558                 }
559                 return EXT2_ET_CORRUPT_JOURNAL_SB;
560         } else if (recover) {
561                 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
562                         e2fsck_clear_recover(ctx, 1);
563                         return 0;
564                 }
565                 return EXT2_ET_UNSUPP_FEATURE;
566         }
567         return 0;
568 }
569
570 #define V1_SB_SIZE      0x0024
571 static void clear_v2_journal_fields(journal_t *journal)
572 {
573         e2fsck_t ctx = journal->j_dev->k_ctx;
574         struct problem_context pctx;
575
576         clear_problem_context(&pctx);
577
578         if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
579                 return;
580
581         ctx->flags |= E2F_FLAG_PROBLEMS_FIXED;
582         memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
583                ctx->fs->blocksize-V1_SB_SIZE);
584         mark_buffer_dirty(journal->j_sb_buffer);
585 }
586
587
588 static errcode_t e2fsck_journal_load(journal_t *journal)
589 {
590         e2fsck_t ctx = journal->j_dev->k_ctx;
591         journal_superblock_t *jsb;
592         struct buffer_head *jbh = journal->j_sb_buffer;
593         struct problem_context pctx;
594
595         clear_problem_context(&pctx);
596
597         ll_rw_block(REQ_OP_READ, 0, 1, &jbh);
598         if (jbh->b_err) {
599                 com_err(ctx->device_name, jbh->b_err, "%s",
600                         _("reading journal superblock\n"));
601                 return jbh->b_err;
602         }
603
604         jsb = journal->j_superblock;
605         /* If we don't even have JBD2_MAGIC, we probably have a wrong inode */
606         if (jsb->s_header.h_magic != htonl(JBD2_MAGIC_NUMBER))
607                 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
608
609         switch (ntohl(jsb->s_header.h_blocktype)) {
610         case JBD2_SUPERBLOCK_V1:
611                 journal->j_format_version = 1;
612                 if (jsb->s_feature_compat ||
613                     jsb->s_feature_incompat ||
614                     jsb->s_feature_ro_compat ||
615                     jsb->s_nr_users)
616                         clear_v2_journal_fields(journal);
617                 break;
618
619         case JBD2_SUPERBLOCK_V2:
620                 journal->j_format_version = 2;
621                 if (ntohl(jsb->s_nr_users) > 1 &&
622                     uuid_is_null(ctx->fs->super->s_journal_uuid))
623                         clear_v2_journal_fields(journal);
624                 if (ntohl(jsb->s_nr_users) > 1) {
625                         fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
626                         return EXT2_ET_JOURNAL_UNSUPP_VERSION;
627                 }
628                 break;
629
630         /*
631          * These should never appear in a journal super block, so if
632          * they do, the journal is badly corrupted.
633          */
634         case JBD2_DESCRIPTOR_BLOCK:
635         case JBD2_COMMIT_BLOCK:
636         case JBD2_REVOKE_BLOCK:
637                 return EXT2_ET_CORRUPT_JOURNAL_SB;
638
639         /* If we don't understand the superblock major type, but there
640          * is a magic number, then it is likely to be a new format we
641          * just don't understand, so leave it alone. */
642         default:
643                 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
644         }
645
646         if (JBD2_HAS_INCOMPAT_FEATURE(journal, ~JBD2_KNOWN_INCOMPAT_FEATURES))
647                 return EXT2_ET_UNSUPP_FEATURE;
648
649         if (JBD2_HAS_RO_COMPAT_FEATURE(journal, ~JBD2_KNOWN_ROCOMPAT_FEATURES))
650                 return EXT2_ET_RO_UNSUPP_FEATURE;
651
652         /* Checksum v1-3 are mutually exclusive features. */
653         if (jbd2_has_feature_csum2(journal) && jbd2_has_feature_csum3(journal))
654                 return EXT2_ET_CORRUPT_JOURNAL_SB;
655
656         if (jbd2_journal_has_csum_v2or3(journal) &&
657             jbd2_has_feature_checksum(journal))
658                 return EXT2_ET_CORRUPT_JOURNAL_SB;
659
660         if (!e2fsck_journal_verify_csum_type(journal, jsb) ||
661             !e2fsck_journal_sb_csum_verify(journal, jsb))
662                 return EXT2_ET_CORRUPT_JOURNAL_SB;
663
664         if (jbd2_journal_has_csum_v2or3(journal))
665                 journal->j_csum_seed = jbd2_chksum(journal, ~0, jsb->s_uuid,
666                                                    sizeof(jsb->s_uuid));
667
668         /* We have now checked whether we know enough about the journal
669          * format to be able to proceed safely, so any other checks that
670          * fail we should attempt to recover from. */
671         if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
672                 com_err(ctx->program_name, EXT2_ET_CORRUPT_JOURNAL_SB,
673                         _("%s: no valid journal superblock found\n"),
674                         ctx->device_name);
675                 return EXT2_ET_CORRUPT_JOURNAL_SB;
676         }
677
678         if (ntohl(jsb->s_maxlen) < journal->j_total_len)
679                 journal->j_total_len = ntohl(jsb->s_maxlen);
680         else if (ntohl(jsb->s_maxlen) > journal->j_total_len) {
681                 com_err(ctx->program_name, EXT2_ET_CORRUPT_JOURNAL_SB,
682                         _("%s: journal too short\n"),
683                         ctx->device_name);
684                 return EXT2_ET_CORRUPT_JOURNAL_SB;
685         }
686
687         journal->j_tail_sequence = ntohl(jsb->s_sequence);
688         journal->j_transaction_sequence = journal->j_tail_sequence;
689         journal->j_tail = ntohl(jsb->s_start);
690         journal->j_first = ntohl(jsb->s_first);
691         if (jbd2_has_feature_fast_commit(journal)) {
692                 if (ntohl(jsb->s_maxlen) - jbd_get_num_fc_blks(jsb)
693                         < JBD2_MIN_JOURNAL_BLOCKS) {
694                         com_err(ctx->program_name, EXT2_ET_CORRUPT_JOURNAL_SB,
695                                 _("%s: incorrect fast commit blocks\n"),
696                                 ctx->device_name);
697                         return EXT2_ET_CORRUPT_JOURNAL_SB;
698                 }
699                 journal->j_fc_last = ntohl(jsb->s_maxlen);
700                 journal->j_last = journal->j_fc_last -
701                                         jbd_get_num_fc_blks(jsb);
702                 journal->j_fc_first = journal->j_last + 1;
703         } else {
704                 journal->j_last = ntohl(jsb->s_maxlen);
705         }
706
707         return 0;
708 }
709
710 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
711                                        journal_t *journal)
712 {
713         char *p;
714         union {
715                 uuid_t uuid;
716                 __u32 val[4];
717         } u;
718         __u32 new_seq = 0;
719         int i;
720
721         /* Leave a valid existing V1 superblock signature alone.
722          * Anything unrecognisable we overwrite with a new V2
723          * signature. */
724
725         if (jsb->s_header.h_magic != htonl(JBD2_MAGIC_NUMBER) ||
726             jsb->s_header.h_blocktype != htonl(JBD2_SUPERBLOCK_V1)) {
727                 jsb->s_header.h_magic = htonl(JBD2_MAGIC_NUMBER);
728                 jsb->s_header.h_blocktype = htonl(JBD2_SUPERBLOCK_V2);
729         }
730
731         /* Zero out everything else beyond the superblock header */
732
733         p = ((char *) jsb) + sizeof(journal_header_t);
734         memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
735
736         jsb->s_blocksize = htonl(ctx->fs->blocksize);
737         jsb->s_maxlen = htonl(journal->j_total_len);
738         jsb->s_first = htonl(1);
739
740         /* Initialize the journal sequence number so that there is "no"
741          * chance we will find old "valid" transactions in the journal.
742          * This avoids the need to zero the whole journal (slow to do,
743          * and risky when we are just recovering the filesystem).
744          */
745         uuid_generate(u.uuid);
746         for (i = 0; i < 4; i ++)
747                 new_seq ^= u.val[i];
748         jsb->s_sequence = htonl(new_seq);
749         e2fsck_journal_sb_csum_set(journal, jsb);
750
751         mark_buffer_dirty(journal->j_sb_buffer);
752         ll_rw_block(REQ_OP_WRITE, 0, 1, &journal->j_sb_buffer);
753 }
754
755 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
756                                                   journal_t *journal,
757                                                   struct problem_context *pctx)
758 {
759         struct ext2_super_block *sb = ctx->fs->super;
760         int recover = ext2fs_has_feature_journal_needs_recovery(ctx->fs->super);
761
762         if (ext2fs_has_feature_journal(sb)) {
763                 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
764                         e2fsck_journal_reset_super(ctx, journal->j_superblock,
765                                                    journal);
766                         journal->j_transaction_sequence = 1;
767                         e2fsck_clear_recover(ctx, recover);
768                         return 0;
769                 }
770                 return EXT2_ET_CORRUPT_JOURNAL_SB;
771         } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
772                 return EXT2_ET_CORRUPT_JOURNAL_SB;
773
774         return 0;
775 }
776
777 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
778                                    int reset, int drop)
779 {
780         journal_superblock_t *jsb;
781
782         if (drop)
783                 mark_buffer_clean(journal->j_sb_buffer);
784         else if (!(ctx->options & E2F_OPT_READONLY)) {
785                 jsb = journal->j_superblock;
786                 jsb->s_sequence = htonl(journal->j_tail_sequence);
787                 if (reset)
788                         jsb->s_start = 0; /* this marks the journal as empty */
789                 e2fsck_journal_sb_csum_set(journal, jsb);
790                 mark_buffer_dirty(journal->j_sb_buffer);
791         }
792         brelse(journal->j_sb_buffer);
793
794         if (ctx->journal_io) {
795                 if (ctx->fs && ctx->fs->io != ctx->journal_io)
796                         io_channel_close(ctx->journal_io);
797                 ctx->journal_io = 0;
798         }
799
800 #ifndef USE_INODE_IO
801         if (journal->j_inode)
802                 ext2fs_free_mem(&journal->j_inode);
803 #endif
804         if (journal->j_fs_dev)
805                 ext2fs_free_mem(&journal->j_fs_dev);
806         ext2fs_free_mem(&journal);
807 }
808
809 /*
810  * This function makes sure that the superblock fields regarding the
811  * journal are consistent.
812  */
813 errcode_t e2fsck_check_ext3_journal(e2fsck_t ctx)
814 {
815         struct ext2_super_block *sb = ctx->fs->super;
816         journal_t *journal;
817         int recover = ext2fs_has_feature_journal_needs_recovery(ctx->fs->super);
818         struct problem_context pctx;
819         problem_t problem;
820         int reset = 0, force_fsck = 0;
821         errcode_t retval;
822
823         /* If we don't have any journal features, don't do anything more */
824         if (!ext2fs_has_feature_journal(sb) &&
825             !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
826             uuid_is_null(sb->s_journal_uuid))
827                 return 0;
828
829         clear_problem_context(&pctx);
830         pctx.num = sb->s_journal_inum;
831
832         retval = e2fsck_get_journal(ctx, &journal);
833         if (retval) {
834                 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
835                     (retval == EXT2_ET_BAD_BLOCK_NUM) ||
836                     (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
837                     (retval == EXT2_ET_NO_JOURNAL))
838                         return e2fsck_journal_fix_bad_inode(ctx, &pctx);
839                 return retval;
840         }
841
842         retval = e2fsck_journal_load(journal);
843         if (retval) {
844                 if ((retval == EXT2_ET_CORRUPT_JOURNAL_SB) ||
845                     ((retval == EXT2_ET_UNSUPP_FEATURE) &&
846                     (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
847                                   &pctx))) ||
848                     ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
849                     (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
850                                   &pctx))) ||
851                     ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
852                     (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
853                         retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
854                                                                   &pctx);
855                 e2fsck_journal_release(ctx, journal, 0, 1);
856                 return retval;
857         }
858
859         /*
860          * We want to make the flags consistent here.  We will not leave with
861          * needs_recovery set but has_journal clear.  We can't get in a loop
862          * with -y, -n, or -p, only if a user isn't making up their mind.
863          */
864 no_has_journal:
865         if (!ext2fs_has_feature_journal(sb)) {
866                 recover = ext2fs_has_feature_journal_needs_recovery(sb);
867                 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
868                         if (recover &&
869                             !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
870                                 goto no_has_journal;
871                         /*
872                          * Need a full fsck if we are releasing a
873                          * journal stored on a reserved inode.
874                          */
875                         force_fsck = recover ||
876                                 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
877                         /* Clear all of the journal fields */
878                         sb->s_journal_inum = 0;
879                         sb->s_journal_dev = 0;
880                         memset(sb->s_journal_uuid, 0,
881                                sizeof(sb->s_journal_uuid));
882                         e2fsck_clear_recover(ctx, force_fsck);
883                 } else if (!(ctx->options & E2F_OPT_READONLY)) {
884                         ext2fs_set_feature_journal(sb);
885                         ctx->fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
886                         ext2fs_mark_super_dirty(ctx->fs);
887                 }
888         }
889
890         if (ext2fs_has_feature_journal(sb) &&
891             !ext2fs_has_feature_journal_needs_recovery(sb) &&
892             journal->j_superblock->s_start != 0) {
893                 /* Print status information */
894                 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
895                 if (ctx->superblock)
896                         problem = PR_0_JOURNAL_RUN_DEFAULT;
897                 else
898                         problem = PR_0_JOURNAL_RUN;
899                 if (fix_problem(ctx, problem, &pctx)) {
900                         ctx->options |= E2F_OPT_FORCE;
901                         ext2fs_set_feature_journal_needs_recovery(sb);
902                         ext2fs_mark_super_dirty(ctx->fs);
903                 } else if (fix_problem(ctx,
904                                        PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
905                         reset = 1;
906                         sb->s_state &= ~EXT2_VALID_FS;
907                         ext2fs_mark_super_dirty(ctx->fs);
908                 }
909                 /*
910                  * If the user answers no to the above question, we
911                  * ignore the fact that journal apparently has data;
912                  * accidentally replaying over valid data would be far
913                  * worse than skipping a questionable recovery.
914                  *
915                  * XXX should we abort with a fatal error here?  What
916                  * will the ext3 kernel code do if a filesystem with
917                  * !NEEDS_RECOVERY but with a non-zero
918                  * journal->j_superblock->s_start is mounted?
919                  */
920         }
921
922         /*
923          * If we don't need to do replay the journal, check to see if
924          * the journal's errno is set; if so, we need to mark the file
925          * system as being corrupt and clear the journal's s_errno.
926          */
927         if (!ext2fs_has_feature_journal_needs_recovery(sb) &&
928             journal->j_superblock->s_errno) {
929                 ctx->fs->super->s_state |= EXT2_ERROR_FS;
930                 ext2fs_mark_super_dirty(ctx->fs);
931                 journal->j_superblock->s_errno = 0;
932                 e2fsck_journal_sb_csum_set(journal, journal->j_superblock);
933                 mark_buffer_dirty(journal->j_sb_buffer);
934         }
935
936         e2fsck_journal_release(ctx, journal, reset, 0);
937         return retval;
938 }
939
940 static errcode_t recover_ext3_journal(e2fsck_t ctx)
941 {
942         struct problem_context  pctx;
943         journal_t *journal;
944         errcode_t retval;
945
946         clear_problem_context(&pctx);
947
948         retval = jbd2_journal_init_revoke_record_cache();
949         if (retval)
950                 return retval;
951
952         retval = jbd2_journal_init_revoke_table_cache();
953         if (retval)
954                 return retval;
955
956         retval = e2fsck_get_journal(ctx, &journal);
957         if (retval)
958                 return retval;
959
960         retval = e2fsck_journal_load(journal);
961         if (retval)
962                 goto errout;
963
964         retval = jbd2_journal_init_revoke(journal, 1024);
965         if (retval)
966                 goto errout;
967
968         retval = -jbd2_journal_recover(journal);
969         if (retval)
970                 goto errout;
971
972         if (journal->j_failed_commit) {
973                 pctx.ino = journal->j_failed_commit;
974                 fix_problem(ctx, PR_0_JNL_TXN_CORRUPT, &pctx);
975                 journal->j_superblock->s_errno = -EINVAL;
976                 mark_buffer_dirty(journal->j_sb_buffer);
977         }
978
979         journal->j_tail_sequence = journal->j_transaction_sequence;
980
981 errout:
982         jbd2_journal_destroy_revoke(journal);
983         jbd2_journal_destroy_revoke_record_cache();
984         jbd2_journal_destroy_revoke_table_cache();
985         e2fsck_journal_release(ctx, journal, 1, 0);
986         return retval;
987 }
988
989 errcode_t e2fsck_run_ext3_journal(e2fsck_t ctx)
990 {
991         io_manager io_ptr = ctx->fs->io->manager;
992         int blocksize = ctx->fs->blocksize;
993         errcode_t       retval, recover_retval;
994         io_stats        stats = 0;
995         unsigned long long kbytes_written = 0;
996
997         printf(_("%s: recovering journal\n"), ctx->device_name);
998         if (ctx->options & E2F_OPT_READONLY) {
999                 printf(_("%s: won't do journal recovery while read-only\n"),
1000                        ctx->device_name);
1001                 return EXT2_ET_FILE_RO;
1002         }
1003
1004         if (ctx->fs->flags & EXT2_FLAG_DIRTY)
1005                 ext2fs_flush(ctx->fs);  /* Force out any modifications */
1006
1007         recover_retval = recover_ext3_journal(ctx);
1008
1009         /*
1010          * Reload the filesystem context to get up-to-date data from disk
1011          * because journal recovery will change the filesystem under us.
1012          */
1013         if (ctx->fs->super->s_kbytes_written &&
1014             ctx->fs->io->manager->get_stats)
1015                 ctx->fs->io->manager->get_stats(ctx->fs->io, &stats);
1016         if (stats && stats->bytes_written)
1017                 kbytes_written = stats->bytes_written >> 10;
1018
1019         ext2fs_mmp_stop(ctx->fs);
1020         ext2fs_free(ctx->fs);
1021         retval = ext2fs_open(ctx->filesystem_name, ctx->openfs_flags,
1022                              ctx->superblock, blocksize, io_ptr,
1023                              &ctx->fs);
1024         if (retval) {
1025                 com_err(ctx->program_name, retval,
1026                         _("while trying to re-open %s"),
1027                         ctx->device_name);
1028                 fatal_error(ctx, 0);
1029         }
1030         ctx->fs->priv_data = ctx;
1031         ctx->fs->now = ctx->now;
1032         ctx->fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
1033         ctx->fs->super->s_kbytes_written += kbytes_written;
1034
1035         /* Set the superblock flags */
1036         e2fsck_clear_recover(ctx, recover_retval != 0);
1037
1038         /*
1039          * Do one last sanity check, and propagate journal->s_errno to
1040          * the EXT2_ERROR_FS flag in the fs superblock if needed.
1041          */
1042         retval = e2fsck_check_ext3_journal(ctx);
1043         return retval ? retval : recover_retval;
1044 }
1045
1046 /*
1047  * This function will move the journal inode from a visible file in
1048  * the filesystem directory hierarchy to the reserved inode if necessary.
1049  */
1050 static const char * const journal_names[] = {
1051         ".journal", "journal", ".journal.dat", "journal.dat", 0 };
1052
1053 void e2fsck_move_ext3_journal(e2fsck_t ctx)
1054 {
1055         struct ext2_super_block *sb = ctx->fs->super;
1056         struct problem_context  pctx;
1057         struct ext2_inode       inode;
1058         ext2_filsys             fs = ctx->fs;
1059         ext2_ino_t              ino;
1060         errcode_t               retval;
1061         const char * const *    cpp;
1062         dgrp_t                  group;
1063         int                     mount_flags;
1064
1065         clear_problem_context(&pctx);
1066
1067         /*
1068          * If the filesystem is opened read-only, or there is no
1069          * journal, then do nothing.
1070          */
1071         if ((ctx->options & E2F_OPT_READONLY) ||
1072             (sb->s_journal_inum == 0) ||
1073             !ext2fs_has_feature_journal(sb))
1074                 return;
1075
1076         /*
1077          * Read in the journal inode
1078          */
1079         if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
1080                 return;
1081
1082         /*
1083          * If it's necessary to backup the journal inode, do so.
1084          */
1085         if ((sb->s_jnl_backup_type == 0) ||
1086             ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
1087              memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
1088                 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
1089                         memcpy(sb->s_jnl_blocks, inode.i_block,
1090                                EXT2_N_BLOCKS*4);
1091                         sb->s_jnl_blocks[15] = inode.i_size_high;
1092                         sb->s_jnl_blocks[16] = inode.i_size;
1093                         sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
1094                         ext2fs_mark_super_dirty(fs);
1095                         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
1096                 }
1097         }
1098
1099         /*
1100          * If the journal is already the hidden inode, then do nothing
1101          */
1102         if (sb->s_journal_inum == EXT2_JOURNAL_INO)
1103                 return;
1104
1105         /*
1106          * The journal inode had better have only one link and not be readable.
1107          */
1108         if (inode.i_links_count != 1)
1109                 return;
1110
1111         /*
1112          * If the filesystem is mounted, or we can't tell whether
1113          * or not it's mounted, do nothing.
1114          */
1115         retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
1116         if (retval || (mount_flags & EXT2_MF_MOUNTED))
1117                 return;
1118
1119         /*
1120          * If we can't find the name of the journal inode, then do
1121          * nothing.
1122          */
1123         for (cpp = journal_names; *cpp; cpp++) {
1124                 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
1125                                        strlen(*cpp), 0, &ino);
1126                 if ((retval == 0) && (ino == sb->s_journal_inum))
1127                         break;
1128         }
1129         if (*cpp == 0)
1130                 return;
1131
1132         /* We need the inode bitmap to be loaded */
1133         retval = ext2fs_read_bitmaps(fs);
1134         if (retval)
1135                 return;
1136
1137         pctx.str = *cpp;
1138         if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
1139                 return;
1140
1141         /*
1142          * OK, we've done all the checks, let's actually move the
1143          * journal inode.  Errors at this point mean we need to force
1144          * an ext2 filesystem check.
1145          */
1146         if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
1147                 goto err_out;
1148         if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
1149                 goto err_out;
1150         sb->s_journal_inum = EXT2_JOURNAL_INO;
1151         ext2fs_mark_super_dirty(fs);
1152         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
1153         inode.i_links_count = 0;
1154         inode.i_dtime = ctx->now;
1155         if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
1156                 goto err_out;
1157
1158         group = ext2fs_group_of_ino(fs, ino);
1159         ext2fs_unmark_inode_bitmap2(fs->inode_map, ino);
1160         ext2fs_mark_ib_dirty(fs);
1161         ext2fs_bg_free_inodes_count_set(fs, group, ext2fs_bg_free_inodes_count(fs, group) + 1);
1162         ext2fs_group_desc_csum_set(fs, group);
1163         fs->super->s_free_inodes_count++;
1164         return;
1165
1166 err_out:
1167         pctx.errcode = retval;
1168         fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
1169         fs->super->s_state &= ~EXT2_VALID_FS;
1170         ext2fs_mark_super_dirty(fs);
1171         return;
1172 }
1173
1174 /*
1175  * This function makes sure the superblock hint for the external
1176  * journal is correct.
1177  */
1178 int e2fsck_fix_ext3_journal_hint(e2fsck_t ctx)
1179 {
1180         struct ext2_super_block *sb = ctx->fs->super;
1181         struct problem_context pctx;
1182         char uuid[37], *journal_name;
1183         struct stat st;
1184
1185         if (!ext2fs_has_feature_journal(sb) ||
1186             uuid_is_null(sb->s_journal_uuid))
1187                 return 0;
1188
1189         uuid_unparse(sb->s_journal_uuid, uuid);
1190         journal_name = blkid_get_devname(ctx->blkid, "UUID", uuid);
1191         if (!journal_name)
1192                 return 0;
1193
1194         if (stat(journal_name, &st) < 0) {
1195                 free(journal_name);
1196                 return 0;
1197         }
1198
1199         if (st.st_rdev != sb->s_journal_dev) {
1200                 clear_problem_context(&pctx);
1201                 pctx.num = st.st_rdev;
1202                 if (fix_problem(ctx, PR_0_EXTERNAL_JOURNAL_HINT, &pctx)) {
1203                         sb->s_journal_dev = st.st_rdev;
1204                         ext2fs_mark_super_dirty(ctx->fs);
1205                 }
1206         }
1207
1208         free(journal_name);
1209         return 0;
1210 }