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