mkjournal.c revision 4e246704eab31407ac15be9ab206c6f929507cf0
1d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o/* 2d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o * mkjournal.c --- make a journal for a filesystem 3d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o * 4d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o * Copyright (C) 2000 Theodore Ts'o. 5d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o * 6d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o * %Begin-Header% 7d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o * This file may be redistributed under the terms of the GNU Public 8d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o * License. 9d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o * %End-Header% 10d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o */ 11d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 12d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#include <stdio.h> 13d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#include <string.h> 14d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#if HAVE_UNISTD_H 15d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#include <unistd.h> 16d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#endif 17d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#if HAVE_ERRNO_H 18d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#include <errno.h> 19d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#endif 20d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#include <fcntl.h> 21d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#include <time.h> 22d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#if HAVE_SYS_STAT_H 23d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#include <sys/stat.h> 24d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#endif 25d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#if HAVE_SYS_TYPES_H 26d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#include <sys/types.h> 27d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#endif 2817ee8b17f91988a3beedbd96eec4642e784f3251Theodore Ts'o#if HAVE_NETINET_IN_H 2917ee8b17f91988a3beedbd96eec4642e784f3251Theodore Ts'o#include <netinet/in.h> 3017ee8b17f91988a3beedbd96eec4642e784f3251Theodore Ts'o#endif 31d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 32d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#if EXT2_FLAT_INCLUDES 33d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#include "ext2_fs.h" 34d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#else 35d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#include <linux/ext2_fs.h> 36d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#endif 37d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 38d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#include "ext2fs.h" 39586187372afea65ae685687505b49b40fc5f3212Theodore Ts'o#include "jfs_user.h" 40d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 41d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'ostatic void init_journal_superblock(journal_superblock_t *jsb, 424e246704eab31407ac15be9ab206c6f929507cf0Theodore Ts'o __u32 blocksize, __u32 size, int flags) 43d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o{ 44586187372afea65ae685687505b49b40fc5f3212Theodore Ts'o memset (jsb, 0, sizeof(*jsb)); 45586187372afea65ae685687505b49b40fc5f3212Theodore Ts'o 46d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER); 474e246704eab31407ac15be9ab206c6f929507cf0Theodore Ts'o if (flags & EXT2_MKJOURNAL_V1_SUPER) 484e246704eab31407ac15be9ab206c6f929507cf0Theodore Ts'o jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V1); 494e246704eab31407ac15be9ab206c6f929507cf0Theodore Ts'o else 504e246704eab31407ac15be9ab206c6f929507cf0Theodore Ts'o jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2); 51d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o jsb->s_blocksize = htonl(blocksize); 52d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o jsb->s_maxlen = htonl(size); 53d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o jsb->s_first = htonl(1); 54d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o jsb->s_sequence = htonl(1); 55d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o} 56d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 57d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o/* 58d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o * This function adds a journal device to a filesystem 59d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o */ 60d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'oerrcode_t ext2fs_add_journal_device(ext2_filsys fs, char *device, 614e246704eab31407ac15be9ab206c6f929507cf0Theodore Ts'o blk_t size, int flags) 62d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o{ 63d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o journal_superblock_t jsb; 64d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o struct stat st; 65d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o errcode_t retval; 66d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o char *buf = 0; 67d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o blk_t dev_size; 68d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o int i, fd, ret_size; 69d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 70d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o /* Make sure the device exists and is a block device */ 71d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (stat(device, &st) < 0) 72d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return errno; 73d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (!S_ISBLK(st.st_mode)) 74d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return EXT2_JOURNAL_NOT_BLOCK; /* Must be a block device */ 75d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 76d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o /* Get the size of the device */ 77d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if ((retval = ext2fs_get_device_size(device, fs->blocksize, 78d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o &dev_size))) 79d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return retval; 80d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 81d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (!size) 82d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o size = dev_size; /* Default to the size of the device */ 83d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o else if (size > dev_size) 84d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return EINVAL; /* Requested size bigger than device */ 85d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 864e246704eab31407ac15be9ab206c6f929507cf0Theodore Ts'o init_journal_superblock(&jsb, fs->blocksize, size, flags); 87d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 88d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o /* Create a block buffer */ 89d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o buf = malloc(fs->blocksize); 90d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (!buf) 91d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return ENOMEM; 92d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 93d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o /* Open the device */ 94d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if ((fd = open(device, O_WRONLY)) < 0) { 95d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o retval = errno; 96d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o goto errout; 97d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o } 98d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 99d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o /* Write the superblock out */ 100d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o memset(buf, 0, fs->blocksize); 101d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o memcpy(buf, &jsb, sizeof(jsb)); 102d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o retval = EXT2_ET_SHORT_WRITE; 103d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o ret_size = write(fd, buf, fs->blocksize); 104d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (ret_size < 0) { 105d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o errno = retval; 106d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o goto errout; 107d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o } 108d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (ret_size != fs->blocksize) 109d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o goto errout; 110d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o memset(buf, 0, fs->blocksize); 111d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 112d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o for (i=1; i < size; i++) { 113d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o ret_size = write(fd, buf, fs->blocksize); 114d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (ret_size < 0) { 115d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o retval = errno; 116d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o goto errout; 117d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o } 118d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (ret_size != fs->blocksize) 119d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o goto errout; 120d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o } 121d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o close(fd); 122d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 123d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o fs->super->s_journal_dev = st.st_rdev; 124d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o fs->super->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL; 125d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o ext2fs_mark_super_dirty(fs); 126d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 127d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return 0; 128d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'oerrout: 129d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (buf) 130d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o free(buf); 131d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return retval; 132d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o} 133d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 134d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o/* 135d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o * Helper function for creating the journal in the filesystem 136d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o */ 137d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'ostruct mkjournal_struct { 138d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o int num_blocks; 139d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o int newblocks; 140d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o char *buf; 141d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o errcode_t err; 142d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o}; 143d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 144d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'ostatic int mkjournal_proc(ext2_filsys fs, 145d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o blk_t *blocknr, 146d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o e2_blkcnt_t blockcnt, 147d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o blk_t ref_block, 148d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o int ref_offset, 149d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o void *priv_data) 150d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o{ 151d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o struct mkjournal_struct *es = (struct mkjournal_struct *) priv_data; 152d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o blk_t new_blk; 153d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o static blk_t last_blk = 0; 154d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o char *block; 155d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o errcode_t retval; 156d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o int group; 157d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 158d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (*blocknr) { 159d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o last_blk = *blocknr; 160d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return 0; 161d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o } 162d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o retval = ext2fs_new_block(fs, last_blk, 0, &new_blk); 163d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (retval) { 164d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o es->err = retval; 165d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return BLOCK_ABORT; 166d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o } 167d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (blockcnt > 0) 168d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o es->num_blocks--; 169d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 170d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o es->newblocks++; 171d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o retval = io_channel_write_blk(fs->io, new_blk, 1, es->buf); 172d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 173d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (blockcnt == 0) 174d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o memset(es->buf, 0, fs->blocksize); 175d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 176d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (retval) { 177d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o es->err = retval; 178d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return BLOCK_ABORT; 179d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o } 180d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o *blocknr = new_blk; 181d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o ext2fs_mark_block_bitmap(fs->block_map, new_blk); 182d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o ext2fs_mark_bb_dirty(fs); 183d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o group = ext2fs_group_of_blk(fs, new_blk); 184d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o fs->group_desc[group].bg_free_blocks_count--; 185d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o fs->super->s_free_blocks_count--; 186d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o ext2fs_mark_super_dirty(fs); 187d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 188d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (es->num_blocks == 0) 189d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return (BLOCK_CHANGED | BLOCK_ABORT); 190d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o else 191d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return BLOCK_CHANGED; 192d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 193d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o} 194d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 195d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o/* 196d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o * This function adds a journal inode to a filesystem 197d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o */ 1984e246704eab31407ac15be9ab206c6f929507cf0Theodore Ts'oerrcode_t ext2fs_add_journal_fs(ext2_filsys fs, blk_t size, int flags) 199d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o{ 200d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o journal_superblock_t jsb; 201d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o errcode_t retval; 202d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o struct ext2_inode inode; 203d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o struct mkjournal_struct es; 204d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o char *buf; 205d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 2064e246704eab31407ac15be9ab206c6f929507cf0Theodore Ts'o init_journal_superblock(&jsb, fs->blocksize, size, flags); 207d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 208d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if ((retval = ext2fs_read_bitmaps(fs))) 209d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return retval; 210d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 211d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if ((retval = ext2fs_read_inode(fs, EXT2_JOURNAL_INO, &inode))) 212d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return retval; 213d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 214d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (inode.i_blocks > 0) 215d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return EEXIST; 216d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 217d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o /* Create the block buffer */ 218d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o buf = malloc(fs->blocksize); 219d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (!buf) 220d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return ENOMEM; 221d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 222d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o memset(buf, 0, fs->blocksize); 223d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o memcpy(buf, &jsb, sizeof(jsb)); 224d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 225d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o es.num_blocks = size; 226d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o es.newblocks = 0; 227d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o es.buf = buf; 228d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o es.err = 0; 229d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 230d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o retval = ext2fs_block_iterate2(fs, EXT2_JOURNAL_INO, BLOCK_FLAG_APPEND, 231d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 0, mkjournal_proc, &es); 232d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o free(buf); 233d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (es.err) 234d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return es.err; 235d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 236d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if ((retval = ext2fs_read_inode(fs, EXT2_JOURNAL_INO, &inode))) 237d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return retval; 238d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 239d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o inode.i_size += fs->blocksize * size; 240d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o inode.i_blocks += (fs->blocksize / 512) * es.newblocks; 241d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o inode.i_mtime = inode.i_ctime = time(0); 242d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o inode.i_links_count = 1; 243d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o inode.i_mode = LINUX_S_IFREG | 0600; 244d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 245d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode))) 246d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return retval; 247d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 248d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o fs->super->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL; 249d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o fs->super->s_journal_inum = EXT2_JOURNAL_INO; 250d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 251d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o ext2fs_mark_super_dirty(fs); 252d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o return 0; 253d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o} 254d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 255d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#ifdef DEBUG 256d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'omain(int argc, char **argv) 257d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o{ 258d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o errcode_t retval; 259d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o char *device_name; 260d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o ext2_filsys fs; 261d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 262d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (argc < 2) { 263d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o fprintf(stderr, "Usage: %s filesystem\n", argv[0]); 264d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o exit(1); 265d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o } 266d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o device_name = argv[1]; 267d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 268d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o retval = ext2fs_open (device_name, EXT2_FLAG_RW, 0, 0, 269d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o unix_io_manager, &fs); 270d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (retval) { 271d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o com_err(argv[0], retval, "while opening %s", device_name); 272d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o exit(1); 273d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o } 274d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 275d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o retval = ext2fs_add_journal_fs(fs, 1024); 276d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (retval) { 277d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o com_err(argv[0], retval, "while adding journal to %s", 278d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o device_name); 279d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o exit(1); 280d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o } 281d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o retval = ext2fs_flush(fs); 282d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o if (retval) { 283d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o printf("Warning, had trouble writing out superblocks.\n"); 284d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o } 285d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o ext2fs_close(fs); 286d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o exit(0); 287d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o 288d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o} 289d3cd93cabeac8c153c8ae7b1b7358d6ced86b15eTheodore Ts'o#endif 290