Initial commit -- seeded with reiserfsprogs 3.x.0j

This commit is contained in:
Jeff Mahoney committed 2012-10-11 11:26:22 -04:00
commit e7102bdb66
77 files changed
+33513

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
noinst_LIBRARIES = libmisc.a
libmisc_a_SOURCES = io.c misc.c
##reiserfs.c
INCLUDES = -I$(top_srcdir)/include
+260
View File
@@ -0,0 +1,260 @@
# Makefile.in generated automatically by automake 1.4 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
CC = @CC@
MAKEINFO = @MAKEINFO@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
VERSION = @VERSION@
noinst_LIBRARIES = libmisc.a
libmisc_a_SOURCES = io.c misc.c
INCLUDES = -I$(top_srcdir)/include
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
DEFS = @DEFS@ -I. -I$(srcdir)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libmisc_a_LIBADD =
libmisc_a_OBJECTS = io.o misc.o
AR = ar
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
DIST_COMMON = Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
SOURCES = $(libmisc_a_SOURCES)
OBJECTS = $(libmisc_a_OBJECTS)
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .o .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps lib/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
mostlyclean-noinstLIBRARIES:
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
distclean-noinstLIBRARIES:
maintainer-clean-noinstLIBRARIES:
.c.o:
$(COMPILE) -c $<
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
clean-compile:
distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
libmisc.a: $(libmisc_a_OBJECTS) $(libmisc_a_DEPENDENCIES)
-rm -f libmisc.a
$(AR) cru libmisc.a $(libmisc_a_OBJECTS) $(libmisc_a_LIBADD)
$(RANLIB) libmisc.a
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = lib
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
io.o: io.c ../include/io.h ../include/misc.h
misc.o: misc.c ../include/io.h
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am:
install-exec: install-exec-am
install-data-am:
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am:
uninstall: uninstall-am
all-am: Makefile $(LIBRARIES)
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
mostlyclean-tags mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
mostlyclean-am
clean: clean-am
distclean-am: distclean-noinstLIBRARIES distclean-compile \
distclean-tags distclean-generic clean-am
distclean: distclean-am
maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
maintainer-clean-compile maintainer-clean-tags \
maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-am
.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile tags mostlyclean-tags distclean-tags \
clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
check-am installcheck-am installcheck install-exec-am install-exec \
install-data-am install-data install-am install uninstall-am uninstall \
all-redirect all-am all installdirs mostlyclean-generic \
distclean-generic clean-generic maintainer-clean-generic clean \
mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
+508
View File
@@ -0,0 +1,508 @@
/*
* Copyright 1996, 1997 Hans Reiser, see reiserfs/README for licensing and copyright details
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <asm/types.h>
#include <sys/types.h>
/*#include <linux/unistd.h>*/
#include "io.h"
#include "misc.h"
/* All buffers are in double linked cycled list. Buffers of tree are
hashed by their block number. If getblk found buffer with wanted
block number in hash queue it moves buffer to the end of list */
#define BLOCK_SIZE 1024
#define MAX_NR_BUFFERS 16384
static int g_nr_buffers;
#define NR_HASH_QUEUES 4096
static struct buffer_head * g_a_hash_queues [NR_HASH_QUEUES];
static struct buffer_head * g_buffer_list_head;
static struct buffer_head * g_buffer_heads;
static void show_buffers (int dev, int size)
{
int all = 0;
int dirty = 0;
int in_use = 0; /* count != 0 */
int free = 0;
struct buffer_head * next = g_buffer_list_head;
for (;;) {
if (!next)
die ("show_buffers: buffer list is corrupted");
if (next->b_dev == dev && next->b_size == size) {
all ++;
if (next->b_count != 0) {
in_use ++;
}
if (buffer_dirty (next)) {
dirty ++;
}
if (buffer_clean (next) && next->b_count == 0) {
free ++;
}
}
next = next->b_next;
if (next == g_buffer_list_head)
break;
}
printf ("show_buffers (dev %d, size %d): free %d, count != 0 %d, dirty %d, all %d\n", dev, size, free, in_use, dirty, all);
}
static void insert_into_hash_queue (struct buffer_head * bh)
{
int index = bh->b_blocknr % NR_HASH_QUEUES;
if (bh->b_hash_prev || bh->b_hash_next)
die ("insert_into_hash_queue: hash queue corrupted");
if (g_a_hash_queues[index]) {
g_a_hash_queues[index]->b_hash_prev = bh;
bh->b_hash_next = g_a_hash_queues[index];
}
g_a_hash_queues[index] = bh;
}
static void remove_from_hash_queue (struct buffer_head * bh)
{
if (bh->b_hash_next == 0 && bh->b_hash_prev == 0 && bh != g_a_hash_queues[bh->b_blocknr % NR_HASH_QUEUES])
/* (b_dev == 0) ? */
return;
if (bh == g_a_hash_queues[bh->b_blocknr % NR_HASH_QUEUES]) {
if (bh->b_hash_prev != 0)
die ("remove_from_hash_queue: hash queue corrupted");
g_a_hash_queues[bh->b_blocknr % NR_HASH_QUEUES] = bh->b_hash_next;
}
if (bh->b_hash_next)
bh->b_hash_next->b_hash_prev = bh->b_hash_prev;
if (bh->b_hash_prev)
bh->b_hash_prev->b_hash_next = bh->b_hash_next;
bh->b_hash_prev = bh->b_hash_next = 0;
}
static void put_buffer_list_end (struct buffer_head * bh)
{
struct buffer_head * last = 0;
if (bh->b_prev || bh->b_next)
die ("put_buffer_list_end: buffer list corrupted");
if (g_buffer_list_head == 0) {
bh->b_next = bh;
bh->b_prev = bh;
g_buffer_list_head = bh;
} else {
last = g_buffer_list_head->b_prev;
bh->b_next = last->b_next;
bh->b_prev = last;
last->b_next->b_prev = bh;
last->b_next = bh;
}
}
static void remove_from_buffer_list (struct buffer_head * bh)
{
if (bh == bh->b_next) {
g_buffer_list_head = 0;
} else {
bh->b_prev->b_next = bh->b_next;
bh->b_next->b_prev = bh->b_prev;
if (bh == g_buffer_list_head)
g_buffer_list_head = bh->b_next;
}
bh->b_next = bh->b_prev = 0;
}
static void put_buffer_list_head (struct buffer_head * bh)
{
put_buffer_list_end (bh);
g_buffer_list_head = bh;
}
#define GROW_BUFFERS__NEW_BUFERS_PER_CALL 10
/* creates number of new buffers and insert them into head of buffer list
*/
static int grow_buffers (int size)
{
int i;
struct buffer_head * bh, * tmp;
if (g_nr_buffers + GROW_BUFFERS__NEW_BUFERS_PER_CALL > MAX_NR_BUFFERS)
return 0;
/* get memory for array of buffer heads */
bh = (struct buffer_head *)getmem (GROW_BUFFERS__NEW_BUFERS_PER_CALL * sizeof (struct buffer_head) + sizeof (struct buffer_head *));
if (g_buffer_heads == 0)
g_buffer_heads = bh;
else {
/* link new array to the end of array list */
tmp = g_buffer_heads;
while (*(struct buffer_head **)(tmp + GROW_BUFFERS__NEW_BUFERS_PER_CALL) != 0)
tmp = *(struct buffer_head **)(tmp + GROW_BUFFERS__NEW_BUFERS_PER_CALL);
*(struct buffer_head **)(tmp + GROW_BUFFERS__NEW_BUFERS_PER_CALL) = bh;
}
for (i = 0; i < GROW_BUFFERS__NEW_BUFERS_PER_CALL; i ++) {
tmp = bh + i;
memset (tmp, 0, sizeof (struct buffer_head));
tmp->b_data = getmem (size);
if (tmp->b_data == 0)
die ("grow_buffers: no memory for new buffer data");
tmp->b_dev = 0;
tmp->b_size = size;
put_buffer_list_head (tmp);
g_nr_buffers ++;
}
return GROW_BUFFERS__NEW_BUFERS_PER_CALL;
}
struct buffer_head * find_buffer (int dev, int block, int size)
{
struct buffer_head * next;
next = g_a_hash_queues[block % NR_HASH_QUEUES];
for (;;) {
struct buffer_head *tmp = next;
if (!next)
break;
next = tmp->b_hash_next;
if (tmp->b_blocknr != block || tmp->b_size != size || tmp->b_dev != dev)
continue;
next = tmp;
break;
}
return next;
}
void __wait_on_buffer (struct buffer_head * bh)
{
}
struct buffer_head * get_hash_table(dev_t dev, int block, int size)
{
struct buffer_head * bh;
bh = find_buffer (dev, block, size);
if (bh) {
bh->b_count ++;
}
return bh;
}
static struct buffer_head * get_free_buffer (int size)
{
struct buffer_head * next = g_buffer_list_head;
if (!next)
return 0;
for (;;) {
if (!next)
die ("get_free_buffer: buffer list is corrupted");
if (next->b_count == 0 && buffer_clean (next) && next->b_size == size) {
remove_from_hash_queue (next);
remove_from_buffer_list (next);
put_buffer_list_end (next);
return next;
}
next = next->b_next;
if (next == g_buffer_list_head)
break;
}
return 0;
}
static void sync_buffers (int size, int to_write)
{
struct buffer_head * next = g_buffer_list_head;
int written = 0;
for (;;) {
if (!next)
die ("flush_buffer: buffer list is corrupted");
if ((!size || next->b_size == size) && buffer_dirty (next) && buffer_uptodate (next)) {
written ++;
bwrite (next);
if (written == to_write)
return;
}
next = next->b_next;
if (next == g_buffer_list_head)
break;
}
}
void flush_buffers (void)
{
sync_buffers (0, 0);
}
struct buffer_head * getblk (int dev, int block, int size)
{
struct buffer_head * bh;
bh = find_buffer (dev, block, size);
if (bh) {
if (0 && !buffer_uptodate (bh))
die ("getblk: buffer must be uptodate");
// move the buffer to the end of list
/*checkmem (bh->b_data, bh->b_size);*/
remove_from_buffer_list (bh);
put_buffer_list_end (bh);
bh->b_count ++;
return bh;
}
bh = get_free_buffer (size);
if (bh == 0) {
if (grow_buffers (size) == 0) {
sync_buffers (size, 10);
}
bh = get_free_buffer (size);
if (bh == 0) {
show_buffers (dev, size);
die ("getblk: no free buffers after grow_buffers and refill (%d)", g_nr_buffers);
}
}
bh->b_count = 1;
bh->b_dev = dev;
bh->b_size = size;
bh->b_blocknr = block;
bh->b_end_io = NULL ;
memset (bh->b_data, 0, size);
clear_bit(BH_Dirty, &bh->b_state);
clear_bit(BH_Uptodate, &bh->b_state);
insert_into_hash_queue (bh);
/*checkmem (bh->b_data, bh->b_size);*/
return bh;
}
struct buffer_head * reiserfs_getblk (int dev, int block, int size, int *repeat)
{
return getblk (dev, block, size);
}
void brelse (struct buffer_head * bh)
{
if (bh == 0)
return;
if (bh->b_count == 0) {
die ("brelse: can not free a free buffer %lu", bh->b_blocknr);
}
/*checkmem (bh->b_data, bh->b_size);*/
bh->b_count --;
}
void bforget (struct buffer_head * bh)
{
if (bh) {
brelse (bh);
remove_from_hash_queue (bh);
remove_from_buffer_list (bh);
put_buffer_list_head (bh);
}
}
#if 0
#if ! ( defined __USE_LARGEFILE64 || defined __USE_FILE_OFFSET64 )
_syscall5 (int, _llseek, uint, fd, ulong, hi, ulong, lo,
loff_t *, res, uint, wh);
#endif
loff_t reiserfs_llseek (unsigned int fd, loff_t offset, unsigned int origin)
{
#if defined __USE_FILE_OFFSET64
return lseek(fd, offset, origin);
#elif defined __USE_LARGEFILE64
return lseek64(fd, offset, origin);
#else
loff_t retval, result;
retval = _llseek (fd, ((unsigned long long) offset) >> 32,
((unsigned long long) offset) & 0xffffffff,
&result, origin);
return (retval != 0 ? (loff_t)-1 : result);
#endif
}
#endif
static int f_read(struct buffer_head * bh)
{
loff_t offset;
ssize_t bytes;
offset = (loff_t)bh->b_size * (loff_t)bh->b_blocknr;
/*if (reiserfs_llseek (bh->b_dev, offset, SEEK_SET) == (loff_t)-1)*/
if (lseek64 (bh->b_dev, offset, SEEK_SET) == (loff_t)-1)
return 0;
bytes = read (bh->b_dev, bh->b_data, bh->b_size);
if (bytes != (ssize_t)bh->b_size)
return 0;
return 1;
}
struct buffer_head * bread (int dev, unsigned long block, size_t size)
{
struct buffer_head * bh;
/*
if ((size == 32768 && (block == 16 || 1026)) ||
(size == 4096 && (block == 128 || block == 8211))) {
size = 10;
return 0;
}
*/
bh = getblk (dev, block, size);
if (buffer_uptodate (bh))
return bh;
if (f_read(bh) == 0)
{
brelse(bh);
return 0;
}
mark_buffer_uptodate (bh, 0);
return bh;
}
int valid_offset( int fd, loff_t offset)
{
char ch;
loff_t res;
/*res = reiserfs_llseek (fd, offset, 0);*/
res = lseek64 (fd, offset, 0);
if (res < 0)
return 0;
if (read (fd, &ch, 1) < 1)
return 0;
return 1;
}
struct buffer_head * reiserfs_bread (int dev, int block, int size, int *repeat)
{
return bread (dev, block, size);
}
int bwrite (struct buffer_head * bh)
{
loff_t offset;
ssize_t bytes;
size_t size;
if (!buffer_dirty (bh) || !buffer_uptodate (bh))
return 0;
size = bh->b_size;
offset = (loff_t)size * (loff_t)bh->b_blocknr;
if (lseek64 (bh->b_dev, offset, SEEK_SET) == (loff_t)-1){
fprintf (stderr, "bwrite: lseek to position %Ld (block=%lu, dev=%d): %s\n",
offset, bh->b_blocknr, bh->b_dev, strerror (errno));
exit (4); /* File system errors left uncorrected */
}
bytes = write (bh->b_dev, bh->b_data, size);
if (bytes != (ssize_t)size) {
fprintf (stderr, "bwrite: write %d bytes returned %d (block=%ld, dev=%d): %s\n",
size, bytes, bh->b_blocknr, bh->b_dev, strerror (errno));
exit (4);
}
mark_buffer_clean (bh);
if (bh->b_end_io) {
bh->b_end_io(bh, 1) ;
}
return 0;
}
void check_and_free_buffer_mem (void)
{
int i = 0;
struct buffer_head * next = g_buffer_list_head;
//sync_buffers (0, 0);
for (;;) {
if (!next)
die ("check_and_free_buffer_mem: buffer list is corrupted");
if (next->b_count != 0)
fprintf (stderr, "check_and_free_buffer_mem: not free buffer (%ld, %ld, %d)",
next->b_blocknr, next->b_size, next->b_count);
if (buffer_dirty (next) && buffer_uptodate (next))
fprintf (stderr, "check_and_free_buffer_mem: dirty buffer %lu found\n",
next->b_blocknr);
freemem (next->b_data);
i ++;
next = next->b_next;
if (next == g_buffer_list_head)
break;
}
if (i != g_nr_buffers)
die ("check_and_free_buffer_mem: found %d buffers, must be %d", i, g_nr_buffers);
/* free buffer heads */
while ((next = g_buffer_heads)) {
g_buffer_heads = *(struct buffer_head **)(next + GROW_BUFFERS__NEW_BUFERS_PER_CALL);
freemem (next);
}
return;
}
/* */
void free_buffers (void)
{
check_and_free_buffer_mem ();
}
+613
View File
@@ -0,0 +1,613 @@
/*
* Copyright 1996, 1997, 1998 Hans Reiser
*/
/*#define _GNU_SOURCE*/
/*#define _FILE_OFFSET_BITS 64*/
#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <asm/types.h>
#include <stdlib.h>
#include <mntent.h>
#include <sys/vfs.h>
#include <time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "io.h"
/*
* These have been stolen somewhere from linux
*/
int set_bit (int nr, void * addr)
{
__u8 * p, mask;
int retval;
p = (__u8 *)addr;
p += nr >> 3;
mask = 1 << (nr & 0x7);
/*cli();*/
retval = (mask & *p) != 0;
*p |= mask;
/*sti();*/
return retval;
}
int clear_bit (int nr, void * addr)
{
__u8 * p, mask;
int retval;
p = (__u8 *)addr;
p += nr >> 3;
mask = 1 << (nr & 0x7);
/*cli();*/
retval = (mask & *p) != 0;
*p &= ~mask;
/*sti();*/
return retval;
}
int test_bit(int nr, const void * addr)
{
__u8 * p, mask;
p = (__u8 *)addr;
p += nr >> 3;
mask = 1 << (nr & 0x7);
return ((mask & *p) != 0);
}
int find_first_zero_bit (const void *vaddr, unsigned size)
{
const __u8 *p = vaddr, *addr = vaddr;
int res;
if (!size)
return 0;
size = (size >> 3) + ((size & 0x7) > 0);
while (*p++ == 255) {
if (--size == 0)
return (p - addr) << 3;
}
--p;
for (res = 0; res < 8; res++)
if (!test_bit (res, p))
break;
return (p - addr) * 8 + res;
}
int find_next_zero_bit (const void *vaddr, unsigned size, unsigned offset)
{
const __u8 *addr = vaddr;
const __u8 *p = addr + (offset >> 3);
int bit = offset & 7, res;
if (offset >= size)
return size;
if (bit) {
/* Look for zero in first char */
for (res = bit; res < 8; res++)
if (!test_bit (res, p))
return (p - addr) * 8 + res;
p++;
}
/* No zero yet, search remaining full bytes for a zero */
res = find_first_zero_bit (p, size - 8 * (p - addr));
return (p - addr) * 8 + res;
}
/*int test_and_set_bit (int nr, void * addr)
{
int oldbit = test_bit (nr, addr);
set_bit (nr, addr);
return oldbit;
}
int test_and_clear_bit (int nr, void * addr)
{
int oldbit = test_bit (nr, addr);
clear_bit (nr, addr);
return oldbit;
}*/
void die (char * fmt, ...)
{
static char buf[1024];
va_list args;
va_start (args, fmt);
vsprintf (buf, fmt, args);
va_end (args);
fprintf (stderr, "\n%s\n\n\n", buf);
exit (-1);
}
#define MEM_BEGIN "_mem_begin_"
#define MEM_END "mem_end"
#define MEM_FREED "__free_"
#define CONTROL_SIZE (strlen (MEM_BEGIN) + 1 + sizeof (int) + strlen (MEM_END) + 1)
static int get_mem_size (char * p)
{
char * begin;
begin = p - strlen (MEM_BEGIN) - 1 - sizeof (int);
return *(int *)(begin + strlen (MEM_BEGIN) + 1);
}
void checkmem (char * p, int size)
{
char * begin;
char * end;
begin = p - strlen (MEM_BEGIN) - 1 - sizeof (int);
if (strcmp (begin, MEM_BEGIN))
die ("checkmem: memory corrupted - invalid head sign");
if (*(int *)(begin + strlen (MEM_BEGIN) + 1) != size)
die ("checkmem: memory corrupted - invalid size");
end = begin + size + CONTROL_SIZE - strlen (MEM_END) - 1;
if (strcmp (end, MEM_END))
die ("checkmem: memory corrupted - invalid end sign");
}
void * getmem (int size)
{
char * p;
char * mem;
p = (char *)malloc (CONTROL_SIZE + size);
if (!p)
die ("getmem: no more memory (%d)", size);
strcpy (p, MEM_BEGIN);
p += strlen (MEM_BEGIN) + 1;
*(int *)p = size;
p += sizeof (int);
mem = p;
memset (mem, 0, size);
p += size;
strcpy (p, MEM_END);
checkmem (mem, size);
return mem;
}
void * expandmem (void * vp, int size, int by)
{
int allocated;
char * mem, * p = vp;
int expand_by = by;
if (p) {
checkmem (p, size);
allocated = CONTROL_SIZE + size;
p -= (strlen (MEM_BEGIN) + 1 + sizeof (int));
} else {
allocated = 0;
/* add control bytes to the new allocated area */
expand_by += CONTROL_SIZE;
}
p = realloc (p, allocated + expand_by);
if (!p)
die ("expandmem: no more memory (%d)", size);
if (!vp) {
strcpy (p, MEM_BEGIN);
}
mem = p + strlen (MEM_BEGIN) + 1 + sizeof (int);
*(int *)(p + strlen (MEM_BEGIN) + 1) = size + by;
/* fill new allocated area by 0s */
if(by > 0)
memset (mem + size, 0, by);
strcpy (mem + size + by, MEM_END);
checkmem (mem, size + by);
return mem;
}
void freemem (void * vp)
{
char * p = vp;
int size;
if (!p)
return;
size = get_mem_size (vp);
checkmem (p, size);
p -= (strlen (MEM_BEGIN) + 1 + sizeof (int));
strcpy (p, MEM_FREED);
strcpy (p + size + CONTROL_SIZE - strlen (MEM_END) - 1, MEM_FREED);
free (p);
}
typedef int (*func_t) (char *);
static int is_readonly_dir (char * dir)
{
char * name;
FILE * f;
name = tempnam (dir, 0);
if (!name) {
fprintf (stderr, "is_readonly: tempnam failed, think fs is not readonly\n");
return 0;
}
f = fopen (name, "w");
if (f) {
unlink (name);
free (name);
return 0;
}
free (name);
return (errno == EROFS) ? 1 : 0;
}
int user_confirmed (char * q, char * yes)
{
char * answer = 0;
size_t n = 0;
fprintf (stderr, "%s", q);
if (getline (&answer, &n, stdin) != strlen (yes) || strcmp (yes, answer))
return 0;
return 1;
}
#include <unistd.h>
#include <linux/unistd.h>
#define __NR_stat64 195
_syscall2(long, stat64, char *, filename, struct stat *, statbuf);
static int _is_mounted (char * device_name, func_t f)
{
int retval;
FILE *fp;
struct mntent *mnt;
struct statfs stfs;
struct stat root_st;
struct stat device_st;
/* struct stat64 device_st64;*/
int used_stat64 = 1;
if (stat ("/", &root_st) == -1)
die ("is_mounted: could not stat \"/\": %m\n");
if (stat64 (device_name, &device_st) == -1) {
used_stat64 = 0;
if (stat (device_name, &device_st) == -1)
die ("is_mounted: could not stat file \"%s\": %m",
device_name);
}
if ((used_stat64 && !S_ISBLK (device_st.st_mode)) || !S_ISBLK (device_st.st_mode))
/* not block device file could not be mounted */
return 0;
if ((used_stat64 && root_st.st_dev == device_st.st_rdev) ||
root_st.st_dev == device_st.st_rdev) {
/* device is mounted as root */
return (f ? f ("/") : 1);
}
/* if proc filesystem is mounted */
if (statfs ("/proc", &stfs) == -1 || stfs.f_type != 0x9fa0/*procfs magic*/ ||
(fp = setmntent ("/proc/mounts", "r")) == NULL) {
/* proc filesystem is not mounted, or /proc/mounts does not
exist */
if (f)
return (user_confirmed (" (could not figure out) Is filesystem mounted read-only? (Yes)",
"Yes\n"));
else
return (user_confirmed (" (could not figure out) Is filesystem mounted? (Yes)",
"Yes\n"));
}
retval = 0;
while ((mnt = getmntent (fp)) != NULL)
if (strcmp (device_name, mnt->mnt_fsname) == 0) {
retval = (f ? f (mnt->mnt_dir) : 1);
break;
}
endmntent (fp);
return retval;
}
int is_mounted_read_only (char * device_name)
{
return _is_mounted (device_name, is_readonly_dir);
}
int is_mounted (char * device_name)
{
return _is_mounted (device_name, 0);
}
char buf1 [100];
char buf2 [100];
void print_how_fast (unsigned long passed, unsigned long total,
int cursor_pos, int reset_time)
{
static time_t t0, t1;
int speed;
int indent;
if (reset_time)
time (&t0);
time (&t1);
if (t1 != t0)
speed = passed / (t1 - t0);
else
speed = 0;
/* what has to be written */
if (total)
sprintf (buf1, "left %lu, %d /sec", total - passed, speed);
else {
/*(*passed) ++;*/
sprintf (buf1, "done %lu, %d /sec", passed, speed);
}
/* make indent */
indent = 79 - cursor_pos - strlen (buf1);
memset (buf2, ' ', indent);
buf2[indent] = 0;
fprintf (stderr, "%s%s", buf2, buf1);
memset (buf2, '\b', indent + strlen (buf1));
buf2 [indent + strlen (buf1)] = 0;
fprintf (stderr, "%s", buf2);
fflush (stderr);
}
static char * strs[] =
{"0%",".",".",".",".","20%",".",".",".",".","40%",".",".",".",".","60%",".",".",".",".","80%",".",".",".",".","100%"};
static char progress_to_be[1024];
static char current_progress[1024];
static void str_to_be (char * buf, int prosents)
{
int i;
prosents -= prosents % 4;
buf[0] = 0;
for (i = 0; i <= prosents / 4; i ++)
strcat (buf, strs[i]);
}
void print_how_far (unsigned long * passed, unsigned long total,
int inc, int quiet)
{
int percent;
if (*passed == 0)
current_progress[0] = 0;
(*passed) += inc;
if (*passed > total) {
fprintf (stderr, "\nprint_how_far: total %lu has been reached already. cur=%lu\n",
total, *passed);
return;
}
percent = ((*passed) * 100) / total;
str_to_be (progress_to_be, percent);
if (strlen (current_progress) != strlen (progress_to_be)) {
fprintf (stderr, "%s", progress_to_be + strlen (current_progress));
}
strcat (current_progress, progress_to_be + strlen (current_progress));
if (!quiet)
print_how_fast (*passed/* - inc*/, total, strlen (progress_to_be),
(*passed == inc) ? 1 : 0);
fflush (stderr);
}
#define ENDIANESS_NOT_DEFINED 0
#define LITTLE_ENDIAN_ARCH 1
#define BIG_ENDIAN_ARCH 2
static int endianess = ENDIANESS_NOT_DEFINED;
static void find_endianess (void)
{
__u32 x = 0x0f0d0b09;
char * s;
s = (char *)&x;
// little-endian is 1234
if (s[0] == '\11' && s[1] == '\13' && s[2] == '\15' && s[3] == '\17')
endianess = LITTLE_ENDIAN_ARCH;
// big-endian is 4321
if (s[0] == '\17' && s[1] == '\15' && s[2] == '\13' && s[3] == '\11')
die ("big-endian archs are not supported");
// nuxi/pdp-endian is 3412
if (s[0] == '\15' && s[1] == '\17' && s[2] == '\11' && s[3] == '\13')
die ("nuxi/pdp-endian archs are not supported");
}
// we used to use such function in the kernel stuff of reiserfs. Lets
// have them in utils as well
inline __u32 cpu_to_le32 (__u32 val)
{
if (endianess == ENDIANESS_NOT_DEFINED)
find_endianess ();
if (endianess == LITTLE_ENDIAN_ARCH)
return val;
die ("neither big- nor any other endian archs are supported yet ");
return ((val>>24) | ((val>>8)&0xFF00) |
((val<<8)&0xFF0000) | (val<<24));
}
inline __u32 le32_to_cpu (__u32 val)
{
return cpu_to_le32 (val);
}
inline __u16 cpu_to_le16 (__u16 val)
{
return val;
if (endianess == ENDIANESS_NOT_DEFINED)
find_endianess ();
if (endianess == LITTLE_ENDIAN_ARCH)
return val;
die ("neither big- nor pdp- endian arch are supported yet ");
return (val >> 8) | (val << 8);
}
inline __u16 le16_to_cpu (__u16 val)
{
/*printf ("%s:%u %p %p %p\n", __FILE__, __LINE__,
__builtin_return_address (0),
__builtin_return_address (1),
__builtin_return_address (2));*/
return val;
return cpu_to_le16 (val);
}
inline __u64 cpu_to_le64 (__u64 val)
{
if (endianess == ENDIANESS_NOT_DEFINED)
find_endianess ();
if (endianess == LITTLE_ENDIAN_ARCH)
return val;
die ("neither big- nor pdp- endian arch are supported yet ");
return 0;
}
inline __u64 le64_to_cpu (__u64 val)
{
return cpu_to_le64 (val);
}
/* Given a file descriptor and an offset, check whether the offset is
a valid offset for the file - return 0 if it isn't valid or 1 if it
is */
loff_t reiserfs_llseek (unsigned int fd, loff_t offset, unsigned int origin);
#if 0
static int valid_offset( int fd, loff_t offset )
{
char ch;
loff_t res;
/*res = reiserfs_llseek (fd, offset, 0);*/
res = lseek64 (fd, offset, 0);
if (res < 0)
return 0;
if (read (fd, &ch, 1) < 1)
return 0;
return 1;
}
#endif
/* calculates number of blocks on device */
unsigned long count_blocks (char * filename, int blocksize, int fd)
{
loff_t high, low;
int opened_here = 0;
if (fd < 0) {
fd = open (filename, O_RDONLY);
opened_here = 1;
}
if (fd < 0)
die ("count_blocks: open failed (%s)", strerror (errno));
#ifdef BLKGETSIZE
{
long size;
if (ioctl (fd, BLKGETSIZE, &size) >= 0) {
if (opened_here)
close (fd);
return size / (blocksize / 512);
}
}
#endif
low = 0;
for( high = 1; valid_offset (fd, high); high *= 2 )
low = high;
while (low < high - 1) {
const loff_t mid = ( low + high ) / 2;
if (valid_offset (fd, mid))
low = mid;
else
high = mid;
}
valid_offset (fd, 0);
if (opened_here)
close (fd);
return (low + 1) / (blocksize);
}