13984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/* 23984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * extent.c --- routines to implement extents support 33984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 43984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Copyright (C) 2007 Theodore Ts'o. 53984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 63984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * %Begin-Header% 78558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * This file may be redistributed under the terms of the GNU Library 88558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * General Public License, version 2. 93984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * %End-Header% 103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <stdio.h> 133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <string.h> 143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#if HAVE_UNISTD_H 153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <unistd.h> 163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#if HAVE_ERRNO_H 183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <errno.h> 193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#if HAVE_SYS_STAT_H 213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <sys/stat.h> 223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#if HAVE_SYS_TYPES_H 243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <sys/types.h> 253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include "ext2_fs.h" 283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include "ext2fsP.h" 293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include "e2image.h" 303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/* 323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Definitions to be dropped in lib/ext2fs/ext2fs.h 333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/* 363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Private definitions 373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstruct extent_path { 403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt char *buf; 413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int entries; 423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int max_entries; 433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int left; 443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int visit_num; 453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int flags; 463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk64_t end_blk; 473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt void *curr; 483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}; 493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstruct ext2_extent_handle { 523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t magic; 533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2_filsys fs; 543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2_ino_t ino; 553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2_inode *inode; 563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int type; 573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int level; 583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int max_depth; 593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct extent_path *path; 603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}; 613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstruct ext2_extent_path { 633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t magic; 643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int leaf_height; 653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk64_t lblk; 663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}; 673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/* 693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Useful Debugging stuff 703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic void dbg_show_header(struct ext3_extent_header *eh) 743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("header: magic=%x entries=%u max=%u depth=%u generation=%u\n", 763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le16_to_cpu(eh->eh_magic), 773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le16_to_cpu(eh->eh_entries), 783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le16_to_cpu(eh->eh_max), 793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le16_to_cpu(eh->eh_depth), 803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le32_to_cpu(eh->eh_generation)); 813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic void dbg_show_index(struct ext3_extent_idx *ix) 843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("index: block=%u leaf=%u leaf_hi=%u unused=%u\n", 863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le32_to_cpu(ix->ei_block), 873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le32_to_cpu(ix->ei_leaf), 883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le16_to_cpu(ix->ei_leaf_hi), 893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le16_to_cpu(ix->ei_unused)); 903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic void dbg_show_extent(struct ext3_extent *ex) 933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("extent: block=%u-%u len=%u start=%u start_hi=%u\n", 953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le32_to_cpu(ex->ee_block), 963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le32_to_cpu(ex->ee_block) + 973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le16_to_cpu(ex->ee_len) - 1, 983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le16_to_cpu(ex->ee_len), 993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le32_to_cpu(ex->ee_start), 1003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le16_to_cpu(ex->ee_start_hi)); 1013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 1023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic void dbg_print_extent(char *desc, struct ext2fs_extent *extent) 1043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 1053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (desc) 1063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("%s: ", desc); 1073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("extent: lblk %llu--%llu, len %u, pblk %llu, flags: ", 1083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent->e_lblk, extent->e_lblk + extent->e_len - 1, 1093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent->e_len, extent->e_pblk); 1103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (extent->e_flags & EXT2_EXTENT_FLAGS_LEAF) 1113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fputs("LEAF ", stdout); 1123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (extent->e_flags & EXT2_EXTENT_FLAGS_UNINIT) 1133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fputs("UNINIT ", stdout); 1143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (extent->e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT) 1153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fputs("2ND_VISIT ", stdout); 1163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!extent->e_flags) 1173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fputs("(none)", stdout); 1183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fputc('\n', stdout); 1193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 1213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#else 1233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define dbg_show_header(eh) do { } while (0) 1243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define dbg_show_index(ix) do { } while (0) 1253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define dbg_show_extent(ex) do { } while (0) 1263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define dbg_print_extent(desc, ex) do { } while (0) 1273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 1283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/* 1303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Verify the extent header as being sane 1313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 1323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidterrcode_t ext2fs_extent_header_verify(void *ptr, int size) 1333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 1343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int eh_max, entry_size; 1353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext3_extent_header *eh = ptr; 1363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dbg_show_header(eh); 1383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (ext2fs_le16_to_cpu(eh->eh_magic) != EXT3_EXT_MAGIC) 1393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_EXTENT_HEADER_BAD; 1403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (ext2fs_le16_to_cpu(eh->eh_entries) > ext2fs_le16_to_cpu(eh->eh_max)) 1413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_EXTENT_HEADER_BAD; 1423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (eh->eh_depth == 0) 1433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt entry_size = sizeof(struct ext3_extent); 1443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else 1453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt entry_size = sizeof(struct ext3_extent_idx); 1463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh_max = (size - sizeof(*eh)) / entry_size; 1483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* Allow two extent-sized items at the end of the block, for 1493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * ext4_extent_tail with checksum in the future. */ 1503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((ext2fs_le16_to_cpu(eh->eh_max) > eh_max) || 1513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (ext2fs_le16_to_cpu(eh->eh_max) < (eh_max - 2))) 1523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_EXTENT_HEADER_BAD; 1533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 1553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 1563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/* 1593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Begin functions to handle an inode's extent information 1603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 1613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtextern void ext2fs_extent_free(ext2_extent_handle_t handle) 1623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 1633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int i; 1643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!handle) 1663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 1673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->inode) 1693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_free_mem(&handle->inode); 1703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->path) { 1713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt for (i=1; i <= handle->max_depth; i++) { 1723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->path[i].buf) 1733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_free_mem(&handle->path[i].buf); 1743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 1753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_free_mem(&handle->path); 1763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 1773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_free_mem(&handle); 1783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 1793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtextern errcode_t ext2fs_extent_open(ext2_filsys fs, ext2_ino_t ino, 1813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2_extent_handle_t *ret_handle) 1823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 1833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return ext2fs_extent_open2(fs, ino, NULL, ret_handle); 1843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 1853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtextern errcode_t ext2fs_extent_open2(ext2_filsys fs, ext2_ino_t ino, 1873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2_inode *inode, 1883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2_extent_handle_t *ret_handle) 1893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 1903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2_extent_handle *handle; 1913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 1923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int i; 1933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext3_extent_header *eh; 1943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 1963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 1973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!inode) 1983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((ino == 0) || (ino > fs->super->s_inodes_count)) 1993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_BAD_INODE_NUM; 2003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_get_mem(sizeof(struct ext2_extent_handle), &handle); 2023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 2033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 2043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt memset(handle, 0, sizeof(struct ext2_extent_handle)); 2053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_get_mem(sizeof(struct ext2_inode), &handle->inode); 2073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 2083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto errout; 2093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->ino = ino; 2113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->fs = fs; 2123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (inode) { 2143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt memcpy(handle->inode, inode, sizeof(struct ext2_inode)); 2153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 2163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else { 2173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_read_inode(fs, ino, handle->inode); 2183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 2193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto errout; 2203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 2213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh = (struct ext3_extent_header *) &handle->inode->i_block[0]; 2233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt for (i=0; i < EXT2_N_BLOCKS; i++) 2253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->inode->i_block[i]) 2263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 2273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (i >= EXT2_N_BLOCKS) { 2283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh->eh_magic = ext2fs_cpu_to_le16(EXT3_EXT_MAGIC); 2293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh->eh_depth = 0; 2303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh->eh_entries = 0; 2313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt i = (sizeof(handle->inode->i_block) - sizeof(*eh)) / 2323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt sizeof(struct ext3_extent); 2333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh->eh_max = ext2fs_cpu_to_le16(i); 2343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->inode->i_flags |= EXT4_EXTENTS_FL; 2353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 2363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!(handle->inode->i_flags & EXT4_EXTENTS_FL)) { 2383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = EXT2_ET_INODE_NOT_EXTENT; 2393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto errout; 2403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 2413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_header_verify(eh, sizeof(handle->inode->i_block)); 2433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 2443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto errout; 2453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->max_depth = ext2fs_le16_to_cpu(eh->eh_depth); 2473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->type = ext2fs_le16_to_cpu(eh->eh_magic); 2483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_get_mem(((handle->max_depth+1) * 2503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt sizeof(struct extent_path)), 2513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &handle->path); 2523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt memset(handle->path, 0, 2533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (handle->max_depth+1) * sizeof(struct extent_path)); 2543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->path[0].buf = (char *) handle->inode->i_block; 2553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->path[0].left = handle->path[0].entries = 2573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le16_to_cpu(eh->eh_entries); 2583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->path[0].max_entries = ext2fs_le16_to_cpu(eh->eh_max); 2593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->path[0].curr = 0; 2603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->path[0].end_blk = 2613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((((__u64) handle->inode->i_size_high << 32) + 2623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->inode->i_size + (fs->blocksize - 1)) 2633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt >> EXT2_BLOCK_SIZE_BITS(fs->super)); 2643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->path[0].visit_num = 1; 2653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->level = 0; 2663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->magic = EXT2_ET_MAGIC_EXTENT_HANDLE; 2673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *ret_handle = handle; 2693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 2703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidterrout: 2723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_extent_free(handle); 2733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 2743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 2753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/* 2773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * This function is responsible for (optionally) moving through the 2783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * extent tree and then returning the current extent 2793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 2803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidterrcode_t ext2fs_extent_get(ext2_extent_handle_t handle, 2813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int flags, struct ext2fs_extent *extent) 2823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 2833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct extent_path *path, *newpath; 2843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext3_extent_header *eh; 2853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext3_extent_idx *ix = 0; 2863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext3_extent *ex; 2873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 2883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk_t blk; 2893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk64_t end_blk; 2903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int orig_op, op; 2913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE); 2933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!handle->path) 2953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_NO_CURRENT_NODE; 2963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt orig_op = op = flags & EXT2_EXTENT_MOVE_MASK; 2983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtretry: 3003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path = handle->path + handle->level; 3013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((orig_op == EXT2_EXTENT_NEXT) || 3023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (orig_op == EXT2_EXTENT_NEXT_LEAF)) { 3033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->level < handle->max_depth) { 3043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* interior node */ 3053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path->visit_num == 0) { 3063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->visit_num++; 3073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt op = EXT2_EXTENT_DOWN; 3083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else if (path->left > 0) 3093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt op = EXT2_EXTENT_NEXT_SIB; 3103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else if (handle->level > 0) 3113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt op = EXT2_EXTENT_UP; 3123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else 3133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_EXTENT_NO_NEXT; 3143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 3153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* leaf node */ 3163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path->left > 0) 3173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt op = EXT2_EXTENT_NEXT_SIB; 3183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else if (handle->level > 0) 3193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt op = EXT2_EXTENT_UP; 3203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else 3213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_EXTENT_NO_NEXT; 3223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 3233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (op != EXT2_EXTENT_NEXT_SIB) { 3243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG_GET_EXTENT 3253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("<<<< OP = %s\n", 3263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (op == EXT2_EXTENT_DOWN) ? "down" : 3273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((op == EXT2_EXTENT_UP) ? "up" : "unknown")); 3283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 3293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 3303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 3313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 3323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((orig_op == EXT2_EXTENT_PREV) || 3333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (orig_op == EXT2_EXTENT_PREV_LEAF)) { 3343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->level < handle->max_depth) { 3353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* interior node */ 3363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path->visit_num > 0 ) { 3373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* path->visit_num = 0; */ 3383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt op = EXT2_EXTENT_DOWN_AND_LAST; 3393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else if (path->left < path->entries-1) 3403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt op = EXT2_EXTENT_PREV_SIB; 3413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else if (handle->level > 0) 3423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt op = EXT2_EXTENT_UP; 3433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else 3443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_EXTENT_NO_PREV; 3453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 3463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* leaf node */ 3473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path->left < path->entries-1) 3483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt op = EXT2_EXTENT_PREV_SIB; 3493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else if (handle->level > 0) 3503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt op = EXT2_EXTENT_UP; 3513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else 3523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_EXTENT_NO_PREV; 3533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 3543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (op != EXT2_EXTENT_PREV_SIB) { 3553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG_GET_EXTENT 3563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("<<<< OP = %s\n", 3573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (op == EXT2_EXTENT_DOWN_AND_LAST) ? "down/last" : 3583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((op == EXT2_EXTENT_UP) ? "up" : "unknown")); 3593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 3603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 3613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 3623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 3633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (orig_op == EXT2_EXTENT_LAST_LEAF) { 3643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((handle->level < handle->max_depth) && 3653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (path->left == 0)) 3663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt op = EXT2_EXTENT_DOWN; 3673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else 3683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt op = EXT2_EXTENT_LAST_SIB; 3693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG_GET_EXTENT 3703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("<<<< OP = %s\n", 3713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (op == EXT2_EXTENT_DOWN) ? "down" : "last_sib"); 3723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 3733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 3743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 3753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt switch (op) { 3763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt case EXT2_EXTENT_CURRENT: 3773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix = path->curr; 3783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 3793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt case EXT2_EXTENT_ROOT: 3803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->level = 0; 3813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path = handle->path + handle->level; 3823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt case EXT2_EXTENT_FIRST_SIB: 3833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->left = path->entries; 3843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->curr = 0; 3853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt case EXT2_EXTENT_NEXT_SIB: 3863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path->left <= 0) 3873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_EXTENT_NO_NEXT; 3883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path->curr) { 3893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix = path->curr; 3903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix++; 3913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 3923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh = (struct ext3_extent_header *) path->buf; 3933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix = EXT_FIRST_INDEX(eh); 3943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 3953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->left--; 3963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->curr = ix; 3973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->visit_num = 0; 3983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 3993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt case EXT2_EXTENT_PREV_SIB: 4003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!path->curr || 4013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->left+1 >= path->entries) 4023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_EXTENT_NO_PREV; 4033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix = path->curr; 4043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix--; 4053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->curr = ix; 4063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->left++; 4073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->level < handle->max_depth) 4083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->visit_num = 1; 4093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 4103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt case EXT2_EXTENT_LAST_SIB: 4113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh = (struct ext3_extent_header *) path->buf; 4123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->curr = EXT_LAST_EXTENT(eh); 4133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix = path->curr; 4143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->left = 0; 4153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->visit_num = 0; 4163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 4173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt case EXT2_EXTENT_UP: 4183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->level <= 0) 4193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_EXTENT_NO_UP; 4203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->level--; 4213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path--; 4223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix = path->curr; 4233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((orig_op == EXT2_EXTENT_PREV) || 4243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (orig_op == EXT2_EXTENT_PREV_LEAF)) 4253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->visit_num = 0; 4263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 4273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt case EXT2_EXTENT_DOWN: 4283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt case EXT2_EXTENT_DOWN_AND_LAST: 4293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!path->curr ||(handle->level >= handle->max_depth)) 4303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_EXTENT_NO_DOWN; 4313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 4323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix = path->curr; 4333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt newpath = path + 1; 4343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!newpath->buf) { 4353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_get_mem(handle->fs->blocksize, 4363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &newpath->buf); 4373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 4383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 4393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 4403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk = ext2fs_le32_to_cpu(ix->ei_leaf) + 4413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((__u64) ext2fs_le16_to_cpu(ix->ei_leaf_hi) << 32); 4423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((handle->fs->flags & EXT2_FLAG_IMAGE_FILE) && 4433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (handle->fs->io != handle->fs->image_io)) 4443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt memset(newpath->buf, 0, handle->fs->blocksize); 4453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else { 4463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = io_channel_read_blk(handle->fs->io, 4473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk, 1, newpath->buf); 4483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 4493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 4503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 4513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->level++; 4523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 4533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh = (struct ext3_extent_header *) newpath->buf; 4543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 4553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_header_verify(eh, handle->fs->blocksize); 4563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 4573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->level--; 4583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 4593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 4603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 4613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt newpath->left = newpath->entries = 4623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_le16_to_cpu(eh->eh_entries); 4633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt newpath->max_entries = ext2fs_le16_to_cpu(eh->eh_max); 4643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 4653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path->left > 0) { 4663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix++; 4673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt newpath->end_blk = ext2fs_le32_to_cpu(ix->ei_block); 4683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else 4693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt newpath->end_blk = path->end_blk; 4703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 4713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path = newpath; 4723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (op == EXT2_EXTENT_DOWN) { 4733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix = EXT_FIRST_INDEX((struct ext3_extent_header *) eh); 4743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->curr = ix; 4753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->left = path->entries - 1; 4763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->visit_num = 0; 4773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 4783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix = EXT_LAST_INDEX((struct ext3_extent_header *) eh); 4793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->curr = ix; 4803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->left = 0; 4813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->level < handle->max_depth) 4823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->visit_num = 1; 4833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 4843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG_GET_EXTENT 4853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("Down to level %d/%d, end_blk=%llu\n", 4863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->level, handle->max_depth, 4873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->end_blk); 4883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 4893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 4903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt default: 4913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_OP_NOT_SUPPORTED; 4923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 4933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 4943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!ix) 4953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_NO_CURRENT_NODE; 4963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 4973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent->e_flags = 0; 4983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG_GET_EXTENT 4993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("(Left %d)\n", path->left); 5003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 5013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->level == handle->max_depth) { 5033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ex = (struct ext3_extent *) ix; 5043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent->e_pblk = ext2fs_le32_to_cpu(ex->ee_start) + 5063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((__u64) ext2fs_le16_to_cpu(ex->ee_start_hi) << 32); 5073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent->e_lblk = ext2fs_le32_to_cpu(ex->ee_block); 5083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent->e_len = ext2fs_le16_to_cpu(ex->ee_len); 5093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent->e_flags |= EXT2_EXTENT_FLAGS_LEAF; 5103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (extent->e_len > EXT_INIT_MAX_LEN) { 5113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent->e_len -= EXT_INIT_MAX_LEN; 5123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent->e_flags |= EXT2_EXTENT_FLAGS_UNINIT; 5133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 5143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 5153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent->e_pblk = ext2fs_le32_to_cpu(ix->ei_leaf) + 5163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((__u64) ext2fs_le16_to_cpu(ix->ei_leaf_hi) << 32); 5173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent->e_lblk = ext2fs_le32_to_cpu(ix->ei_block); 5183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path->left > 0) { 5193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix++; 5203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt end_blk = ext2fs_le32_to_cpu(ix->ei_block); 5213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else 5223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt end_blk = path->end_blk; 5233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent->e_len = end_blk - extent->e_lblk; 5253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 5263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path->visit_num) 5273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent->e_flags |= EXT2_EXTENT_FLAGS_SECOND_VISIT; 5283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (((orig_op == EXT2_EXTENT_NEXT_LEAF) || 5303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (orig_op == EXT2_EXTENT_PREV_LEAF)) && 5313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (handle->level != handle->max_depth)) 5323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto retry; 5333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((orig_op == EXT2_EXTENT_LAST_LEAF) && 5353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((handle->level != handle->max_depth) || 5363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (path->left != 0))) 5373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto retry; 5383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 5403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 5413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic errcode_t update_path(ext2_extent_handle_t handle) 5433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 5443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk64_t blk; 5453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 5463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext3_extent_idx *ix; 5473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->level == 0) { 5493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_write_inode(handle->fs, handle->ino, 5503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->inode); 5513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 5523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix = handle->path[handle->level - 1].curr; 5533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk = ext2fs_le32_to_cpu(ix->ei_leaf) + 5543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((__u64) ext2fs_le16_to_cpu(ix->ei_leaf_hi) << 32); 5553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = io_channel_write_blk(handle->fs->io, 5573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk, 1, handle->path[handle->level].buf); 5583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 5593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 5603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 5613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#if 0 5633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidterrcode_t ext2fs_extent_save_path(ext2_extent_handle_t handle, 5643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2_extent_path_t *ret_path) 5653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 5663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2_extent_path_t save_path; 5673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent extent; 5683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2_extent_info info; 5693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 5703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent); 5723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 5733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 5743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get_info(handle, &info); 5763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 5773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 5783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_get_mem(sizeof(struct ext2_extent_path), &save_path); 5803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 5813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 5823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt memset(save_path, 0, sizeof(struct ext2_extent_path)); 5833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt save_path->magic = EXT2_ET_MAGIC_EXTENT_PATH; 5853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt save_path->leaf_height = info.max_depth - info.curr_level - 1; 5863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt save_path->lblk = extent.e_lblk; 5873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *ret_path = save_path; 5893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 5903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 5913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidterrcode_t ext2fs_extent_free_path(ext2_extent_path_t path) 5933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 5943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_CHECK_MAGIC(path, EXT2_ET_MAGIC_EXTENT_PATH); 5953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 5963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_free_mem(&path); 5973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 5983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 5993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 6003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/* 6023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Go to the node at leaf_level which contains logical block blk. 6033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 6043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * leaf_level is height from the leaf node level, i.e. 6053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * leaf_level 0 is at leaf node, leaf_level 1 is 1 above etc. 6063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 6073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * If "blk" has no mapping (hole) then handle is left at last 6083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * extent before blk. 6093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 6103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic errcode_t extent_goto(ext2_extent_handle_t handle, 6113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int leaf_level, blk64_t blk) 6123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 6133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent extent; 6143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 6153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent); 6173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 6183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval == EXT2_ET_EXTENT_NO_NEXT) 6193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = EXT2_ET_EXTENT_NOT_FOUND; 6203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 6213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (leaf_level > handle->max_depth) { 6243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 6253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("leaf level %d greater than tree depth %d\n", 6263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt leaf_level, handle->max_depth); 6273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 6283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_OP_NOT_SUPPORTED; 6293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 6323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("goto extent ino %u, level %d, %llu\n", handle->ino, 6333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt leaf_level, blk); 6343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 6353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG_GOTO_EXTENTS 6373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dbg_print_extent("root", &extent); 6383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 6393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt while (1) { 6403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->max_depth - handle->level == leaf_level) { 6413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* block is in this &extent */ 6423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((blk >= extent.e_lblk) && 6433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (blk < extent.e_lblk + extent.e_len)) 6443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 6453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (blk < extent.e_lblk) { 6463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, 6473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_EXTENT_PREV_SIB, 6483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &extent); 6493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_EXTENT_NOT_FOUND; 6503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, 6523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_EXTENT_NEXT_SIB, 6533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &extent); 6543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval == EXT2_ET_EXTENT_NO_NEXT) 6553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_EXTENT_NOT_FOUND; 6563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 6573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 6583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt continue; 6593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_NEXT_SIB, 6623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &extent); 6633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval == EXT2_ET_EXTENT_NO_NEXT) 6643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto go_down; 6653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 6663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 6673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG_GOTO_EXTENTS 6693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dbg_print_extent("next", &extent); 6703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 6713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (blk == extent.e_lblk) 6723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto go_down; 6733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (blk > extent.e_lblk) 6743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt continue; 6753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_PREV_SIB, 6773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &extent); 6783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 6793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 6803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG_GOTO_EXTENTS 6823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dbg_print_extent("prev", &extent); 6833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 6843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt go_down: 6863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_DOWN, 6873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &extent); 6883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 6893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 6903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG_GOTO_EXTENTS 6923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dbg_print_extent("down", &extent); 6933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 6943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 6953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 6963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 6973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidterrcode_t ext2fs_extent_goto(ext2_extent_handle_t handle, 6983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk64_t blk) 6993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 7003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return extent_goto(handle, 0, blk); 7013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 7023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/* 7043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Traverse back up to root fixing parents of current node as needed. 7053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 7063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * If we changed start of first entry in a node, fix parent index start 7073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * and so on. 7083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 7093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Safe to call for any position in node; if not at the first entry, 7103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * will simply return. 7113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 7123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic errcode_t ext2fs_extent_fix_parents(ext2_extent_handle_t handle) 7133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 7143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int retval = 0; 7153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk64_t start; 7163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct extent_path *path; 7173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent extent; 7183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE); 7203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!(handle->fs->flags & EXT2_FLAG_RW)) 7223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_RO_FILSYS; 7233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!handle->path) 7253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_NO_CURRENT_NODE; 7263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path = handle->path + handle->level; 7283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!path->curr) 7293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_NO_CURRENT_NODE; 7303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent); 7323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 7333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 7343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* modified node's start block */ 7363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt start = extent.e_lblk; 7373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* traverse up until index not first, or startblk matches, or top */ 7393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt while (handle->level > 0 && 7403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (path->left == path->entries - 1)) { 7413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_UP, &extent); 7423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 7433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 7443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (extent.e_lblk == start) 7453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 7463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path = handle->path + handle->level; 7473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_len += (extent.e_lblk - start); 7483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_lblk = start; 7493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_replace(handle, 0, &extent); 7503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 7513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 7523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt update_path(handle); 7533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 7543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* put handle back to where we started */ 7563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_goto(handle, start); 7573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtdone: 7583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 7593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 7603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidterrcode_t ext2fs_extent_replace(ext2_extent_handle_t handle, 7623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int flags EXT2FS_ATTR((unused)), 7633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent *extent) 7643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 7653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct extent_path *path; 7663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext3_extent_idx *ix; 7673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext3_extent *ex; 7683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE); 7703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!(handle->fs->flags & EXT2_FLAG_RW)) 7723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_RO_FILSYS; 7733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!handle->path) 7753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_NO_CURRENT_NODE; 7763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path = handle->path + handle->level; 7783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!path->curr) 7793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_NO_CURRENT_NODE; 7803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 7823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("extent replace: %u ", handle->ino); 7833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dbg_print_extent(0, extent); 7843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 7853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->level == handle->max_depth) { 7873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ex = path->curr; 7883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 7893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ex->ee_block = ext2fs_cpu_to_le32(extent->e_lblk); 7903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ex->ee_start = ext2fs_cpu_to_le32(extent->e_pblk & 0xFFFFFFFF); 7913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ex->ee_start_hi = ext2fs_cpu_to_le16(extent->e_pblk >> 32); 7923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (extent->e_flags & EXT2_EXTENT_FLAGS_UNINIT) { 7933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (extent->e_len > EXT_UNINIT_MAX_LEN) 7943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_EXTENT_INVALID_LENGTH; 7953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ex->ee_len = ext2fs_cpu_to_le16(extent->e_len + 7963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT_INIT_MAX_LEN); 7973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 7983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (extent->e_len > EXT_INIT_MAX_LEN) 7993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_EXTENT_INVALID_LENGTH; 8003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ex->ee_len = ext2fs_cpu_to_le16(extent->e_len); 8013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 8023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 8033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix = path->curr; 8043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix->ei_leaf = ext2fs_cpu_to_le32(extent->e_pblk & 0xFFFFFFFF); 8063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix->ei_leaf_hi = ext2fs_cpu_to_le16(extent->e_pblk >> 32); 8073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix->ei_block = ext2fs_cpu_to_le32(extent->e_lblk); 8083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix->ei_unused = 0; 8093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 8103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt update_path(handle); 8113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 8123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 8133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/* 8153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * allocate a new block, move half the current node to it, and update parent 8163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 8173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * handle will be left pointing at original record. 8183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 8193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic errcode_t extent_node_split(ext2_extent_handle_t handle) 8203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 8213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval = 0; 8223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk_t new_node_pblk; 8233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk64_t new_node_start; 8243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk64_t orig_lblk; 8253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk64_t goal_blk = 0; 8263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int orig_height; 8273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt char *block_buf = NULL; 8283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent extent; 8293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct extent_path *path, *newpath = 0; 8303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext3_extent_header *eh, *neweh; 8313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int tocopy; 8323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int new_root = 0; 8333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2_extent_info info; 8343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* basic sanity */ 8363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE); 8373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!(handle->fs->flags & EXT2_FLAG_RW)) 8393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_RO_FILSYS; 8403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!handle->path) 8423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_NO_CURRENT_NODE; 8433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 8453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("splitting node at level %d\n", handle->level); 8463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 8473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent); 8483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 8493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 8503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get_info(handle, &info); 8523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 8533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 8543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* save the position we were originally splitting... */ 8563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt orig_height = info.max_depth - info.curr_level; 8573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt orig_lblk = extent.e_lblk; 8583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* Is there room in the parent for a new entry? */ 8603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->level && 8613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (handle->path[handle->level - 1].entries >= 8623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->path[handle->level - 1].max_entries)) { 8633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 8653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("parent level %d full; splitting it too\n", 8663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->level - 1); 8673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 8683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* split the parent */ 8693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_UP, &extent); 8703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 8713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 8723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goal_blk = extent.e_pblk; 8733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = extent_node_split(handle); 8753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 8763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 8773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* get handle back to our original split position */ 8793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = extent_goto(handle, orig_height, orig_lblk); 8803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 8813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 8823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 8833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* At this point, parent should have room for this split */ 8853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path = handle->path + handle->level; 8863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!path->curr) 8873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_NO_CURRENT_NODE; 8883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* extent header of the current node we'll split */ 8903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh = (struct ext3_extent_header *)path->buf; 8913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 8923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* splitting root level means moving them all out */ 8933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->level == 0) { 8943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt new_root = 1; 8953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt tocopy = ext2fs_le16_to_cpu(eh->eh_entries); 8963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_get_mem(((handle->max_depth+2) * 8973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt sizeof(struct extent_path)), 8983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &newpath); 8993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 9003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 9013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt memset(newpath, 0, 9023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((handle->max_depth+2) * sizeof(struct extent_path))); 9033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 9043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt tocopy = ext2fs_le16_to_cpu(eh->eh_entries) / 2; 9053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 9063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 9083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("will copy out %d of %d entries at level %d\n", 9093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt tocopy, ext2fs_le16_to_cpu(eh->eh_entries), 9103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->level); 9113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 9123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!tocopy) { 9143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 9153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("Nothing to copy to new block!\n"); 9163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 9173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = EXT2_ET_CANT_SPLIT_EXTENT; 9183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 9193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 9203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* first we need a new block, or can do nothing. */ 9223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt block_buf = malloc(handle->fs->blocksize); 9233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!block_buf) { 9243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ENOMEM; 9253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 9263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 9273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!goal_blk) { 9293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dgrp_t group = ext2fs_group_of_ino(handle->fs, handle->ino); 9303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt __u8 log_flex = handle->fs->super->s_log_groups_per_flex; 9313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (log_flex) 9333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt group = group & ~((1 << (log_flex)) - 1); 9343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goal_blk = (group * handle->fs->super->s_blocks_per_group) + 9353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->fs->super->s_first_data_block; 9363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 9373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_alloc_block(handle->fs, (blk_t) goal_blk, block_buf, 9383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &new_node_pblk); 9393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 9403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 9413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 9433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("will copy to new node at block %lu\n", 9443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (unsigned long) new_node_pblk); 9453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 9463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* Copy data into new block buffer */ 9483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* First the header for the new block... */ 9493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt neweh = (struct ext3_extent_header *) block_buf; 9503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt memcpy(neweh, eh, sizeof(struct ext3_extent_header)); 9513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt neweh->eh_entries = ext2fs_cpu_to_le16(tocopy); 9523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt neweh->eh_max = ext2fs_cpu_to_le16((handle->fs->blocksize - 9533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt sizeof(struct ext3_extent_header)) / 9543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt sizeof(struct ext3_extent)); 9553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* then the entries for the new block... */ 9573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt memcpy(EXT_FIRST_INDEX(neweh), 9583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT_FIRST_INDEX(eh) + 9593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (ext2fs_le16_to_cpu(eh->eh_entries) - tocopy), 9603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt sizeof(struct ext3_extent_idx) * tocopy); 9613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt new_node_start = ext2fs_le32_to_cpu(EXT_FIRST_INDEX(neweh)->ei_block); 9633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* ...and write the new node block out to disk. */ 9653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = io_channel_write_blk(handle->fs->io, new_node_pblk, 1, block_buf); 9663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 9683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 9693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* OK! we've created the new node; now adjust the tree */ 9713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* current path now has fewer active entries, we copied some out */ 9733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (handle->level == 0) { 9743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt memcpy(newpath, path, 9753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt sizeof(struct extent_path) * (handle->max_depth+1)); 9763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->path = newpath; 9773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt newpath = path; 9783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path = handle->path; 9793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->entries = 1; 9803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->left = path->max_entries - 1; 9813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->max_depth++; 9823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh->eh_depth = ext2fs_cpu_to_le16(handle->max_depth); 9833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 9843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->entries -= tocopy; 9853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->left -= tocopy; 9863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 9873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh->eh_entries = ext2fs_cpu_to_le16(path->entries); 9893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* this writes out the node, incl. the modified header */ 9903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = update_path(handle); 9913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 9923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 9933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 9943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* now go up and insert/replace index for new node we created */ 9953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (new_root) { 9963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_FIRST_SIB, &extent); 9973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 9983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 9993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_lblk = new_node_start; 10013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_pblk = new_node_pblk; 10023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_len = handle->path[0].end_blk - extent.e_lblk; 10033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_replace(handle, 0, &extent); 10043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 10053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 10063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 10073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt __u32 new_node_length; 10083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_UP, &extent); 10103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* will insert after this one; it's length is shorter now */ 10113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt new_node_length = new_node_start - extent.e_lblk; 10123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_len -= new_node_length; 10133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_replace(handle, 0, &extent); 10143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 10153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 10163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* now set up the new extent and insert it */ 10183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_lblk = new_node_start; 10193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_pblk = new_node_pblk; 10203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_len = new_node_length; 10213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_insert(handle, EXT2_EXTENT_INSERT_AFTER, &extent); 10223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 10233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 10243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 10253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* get handle back to our original position */ 10273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = extent_goto(handle, orig_height, orig_lblk); 10283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 10293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 10303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* new node hooked in, so update inode block count (do this here?) */ 10323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->inode->i_blocks += handle->fs->blocksize / 512; 10333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_write_inode(handle->fs, handle->ino, 10343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->inode); 10353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 10363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 10373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtdone: 10393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (newpath) 10403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_free_mem(&newpath); 10413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt free(block_buf); 10423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 10443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 10453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidterrcode_t ext2fs_extent_insert(ext2_extent_handle_t handle, int flags, 10473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent *extent) 10483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 10493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct extent_path *path; 10503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext3_extent_idx *ix; 10513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext3_extent_header *eh; 10523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 10533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE); 10553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!(handle->fs->flags & EXT2_FLAG_RW)) 10573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_RO_FILSYS; 10583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!handle->path) 10603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_NO_CURRENT_NODE; 10613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 10633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("extent insert: %u ", handle->ino); 10643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dbg_print_extent(0, extent); 10653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 10663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path = handle->path + handle->level; 10683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path->entries >= path->max_entries) { 10703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (flags & EXT2_EXTENT_INSERT_NOSPLIT) { 10713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_CANT_INSERT_EXTENT; 10723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 10733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 10743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("node full (level %d) - splitting\n", 10753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->level); 10763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 10773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = extent_node_split(handle); 10783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 10793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 10803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path = handle->path + handle->level; 10813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 10823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 10833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh = (struct ext3_extent_header *) path->buf; 10853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path->curr) { 10863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix = path->curr; 10873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (flags & EXT2_EXTENT_INSERT_AFTER) { 10883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix++; 10893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->left--; 10903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 10913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else 10923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix = EXT_FIRST_INDEX(eh); 10933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->curr = ix; 10953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 10963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path->left >= 0) 10973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt memmove(ix + 1, ix, 10983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (path->left+1) * sizeof(struct ext3_extent_idx)); 10993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->left++; 11003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->entries++; 11013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh = (struct ext3_extent_header *) path->buf; 11033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh->eh_entries = ext2fs_cpu_to_le16(path->entries); 11043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_replace(handle, 0, extent); 11063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 11073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto errout; 11083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = update_path(handle); 11103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 11113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto errout; 11123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 11143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidterrout: 11163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_extent_delete(handle, 0); 11173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 11183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 11193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/* 11213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Sets the physical block for a logical file block in the extent tree. 11223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 11233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * May: map unmapped, unmap mapped, or remap mapped blocks. 11243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 11253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Mapping an unmapped block adds a single-block extent. 11263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 11273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Unmapping first or last block modifies extent in-place 11283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * - But may need to fix parent's starts too in first-block case 11293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 11303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Mapping any unmapped block requires adding a (single-block) extent 11313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * and inserting into proper point in tree. 11323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 11333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Modifying (unmapping or remapping) a block in the middle 11343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * of an extent requires splitting the extent. 11353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * - Remapping case requires new single-block extent. 11363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 11373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Remapping first or last block adds an extent. 11383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 11393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * We really need extent adding to be smart about merging. 11403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 11413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidterrcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle, 11433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk64_t logical, blk64_t physical, int flags) 11443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 11453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t ec, retval = 0; 11463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int mapped = 1; /* logical is mapped? */ 11473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int orig_height; 11483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int extent_uninit = 0; 11493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int prev_uninit = 0; 11503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int next_uninit = 0; 11513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int new_uninit = 0; 11523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int max_len = EXT_INIT_MAX_LEN; 11533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int has_prev, has_next; 11543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk64_t orig_lblk; 11553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct extent_path *path; 11563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent extent, next_extent, prev_extent; 11573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent newextent; 11583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2_extent_info info; 11593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE); 11613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 11633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("set_bmap ino %u log %lld phys %lld flags %d\n", 11643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->ino, logical, physical, flags); 11653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 11663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!(handle->fs->flags & EXT2_FLAG_RW)) 11683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_RO_FILSYS; 11693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!handle->path) 11713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_NO_CURRENT_NODE; 11723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path = handle->path + handle->level; 11743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (flags & EXT2_EXTENT_SET_BMAP_UNINIT) { 11763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt new_uninit = 1; 11773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt max_len = EXT_UNINIT_MAX_LEN; 11783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 11793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* if (re)mapping, set up new extent to insert */ 11813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (physical) { 11823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt newextent.e_len = 1; 11833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt newextent.e_pblk = physical; 11843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt newextent.e_lblk = logical; 11853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt newextent.e_flags = EXT2_EXTENT_FLAGS_LEAF; 11863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (new_uninit) 11873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt newextent.e_flags |= EXT2_EXTENT_FLAGS_UNINIT; 11883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 11893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* special case if the extent tree is completely empty */ 11913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((handle->max_depth == 0) && (path->entries == 0)) { 11923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_insert(handle, 0, &newextent); 11933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 11943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 11953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 11963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* save our original location in the extent tree */ 11973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, 11983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &extent))) { 11993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval != EXT2_ET_NO_CURRENT_NODE) 12003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 12013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt memset(&extent, 0, sizeof(extent)); 12023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 12033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((retval = ext2fs_extent_get_info(handle, &info))) 12043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 12053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt orig_height = info.max_depth - info.curr_level; 12063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt orig_lblk = extent.e_lblk; 12073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 12083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* go to the logical spot we want to (re/un)map */ 12093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_goto(handle, logical); 12103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 12113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval == EXT2_ET_EXTENT_NOT_FOUND) { 12123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = 0; 12133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt mapped = 0; 12143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!physical) { 12153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 12163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("block %llu already unmapped\n", 12173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt logical); 12183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 12193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 12203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 12213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else 12223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 12233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 12243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 12253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* 12263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * This may be the extent *before* the requested logical, 12273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * if it's currently unmapped. 12283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * 12293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Get the previous and next leaf extents, if they are present. 12303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 12313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent); 12323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 12333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 12343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT) 12353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent_uninit = 1; 12363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_NEXT_LEAF, &next_extent); 12373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 12383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt has_next = 0; 12393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval != EXT2_ET_EXTENT_NO_NEXT) 12403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 12413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 12423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dbg_print_extent("set_bmap: next_extent", 12433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &next_extent); 12443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt has_next = 1; 12453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (next_extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT) 12463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt next_uninit = 1; 12473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 12483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_goto(handle, logical); 12493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval && retval != EXT2_ET_EXTENT_NOT_FOUND) 12503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 12513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_PREV_LEAF, &prev_extent); 12523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 12533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt has_prev = 0; 12543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval != EXT2_ET_EXTENT_NO_PREV) 12553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 12563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 12573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt has_prev = 1; 12583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dbg_print_extent("set_bmap: prev_extent", 12593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &prev_extent); 12603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (prev_extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT) 12613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt prev_uninit = 1; 12623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 12633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_goto(handle, logical); 12643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval && retval != EXT2_ET_EXTENT_NOT_FOUND) 12653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 12663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 12673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* check if already pointing to the requested physical */ 12683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (mapped && (new_uninit == extent_uninit) && 12693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (extent.e_pblk + (logical - extent.e_lblk) == physical)) { 12703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 12713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("physical block (at %llu) unchanged\n", logical); 12723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 12733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 12743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 12753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 12763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!mapped) { 12773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 12783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("mapping unmapped logical block %llu\n", logical); 12793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 12803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((logical == extent.e_lblk + extent.e_len) && 12813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (physical == extent.e_pblk + extent.e_len) && 12823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (new_uninit == extent_uninit) && 12833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((int) extent.e_len < max_len-1)) { 12843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_len++; 12853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_replace(handle, 0, &extent); 12863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else if ((logical == extent.e_lblk - 1) && 12873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (physical == extent.e_pblk - 1) && 12883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (new_uninit == extent_uninit) && 12893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((int) extent.e_len < max_len - 1)) { 12903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_len++; 12913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_lblk--; 12923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_pblk--; 12933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_replace(handle, 0, &extent); 12943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else if (has_next && 12953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (logical == next_extent.e_lblk - 1) && 12963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (physical == next_extent.e_pblk - 1) && 12973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (new_uninit == next_uninit) && 12983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((int) next_extent.e_len < max_len - 1)) { 12993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, 13003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_EXTENT_NEXT_LEAF, 13013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &next_extent); 13023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 13033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 13043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt next_extent.e_len++; 13053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt next_extent.e_lblk--; 13063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt next_extent.e_pblk--; 13073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_replace(handle, 0, &next_extent); 13083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else if (logical < extent.e_lblk) 13093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_insert(handle, 0, &newextent); 13103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else 13113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_insert(handle, 13123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_EXTENT_INSERT_AFTER, &newextent); 13133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 13143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 13153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_fix_parents(handle); 13163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 13173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 13183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else if ((logical == extent.e_lblk) && (extent.e_len == 1)) { 13193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 13203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("(re/un)mapping only block in extent\n"); 13213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 13223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (physical) { 13233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_replace(handle, 0, &newextent); 13243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 13253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_delete(handle, 0); 13263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 13273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 13283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ec = ext2fs_extent_fix_parents(handle); 13293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (ec != EXT2_ET_NO_CURRENT_NODE) 13303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ec; 13313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 13323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 13333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 13343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 13353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else if (logical == extent.e_lblk + extent.e_len - 1) { 13363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 13373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("(re/un)mapping last block in extent\n"); 13383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 13393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (physical) { 13403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (has_next && 13413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (logical == (next_extent.e_lblk - 1)) && 13423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (physical == (next_extent.e_pblk - 1)) && 13433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (new_uninit == next_uninit) && 13443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((int) next_extent.e_len < max_len - 1)) { 13453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, 13463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_EXTENT_NEXT_LEAF, &next_extent); 13473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 13483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 13493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt next_extent.e_len++; 13503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt next_extent.e_lblk--; 13513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt next_extent.e_pblk--; 13523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_replace(handle, 0, 13533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &next_extent); 13543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 13553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 13563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else 13573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_insert(handle, 13583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_EXTENT_INSERT_AFTER, &newextent); 13593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 13603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 13613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* Now pointing at inserted extent; move back to prev */ 13623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, 13633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_EXTENT_PREV_LEAF, 13643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &extent); 13653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 13663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 13673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 13683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_len--; 13693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_replace(handle, 0, &extent); 13703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 13713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 13723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else if (logical == extent.e_lblk) { 13733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 13743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("(re/un)mapping first block in extent\n"); 13753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 13763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (physical) { 13773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (has_prev && 13783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (logical == (prev_extent.e_lblk + 13793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt prev_extent.e_len)) && 13803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (physical == (prev_extent.e_pblk + 13813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt prev_extent.e_len)) && 13823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (new_uninit == prev_uninit) && 13833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ((int) prev_extent.e_len < max_len-1)) { 13843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, 13853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_EXTENT_PREV_LEAF, &prev_extent); 13863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 13873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 13883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt prev_extent.e_len++; 13893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_replace(handle, 0, 13903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &prev_extent); 13913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else 13923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_insert(handle, 13933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 0, &newextent); 13943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 13953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 13963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, 13973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_EXTENT_NEXT_LEAF, 13983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &extent); 13993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 14003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 14013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 14023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_pblk++; 14033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_lblk++; 14043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_len--; 14053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_replace(handle, 0, &extent); 14063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 14073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 14083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 14093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt __u32 orig_length; 14103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 14123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("(re/un)mapping in middle of extent\n"); 14133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 14143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* need to split this extent; later */ 14153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt orig_length = extent.e_len; 14173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* shorten pre-split extent */ 14193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_len = (logical - extent.e_lblk); 14203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_replace(handle, 0, &extent); 14213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 14223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 14233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* insert our new extent, if any */ 14243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (physical) { 14253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* insert new extent after current */ 14263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_insert(handle, 14273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_EXTENT_INSERT_AFTER, &newextent); 14283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 14293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 14303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 14313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* add post-split extent */ 14323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_pblk += extent.e_len + 1; 14333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_lblk += extent.e_len + 1; 14343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_len = orig_length - extent.e_len - 1; 14353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_insert(handle, 14363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_EXTENT_INSERT_AFTER, &extent); 14373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 14383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt goto done; 14393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 14403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtdone: 14423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* get handle back to its position */ 14433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (orig_height > handle->max_depth) 14443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt orig_height = handle->max_depth; /* In case we shortened the tree */ 14453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent_goto(handle, orig_height, orig_lblk); 14463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 14473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 14483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidterrcode_t ext2fs_extent_delete(ext2_extent_handle_t handle, int flags) 14503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 14513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct extent_path *path; 14523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt char *cp; 14533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext3_extent_header *eh; 14543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval = 0; 14553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE); 14573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!(handle->fs->flags & EXT2_FLAG_RW)) 14593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_RO_FILSYS; 14603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!handle->path) 14623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_NO_CURRENT_NODE; 14633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 14653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt { 14663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent extent; 14673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, 14693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &extent); 14703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval == 0) { 14713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("extent delete %u ", handle->ino); 14723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dbg_print_extent(0, &extent); 14733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 14743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 14753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 14763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path = handle->path + handle->level; 14783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!path->curr) 14793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return EXT2_ET_NO_CURRENT_NODE; 14803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt cp = path->curr; 14823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path->left) { 14843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt memmove(cp, cp + sizeof(struct ext3_extent_idx), 14853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->left * sizeof(struct ext3_extent_idx)); 14863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->left--; 14873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 14883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext3_extent_idx *ix = path->curr; 14893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ix--; 14903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->curr = ix; 14913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 14923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (--path->entries == 0) 14933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path->curr = 0; 14943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 14953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt /* if non-root node has no entries left, remove it & parent ptr to it */ 14963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path->entries == 0 && handle->level) { 14973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!(flags & EXT2_EXTENT_DELETE_KEEP_EMPTY)) { 14983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent extent; 14993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(handle, EXT2_EXTENT_UP, 15013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt &extent); 15023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) 15033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 15043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_delete(handle, flags); 15063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->inode->i_blocks -= handle->fs->blocksize / 512; 15073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_write_inode(handle->fs, handle->ino, 15083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt handle->inode); 15093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2fs_block_alloc_stats(handle->fs, extent.e_pblk, -1); 15103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 15113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 15123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh = (struct ext3_extent_header *) path->buf; 15133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh->eh_entries = ext2fs_cpu_to_le16(path->entries); 15143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if ((path->entries == 0) && (handle->level == 0)) 15153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt eh->eh_depth = handle->max_depth = 0; 15163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = update_path(handle); 15173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 15183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return retval; 15193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 15203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidterrcode_t ext2fs_extent_get_info(ext2_extent_handle_t handle, 15223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2_extent_info *info) 15233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 15243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct extent_path *path; 15253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE); 15273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt memset(info, 0, sizeof(struct ext2_extent_info)); 15293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt path = handle->path + handle->level; 15313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path) { 15323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (path->curr) 15333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt info->curr_entry = ((char *) path->curr - path->buf) / 15343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt sizeof(struct ext3_extent_idx); 15353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else 15363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt info->curr_entry = 0; 15373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt info->num_entries = path->entries; 15383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt info->max_entries = path->max_entries; 15393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt info->bytes_avail = (path->max_entries - path->entries) * 15403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt sizeof(struct ext3_extent); 15413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 15423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt info->curr_level = handle->level; 15443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt info->max_depth = handle->max_depth; 15453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt info->max_lblk = ((__u64) 1 << 32) - 1; 15463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt info->max_pblk = ((__u64) 1 << 48) - 1; 15473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt info->max_len = (1UL << 15); 15483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt info->max_uninit_len = (1UL << 15) - 1; 15493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 15513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 15523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef DEBUG 15543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include "ss/ss.h" 15563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include "debugfs.h" 15583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/* 15603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Hook in new commands into debugfs 15613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */ 15623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtconst char *debug_prog_name = "tst_extents"; 15633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtextern ss_request_table extent_cmds; 15643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtss_request_table *extra_cmds = &extent_cmds; 15653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtext2_ino_t current_ino = 0; 15673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtext2_extent_handle_t current_handle; 15683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtint common_extent_args_process(int argc, char *argv[], int min_argc, 15703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int max_argc, const char *cmd, 15713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt const char *usage, int flags) 15723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 15733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (common_args_process(argc, argv, min_argc, max_argc, cmd, 15743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt usage, flags)) 15753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 1; 15763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!current_handle) { 15783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err(cmd, 0, "Extent handle not open"); 15793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 1; 15803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 15813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return 0; 15823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 15833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_inode(int argc, char *argv[]) 15853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 15863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt ext2_ino_t inode; 15873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int i; 15883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext3_extent_header *eh; 15893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 15903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (check_fs_open(argv[0])) 15923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 15933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 15943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (argc == 1) { 15953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (current_ino) 15963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("Current inode is %d\n", current_ino); 15973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else 15983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("No current inode\n"); 15993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 16003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 16013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (common_inode_args_process(argc, argv, &inode, 0)) { 16033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 16043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 16053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt current_ino = 0; 16073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_open(current_fs, inode, ¤t_handle); 16093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 16103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err(argv[1], retval, "while opening extent handle"); 16113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 16123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 16133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt current_ino = inode; 16153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("Loaded inode %d\n", current_ino); 16173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 16193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 16203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid generic_goto_node(char *cmd_name, int op) 16223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 16233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent extent; 16243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 16253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (check_fs_open(cmd_name)) 16273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 16283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!current_handle) { 16303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err(cmd_name, 0, "Extent handle not open"); 16313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 16323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 16333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(current_handle, op, &extent); 16353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 16363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err(cmd_name, retval, 0); 16373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 16383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 16393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dbg_print_extent(0, &extent); 16403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 16413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_current_node(int argc, char *argv[]) 16433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 16443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt generic_goto_node(argv[0], EXT2_EXTENT_CURRENT); 16453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 16463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_root_node(int argc, char *argv[]) 16483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 16493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt generic_goto_node(argv[0], EXT2_EXTENT_ROOT); 16503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 16513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_last_leaf(int argc, char *argv[]) 16533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 16543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt generic_goto_node(argv[0], EXT2_EXTENT_LAST_LEAF); 16553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 16563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_first_sib(int argc, char *argv[]) 16583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 16593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt generic_goto_node(argv[0], EXT2_EXTENT_FIRST_SIB); 16603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 16613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_last_sib(int argc, char *argv[]) 16633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 16643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt generic_goto_node(argv[0], EXT2_EXTENT_LAST_SIB); 16653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 16663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_next_sib(int argc, char *argv[]) 16683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 16693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt generic_goto_node(argv[0], EXT2_EXTENT_NEXT_SIB); 16703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 16713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_prev_sib(int argc, char *argv[]) 16733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 16743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt generic_goto_node(argv[0], EXT2_EXTENT_PREV_SIB); 16753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 16763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_next_leaf(int argc, char *argv[]) 16783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 16793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt generic_goto_node(argv[0], EXT2_EXTENT_NEXT_LEAF); 16803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 16813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_prev_leaf(int argc, char *argv[]) 16833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 16843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt generic_goto_node(argv[0], EXT2_EXTENT_PREV_LEAF); 16853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 16863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_next(int argc, char *argv[]) 16883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 16893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt generic_goto_node(argv[0], EXT2_EXTENT_NEXT); 16903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 16913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_prev(int argc, char *argv[]) 16933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 16943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt generic_goto_node(argv[0], EXT2_EXTENT_PREV); 16953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 16963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 16973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_up(int argc, char *argv[]) 16983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 16993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt generic_goto_node(argv[0], EXT2_EXTENT_UP); 17003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 17013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_down(int argc, char *argv[]) 17033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 17043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt generic_goto_node(argv[0], EXT2_EXTENT_DOWN); 17053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 17063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_delete_node(int argc, char *argv[]) 17083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 17093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 17103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int err; 17113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (common_extent_args_process(argc, argv, 1, 1, "delete_node", 17133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt "", CHECK_FS_RW | CHECK_FS_BITMAPS)) 17143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 17153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_delete(current_handle, 0); 17173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 17183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err(argv[0], retval, 0); 17193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 17203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 17213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (current_handle->path && current_handle->path[0].curr) 17223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt do_current_node(argc, argv); 17233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 17243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_replace_node(int argc, char *argv[]) 17263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 17273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt const char *usage = "[--uninit] <lblk> <len> <pblk>"; 17283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 17293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent extent; 17303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int err; 17313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (common_extent_args_process(argc, argv, 3, 5, "replace_node", 17333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt usage, CHECK_FS_RW | CHECK_FS_BITMAPS)) 17343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 17353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_flags = 0; 17373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!strcmp(argv[1], "--uninit")) { 17393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt argc--; 17403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt argv++; 17413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_flags |= EXT2_EXTENT_FLAGS_UNINIT; 17423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 17433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (argc != 4) { 17453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fprintf(stderr, "Usage: %s %s\n", argv[0], usage); 17463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 17473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 17483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_lblk = parse_ulong(argv[1], argv[0], "logical block", &err); 17503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (err) 17513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 17523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_len = parse_ulong(argv[2], argv[0], "logical block", &err); 17543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (err) 17553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 17563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_pblk = parse_ulong(argv[3], argv[0], "logical block", &err); 17583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (err) 17593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 17603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_replace(current_handle, 0, &extent); 17623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 17633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err(argv[0], retval, 0); 17643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 17653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 17663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt do_current_node(argc, argv); 17673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 17683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_split_node(int argc, char *argv[]) 17703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 17713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 17723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent extent; 17733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int err; 17743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (common_extent_args_process(argc, argv, 1, 1, "split_node", 17763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt "", CHECK_FS_RW | CHECK_FS_BITMAPS)) 17773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 17783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = extent_node_split(current_handle); 17803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 17813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err(argv[0], retval, 0); 17823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 17833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 17843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt do_current_node(argc, argv); 17853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 17863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_insert_node(int argc, char *argv[]) 17883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 17893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt const char *usage = "[--after] [--uninit] <lblk> <len> <pblk>"; 17903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 17913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent extent; 17923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt char *cmd; 17933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int err; 17943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int flags = 0; 17953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 17963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (common_extent_args_process(argc, argv, 3, 6, "insert_node", 17973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt usage, CHECK_FS_RW | CHECK_FS_BITMAPS)) 17983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 17993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt cmd = argv[0]; 18013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_flags = 0; 18033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt while (argc > 2) { 18053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!strcmp(argv[1], "--after")) { 18063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt argc--; 18073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt argv++; 18083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt flags |= EXT2_EXTENT_INSERT_AFTER; 18093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt continue; 18103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 18113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!strcmp(argv[1], "--uninit")) { 18123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt argc--; 18133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt argv++; 18143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_flags |= EXT2_EXTENT_FLAGS_UNINIT; 18153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt continue; 18163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 18173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 18183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 18193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (argc != 4) { 18213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fprintf(stderr, "usage: %s %s\n", cmd, usage); 18223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 18233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 18243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_lblk = parse_ulong(argv[1], cmd, 18263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt "logical block", &err); 18273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (err) 18283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 18293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_len = parse_ulong(argv[2], cmd, 18313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt "length", &err); 18323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (err) 18333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 18343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt extent.e_pblk = parse_ulong(argv[3], cmd, 18363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt "pysical block", &err); 18373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (err) 18383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 18393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_insert(current_handle, flags, &extent); 18413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 18423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err(cmd, retval, 0); 18433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 18443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 18453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt do_current_node(argc, argv); 18463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 18473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_set_bmap(int argc, char **argv) 18493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 18503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt const char *usage = "[--uninit] <lblk> <pblk>"; 18513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 18523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk_t logical; 18533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk_t physical; 18543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt char *cmd = argv[0]; 18553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int flags = 0; 18563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int err; 18573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (common_extent_args_process(argc, argv, 3, 5, "set_bmap", 18593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt usage, CHECK_FS_RW | CHECK_FS_BITMAPS)) 18603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 18613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (argc > 2 && !strcmp(argv[1], "--uninit")) { 18633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt argc--; 18643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt argv++; 18653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt flags |= EXT2_EXTENT_SET_BMAP_UNINIT; 18663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 18673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (argc != 3) { 18693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fprintf(stderr, "Usage: %s %s\n", cmd, usage); 18703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 18713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 18723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt logical = parse_ulong(argv[1], cmd, 18743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt "logical block", &err); 18753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (err) 18763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 18773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt physical = parse_ulong(argv[2], cmd, 18793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt "physical block", &err); 18803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (err) 18813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 18823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_set_bmap(current_handle, logical, 18843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt (blk64_t) physical, flags); 18853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 18863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err(cmd, retval, 0); 18873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 18883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 18893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (current_handle->path && current_handle->path[0].curr) 18903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt do_current_node(argc, argv); 18913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 18923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 18933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_print_all(int argc, char **argv) 18943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 18953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt const char *usage = "[--leaf-only|--reverse|--reverse-leaf]"; 18963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent extent; 18973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 18983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t end_err = EXT2_ET_EXTENT_NO_NEXT; 18993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int op = EXT2_EXTENT_NEXT; 19003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int first_op = EXT2_EXTENT_ROOT; 19013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (common_extent_args_process(argc, argv, 1, 2, "print_all", 19043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt usage, 0)) 19053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 19063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (argc == 2) { 19083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (!strcmp(argv[1], "--leaf-only")) 19093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt op = EXT2_EXTENT_NEXT_LEAF; 19103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt else if (!strcmp(argv[1], "--reverse")) { 19113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt op = EXT2_EXTENT_PREV; 19123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt first_op = EXT2_EXTENT_LAST_LEAF; 19133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt end_err = EXT2_ET_EXTENT_NO_PREV; 19143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else if (!strcmp(argv[1], "--reverse-leaf")) { 19153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt op = EXT2_EXTENT_PREV_LEAF; 19163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt first_op = EXT2_EXTENT_LAST_LEAF; 19173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt end_err = EXT2_ET_EXTENT_NO_PREV; 19183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } else { 19193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt fprintf(stderr, "Usage: %s %s\n", argv[0], usage); 19203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 19213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 19223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 19233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(current_handle, first_op, &extent); 19253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 19263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err(argv[0], retval, 0); 19273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 19283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 19293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dbg_print_extent(0, &extent); 19303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt while (1) { 19323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(current_handle, op, &extent); 19333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval == end_err) 19343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt break; 19353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 19373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err(argv[0], retval, 0); 19383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 19393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 19403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dbg_print_extent(0, &extent); 19413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 19423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 19433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_info(int argc, char **argv) 19453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 19463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent extent; 19473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2_extent_info info; 19483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 19493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (common_extent_args_process(argc, argv, 1, 1, "info", "", 0)) 19513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 19523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get_info(current_handle, &info); 19543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 19553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err(argv[0], retval, 0); 19563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 19573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 19583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = ext2fs_extent_get(current_handle, 19603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt EXT2_EXTENT_CURRENT, &extent); 19613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 19623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err(argv[0], retval, 0); 19633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 19643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 19653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt dbg_print_extent(0, &extent); 19673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("Current handle location: %d/%d (max: %d, bytes %d), level %d/%d\n", 19693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt info.curr_entry, info.num_entries, info.max_entries, 19703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt info.bytes_avail, info.curr_level, info.max_depth); 19713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("\tmax lblk: %llu, max pblk: %llu\n", info.max_lblk, 19723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt info.max_pblk); 19733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt printf("\tmax_len: %u, max_uninit_len: %u\n", info.max_len, 19743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt info.max_uninit_len); 19753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 19763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid do_goto_block(int argc, char **argv) 19783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{ 19793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt struct ext2fs_extent extent; 19803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt errcode_t retval; 19813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int op = EXT2_EXTENT_NEXT_LEAF; 19823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk_t blk; 19833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt int level = 0; 19843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (common_extent_args_process(argc, argv, 2, 3, "goto_block", 19863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt "block [level]", 0)) 19873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 19883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (strtoblk(argv[0], argv[1], &blk)) 19903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 19913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (argc == 3) 19933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (strtoblk(argv[0], argv[2], &level)) 19943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 19953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt retval = extent_goto(current_handle, level, (blk64_t) blk); 19973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 19983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt if (retval) { 19993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt com_err(argv[0], retval, 20003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt "while trying to go to block %u, level %d", 20013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt blk, level); 20023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt return; 20033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt } 20043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 20053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt generic_goto_node(argv[0], EXT2_EXTENT_CURRENT); 20063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt} 20073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif 20083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt 2009