mirror of https://github.com/vitalif/e2fsprogs
Add support for extents to libext2fs
Initial implemenation of extents support in libext2fs Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>bitmap-optimize
parent
e3df15abdb
commit
3eb07f6493
|
@ -10,6 +10,8 @@ INSTALL = @INSTALL@
|
|||
@DEBUGFS_CMT@DEBUGFS_LIB_OBJS = bb_compat.o fileio.o \
|
||||
@DEBUGFS_CMT@ inode_io.o namei.o write_bb_file.o
|
||||
|
||||
MK_CMDS= _SS_DIR_OVERRIDE=../ss ../ss/mk_cmds
|
||||
|
||||
@RESIZER_CMT@RESIZE_LIB_OBJS = dupfs.o test_io.o
|
||||
|
||||
@IMAGER_CMT@E2IMAGE_LIB_OBJS = imager.o
|
||||
|
@ -35,6 +37,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
|
|||
dir_iterate.o \
|
||||
expanddir.o \
|
||||
ext_attr.o \
|
||||
extent.o \
|
||||
finddev.o \
|
||||
flushb.o \
|
||||
freefs.o \
|
||||
|
@ -90,6 +93,7 @@ SRCS= ext2_err.c \
|
|||
$(srcdir)/dupfs.c \
|
||||
$(srcdir)/expanddir.c \
|
||||
$(srcdir)/ext_attr.c \
|
||||
$(srcdir)/extent.c \
|
||||
$(srcdir)/fileio.c \
|
||||
$(srcdir)/finddev.c \
|
||||
$(srcdir)/flushb.c \
|
||||
|
@ -239,6 +243,68 @@ ext2_tdbtool: tdbtool.o
|
|||
@echo " LD $@"
|
||||
@$(CC) -o ext2_tdbtool tdbtool.o tdb.o
|
||||
|
||||
extent_dbg.c: $(srcdir)/extent_dbg.ct
|
||||
@echo " MK_CMDS $<"
|
||||
@$(MK_CMDS) $(srcdir)/extent_dbg.ct
|
||||
|
||||
debug_cmds.c debug_cmds.h: $(top_srcdir)/debugfs/debug_cmds.ct
|
||||
@echo " MK_CMDS $<@"
|
||||
@$(MK_CMDS) $(top_srcdir)/debugfs/debug_cmds.ct
|
||||
|
||||
DEBUG_OBJS= debug_cmds.o debugfs.o util.o ncheck.o icheck.o ls.o \
|
||||
lsdel.o dump.o set_fields.o logdump.o htree.o unused.o
|
||||
|
||||
debugfs.o: $(top_srcdir)/debugfs/debugfs.c
|
||||
@echo " CC $<"
|
||||
@$(CC) $(ALL_CFLAGS) -c $< -o $@
|
||||
|
||||
util.o: $(top_srcdir)/debugfs/util.c
|
||||
@echo " CC $<"
|
||||
@$(CC) $(ALL_CFLAGS) -c $< -o $@
|
||||
|
||||
ncheck.o: $(top_srcdir)/debugfs/ncheck.c
|
||||
@echo " CC $<"
|
||||
@$(CC) $(ALL_CFLAGS) -c $< -o $@
|
||||
|
||||
icheck.o: $(top_srcdir)/debugfs/icheck.c
|
||||
@echo " CC $<"
|
||||
@$(CC) $(ALL_CFLAGS) -c $< -o $@
|
||||
|
||||
ls.o: $(top_srcdir)/debugfs/ls.c
|
||||
@echo " CC $<"
|
||||
@$(CC) $(ALL_CFLAGS) -c $< -o $@
|
||||
|
||||
lsdel.o: $(top_srcdir)/debugfs/lsdel.c
|
||||
@echo " CC $<"
|
||||
@$(CC) $(ALL_CFLAGS) -c $< -o $@
|
||||
|
||||
dump.o: $(top_srcdir)/debugfs/dump.c
|
||||
@echo " CC $<"
|
||||
@$(CC) $(ALL_CFLAGS) -c $< -o $@
|
||||
|
||||
set_fields.o: $(top_srcdir)/debugfs/set_fields.c
|
||||
@echo " CC $<"
|
||||
@$(CC) $(ALL_CFLAGS) -c $< -o $@
|
||||
|
||||
logdump.o: $(top_srcdir)/debugfs/logdump.c
|
||||
@echo " CC $<"
|
||||
@$(CC) $(ALL_CFLAGS) -c $< -o $@
|
||||
|
||||
htree.o: $(top_srcdir)/debugfs/htree.c
|
||||
@echo " CC $<"
|
||||
@$(CC) $(ALL_CFLAGS) -c $< -o $@
|
||||
|
||||
unused.o: $(top_srcdir)/debugfs/unused.c
|
||||
@echo " CC $<"
|
||||
@$(CC) $(ALL_CFLAGS) -c $< -o $@
|
||||
|
||||
tst_extents: $(srcdir)/extent.c extent_dbg.c $(DEBUG_OBJS) $(LIBSS) $(LIBE2P) $(DEPLIBUUID) $(DEPLIBBLKID)
|
||||
@echo " LD $@"
|
||||
@$(CC) -o tst_extents $(srcdir)/extent.c extent_dbg.c \
|
||||
$(ALL_CFLAGS) -DDEBUG $(DEBUG_OBJS) $(LIBSS) $(LIBE2P) \
|
||||
$(LIBUUID) $(STATIC_LIBEXT2FS) $(LIBBLKID) $(LIBCOM_ERR) \
|
||||
-I $(top_srcdir)/debugfs
|
||||
|
||||
mkjournal: mkjournal.c $(STATIC_LIBEXT2FS)
|
||||
@echo " LD $@"
|
||||
@$(CC) -o mkjournal $(srcdir)/mkjournal.c -DDEBUG $(STATIC_LIBEXT2FS) $(LIBCOM_ERR) $(ALL_CFLAGS)
|
||||
|
@ -282,7 +348,7 @@ clean::
|
|||
tst_badblocks tst_iscan ext2_err.et ext2_err.c ext2_err.h \
|
||||
tst_byteswap tst_ismounted tst_getsize tst_sectgetsize \
|
||||
tst_bitops tst_types tst_icount tst_super_size \
|
||||
ext2_tdbtool mkjournal \
|
||||
ext2_tdbtool mkjournal debug_cmds.c \
|
||||
../libext2fs.a ../libext2fs_p.a ../libext2fs_chk.a
|
||||
|
||||
mostlyclean:: clean
|
||||
|
|
|
@ -62,8 +62,8 @@ ec EXT2_ET_MAGIC_E2IMAGE,
|
|||
ec EXT2_ET_MAGIC_INODE_IO_CHANNEL,
|
||||
"Wrong magic number for inode io_channel structure"
|
||||
|
||||
ec EXT2_ET_MAGIC_RESERVED_9,
|
||||
"Wrong magic number --- RESERVED_9"
|
||||
ec EXT2_ET_MAGIC_EXTENT_HANDLE,
|
||||
"Wrong magic number for ext4 extent handle"
|
||||
|
||||
ec EXT2_ET_BAD_MAGIC,
|
||||
"Bad magic number in super-block"
|
||||
|
@ -329,5 +329,76 @@ ec EXT2_ET_TDB_ERR_RDONLY,
|
|||
ec EXT2_ET_RO_BLOCK_ITERATE,
|
||||
"Attempt to modify a block mapping via a read-only block iterator"
|
||||
|
||||
end
|
||||
ec EXT2_ET_MAGIC_EXTENT_PATH,
|
||||
"Wrong magic number for ext4 extent saved path"
|
||||
|
||||
ec EXT2_ET_MAGIC_RESERVED_10,
|
||||
"Wrong magic number --- RESERVED_10"
|
||||
|
||||
ec EXT2_ET_MAGIC_RESERVED_11,
|
||||
"Wrong magic number --- RESERVED_11"
|
||||
|
||||
ec EXT2_ET_MAGIC_RESERVED_12,
|
||||
"Wrong magic number --- RESERVED_12"
|
||||
|
||||
ec EXT2_ET_MAGIC_RESERVED_13,
|
||||
"Wrong magic number --- RESERVED_13"
|
||||
|
||||
ec EXT2_ET_MAGIC_RESERVED_14,
|
||||
"Wrong magic number --- RESERVED_14"
|
||||
|
||||
ec EXT2_ET_MAGIC_RESERVED_15,
|
||||
"Wrong magic number --- RESERVED_15"
|
||||
|
||||
ec EXT2_ET_MAGIC_RESERVED_16,
|
||||
"Wrong magic number --- RESERVED_16"
|
||||
|
||||
ec EXT2_ET_MAGIC_RESERVED_17,
|
||||
"Wrong magic number --- RESERVED_17"
|
||||
|
||||
ec EXT2_ET_MAGIC_RESERVED_18,
|
||||
"Wrong magic number --- RESERVED_18"
|
||||
|
||||
ec EXT2_ET_MAGIC_RESERVED_19,
|
||||
"Wrong magic number --- RESERVED_19"
|
||||
|
||||
ec EXT2_ET_EXTENT_HEADER_BAD,
|
||||
"Corrupt extent header"
|
||||
|
||||
ec EXT2_ET_EXTENT_INDEX_BAD,
|
||||
"Corrupt extent index"
|
||||
|
||||
ec EXT2_ET_EXTENT_LEAF_BAD,
|
||||
"Corrupt extent"
|
||||
|
||||
ec EXT2_ET_EXTENT_NO_SPACE,
|
||||
"No free space in extent map"
|
||||
|
||||
ec EXT2_ET_INODE_NOT_EXTENT,
|
||||
"Inode does not use extents"
|
||||
|
||||
ec EXT2_ET_EXTENT_NO_NEXT,
|
||||
"No 'next' extent"
|
||||
|
||||
ec EXT2_ET_EXTENT_NO_PREV,
|
||||
"No 'previous' extent"
|
||||
|
||||
ec EXT2_ET_EXTENT_NO_UP,
|
||||
"No 'up' extent"
|
||||
|
||||
ec EXT2_ET_EXTENT_NO_DOWN,
|
||||
"No 'down' extent"
|
||||
|
||||
ec EXT2_ET_NO_CURRENT_NODE,
|
||||
"No current node"
|
||||
|
||||
ec EXT2_ET_OP_NOT_SUPPORTED,
|
||||
"Ext2fs operation not supported"
|
||||
|
||||
ec EXT2_ET_CANT_INSERT_EXTENT,
|
||||
"No room to insert extent in node"
|
||||
|
||||
ec EXT2_ET_EXTENT_NOT_FOUND,
|
||||
"Extent not found"
|
||||
|
||||
end
|
||||
|
|
|
@ -289,6 +289,65 @@ struct struct_ext2_filsys {
|
|||
#define EXT2_BMOVE_DEBUG 0x0002
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Generic (non-filesystem layout specific) extents structure
|
||||
*/
|
||||
|
||||
#define EXT2_EXTENT_FLAGS_LEAF 0x0001
|
||||
#define EXT2_EXTENT_FLAGS_UNINIT 0x0002
|
||||
#define EXT2_EXTENT_FLAGS_SECOND_VISIT 0x0004
|
||||
|
||||
struct ext2fs_extent {
|
||||
blk64_t e_pblk; /* first physical block */
|
||||
blk64_t e_lblk; /* first logical block extent covers */
|
||||
__u32 e_len; /* number of blocks covered by extent */
|
||||
__u32 e_flags; /* extent flags */
|
||||
};
|
||||
|
||||
typedef struct ext2_extent_handle *ext2_extent_handle_t;
|
||||
typedef struct ext2_extent_path *ext2_extent_path_t;
|
||||
|
||||
/*
|
||||
* Flags used by ext2fs_extent_get()
|
||||
*/
|
||||
#define EXT2_EXTENT_CURRENT 0x0000
|
||||
#define EXT2_EXTENT_MOVE_MASK 0x000F
|
||||
#define EXT2_EXTENT_ROOT 0x0001
|
||||
#define EXT2_EXTENT_LAST_LEAF 0x0002
|
||||
#define EXT2_EXTENT_FIRST_SIB 0x0003
|
||||
#define EXT2_EXTENT_LAST_SIB 0x0004
|
||||
#define EXT2_EXTENT_NEXT_SIB 0x0005
|
||||
#define EXT2_EXTENT_PREV_SIB 0x0006
|
||||
#define EXT2_EXTENT_NEXT_LEAF 0x0007
|
||||
#define EXT2_EXTENT_PREV_LEAF 0x0008
|
||||
#define EXT2_EXTENT_NEXT 0x0009
|
||||
#define EXT2_EXTENT_PREV 0x000A
|
||||
#define EXT2_EXTENT_UP 0x000B
|
||||
#define EXT2_EXTENT_DOWN 0x000C
|
||||
#define EXT2_EXTENT_DOWN_AND_LAST 0x000D
|
||||
|
||||
/*
|
||||
* Flags used by ext2fs_extent_insert()
|
||||
*/
|
||||
|
||||
#define EXT2_EXTENT_INSERT_AFTER 0x0001
|
||||
|
||||
/*
|
||||
* Data structure returned by ext2fs_extent_get_info()
|
||||
*/
|
||||
struct ext2_extent_info {
|
||||
int curr_entry;
|
||||
int curr_level;
|
||||
int num_entries;
|
||||
int max_entries;
|
||||
int max_depth;
|
||||
int bytes_avail;
|
||||
blk64_t max_lblk;
|
||||
blk64_t max_pblk;
|
||||
__u32 max_len;
|
||||
__u32 max_uninit_len;
|
||||
};
|
||||
|
||||
/*
|
||||
* Flags for directory block reading and writing functions
|
||||
*/
|
||||
|
@ -722,6 +781,22 @@ extern errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
|
|||
char *block_buf,
|
||||
int adjust, __u32 *newcount);
|
||||
|
||||
/* extent.c */
|
||||
extern errcode_t ext2fs_extent_header_verify(void *ptr, int size);
|
||||
extern errcode_t ext2fs_extent_open(ext2_filsys fs, ext2_ino_t ino,
|
||||
ext2_extent_handle_t *handle);
|
||||
extern errcode_t ext2fs_extent_get(ext2_extent_handle_t handle,
|
||||
int flags, struct ext2fs_extent *extent);
|
||||
extern errcode_t ext2fs_extent_replace(ext2_extent_handle_t handle, int flags,
|
||||
struct ext2fs_extent *extent);
|
||||
extern errcode_t ext2fs_extent_insert(ext2_extent_handle_t handle, int flags,
|
||||
struct ext2fs_extent *extent);
|
||||
extern errcode_t ext2fs_extent_delete(ext2_extent_handle_t handle, int flags);
|
||||
extern errcode_t ext2fs_extent_get_info(ext2_extent_handle_t handle,
|
||||
struct ext2_extent_info *info);
|
||||
extern errcode_t ext2fs_extent_goto(ext2_extent_handle_t handle,
|
||||
blk64_t blk);
|
||||
|
||||
/* fileio.c */
|
||||
extern errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino,
|
||||
struct ext2_inode *inode,
|
||||
|
|
|
@ -126,6 +126,26 @@ struct ext3_ext_path {
|
|||
#define EXT_MAX_BLOCK 0xffffffff
|
||||
#define EXT_CACHE_MARK 0xffff
|
||||
|
||||
/*
|
||||
* EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an
|
||||
* initialized extent. This is 2^15 and not (2^16 - 1), since we use the
|
||||
* MSB of ee_len field in the extent datastructure to signify if this
|
||||
* particular extent is an initialized extent or an uninitialized (i.e.
|
||||
* preallocated).
|
||||
* EXT_UNINIT_MAX_LEN is the maximum number of blocks we can have in an
|
||||
* uninitialized extent.
|
||||
* If ee_len is <= 0x8000, it is an initialized extent. Otherwise, it is an
|
||||
* uninitialized one. In other words, if MSB of ee_len is set, it is an
|
||||
* uninitialized extent with only one special scenario when ee_len = 0x8000.
|
||||
* In this case we can not have an uninitialized extent of zero length and
|
||||
* thus we make it as a special case of initialized extent with 0x8000 length.
|
||||
* This way we get better extent-to-group alignment for initialized extents.
|
||||
* Hence, the maximum number of blocks we can have in an *initialized*
|
||||
* extent is 2^15 (32768) and in an *uninitialized* extent is 2^15-1 (32767).
|
||||
*/
|
||||
#define EXT_INIT_MAX_LEN (1UL << 15)
|
||||
#define EXT_UNINIT_MAX_LEN (EXT_INIT_MAX_LEN - 1)
|
||||
|
||||
|
||||
#define EXT_FIRST_EXTENT(__hdr__) \
|
||||
((struct ext3_extent *) (((char *) (__hdr__)) + \
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,68 @@
|
|||
#
|
||||
# Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
|
||||
# under the terms of the GNU Public License.
|
||||
#
|
||||
command_table extent_cmds;
|
||||
|
||||
request do_inode, "Open an inode",
|
||||
inode;
|
||||
|
||||
request do_current_node, "Current extent node",
|
||||
current_node, current;
|
||||
|
||||
request do_root_node, "Goto root extent",
|
||||
root_node, root;
|
||||
|
||||
request do_last_leaf, "Goto last leaf",
|
||||
last_leaf;
|
||||
|
||||
request do_first_sib, "Goto first sibling",
|
||||
first_sibling, first_sib;
|
||||
|
||||
request do_last_sib, "Goto last sibling",
|
||||
last_sibling, last_sib;
|
||||
|
||||
request do_next_sib, "Goto next sibling",
|
||||
next_sibling, next_sib, ns;
|
||||
|
||||
request do_prev_sib, "Goto previous sibling",
|
||||
prev_sibling, prev_sib, ps;
|
||||
|
||||
request do_next_leaf, "Goto next leaf",
|
||||
next_leaf, nl;
|
||||
|
||||
request do_prev_leaf, "Goto previous leaf",
|
||||
prev_leaf, pl;
|
||||
|
||||
request do_next, "Goto next node",
|
||||
next, n;
|
||||
|
||||
request do_prev, "Goto previous node",
|
||||
previous, prev, p;
|
||||
|
||||
request do_up, "Up node",
|
||||
up_node, up, u;
|
||||
|
||||
request do_down, "Down node",
|
||||
down_node, down, d;
|
||||
|
||||
request do_delete_node, "Delete node",
|
||||
delete_node, delete;
|
||||
|
||||
request do_insert_node, "Insert node",
|
||||
insert_node, insert;
|
||||
|
||||
request do_replace_node, "Insert node",
|
||||
replace_node, replace;
|
||||
|
||||
request do_print_all, "Iterate over all nodes and print them",
|
||||
print_all, all;
|
||||
|
||||
request do_goto_block, "Goto extent containing specified block",
|
||||
goto_block, goto;
|
||||
|
||||
request do_info, "Print extent info",
|
||||
info;
|
||||
|
||||
end;
|
||||
|
Loading…
Reference in New Issue