119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* 219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * bmove.c --- Move blocks around to make way for a particular 319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * filesystem structure. 419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * 58558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * Copyright (C) 1997 Theodore Ts'o. 68558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * 78558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * %Begin-Header% 88558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * This file may be redistributed under the terms of the GNU Library 98558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * General Public License, version 2. 108558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * %End-Header% 1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h> 1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h> 1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_UNISTD_H 1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <unistd.h> 1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_SYS_TYPES_H 1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/types.h> 2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_SYS_TIME_H 2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/time.h> 2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2_fs.h" 2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2fsP.h" 2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstruct process_block_struct { 2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_ino_t ino; 3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_inode * inode; 3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_block_bitmap reserve; 3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_block_bitmap alloc_map; 3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t error; 3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *buf; 3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int add_dir; 3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int flags; 3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}; 3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int process_block(ext2_filsys fs, blk_t *block_nr, 4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project e2_blkcnt_t blockcnt, blk_t ref_block, 4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int ref_offset, void *priv_data) 4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct process_block_struct *pb; 4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int ret; 4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blk_t block, orig; 4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb = (struct process_block_struct *) priv_data; 4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project block = orig = *block_nr; 5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ret = 0; 513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Let's see if this is one which we need to relocate 5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (ext2fs_test_block_bitmap(pb->reserve, block)) { 5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project do { 5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (++block >= fs->super->s_blocks_count) 5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project block = fs->super->s_first_data_block; 5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (block == orig) { 6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb->error = EXT2_ET_BLOCK_ALLOC_FAIL; 6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return BLOCK_ABORT; 6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } while (ext2fs_test_block_bitmap(pb->reserve, block) || 6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_test_block_bitmap(pb->alloc_map, block)); 6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = io_channel_read_blk(fs->io, orig, 1, pb->buf); 6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) { 6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb->error = retval; 6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return BLOCK_ABORT; 7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = io_channel_write_blk(fs->io, block, 1, pb->buf); 7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) { 7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb->error = retval; 7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return BLOCK_ABORT; 7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *block_nr = block; 7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_mark_block_bitmap(pb->alloc_map, block); 7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ret = BLOCK_CHANGED; 7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pb->flags & EXT2_BMOVE_DEBUG) 8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project printf("ino=%ld, blockcnt=%lld, %u->%u\n", pb->ino, 8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project blockcnt, orig, block); 8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pb->add_dir) { 8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_add_dir_block(fs->dblist, pb->ino, 8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project block, (int) blockcnt); 8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) { 8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb->error = retval; 8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ret |= BLOCK_ABORT; 8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return ret; 9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrcode_t ext2fs_move_blocks(ext2_filsys fs, 9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_block_bitmap reserve, 9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_block_bitmap alloc_map, 9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project int flags) 9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_ino_t ino; 10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct ext2_inode inode; 10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project errcode_t retval; 10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project struct process_block_struct pb; 10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2_inode_scan scan; 10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project char *block_buf; 1053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_open_inode_scan(fs, 0, &scan); 10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.reserve = reserve; 11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.error = 0; 11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.alloc_map = alloc_map ? alloc_map : fs->block_map; 11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.flags = flags; 1143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_get_array(4, fs->blocksize, &block_buf); 11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.buf = block_buf + fs->blocksize * 3; 11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* 12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If GET_DBLIST is set in the flags field, then we should 12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * gather directory block information while we're doing the 12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * block move. 12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */ 12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (flags & EXT2_BMOVE_GET_DBLIST) { 12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (fs->dblist) { 12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ext2fs_free_dblist(fs->dblist); 12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project fs->dblist = NULL; 12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_init_dblist(fs, 0); 13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_get_next_inode(scan, &ino, &inode); 13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 1383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project while (ino) { 14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if ((inode.i_links_count == 0) || 14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project !ext2fs_inode_has_valid_blocks(&inode)) 14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto next; 1433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.ino = ino; 14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.inode = &inode; 14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project pb.add_dir = (LINUX_S_ISDIR(inode.i_mode) && 14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project flags & EXT2_BMOVE_GET_DBLIST); 14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_block_iterate2(fs, ino, 0, block_buf, 15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project process_block, &pb); 15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval) 15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return retval; 15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (pb.error) 15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return pb.error; 15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project next: 15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project retval = ext2fs_get_next_inode(scan, &ino, &inode); 15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) 16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project goto next; 16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project } 16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return 0; 16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 165