Changeset View
Changeset View
Standalone View
Standalone View
stand/libsa/ufsread.c
Show All 40 Lines | |||||
* implied warranties, including, without limitation, the implied | * implied warranties, including, without limitation, the implied | ||||
* warranties of merchantability and fitness for a particular | * warranties of merchantability and fitness for a particular | ||||
* purpose. | * purpose. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | |||||
#include <ufs/ufs/dinode.h> | #include <ufs/ufs/dinode.h> | ||||
#include <ufs/ufs/dir.h> | #include <ufs/ufs/dir.h> | ||||
#include <ufs/ffs/fs.h> | #include <ufs/ffs/fs.h> | ||||
#include "ufsread.h" | |||||
/* These routines must be provided by other code. */ | |||||
void memcpy(void *, const void *, int); | |||||
void printf(const char *, ...); | |||||
int strcmp(const char *, const char *); | |||||
int dskread(void *, unsigned, unsigned); | |||||
#ifdef UFS_SMALL_CGBASE | #ifdef UFS_SMALL_CGBASE | ||||
/* XXX: Revert to old (broken for over 1.5Tb filesystems) version of cgbase | /* XXX: Revert to old (broken for over 1.5Tb filesystems) version of cgbase | ||||
(see sys/ufs/ffs/fs.h rev 1.39) so that small boot loaders (e.g. boot2) can | (see sys/ufs/ffs/fs.h rev 1.39) so that small boot loaders (e.g. boot2) can | ||||
support both UFS1 and UFS2. */ | support both UFS1 and UFS2. */ | ||||
#undef cgbase | #undef cgbase | ||||
#define cgbase(fs, c) ((ufs2_daddr_t)((fs)->fs_fpg * (c))) | #define cgbase(fs, c) ((ufs2_daddr_t)((fs)->fs_fpg * (c))) | ||||
#endif | #endif | ||||
typedef uint32_t ufs_ino_t; | struct dmadat *dmadat; | ||||
/* | uint8_t ls, dsk_meta; | ||||
* We use 4k `virtual' blocks for filesystem data, whatever the actual | uint32_t fs_off; | ||||
* filesystem block size. FFS blocks are always a multiple of 4k. | |||||
*/ | |||||
#define VBLKSHIFT 12 | |||||
#define VBLKSIZE (1 << VBLKSHIFT) | |||||
#define VBLKMASK (VBLKSIZE - 1) | |||||
#define DBPERVBLK (VBLKSIZE / DEV_BSIZE) | |||||
#define INDIRPERVBLK(fs) (NINDIR(fs) / ((fs)->fs_bsize >> VBLKSHIFT)) | |||||
#define IPERVBLK(fs) (INOPB(fs) / ((fs)->fs_bsize >> VBLKSHIFT)) | |||||
#define INO_TO_VBA(fs, ipervblk, x) \ | |||||
(fsbtodb(fs, cgimin(fs, ino_to_cg(fs, x))) + \ | |||||
(((x) % (fs)->fs_ipg) / (ipervblk) * DBPERVBLK)) | |||||
#define INO_TO_VBO(ipervblk, x) ((x) % ipervblk) | |||||
#define FS_TO_VBA(fs, fsb, off) (fsbtodb(fs, fsb) + \ | |||||
((off) / VBLKSIZE) * DBPERVBLK) | |||||
#define FS_TO_VBO(fs, fsb, off) ((off) & VBLKMASK) | |||||
/* Buffers that must not span a 64k boundary. */ | |||||
struct dmadat { | |||||
char blkbuf[VBLKSIZE]; /* filesystem blocks */ | |||||
char indbuf[VBLKSIZE]; /* indir blocks */ | |||||
char sbbuf[SBLOCKSIZE]; /* superblock */ | |||||
char secbuf[DEV_BSIZE]; /* for MBR/disklabel */ | |||||
}; | |||||
static struct dmadat *dmadat; | |||||
static ufs_ino_t lookup(const char *); | |||||
static ssize_t fsread(ufs_ino_t, void *, size_t); | |||||
static uint8_t ls, dsk_meta; | |||||
static uint32_t fs_off; | |||||
static __inline uint8_t | static __inline uint8_t | ||||
fsfind(const char *name, ufs_ino_t * ino) | fsfind(const char *name, ufs_ino_t * ino) | ||||
{ | { | ||||
static char buf[DEV_BSIZE]; | static char buf[DEV_BSIZE]; | ||||
static struct direct d; | static struct direct d; | ||||
char *s; | char *s; | ||||
ssize_t n; | ssize_t n; | ||||
Show All 9 Lines | for (s = buf; s < buf + DEV_BSIZE;) { | ||||
} | } | ||||
s += d.d_reclen; | s += d.d_reclen; | ||||
} | } | ||||
if (n != -1 && ls) | if (n != -1 && ls) | ||||
printf("\n"); | printf("\n"); | ||||
return 0; | return 0; | ||||
} | } | ||||
static ufs_ino_t | ufs_ino_t | ||||
lookup(const char *path) | lookup(const char *path) | ||||
{ | { | ||||
static char name[UFS_MAXNAMLEN + 1]; | static char name[UFS_MAXNAMLEN + 1]; | ||||
const char *s; | const char *s; | ||||
ufs_ino_t ino; | ufs_ino_t ino; | ||||
ssize_t n; | ssize_t n; | ||||
uint8_t dt; | uint8_t dt; | ||||
Show All 29 Lines | |||||
#if defined(UFS2_ONLY) | #if defined(UFS2_ONLY) | ||||
#define DIP(field) dp2.field | #define DIP(field) dp2.field | ||||
#elif defined(UFS1_ONLY) | #elif defined(UFS1_ONLY) | ||||
#define DIP(field) dp1.field | #define DIP(field) dp1.field | ||||
#else | #else | ||||
#define DIP(field) fs.fs_magic == FS_UFS1_MAGIC ? dp1.field : dp2.field | #define DIP(field) fs.fs_magic == FS_UFS1_MAGIC ? dp1.field : dp2.field | ||||
#endif | #endif | ||||
static ssize_t | ssize_t | ||||
fsread_size(ufs_ino_t inode, void *buf, size_t nbyte, size_t *fsizep) | fsread_size(ufs_ino_t inode, void *buf, size_t nbyte, size_t *fsizep) | ||||
{ | { | ||||
#ifndef UFS2_ONLY | #ifndef UFS2_ONLY | ||||
static struct ufs1_dinode dp1; | static struct ufs1_dinode dp1; | ||||
ufs1_daddr_t addr1; | ufs1_daddr_t addr1; | ||||
#endif | #endif | ||||
#ifndef UFS1_ONLY | #ifndef UFS1_ONLY | ||||
static struct ufs2_dinode dp2; | static struct ufs2_dinode dp2; | ||||
▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
if (fsizep != NULL) | if (fsizep != NULL) | ||||
*fsizep = size; | *fsizep = size; | ||||
return nbyte; | return nbyte; | ||||
} | } | ||||
static ssize_t | ssize_t | ||||
fsread(ufs_ino_t inode, void *buf, size_t nbyte) | fsread(ufs_ino_t inode, void *buf, size_t nbyte) | ||||
{ | { | ||||
return fsread_size(inode, buf, nbyte, NULL); | return fsread_size(inode, buf, nbyte, NULL); | ||||
} | } | ||||