mkjournal.c revision 9f8046fc6dfc13eee2f5c363214e60b533872cac
1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch/* 2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * mkjournal.c --- make a journal for a filesystem 3ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * 4ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch * Copyright (C) 2000 Theodore Ts'o. 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * %Begin-Header% 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This file may be redistributed under the terms of the GNU Public 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * License. 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * %End-Header% 103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch */ 113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <stdio.h> 13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include <string.h> 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if HAVE_UNISTD_H 153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include <unistd.h> 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif 173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#if HAVE_ERRNO_H 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <errno.h> 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <fcntl.h> 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <time.h> 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if HAVE_SYS_STAT_H 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <sys/stat.h> 24bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#endif 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if HAVE_SYS_TYPES_H 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <sys/types.h> 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if HAVE_NETINET_IN_H 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <netinet/in.h> 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ext2_fs.h" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "e2p/e2p.h" 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ext2fs.h" 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "jfs_user.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/* 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * This function automatically sets up the journal superblock and 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * returns it as an allocated block. 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)errcode_t ext2fs_create_journal_superblock(ext2_filsys fs, 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) __u32 size, int flags, 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) char **ret_jsb) 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles){ 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errcode_t retval; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) journal_superblock_t *jsb; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (size < 1024) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return EXT2_ET_JOURNAL_TOO_SMALL; 50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((retval = ext2fs_get_mem(fs->blocksize, (void **) &jsb))) 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return retval; 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch memset (jsb, 0, fs->blocksize); 5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER); 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (flags & EXT2_MKJOURNAL_V1_SUPER) 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V1); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2); 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jsb->s_blocksize = htonl(fs->blocksize); 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) jsb->s_maxlen = htonl(size); 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jsb->s_nr_users = htonl(1); 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jsb->s_first = htonl(1); 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jsb->s_sequence = htonl(1); 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch memcpy(jsb->s_uuid, fs->super->s_uuid, sizeof(fs->super->s_uuid)); 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * If we're creating an external journal device, we need to 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * adjust these fields. 7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) */ 7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (fs->super->s_feature_incompat & 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) jsb->s_nr_users = 0; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *ret_jsb = (char *) jsb; 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/* 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This function writes a journal using POSIX routines. It is used 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * for creating external journals and creating journals on live 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * filesystems. 8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) */ 8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)static errcode_t write_journal_file(ext2_filsys fs, char *filename, 8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) blk_t size, int flags) 8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles){ 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errcode_t retval; 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) char *buf = 0; 8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int i, fd, ret_size; 9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if ((retval = ext2fs_create_journal_superblock(fs, size, flags, &buf))) 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return retval; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Open the device or journal file */ 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if ((fd = open(filename, O_WRONLY)) < 0) { 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) retval = errno; 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) goto errout; 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) /* Write the superblock out */ 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) retval = EXT2_ET_SHORT_WRITE; 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ret_size = write(fd, buf, fs->blocksize); 10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (ret_size < 0) { 10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) retval = errno; 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) goto errout; 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (ret_size != fs->blocksize) 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) goto errout; 10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) memset(buf, 0, fs->blocksize); 110bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 111bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch for (i = 1; i < size; i++) { 112bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ret_size = write(fd, buf, fs->blocksize); 113bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (ret_size < 0) { 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) retval = errno; 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) goto errout; 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ret_size != fs->blocksize) 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) goto errout; 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) close(fd); 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) retval = 0; 12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)errout: 12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ext2fs_free_mem((void **) &buf); 12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return retval; 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/* 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Helper function for creating the journal using direct I/O routines 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct mkjournal_struct { 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int num_blocks; 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int newblocks; 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char *buf; 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errcode_t err; 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static int mkjournal_proc(ext2_filsys fs, 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) blk_t *blocknr, 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) e2_blkcnt_t blockcnt, 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) blk_t ref_block, 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int ref_offset, 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void *priv_data) 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){ 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct mkjournal_struct *es = (struct mkjournal_struct *) priv_data; 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) blk_t new_blk; 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static blk_t last_blk = 0; 148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch errcode_t retval; 149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int group; 150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (*blocknr) { 152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch last_blk = *blocknr; 153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return 0; 154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch retval = ext2fs_new_block(fs, last_blk, 0, &new_blk); 156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (retval) { 1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch es->err = retval; 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return BLOCK_ABORT; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (blockcnt > 0) 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) es->num_blocks--; 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) es->newblocks++; 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) retval = io_channel_write_blk(fs->io, new_blk, 1, es->buf); 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (blockcnt == 0) 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memset(es->buf, 0, fs->blocksize); 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (retval) { 1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch es->err = retval; 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return BLOCK_ABORT; 1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch *blocknr = new_blk; 1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ext2fs_mark_block_bitmap(fs->block_map, new_blk); 1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ext2fs_mark_bb_dirty(fs); 1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch group = ext2fs_group_of_blk(fs, new_blk); 1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fs->group_desc[group].bg_free_blocks_count--; 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fs->super->s_free_blocks_count--; 1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ext2fs_mark_super_dirty(fs); 1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (es->num_blocks == 0) 1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return (BLOCK_CHANGED | BLOCK_ABORT); 1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else 1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return BLOCK_CHANGED; 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/* 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * This function creates a journal using direct I/O routines. 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstatic errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino, 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) blk_t size, int flags) 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){ 194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) char *buf; 195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errcode_t retval; 196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) struct ext2_inode inode; 197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) struct mkjournal_struct es; 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if ((retval = ext2fs_create_journal_superblock(fs, size, flags, &buf))) 200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return retval; 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((retval = ext2fs_read_bitmaps(fs))) 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return retval; 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if ((retval = ext2fs_read_inode(fs, journal_ino, &inode))) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return retval; 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (inode.i_blocks > 0) 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return EEXIST; 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) es.num_blocks = size; 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) es.newblocks = 0; 21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) es.buf = buf; 21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) es.err = 0; 21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) retval = ext2fs_block_iterate2(fs, journal_ino, BLOCK_FLAG_APPEND, 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 0, mkjournal_proc, &es); 21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (es.err) { 21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) retval = es.err; 22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) goto errout; 22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if ((retval = ext2fs_read_inode(fs, journal_ino, &inode))) 22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) goto errout; 22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 22668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) inode.i_size += fs->blocksize * size; 22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) inode.i_blocks += (fs->blocksize / 512) * es.newblocks; 22868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) inode.i_mtime = inode.i_ctime = time(0); 22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) inode.i_links_count = 1; 23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) inode.i_mode = LINUX_S_IFREG | 0600; 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ((retval = ext2fs_write_inode(fs, journal_ino, &inode))) 233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto errout; 234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) retval = 0; 235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)errout: 237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ext2fs_free_mem((void **) &buf); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return retval; 239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This function adds a journal device to a filesystem 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)errcode_t ext2fs_add_journal_device(ext2_filsys fs, ext2_filsys journal_dev) 245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct stat st; 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errcode_t retval; 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) char buf[1024]; 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) journal_superblock_t *jsb; 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int i; 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) __u32 nr_users; 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Make sure the device exists and is a block device */ 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (stat(journal_dev->device_name, &st) < 0) 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return errno; 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!S_ISBLK(st.st_mode)) 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return EXT2_ET_JOURNAL_NOT_BLOCK; /* Must be a block device */ 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* Get the journal superblock */ 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if ((retval = io_channel_read_blk(journal_dev->io, 1, -1024, buf))) 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return retval; 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) jsb = (journal_superblock_t *) buf; 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if ((jsb->s_header.h_magic != (unsigned) ntohl(JFS_MAGIC_NUMBER)) || 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (jsb->s_header.h_blocktype != (unsigned) ntohl(JFS_SUPERBLOCK_V2))) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return EXT2_ET_NO_JOURNAL_SB; 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ntohl(jsb->s_blocksize) != fs->blocksize) 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return EXT2_ET_UNEXPECTED_BLOCK_SIZE; 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch /* Check and see if this filesystem has already been added */ 2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch nr_users = ntohl(jsb->s_nr_users); 2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (i=0; i < nr_users; i++) { 2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (memcmp(fs->super->s_uuid, 2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch &jsb->s_users[i*16], 16) == 0) 2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (i >= nr_users) { 2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch memcpy(&jsb->s_users[nr_users*16], 281effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch fs->super->s_uuid, 16); 282effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch jsb->s_nr_users = htonl(nr_users+1); 283effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 284effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 285effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch /* Writeback the journal superblock */ 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((retval = io_channel_write_blk(journal_dev->io, 1, -1024, buf))) 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return retval; 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fs->super->s_journal_inum = 0; 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fs->super->s_journal_dev = st.st_rdev; 2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch memcpy(fs->super->s_journal_uuid, jsb->s_uuid, 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sizeof(fs->super->s_journal_uuid)); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fs->super->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL; 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ext2fs_mark_super_dirty(fs); 2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return 0; 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This function adds a journal inode to a filesystem, using either 3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * POSIX routines if the filesystem is mounted, or using direct I/O 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * functions if it is not. 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size, int flags) 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errcode_t retval; 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ext2_ino_t journal_ino; 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct stat st; 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char jfile[1024]; 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int fd, mount_flags; 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((retval = ext2fs_check_mount_point(fs->device_name, &mount_flags, 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) jfile, sizeof(jfile)-10))) 313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return retval; 314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (mount_flags & EXT2_MF_MOUNTED) { 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) strcat(jfile, "/.journal"); 317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Create the journal file */ 319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if ((fd = open(jfile, O_CREAT|O_WRONLY, 0600)) < 0) 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return errno; 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close(fd); 322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ((retval = write_journal_file(fs, jfile, size, flags))) 324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return retval; 325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* Get inode number of the journal file */ 327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (stat(jfile, &st) < 0) 328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return errno; 329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ((retval = fsetflags(jfile, 331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXT2_NODUMP_FL | EXT2_IMMUTABLE_FL))) 332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return retval; 333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch journal_ino = st.st_ino; 335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch journal_ino = EXT2_JOURNAL_INO; 337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ((retval = write_journal_inode(fs, journal_ino, 338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size, flags))) 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return retval; 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fs->super->s_journal_inum = journal_ino; 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) fs->super->s_journal_dev = 0; 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) memset(fs->super->s_journal_uuid, 0, 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sizeof(fs->super->s_journal_uuid)); 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) fs->super->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL; 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ext2fs_mark_super_dirty(fs); 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return 0; 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifdef DEBUG 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)main(int argc, char **argv) 354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errcode_t retval; 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char *device_name; 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ext2_filsys fs; 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (argc < 2) { 3607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fprintf(stderr, "Usage: %s filesystem\n", argv[0]); 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) exit(1); 362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) device_name = argv[1]; 364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) retval = ext2fs_open (device_name, EXT2_FLAG_RW, 0, 0, 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unix_io_manager, &fs); 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (retval) { 368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) com_err(argv[0], retval, "while opening %s", device_name); 369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) exit(1); 370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) retval = ext2fs_add_journal_inode(fs, 1024); 373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval) { 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) com_err(argv[0], retval, "while adding journal to %s", 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_name); 376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) exit(1); 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) retval = ext2fs_flush(fs); 379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (retval) { 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) printf("Warning, had trouble writing out superblocks.\n"); 381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ext2fs_close(fs); 383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) exit(0); 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)