Submitted By: Joe Ciccone Date: 2007-04-05 Initial Package Version: 1.4.13 Upstream Status: Unknown Origin: Rocklinux and Jim Gifford and Joe Ciccone Description: Fixes cross-compilation issues and silo no longer links to libext2fs.so, it is integrated instead. Also allows silo to build and work properly on pure64 systems. diff -Naur silo-1.4.13.orig/common/Makefile silo-1.4.13/common/Makefile --- silo-1.4.13.orig/common/Makefile 2006-06-01 13:24:53.000000000 -0400 +++ silo-1.4.13/common/Makefile 2007-04-03 17:02:53.000000000 -0400 @@ -5,19 +5,22 @@ include ../Rules.make .c.o: - $(CC) $(CFLAGS) -c $*.c + $(CC-SILO) $(CFLAGS) -c $*.c .S.o: - $(CC) $(CFLAGS) -c $*.S + $(CC-SILO) $(CFLAGS) -c $*.S OBJS = sdiv.o rem.o udiv.o urem.o jmp.o printf.o console.o prom.o tree.o stringops2.o\ stringops1.o ffs.o divdi3.o udivdi3.o -PROGRAMS = bin2h -all: $(OBJS) $(PROGRAMS) +bin2h: + $(BUILD_CC) $(CFLAGS) -o bin2h bin2h.c + +all: $(OBJS) bin2h prom.o: prom.c - $(CC) $(CFLAGS) -c -Wa,-Av9 -o prom.o prom.c + $(CC-SILO) $(CFLAGS) -c -Wa,-Av9 -o prom.o prom.c clean: - $(RM) $(PROGRAMS) *.o + $(RM) bin2h *.o + diff -Naur silo-1.4.13.orig/first/Makefile silo-1.4.13/first/Makefile --- silo-1.4.13.orig/first/Makefile 2006-06-01 13:24:53.000000000 -0400 +++ silo-1.4.13/first/Makefile 2007-04-05 19:48:31.000000000 -0400 @@ -1,4 +1,4 @@ -## +# ## Linux Loader for SPARC ## # @@ -13,7 +13,7 @@ LDFLAGS=-N -Ttext 0x4000 .S.o: - $(CC) $(CFLAGS) -c $*.S + $(CC-SILO) $(CFLAGS) -c $*.S all: first.b first.h ultra.b ultra.h generic.b generic.h fd.b ieee32.b @@ -33,7 +33,7 @@ sed -n 's/^\(000000000000\|0000\)4\([0-9a-f][0-9a-f][0-9a-f]\) .*letter_here.*$$/#define FD_LETTER_OFFSET_TMP 0x\2/p' < fd.map >> fd.h first.o: first.S - $(CC) $(CFLAGS) -c first.S -o first.o + $(CC-SILO) $(CFLAGS) -c first.S -o first.o first: first.o $(LD) $(LDFLAGS) -o first first.o @@ -46,7 +46,7 @@ $(DD) if=/dev/zero of=first.b bs=4 count=1 seek=127 ultra.o: ultra.S - $(CC) $(CFLAGS) -c -Wa,-Av9a ultra.S + $(CC-SILO) $(CFLAGS) -c -Wa,-Av9a ultra.S ultra: ultra.o $(LD) $(LDFLAGS) -o ultra ultra.o @@ -56,11 +56,11 @@ ultra.b: ultra $(ELFTOAOUT) -o ultra.b ultra echo -n 'SILO'$(IMGVERSION) | $(DD) of=ultra.b bs=8 conv=notrunc seek=3 count=1 - echo -n -e '\340' | $(DD) of=ultra.b bs=1 count=1 seek=7 conv=notrunc + echo -n -e '\0340' | $(DD) of=ultra.b bs=1 count=1 seek=7 conv=notrunc $(DD) if=/dev/zero of=ultra.b bs=4 count=1 seek=127 generic.o: generic.S - $(CC) $(CFLAGS) -c -Wa,-Av9a generic.S + $(CC-SILO) $(CFLAGS) -c -Wa,-Av9a generic.S generic: generic.o $(LD) $(LDFLAGS) -o generic generic.o @@ -70,11 +70,11 @@ generic.b: generic $(ELFTOAOUT) -o generic.b generic echo -n 'SILO'$(IMGVERSION) | $(DD) of=generic.b bs=8 conv=notrunc seek=3 count=1 - echo -n -e '\340' | $(DD) of=generic.b bs=1 count=1 seek=7 conv=notrunc + echo -n -e '\0340' | $(DD) of=generic.b bs=1 count=1 seek=7 conv=notrunc $(DD) if=/dev/zero of=generic.b bs=4 count=1 seek=255 fd.o: fd.S - $(CC) $(CFLAGS) -c -Wa,-Av9a fd.S + $(CC-SILO) $(CFLAGS) -c -Wa,-Av9a fd.S fd: fd.o $(LD) $(LDFLAGS) -o fd fd.o @@ -84,11 +84,11 @@ fd.b: fd $(ELFTOAOUT) -o fd.b fd echo -n 'SILO'$(IMGVERSION) | $(DD) of=fd.b bs=8 conv=notrunc seek=3 count=1 - echo -n -e '\340' | $(DD) of=fd.b bs=1 count=1 seek=7 conv=notrunc + echo -n -e '\0340' | $(DD) of=fd.b bs=1 count=1 seek=7 conv=notrunc $(DD) if=/dev/zero of=fd.b bs=4 count=1 seek=255 ieee32.o: ieee32.S ieee32.h - $(CC) $(CFLAGS) -DIMGVERSION='"SILO$(IMGVERSION)"' -c ieee32.S + $(CC-SILO) $(CFLAGS) -DIMGVERSION='"SILO$(IMGVERSION)"' -c ieee32.S ieee32.b: ieee32.o $(LD) $(LDFLAGS) -o ieee32.b ieee32.o diff -Naur silo-1.4.13.orig/first-isofs/Makefile silo-1.4.13/first-isofs/Makefile --- silo-1.4.13.orig/first-isofs/Makefile 2006-06-01 13:24:53.000000000 -0400 +++ silo-1.4.13/first-isofs/Makefile 2007-04-03 17:02:53.000000000 -0400 @@ -11,10 +11,10 @@ all: $(NAME).b .c.o: - $(CC) $(CFLAGS) -c $*.c + $(CC-SILO) $(CFLAGS) -c $*.c .S.o: - $(CC) $(CFLAGS) -c $*.S + $(CC-SILO) $(CFLAGS) -c $*.S OBJS_COMMON = ../common/prom.o ../common/console.o ../common/tree.o OBJS = crt0.o $(NAME).o $(OBJS_COMMON) @@ -28,7 +28,7 @@ cat $<.aout >> $@ crt0.o: crt0.S - $(CC) $(CFLAGS) -c -Wa,-Av9 -o $@ $< + $(CC-SILO) $(CFLAGS) -c -Wa,-Av9 -o $@ $< clean: $(RM) *.o $(NAME) $(NAME).b $(NAME).aout diff -Naur silo-1.4.13.orig/include/emul_32/asm/elf.h silo-1.4.13/include/emul_32/asm/elf.h --- silo-1.4.13.orig/include/emul_32/asm/elf.h 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/include/emul_32/asm/elf.h 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,162 @@ +#ifndef __ASMSPARC_ELF_H +#define __ASMSPARC_ELF_H + +/* + * ELF register definitions.. + */ + + +/* + * Sparc section types + */ +#define STT_REGISTER 13 + +/* + * Sparc ELF relocation types + */ +#define R_SPARC_NONE 0 +#define R_SPARC_8 1 +#define R_SPARC_16 2 +#define R_SPARC_32 3 +#define R_SPARC_DISP8 4 +#define R_SPARC_DISP16 5 +#define R_SPARC_DISP32 6 +#define R_SPARC_WDISP30 7 +#define R_SPARC_WDISP22 8 +#define R_SPARC_HI22 9 +#define R_SPARC_22 10 +#define R_SPARC_13 11 +#define R_SPARC_LO10 12 +#define R_SPARC_GOT10 13 +#define R_SPARC_GOT13 14 +#define R_SPARC_GOT22 15 +#define R_SPARC_PC10 16 +#define R_SPARC_PC22 17 +#define R_SPARC_WPLT30 18 +#define R_SPARC_COPY 19 +#define R_SPARC_GLOB_DAT 20 +#define R_SPARC_JMP_SLOT 21 +#define R_SPARC_RELATIVE 22 +#define R_SPARC_UA32 23 +#define R_SPARC_PLT32 24 +#define R_SPARC_HIPLT22 25 +#define R_SPARC_LOPLT10 26 +#define R_SPARC_PCPLT32 27 +#define R_SPARC_PCPLT22 28 +#define R_SPARC_PCPLT10 29 +#define R_SPARC_10 30 +#define R_SPARC_11 31 +#define R_SPARC_64 32 +#define R_SPARC_OLO10 33 +#define R_SPARC_WDISP16 40 +#define R_SPARC_WDISP19 41 +#define R_SPARC_7 43 +#define R_SPARC_5 44 +#define R_SPARC_6 45 + +/* Bits present in AT_HWCAP, primarily for Sparc32. */ + +#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */ +#define HWCAP_SPARC_STBAR 2 +#define HWCAP_SPARC_SWAP 4 +#define HWCAP_SPARC_MULDIV 8 +#define HWCAP_SPARC_V9 16 +#define HWCAP_SPARC_ULTRA3 32 + +/* For the most part we present code dumps in the format + * Solaris does. + */ +typedef unsigned long elf_greg_t; +#define ELF_NGREG 38 +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +/* Format is: + * G0 --> G7 + * O0 --> O7 + * L0 --> L7 + * I0 --> I7 + * PSR, PC, nPC, Y, WIM, TBR + */ +#define ELF_CORE_COPY_REGS(__elf_regs, __pt_regs) \ +do { unsigned long *dest = &(__elf_regs[0]); \ + struct pt_regs *src = (__pt_regs); \ + unsigned long *sp; \ + memcpy(&dest[0], &src->u_regs[0], \ + sizeof(unsigned long) * 16); \ + /* Don't try this at home kids... */ \ + sp = (unsigned long *) src->u_regs[14]; \ + copy_from_user(&dest[16], sp, \ + sizeof(unsigned long) * 16); \ + dest[32] = src->psr; \ + dest[33] = src->pc; \ + dest[34] = src->npc; \ + dest[35] = src->y; \ + dest[36] = dest[37] = 0; /* XXX */ \ +} while(0); /* Janitors: Don't touch this colon. */ + +typedef struct { + union { + unsigned long pr_regs[32]; + double pr_dregs[16]; + } pr_fr; + unsigned long __unused; + unsigned long pr_fsr; + unsigned char pr_qcnt; + unsigned char pr_q_entrysize; + unsigned char pr_en; + unsigned int pr_q[64]; +} elf_fpregset_t; + +#define ELF_CORE_COPY_TASK_REGS(__tsk, __elf_regs) \ + ({ ELF_CORE_COPY_REGS((*(__elf_regs)), (__tsk)->thread.kregs); 1; }) + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ((x)->e_machine == EM_SPARC) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_ARCH EM_SPARC +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2MSB + +#define USE_ELF_CORE_DUMP +#ifndef CONFIG_SUN4 +#define ELF_EXEC_PAGESIZE 4096 +#else +#define ELF_EXEC_PAGESIZE 8192 +#endif + + +/* This is the location that an ET_DYN program is loaded if exec'ed. Typical + use of this is to invoke "./ld.so someprog" to test out a new version of + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE) + +/* This yields a mask that user programs can use to figure out what + instruction set this cpu supports. This can NOT be done in userspace + on Sparc. */ + +/* Sun4c has none of the capabilities, most sun4m's have them all. + * XXX This is gross, set some global variable at boot time. -DaveM + */ +#define ELF_HWCAP ((ARCH_SUN4C_SUN4) ? 0 : \ + (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \ + HWCAP_SPARC_SWAP | \ + ((srmmu_modtype != Cypress && \ + srmmu_modtype != Cypress_vE && \ + srmmu_modtype != Cypress_vD) ? \ + HWCAP_SPARC_MULDIV : 0))) + +/* This yields a string that ld.so will use to load implementation + specific libraries for optimization. This is more specific in + intent than poking at uname or /proc/cpuinfo. */ + +#define ELF_PLATFORM (NULL) + + +#endif /* !(__ASMSPARC_ELF_H) */ diff -Naur silo-1.4.13.orig/include/emul_32/asm/posix_types.h silo-1.4.13/include/emul_32/asm/posix_types.h --- silo-1.4.13.orig/include/emul_32/asm/posix_types.h 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/include/emul_32/asm/posix_types.h 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,122 @@ +#ifndef __ARCH_SPARC_POSIX_TYPES_H +#define __ARCH_SPARC_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef long int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_umode_t; +typedef short __kernel_nlink_t; +typedef long __kernel_daddr_t; +typedef long __kernel_off_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef unsigned short __kernel_old_dev_t; +typedef int __kernel_clockid_t; +typedef int __kernel_timer_t; + +#if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || (__STDC_VERSION__ >= 199901L) +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + fdsetp->fds_bits[_tmp] |= (1UL<<_rem); +} + +#undef __FD_CLR +static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem); +} + +#undef __FD_ISSET +static __inline__ int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p) +{ + unsigned long _tmp = fd / __NFDBITS; + unsigned long _rem = fd % __NFDBITS; + return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0; +} + +/* + * This will unroll the loop for the normal constant cases (8 or 32 longs, + * for 256 and 1024-bit fd_sets respectively) + */ +#undef __FD_ZERO +static __inline__ void __FD_ZERO(__kernel_fd_set *p) +{ + unsigned long *tmp = p->fds_bits; + int i; + + if (__builtin_constant_p(__FDSET_LONGS)) { + switch (__FDSET_LONGS) { + case 32: + tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; + tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0; + tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0; + tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0; + tmp[16] = 0; tmp[17] = 0; tmp[18] = 0; tmp[19] = 0; + tmp[20] = 0; tmp[21] = 0; tmp[22] = 0; tmp[23] = 0; + tmp[24] = 0; tmp[25] = 0; tmp[26] = 0; tmp[27] = 0; + tmp[28] = 0; tmp[29] = 0; tmp[30] = 0; tmp[31] = 0; + return; + case 16: + tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; + tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0; + tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0; + tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0; + return; + case 8: + tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; + tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0; + return; + case 4: + tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0; + return; + } + } + i = __FDSET_LONGS; + while (i) { + i--; + *tmp = 0; + tmp++; + } +} + +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ + +#endif /* !(__ARCH_SPARC_POSIX_TYPES_H) */ diff -Naur silo-1.4.13.orig/include/emul_32/asm/types.h silo-1.4.13/include/emul_32/asm/types.h --- silo-1.4.13.orig/include/emul_32/asm/types.h 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/include/emul_32/asm/types.h 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,41 @@ +#ifndef _SPARC_TYPES_H +#define _SPARC_TYPES_H + +/* + * _xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space. + */ + +/* + * This file is never included by application software unless + * explicitly requested (e.g., via linux/types.h) in which case the + * application is Linux specific so (user-) name space pollution is + * not a major issue. However, for interoperability, libraries still + * need to be careful to avoid a name clashes. + */ + +#ifndef __ASSEMBLY__ + +typedef unsigned short umode_t; + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || (__STDC_VERSION__ >= 199901L) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +#if (defined(__STRICT_ANSI__) && !defined(inline)) +#define inline __inline__ +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* defined(_SPARC_TYPES_H) */ diff -Naur silo-1.4.13.orig/include/ext2fs/ext2_err.h silo-1.4.13/include/ext2fs/ext2_err.h --- silo-1.4.13.orig/include/ext2fs/ext2_err.h 2006-06-01 13:24:53.000000000 -0400 +++ silo-1.4.13/include/ext2fs/ext2_err.h 2007-04-03 17:02:53.000000000 -0400 @@ -3,6 +3,8 @@ * This file is automatically generated; please do not edit it. */ +#include + #define EXT2_ET_BASE (2133571328L) #define EXT2_ET_MAGIC_EXT2FS_FILSYS (2133571329L) #define EXT2_ET_MAGIC_BADBLOCKS_LIST (2133571330L) @@ -19,8 +21,8 @@ #define EXT2_ET_MAGIC_ICOUNT (2133571341L) #define EXT2_ET_MAGIC_PQ_IO_CHANNEL (2133571342L) #define EXT2_ET_MAGIC_EXT2_FILE (2133571343L) -#define EXT2_ET_MAGIC_RESERVED_7 (2133571344L) -#define EXT2_ET_MAGIC_RESERVED_8 (2133571345L) +#define EXT2_ET_MAGIC_E2IMAGE (2133571344L) +#define EXT2_ET_MAGIC_INODE_IO_CHANNEL (2133571345L) #define EXT2_ET_MAGIC_RESERVED_9 (2133571346L) #define EXT2_ET_BAD_MAGIC (2133571347L) #define EXT2_ET_REV_TOO_HIGH (2133571348L) @@ -86,7 +88,25 @@ #define EXT2_ET_UNIMPLEMENTED (2133571408L) #define EXT2_ET_CANCEL_REQUESTED (2133571409L) #define EXT2_ET_FILE_TOO_BIG (2133571410L) +#define EXT2_ET_JOURNAL_NOT_BLOCK (2133571411L) +#define EXT2_ET_NO_JOURNAL_SB (2133571412L) +#define EXT2_ET_JOURNAL_TOO_SMALL (2133571413L) +#define EXT2_ET_JOURNAL_UNSUPP_VERSION (2133571414L) +#define EXT2_ET_LOAD_EXT_JOURNAL (2133571415L) +#define EXT2_ET_NO_JOURNAL (2133571416L) +#define EXT2_ET_DIRHASH_UNSUPP (2133571417L) +#define EXT2_ET_BAD_EA_BLOCK_NUM (2133571418L) +#define EXT2_ET_TOO_MANY_INODES (2133571419L) +#define EXT2_ET_NOT_IMAGE_FILE (2133571420L) +#define EXT2_ET_RES_GDT_BLOCKS (2133571421L) +#define EXT2_ET_RESIZE_INODE_CORRUPT (2133571422L) +#define EXT2_ET_SET_BMAP_NO_IND (2133571423L) +extern const struct error_table et_ext2_error_table; extern void initialize_ext2_error_table(void); + +/* For compatibility with Heimdal */ +extern void initialize_ext2_error_table_r(struct et_list **list); + #define ERROR_TABLE_BASE_ext2 (2133571328L) /* for compatibility with older versions... */ diff -Naur silo-1.4.13.orig/include/ext2fs/ext2_io.h silo-1.4.13/include/ext2fs/ext2_io.h --- silo-1.4.13.orig/include/ext2fs/ext2_io.h 2006-06-01 13:24:53.000000000 -0400 +++ silo-1.4.13/include/ext2fs/ext2_io.h 2007-04-03 17:02:53.000000000 -0400 @@ -27,6 +27,8 @@ typedef struct struct_io_manager *io_manager; typedef struct struct_io_channel *io_channel; +#define CHANNEL_FLAGS_WRITETHROUGH 0x01 + struct struct_io_channel { errcode_t magic; io_manager manager; @@ -47,7 +49,8 @@ int actual_bytes_written, errcode_t error); int refcount; - int reserved[15]; + int flags; + int reserved[14]; void *private_data; void *app_data; }; @@ -63,7 +66,11 @@ errcode_t (*write_blk)(io_channel channel, unsigned long block, int count, const void *data); errcode_t (*flush)(io_channel channel); - int reserved[16]; + errcode_t (*write_byte)(io_channel channel, unsigned long offset, + int count, const void *data); + errcode_t (*set_option)(io_channel channel, const char *option, + const char *arg); + int reserved[14]; }; #define IO_FLAG_RW 1 @@ -78,6 +85,13 @@ #define io_channel_flush(c) ((c)->manager->flush((c))) #define io_channel_bumpcount(c) ((c)->refcount++) +/* io_manager.c */ +extern errcode_t io_channel_set_options(io_channel channel, + const char *options); +extern errcode_t io_channel_write_byte(io_channel channel, + unsigned long offset, + int count, const void *data); + /* unix_io.c */ extern io_manager unix_io_manager; diff -Naur silo-1.4.13.orig/libext2fs/alloc.c silo-1.4.13/libext2fs/alloc.c --- silo-1.4.13.orig/libext2fs/alloc.c 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/alloc.c 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,173 @@ +/* + * alloc.c --- allocate new inodes, blocks for ext2fs + * + * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + * + */ + +#include +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#if HAVE_SYS_STAT_H +#include +#endif +#if HAVE_SYS_TYPES_H +#include +#endif + +#include "ext2_fs.h" +#include "ext2fs.h" + +/* + * Right now, just search forward from the parent directory's block + * group to find the next free inode. + * + * Should have a special policy for directories. + */ +errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, + int mode EXT2FS_ATTR((unused)), + ext2fs_inode_bitmap map, ext2_ino_t *ret) +{ + ext2_ino_t dir_group = 0; + ext2_ino_t i; + ext2_ino_t start_inode; + + EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); + + if (!map) + map = fs->inode_map; + if (!map) + return EXT2_ET_NO_INODE_BITMAP; + + if (dir > 0) + dir_group = (dir - 1) / EXT2_INODES_PER_GROUP(fs->super); + + start_inode = (dir_group * EXT2_INODES_PER_GROUP(fs->super)) + 1; + if (start_inode < EXT2_FIRST_INODE(fs->super)) + start_inode = EXT2_FIRST_INODE(fs->super); + i = start_inode; + + do { + if (!ext2fs_fast_test_inode_bitmap(map, i)) + break; + i++; + if (i > fs->super->s_inodes_count) + i = EXT2_FIRST_INODE(fs->super); + } while (i != start_inode); + + if (ext2fs_test_inode_bitmap(map, i)) + return EXT2_ET_INODE_ALLOC_FAIL; + *ret = i; + return 0; +} + +/* + * Stupid algorithm --- we now just search forward starting from the + * goal. Should put in a smarter one someday.... + */ +errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal, + ext2fs_block_bitmap map, blk_t *ret) +{ + blk_t i; + + EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); + + if (!map) + map = fs->block_map; + if (!map) + return EXT2_ET_NO_BLOCK_BITMAP; + if (!goal || (goal >= fs->super->s_blocks_count)) + goal = fs->super->s_first_data_block; + i = goal; + do { + if (!ext2fs_fast_test_block_bitmap(map, i)) { + *ret = i; + return 0; + } + i++; + if (i >= fs->super->s_blocks_count) + i = fs->super->s_first_data_block; + } while (i != goal); + return EXT2_ET_BLOCK_ALLOC_FAIL; +} + +/* + * This function zeros out the allocated block, and updates all of the + * appropriate filesystem records. + */ +errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal, + char *block_buf, blk_t *ret) +{ + errcode_t retval; + blk_t block; + char *buf = 0; + + if (!block_buf) { + retval = ext2fs_get_mem(fs->blocksize, &buf); + if (retval) + return retval; + block_buf = buf; + } + memset(block_buf, 0, fs->blocksize); + + if (!fs->block_map) { + retval = ext2fs_read_block_bitmap(fs); + if (retval) + goto fail; + } + + retval = ext2fs_new_block(fs, goal, 0, &block); + if (retval) + goto fail; + + retval = io_channel_write_blk(fs->io, block, 1, block_buf); + if (retval) + goto fail; + + ext2fs_block_alloc_stats(fs, block, +1); + *ret = block; + return 0; + +fail: + if (buf) + ext2fs_free_mem(&buf); + return retval; +} + +errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, blk_t finish, + int num, ext2fs_block_bitmap map, blk_t *ret) +{ + blk_t b = start; + + EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); + + if (!map) + map = fs->block_map; + if (!map) + return EXT2_ET_NO_BLOCK_BITMAP; + if (!b) + b = fs->super->s_first_data_block; + if (!finish) + finish = start; + if (!num) + num = 1; + do { + if (b+num-1 > fs->super->s_blocks_count) + b = fs->super->s_first_data_block; + if (ext2fs_fast_test_block_bitmap_range(map, b, num)) { + *ret = b; + return 0; + } + b++; + } while (b != finish); + return EXT2_ET_BLOCK_ALLOC_FAIL; +} + diff -Naur silo-1.4.13.orig/libext2fs/alloc_sb.c silo-1.4.13/libext2fs/alloc_sb.c --- silo-1.4.13.orig/libext2fs/alloc_sb.c 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/alloc_sb.c 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,57 @@ +/* + * alloc_sb.c --- Allocate the superblock and block group descriptors for a + * newly initialized filesystem. Used by mke2fs when initializing a filesystem + * + * Copyright (C) 1994, 1995, 1996, 2003 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#if HAVE_SYS_STAT_H +#include +#endif +#if HAVE_SYS_TYPES_H +#include +#endif + +#include "ext2_fs.h" +#include "ext2fs.h" + +int ext2fs_reserve_super_and_bgd(ext2_filsys fs, + dgrp_t group, + ext2fs_block_bitmap bmap) +{ + blk_t super_blk, old_desc_blk, new_desc_blk; + int j, old_desc_blocks, num_blocks; + + num_blocks = ext2fs_super_and_bgd_loc(fs, group, &super_blk, + &old_desc_blk, &new_desc_blk, 0); + + if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) + old_desc_blocks = fs->super->s_first_meta_bg; + else + old_desc_blocks = + fs->desc_blocks + fs->super->s_reserved_gdt_blocks; + + if (super_blk || (group == 0)) + ext2fs_mark_block_bitmap(bmap, super_blk); + + if (old_desc_blk) { + for (j=0; j < old_desc_blocks; j++) + ext2fs_mark_block_bitmap(bmap, old_desc_blk + j); + } + if (new_desc_blk) + ext2fs_mark_block_bitmap(bmap, new_desc_blk); + + return num_blocks; +} diff -Naur silo-1.4.13.orig/libext2fs/alloc_stats.c silo-1.4.13/libext2fs/alloc_stats.c --- silo-1.4.13.orig/libext2fs/alloc_stats.c 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/alloc_stats.c 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,52 @@ +/* + * alloc_stats.c --- Update allocation statistics for ext2fs + * + * Copyright (C) 2001 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + * + */ + +#include + +#include "ext2_fs.h" +#include "ext2fs.h" + +void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino, + int inuse, int isdir) +{ + int group = ext2fs_group_of_ino(fs, ino); + + if (inuse > 0) + ext2fs_mark_inode_bitmap(fs->inode_map, ino); + else + ext2fs_unmark_inode_bitmap(fs->inode_map, ino); + fs->group_desc[group].bg_free_inodes_count -= inuse; + if (isdir) + fs->group_desc[group].bg_used_dirs_count += inuse; + fs->super->s_free_inodes_count -= inuse; + ext2fs_mark_super_dirty(fs); + ext2fs_mark_ib_dirty(fs); +} + +void ext2fs_inode_alloc_stats(ext2_filsys fs, ext2_ino_t ino, int inuse) +{ + ext2fs_inode_alloc_stats2(fs, ino, inuse, 0); +} + +void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse) +{ + int group = ext2fs_group_of_blk(fs, blk); + + if (inuse > 0) + ext2fs_mark_block_bitmap(fs->block_map, blk); + else + ext2fs_unmark_block_bitmap(fs->block_map, blk); + fs->group_desc[group].bg_free_blocks_count -= inuse; + fs->super->s_free_blocks_count -= inuse; + ext2fs_mark_super_dirty(fs); + ext2fs_mark_bb_dirty(fs); +} diff -Naur silo-1.4.13.orig/libext2fs/alloc_tables.c silo-1.4.13/libext2fs/alloc_tables.c --- silo-1.4.13.orig/libext2fs/alloc_tables.c 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/alloc_tables.c 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,117 @@ +/* + * alloc_tables.c --- Allocate tables for a newly initialized + * filesystem. Used by mke2fs when initializing a filesystem + * + * Copyright (C) 1996 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#if HAVE_SYS_STAT_H +#include +#endif +#if HAVE_SYS_TYPES_H +#include +#endif + +#include "ext2_fs.h" +#include "ext2fs.h" + +errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group, + ext2fs_block_bitmap bmap) +{ + errcode_t retval; + blk_t group_blk, start_blk, last_blk, new_blk, blk; + int j; + + group_blk = fs->super->s_first_data_block + + (group * fs->super->s_blocks_per_group); + + last_blk = group_blk + fs->super->s_blocks_per_group; + if (last_blk >= fs->super->s_blocks_count) + last_blk = fs->super->s_blocks_count - 1; + + if (!bmap) + bmap = fs->block_map; + + /* + * Allocate the block and inode bitmaps, if necessary + */ + if (fs->stride) { + start_blk = group_blk + fs->inode_blocks_per_group; + start_blk += ((fs->stride * group) % + (last_blk - start_blk)); + if (start_blk > last_blk) + start_blk = group_blk; + } else + start_blk = group_blk; + + if (!fs->group_desc[group].bg_block_bitmap) { + retval = ext2fs_get_free_blocks(fs, start_blk, last_blk, + 1, bmap, &new_blk); + if (retval == EXT2_ET_BLOCK_ALLOC_FAIL) + retval = ext2fs_get_free_blocks(fs, group_blk, + last_blk, 1, bmap, &new_blk); + if (retval) + return retval; + ext2fs_mark_block_bitmap(bmap, new_blk); + fs->group_desc[group].bg_block_bitmap = new_blk; + } + + if (!fs->group_desc[group].bg_inode_bitmap) { + retval = ext2fs_get_free_blocks(fs, start_blk, last_blk, + 1, bmap, &new_blk); + if (retval == EXT2_ET_BLOCK_ALLOC_FAIL) + retval = ext2fs_get_free_blocks(fs, group_blk, + last_blk, 1, bmap, &new_blk); + if (retval) + return retval; + ext2fs_mark_block_bitmap(bmap, new_blk); + fs->group_desc[group].bg_inode_bitmap = new_blk; + } + + /* + * Allocate the inode table + */ + if (!fs->group_desc[group].bg_inode_table) { + retval = ext2fs_get_free_blocks(fs, group_blk, last_blk, + fs->inode_blocks_per_group, + bmap, &new_blk); + if (retval) + return retval; + for (j=0, blk = new_blk; + j < fs->inode_blocks_per_group; + j++, blk++) + ext2fs_mark_block_bitmap(bmap, blk); + fs->group_desc[group].bg_inode_table = new_blk; + } + + + return 0; +} + + + +errcode_t ext2fs_allocate_tables(ext2_filsys fs) +{ + errcode_t retval; + dgrp_t i; + + for (i = 0; i < fs->group_desc_count; i++) { + retval = ext2fs_allocate_group_table(fs, i, fs->block_map); + if (retval) + return retval; + } + return 0; +} + diff -Naur silo-1.4.13.orig/libext2fs/badblocks.c silo-1.4.13/libext2fs/badblocks.c --- silo-1.4.13.orig/libext2fs/badblocks.c 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/badblocks.c 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,327 @@ +/* + * badblocks.c --- routines to manipulate the bad block structure + * + * Copyright (C) 1994, 1995, 1996 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#if HAVE_SYS_STAT_H +#include +#endif +#if HAVE_SYS_TYPES_H +#include +#endif + +#include "ext2_fs.h" +#include "ext2fsP.h" + +/* + * Helper function for making a badblocks list + */ +static errcode_t make_u32_list(int size, int num, __u32 *list, + ext2_u32_list *ret) +{ + ext2_u32_list bb; + errcode_t retval; + + retval = ext2fs_get_mem(sizeof(struct ext2_struct_u32_list), &bb); + if (retval) + return retval; + memset(bb, 0, sizeof(struct ext2_struct_u32_list)); + bb->magic = EXT2_ET_MAGIC_BADBLOCKS_LIST; + bb->size = size ? size : 10; + bb->num = num; + retval = ext2fs_get_mem(bb->size * sizeof(blk_t), &bb->list); + if (!bb->list) { + ext2fs_free_mem(&bb); + return retval; + } + if (list) + memcpy(bb->list, list, bb->size * sizeof(blk_t)); + else + memset(bb->list, 0, bb->size * sizeof(blk_t)); + *ret = bb; + return 0; +} + + +/* + * This procedure creates an empty u32 list. + */ +errcode_t ext2fs_u32_list_create(ext2_u32_list *ret, int size) +{ + return make_u32_list(size, 0, 0, ret); +} + +/* + * This procedure creates an empty badblocks list. + */ +errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret, int size) +{ + return make_u32_list(size, 0, 0, (ext2_badblocks_list *) ret); +} + + +/* + * This procedure copies a badblocks list + */ +errcode_t ext2fs_u32_copy(ext2_u32_list src, ext2_u32_list *dest) +{ + errcode_t retval; + + retval = make_u32_list(src->size, src->num, src->list, dest); + if (retval) + return retval; + (*dest)->badblocks_flags = src->badblocks_flags; + return 0; +} + +errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src, + ext2_badblocks_list *dest) +{ + return ext2fs_u32_copy((ext2_u32_list) src, + (ext2_u32_list *) dest); +} + +/* + * This procedure frees a badblocks list. + * + * (note: moved to closefs.c) + */ + + +/* + * This procedure adds a block to a badblocks list. + */ +errcode_t ext2fs_u32_list_add(ext2_u32_list bb, __u32 blk) +{ + errcode_t retval; + int i, j; + unsigned long old_size; + + EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST); + + if (bb->num >= bb->size) { + old_size = bb->size * sizeof(__u32); + bb->size += 100; + retval = ext2fs_resize_mem(old_size, bb->size * sizeof(__u32), + &bb->list); + if (retval) { + bb->size -= 100; + return retval; + } + } + + /* + * Add special case code for appending to the end of the list + */ + i = bb->num-1; + if ((bb->num != 0) && (bb->list[i] == blk)) + return 0; + if ((bb->num == 0) || (bb->list[i] < blk)) { + bb->list[bb->num++] = blk; + return 0; + } + + j = bb->num; + for (i=0; i < bb->num; i++) { + if (bb->list[i] == blk) + return 0; + if (bb->list[i] > blk) { + j = i; + break; + } + } + for (i=bb->num; i > j; i--) + bb->list[i] = bb->list[i-1]; + bb->list[j] = blk; + bb->num++; + return 0; +} + +errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb, blk_t blk) +{ + return ext2fs_u32_list_add((ext2_u32_list) bb, (__u32) blk); +} + +/* + * This procedure finds a particular block is on a badblocks + * list. + */ +int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk) +{ + int low, high, mid; + + if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST) + return -1; + + if (bb->num == 0) + return -1; + + low = 0; + high = bb->num-1; + if (blk == bb->list[low]) + return low; + if (blk == bb->list[high]) + return high; + + while (low < high) { + mid = (low+high)/2; + if (mid == low || mid == high) + break; + if (blk == bb->list[mid]) + return mid; + if (blk < bb->list[mid]) + high = mid; + else + low = mid; + } + return -1; +} + +/* + * This procedure tests to see if a particular block is on a badblocks + * list. + */ +int ext2fs_u32_list_test(ext2_u32_list bb, __u32 blk) +{ + if (ext2fs_u32_list_find(bb, blk) < 0) + return 0; + else + return 1; +} + +int ext2fs_badblocks_list_test(ext2_badblocks_list bb, blk_t blk) +{ + return ext2fs_u32_list_test((ext2_u32_list) bb, (__u32) blk); +} + + +/* + * Remove a block from the badblock list + */ +int ext2fs_u32_list_del(ext2_u32_list bb, __u32 blk) +{ + int remloc, i; + + if (bb->num == 0) + return -1; + + remloc = ext2fs_u32_list_find(bb, blk); + if (remloc < 0) + return -1; + + for (i = remloc ; i < bb->num-1; i++) + bb->list[i] = bb->list[i+1]; + bb->num--; + return 0; +} + +void ext2fs_badblocks_list_del(ext2_u32_list bb, __u32 blk) +{ + ext2fs_u32_list_del(bb, blk); +} + +errcode_t ext2fs_u32_list_iterate_begin(ext2_u32_list bb, + ext2_u32_iterate *ret) +{ + ext2_u32_iterate iter; + errcode_t retval; + + EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST); + + retval = ext2fs_get_mem(sizeof(struct ext2_struct_u32_iterate), &iter); + if (retval) + return retval; + + iter->magic = EXT2_ET_MAGIC_BADBLOCKS_ITERATE; + iter->bb = bb; + iter->ptr = 0; + *ret = iter; + return 0; +} + +errcode_t ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb, + ext2_badblocks_iterate *ret) +{ + return ext2fs_u32_list_iterate_begin((ext2_u32_list) bb, + (ext2_u32_iterate *) ret); +} + + +int ext2fs_u32_list_iterate(ext2_u32_iterate iter, __u32 *blk) +{ + ext2_u32_list bb; + + if (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE) + return 0; + + bb = iter->bb; + + if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST) + return 0; + + if (iter->ptr < bb->num) { + *blk = bb->list[iter->ptr++]; + return 1; + } + *blk = 0; + return 0; +} + +int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter, blk_t *blk) +{ + return ext2fs_u32_list_iterate((ext2_u32_iterate) iter, + (__u32 *) blk); +} + + +void ext2fs_u32_list_iterate_end(ext2_u32_iterate iter) +{ + if (!iter || (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE)) + return; + + iter->bb = 0; + ext2fs_free_mem(&iter); +} + +void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter) +{ + ext2fs_u32_list_iterate_end((ext2_u32_iterate) iter); +} + + +int ext2fs_u32_list_equal(ext2_u32_list bb1, ext2_u32_list bb2) +{ + EXT2_CHECK_MAGIC(bb1, EXT2_ET_MAGIC_BADBLOCKS_LIST); + EXT2_CHECK_MAGIC(bb2, EXT2_ET_MAGIC_BADBLOCKS_LIST); + + if (bb1->num != bb2->num) + return 0; + + if (memcmp(bb1->list, bb2->list, bb1->num * sizeof(blk_t)) != 0) + return 0; + return 1; +} + +int ext2fs_badblocks_equal(ext2_badblocks_list bb1, ext2_badblocks_list bb2) +{ + return ext2fs_u32_list_equal((ext2_u32_list) bb1, + (ext2_u32_list) bb2); +} + +int ext2fs_u32_list_count(ext2_u32_list bb) +{ + return bb->num; +} diff -Naur silo-1.4.13.orig/libext2fs/bb_compat.c silo-1.4.13/libext2fs/bb_compat.c --- silo-1.4.13.orig/libext2fs/bb_compat.c 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/bb_compat.c 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,63 @@ +/* + * bb_compat.c --- compatibility badblocks routines + * + * Copyright (C) 1997 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#if HAVE_SYS_STAT_H +#include +#endif +#if HAVE_SYS_TYPES_H +#include +#endif + +#include "ext2_fs.h" +#include "ext2fsP.h" + +errcode_t badblocks_list_create(badblocks_list *ret, int size) +{ + return ext2fs_badblocks_list_create(ret, size); +} + +void badblocks_list_free(badblocks_list bb) +{ + ext2fs_badblocks_list_free(bb); +} + +errcode_t badblocks_list_add(badblocks_list bb, blk_t blk) +{ + return ext2fs_badblocks_list_add(bb, blk); +} + +int badblocks_list_test(badblocks_list bb, blk_t blk) +{ + return ext2fs_badblocks_list_test(bb, blk); +} + +errcode_t badblocks_list_iterate_begin(badblocks_list bb, + badblocks_iterate *ret) +{ + return ext2fs_badblocks_list_iterate_begin(bb, ret); +} + +int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk) +{ + return ext2fs_badblocks_list_iterate(iter, blk); +} + +void badblocks_list_iterate_end(badblocks_iterate iter) +{ + ext2fs_badblocks_list_iterate_end(iter); +} diff -Naur silo-1.4.13.orig/libext2fs/bb_inode.c silo-1.4.13/libext2fs/bb_inode.c --- silo-1.4.13.orig/libext2fs/bb_inode.c 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/bb_inode.c 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,267 @@ +/* + * bb_inode.c --- routines to update the bad block inode. + * + * WARNING: This routine modifies a lot of state in the filesystem; if + * this routine returns an error, the bad block inode may be in an + * inconsistent state. + * + * Copyright (C) 1994, 1995 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#if HAVE_SYS_STAT_H +#include +#endif +#if HAVE_SYS_TYPES_H +#include +#endif + +#include "ext2_fs.h" +#include "ext2fs.h" + +struct set_badblock_record { + ext2_badblocks_iterate bb_iter; + int bad_block_count; + blk_t *ind_blocks; + int max_ind_blocks; + int ind_blocks_size; + int ind_blocks_ptr; + char *block_buf; + errcode_t err; +}; + +static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr, + e2_blkcnt_t blockcnt, + blk_t ref_block, int ref_offset, + void *priv_data); +static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr, + e2_blkcnt_t blockcnt, + blk_t ref_block, int ref_offset, + void *priv_data); + +/* + * Given a bad blocks bitmap, update the bad blocks inode to reflect + * the map. + */ +errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list) +{ + errcode_t retval; + struct set_badblock_record rec; + struct ext2_inode inode; + + EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); + + if (!fs->block_map) + return EXT2_ET_NO_BLOCK_BITMAP; + + rec.bad_block_count = 0; + rec.ind_blocks_size = rec.ind_blocks_ptr = 0; + rec.max_ind_blocks = 10; + retval = ext2fs_get_mem(rec.max_ind_blocks * sizeof(blk_t), + &rec.ind_blocks); + if (retval) + return retval; + memset(rec.ind_blocks, 0, rec.max_ind_blocks * sizeof(blk_t)); + retval = ext2fs_get_mem(fs->blocksize, &rec.block_buf); + if (retval) + goto cleanup; + memset(rec.block_buf, 0, fs->blocksize); + rec.err = 0; + + /* + * First clear the old bad blocks (while saving the indirect blocks) + */ + retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO, + BLOCK_FLAG_DEPTH_TRAVERSE, 0, + clear_bad_block_proc, &rec); + if (retval) + goto cleanup; + if (rec.err) { + retval = rec.err; + goto cleanup; + } + + /* + * Now set the bad blocks! + * + * First, mark the bad blocks as used. This prevents a bad + * block from being used as an indirecto block for the bad + * block inode (!). + */ + if (bb_list) { + retval = ext2fs_badblocks_list_iterate_begin(bb_list, + &rec.bb_iter); + if (retval) + goto cleanup; + retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO, + BLOCK_FLAG_APPEND, 0, + set_bad_block_proc, &rec); + ext2fs_badblocks_list_iterate_end(rec.bb_iter); + if (retval) + goto cleanup; + if (rec.err) { + retval = rec.err; + goto cleanup; + } + } + + /* + * Update the bad block inode's mod time and block count + * field. + */ + retval = ext2fs_read_inode(fs, EXT2_BAD_INO, &inode); + if (retval) + goto cleanup; + + inode.i_atime = inode.i_mtime = time(0); + if (!inode.i_ctime) + inode.i_ctime = time(0); + inode.i_blocks = rec.bad_block_count * (fs->blocksize / 512); + inode.i_size = rec.bad_block_count * fs->blocksize; + + retval = ext2fs_write_inode(fs, EXT2_BAD_INO, &inode); + if (retval) + goto cleanup; + +cleanup: + ext2fs_free_mem(&rec.ind_blocks); + ext2fs_free_mem(&rec.block_buf); + return retval; +} + +/* + * Helper function for update_bb_inode() + * + * Clear the bad blocks in the bad block inode, while saving the + * indirect blocks. + */ +#ifdef __TURBOC__ + #pragma argsused +#endif +static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr, + e2_blkcnt_t blockcnt, + blk_t ref_block EXT2FS_ATTR((unused)), + int ref_offset EXT2FS_ATTR((unused)), + void *priv_data) +{ + struct set_badblock_record *rec = (struct set_badblock_record *) + priv_data; + errcode_t retval; + unsigned long old_size; + + if (!*block_nr) + return 0; + + /* + * If the block number is outrageous, clear it and ignore it. + */ + if (*block_nr >= fs->super->s_blocks_count || + *block_nr < fs->super->s_first_data_block) { + *block_nr = 0; + return BLOCK_CHANGED; + } + + if (blockcnt < 0) { + if (rec->ind_blocks_size >= rec->max_ind_blocks) { + old_size = rec->max_ind_blocks * sizeof(blk_t); + rec->max_ind_blocks += 10; + retval = ext2fs_resize_mem(old_size, + rec->max_ind_blocks * sizeof(blk_t), + &rec->ind_blocks); + if (retval) { + rec->max_ind_blocks -= 10; + rec->err = retval; + return BLOCK_ABORT; + } + } + rec->ind_blocks[rec->ind_blocks_size++] = *block_nr; + } + + /* + * Mark the block as unused, and update accounting information + */ + ext2fs_block_alloc_stats(fs, *block_nr, -1); + + *block_nr = 0; + return BLOCK_CHANGED; +} + + +/* + * Helper function for update_bb_inode() + * + * Set the block list in the bad block inode, using the supplied bitmap. + */ +#ifdef __TURBOC__ + #pragma argsused +#endif +static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr, + e2_blkcnt_t blockcnt, + blk_t ref_block EXT2FS_ATTR((unused)), + int ref_offset EXT2FS_ATTR((unused)), + void *priv_data) +{ + struct set_badblock_record *rec = (struct set_badblock_record *) + priv_data; + errcode_t retval; + blk_t blk; + + if (blockcnt >= 0) { + /* + * Get the next bad block. + */ + if (!ext2fs_badblocks_list_iterate(rec->bb_iter, &blk)) + return BLOCK_ABORT; + rec->bad_block_count++; + } else { + /* + * An indirect block; fetch a block from the + * previously used indirect block list. The block + * most be not marked as used; if so, get another one. + * If we run out of reserved indirect blocks, allocate + * a new one. + */ + retry: + if (rec->ind_blocks_ptr < rec->ind_blocks_size) { + blk = rec->ind_blocks[rec->ind_blocks_ptr++]; + if (ext2fs_test_block_bitmap(fs->block_map, blk)) + goto retry; + } else { + retval = ext2fs_new_block(fs, 0, 0, &blk); + if (retval) { + rec->err = retval; + return BLOCK_ABORT; + } + } + retval = io_channel_write_blk(fs->io, blk, 1, rec->block_buf); + if (retval) { + rec->err = retval; + return BLOCK_ABORT; + } + } + + /* + * Update block counts + */ + ext2fs_block_alloc_stats(fs, blk, +1); + + *block_nr = blk; + return BLOCK_CHANGED; +} + + + + + + diff -Naur silo-1.4.13.orig/libext2fs/bitmaps.c silo-1.4.13/libext2fs/bitmaps.c --- silo-1.4.13.orig/libext2fs/bitmaps.c 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/bitmaps.c 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,212 @@ +/* + * bitmaps.c --- routines to read, write, and manipulate the inode and + * block bitmaps. + * + * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#if HAVE_SYS_STAT_H +#include +#endif +#if HAVE_SYS_TYPES_H +#include +#endif + +#include "ext2_fs.h" +#include "ext2fs.h" + +static errcode_t make_bitmap(__u32 start, __u32 end, __u32 real_end, + const char *descr, char *init_map, + ext2fs_generic_bitmap *ret) +{ + ext2fs_generic_bitmap bitmap; + errcode_t retval; + size_t size; + + retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap), + &bitmap); + if (retval) + return retval; + + bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP; + bitmap->fs = NULL; + bitmap->start = start; + bitmap->end = end; + bitmap->real_end = real_end; + bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK; + if (descr) { + retval = ext2fs_get_mem(strlen(descr)+1, &bitmap->description); + if (retval) { + ext2fs_free_mem(&bitmap); + return retval; + } + strcpy(bitmap->description, descr); + } else + bitmap->description = 0; + + size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1); + retval = ext2fs_get_mem(size, &bitmap->bitmap); + if (retval) { + ext2fs_free_mem(&bitmap->description); + ext2fs_free_mem(&bitmap); + return retval; + } + + if (init_map) + memcpy(bitmap->bitmap, init_map, size); + else + memset(bitmap->bitmap, 0, size); + *ret = bitmap; + return 0; +} + +errcode_t ext2fs_allocate_generic_bitmap(__u32 start, + __u32 end, + __u32 real_end, + const char *descr, + ext2fs_generic_bitmap *ret) +{ + return make_bitmap(start, end, real_end, descr, 0, ret); +} + +errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src, + ext2fs_generic_bitmap *dest) +{ + errcode_t retval; + ext2fs_generic_bitmap new_map; + + retval = make_bitmap(src->start, src->end, src->real_end, + src->description, src->bitmap, &new_map); + if (retval) + return retval; + new_map->magic = src->magic; + new_map->fs = src->fs; + new_map->base_error_code = src->base_error_code; + *dest = new_map; + return 0; +} + +void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map) +{ + __u32 i, j; + + for (i=map->end+1, j = i - map->start; i <= map->real_end; i++, j++) + ext2fs_set_bit(j, map->bitmap); + + return; +} + +errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs, + const char *descr, + ext2fs_inode_bitmap *ret) +{ + ext2fs_inode_bitmap bitmap; + errcode_t retval; + __u32 start, end, real_end; + + EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); + + fs->write_bitmaps = ext2fs_write_bitmaps; + + start = 1; + end = fs->super->s_inodes_count; + real_end = (EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count); + + retval = ext2fs_allocate_generic_bitmap(start, end, real_end, + descr, &bitmap); + if (retval) + return retval; + + bitmap->magic = EXT2_ET_MAGIC_INODE_BITMAP; + bitmap->fs = fs; + bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK; + + *ret = bitmap; + return 0; +} + +errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs, + const char *descr, + ext2fs_block_bitmap *ret) +{ + ext2fs_block_bitmap bitmap; + errcode_t retval; + __u32 start, end, real_end; + + EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); + + fs->write_bitmaps = ext2fs_write_bitmaps; + + start = fs->super->s_first_data_block; + end = fs->super->s_blocks_count-1; + real_end = (EXT2_BLOCKS_PER_GROUP(fs->super) + * fs->group_desc_count)-1 + start; + + retval = ext2fs_allocate_generic_bitmap(start, end, real_end, + descr, &bitmap); + if (retval) + return retval; + + bitmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP; + bitmap->fs = fs; + bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK; + + *ret = bitmap; + return 0; +} + +errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap, + ext2_ino_t end, ext2_ino_t *oend) +{ + EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP); + + if (end > bitmap->real_end) + return EXT2_ET_FUDGE_INODE_BITMAP_END; + if (oend) + *oend = bitmap->end; + bitmap->end = end; + return 0; +} + +errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap, + blk_t end, blk_t *oend) +{ + EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP); + + if (end > bitmap->real_end) + return EXT2_ET_FUDGE_BLOCK_BITMAP_END; + if (oend) + *oend = bitmap->end; + bitmap->end = end; + return 0; +} + +void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap) +{ + if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP)) + return; + + memset(bitmap->bitmap, 0, + (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1)); +} + +void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap) +{ + if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_BLOCK_BITMAP)) + return; + + memset(bitmap->bitmap, 0, + (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1)); +} diff -Naur silo-1.4.13.orig/libext2fs/bitops.c silo-1.4.13/libext2fs/bitops.c --- silo-1.4.13.orig/libext2fs/bitops.c 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/bitops.c 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,91 @@ +/* + * bitops.c --- Bitmap frobbing code. See bitops.h for the inlined + * routines. + * + * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#include +#if HAVE_SYS_TYPES_H +#include +#endif + +#include "ext2_fs.h" +#include "ext2fs.h" + +#ifndef _EXT2_HAVE_ASM_BITOPS_ + +/* + * For the benefit of those who are trying to port Linux to another + * architecture, here are some C-language equivalents. You should + * recode these in the native assmebly language, if at all possible. + * + * C language equivalents written by Theodore Ts'o, 9/26/92. + * Modified by Pete A. Zaitcev 7/14/95 to be portable to big endian + * systems, as well as non-32 bit systems. + */ + +int ext2fs_set_bit(unsigned int nr,void * addr) +{ + int mask, retval; + unsigned char *ADDR = (unsigned char *) addr; + + ADDR += nr >> 3; + mask = 1 << (nr & 0x07); + retval = mask & *ADDR; + *ADDR |= mask; + return retval; +} + +int ext2fs_clear_bit(unsigned int nr, void * addr) +{ + int mask, retval; + unsigned char *ADDR = (unsigned char *) addr; + + ADDR += nr >> 3; + mask = 1 << (nr & 0x07); + retval = mask & *ADDR; + *ADDR &= ~mask; + return retval; +} + +int ext2fs_test_bit(unsigned int nr, const void * addr) +{ + int mask; + const unsigned char *ADDR = (const unsigned char *) addr; + + ADDR += nr >> 3; + mask = 1 << (nr & 0x07); + return (mask & *ADDR); +} + +#endif /* !_EXT2_HAVE_ASM_BITOPS_ */ + +void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg, + const char *description) +{ +#ifndef OMIT_COM_ERR + if (description) + com_err(0, errcode, "#%lu for %s", arg, description); + else + com_err(0, errcode, "#%lu", arg); +#endif +} + +void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap, + int code, unsigned long arg) +{ +#ifndef OMIT_COM_ERR + if (bitmap->description) + com_err(0, bitmap->base_error_code+code, + "#%lu for %s", arg, bitmap->description); + else + com_err(0, bitmap->base_error_code + code, "#%lu", arg); +#endif +} + diff -Naur silo-1.4.13.orig/libext2fs/bitops.h silo-1.4.13/libext2fs/bitops.h --- silo-1.4.13.orig/libext2fs/bitops.h 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/bitops.h 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,617 @@ +/* + * bitops.h --- Bitmap frobbing code. The byte swapping routines are + * also included here. + * + * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + * + * i386 bitops operations taken from , Copyright 1992, + * Linus Torvalds. + */ + + +extern int ext2fs_set_bit(unsigned int nr,void * addr); +extern int ext2fs_clear_bit(unsigned int nr, void * addr); +extern int ext2fs_test_bit(unsigned int nr, const void * addr); +extern __u16 ext2fs_swab16(__u16 val); +extern __u32 ext2fs_swab32(__u32 val); + +#ifdef WORDS_BIGENDIAN +#define ext2fs_cpu_to_le32(x) ext2fs_swab32((x)) +#define ext2fs_le32_to_cpu(x) ext2fs_swab32((x)) +#define ext2fs_cpu_to_le16(x) ext2fs_swab16((x)) +#define ext2fs_le16_to_cpu(x) ext2fs_swab16((x)) +#define ext2fs_cpu_to_be32(x) ((__u32)(x)) +#define ext2fs_be32_to_cpu(x) ((__u32)(x)) +#define ext2fs_cpu_to_be16(x) ((__u16)(x)) +#define ext2fs_be16_to_cpu(x) ((__u16)(x)) +#else +#define ext2fs_cpu_to_le32(x) ((__u32)(x)) +#define ext2fs_le32_to_cpu(x) ((__u32)(x)) +#define ext2fs_cpu_to_le16(x) ((__u16)(x)) +#define ext2fs_le16_to_cpu(x) ((__u16)(x)) +#define ext2fs_cpu_to_be32(x) ext2fs_swab32((x)) +#define ext2fs_be32_to_cpu(x) ext2fs_swab32((x)) +#define ext2fs_cpu_to_be16(x) ext2fs_swab16((x)) +#define ext2fs_be16_to_cpu(x) ext2fs_swab16((x)) +#endif + +/* + * EXT2FS bitmap manipulation routines. + */ + +/* Support for sending warning messages from the inline subroutines */ +extern const char *ext2fs_block_string; +extern const char *ext2fs_inode_string; +extern const char *ext2fs_mark_string; +extern const char *ext2fs_unmark_string; +extern const char *ext2fs_test_string; +extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg, + const char *description); +extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap, + int code, unsigned long arg); + +extern int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block); +extern int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap, + blk_t block); +extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block); + +extern int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode); +extern int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap, + ext2_ino_t inode); +extern int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode); + +extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap, + blk_t block); +extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap, + blk_t block); +extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap, + blk_t block); + +extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, + ext2_ino_t inode); +extern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap, + ext2_ino_t inode); +extern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap, + ext2_ino_t inode); +extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap); +extern ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap); +extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap); +extern ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap); + +extern void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap, + blk_t block, int num); +extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap, + blk_t block, int num); +extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap, + blk_t block, int num); +extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap, + blk_t block, int num); +extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap, + blk_t block, int num); +extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap, + blk_t block, int num); +extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map); + +/* These two routines moved to gen_bitmap.c */ +extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap, + __u32 bitno); +extern int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap, + blk_t bitno); +/* + * The inline routines themselves... + * + * If NO_INLINE_FUNCS is defined, then we won't try to do inline + * functions at all; they will be included as normal functions in + * inline.c + */ +#ifdef NO_INLINE_FUNCS +#if (defined(__GNUC__) && (defined(__i386__) || defined(__i486__) || \ + defined(__i586__) || defined(__mc68000__) || \ + defined(__sparc__))) + /* This prevents bitops.c from trying to include the C */ + /* function version of these functions */ +#define _EXT2_HAVE_ASM_BITOPS_ +#endif +#endif /* NO_INLINE_FUNCS */ + +#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS)) +#ifdef INCLUDE_INLINE_FUNCS +#define _INLINE_ extern +#else +#ifdef __GNUC__ +#define _INLINE_ extern __inline__ +#else /* For Watcom C */ +#define _INLINE_ extern inline +#endif +#endif + +#if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \ + (defined(__i386__) || defined(__i486__) || defined(__i586__))) + +#define _EXT2_HAVE_ASM_BITOPS_ +#define _EXT2_HAVE_ASM_SWAB_ +#define _EXT2_HAVE_ASM_FINDBIT_ + +/* + * These are done by inline assembly for speed reasons..... + * + * All bitoperations return 0 if the bit was cleared before the + * operation and != 0 if it was not. Bit 0 is the LSB of addr; bit 32 + * is the LSB of (addr+1). + */ + +/* + * Some hacks to defeat gcc over-optimizations.. + */ +struct __dummy_h { unsigned long a[100]; }; +#define EXT2FS_ADDR (*(struct __dummy_h *) addr) +#define EXT2FS_CONST_ADDR (*(const struct __dummy_h *) addr) + +_INLINE_ int ext2fs_set_bit(unsigned int nr, void * addr) +{ + int oldbit; + + __asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (EXT2FS_ADDR) + :"r" (nr)); + return oldbit; +} + +_INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr) +{ + int oldbit; + + __asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (EXT2FS_ADDR) + :"r" (nr)); + return oldbit; +} + +_INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr) +{ + int oldbit; + + __asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit) + :"m" (EXT2FS_CONST_ADDR),"r" (nr)); + return oldbit; +} + +#if 0 +_INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size) +{ + int d0, d1, d2; + int res; + + if (!size) + return 0; + /* This looks at memory. Mark it volatile to tell gcc not to move it around */ + __asm__ __volatile__( + "cld\n\t" + "xorl %%eax,%%eax\n\t" + "xorl %%edx,%%edx\n\t" + "repe; scasl\n\t" + "je 1f\n\t" + "movl -4(%%edi),%%eax\n\t" + "subl $4,%%edi\n\t" + "bsfl %%eax,%%edx\n" + "1:\tsubl %%esi,%%edi\n\t" + "shll $3,%%edi\n\t" + "addl %%edi,%%edx" + :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) + :"1" ((size + 31) >> 5), "2" (addr), "S" (addr)); + return res; +} + +_INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset) +{ + unsigned long * p = ((unsigned long *) addr) + (offset >> 5); + int set = 0, bit = offset & 31, res; + + if (bit) { + /* + * Look for zero in first byte + */ + __asm__("bsfl %1,%0\n\t" + "jne 1f\n\t" + "movl $32, %0\n" + "1:" + : "=r" (set) + : "r" (*p >> bit)); + if (set < (32 - bit)) + return set + offset; + set = 32 - bit; + p++; + } + /* + * No bit found yet, search remaining full bytes for a bit + */ + res = ext2fs_find_first_bit_set(p, size - 32 * (p - (unsigned long *) addr)); + return (offset + set + res); +} +#endif + +#ifdef EXT2FS_ENABLE_SWAPFS +_INLINE_ __u32 ext2fs_swab32(__u32 val) +{ +#ifdef EXT2FS_REQUIRE_486 + __asm__("bswap %0" : "=r" (val) : "0" (val)); +#else + __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ + "rorl $16,%0\n\t" /* swap words */ + "xchgb %b0,%h0" /* swap higher bytes */ + :"=q" (val) + : "0" (val)); +#endif + return val; +} + +_INLINE_ __u16 ext2fs_swab16(__u16 val) +{ + __asm__("xchgb %b0,%h0" /* swap bytes */ \ + : "=q" (val) \ + : "0" (val)); \ + return val; +} +#endif + +#undef EXT2FS_ADDR + +#endif /* i386 */ + +#ifdef __mc68000__ + +#define _EXT2_HAVE_ASM_BITOPS_ + +_INLINE_ int ext2fs_set_bit(unsigned int nr,void * addr) +{ + char retval; + + __asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0" + : "=d" (retval) : "d" (nr^7), "a" (addr)); + + return retval; +} + +_INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr) +{ + char retval; + + __asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0" + : "=d" (retval) : "d" (nr^7), "a" (addr)); + + return retval; +} + +_INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr) +{ + char retval; + + __asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0" + : "=d" (retval) : "d" (nr^7), "a" (addr)); + + return retval; +} + +#endif /* __mc68000__ */ + + +#if !defined(_EXT2_HAVE_ASM_SWAB_) && defined(EXT2FS_ENABLE_SWAPFS) + +_INLINE_ __u16 ext2fs_swab16(__u16 val) +{ + return (val >> 8) | (val << 8); +} + +_INLINE_ __u32 ext2fs_swab32(__u32 val) +{ + return ((val>>24) | ((val>>8)&0xFF00) | + ((val<<8)&0xFF0000) | (val<<24)); +} + +#endif /* !_EXT2_HAVE_ASM_SWAB */ + +#if !defined(_EXT2_HAVE_ASM_FINDBIT_) +_INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size) +{ + char *cp = (unsigned char *) addr; + int res = 0, d0; + + if (!size) + return 0; + + while ((size > res) && (*cp == 0)) { + cp++; + res += 8; + } + d0 = ffs(*cp); + if (d0 == 0) + return size; + + return res + d0 - 1; +} + +_INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset) +{ + unsigned char * p; + int set = 0, bit = offset & 7, res = 0, d0; + + res = offset >> 3; + p = ((unsigned char *) addr) + res; + + if (bit) { + set = ffs(*p & ~((1 << bit) - 1)); + if (set) + return (offset & ~7) + set - 1; + p++; + res += 8; + } + while ((size > res) && (*p == 0)) { + p++; + res += 8; + } + d0 = ffs(*p); + if (d0 == 0) + return size; + + return (res + d0 - 1); +} +#endif + +_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap, + blk_t bitno); + +_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap, + blk_t bitno) +{ + if ((bitno < bitmap->start) || (bitno > bitmap->end)) { + ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno); + return 0; + } + return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap); +} + +_INLINE_ int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, + blk_t block) +{ + return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) + bitmap, + block); +} + +_INLINE_ int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap, + blk_t block) +{ + return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, + block); +} + +_INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, + blk_t block) +{ + return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, + block); +} + +_INLINE_ int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, + ext2_ino_t inode) +{ + return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, + inode); +} + +_INLINE_ int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap, + ext2_ino_t inode) +{ + return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, + inode); +} + +_INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, + ext2_ino_t inode) +{ + return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, + inode); +} + +_INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap, + blk_t block) +{ +#ifdef EXT2FS_DEBUG_FAST_OPS + if ((block < bitmap->start) || (block > bitmap->end)) { + ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block, + bitmap->description); + return; + } +#endif + ext2fs_set_bit(block - bitmap->start, bitmap->bitmap); +} + +_INLINE_ void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap, + blk_t block) +{ +#ifdef EXT2FS_DEBUG_FAST_OPS + if ((block < bitmap->start) || (block > bitmap->end)) { + ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, + block, bitmap->description); + return; + } +#endif + ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap); +} + +_INLINE_ int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap, + blk_t block) +{ +#ifdef EXT2FS_DEBUG_FAST_OPS + if ((block < bitmap->start) || (block > bitmap->end)) { + ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST, + block, bitmap->description); + return 0; + } +#endif + return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap); +} + +_INLINE_ void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, + ext2_ino_t inode) +{ +#ifdef EXT2FS_DEBUG_FAST_OPS + if ((inode < bitmap->start) || (inode > bitmap->end)) { + ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK, + inode, bitmap->description); + return; + } +#endif + ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap); +} + +_INLINE_ void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap, + ext2_ino_t inode) +{ +#ifdef EXT2FS_DEBUG_FAST_OPS + if ((inode < bitmap->start) || (inode > bitmap->end)) { + ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK, + inode, bitmap->description); + return; + } +#endif + ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap); +} + +_INLINE_ int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap, + ext2_ino_t inode) +{ +#ifdef EXT2FS_DEBUG_FAST_OPS + if ((inode < bitmap->start) || (inode > bitmap->end)) { + ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST, + inode, bitmap->description); + return 0; + } +#endif + return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap); +} + +_INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap) +{ + return bitmap->start; +} + +_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap) +{ + return bitmap->start; +} + +_INLINE_ blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap) +{ + return bitmap->end; +} + +_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap) +{ + return bitmap->end; +} + +_INLINE_ int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap, + blk_t block, int num) +{ + int i; + + if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { + ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST, + block, bitmap->description); + return 0; + } + for (i=0; i < num; i++) { + if (ext2fs_fast_test_block_bitmap(bitmap, block+i)) + return 0; + } + return 1; +} + +_INLINE_ int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap, + blk_t block, int num) +{ + int i; + +#ifdef EXT2FS_DEBUG_FAST_OPS + if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { + ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST, + block, bitmap->description); + return 0; + } +#endif + for (i=0; i < num; i++) { + if (ext2fs_fast_test_block_bitmap(bitmap, block+i)) + return 0; + } + return 1; +} + +_INLINE_ void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap, + blk_t block, int num) +{ + int i; + + if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { + ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block, + bitmap->description); + return; + } + for (i=0; i < num; i++) + ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap); +} + +_INLINE_ void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap, + blk_t block, int num) +{ + int i; + +#ifdef EXT2FS_DEBUG_FAST_OPS + if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { + ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block, + bitmap->description); + return; + } +#endif + for (i=0; i < num; i++) + ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap); +} + +_INLINE_ void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap, + blk_t block, int num) +{ + int i; + + if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { + ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block, + bitmap->description); + return; + } + for (i=0; i < num; i++) + ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap); +} + +_INLINE_ void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap, + blk_t block, int num) +{ + int i; + +#ifdef EXT2FS_DEBUG_FAST_OPS + if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { + ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block, + bitmap->description); + return; + } +#endif + for (i=0; i < num; i++) + ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap); +} +#undef _INLINE_ +#endif + diff -Naur silo-1.4.13.orig/libext2fs/block.c silo-1.4.13/libext2fs/block.c --- silo-1.4.13.orig/libext2fs/block.c 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/block.c 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,437 @@ +/* + * block.c --- iterate over all blocks in an inode + * + * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#include +#include +#if HAVE_UNISTD_H +#include +#endif + +#include "ext2_fs.h" +#include "ext2fs.h" + +struct block_context { + ext2_filsys fs; + int (*func)(ext2_filsys fs, + blk_t *blocknr, + e2_blkcnt_t bcount, + blk_t ref_blk, + int ref_offset, + void *priv_data); + e2_blkcnt_t bcount; + int bsize; + int flags; + errcode_t errcode; + char *ind_buf; + char *dind_buf; + char *tind_buf; + void *priv_data; +}; + +static int block_iterate_ind(blk_t *ind_block, blk_t ref_block, + int ref_offset, struct block_context *ctx) +{ + int ret = 0, changed = 0; + int i, flags, limit, offset; + blk_t *block_nr; + + limit = ctx->fs->blocksize >> 2; + if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) && + !(ctx->flags & BLOCK_FLAG_DATA_ONLY)) + ret = (*ctx->func)(ctx->fs, ind_block, + BLOCK_COUNT_IND, ref_block, + ref_offset, ctx->priv_data); + if (!*ind_block || (ret & BLOCK_ABORT)) { + ctx->bcount += limit; + return ret; + } + if (*ind_block >= ctx->fs->super->s_blocks_count || + *ind_block < ctx->fs->super->s_first_data_block) { + ctx->errcode = EXT2_ET_BAD_IND_BLOCK; + ret |= BLOCK_ERROR; + return ret; + } + ctx->errcode = ext2fs_read_ind_block(ctx->fs, *ind_block, + ctx->ind_buf); + if (ctx->errcode) { + ret |= BLOCK_ERROR; + return ret; + } + + block_nr = (blk_t *) ctx->ind_buf; + offset = 0; + if (ctx->flags & BLOCK_FLAG_APPEND) { + for (i = 0; i < limit; i++, ctx->bcount++, block_nr++) { + flags = (*ctx->func)(ctx->fs, block_nr, ctx->bcount, + *ind_block, offset, + ctx->priv_data); + changed |= flags; + if (flags & BLOCK_ABORT) { + ret |= BLOCK_ABORT; + break; + } + offset += sizeof(blk_t); + } + } else { + for (i = 0; i < limit; i++, ctx->bcount++, block_nr++) { + if (*block_nr == 0) + continue; + flags = (*ctx->func)(ctx->fs, block_nr, ctx->bcount, + *ind_block, offset, + ctx->priv_data); + changed |= flags; + if (flags & BLOCK_ABORT) { + ret |= BLOCK_ABORT; + break; + } + offset += sizeof(blk_t); + } + } + if (changed & BLOCK_CHANGED) { + ctx->errcode = ext2fs_write_ind_block(ctx->fs, *ind_block, + ctx->ind_buf); + if (ctx->errcode) + ret |= BLOCK_ERROR | BLOCK_ABORT; + } + if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) && + !(ctx->flags & BLOCK_FLAG_DATA_ONLY) && + !(ret & BLOCK_ABORT)) + ret |= (*ctx->func)(ctx->fs, ind_block, + BLOCK_COUNT_IND, ref_block, + ref_offset, ctx->priv_data); + return ret; +} + +static int block_iterate_dind(blk_t *dind_block, blk_t ref_block, + int ref_offset, struct block_context *ctx) +{ + int ret = 0, changed = 0; + int i, flags, limit, offset; + blk_t *block_nr; + + limit = ctx->fs->blocksize >> 2; + if (!(ctx->flags & (BLOCK_FLAG_DEPTH_TRAVERSE | + BLOCK_FLAG_DATA_ONLY))) + ret = (*ctx->func)(ctx->fs, dind_block, + BLOCK_COUNT_DIND, ref_block, + ref_offset, ctx->priv_data); + if (!*dind_block || (ret & BLOCK_ABORT)) { + ctx->bcount += limit*limit; + return ret; + } + if (*dind_block >= ctx->fs->super->s_blocks_count || + *dind_block < ctx->fs->super->s_first_data_block) { + ctx->errcode = EXT2_ET_BAD_DIND_BLOCK; + ret |= BLOCK_ERROR; + return ret; + } + ctx->errcode = ext2fs_read_ind_block(ctx->fs, *dind_block, + ctx->dind_buf); + if (ctx->errcode) { + ret |= BLOCK_ERROR; + return ret; + } + + block_nr = (blk_t *) ctx->dind_buf; + offset = 0; + if (ctx->flags & BLOCK_FLAG_APPEND) { + for (i = 0; i < limit; i++, block_nr++) { + flags = block_iterate_ind(block_nr, + *dind_block, offset, + ctx); + changed |= flags; + if (flags & (BLOCK_ABORT | BLOCK_ERROR)) { + ret |= flags & (BLOCK_ABORT | BLOCK_ERROR); + break; + } + offset += sizeof(blk_t); + } + } else { + for (i = 0; i < limit; i++, block_nr++) { + if (*block_nr == 0) { + ctx->bcount += limit; + continue; + } + flags = block_iterate_ind(block_nr, + *dind_block, offset, + ctx); + changed |= flags; + if (flags & (BLOCK_ABORT | BLOCK_ERROR)) { + ret |= flags & (BLOCK_ABORT | BLOCK_ERROR); + break; + } + offset += sizeof(blk_t); + } + } + if (changed & BLOCK_CHANGED) { + ctx->errcode = ext2fs_write_ind_block(ctx->fs, *dind_block, + ctx->dind_buf); + if (ctx->errcode) + ret |= BLOCK_ERROR | BLOCK_ABORT; + } + if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) && + !(ctx->flags & BLOCK_FLAG_DATA_ONLY) && + !(ret & BLOCK_ABORT)) + ret |= (*ctx->func)(ctx->fs, dind_block, + BLOCK_COUNT_DIND, ref_block, + ref_offset, ctx->priv_data); + return ret; +} + +static int block_iterate_tind(blk_t *tind_block, blk_t ref_block, + int ref_offset, struct block_context *ctx) +{ + int ret = 0, changed = 0; + int i, flags, limit, offset; + blk_t *block_nr; + + limit = ctx->fs->blocksize >> 2; + if (!(ctx->flags & (BLOCK_FLAG_DEPTH_TRAVERSE | + BLOCK_FLAG_DATA_ONLY))) + ret = (*ctx->func)(ctx->fs, tind_block, + BLOCK_COUNT_TIND, ref_block, + ref_offset, ctx->priv_data); + if (!*tind_block || (ret & BLOCK_ABORT)) { + ctx->bcount += limit*limit*limit; + return ret; + } + if (*tind_block >= ctx->fs->super->s_blocks_count || + *tind_block < ctx->fs->super->s_first_data_block) { + ctx->errcode = EXT2_ET_BAD_TIND_BLOCK; + ret |= BLOCK_ERROR; + return ret; + } + ctx->errcode = ext2fs_read_ind_block(ctx->fs, *tind_block, + ctx->tind_buf); + if (ctx->errcode) { + ret |= BLOCK_ERROR; + return ret; + } + + block_nr = (blk_t *) ctx->tind_buf; + offset = 0; + if (ctx->flags & BLOCK_FLAG_APPEND) { + for (i = 0; i < limit; i++, block_nr++) { + flags = block_iterate_dind(block_nr, + *tind_block, + offset, ctx); + changed |= flags; + if (flags & (BLOCK_ABORT | BLOCK_ERROR)) { + ret |= flags & (BLOCK_ABORT | BLOCK_ERROR); + break; + } + offset += sizeof(blk_t); + } + } else { + for (i = 0; i < limit; i++, block_nr++) { + if (*block_nr == 0) { + ctx->bcount += limit*limit; + continue; + } + flags = block_iterate_dind(block_nr, + *tind_block, + offset, ctx); + changed |= flags; + if (flags & (BLOCK_ABORT | BLOCK_ERROR)) { + ret |= flags & (BLOCK_ABORT | BLOCK_ERROR); + break; + } + offset += sizeof(blk_t); + } + } + if (changed & BLOCK_CHANGED) { + ctx->errcode = ext2fs_write_ind_block(ctx->fs, *tind_block, + ctx->tind_buf); + if (ctx->errcode) + ret |= BLOCK_ERROR | BLOCK_ABORT; + } + if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) && + !(ctx->flags & BLOCK_FLAG_DATA_ONLY) && + !(ret & BLOCK_ABORT)) + ret |= (*ctx->func)(ctx->fs, tind_block, + BLOCK_COUNT_TIND, ref_block, + ref_offset, ctx->priv_data); + + return ret; +} + +errcode_t ext2fs_block_iterate2(ext2_filsys fs, + ext2_ino_t ino, + int flags, + char *block_buf, + int (*func)(ext2_filsys fs, + blk_t *blocknr, + e2_blkcnt_t blockcnt, + blk_t ref_blk, + int ref_offset, + void *priv_data), + void *priv_data) +{ + int i; + int got_inode = 0; + int ret = 0; + blk_t blocks[EXT2_N_BLOCKS]; /* directory data blocks */ + struct ext2_inode inode; + errcode_t retval; + struct block_context ctx; + int limit; + + EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); + + /* + * Check to see if we need to limit large files + */ + if (flags & BLOCK_FLAG_NO_LARGE) { + ctx.errcode = ext2fs_read_inode(fs, ino, &inode); + if (ctx.errcode) + return ctx.errcode; + got_inode = 1; + if (!LINUX_S_ISDIR(inode.i_mode) && + (inode.i_size_high != 0)) + return EXT2_ET_FILE_TOO_BIG; + } + + retval = ext2fs_get_blocks(fs, ino, blocks); + if (retval) + return retval; + + limit = fs->blocksize >> 2; + + ctx.fs = fs; + ctx.func = func; + ctx.priv_data = priv_data; + ctx.flags = flags; + ctx.bcount = 0; + if (block_buf) { + ctx.ind_buf = block_buf; + } else { + retval = ext2fs_get_mem(fs->blocksize * 3, &ctx.ind_buf); + if (retval) + return retval; + } + ctx.dind_buf = ctx.ind_buf + fs->blocksize; + ctx.tind_buf = ctx.dind_buf + fs->blocksize; + + /* + * Iterate over the HURD translator block (if present) + */ + if ((fs->super->s_creator_os == EXT2_OS_HURD) && + !(flags & BLOCK_FLAG_DATA_ONLY)) { + ctx.errcode = ext2fs_read_inode(fs, ino, &inode); + if (ctx.errcode) + goto abort_exit; + got_inode = 1; + if (inode.osd1.hurd1.h_i_translator) { + ret |= (*ctx.func)(fs, + &inode.osd1.hurd1.h_i_translator, + BLOCK_COUNT_TRANSLATOR, + 0, 0, priv_data); + if (ret & BLOCK_ABORT) + goto abort_exit; + } + } + + /* + * Iterate over normal data blocks + */ + for (i = 0; i < EXT2_NDIR_BLOCKS ; i++, ctx.bcount++) { + if (blocks[i] || (flags & BLOCK_FLAG_APPEND)) { + ret |= (*ctx.func)(fs, &blocks[i], + ctx.bcount, 0, i, priv_data); + if (ret & BLOCK_ABORT) + goto abort_exit; + } + } + if (*(blocks + EXT2_IND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) { + ret |= block_iterate_ind(blocks + EXT2_IND_BLOCK, + 0, EXT2_IND_BLOCK, &ctx); + if (ret & BLOCK_ABORT) + goto abort_exit; + } else + ctx.bcount += limit; + if (*(blocks + EXT2_DIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) { + ret |= block_iterate_dind(blocks + EXT2_DIND_BLOCK, + 0, EXT2_DIND_BLOCK, &ctx); + if (ret & BLOCK_ABORT) + goto abort_exit; + } else + ctx.bcount += limit * limit; + if (*(blocks + EXT2_TIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) { + ret |= block_iterate_tind(blocks + EXT2_TIND_BLOCK, + 0, EXT2_TIND_BLOCK, &ctx); + if (ret & BLOCK_ABORT) + goto abort_exit; + } + +abort_exit: + if (ret & BLOCK_CHANGED) { + if (!got_inode) { + retval = ext2fs_read_inode(fs, ino, &inode); + if (retval) + return retval; + } + for (i=0; i < EXT2_N_BLOCKS; i++) + inode.i_block[i] = blocks[i]; + retval = ext2fs_write_inode(fs, ino, &inode); + if (retval) + return retval; + } + + if (!block_buf) + ext2fs_free_mem(&ctx.ind_buf); + + return (ret & BLOCK_ERROR) ? ctx.errcode : 0; +} + +/* + * Emulate the old ext2fs_block_iterate function! + */ + +struct xlate { + int (*func)(ext2_filsys fs, + blk_t *blocknr, + int bcount, + void *priv_data); + void *real_private; +}; + +#ifdef __TURBOC__ + #pragma argsused +#endif +static int xlate_func(ext2_filsys fs, blk_t *blocknr, e2_blkcnt_t blockcnt, + blk_t ref_block EXT2FS_ATTR((unused)), + int ref_offset EXT2FS_ATTR((unused)), + void *priv_data) +{ + struct xlate *xl = (struct xlate *) priv_data; + + return (*xl->func)(fs, blocknr, (int) blockcnt, xl->real_private); +} + +errcode_t ext2fs_block_iterate(ext2_filsys fs, + ext2_ino_t ino, + int flags, + char *block_buf, + int (*func)(ext2_filsys fs, + blk_t *blocknr, + int blockcnt, + void *priv_data), + void *priv_data) +{ + struct xlate xl; + + xl.real_private = priv_data; + xl.func = func; + + return ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_NO_LARGE | flags, + block_buf, xlate_func, &xl); +} + diff -Naur silo-1.4.13.orig/libext2fs/bmap.c silo-1.4.13/libext2fs/bmap.c --- silo-1.4.13.orig/libext2fs/bmap.c 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/bmap.c 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,270 @@ +/* + * bmap.c --- logical to physical block mapping + * + * Copyright (C) 1997 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#include +#include +#if HAVE_UNISTD_H +#include +#endif + +#include "ext2_fs.h" +#include "ext2fs.h" + +#if defined(__GNUC__) && !defined(NO_INLINE_FUNCS) +#define _BMAP_INLINE_ __inline__ +#else +#define _BMAP_INLINE_ +#endif + +extern errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, + struct ext2_inode *inode, + char *block_buf, int bmap_flags, + blk_t block, blk_t *phys_blk); + +#define inode_bmap(inode, nr) ((inode)->i_block[(nr)]) + +static _BMAP_INLINE_ errcode_t block_ind_bmap(ext2_filsys fs, int flags, + blk_t ind, char *block_buf, + int *blocks_alloc, + blk_t nr, blk_t *ret_blk) +{ + errcode_t retval; + blk_t b; + + if (!ind) { + if (flags & BMAP_SET) + return EXT2_ET_SET_BMAP_NO_IND; + *ret_blk = 0; + return 0; + } + retval = io_channel_read_blk(fs->io, ind, 1, block_buf); + if (retval) + return retval; + + if (flags & BMAP_SET) { + b = *ret_blk; +#ifdef EXT2FS_ENABLE_SWAPFS + if ((fs->flags & EXT2_FLAG_SWAP_BYTES) || + (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)) + b = ext2fs_swab32(b); +#endif + ((blk_t *) block_buf)[nr] = b; + return io_channel_write_blk(fs->io, ind, 1, block_buf); + } + + b = ((blk_t *) block_buf)[nr]; + +#ifdef EXT2FS_ENABLE_SWAPFS + if ((fs->flags & EXT2_FLAG_SWAP_BYTES) || + (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)) + b = ext2fs_swab32(b); +#endif + + if (!b && (flags & BMAP_ALLOC)) { + b = nr ? ((blk_t *) block_buf)[nr-1] : 0; + retval = ext2fs_alloc_block(fs, b, + block_buf + fs->blocksize, &b); + if (retval) + return retval; + +#ifdef EXT2FS_ENABLE_SWAPFS + if ((fs->flags & EXT2_FLAG_SWAP_BYTES) || + (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)) + ((blk_t *) block_buf)[nr] = ext2fs_swab32(b); + else +#endif + ((blk_t *) block_buf)[nr] = b; + + retval = io_channel_write_blk(fs->io, ind, 1, block_buf); + if (retval) + return retval; + + (*blocks_alloc)++; + } + + *ret_blk = b; + return 0; +} + +static _BMAP_INLINE_ errcode_t block_dind_bmap(ext2_filsys fs, int flags, + blk_t dind, char *block_buf, + int *blocks_alloc, + blk_t nr, blk_t *ret_blk) +{ + blk_t b; + errcode_t retval; + blk_t addr_per_block; + + addr_per_block = (blk_t) fs->blocksize >> 2; + + retval = block_ind_bmap(fs, flags & ~BMAP_SET, dind, block_buf, + blocks_alloc, nr / addr_per_block, &b); + if (retval) + return retval; + retval = block_ind_bmap(fs, flags, b, block_buf, blocks_alloc, + nr % addr_per_block, ret_blk); + return retval; +} + +static _BMAP_INLINE_ errcode_t block_tind_bmap(ext2_filsys fs, int flags, + blk_t tind, char *block_buf, + int *blocks_alloc, + blk_t nr, blk_t *ret_blk) +{ + blk_t b; + errcode_t retval; + blk_t addr_per_block; + + addr_per_block = (blk_t) fs->blocksize >> 2; + + retval = block_dind_bmap(fs, flags & ~BMAP_SET, tind, block_buf, + blocks_alloc, nr / addr_per_block, &b); + if (retval) + return retval; + retval = block_ind_bmap(fs, flags, b, block_buf, blocks_alloc, + nr % addr_per_block, ret_blk); + return retval; +} + +errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, + char *block_buf, int bmap_flags, blk_t block, + blk_t *phys_blk) +{ + struct ext2_inode inode_buf; + blk_t addr_per_block; + blk_t b; + char *buf = 0; + errcode_t retval = 0; + int blocks_alloc = 0, inode_dirty = 0; + + if (!(bmap_flags & BMAP_SET)) + *phys_blk = 0; + + /* Read inode structure if necessary */ + if (!inode) { + retval = ext2fs_read_inode(fs, ino, &inode_buf); + if (retval) + return retval; + inode = &inode_buf; + } + addr_per_block = (blk_t) fs->blocksize >> 2; + + if (!block_buf) { + retval = ext2fs_get_mem(fs->blocksize * 2, &buf); + if (retval) + return retval; + block_buf = buf; + } + + if (block < EXT2_NDIR_BLOCKS) { + if (bmap_flags & BMAP_SET) { + b = *phys_blk; +#ifdef EXT2FS_ENABLE_SWAPFS + if ((fs->flags & EXT2_FLAG_SWAP_BYTES) || + (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)) + b = ext2fs_swab32(b); +#endif + inode_bmap(inode, block) = b; + inode_dirty++; + goto done; + } + + *phys_blk = inode_bmap(inode, block); + b = block ? inode_bmap(inode, block-1) : 0; + + if ((*phys_blk == 0) && (bmap_flags & BMAP_ALLOC)) { + retval = ext2fs_alloc_block(fs, b, block_buf, &b); + if (retval) + goto done; + inode_bmap(inode, block) = b; + blocks_alloc++; + *phys_blk = b; + } + goto done; + } + + /* Indirect block */ + block -= EXT2_NDIR_BLOCKS; + if (block < addr_per_block) { + b = inode_bmap(inode, EXT2_IND_BLOCK); + if (!b) { + if (!(bmap_flags & BMAP_ALLOC)) { + if (bmap_flags & BMAP_SET) + retval = EXT2_ET_SET_BMAP_NO_IND; + goto done; + } + + b = inode_bmap(inode, EXT2_IND_BLOCK-1); + retval = ext2fs_alloc_block(fs, b, block_buf, &b); + if (retval) + goto done; + inode_bmap(inode, EXT2_IND_BLOCK) = b; + blocks_alloc++; + } + retval = block_ind_bmap(fs, bmap_flags, b, block_buf, + &blocks_alloc, block, phys_blk); + goto done; + } + + /* Doubly indirect block */ + block -= addr_per_block; + if (block < addr_per_block * addr_per_block) { + b = inode_bmap(inode, EXT2_DIND_BLOCK); + if (!b) { + if (!(bmap_flags & BMAP_ALLOC)) { + if (bmap_flags & BMAP_SET) + retval = EXT2_ET_SET_BMAP_NO_IND; + goto done; + } + + b = inode_bmap(inode, EXT2_IND_BLOCK); + retval = ext2fs_alloc_block(fs, b, block_buf, &b); + if (retval) + goto done; + inode_bmap(inode, EXT2_DIND_BLOCK) = b; + blocks_alloc++; + } + retval = block_dind_bmap(fs, bmap_flags, b, block_buf, + &blocks_alloc, block, phys_blk); + goto done; + } + + /* Triply indirect block */ + block -= addr_per_block * addr_per_block; + b = inode_bmap(inode, EXT2_TIND_BLOCK); + if (!b) { + if (!(bmap_flags & BMAP_ALLOC)) { + if (bmap_flags & BMAP_SET) + retval = EXT2_ET_SET_BMAP_NO_IND; + goto done; + } + + b = inode_bmap(inode, EXT2_DIND_BLOCK); + retval = ext2fs_alloc_block(fs, b, block_buf, &b); + if (retval) + goto done; + inode_bmap(inode, EXT2_TIND_BLOCK) = b; + blocks_alloc++; + } + retval = block_tind_bmap(fs, bmap_flags, b, block_buf, + &blocks_alloc, block, phys_blk); +done: + if (buf) + ext2fs_free_mem(&buf); + if ((retval == 0) && (blocks_alloc || inode_dirty)) { + inode->i_blocks += (blocks_alloc * fs->blocksize) / 512; + retval = ext2fs_write_inode(fs, ino, inode); + } + return retval; +} + + + diff -Naur silo-1.4.13.orig/libext2fs/bmove.c silo-1.4.13/libext2fs/bmove.c --- silo-1.4.13.orig/libext2fs/bmove.c 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/bmove.c 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,160 @@ +/* + * bmove.c --- Move blocks around to make way for a particular + * filesystem structure. + * + * Copyright (C) 1997 Theodore Ts'o. This file may be redistributed + * under the terms of the GNU Public License. + */ + +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_SYS_TIME_H +#include +#endif + +#include "ext2_fs.h" +#include "ext2fsP.h" + +struct process_block_struct { + ext2_ino_t ino; + struct ext2_inode * inode; + ext2fs_block_bitmap reserve; + ext2fs_block_bitmap alloc_map; + errcode_t error; + char *buf; + int add_dir; + int flags; +}; + +static int process_block(ext2_filsys fs, blk_t *block_nr, + e2_blkcnt_t blockcnt, blk_t ref_block, + int ref_offset, void *priv_data) +{ + struct process_block_struct *pb; + errcode_t retval; + int ret; + blk_t block, orig; + + pb = (struct process_block_struct *) priv_data; + block = orig = *block_nr; + ret = 0; + + /* + * Let's see if this is one which we need to relocate + */ + if (ext2fs_test_block_bitmap(pb->reserve, block)) { + do { + if (++block >= fs->super->s_blocks_count) + block = fs->super->s_first_data_block; + if (block == orig) { + pb->error = EXT2_ET_BLOCK_ALLOC_FAIL; + return BLOCK_ABORT; + } + } while (ext2fs_test_block_bitmap(pb->reserve, block) || + ext2fs_test_block_bitmap(pb->alloc_map, block)); + + retval = io_channel_read_blk(fs->io, orig, 1, pb->buf); + if (retval) { + pb->error = retval; + return BLOCK_ABORT; + } + retval = io_channel_write_blk(fs->io, block, 1, pb->buf); + if (retval) { + pb->error = retval; + return BLOCK_ABORT; + } + *block_nr = block; + ext2fs_mark_block_bitmap(pb->alloc_map, block); + ret = BLOCK_CHANGED; + if (pb->flags & EXT2_BMOVE_DEBUG) + printf("ino=%ld, blockcnt=%lld, %d->%d\n", pb->ino, + blockcnt, orig, block); + } + if (pb->add_dir) { + retval = ext2fs_add_dir_block(fs->dblist, pb->ino, + block, (int) blockcnt); + if (retval) { + pb->error = retval; + ret |= BLOCK_ABORT; + } + } + return ret; +} + +errcode_t ext2fs_move_blocks(ext2_filsys fs, + ext2fs_block_bitmap reserve, + ext2fs_block_bitmap alloc_map, + int flags) +{ + ext2_ino_t ino; + struct ext2_inode inode; + errcode_t retval; + struct process_block_struct pb; + ext2_inode_scan scan; + char *block_buf; + + retval = ext2fs_open_inode_scan(fs, 0, &scan); + if (retval) + return retval; + + pb.reserve = reserve; + pb.error = 0; + pb.alloc_map = alloc_map ? alloc_map : fs->block_map; + pb.flags = flags; + + retval = ext2fs_get_mem(fs->blocksize * 4, &block_buf); + if (retval) + return retval; + pb.buf = block_buf + fs->blocksize * 3; + + /* + * If GET_DBLIST is set in the flags field, then we should + * gather directory block information while we're doing the + * block move. + */ + if (flags & EXT2_BMOVE_GET_DBLIST) { + if (fs->dblist) { + ext2fs_free_dblist(fs->dblist); + fs->dblist = NULL; + } + retval = ext2fs_init_dblist(fs, 0); + if (retval) + return retval; + } + + retval = ext2fs_get_next_inode(scan, &ino, &inode); + if (retval) + return retval; + + while (ino) { + if ((inode.i_links_count == 0) || + !ext2fs_inode_has_valid_blocks(&inode)) + goto next; + + pb.ino = ino; + pb.inode = &inode; + + pb.add_dir = (LINUX_S_ISDIR(inode.i_mode) && + flags & EXT2_BMOVE_GET_DBLIST); + + retval = ext2fs_block_iterate2(fs, ino, 0, block_buf, + process_block, &pb); + if (retval) + return retval; + if (pb.error) + return pb.error; + + next: + retval = ext2fs_get_next_inode(scan, &ino, &inode); + if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) + goto next; + } + return 0; +} + diff -Naur silo-1.4.13.orig/libext2fs/brel.h silo-1.4.13/libext2fs/brel.h --- silo-1.4.13.orig/libext2fs/brel.h 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/brel.h 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,86 @@ +/* + * brel.h + * + * Copyright (C) 1996, 1997 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +struct ext2_block_relocate_entry { + blk_t new; + __s16 offset; + __u16 flags; + union { + blk_t block_ref; + ext2_ino_t inode_ref; + } owner; +}; + +#define RELOCATE_TYPE_REF 0x0007 +#define RELOCATE_BLOCK_REF 0x0001 +#define RELOCATE_INODE_REF 0x0002 + +typedef struct ext2_block_relocation_table *ext2_brel; + +struct ext2_block_relocation_table { + __u32 magic; + char *name; + blk_t current; + void *priv_data; + + /* + * Add a block relocation entry. + */ + errcode_t (*put)(ext2_brel brel, blk_t old, + struct ext2_block_relocate_entry *ent); + + /* + * Get a block relocation entry. + */ + errcode_t (*get)(ext2_brel brel, blk_t old, + struct ext2_block_relocate_entry *ent); + + /* + * Initialize for iterating over the block relocation entries. + */ + errcode_t (*start_iter)(ext2_brel brel); + + /* + * The iterator function for the inode relocation entries. + * Returns an inode number of 0 when out of entries. + */ + errcode_t (*next)(ext2_brel brel, blk_t *old, + struct ext2_block_relocate_entry *ent); + + /* + * Move the inode relocation table from one block number to + * another. + */ + errcode_t (*move)(ext2_brel brel, blk_t old, blk_t new); + + /* + * Remove a block relocation entry. + */ + errcode_t (*delete)(ext2_brel brel, blk_t old); + + + /* + * Free the block relocation table. + */ + errcode_t (*free)(ext2_brel brel); +}; + +errcode_t ext2fs_brel_memarray_create(char *name, blk_t max_block, + ext2_brel *brel); + +#define ext2fs_brel_put(brel, old, ent) ((brel)->put((brel), old, ent)) +#define ext2fs_brel_get(brel, old, ent) ((brel)->get((brel), old, ent)) +#define ext2fs_brel_start_iter(brel) ((brel)->start_iter((brel))) +#define ext2fs_brel_next(brel, old, ent) ((brel)->next((brel), old, ent)) +#define ext2fs_brel_move(brel, old, new) ((brel)->move((brel), old, new)) +#define ext2fs_brel_delete(brel, old) ((brel)->delete((brel), old)) +#define ext2fs_brel_free(brel) ((brel)->free((brel))) + diff -Naur silo-1.4.13.orig/libext2fs/brel_ma.c silo-1.4.13/libext2fs/brel_ma.c --- silo-1.4.13.orig/libext2fs/brel_ma.c 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/brel_ma.c 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,197 @@ +/* + * brel_ma.c + * + * Copyright (C) 1996, 1997 Theodore Ts'o. + * + * TODO: rewrite to not use a direct array!!! (Fortunately this + * module isn't really used yet.) + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#include +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_ERRNO_H +#include +#endif + +#include "ext2_fs.h" +#include "ext2fs.h" +#include "brel.h" + +static errcode_t bma_put(ext2_brel brel, blk_t old, + struct ext2_block_relocate_entry *ent); +static errcode_t bma_get(ext2_brel brel, blk_t old, + struct ext2_block_relocate_entry *ent); +static errcode_t bma_start_iter(ext2_brel brel); +static errcode_t bma_next(ext2_brel brel, blk_t *old, + struct ext2_block_relocate_entry *ent); +static errcode_t bma_move(ext2_brel brel, blk_t old, blk_t new); +static errcode_t bma_delete(ext2_brel brel, blk_t old); +static errcode_t bma_free(ext2_brel brel); + +struct brel_ma { + __u32 magic; + blk_t max_block; + struct ext2_block_relocate_entry *entries; +}; + +errcode_t ext2fs_brel_memarray_create(char *name, blk_t max_block, + ext2_brel *new_brel) +{ + ext2_brel brel = 0; + errcode_t retval; + struct brel_ma *ma = 0; + size_t size; + + *new_brel = 0; + + /* + * Allocate memory structures + */ + retval = ext2fs_get_mem(sizeof(struct ext2_block_relocation_table), + &brel); + if (retval) + goto errout; + memset(brel, 0, sizeof(struct ext2_block_relocation_table)); + + retval = ext2fs_get_mem(strlen(name)+1, &brel->name); + if (retval) + goto errout; + strcpy(brel->name, name); + + retval = ext2fs_get_mem(sizeof(struct brel_ma), &ma); + if (retval) + goto errout; + memset(ma, 0, sizeof(struct brel_ma)); + brel->priv_data = ma; + + size = (size_t) (sizeof(struct ext2_block_relocate_entry) * + (max_block+1)); + retval = ext2fs_get_mem(size, &ma->entries); + if (retval) + goto errout; + memset(ma->entries, 0, size); + ma->max_block = max_block; + + /* + * Fill in the brel data structure + */ + brel->put = bma_put; + brel->get = bma_get; + brel->start_iter = bma_start_iter; + brel->next = bma_next; + brel->move = bma_move; + brel->delete = bma_delete; + brel->free = bma_free; + + *new_brel = brel; + return 0; + +errout: + bma_free(brel); + return retval; +} + +static errcode_t bma_put(ext2_brel brel, blk_t old, + struct ext2_block_relocate_entry *ent) +{ + struct brel_ma *ma; + + ma = brel->priv_data; + if (old > ma->max_block) + return EXT2_ET_INVALID_ARGUMENT; + ma->entries[(unsigned)old] = *ent; + return 0; +} + +static errcode_t bma_get(ext2_brel brel, blk_t old, + struct ext2_block_relocate_entry *ent) +{ + struct brel_ma *ma; + + ma = brel->priv_data; + if (old > ma->max_block) + return EXT2_ET_INVALID_ARGUMENT; + if (ma->entries[(unsigned)old].new == 0) + return ENOENT; + *ent = ma->entries[old]; + return 0; +} + +static errcode_t bma_start_iter(ext2_brel brel) +{ + brel->current = 0; + return 0; +} + +static errcode_t bma_next(ext2_brel brel, blk_t *old, + struct ext2_block_relocate_entry *ent) +{ + struct brel_ma *ma; + + ma = brel->priv_data; + while (++brel->current < ma->max_block) { + if (ma->entries[(unsigned)brel->current].new == 0) + continue; + *old = brel->current; + *ent = ma->entries[(unsigned)brel->current]; + return 0; + } + *old = 0; + return 0; +} + +static errcode_t bma_move(ext2_brel brel, blk_t old, blk_t new) +{ + struct brel_ma *ma; + + ma = brel->priv_data; + if ((old > ma->max_block) || (new > ma->max_block)) + return EXT2_ET_INVALID_ARGUMENT; + if (ma->entries[(unsigned)old].new == 0) + return ENOENT; + ma->entries[(unsigned)new] = ma->entries[old]; + ma->entries[(unsigned)old].new = 0; + return 0; +} + +static errcode_t bma_delete(ext2_brel brel, blk_t old) +{ + struct brel_ma *ma; + + ma = brel->priv_data; + if (old > ma->max_block) + return EXT2_ET_INVALID_ARGUMENT; + if (ma->entries[(unsigned)old].new == 0) + return ENOENT; + ma->entries[(unsigned)old].new = 0; + return 0; +} + +static errcode_t bma_free(ext2_brel brel) +{ + struct brel_ma *ma; + + if (!brel) + return 0; + + ma = brel->priv_data; + + if (ma) { + if (ma->entries) + ext2fs_free_mem(&ma->entries); + ext2fs_free_mem(&ma); + } + if (brel->name) + ext2fs_free_mem(&brel->name); + ext2fs_free_mem(&brel); + return 0; +} diff -Naur silo-1.4.13.orig/libext2fs/ChangeLog silo-1.4.13/libext2fs/ChangeLog --- silo-1.4.13.orig/libext2fs/ChangeLog 1969-12-31 19:00:00.000000000 -0500 +++ silo-1.4.13/libext2fs/ChangeLog 2007-04-03 17:02:53.000000000 -0400 @@ -0,0 +1,3311 @@ +2006-06-30 Theodore Ts'o + + * Release of E2fsprogs 1.38 + +2005-06-30 Theodore Ts'o + + * bitops.h, bitops.c (ext2fs_set_bit, ext2fs_clear_bit, + ext2fs_test_bit): Change these function prototypes to be + unsigned int's. Negative bit numbers were never allowed + (and never made any sense), so this should be a safe + change. This is needed to allow safe use of block numbers + greater than or equal to 2**31. + +2005-06-27 Stephen Tweedie + + * ext2fs.h (ext2fs_resize_mem): Fix C99 strict type aliasing + problems. Addresses Red Hat Bugzilla #161183. + +2005-06-19 Theodore Ts'o + + * getsectsize.c (BLKSSZGET): Clean up test for when to manually + define the BLKSSZGET ioctl. + +2005-05-29 Theodore Ts'o + + * ismounted.c (ext2fs_check_mount_point): Add test to see if the + device appears to be busy; this only works on Linux 2.6+ + systems, but provides some additional bullet-proofing in + those cases. + +2005-05-08 Theodore Ts'o + + * test_io.c (safe_getenv): Fix bug so it would fetch the right + environment variable. + +2005-04-09 Theodore Ts'o + + * inode.c (ext2fs_write_new_inode), + ind_block.c (ext2fs_read_ind_block): Add missing return + value in error return case. (Otherwise we return garbage + instead of the error code.) + +2005-03-31 Theodore Ts'o + + * test_io.c (test_open): If called by a setuid/setgid or an + otherwise privileged program, be paranoid and ignore the + TEST_IO_* environment variables. + +2005-03-21 Theodore Ts'o + + * Release of E2fsprogs 1.37 + +2005-03-21 Theodore Ts'o + + * ext2_ext_attr.h (EXT2_XATTR_LEN, EXT2_XATTR_SIZE): Add new + convenience cpp macros. + +2005-03-20 Theodore Ts'o + + * mkdir.c (ext2fs_mkdir): Call ext2fs_write_new_inode() instead of + ext2fs_write_inode(). + + * inode.c (ext2fs_write_new_inode): New function which should be + used when the caller is writing an inode for the first + time. It makes sure that the extra portion of the large + inode is initialized properly. + +2005-03-18 Theodore Ts'o + + * Makefile.in: Fix clean target to remove tst_getsectsize. + + * getsize.c (ext2fs_get_device_size): Check to see if the number + of blocks is greater than 2**32 when we are doing a binary + search to determine the device size. Thanks to Stephen + Tweedie for the patch. + +2006-02-05 Theodore Ts'o + + * Release of E2fsprogs 1.36 + +2005-02-05 Theodore Ts'o + + * Makefile.in: Remove ext2fs.pc on a "make distclean" + +2005-02-04 Theodore Ts'o + + * Makefile.in (clean): Remove tst_getsize when doing a make clean + +2005-02-03 Theodore Ts'o + + * bitops.c: Make the generic functions more efficient. + + * bitops.h: Drop SPARC assembly code. It's less efficient than GCC + 3.4 compiled code and also triggers nasty compiler + warnings on sparc64. Thanks to Matthias Andree for his + analysis and suggestion. + +2005-01-27 Theodore Ts'o + + * res_gdt.c (ext2fs_create_resize_inode): Create the resize inode + even if s_reserved_gdt_blocks is zero. + +2005-01-26 Theodore Ts'o + + * ext2fs.pc.in: Add pkg-config files. + +2005-01-25 Theodore Ts'o + + * ext2fs.h: Add definition of struct ext2_inode_large + + * ext2_fs.h: Add new function prototypes + + * ext_attr.c (ext2fs_read_ext_attr, ext2fs_write_ext_attr): The + ext2fs_swap_ext_attr() has been moved to swapfs.c, and + given a new argument, has_header. + + * swapfs.c (ext2fs_swap_ext_attr): Moved from ext_attr.c, and + takes an argument which controls whether or not there is + an EA header which needs to be byteswaped. + (ext2fs_swap_inode_full): New function which byte-swaps + the EA in inode. + + * inode.c (ext2fs_get_next_inode_full, ext2fs_read_inode_full, + ext2fs_write_inode_full): New functions, originally from + Alex Tomas, but which needed to be substantially fixed so + that the tests wouldn't cause major stack overwrite bugs + in byte-swapping is enabled. + +2005-01-18 Theodore Ts'o + + * Makefile.in: Fix the kernel compile-time echo commands to be + consistent and portable + +2005-01-07 Theodore Ts'o + + * unlink.c (ext2fs_unlink): If both the name and the inode number + are unspecified, then return an error, so that we don't do + something surprising such as unconditionally deleting the + first directory entry. + (unlink_proc): Delete directory entries by coalescing it + with the previous entry, to avoid directory fragmentation. + +2005-01-06 Theodore Ts'o + + * version.c (ext2fs_parse_version_string): Change parsing + algorithm so that version strings such as 1.36-rc1 returns + a non-surprising result (i.e., 136, and not 1361). + +2005-01-05 Theodore Ts'o + + * block.c (block_iterate_ind, block_iterate_dind, + block_iterate_tind): Move the code which byte swaps and + read/writes indirect blocks to ext2fs_{read,write}_ind_block. + This saves 400 bytes, and we need them for the + resize_inode handling. + + * ind_block.c (ext2fs_read_ind_block, ext2fs_write_ind_block): New + functions. + + * res_gdt.c (ext2fs_create_resize_inode): Use + ext2fs_{read,write}_ind_block so that byte swapping is + handled on big-endian systems. + + * dupfs.c (ext2fs_dup_handle): Make sure the new filesystem handle + has its own copy of the orig_super data structure. (This + is a better way of fixing a double-free problem in + resize2fs which Fedora attempted to fix in + e2fsprogs-1.35-double_free.patch. Addresses Red Hat + Bugzilla #132707.) + +2004-12-23 Theodore Ts'o + + * inode.c (ext2fs_flush_icache): When flushing the icache, clear + the last-read block information as well. + + * ext2fs.h (BMAP_SET), bmap.c (ext2fs_bmap): Add support for new + flag, BMAP_SET, which allows the caller to set a + particular logical->physical block mapping. + + * ext2_err.et.in (EXT2_ET_SET_BMAP_NO_IND): New error code + + * initialize.c (calc_reserved_gdt_blocks): #ifdef out all + debugging printf statements. + + * res_gdt.c (ext2fs_create_resize_inode): Return + EXT2_ET_RESIZE_INODE_CORRUPT if the resize inode is not + what we expect. #ifdef out all debugging printf + statements. + + * ext2_err.et.in (EXT2_ET_RESIZE_INODE_CORRUPT): Add new error code. + +2004-12-22 Theodore Ts'o + + * swapfs.c (ext2fs_swap_super): Byteswap the reserved_gdt_blocks + superblocks field. + +2004-12-15 Theodore Ts'o + + * sparse.c (ext2fs_list_backups, ext2fs_bg_has_super), + res_gdt.c (list_backups), closefs.c (ext2fs_bg_has_super), + ext2fs.h: Move ext2fs_list_backups() to res_gdt.c, and + ext2fs_bg_has_super() back to closefs.c. There's no + reason for the new file, since list_backups() isn't being + used by any other functions, and can be made static, and + all users of the ext2fs filesystem will have to call + ext2fs_close() anyway. + +2004-12-15 Theodore Ts'o + + * Applied resize inode patch from Andreas Dilger + + * res_gdt.c (ext2fs_create_resize_inode): New function that + creates the resize inode. + + * initialize.c (ext2fs_initialize): Reserve space for the resize + inode. + + * ext2fs.h (EXT2_LIB_FEATURE_COMPAT_SUPP): Add + EXT2_FEATURE_COMPAT_RESIZE_INODE to the list of supported + capabilities. + Add function prototypes for res_gdt.c and sparse.c. + + * closefs.c (ext2fs_super_and_bgd_loc): Take the reserved blocks + into account when calculating the number of overhead + blocks. + + * closefs.c (ext2fs_bg_has_super, test_root), sparse.c: Move these + functions to the new file sparse.c + + * alloc_sb.c (ext2fs_reserve_super_and_bgd): Reserve the blocks + saved in the resize inode as being in use. + + * ext2_err.et.in (EXT2_ET_RES_GDT_BLOCKS): Add new error code. + + * Makefile.in (srcdir): Add res_gdt.c and sparse.c to the ext2fs + library. + +2004-12-14 Theodore Ts'o + + * Makefile.in: Use Linux-kernel-style makefile output for "make + install" + + * Makefile.in (installdirs): Use $(MKINSTALLDIRS) macro + Update dependencies. + +2004-11-30 Theodore Ts'o + + * unix_io.c (unix_set_option): Add support for the offset option. + + * test_io.c (test_set_option): Add support for the set_option method. + + * ext2_io.h: Add new io_channel method, set_option(), and change + io_channel_write_byte() from a macro to a library function. + + * ext2fs.h, openfs.c(ext2fs_open2): New version of ext2fs_open + which adds a new parameter, io_options. + (ext2fs_open): If there is a question mark in the + filename, and no io_options are specified, assumed that + the text following the question mark are io_options. + + * io_manager.c, Makefile.in: New source file which contains + high-level functions for the io_channel layer. + + * freefs.c (ext2fs_free): Make sure we don't free the io_channel + if image_io is NULL. + + * Makefile.in: Use Linux-kernel-style makefile output to make it + easier to see errors/warnings. + +2004-11-29 Theodore Ts'o + + * ext2_fs.h (EXT2_EXTENTS_FL, EXT3_FEATURE_INCOMPAT_EXTENTS, + EXT2_MAX_BLOCK_LOG_SIZE): Add definition for extent + feature and inode flag. Change maximum allowable block + size to be 65536. + +2004-10-08 Theodore Ts'o + + * getsize.c (ext2fs_get_device_size): Add support for Windows + 9x/NT under Cygwin. Thanks to Sam Robb + (samrobb@users.sourceforge.net) for pointing this and the + suggested code patch. + +2004-09-17 Theodore Ts'o + + * getsize.c: Clean up header #include's. + + * llseek.c (ext2fs_llseek): On non-linux systems, use lseek64() if + it is present. (Addresses Debian bug #269044) + +2004-07-28 Theodore Ts'o + + * rw_bitmaps.c (read_bitmaps), block.c (block_iterate_ind, + block_iterate_dind, block_iterate_tind), inode.c + (ext2fs_read_inode): If EXT2_FLAG_IMAGE_FILE is set, so + read the metadata from fs->image_io instead of fs->io. + + * initialize.c (ext2fs_initialize), openfs.c (ext2fs_open): + Initialize fs->image_io to be the same as fs->io. + + * ext2_err.et.in (EXT2_ET_NOT_IMAGE_FILE): Add new error code. + + * openfs.c (ext2fs_get_data_io, ext2fs_set_data_io, + ext2fs_rewrite_to_io): New functions that allow + applications to manipulate fs->image_io and fs->io safely. + + * freefs.c (ext2fs_free): If fs->image_io is different fs->io, + then call io_channel_close on fs->image_io. + + * ext2fs.h: Add image_io element to the ext2_filsys data + structure. Add ext2fs_get_data_io() ext2fs_set_data_io(), + and ext2fs_rewrite_to_io() prototypes. + +2004-05-26 Theodore Ts'o + + * closefs.c (ext2fs_flush): Make sure the master superblock is + written last, and only after other I/O has been flushed to + disk. Thanks to Junfeng Yang from the Stanford + Metacompilation group for pointing a potential ordering + constraint problem if we don't write things out in the + right order. + + * test_io.c: Implement the ability to abort after n reads or + writes to a particular block. The block is specified by + TEST_IO_BLOCK environment variable, and the read/write + count by the TEST_IO_READ_ABORT and TEST_IO_WRITE_ABORT + environment variables. The block data is now only dumped + if the 0x10 bit is set in TEST_IO_FLAGS. + +2004-04-03 Theodore Ts'o + + * ext2_types.h.in: Remove check for _UUID_TYPES since uuid_types.h + is no longer used. + +2004-03-08 Theodore Ts'o + + * getsize.c (ext2fs_get_device_size): Only use the BLKGETSIZE64 + ioctl on Linux 2.6 since it is unreliable in Linux 2.4. + (Addresses Debian Bug #236528). Fix typo in the ioctl + used for Mac OS X. + +2004-03-02 Theodore Ts'o + + * getsize.c (ext2fs_get_device_size): Update getsize functions to + use Apple Darwin and Linux 64-bit ioctl's + +2004-02-29 Brian Bergstrand + + * Makefile.in: Use $(BSDLIB_PIC_FLAG) to determine whether to use + -fpic or -fPIC + +2004-02-28 Theodore Ts'o + + * Release of E2fsprogs 1.35 + +2004-02-21 Theodore Ts'o + + * ext2fs.h (ext2fs_resize_mem): Fix C++ problem. (Addresses Red + Hat Bugzilla #112448; thanks Thomas Woerner from Red Hat.) + +2004-02-14 Theodore Ts'o + + * namei.c (follow_link): Correctly deal with symlinks that have + extended attribute information. (Addresses Debian Bug + #232328) + +2004-01-30 Theodore Ts'o + + * ext2_fs.h: Reserve an extra 4 bytes for the journal backup, + which we're using due to a typo in the e2fsck code. (Oops) + + * swapfs.c (ext2fs_swap_inode): Fix byte swap bug which causes SE + Linux created symlinks with mandatory attributes to fail + to be properly handled on big endian systems. (Addresses + Debian Bug #228723). + (ext2fs_swap_super): Byte swap some new fields in the + superblock, including the journal backup fields. + +2003-12-02 Theodore Ts'o + + * alloc.c, bb_inode.c, bitops.c, block.c, check_desc.c, closefs.c, + dir_iterate.c, dirblock.c, expanddir.c, ext2fs.h, + get_pathname.c, icount.c, imager.c, initalize.c, inode.c, + lookup.c, openfs.c, read_bb.c, read_bb_file.c, + rw_bitmaps.c, unix_io.c, unlink.c, write_bb_file.c: Fix + gcc -Wall complaints. Mainly marking variables as being + unsued, and catching signed vs. unsigned comparisons. + +2003-09-03 Theodore Ts'o + + * closefs.c (ext2fs_super_and_bgd_loc): New function which + centralizes the calculation of the superblock and block + group descriptors. + (ext2fs_flush): Use ext2fs_super_and_bgd_lock to figure + out where to write the superblock and block group + descriptors. + + * alloc_sb.c (ext2fs_reserve_super_and_bgd): New function which + reserves space in the block bitmap using + ext2fs_super_and_bgd_loc. + + * initialize.c (ext2fs_initialize): Use + ext2fs_reserve_super_and_bgd to initialize the block bitmap. + +2003-08-20 Theodore Ts'o + + * inode_io.c (ext2fs_inode_io_intern2), ext2fs.h: Add new function + allows the caller to pass in the inode data structure. + + * fileio.c (ext2fs_file_open2), ext2fs.h: Add new function which + allows the caller to pass in the inode to be used in the + file I/O. + + * ext2_fs.h: Add a backup of the location of the journal inode + blocks to the superblock. + + * mkjournal.c (write_journal_inode): Save the location of the + journal inode to the backup location in the superblock. + +2003-08-01 Philipp Thomas + + * alloc.c, badblocks.c, bb_inode.c, bitmaps.c, block.c, bmap.c, + bmove.c, brel_ma.c, closefs.c, dblist.c, dblist_dir.c, + dir_iterate.c, dirblock.c, dupfs.c, expanddir.c, ext2fs.h, + ext_attr.c, fileio.c, freefs.c, get_pathname.c, icount.c, + initialize.c, inode.c, inode_io.c, irel_ma.c, mkdir.c, + mkjournal.c, namei.c, newdir.c, openfs.c, rs_bitmap.c, + rw_bitmaps.c, test_io.c, unix_io.c: ext2fs_getmem(), + ext2fs_free_mem(), and ext2fs_resize_mem() all now take a + 'void *' instead of a 'void **' in order to avoid pointer + aliasing problems with GCC 3.x. + +2003-07-25 Theodore Ts'o + + * Release of E2fsprogs 1.34 + +2003-07-06 Theodore Ts'o + + * kernel-jbd.h, flushb.c: Fix gcc -Wall nitpicks (indented cpp + directives) + + * ext2_types.h.in, initialize.c: Fix gcc -Wall nitpicks + (don't use #elsif) + + * ismounted.c: Fix gcc -Wall nitpicks (Don't use exit as a goto label) + + * llseek.c: Fix gcc -Wall nitpicks (don't use #elsif) + + * lookup.c, read_bb.c: Fix gcc -Wall nitpicks (indent + non-traditional #pragma) + + * test_io.c: Fix gcc -Wall nitpicks (const/unsigned type issues) + +2003-06-24 + + * badblocks.c, ext2fs.h (ext2fs_u32_list_find, + ext2fs_u32_list_test, ext2fs_u32_list_del, + ext2fs_badblocks_list_del): Add functions to delete a + block from the badblocks list. + * tst_badblocks.c: Add test cases for ext2fs_badblocks_list_del(). + +2003-05-21 Theodore Ts'o + + * getsectsize.c (ext2fs_get_device_sectsize): New function which + returns the hardware sector size (if it is available). + +2003-05-13 Theodore Ts'o + + * unix_io.c: Add #ifdef NO_IO_CACHE which disables all userspace + caching by the unix_io layer. Not enabled, only for + debugging. + +2003-05-05 Theodore Ts'o + + * test_io.c: Pay attention to the environment variables + TEST_IO_LOGFILE, TEST_IO_FLAGS, and TEST_IO_BLOCK to + determine whether or not we should log io activity, and to + where. + +2003-05-03 Theodore Ts'o + + * tst_badblocks.c (file_test): Use tmpfile() instead of mktemp(). + +2003-04-29 Theodore Ts'o + + * getsize.c (ext2fs_get_device_size): Allow windows code to get + the resize for filesystems that are in regular files. + +2003-04-21 Theodore Ts'o + + * Release of E2fsprogs 1.33 + +2003-04-21 Theodore Ts'o + + * Makefile.in: Use DYLD_LIBRAY_PATH so that "make check" works on + Darwin systems when building with shared libraries. + +2003-04-18 Theodore Ts'o + + * unix_io.c: Use __CYGWIN__ instead of CYGWIN. + +2003-04-17 Theodore Ts'o + + * getsize.c: Add Cygwin/Windows version of ext2fs_get_device_size() + +2003-04-12 Theodore Ts'o + + * unix_io.c (raw_read_blk): Add Cygwin support (the Windows block + device only accepts sector aligned read requests. + + * ismounted.c (check_mntent_file): Deal with OS's that don't + define MNTOPT_RO. + + * imager.c: If the OS doesn't define ssize_t, typedef it to int. + +2003-04-11 Theodore Ts'o + + * ext2_fs.h (EXT2_FEATURE_RO_COMPAT_BTREE_DIR): Comment out unused + feature flag + +2003-03-30 Theodore Ts'o + + * Makefile.in: Use the compile_et --build-tree option. + +2003-03-14 Theodore Ts'o + + * getsize.c: Add support for Apple Darwin's ioctl to get the hard + disk size. + + * badblocks.c (ext2fs_u32_list_count), ext2fs.h: Add new function + which returns the number of entries in the list. + +2003-03-10 Theodore Ts'o + + * fileio.c (ext2fs_file_lseek): Fix bug added when adding 64-bit + support; avoid null dereference when ret_pos is NULL. + +2003-03-06 Theodore Tso + + * ext2_types.h.in: Don't redefine types if other e2fsprogs + *_types.h files have been included already. + + * kernel-jbd.h: Use C99 variadic cpp macros if not using GCC. + (Older GCC's don't support the C99 variadic macros.) + + * flushb.c (ext2fs_sync_device), + ismounted.c (ext2fs_check_mount_point): Avoid GCC extension: + #warning not supported by Solaris suncc + + * ext2_ext_attr.h: Avoid GCC extension: 0 length arrays in + structure definition. Not needed for now in + ext2_ext_attr_entry. + +2003-01-25 Theodore Ts'o + + * dirhash.c: Fix gcc -Wall nits. + +2003-01-22 Theodore Ts'o + + * unix_io.c (unix_write_blk): Fix up GCC -Wall nits. + +2003-01-21 Theodore Ts'o + + * fileio.c (ext2fs_file_read, ext2_file_lseek, + ext2_file_get_size): Add 64-bit support. + + * ext2fs.h (EXT2_I_SIZE): Add macro which caluates a 64bit size + from i_size and i_size_high. + +2003-01-19 Theodore Ts'o + + * initialize.c (ext2fs_initialize): If the user specifies a really + large number of inodes, then reduce the number of blocks + per group until we find a workable set of filesystem + parameters. + + * ext2_err.et.in (EXT2_ET_TOO_MANY_INODES): Add new error code. + +2002-11-09 Theodore Ts'o + + * Release of E2fsprogs 1.32 + +2002-11-09 Theodore Ts'o + + * unix_io.c (find_cached_block, reuse_cache, unix_read_blk, + unix_write_blk): Optimize routines so that we don't end up + searching the cache twice when a block isn't in the + cache. If reads are larger than READ_DIRECT_SIZE, don't + let them go through the cache. + + * unix_io.c (find_cached_block): Fixed bug which caused some clean + blocks to be erroneously marked as dirty, so they would + get written back to the disk before they are evicted from + the cache. Harmless, but it slows down e2fsck + significantly. + +2002-11-08 Theodore Ts'o + + * Release of E2fsprogs 1.31 + +2002-11-08 + + * Makefile.in (check): Skip trying to compile test_byteswap + if --disable-byteswaap had been given to configure. + +2002-11-07 + + * closefs.c (write_bgdesc, ext2fs_flush): Fix bug in meta_bg + support when the MASTER_SB_ONLY flag is set. Some of + the descriptor blocks that should have been written out + were getting skipped. + +2002-10-31 Theodore Ts'o + + * Release of E2fsprogs 1.30 + +2002-10-31 Theodore Ts'o + + * ext2_fs.h: Add support for a new inode flag, which is to be used + for indicating the top of directory hierarchies for the + Orlov block allocator. + + * ismounted.c (check_mntent, check_mntent_file): Add better + support for loopback-mounted filesystems. Check /etc/mtab + if /proc/mounts doesn't turn up any mount flags, since + /etc/mtab has the loopback image filename, instead of + /dev/loop0. Also, check based on st_dev and st_ino, so + that if a relative pathname or a pathnames using symbolic + links are used, we can detect the the filesystem correctly + in those cases. (Addresses Sourceforge bug #619119) + + * flushb.c (ext2fs_sync_device): If the BLKFLSBUF ioctl succeeds, + don't try the FDFLUSH ioctl that was required for floppies + with older kernels. This avoids needless whining from the + MD device driver. (Addresses Sourceforge bug #545832). + + * openfs.c (ext2fs_open): Fix bug which caused us to pass the + wrong group_block to ext2fs_descriptor_block_loc if we're + using the backup superblock/block group descriptors. + (ext2fs_descriptor_block_loc): If we're using the backup + superblock descriptors, use the backup descriptor block in + the next block group. + +2002-10-30 Theodore Ts'o + + * alloc_tables.c (ext2fs_allocate_group_table): Allocate the inode + table so that it buts up against the bitmap blocks, to + avoid block fragmentation. + + * closefs.c (write_bgdesc), initalize.c (ext2fs_initialize): Fix + bug; only allocate group descriptor blocks up to + s_first_meta_bg. + +2002-10-25 Theodore Ts'o + + * ext2_fs.h: Add a new superblock field, s_mkfs_time, so that we + know when a filesystem was created. (Sometimes this can + be useful...) + + * initialize.c (ext2fs_initialize): Set the s_mkfs_time field. + +2002-10-20 Theodore Ts'o + + * ext2_fs.h (EXT3_DEFM_JMODE): Add new default mount options for + the journal data mode. + + * closefs.c (ext2fs_flush, write_bgdesc), ext2_fs.h, ext2fs.h, + openfs.c (ext2fs_descriptor_block_loc, ext2fs_open), initialize.c + (ext2fs_initialize), swapfs.c (ext2fs_swap_super): Add support for + the meta_blockgroup filesystem format. + +2002-10-15 + + * ext2_fs.h: Add new field in superblock for default mount options. + +2002-10-13 Theodore Ts'o + + * ext2fs.h: Add #include of header files necessary for ext2fs.h to + compile cleanly. + +2002-10-02 Theodore Y. Ts'o + + * rw_bitmaps.c (ext2fs_write_block_bitmap, + ext2fs_read_block_bitmap): Don't set the CHANGED bit just + because the bitmap is getting written to disk. Make + ext2fs_swap_bitmap be a static function, since it's not + intended to be exported. + + * swapfs.c (ext2fs_swap_super): Byte-swap the hash seed + +2001-09-24 Theodore Tso + + * Release of E2fsprogs 1.29 + +2001-08-31 Theodore Tso + + * Release of E2fsprogs 1.28 + +2002-08-31 Theodore Ts'o + + * dblist.c (ext2fs_dblist_sort): New function which allows the + caller to pass in a special sort comparison function. + +2002-08-20 Theodore Ts'o + + * valid_blk.c (ext2fs_inode_has_valid_blocks): Fix bug which + failed to accurately characterize non-standard slow + symlinks. (Which don't appear in practice on real-life + systems, fortunately.) + +2002-08-17 Theodore Ts'o + + * Makefile.in: Remove inode_io.o from the standard object files, + and only build it if debugfs is enabled (it requires + fileio.o, which is only built if --disable-debugfs isn't + specified to configure). + + * dirhash.c (ext2fs_dirhash): Change the MD4 hash in a backwards + incompatible way so that it is no longer + endian-dependent. Add the TEA hash. Allow the seed + parameter to be optional. + + * ext2_fs.h: Remove the HALF_MD4_SEED and HALF_MD4_64 hashes. + These features are all now in the HALF_MD4 hash. Add + definition for EXT2_HASH_TEA. + + * ext2fs.h (ext2fs_dirhash): Change function prototype so it takes + a pointer instead of an array. + +2002-08-16 Theodore Ts'o + + * ext2_err.et.in (EXT2_ET_BAD_EA_BLOCK_NUM): New error code + + * ext2fs.h (ext2fs_inode_data_blocks): New function which returns + the number of data blocks used by an inode exclusive of + the EA block. + + * ext_attr.c (ext2fs_adjust_ea_refcount): New function which + adjusts the reference count in an extended attribute block. + + * valid_blk.c (ext2fs_inode_has_valid_blocks): Add code to + correctly deal with extended attribute blocks in symbolic + links. + +2002-08-13 + + * Makefile.in: Move dupfs.o and test_io.o from the + needed-by-debugfs object list to the needed-by-resizer + object list. Fixes compile problem if the system is built + with only --disable-debugfs. + +2002-07-29 Theodore Ts'o + + * link.c (ext2fs_link): When adding a new link to a directory, + clear the HTREE bit. + +2002-07-23 Theodore Ts'o + + * dirhash.c (ext2fs_dirhash): Fix bug which caused MD4 + calculations for names > 32 characters to be completely + bogus. Changed MD4 calculation to match what is currently + being used in the CVS gkernel tree. + +2002-07-19 Theodore Ts'o + + * ext2_fs.h: Add s_hash_seed and s_def_hash_version to the + superblock definition. + + * badblocks.c, freefs.c, ext2fs.h: Use the badblocks functions to + create a set of u32_list functions. + + * dirhash.c (halfMD4Transform): Shift the hash by one bit, + since that's required by the directory indexing code. + +2002-07-14 Theodore Ts'o + + * ext2fs.h, read_bb_file.c: Change private to priv_data, to avoid + using a C++ reserved word. + + * unix_io.c (unix_open): Only attempt the setrlimit workaround if + the kernel version is 2.4.10 -- 2.4.17, since otherwise an + old version of glibc (built against 2.2 headers) will + interact badly with the workaround to actually cause more + problems. I hate it when the glibc folks think they're + being smarter than the kernel.... + +2002-06-28 Andreas Dilger + + * ext2_fs.h: Add superblock field for reserved group descriptors. + +2002-06-28 Theodore Ts'o + + * bitops.h: Add #define's for ext2fs_{l,b}e{32,16}_to_cpu and + ext2fs_cpu_to_{l,b}e{32,16} + +2002-06-27 Theodore Ts'o + + * ismounted.c (check_mntent): In AIX 4.3, MOUNTED isn't defined. + Add appropriate fallbacks in this case. + +2002-06-26 Theodore Ts'o + + * dirhash.c (ext2fs_dirhash): Change function signature to support + a hash seed, and to return the minor hash (for 64-bit hash + support). Add support for the half MD4, half MD4 with + seed, and half MD4 with seed and 64 bits. + +2002-06-15 Theodore Ts'o + + * ext2_fs.h (EXT2_DIRSYNC_FL): Add new file. + +2002-06-09 Andreas Dilger + + * ext2_fs.h: Add macros for maximum block/inode counts: + EXT2_INODES_PER_BLOCK, EXT2_MAX_BLOCKS_PER_GROUP, + and EXT2_MAX_INODES_PER_GROUP. + + * openfs.c (ext2fs_open): Check that the number of blocks in a group + is less than 2^16, otherwise we need an INCOMPAT flag (not + in existence yet, if ever) to open such a filesystem. + + * initialize.c (ext2fs_initialize): Limit the number of blocks and + inodes in a group to less than 2^16. + +2002-06-09 Andreas Dilger + + * ext2_fs.h: Further minor cleanups of the header. Consolidate + some checks for __KERNEL__ into one place. + +2002-05-22 Andreas Dilger + + * ext2_fs.h: Remove macros accessing u.ext2_sb field and use + the EXT2_SB() macro instead. Remove kernel function + prototypes also. This matches the 2.5 kernel, and + is also cleaner for other reasons. Whitespace cleanup. + +2002-05-21 Theodore Ts'o + + * ext2_ext_attr.h: Update to V2 version of the Bestbits format. + +2002-05-16 Andreas Dilger + + * ext2_fs.h: Change limits to support filesystems with 8k blocks. + + * initialize.c (ext2fs_initialize): Remove assumption that + blocksizes are always <= 4k. + +2002-05-11 Theodore Ts'o + + * bmap.c (ext2fs_bmap): Fix bug which caused ext2fs_bmap to fail + silently if inode pointer is NULL (and ext2fs_bmap is + expected to read the inode itself). + +2002-04-27 Theodore Ts'o + + * ismounted.c (check_mntent_file, is_swap_device): Verify that the + file we are checking is a block device file before looking + at st_rdev, since it's not valid for normal files. + (is_swap_device): Move so that it is outside the + HAVE_MNTENT_H, so that it is always built. + +2002-03-11 Theodore Tso + + * dirblock.c (ext2fs_read_dir_block2, ext2fs_write_dir_block): New + functions which take an extra flags argument. The flag + EXT2_DIRBLOCK_V2_STRUCT will reverse when the name_len + field is byte swampped on big-endian machines, since in + the V2 structure, name_len is a char field which is + doesn't need to be byte swapped --- except if an + old-style kernel had byte-swapped the name_len field + as part of the V1 structure. + + * ext2_err.et.in (EXT2_ET_DIRHASH_UNSUPP): New error code + + * dirhash.c (ext2fs_dirhash): New function which calculates the + hash for a filename in an indexed directory. + +2002-03-08 Theodore Tso + + * Release of E2fsprogs 1.27 + +2002-03-07 Theodore Tso + + * ext2fs.h (ext2fs_inode_io_intern): Add missing function prototype. + + * bmap.c, fileio.c, inode_io.c, tst_badblocks.c, + tst_byteswap.c: Fix gcc -Wall complaints + + * Makefile.in (check): Use LD_LIBRARY_PATH to run test programs. + (From Philipp Thomas ) + +2002-02-25 Theodore Tso