Imported reiserfsprogs-3.6.13

This commit is contained in:
Jeff Mahoney committed 2012-10-11 11:30:27 -04:00
1 parent cccefa4d84
commit 18057cdad6
78 files changed
+1697 -2226

No files matched your search

+1
View File
@@ -77,6 +77,7 @@ RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_RANLIB = @ac_ct_RANLIB@
+20 -55
View File
@@ -1,8 +1,9 @@
/*
* Copyright 1996-2003 by Hans Reiser, licensing governed by
* Copyright 1996-2004 by Hans Reiser, licensing governed by
* reiserfsprogs/README
*/
#define _FILE_OFFSET_BITS 64
#define _GNU_SOURCE
#include <stdio.h>
@@ -22,28 +23,25 @@
void check_memory_msg (void) {
fprintf(stderr,
"\nThe problem has occurred looks like a hardware problem (perhaps memory).\n"
"Send us the bug report only if the second run dies at the same place with\n"
"the same block number.\n");
"\nThe problem has occurred looks like a hardware problem (perhaps\n"
"memory). Send us the bug report only if the second run dies at\n"
"the same place with the same block number.\n");
}
void check_hd_msg (void) {
fprintf(stderr,
"\nThe problem has occurred looks like a hardware problem.\n"
"If you have bad blocks, we advise you to get a new hard\n"
"drive, because once you get one bad block that the disk\n"
"drive internals cannot hide from your sight, the chances\n"
"of getting more are generally said to become much higher\n"
"(precise statistics are unknown to us), and this disk drive\n"
"is probably not expensive enough for you to risk your time\n"
"and data on it. If you don't want to follow that advice,\n"
"then if you have just a few bad blocks, try writing to the\n"
"bad blocks and see if the drive remaps the bad blocks (that\n"
"means it takes a block it has in reserve and allocates it\n"
"for use for requests of that block number). If it cannot\n"
"remap the block, this could be quite bad, as it may mean\n"
"that so many blocks have gone bad that none remain in \n"
"reserve to allocate.\n");
"\nThe problem has occurred looks like a hardware problem. If you have\n"
"bad blocks, we advise you to get a new hard drive, because once you\n"
"get one bad block that the disk drive internals cannot hide from\n"
"your sight,the chances of getting more are generally said to become\n"
"much higher (precise statistics are unknown to us), and this disk\n"
"drive is probably not expensive enough for you to you to risk your\n"
"time and data on it. If you don't want to follow that follow that\n"
"advice then if you have just a few bad blocks, try writing to the\n"
"bad blocks and see if the drive remaps the bad blocks (that means\n"
"it takes a block it has in reserve and allocates it for use for\n"
"of that block number). If it cannot remap the block, use badblock\n"
"option (-B) with reiserfs utils to handle this block correctly.\n");
}
static int is_bad_block (unsigned long block)
@@ -514,7 +512,7 @@ struct buffer_head * bread (int dev, unsigned long block, size_t size)
ret = f_read(bh);
if (ret > 0)
die ("%s: End of file, cannot read the block (%lu).\n", __FUNCTION__, bh->b_blocknr);
die ("%s: End of file, cannot read the block (%lu).\n", __FUNCTION__, block);
else if (ret < 0) {
/* BAD BLOCK LIST SUPPORT
* die ("%s: Cannot read a block # %lu. Specify list of badblocks\n",*/
@@ -522,10 +520,10 @@ struct buffer_head * bread (int dev, unsigned long block, size_t size)
if (errno == EIO) {
check_hd_msg();
die ("%s: Cannot read the block (%lu): (%s).\n", __FUNCTION__,
bh->b_blocknr, strerror(errno));
block, strerror(errno));
} else {
fprintf (stderr, "%s: Cannot read the block (%lu): (%s).\n", __FUNCTION__,
bh->b_blocknr, strerror(errno));
block, strerror(errno));
return NULL;
}
}
@@ -534,26 +532,6 @@ struct buffer_head * bread (int dev, unsigned long block, size_t size)
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, SEEK_SET);
if (res < 0)
return 0;
/* if (read (fd, &ch, 1) < 0) does not wirk on files */
if (read (fd, &ch, 1) < 1)
return 0;
return 1;
}
#define ROLLBACK_FILE_START_MAGIC "_RollBackFileForReiserfsFSCK"
static struct block_handler * rollback_blocks_array;
@@ -986,16 +964,3 @@ void invalidate_buffers (int dev)
_invalidate_buffer_list(Buffer_list_head, dev) ;
_invalidate_buffer_list(g_free_buffers, dev) ;
}
int user_confirmed (FILE * fp, char * q, char * yes)
{
char * answer = 0;
size_t n = 0;
fprintf (fp, "%s", q);
if (getline (&answer, &n, stdin) != (ssize_t)strlen (yes) || strcmp (yes, answer))
return 0;
return 1;
}
+227 -258
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1996-2003 by Hans Reiser, licensing governed by
* Copyright 1996-2004 by Hans Reiser, licensing governed by
* reiserfsprogs/README
*/
@@ -16,29 +16,34 @@
#include <stdlib.h>
#include <mntent.h>
#include <sys/vfs.h>
#include <fcntl.h>
#include <time.h>
#include <utime.h>
#include <ctype.h>
#include <linux/hdreg.h>
#include <dirent.h>
#include <assert.h>
#include <asm/ioctl.h>
#include <unistd.h>
#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
# define BLKGETSIZE64 _IOR(0x12, 114, sizeof(__u64))
#endif
#include "swab.h"
#include "io.h"
#include "misc.h"
/* Debian modifications by Ed Boraas <ed@debian.org> */
#include <sys/mount.h>
/* End Debian mods */
#define STAT_FIELD(Field, Type) \
inline Type misc_device_##Field(char *device) { \
struct stat st; \
\
if (stat(device, &st) == 0) \
return st.st_##Field; \
\
fprintf(stderr, "Stat of the device '%s' failed.", device); \
exit(8); \
}
STAT_FIELD(mode, mode_t);
STAT_FIELD(rdev, dev_t);
STAT_FIELD(size, off64_t);
STAT_FIELD(blocks, blkcnt64_t);
void die (char * fmt, ...)
{
@@ -173,144 +178,174 @@ void freemem (void * vp)
typedef int (*func_t) (char *);
static int is_readonly_dir (char * dir)
/* Lookup the @file in the @mntfile. @file is mntent.mnt_fsname if @fsname
is set; mntent.mnt_dir otherwise. Return the mnt entry from the @mntfile.
Warning: if the root fs is mounted RO, the content of /etc/mtab may be
not correct. */
static struct mntent *misc_mntent_lookup(char *mntfile,
char *file,
int fsname)
{
/*
int fd;
char template [1024];
struct mntent *mnt;
struct stat st;
dev_t rdev = 0;
dev_t dev = 0;
ino_t ino = 0;
FILE *fp;
snprintf (template, 1024, "%s/testXXXXXX", dir);
fd = mkstemp (template);
if (fd >= 0) {
close (fd);
return 0;
}
*/
if (utime (dir, 0) != -1)
/* this is not ro mounted fs */
return 0;
return (errno == EROFS) ? 1 : 0;
}
assert(mntfile != NULL);
assert(file != NULL);
#ifdef __i386__
#include <unistd.h>
#include <linux/unistd.h>
#define __NR_bad_stat64 195
_syscall2(long, bad_stat64, char *, filename, struct stat64 *, statbuf);
#else
#define bad_stat64 stat64
#endif
/* yes, I know how ugly it is */
#define return_stat_field(field) \
struct stat st;\
struct stat64 st64;\
\
if (bad_stat64 (file_name, &st64) == 0) {\
return st64.st_##field;\
} else if (stat (file_name, &st) == 0)\
return st.st_##field;\
\
perror ("stat failed");\
exit (8);\
mode_t get_st_mode (char * file_name)
{
return_stat_field (mode);
}
/* may I look at this undocumented (at least in the info of libc 2.3.1-58)
field? */
dev_t get_st_rdev (char * file_name)
{
return_stat_field (rdev);
}
off64_t get_st_size (char * file_name)
{
return_stat_field (size);
}
blkcnt64_t get_st_blocks (char * file_name)
{
return_stat_field (blocks);
}
static int _is_mounted (char * device_name, func_t f)
{
int retval;
FILE *fp;
struct mntent *mnt;
struct statfs stfs;
struct stat root_st;
mode_t mode;
if (stat ("/", &root_st) == -1)
die ("is_mounted: could not stat \"/\": %s\n", strerror(errno));
mode = get_st_mode (device_name);
if (S_ISREG (mode))
/* regular file can not be mounted */
return 0;
if (!S_ISBLK (mode))
die ("is_mounted: %s is neither regular file nor block device", device_name);
if (root_st.st_dev == get_st_rdev (device_name)) {
/* device is mounted as root. Check whether it is mounted read-only */
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 (stderr,
" (could not figure out) Is filesystem mounted read-only? (Yes)",
"Yes\n"));
else
return (user_confirmed (stderr,
" (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/*mounted*/);
break;
if (fsname && stat(file, &st) == 0) {
/* Devices is stated. */
if (S_ISBLK(st.st_mode)) {
rdev = st.st_rdev;
} else {
dev = st.st_dev;
ino = st.st_ino;
}
}
endmntent (fp);
return retval;
if ((fp = setmntent(mntfile, "r")) == NULL)
return INVAL_PTR;
while ((mnt = getmntent(fp)) != NULL) {
/* Check if names match. */
if (fsname) {
if (strcmp(file, mnt->mnt_fsname) == 0)
break;
} else {
if (strcmp(file, mnt->mnt_dir) == 0)
break;
continue;
}
/* Check if stats match. */
if (stat(mnt->mnt_fsname, &st) == 0) {
if (rdev && S_ISBLK(st.st_mode)) {
if (rdev == st.st_rdev)
break;
} else {
if (dev == st.st_dev &&
ino == st.st_ino)
break;
}
}
}
endmntent (fp);
return mnt;
}
static int misc_root_mounted(char *device) {
struct stat rootst, devst;
assert(device != NULL);
int is_mounted_read_only (char * device_name)
{
return _is_mounted (device_name, is_readonly_dir);
if (stat("/", &rootst) != 0)
return -1;
if (stat(device, &devst) != 0)
return -1;
if (!S_ISBLK(devst.st_mode) ||
devst.st_rdev != rootst.st_dev)
return 0;
return 1;
}
static int misc_file_ro(char *file) {
if (utime(file, 0) == -1) {
if (errno == EROFS)
return 1;
}
int is_mounted (char * device_name)
{
return _is_mounted (device_name, 0);
return 0;
}
struct mntent *misc_mntent(char *device) {
int proc = 0, path = 0, root = 0;
struct mntent *mnt;
struct statfs stfs;
assert(device != NULL);
/* Check if the root. */
if (misc_root_mounted(device) == 1)
root = 1;
#ifdef __linux__
/* Check if /proc is procfs. */
if (statfs("/proc", &stfs) == 0 && stfs.f_type == 0x9fa0) {
proc = 1;
if (root) {
/* Lookup the "/" entry in /proc/mounts. Special
case as root entry can present as:
rootfs / rootfs rw 0 0
Look up the mount point in this case. */
mnt = misc_mntent_lookup("/proc/mounts", "/", 0);
} else {
/* Lookup the @device /proc/mounts */
mnt = misc_mntent_lookup("/proc/mounts", device, 1);
}
if (mnt == INVAL_PTR)
proc = 0;
else if (mnt)
return mnt;
}
#endif /* __linux__ */
#if defined(MOUNTED) || defined(_PATH_MOUNTED)
#ifndef MOUNTED
#define MOUNTED _PATH_MOUNTED
#endif
/* Check in MOUNTED (/etc/mtab) if RW. */
if (!misc_file_ro(MOUNTED)) {
path = 1;
if (root) {
mnt = misc_mntent_lookup(MOUNTED, "/", 0);
} else {
mnt = misc_mntent_lookup(MOUNTED, device, 1);
}
if (mnt == INVAL_PTR)
path = 0;
else if (mnt)
return mnt;
}
#endif /* defined(MOUNTED) || defined(_PATH_MOUNTED) */
/* If has not been checked in neither /proc/mounts nor /etc/mtab (or
errors have occured), return INVAL_PTR, NULL otherwise. */
return (!proc && !path) ? INVAL_PTR : NULL;
}
int misc_device_mounted(char *device) {
struct mntent *mnt;
/* Check for the "/" first to avoid any possible problem with
reflecting the root fs info in mtab files. */
if (misc_root_mounted(device) == 1) {
return misc_file_ro("/") ? MF_RO : MF_RW;
}
/* Lookup the mount entry. */
if ((mnt = misc_mntent(device)) == NULL) {
return MF_NOT_MOUNTED;
} else if (mnt == INVAL_PTR) {
return 0;
}
return hasmntopt(mnt, MNTOPT_RO) ? MF_RO : MF_RW;
}
char buf1 [100];
char buf2 [100];
@@ -407,19 +442,42 @@ void print_how_far (FILE * fp,
fflush (fp);
}
#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
# define BLKGETSIZE64 _IOR(0x12, 114, __u64)
#endif
/* To not have problem with last sectors on the block device when switching
to smaller one. */
#define MAX_BS (64 * 1024)
int valid_offset( int fd, loff_t offset) {
char ch;
loff_t res;
/*res = reiserfs_llseek (fd, offset, 0);*/
res = lseek64 (fd, offset, SEEK_SET);
if (res < 0)
return 0;
/* if (read (fd, &ch, 1) < 0) does not wirk on files */
if (read (fd, &ch, 1) < 1)
return 0;
return 1;
}
/* calculates number of blocks in a file. Returns 0 for "sparse"
regular files and files other than regular files and block devices */
unsigned long count_blocks (char * filename, int blocksize)
{
loff_t high, low;
int fd;
unsigned long sz;
__u64 size;
int fd;
if (!S_ISBLK (get_st_mode (filename)) && !S_ISREG (get_st_mode (filename)))
if (!S_ISBLK(misc_device_mode(filename)) &&
!S_ISREG(misc_device_mode(filename)))
return 0;
fd = open (filename, O_RDONLY);
@@ -429,10 +487,12 @@ unsigned long count_blocks (char * filename, int blocksize)
#ifdef BLKGETSIZE64
{
if (ioctl (fd, BLKGETSIZE64, &size) >= 0) {
size = (size / 4096) * 4096 / blocksize;
size = (size / MAX_BS) * MAX_BS / blocksize;
sz = size;
if ((__u64)sz != size)
die ("count_blocks: block device too large");
close(fd);
return sz;
}
}
@@ -443,7 +503,9 @@ unsigned long count_blocks (char * filename, int blocksize)
{
if (ioctl (fd, BLKGETSIZE, &sz) >= 0) {
size = sz;
return (size * 512 / 4096) * 4096 / blocksize;
close(fd);
return (size * 512 / MAX_BS) * MAX_BS / blocksize;
}
}
#endif
@@ -459,15 +521,13 @@ unsigned long count_blocks (char * filename, int blocksize)
else
high = mid;
}
valid_offset (fd, 0);
close (fd);
return (low + 1) * 4096 / 4096 / blocksize ;
return (low + 1) * MAX_BS / MAX_BS / blocksize;
}
/* there are masks for certain bits */
__u16 mask16 (int from, int count)
{
@@ -570,27 +630,6 @@ int blockdev_list_compare (const void * block1, const void * block2) {
return 0;
}
/* return -1 if smth found, otherwise return position which new item should be inserted into */
/*
int blocklist__is_block_saved (struct block_handler ** base, __u32 * count,
__u32 blocknr, dev_t device, __u32 * position) {
struct block_handler block_h;
*position = 0;
if (*base == NULL)
return 0;
block_h.blocknr = blocknr;
block_h.device = device;
if (reiserfs_bin_search (&block_h, *base, *count, sizeof (block_h),
position, blocklist_compare) == POSITION_FOUND)
return 1;
return 0;
}
*/
void blocklist__insert_in_position (void *elem, void **base, __u32 *count,
int elem_size, __u32 *position)
{
@@ -614,93 +653,6 @@ void blocklist__insert_in_position (void *elem, void **base, __u32 *count,
*count+=1;
}
static int get_random_bytes (void *out, int size) {
int fd;
if ((fd = open("/dev/urandom", O_RDONLY)) == -1)
return 1;
if (read(fd, out, size) <= 0) {
close (fd);
return 1;
}
close (fd);
return 0;
}
int generate_random_uuid (unsigned char * uuid)
{
if (get_random_bytes(uuid, 16)) {
return -1;
}
/* Set the UUID variant to DCE */
uuid[8] = (uuid[8] & 0x3F) | 0x80;
/* Set UUID version to 4 --- truely random generation */
uuid[6] = (uuid[6] & 0x0F) | 0x40;
return 0;
}
int uuid_is_correct (unsigned char * uuid)
{
int i;
for (i = 0; i < 16; i++)
if (uuid[i])
break;
if (i == 16)
return 0;
if (!misc_test_bit(7, &uuid[8]) || misc_test_bit(6, &uuid[8]))
return 0;
if (misc_test_bit(7, &uuid[6]) || !misc_test_bit(6, &uuid[6]) ||
misc_test_bit(5, &uuid[6]) || misc_test_bit(4, &uuid[6]))
return 0;
return 1;
}
static int parse_uuid (const unsigned char * in, unsigned char * uuid)
{
int i, j = 0;
unsigned char frame[3];
if (strlen(in) != 36)
return -1;
for (i = 0; i < 36; i++) {
if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) {
if (in[i] != '-')
return 0;
} else if (!isxdigit(in[i])) {
return -1;
}
}
frame[2] = 0;
for (i = 0; i < 36; i ++) {
if ((i == 8) || (i == 13) || (i == 18) || (i == 23))
continue;
frame[0] = in[i++];
frame[1] = in[i];
uuid[j++] = strtoul(frame, NULL, 16);
}
return 0;
}
int set_uuid (const unsigned char * text, unsigned char * UUID)
{
if (parse_uuid (text, UUID) || !uuid_is_correct(UUID))
return -1;
return 0;
}
/* 0 - dma is not supported, scsi or regular file */
/* 1 - xt drive */
/* 2 - ide drive */
@@ -971,13 +923,30 @@ inline unsigned long long misc_find_next_set_bit(const void *vaddr,
/* Reads the "CREDITS" file and prints one paragraph from it. */
void misc_print_credit(FILE *out) {
char *line;
__u32 num1, num2;
fprintf(out, "\nA pair of credits:\n");
fprintf(out, "A pair of credits:\n");
line = credits[(random() % CREDITS_COUNT)];
fprintf(out, "%s", line);
srandom (time (0));
line = credits[(random() % CREDITS_COUNT)];
fprintf(out, "%s", line);
num1 = random() % CREDITS_COUNT;
line = credits[num1];
fprintf(out, "%s\n", line);
while ((num1 == (num2 = random() % CREDITS_COUNT))) {}
line = credits[num2];
fprintf(out, "%s\n", line);
}
int user_confirmed (FILE * fp, char * q, char * yes) {
char * answer = 0;
size_t n = 0;
fprintf (fp, "%s", q);
if (getline (&answer, &n, stdin) != (ssize_t)strlen (yes) || strcmp (yes, answer))
return 0;
return 1;
}