13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* 23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * closefs.c --- close an ext2 filesystem 3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o. 521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * 621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * %Begin-Header% 7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library 8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2. 921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * %End-Header% 103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h> 134cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#if HAVE_UNISTD_H 143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h> 154cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif 163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <time.h> 1750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <string.h> 183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 19b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h" 2021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#include "ext2fsP.h" 213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 22e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic int test_root(unsigned int a, unsigned int b) 231b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o{ 241b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o while (1) { 25e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (a < b) 26e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return 0; 27e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (a == b) 281b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o return 1; 291b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o if (a % b) 301b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o return 0; 311b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o a = a / b; 321b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o } 331b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o} 341b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o 35e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallint ext2fs_bg_has_super(ext2_filsys fs, dgrp_t group) 361b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o{ 371b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o if (!(fs->super->s_feature_ro_compat & 38e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) || group <= 1) 391b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o return 1; 40e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (!(group & 1)) 41e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return 0; 42e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (test_root(group, 3) || (test_root(group, 5)) || 43e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall test_root(group, 7)) 441b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o return 1; 451b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o 461b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o return 0; 471b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o} 481b4cd9c7464d5bd0f5b416c7303bcc827e312473Theodore Ts'o 494a568505ab904d39d9553e9c1d1c565615a5c6caTheodore Ts'o/* 50e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * ext2fs_super_and_bgd_loc2() 51e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * @fs: ext2 fs pointer 52e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * @group given block group 53e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * @ret_super_blk: if !NULL, returns super block location 54e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * @ret_old_desc_blk: if !NULL, returns location of the old block 55e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * group descriptor 56e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * @ret_new_desc_blk: if !NULL, returns location of meta_bg block 57e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * group descriptor 58e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * @ret_used_blks: if !NULL, returns number of blocks used by 59e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * super block and group_descriptors. 604a568505ab904d39d9553e9c1d1c565615a5c6caTheodore Ts'o * 61e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * Returns errcode_t of 0 624a568505ab904d39d9553e9c1d1c565615a5c6caTheodore Ts'o */ 63e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t ext2fs_super_and_bgd_loc2(ext2_filsys fs, 64e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall dgrp_t group, 65e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk64_t *ret_super_blk, 66e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk64_t *ret_old_desc_blk, 67e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk64_t *ret_new_desc_blk, 68e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk_t *ret_used_blks) 69ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o{ 70e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk64_t group_block, super_blk = 0, old_desc_blk = 0, new_desc_blk = 0; 71544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o unsigned int meta_bg, meta_bg_size; 72e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk_t numblocks = 0; 73e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk64_t old_desc_blocks; 745d38ef1d049bf56d1c1e88b8b4d287c0f9470e61Valerie Clement int has_super; 75ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o 76e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall group_block = ext2fs_group_first_block2(fs, group); 77e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (group_block == 0 && fs->blocksize == 1024) 78e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall group_block = 1; /* Deal with 1024 blocksize && bigalloc */ 79ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o 80ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) 81ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o old_desc_blocks = fs->super->s_first_meta_bg; 82ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o else 83efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o old_desc_blocks = 84d323f8fb369089b97d6f3bf0f8d64ceeab0b10f5Theodore Ts'o fs->desc_blocks + fs->super->s_reserved_gdt_blocks; 85ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o 86ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o has_super = ext2fs_bg_has_super(fs, group); 87ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o 88ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o if (has_super) { 89ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o super_blk = group_block; 90e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall numblocks++; 91ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o } 92f2de1d38d0819b17895977fabc52d81d0ea6ec00Valerie Clement meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super); 93ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o meta_bg = group / meta_bg_size; 94ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o 95ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) || 96ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o (meta_bg < fs->super->s_first_meta_bg)) { 97ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o if (has_super) { 98ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o old_desc_blk = group_block + 1; 99e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall numblocks += old_desc_blocks; 100ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o } 101ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o } else { 102ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o if (((group % meta_bg_size) == 0) || 103ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o ((group % meta_bg_size) == 1) || 104ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o ((group % meta_bg_size) == (meta_bg_size-1))) { 105ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o if (has_super) 106ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o has_super = 1; 107ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o new_desc_blk = group_block + has_super; 108e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall numblocks++; 109ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o } 110ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o } 111efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 112ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o if (ret_super_blk) 113ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o *ret_super_blk = super_blk; 114ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o if (ret_old_desc_blk) 115ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o *ret_old_desc_blk = old_desc_blk; 116ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o if (ret_new_desc_blk) 117ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o *ret_new_desc_blk = new_desc_blk; 118e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ret_used_blks) 119e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *ret_used_blks = numblocks; 120e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 121e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return 0; 122ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o} 123ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o 124e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall/* 125e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * This function returns the location of the superblock, block group 126e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * descriptors for a given block group. It currently returns the 127e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * number of free blocks assuming that inode table and allocation 128e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * bitmaps will be in the group. This is not necessarily the case 129e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * when the flex_bg feature is enabled, so callers should take care! 130e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * It was only really intended for use by mke2fs, and even there it's 131e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * not that useful. 132e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * 133e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * The ext2fs_super_and_bgd_loc2() function is 64-bit block number 134e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * capable and returns the number of blocks used by super block and 135e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall * group descriptors. 136e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall */ 137e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallint ext2fs_super_and_bgd_loc(ext2_filsys fs, 138e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall dgrp_t group, 139e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk_t *ret_super_blk, 140e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk_t *ret_old_desc_blk, 141e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk_t *ret_new_desc_blk, 142e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall int *ret_meta_bg) 143e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{ 144e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk64_t ret_super_blk2; 145e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk64_t ret_old_desc_blk2; 146e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk64_t ret_new_desc_blk2; 147e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk_t ret_used_blks; 148e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk_t numblocks; 149e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall unsigned int meta_bg_size; 150e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 151e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_super_and_bgd_loc2(fs, group, &ret_super_blk2, 152e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall &ret_old_desc_blk2, 153e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall &ret_new_desc_blk2, 154e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall &ret_used_blks); 155e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 156e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall numblocks = ext2fs_group_blocks_count(fs, group); 157e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 158e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ret_super_blk) 159e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *ret_super_blk = (blk_t)ret_super_blk2; 160e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ret_old_desc_blk) 161e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *ret_old_desc_blk = (blk_t)ret_old_desc_blk2; 162e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ret_new_desc_blk) 163e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *ret_new_desc_blk = (blk_t)ret_new_desc_blk2; 164e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ret_meta_bg) { 165e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall meta_bg_size = EXT2_DESC_PER_BLOCK(fs->super); 166e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *ret_meta_bg = group / meta_bg_size; 167e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 168e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 169e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall numblocks -= 2 + fs->inode_blocks_per_group + ret_used_blks; 170e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 171e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return numblocks; 172e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall} 173ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o 174c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o/* 175c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o * This function forces out the primary superblock. We need to only 176c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o * write out those fields which we have changed, since if the 177c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o * filesystem is mounted, it may have changed some of the other 178c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o * fields. 179c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o * 180c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o * It takes as input a superblock which has already been byte swapped 181c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o * (if necessary). 182c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o * 183c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o */ 184c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'ostatic errcode_t write_primary_superblock(ext2_filsys fs, 185c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o struct ext2_super_block *super) 186c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o{ 187c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o __u16 *old_super, *new_super; 188c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o int check_idx, write_idx, size; 189c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o errcode_t retval; 190c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o 191c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o if (!fs->io->manager->write_byte || !fs->orig_super) { 1927f1a1fbf850f6b73b5c9c82365f01029fb250a1cTheodore Ts'o fallback: 193c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o io_channel_set_blksize(fs->io, SUPERBLOCK_OFFSET); 194e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = io_channel_write_blk64(fs->io, 1, -SUPERBLOCK_SIZE, 195c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o super); 196c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o io_channel_set_blksize(fs->io, fs->blocksize); 197c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o return retval; 198c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o } 199c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o 200c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o old_super = (__u16 *) fs->orig_super; 201c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o new_super = (__u16 *) super; 202c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o 203c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o for (check_idx = 0; check_idx < SUPERBLOCK_SIZE/2; check_idx++) { 204c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o if (old_super[check_idx] == new_super[check_idx]) 205c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o continue; 206c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o write_idx = check_idx; 207c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o for (check_idx++; check_idx < SUPERBLOCK_SIZE/2; check_idx++) 208c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o if (old_super[check_idx] == new_super[check_idx]) 209c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o break; 210c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o size = 2 * (check_idx - write_idx); 211c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o#if 0 212c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o printf("Writing %d bytes starting at %d\n", 213c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o size, write_idx*2); 214c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o#endif 215c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o retval = io_channel_write_byte(fs->io, 216c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o SUPERBLOCK_OFFSET + (2 * write_idx), size, 217c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o new_super + write_idx); 2187f1a1fbf850f6b73b5c9c82365f01029fb250a1cTheodore Ts'o if (retval == EXT2_ET_UNIMPLEMENTED) 2197f1a1fbf850f6b73b5c9c82365f01029fb250a1cTheodore Ts'o goto fallback; 220c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o if (retval) 221c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o return retval; 222c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o } 2233c6b8977d44c66f0a50dd77c18a78b57b1022f8cTheodore Ts'o memcpy(fs->orig_super, super, SUPERBLOCK_SIZE); 224c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o return 0; 225c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o} 226c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o 227c180ac86533bcbfb1560bd4aa01464785a760f70Theodore Ts'o 2283fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o/* 2293fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o * Updates the revision to EXT2_DYNAMIC_REV 2303fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o */ 231a917d1ccf49605b3009f4e7225f00b81fc16100bTheodore Ts'ovoid ext2fs_update_dynamic_rev(ext2_filsys fs) 2323fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o{ 2333fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o struct ext2_super_block *sb = fs->super; 2343fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o 2353fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o if (sb->s_rev_level > EXT2_GOOD_OLD_REV) 2363fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o return; 2373fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o 2383fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o sb->s_rev_level = EXT2_DYNAMIC_REV; 2393fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o sb->s_first_ino = EXT2_GOOD_OLD_FIRST_INO; 2403fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o sb->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE; 2413fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o /* s_uuid is handled by e2fsck already */ 2423fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o /* other fields should be left alone */ 2433fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o} 2443fe973b3068f68bb9d3ea6ba309dc7d2df30301fTheodore Ts'o 245c046ac7f2e4c53e20cf1e909bbe511f91074b396Theodore Ts'ostatic errcode_t write_backup_super(ext2_filsys fs, dgrp_t group, 246e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk64_t group_block, 247c046ac7f2e4c53e20cf1e909bbe511f91074b396Theodore Ts'o struct ext2_super_block *super_shadow) 248c046ac7f2e4c53e20cf1e909bbe511f91074b396Theodore Ts'o{ 249c046ac7f2e4c53e20cf1e909bbe511f91074b396Theodore Ts'o dgrp_t sgrp = group; 250efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 251c046ac7f2e4c53e20cf1e909bbe511f91074b396Theodore Ts'o if (sgrp > ((1 << 16) - 1)) 252c046ac7f2e4c53e20cf1e909bbe511f91074b396Theodore Ts'o sgrp = (1 << 16) - 1; 253126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o#ifdef WORDS_BIGENDIAN 254126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o super_shadow->s_block_group_nr = ext2fs_swab16(sgrp); 255126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o#else 256126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o fs->super->s_block_group_nr = sgrp; 257c046ac7f2e4c53e20cf1e909bbe511f91074b396Theodore Ts'o#endif 258c046ac7f2e4c53e20cf1e909bbe511f91074b396Theodore Ts'o 259e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return io_channel_write_blk64(fs->io, group_block, -SUPERBLOCK_SIZE, 260c046ac7f2e4c53e20cf1e909bbe511f91074b396Theodore Ts'o super_shadow); 261c046ac7f2e4c53e20cf1e909bbe511f91074b396Theodore Ts'o} 262c046ac7f2e4c53e20cf1e909bbe511f91074b396Theodore Ts'o 26365f0aab98b20b5994a726ab90d355248bcddfffdJP Abgrallerrcode_t ext2fs_flush(ext2_filsys fs) 2649d9a53e651fa877eb4f9df0bfd97fbcc5f514293Richard W.M. Jones{ 265e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return ext2fs_flush2(fs, 0); 266e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall} 267e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 268e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t ext2fs_flush2(ext2_filsys fs, int flags) 269e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{ 2702d328bb76d2d63bdfdba923b54c28bd686bd8fecTheodore Ts'o dgrp_t i; 2713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o errcode_t retval; 272f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o unsigned long fs_state; 2739a083af71a2388ae47252f8af2b796f9055f4af7Theodore Ts'o __u32 feature_incompat; 27450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o struct ext2_super_block *super_shadow = 0; 27550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o struct ext2_group_desc *group_shadow = 0; 2762d328bb76d2d63bdfdba923b54c28bd686bd8fecTheodore Ts'o#ifdef WORDS_BIGENDIAN 277e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall struct ext2_group_desc *gdp; 2782d328bb76d2d63bdfdba923b54c28bd686bd8fecTheodore Ts'o dgrp_t j; 2792d328bb76d2d63bdfdba923b54c28bd686bd8fecTheodore Ts'o#endif 280ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o char *group_ptr; 281ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o int old_desc_blocks; 282e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall struct ext2fs_numeric_progress_struct progress; 283efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 284f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 285f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 28650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o fs_state = fs->super->s_state; 2879a083af71a2388ae47252f8af2b796f9055f4af7Theodore Ts'o feature_incompat = fs->super->s_feature_incompat; 28850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 28932138187f08d1f1dc03feb269f987982db76f3dbTheodore Ts'o fs->super->s_wtime = fs->now ? fs->now : time(NULL); 290e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o fs->super->s_block_group_nr = 0; 291126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o#ifdef WORDS_BIGENDIAN 292126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o retval = EXT2_ET_NO_MEMORY; 293126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &super_shadow); 294126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o if (retval) 295126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o goto errout; 296efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o retval = ext2fs_get_array(fs->desc_blocks, fs->blocksize, 297e6a4571eec5ce0e75fb8a5a41c30bf0e68d90efeTheodore Ts'o &group_shadow); 298126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o if (retval) 299126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o goto errout; 300e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall memcpy(group_shadow, fs->group_desc, (size_t) fs->blocksize * 301126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o fs->desc_blocks); 302efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 303126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o /* swap the group descriptors */ 304e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall for (j = 0; j < fs->group_desc_count; j++) { 305e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall gdp = ext2fs_group_desc(fs, group_shadow, j); 306e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_swap_group_desc2(fs, gdp); 30750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 3085df55d7f847e29d23227592a0bb23daad1a61500Theodore Ts'o#else 3095df55d7f847e29d23227592a0bb23daad1a61500Theodore Ts'o super_shadow = fs->super; 310e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall group_shadow = ext2fs_group_desc(fs, fs->group_desc, 0); 3115df55d7f847e29d23227592a0bb23daad1a61500Theodore Ts'o#endif 312efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 3133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 31450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o * Set the state of the FS to be non-valid. (The state has 315a63d12678369f4ab0edf8fc5741825c035e78bf9Theodore Ts'o * already been backed up earlier, and will be restored after 316a63d12678369f4ab0edf8fc5741825c035e78bf9Theodore Ts'o * we write out the backup superblocks.) 317f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o */ 318f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o fs->super->s_state &= ~EXT2_VALID_FS; 3199a083af71a2388ae47252f8af2b796f9055f4af7Theodore Ts'o fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER; 320126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o#ifdef WORDS_BIGENDIAN 321126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o *super_shadow = *fs->super; 322126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o ext2fs_swap_super(super_shadow); 3235df55d7f847e29d23227592a0bb23daad1a61500Theodore Ts'o#endif 324f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 325f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o /* 3260d961040fe9ad927254b5a0e1a4de7bedadd8579Theodore Ts'o * If this is an external journal device, don't write out the 3270d961040fe9ad927254b5a0e1a4de7bedadd8579Theodore Ts'o * block group descriptors or any of the backup superblocks 3280d961040fe9ad927254b5a0e1a4de7bedadd8579Theodore Ts'o */ 3290d961040fe9ad927254b5a0e1a4de7bedadd8579Theodore Ts'o if (fs->super->s_feature_incompat & 3300d961040fe9ad927254b5a0e1a4de7bedadd8579Theodore Ts'o EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) 3310d961040fe9ad927254b5a0e1a4de7bedadd8579Theodore Ts'o goto write_primary_superblock_only; 3320d961040fe9ad927254b5a0e1a4de7bedadd8579Theodore Ts'o 3330d961040fe9ad927254b5a0e1a4de7bedadd8579Theodore Ts'o /* 3343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Write out the master group descriptors, and the backup 3353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * superblocks and group descriptors. 3363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 337ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o group_ptr = (char *) group_shadow; 338ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) 339ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o old_desc_blocks = fs->super->s_first_meta_bg; 340ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o else 341ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o old_desc_blocks = fs->desc_blocks; 342ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o 343e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_numeric_progress_init(fs, &progress, NULL, 344e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall fs->group_desc_count); 345e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 346e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 347bfd418832d46da1767517b40a7857de449ea03feTheodore Ts'o for (i = 0; i < fs->group_desc_count; i++) { 348e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk64_t super_blk, old_desc_blk, new_desc_blk; 349ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o 350e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_numeric_progress_update(fs, &progress, i); 351e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_super_and_bgd_loc2(fs, i, &super_blk, &old_desc_blk, 352e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall &new_desc_blk, 0); 353ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o 354ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o if (!(fs->flags & EXT2_FLAG_MASTER_SB_ONLY) &&i && super_blk) { 355ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o retval = write_backup_super(fs, i, super_blk, 356c046ac7f2e4c53e20cf1e909bbe511f91074b396Theodore Ts'o super_shadow); 35750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (retval) 35850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o goto errout; 3593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 360ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o if (fs->flags & EXT2_FLAG_SUPER_ONLY) 361ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o continue; 362efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o if ((old_desc_blk) && 363ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o (!(fs->flags & EXT2_FLAG_MASTER_SB_ONLY) || (i == 0))) { 364e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = io_channel_write_blk64(fs->io, 365ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o old_desc_blk, old_desc_blocks, group_ptr); 366ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o if (retval) 367ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o goto errout; 368ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o } 369ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o if (new_desc_blk) { 370e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall int meta_bg = i / EXT2_DESC_PER_BLOCK(fs->super); 371e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 372e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = io_channel_write_blk64(fs->io, new_desc_blk, 373ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o 1, group_ptr + (meta_bg*fs->blocksize)); 374ef344e13d2125e9dae3764b98f9fe3a170cd79e2Theodore Ts'o if (retval) 37550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o goto errout; 3763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 3773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 3783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 379e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_numeric_progress_close(fs, &progress, NULL); 380e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 3813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 3823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * If the write_bitmaps() function is present, call it to 3833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * flush the bitmaps. This is done this way so that a simple 3843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * program that doesn't mess with the bitmaps doesn't need to 3853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * drag in the bitmaps.c code. 3863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 3873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (fs->write_bitmaps) { 3883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = fs->write_bitmaps(fs); 3893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) 39050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o goto errout; 3913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 392b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o 393a63d12678369f4ab0edf8fc5741825c035e78bf9Theodore Ts'owrite_primary_superblock_only: 394b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o /* 395a63d12678369f4ab0edf8fc5741825c035e78bf9Theodore Ts'o * Write out master superblock. This has to be done 396a63d12678369f4ab0edf8fc5741825c035e78bf9Theodore Ts'o * separately, since it is located at a fixed location 397a63d12678369f4ab0edf8fc5741825c035e78bf9Theodore Ts'o * (SUPERBLOCK_OFFSET). We flush all other pending changes 398a63d12678369f4ab0edf8fc5741825c035e78bf9Theodore Ts'o * out to disk first, just to avoid a race condition with an 399a63d12678369f4ab0edf8fc5741825c035e78bf9Theodore Ts'o * insy-tinsy window.... 400b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o */ 4010d961040fe9ad927254b5a0e1a4de7bedadd8579Theodore Ts'o 4020d961040fe9ad927254b5a0e1a4de7bedadd8579Theodore Ts'o fs->super->s_block_group_nr = 0; 4030d961040fe9ad927254b5a0e1a4de7bedadd8579Theodore Ts'o fs->super->s_state = fs_state; 4049a083af71a2388ae47252f8af2b796f9055f4af7Theodore Ts'o fs->super->s_feature_incompat = feature_incompat; 405126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o#ifdef WORDS_BIGENDIAN 406126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o *super_shadow = *fs->super; 407126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o ext2fs_swap_super(super_shadow); 4080d961040fe9ad927254b5a0e1a4de7bedadd8579Theodore Ts'o#endif 4090d961040fe9ad927254b5a0e1a4de7bedadd8579Theodore Ts'o 410e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (!(flags & EXT2_FLAG_FLUSH_NO_SYNC)) 411e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = io_channel_flush(fs->io); 412a63d12678369f4ab0edf8fc5741825c035e78bf9Theodore Ts'o retval = write_primary_superblock(fs, super_shadow); 413a63d12678369f4ab0edf8fc5741825c035e78bf9Theodore Ts'o if (retval) 414a63d12678369f4ab0edf8fc5741825c035e78bf9Theodore Ts'o goto errout; 415a63d12678369f4ab0edf8fc5741825c035e78bf9Theodore Ts'o 416a63d12678369f4ab0edf8fc5741825c035e78bf9Theodore Ts'o fs->flags &= ~EXT2_FLAG_DIRTY; 417a63d12678369f4ab0edf8fc5741825c035e78bf9Theodore Ts'o 418e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (!(flags & EXT2_FLAG_FLUSH_NO_SYNC)) 419e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = io_channel_flush(fs->io); 42050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oerrout: 42150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o fs->super->s_state = fs_state; 422126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o#ifdef WORDS_BIGENDIAN 423126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o if (super_shadow) 424126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o ext2fs_free_mem(&super_shadow); 425126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o if (group_shadow) 426126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o ext2fs_free_mem(&group_shadow); 427126a291c768b523bc228b276d3bea82675a86d09Theodore Ts'o#endif 42850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o return retval; 4293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 4303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 4313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oerrcode_t ext2fs_close(ext2_filsys fs) 4323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 433e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return ext2fs_close2(fs, 0); 434e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall} 435e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 436e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t ext2fs_close2(ext2_filsys fs, int flags) 437e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{ 4383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o errcode_t retval; 439b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o int meta_blks; 440b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o io_stats stats = 0; 441efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 442f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 443f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 444b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o if (fs->write_bitmaps) { 445b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o retval = fs->write_bitmaps(fs); 4463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) 4473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return retval; 4483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 449b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o if (fs->super->s_kbytes_written && 450b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o fs->io->manager->get_stats) 451b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o fs->io->manager->get_stats(fs->io, &stats); 452b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o if (stats && stats->bytes_written && (fs->flags & EXT2_FLAG_RW)) { 453b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o fs->super->s_kbytes_written += stats->bytes_written >> 10; 454b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o meta_blks = fs->desc_blocks + 1; 455b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o if (!(fs->flags & EXT2_FLAG_SUPER_ONLY)) 456b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o fs->super->s_kbytes_written += meta_blks / 457b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o (fs->blocksize / 1024); 4586d67ee305cdfff7131a4105551409d1603dba81dTheodore Ts'o if ((fs->flags & EXT2_FLAG_DIRTY) == 0) 4596d67ee305cdfff7131a4105551409d1603dba81dTheodore Ts'o fs->flags |= EXT2_FLAG_SUPER_ONLY | EXT2_FLAG_DIRTY; 460b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o } 461b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o if (fs->flags & EXT2_FLAG_DIRTY) { 462e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = ext2fs_flush2(fs, flags); 46321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o if (retval) 46421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o return retval; 46521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o } 466e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 467e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = ext2fs_mmp_stop(fs); 468e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (retval) 469e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return retval; 470e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 4713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o ext2fs_free(fs); 4723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return 0; 4733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 47421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o 475