Fsutil: sources reformatted to 4-space indents.
This commit is contained in:
@@ -28,29 +28,29 @@ extern int verbose;
|
|||||||
|
|
||||||
int fs_read_block (fs_t *fs, unsigned bnum, unsigned char *data)
|
int fs_read_block (fs_t *fs, unsigned bnum, unsigned char *data)
|
||||||
{
|
{
|
||||||
if (verbose > 3)
|
if (verbose > 3)
|
||||||
printf ("read block %d\n", bnum);
|
printf ("read block %d\n", bnum);
|
||||||
if (bnum < fs->isize)
|
if (bnum < fs->isize)
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_seek (fs, bnum * BSDFS_BSIZE))
|
if (! fs_seek (fs, bnum * BSDFS_BSIZE))
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_read (fs, data, BSDFS_BSIZE))
|
if (! fs_read (fs, data, BSDFS_BSIZE))
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_write_block (fs_t *fs, unsigned bnum, unsigned char *data)
|
int fs_write_block (fs_t *fs, unsigned bnum, unsigned char *data)
|
||||||
{
|
{
|
||||||
if (verbose > 3)
|
if (verbose > 3)
|
||||||
printf ("write block %d\n", bnum);
|
printf ("write block %d\n", bnum);
|
||||||
if (! fs->writable || bnum < fs->isize)
|
if (! fs->writable || bnum < fs->isize)
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_seek (fs, bnum * BSDFS_BSIZE))
|
if (! fs_seek (fs, bnum * BSDFS_BSIZE))
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write (fs, data, BSDFS_BSIZE))
|
if (! fs_write (fs, data, BSDFS_BSIZE))
|
||||||
return 0;
|
return 0;
|
||||||
fs->modified = 1;
|
fs->modified = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -58,27 +58,27 @@ int fs_write_block (fs_t *fs, unsigned bnum, unsigned char *data)
|
|||||||
*/
|
*/
|
||||||
int fs_block_free (fs_t *fs, unsigned int bno)
|
int fs_block_free (fs_t *fs, unsigned int bno)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned buf [BSDFS_BSIZE / 4];
|
unsigned buf [BSDFS_BSIZE / 4];
|
||||||
|
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
printf ("free block %d, total %d\n", bno, fs->nfree);
|
printf ("free block %d, total %d\n", bno, fs->nfree);
|
||||||
if (fs->nfree >= NICFREE) {
|
if (fs->nfree >= NICFREE) {
|
||||||
buf[0] = fs->nfree;
|
buf[0] = fs->nfree;
|
||||||
for (i=0; i<NICFREE; i++)
|
for (i=0; i<NICFREE; i++)
|
||||||
buf[i+1] = fs->free[i];
|
buf[i+1] = fs->free[i];
|
||||||
if (! fs_write_block (fs, bno, (unsigned char*) buf)) {
|
if (! fs_write_block (fs, bno, (unsigned char*) buf)) {
|
||||||
fprintf (stderr, "block_free: write error at block %d\n", bno);
|
fprintf (stderr, "block_free: write error at block %d\n", bno);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fs->nfree = 0;
|
fs->nfree = 0;
|
||||||
}
|
}
|
||||||
fs->free [fs->nfree] = bno;
|
fs->free [fs->nfree] = bno;
|
||||||
fs->nfree++;
|
fs->nfree++;
|
||||||
fs->dirty = 1;
|
fs->dirty = 1;
|
||||||
if (bno) /* Count total free blocks. */
|
if (bno) /* Count total free blocks. */
|
||||||
++fs->tfree;
|
++fs->tfree;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -86,26 +86,26 @@ int fs_block_free (fs_t *fs, unsigned int bno)
|
|||||||
*/
|
*/
|
||||||
int fs_indirect_block_free (fs_t *fs, unsigned int bno, int nblk)
|
int fs_indirect_block_free (fs_t *fs, unsigned int bno, int nblk)
|
||||||
{
|
{
|
||||||
unsigned nb;
|
unsigned nb;
|
||||||
unsigned char data [BSDFS_BSIZE];
|
unsigned char data [BSDFS_BSIZE];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (! fs_read_block (fs, bno, data)) {
|
if (! fs_read_block (fs, bno, data)) {
|
||||||
fprintf (stderr, "inode_clear: read error at block %d\n", bno);
|
fprintf (stderr, "inode_clear: read error at block %d\n", bno);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for (i=BSDFS_BSIZE-4; i>=0; i-=4) {
|
for (i=BSDFS_BSIZE-4; i>=0; i-=4) {
|
||||||
if (i/4 < nblk) {
|
if (i/4 < nblk) {
|
||||||
/* Truncate up to required size. */
|
/* Truncate up to required size. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
nb = data [i+3] << 24 | data [i+2] << 16 |
|
nb = data [i+3] << 24 | data [i+2] << 16 |
|
||||||
data [i+1] << 8 | data [i];
|
data [i+1] << 8 | data [i];
|
||||||
if (nb)
|
if (nb)
|
||||||
fs_block_free (fs, nb);
|
fs_block_free (fs, nb);
|
||||||
}
|
}
|
||||||
fs_block_free (fs, bno);
|
fs_block_free (fs, bno);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -113,27 +113,27 @@ int fs_indirect_block_free (fs_t *fs, unsigned int bno, int nblk)
|
|||||||
*/
|
*/
|
||||||
int fs_double_indirect_block_free (fs_t *fs, unsigned int bno, int nblk)
|
int fs_double_indirect_block_free (fs_t *fs, unsigned int bno, int nblk)
|
||||||
{
|
{
|
||||||
unsigned nb;
|
unsigned nb;
|
||||||
unsigned char data [BSDFS_BSIZE];
|
unsigned char data [BSDFS_BSIZE];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (! fs_read_block (fs, bno, data)) {
|
if (! fs_read_block (fs, bno, data)) {
|
||||||
fprintf (stderr, "inode_clear: read error at block %d\n", bno);
|
fprintf (stderr, "inode_clear: read error at block %d\n", bno);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for (i=BSDFS_BSIZE-4; i>=0; i-=4) {
|
for (i=BSDFS_BSIZE-4; i>=0; i-=4) {
|
||||||
if (i/4 * BSDFS_BSIZE/4 < nblk) {
|
if (i/4 * BSDFS_BSIZE/4 < nblk) {
|
||||||
/* Truncate up to required size. */
|
/* Truncate up to required size. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
nb = data [i+3] << 24 | data [i+2] << 16 |
|
nb = data [i+3] << 24 | data [i+2] << 16 |
|
||||||
data [i+1] << 8 | data [i];
|
data [i+1] << 8 | data [i];
|
||||||
if (nb)
|
if (nb)
|
||||||
fs_indirect_block_free (fs, nb,
|
fs_indirect_block_free (fs, nb,
|
||||||
nblk - i/4 * BSDFS_BSIZE/4);
|
nblk - i/4 * BSDFS_BSIZE/4);
|
||||||
}
|
}
|
||||||
fs_block_free (fs, bno);
|
fs_block_free (fs, bno);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -141,27 +141,27 @@ int fs_double_indirect_block_free (fs_t *fs, unsigned int bno, int nblk)
|
|||||||
*/
|
*/
|
||||||
int fs_triple_indirect_block_free (fs_t *fs, unsigned int bno, int nblk)
|
int fs_triple_indirect_block_free (fs_t *fs, unsigned int bno, int nblk)
|
||||||
{
|
{
|
||||||
unsigned nb;
|
unsigned nb;
|
||||||
unsigned char data [BSDFS_BSIZE];
|
unsigned char data [BSDFS_BSIZE];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (! fs_read_block (fs, bno, data)) {
|
if (! fs_read_block (fs, bno, data)) {
|
||||||
fprintf (stderr, "inode_clear: read error at block %d\n", bno);
|
fprintf (stderr, "inode_clear: read error at block %d\n", bno);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for (i=BSDFS_BSIZE-4; i>=0; i-=4) {
|
for (i=BSDFS_BSIZE-4; i>=0; i-=4) {
|
||||||
if (i/4 * BSDFS_BSIZE/4 * BSDFS_BSIZE/4 < nblk) {
|
if (i/4 * BSDFS_BSIZE/4 * BSDFS_BSIZE/4 < nblk) {
|
||||||
/* Truncate up to required size. */
|
/* Truncate up to required size. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
nb = data [i+3] << 24 | data [i+2] << 16 |
|
nb = data [i+3] << 24 | data [i+2] << 16 |
|
||||||
data [i+1] << 8 | data [i];
|
data [i+1] << 8 | data [i];
|
||||||
if (nb)
|
if (nb)
|
||||||
fs_double_indirect_block_free (fs, nb,
|
fs_double_indirect_block_free (fs, nb,
|
||||||
nblk - i/4 * BSDFS_BSIZE/4 * BSDFS_BSIZE/4);
|
nblk - i/4 * BSDFS_BSIZE/4 * BSDFS_BSIZE/4);
|
||||||
}
|
}
|
||||||
fs_block_free (fs, bno);
|
fs_block_free (fs, bno);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -169,26 +169,26 @@ int fs_triple_indirect_block_free (fs_t *fs, unsigned int bno, int nblk)
|
|||||||
*/
|
*/
|
||||||
int fs_block_alloc (fs_t *fs, unsigned int *bno)
|
int fs_block_alloc (fs_t *fs, unsigned int *bno)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned buf [BSDFS_BSIZE / 4];
|
unsigned buf [BSDFS_BSIZE / 4];
|
||||||
again:
|
again:
|
||||||
if (fs->nfree == 0)
|
if (fs->nfree == 0)
|
||||||
return 0;
|
return 0;
|
||||||
fs->nfree--;
|
fs->nfree--;
|
||||||
--fs->tfree; /* Count total free blocks. */
|
--fs->tfree; /* Count total free blocks. */
|
||||||
*bno = fs->free [fs->nfree];
|
*bno = fs->free [fs->nfree];
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf ("allocate new block %d from slot %d\n", *bno, fs->nfree);
|
printf ("allocate new block %d from slot %d\n", *bno, fs->nfree);
|
||||||
fs->free [fs->nfree] = 0;
|
fs->free [fs->nfree] = 0;
|
||||||
fs->dirty = 1;
|
fs->dirty = 1;
|
||||||
if (fs->nfree <= 0) {
|
if (fs->nfree <= 0) {
|
||||||
if (! fs_read_block (fs, *bno, (unsigned char*) buf))
|
if (! fs_read_block (fs, *bno, (unsigned char*) buf))
|
||||||
return 0;
|
return 0;
|
||||||
fs->nfree = buf[0];
|
fs->nfree = buf[0];
|
||||||
for (i=0; i<NICFREE; i++)
|
for (i=0; i<NICFREE; i++)
|
||||||
fs->free[i] = buf[i+1];
|
fs->free[i] = buf[i+1];
|
||||||
}
|
}
|
||||||
if (*bno == 0)
|
if (*bno == 0)
|
||||||
goto again;
|
goto again;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,135 +21,135 @@
|
|||||||
* arising out of or in connection with the use or performance of
|
* arising out of or in connection with the use or performance of
|
||||||
* this software.
|
* this software.
|
||||||
*/
|
*/
|
||||||
#define BSDFS_BSIZE 1024 /* block size */
|
#define BSDFS_BSIZE 1024 /* block size */
|
||||||
#define BSDFS_ROOT_INODE 2 /* root directory in inode 2 */
|
#define BSDFS_ROOT_INODE 2 /* root directory in inode 2 */
|
||||||
#define BSDFS_LOSTFOUND_INODE 3 /* lost+found directory in inode 3 */
|
#define BSDFS_LOSTFOUND_INODE 3 /* lost+found directory in inode 3 */
|
||||||
#define BSDFS_SWAP_INODE 4 /* swap file in inode 4 */
|
#define BSDFS_SWAP_INODE 4 /* swap file in inode 4 */
|
||||||
#define BSDFS_INODES_PER_BLOCK 16 /* inodes per block */
|
#define BSDFS_INODES_PER_BLOCK 16 /* inodes per block */
|
||||||
|
|
||||||
#define NICINOD 32 /* number of superblock inodes */
|
#define NICINOD 32 /* number of superblock inodes */
|
||||||
#define NICFREE 200 /* number of superblock free blocks */
|
#define NICFREE 200 /* number of superblock free blocks */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 28 of the di_addr address bytes are used; 7 addresses of 4
|
* 28 of the di_addr address bytes are used; 7 addresses of 4
|
||||||
* bytes each: 4 direct (4Kb directly accessible) and 3 indirect.
|
* bytes each: 4 direct (4Kb directly accessible) and 3 indirect.
|
||||||
*/
|
*/
|
||||||
#define NDADDR 4 /* direct addresses in inode */
|
#define NDADDR 4 /* direct addresses in inode */
|
||||||
#define NIADDR 3 /* indirect addresses in inode */
|
#define NIADDR 3 /* indirect addresses in inode */
|
||||||
#define NADDR (NDADDR + NIADDR) /* total addresses in inode */
|
#define NADDR (NDADDR + NIADDR) /* total addresses in inode */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NINDIR is the number of indirects in a file system block.
|
* NINDIR is the number of indirects in a file system block.
|
||||||
*/
|
*/
|
||||||
#define NINDIR (DEV_BSIZE / sizeof(daddr_t))
|
#define NINDIR (DEV_BSIZE / sizeof(daddr_t))
|
||||||
#define NSHIFT 8 /* log2(NINDIR) */
|
#define NSHIFT 8 /* log2(NINDIR) */
|
||||||
#define NMASK 0377L /* NINDIR - 1 */
|
#define NMASK 0377L /* NINDIR - 1 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The path name on which the file system is mounted is maintained
|
* The path name on which the file system is mounted is maintained
|
||||||
* in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in
|
* in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in
|
||||||
* the super block for this name.
|
* the super block for this name.
|
||||||
*/
|
*/
|
||||||
#define MAXMNTLEN 28
|
#define MAXMNTLEN 28
|
||||||
|
|
||||||
#define FSMAGIC1 ('F' | 'S'<<8 | '<'<<16 | '<'<<24)
|
#define FSMAGIC1 ('F' | 'S'<<8 | '<'<<16 | '<'<<24)
|
||||||
#define FSMAGIC2 ('>' | '>'<<8 | 'F'<<16 | 'S'<<24)
|
#define FSMAGIC2 ('>' | '>'<<8 | 'F'<<16 | 'S'<<24)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *filename;
|
const char *filename;
|
||||||
int fd;
|
int fd;
|
||||||
unsigned long seek;
|
unsigned long seek;
|
||||||
int writable;
|
int writable;
|
||||||
int dirty; /* sync needed */
|
int dirty; /* sync needed */
|
||||||
int modified; /* write_block was called */
|
int modified; /* write_block was called */
|
||||||
|
|
||||||
unsigned isize; /* size in blocks of superblock + I list */
|
unsigned isize; /* size in blocks of superblock + I list */
|
||||||
unsigned fsize; /* size in blocks of entire volume */
|
unsigned fsize; /* size in blocks of entire volume */
|
||||||
unsigned swapsz; /* size in blocks of swap area */
|
unsigned swapsz; /* size in blocks of swap area */
|
||||||
unsigned nfree; /* number of in core free blocks (0-100) */
|
unsigned nfree; /* number of in core free blocks (0-100) */
|
||||||
unsigned free [NICFREE]; /* in core free blocks */
|
unsigned free [NICFREE]; /* in core free blocks */
|
||||||
unsigned ninode; /* number of in core I nodes (0-100) */
|
unsigned ninode; /* number of in core I nodes (0-100) */
|
||||||
unsigned inode [NICINOD]; /* in core free I nodes */
|
unsigned inode [NICINOD]; /* in core free I nodes */
|
||||||
unsigned flock; /* lock during free list manipulation */
|
unsigned flock; /* lock during free list manipulation */
|
||||||
unsigned ilock; /* lock during I list manipulation */
|
unsigned ilock; /* lock during I list manipulation */
|
||||||
unsigned fmod; /* super block modified flag */
|
unsigned fmod; /* super block modified flag */
|
||||||
unsigned ronly; /* mounted read-only flag */
|
unsigned ronly; /* mounted read-only flag */
|
||||||
long utime; /* current date of last update */
|
long utime; /* current date of last update */
|
||||||
unsigned tfree; /* total free blocks */
|
unsigned tfree; /* total free blocks */
|
||||||
unsigned tinode; /* total free inodes */
|
unsigned tinode; /* total free inodes */
|
||||||
char fsmnt [MAXMNTLEN]; /* ordinary file mounted on */
|
char fsmnt [MAXMNTLEN]; /* ordinary file mounted on */
|
||||||
unsigned lasti; /* start place for circular search */
|
unsigned lasti; /* start place for circular search */
|
||||||
unsigned nbehind; /* est # free inodes before s_lasti */
|
unsigned nbehind; /* est # free inodes before s_lasti */
|
||||||
unsigned flags; /* mount time flags */
|
unsigned flags; /* mount time flags */
|
||||||
} fs_t;
|
} fs_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
fs_t *fs;
|
fs_t *fs;
|
||||||
unsigned number;
|
unsigned number;
|
||||||
int dirty; /* save needed */
|
int dirty; /* save needed */
|
||||||
|
|
||||||
unsigned short mode; /* file type and access mode */
|
unsigned short mode; /* file type and access mode */
|
||||||
#define INODE_MODE_FMT 0170000 /* type of file */
|
#define INODE_MODE_FMT 0170000 /* type of file */
|
||||||
#define INODE_MODE_FCHR 020000 /* character special */
|
#define INODE_MODE_FCHR 020000 /* character special */
|
||||||
#define INODE_MODE_FDIR 040000 /* directory */
|
#define INODE_MODE_FDIR 040000 /* directory */
|
||||||
#define INODE_MODE_FBLK 060000 /* block special */
|
#define INODE_MODE_FBLK 060000 /* block special */
|
||||||
#define INODE_MODE_FREG 0100000 /* regular */
|
#define INODE_MODE_FREG 0100000 /* regular */
|
||||||
#define INODE_MODE_FLNK 0120000 /* symbolic link */
|
#define INODE_MODE_FLNK 0120000 /* symbolic link */
|
||||||
#define INODE_MODE_FSOCK 0140000 /* socket */
|
#define INODE_MODE_FSOCK 0140000 /* socket */
|
||||||
#define INODE_MODE_SUID 04000 /* set user id on execution */
|
#define INODE_MODE_SUID 04000 /* set user id on execution */
|
||||||
#define INODE_MODE_SGID 02000 /* set group id on execution */
|
#define INODE_MODE_SGID 02000 /* set group id on execution */
|
||||||
#define INODE_MODE_SVTX 01000 /* save swapped text even after use */
|
#define INODE_MODE_SVTX 01000 /* save swapped text even after use */
|
||||||
#define INODE_MODE_READ 0400 /* read, write, execute permissions */
|
#define INODE_MODE_READ 0400 /* read, write, execute permissions */
|
||||||
#define INODE_MODE_WRITE 0200
|
#define INODE_MODE_WRITE 0200
|
||||||
#define INODE_MODE_EXEC 0100
|
#define INODE_MODE_EXEC 0100
|
||||||
|
|
||||||
unsigned short nlink; /* directory entries */
|
unsigned short nlink; /* directory entries */
|
||||||
unsigned uid; /* owner */
|
unsigned uid; /* owner */
|
||||||
unsigned gid; /* group */
|
unsigned gid; /* group */
|
||||||
unsigned long size; /* size */
|
unsigned long size; /* size */
|
||||||
unsigned addr [7]; /* device addresses constituting file */
|
unsigned addr [7]; /* device addresses constituting file */
|
||||||
unsigned flags; /* user defined flags */
|
unsigned flags; /* user defined flags */
|
||||||
/*
|
/*
|
||||||
* Super-user and owner changeable flags.
|
* Super-user and owner changeable flags.
|
||||||
*/
|
*/
|
||||||
#define USER_SETTABLE 0x00ff /* mask of owner changeable flags */
|
#define USER_SETTABLE 0x00ff /* mask of owner changeable flags */
|
||||||
#define USER_NODUMP 0x0001 /* do not dump file */
|
#define USER_NODUMP 0x0001 /* do not dump file */
|
||||||
#define USER_IMMUTABLE 0x0002 /* file may not be changed */
|
#define USER_IMMUTABLE 0x0002 /* file may not be changed */
|
||||||
#define USER_APPEND 0x0004 /* writes to file may only append */
|
#define USER_APPEND 0x0004 /* writes to file may only append */
|
||||||
/*
|
/*
|
||||||
* Super-user changeable flags.
|
* Super-user changeable flags.
|
||||||
*/
|
*/
|
||||||
#define SYS_SETTABLE 0xff00 /* mask of superuser changeable flags */
|
#define SYS_SETTABLE 0xff00 /* mask of superuser changeable flags */
|
||||||
#define SYS_ARCHIVED 0x0100 /* file is archived */
|
#define SYS_ARCHIVED 0x0100 /* file is archived */
|
||||||
#define SYS_IMMUTABLE 0x0200 /* file may not be changed */
|
#define SYS_IMMUTABLE 0x0200 /* file may not be changed */
|
||||||
#define SYS_APPEND 0x0400 /* writes to file may only append */
|
#define SYS_APPEND 0x0400 /* writes to file may only append */
|
||||||
|
|
||||||
long atime; /* time last accessed */
|
long atime; /* time last accessed */
|
||||||
long mtime; /* time last modified */
|
long mtime; /* time last modified */
|
||||||
long ctime; /* time created */
|
long ctime; /* time created */
|
||||||
} fs_inode_t;
|
} fs_inode_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned ino;
|
unsigned ino;
|
||||||
unsigned reclen;
|
unsigned reclen;
|
||||||
unsigned namlen;
|
unsigned namlen;
|
||||||
char name [63+1];
|
char name [63+1];
|
||||||
} fs_dirent_t;
|
} fs_dirent_t;
|
||||||
|
|
||||||
typedef void (*fs_directory_scanner_t) (fs_inode_t *dir,
|
typedef void (*fs_directory_scanner_t) (fs_inode_t *dir,
|
||||||
fs_inode_t *file, char *dirname, char *filename, void *arg);
|
fs_inode_t *file, char *dirname, char *filename, void *arg);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
fs_inode_t inode;
|
fs_inode_t inode;
|
||||||
int writable; /* write allowed */
|
int writable; /* write allowed */
|
||||||
unsigned long offset; /* current i/o offset */
|
unsigned long offset; /* current i/o offset */
|
||||||
} fs_file_t;
|
} fs_file_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
INODE_OP_LOOKUP, /* lookup inode by name */
|
INODE_OP_LOOKUP, /* lookup inode by name */
|
||||||
INODE_OP_CREATE, /* create new file */
|
INODE_OP_CREATE, /* create new file */
|
||||||
INODE_OP_DELETE, /* delete file */
|
INODE_OP_DELETE, /* delete file */
|
||||||
INODE_OP_LINK, /* make a link to a file */
|
INODE_OP_LINK, /* make a link to a file */
|
||||||
} fs_op_t;
|
} fs_op_t;
|
||||||
|
|
||||||
int fs_seek (fs_t *fs, unsigned long offset);
|
int fs_seek (fs_t *fs, unsigned long offset);
|
||||||
@@ -167,7 +167,7 @@ int fs_open (fs_t *fs, const char *filename, int writable);
|
|||||||
void fs_close (fs_t *fs);
|
void fs_close (fs_t *fs);
|
||||||
int fs_sync (fs_t *fs, int force);
|
int fs_sync (fs_t *fs, int force);
|
||||||
int fs_create (fs_t *fs, const char *filename, unsigned kbytes,
|
int fs_create (fs_t *fs, const char *filename, unsigned kbytes,
|
||||||
unsigned swap_kbytes);
|
unsigned swap_kbytes);
|
||||||
int fs_check (fs_t *fs);
|
int fs_check (fs_t *fs);
|
||||||
void fs_print (fs_t *fs, FILE *out);
|
void fs_print (fs_t *fs, FILE *out);
|
||||||
|
|
||||||
@@ -179,12 +179,12 @@ void fs_inode_clear (fs_inode_t *inode);
|
|||||||
void fs_inode_truncate (fs_inode_t *inode, unsigned long size);
|
void fs_inode_truncate (fs_inode_t *inode, unsigned long size);
|
||||||
void fs_inode_print (fs_inode_t *inode, FILE *out);
|
void fs_inode_print (fs_inode_t *inode, FILE *out);
|
||||||
int fs_inode_read (fs_inode_t *inode, unsigned long offset,
|
int fs_inode_read (fs_inode_t *inode, unsigned long offset,
|
||||||
unsigned char *data, unsigned long bytes);
|
unsigned char *data, unsigned long bytes);
|
||||||
int fs_inode_write (fs_inode_t *inode, unsigned long offset,
|
int fs_inode_write (fs_inode_t *inode, unsigned long offset,
|
||||||
unsigned char *data, unsigned long bytes);
|
unsigned char *data, unsigned long bytes);
|
||||||
int fs_inode_alloc (fs_t *fs, fs_inode_t *inode);
|
int fs_inode_alloc (fs_t *fs, fs_inode_t *inode);
|
||||||
int fs_inode_by_name (fs_t *fs, fs_inode_t *inode, const char *name,
|
int fs_inode_by_name (fs_t *fs, fs_inode_t *inode, const char *name,
|
||||||
fs_op_t op, int mode);
|
fs_op_t op, int mode);
|
||||||
int inode_build_list (fs_t *fs);
|
int inode_build_list (fs_t *fs);
|
||||||
|
|
||||||
int fs_write_block (fs_t *fs, unsigned bnum, unsigned char *data);
|
int fs_write_block (fs_t *fs, unsigned bnum, unsigned char *data);
|
||||||
@@ -196,14 +196,14 @@ int fs_double_indirect_block_free (fs_t *fs, unsigned int bno, int nblk);
|
|||||||
int fs_triple_indirect_block_free (fs_t *fs, unsigned int bno, int nblk);
|
int fs_triple_indirect_block_free (fs_t *fs, unsigned int bno, int nblk);
|
||||||
|
|
||||||
void fs_directory_scan (fs_inode_t *inode, char *dirname,
|
void fs_directory_scan (fs_inode_t *inode, char *dirname,
|
||||||
fs_directory_scanner_t scanner, void *arg);
|
fs_directory_scanner_t scanner, void *arg);
|
||||||
void fs_dirent_pack (unsigned char *data, fs_dirent_t *dirent);
|
void fs_dirent_pack (unsigned char *data, fs_dirent_t *dirent);
|
||||||
void fs_dirent_unpack (fs_dirent_t *dirent, unsigned char *data);
|
void fs_dirent_unpack (fs_dirent_t *dirent, unsigned char *data);
|
||||||
|
|
||||||
int fs_file_create (fs_t *fs, fs_file_t *file, const char *name, int mode);
|
int fs_file_create (fs_t *fs, fs_file_t *file, const char *name, int mode);
|
||||||
int fs_file_open (fs_t *fs, fs_file_t *file, const char *name, int wflag);
|
int fs_file_open (fs_t *fs, fs_file_t *file, const char *name, int wflag);
|
||||||
int fs_file_read (fs_file_t *file, unsigned char *data,
|
int fs_file_read (fs_file_t *file, unsigned char *data,
|
||||||
unsigned long bytes);
|
unsigned long bytes);
|
||||||
int fs_file_write (fs_file_t *file, unsigned char *data,
|
int fs_file_write (fs_file_t *file, unsigned char *data,
|
||||||
unsigned long bytes);
|
unsigned long bytes);
|
||||||
int fs_file_close (fs_file_t *file);
|
int fs_file_close (fs_file_t *file);
|
||||||
|
|||||||
1420
tools/fsutil/check.c
1420
tools/fsutil/check.c
File diff suppressed because it is too large
Load Diff
@@ -33,368 +33,370 @@ extern int verbose;
|
|||||||
|
|
||||||
int inode_build_list (fs_t *fs)
|
int inode_build_list (fs_t *fs)
|
||||||
{
|
{
|
||||||
fs_inode_t inode;
|
fs_inode_t inode;
|
||||||
unsigned int inum, total_inodes;
|
unsigned int inum, total_inodes;
|
||||||
|
|
||||||
total_inodes = (fs->isize - 1) * BSDFS_INODES_PER_BLOCK;
|
total_inodes = (fs->isize - 1) * BSDFS_INODES_PER_BLOCK;
|
||||||
for (inum = 1; inum <= total_inodes; inum++) {
|
for (inum = 1; inum <= total_inodes; inum++) {
|
||||||
if (! fs_inode_get (fs, &inode, inum))
|
if (! fs_inode_get (fs, &inode, inum))
|
||||||
return 0;
|
return 0;
|
||||||
if (inode.mode == 0) {
|
if (inode.mode == 0) {
|
||||||
fs->inode [fs->ninode++] = inum;
|
fs->inode [fs->ninode++] = inum;
|
||||||
if (fs->ninode >= NICINOD)
|
if (fs->ninode >= NICINOD)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_inode1 (fs_t *fs)
|
static int create_inode1 (fs_t *fs)
|
||||||
{
|
{
|
||||||
fs_inode_t inode;
|
fs_inode_t inode;
|
||||||
|
|
||||||
memset (&inode, 0, sizeof(inode));
|
memset (&inode, 0, sizeof(inode));
|
||||||
inode.mode = INODE_MODE_FREG;
|
inode.mode = INODE_MODE_FREG;
|
||||||
inode.fs = fs;
|
inode.fs = fs;
|
||||||
inode.number = 1;
|
inode.number = 1;
|
||||||
if (! fs_inode_save (&inode, 1))
|
if (! fs_inode_save (&inode, 1))
|
||||||
return 0;
|
return 0;
|
||||||
fs->tinode--;
|
fs->tinode--;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_root_directory (fs_t *fs)
|
static int create_root_directory (fs_t *fs)
|
||||||
{
|
{
|
||||||
fs_inode_t inode;
|
fs_inode_t inode;
|
||||||
unsigned char buf [BSDFS_BSIZE];
|
unsigned char buf [BSDFS_BSIZE];
|
||||||
unsigned int bno;
|
unsigned int bno;
|
||||||
|
|
||||||
memset (&inode, 0, sizeof(inode));
|
memset (&inode, 0, sizeof(inode));
|
||||||
inode.mode = INODE_MODE_FDIR | 0777;
|
inode.mode = INODE_MODE_FDIR | 0777;
|
||||||
inode.fs = fs;
|
inode.fs = fs;
|
||||||
inode.number = BSDFS_ROOT_INODE;
|
inode.number = BSDFS_ROOT_INODE;
|
||||||
inode.size = BSDFS_BSIZE;
|
inode.size = BSDFS_BSIZE;
|
||||||
inode.flags = 0;
|
inode.flags = 0;
|
||||||
|
|
||||||
time (&inode.ctime);
|
time (&inode.ctime);
|
||||||
time (&inode.atime);
|
time (&inode.atime);
|
||||||
time (&inode.mtime);
|
time (&inode.mtime);
|
||||||
|
|
||||||
/* directory - put in extra links */
|
/* directory - put in extra links */
|
||||||
memset (buf, 0, sizeof(buf));
|
memset (buf, 0, sizeof(buf));
|
||||||
buf[0] = inode.number;
|
buf[0] = inode.number;
|
||||||
buf[1] = inode.number >> 8;
|
buf[1] = inode.number >> 8;
|
||||||
buf[2] = inode.number >> 16;
|
buf[2] = inode.number >> 16;
|
||||||
buf[3] = inode.number >> 24;
|
buf[3] = inode.number >> 24;
|
||||||
buf[4] = 12;
|
buf[4] = 12;
|
||||||
buf[5] = 12 >> 8;
|
buf[5] = 12 >> 8;
|
||||||
buf[6] = 1;
|
buf[6] = 1;
|
||||||
buf[7] = 1 >> 8;
|
buf[7] = 1 >> 8;
|
||||||
buf[8] = '.';
|
buf[8] = '.';
|
||||||
buf[9] = 0;
|
buf[9] = 0;
|
||||||
buf[10] = 0;
|
buf[10] = 0;
|
||||||
buf[11] = 0;
|
buf[11] = 0;
|
||||||
|
|
||||||
buf[12+0] = BSDFS_ROOT_INODE;
|
buf[12+0] = BSDFS_ROOT_INODE;
|
||||||
buf[12+1] = BSDFS_ROOT_INODE >> 8;
|
buf[12+1] = BSDFS_ROOT_INODE >> 8;
|
||||||
buf[12+2] = BSDFS_ROOT_INODE >> 16;
|
buf[12+2] = BSDFS_ROOT_INODE >> 16;
|
||||||
buf[12+3] = BSDFS_ROOT_INODE >> 24;
|
buf[12+3] = BSDFS_ROOT_INODE >> 24;
|
||||||
buf[12+4] = 12;
|
buf[12+4] = 12;
|
||||||
buf[12+5] = 12 >> 8;
|
buf[12+5] = 12 >> 8;
|
||||||
buf[12+6] = 2;
|
buf[12+6] = 2;
|
||||||
buf[12+7] = 2 >> 8;
|
buf[12+7] = 2 >> 8;
|
||||||
buf[12+8] = '.';
|
buf[12+8] = '.';
|
||||||
buf[12+9] = '.';
|
buf[12+9] = '.';
|
||||||
buf[12+10] = 0;
|
buf[12+10] = 0;
|
||||||
buf[12+11] = 0;
|
buf[12+11] = 0;
|
||||||
|
|
||||||
buf[24+0] = BSDFS_LOSTFOUND_INODE;
|
buf[24+0] = BSDFS_LOSTFOUND_INODE;
|
||||||
buf[24+1] = BSDFS_LOSTFOUND_INODE >> 8;
|
buf[24+1] = BSDFS_LOSTFOUND_INODE >> 8;
|
||||||
buf[24+2] = BSDFS_LOSTFOUND_INODE >> 16;
|
buf[24+2] = BSDFS_LOSTFOUND_INODE >> 16;
|
||||||
buf[24+3] = BSDFS_LOSTFOUND_INODE >> 24;
|
buf[24+3] = BSDFS_LOSTFOUND_INODE >> 24;
|
||||||
buf[24+4] = (unsigned char) (BSDFS_BSIZE - 12 - 12);
|
buf[24+4] = (unsigned char) (BSDFS_BSIZE - 12 - 12);
|
||||||
buf[24+5] = (BSDFS_BSIZE - 12 - 12) >> 8;
|
buf[24+5] = (BSDFS_BSIZE - 12 - 12) >> 8;
|
||||||
buf[24+6] = 10;
|
buf[24+6] = 10;
|
||||||
buf[24+7] = 10 >> 8;
|
buf[24+7] = 10 >> 8;
|
||||||
memcpy (&buf[24+8], "lost+found\0\0", 12);
|
memcpy (&buf[24+8], "lost+found\0\0", 12);
|
||||||
|
|
||||||
if (fs->swapsz != 0) {
|
if (fs->swapsz != 0) {
|
||||||
buf[24+4] = 20;
|
buf[24+4] = 20;
|
||||||
buf[24+5] = 20 >> 8;
|
buf[24+5] = 20 >> 8;
|
||||||
buf[44+0] = BSDFS_SWAP_INODE;
|
buf[44+0] = BSDFS_SWAP_INODE;
|
||||||
buf[44+1] = BSDFS_SWAP_INODE >> 8;
|
buf[44+1] = BSDFS_SWAP_INODE >> 8;
|
||||||
buf[44+2] = BSDFS_SWAP_INODE >> 16;
|
buf[44+2] = BSDFS_SWAP_INODE >> 16;
|
||||||
buf[44+3] = BSDFS_SWAP_INODE >> 24;
|
buf[44+3] = BSDFS_SWAP_INODE >> 24;
|
||||||
buf[44+4] = (unsigned char) (BSDFS_BSIZE - 12 - 12 - 20);
|
buf[44+4] = (unsigned char) (BSDFS_BSIZE - 12 - 12 - 20);
|
||||||
buf[44+5] = (BSDFS_BSIZE - 12 - 12 - 20) >> 8;
|
buf[44+5] = (BSDFS_BSIZE - 12 - 12 - 20) >> 8;
|
||||||
buf[44+6] = 4;
|
buf[44+6] = 4;
|
||||||
buf[44+7] = 4 >> 8;
|
buf[44+7] = 4 >> 8;
|
||||||
memcpy (&buf[44+8], "swap\0\0\0\0", 8);
|
memcpy (&buf[44+8], "swap\0\0\0\0", 8);
|
||||||
}
|
}
|
||||||
inode.nlink = 3;
|
inode.nlink = 3;
|
||||||
|
|
||||||
if (! fs_block_alloc (fs, &bno))
|
if (! fs_block_alloc (fs, &bno))
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write_block (fs, bno, buf))
|
if (! fs_write_block (fs, bno, buf))
|
||||||
return 0;
|
return 0;
|
||||||
inode.addr[0] = bno;
|
inode.addr[0] = bno;
|
||||||
|
|
||||||
if (! fs_inode_save (&inode, 1))
|
if (! fs_inode_save (&inode, 1))
|
||||||
return 0;
|
return 0;
|
||||||
fs->tinode--;
|
fs->tinode--;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_lost_found_directory (fs_t *fs)
|
static int create_lost_found_directory (fs_t *fs)
|
||||||
{
|
{
|
||||||
fs_inode_t inode;
|
fs_inode_t inode;
|
||||||
unsigned char buf [BSDFS_BSIZE];
|
unsigned char buf [BSDFS_BSIZE];
|
||||||
unsigned int bno;
|
unsigned int bno;
|
||||||
|
|
||||||
memset (&inode, 0, sizeof(inode));
|
memset (&inode, 0, sizeof(inode));
|
||||||
inode.mode = INODE_MODE_FDIR | 0777;
|
inode.mode = INODE_MODE_FDIR | 0777;
|
||||||
inode.fs = fs;
|
inode.fs = fs;
|
||||||
inode.number = BSDFS_LOSTFOUND_INODE;
|
inode.number = BSDFS_LOSTFOUND_INODE;
|
||||||
inode.size = BSDFS_BSIZE;
|
inode.size = BSDFS_BSIZE;
|
||||||
inode.flags = 0;
|
inode.flags = 0;
|
||||||
|
|
||||||
time (&inode.ctime);
|
time (&inode.ctime);
|
||||||
time (&inode.atime);
|
time (&inode.atime);
|
||||||
time (&inode.mtime);
|
time (&inode.mtime);
|
||||||
|
|
||||||
/* directory - put in extra links */
|
/* directory - put in extra links */
|
||||||
memset (buf, 0, sizeof(buf));
|
memset (buf, 0, sizeof(buf));
|
||||||
buf[0] = inode.number;
|
buf[0] = inode.number;
|
||||||
buf[1] = inode.number >> 8;
|
buf[1] = inode.number >> 8;
|
||||||
buf[2] = inode.number >> 16;
|
buf[2] = inode.number >> 16;
|
||||||
buf[3] = inode.number >> 24;
|
buf[3] = inode.number >> 24;
|
||||||
buf[4] = 12;
|
buf[4] = 12;
|
||||||
buf[5] = 12 >> 8;
|
buf[5] = 12 >> 8;
|
||||||
buf[6] = 1;
|
buf[6] = 1;
|
||||||
buf[7] = 1 >> 8;
|
buf[7] = 1 >> 8;
|
||||||
buf[8] = '.';
|
buf[8] = '.';
|
||||||
buf[9] = 0;
|
buf[9] = 0;
|
||||||
buf[10] = 0;
|
buf[10] = 0;
|
||||||
buf[11] = 0;
|
buf[11] = 0;
|
||||||
|
|
||||||
buf[12+0] = BSDFS_ROOT_INODE;
|
buf[12+0] = BSDFS_ROOT_INODE;
|
||||||
buf[12+1] = BSDFS_ROOT_INODE >> 8;
|
buf[12+1] = BSDFS_ROOT_INODE >> 8;
|
||||||
buf[12+2] = BSDFS_ROOT_INODE >> 16;
|
buf[12+2] = BSDFS_ROOT_INODE >> 16;
|
||||||
buf[12+3] = BSDFS_ROOT_INODE >> 24;
|
buf[12+3] = BSDFS_ROOT_INODE >> 24;
|
||||||
buf[12+4] = (unsigned char) (BSDFS_BSIZE - 12);
|
buf[12+4] = (unsigned char) (BSDFS_BSIZE - 12);
|
||||||
buf[12+5] = (BSDFS_BSIZE - 12) >> 8;
|
buf[12+5] = (BSDFS_BSIZE - 12) >> 8;
|
||||||
buf[12+6] = 2;
|
buf[12+6] = 2;
|
||||||
buf[12+7] = 2 >> 8;
|
buf[12+7] = 2 >> 8;
|
||||||
buf[12+8] = '.';
|
buf[12+8] = '.';
|
||||||
buf[12+9] = '.';
|
buf[12+9] = '.';
|
||||||
buf[12+10] = 0;
|
buf[12+10] = 0;
|
||||||
buf[12+11] = 0;
|
buf[12+11] = 0;
|
||||||
|
|
||||||
inode.nlink = 2;
|
inode.nlink = 2;
|
||||||
|
|
||||||
if (! fs_block_alloc (fs, &bno))
|
if (! fs_block_alloc (fs, &bno))
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write_block (fs, bno, buf))
|
if (! fs_write_block (fs, bno, buf))
|
||||||
return 0;
|
return 0;
|
||||||
inode.addr[0] = bno;
|
inode.addr[0] = bno;
|
||||||
|
|
||||||
if (! fs_inode_save (&inode, 1))
|
if (! fs_inode_save (&inode, 1))
|
||||||
return 0;
|
return 0;
|
||||||
fs->tinode--;
|
fs->tinode--;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void map_block_swap (fs_inode_t *inode, unsigned lbn)
|
static void map_block_swap (fs_inode_t *inode, unsigned lbn)
|
||||||
{
|
{
|
||||||
unsigned block [BSDFS_BSIZE / 4];
|
unsigned block [BSDFS_BSIZE / 4];
|
||||||
unsigned int bn, indir, newb, shift, i, j;
|
unsigned int bn, indir, newb, shift, i, j;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Blocks 0..NADDR-3 are direct blocks.
|
* Blocks 0..NADDR-3 are direct blocks.
|
||||||
*/
|
*/
|
||||||
if (lbn < NADDR-3) {
|
if (lbn < NADDR-3) {
|
||||||
/* small file algorithm */
|
/* small file algorithm */
|
||||||
inode->addr[lbn] = inode->fs->isize + lbn;
|
inode->addr[lbn] = inode->fs->isize + lbn;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Addresses NADDR-3, NADDR-2, and NADDR-1
|
* Addresses NADDR-3, NADDR-2, and NADDR-1
|
||||||
* have single, double, triple indirect blocks.
|
* have single, double, triple indirect blocks.
|
||||||
* The first step is to determine
|
* The first step is to determine
|
||||||
* how many levels of indirection.
|
* how many levels of indirection.
|
||||||
*/
|
*/
|
||||||
shift = 0;
|
shift = 0;
|
||||||
i = 1;
|
i = 1;
|
||||||
bn = lbn - (NADDR-3);
|
bn = lbn - (NADDR-3);
|
||||||
for (j=3; ; j--) {
|
for (j=3; ; j--) {
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
fprintf (stderr, "swap: too large size\n");
|
fprintf (stderr, "swap: too large size\n");
|
||||||
exit (-1);
|
exit (-1);
|
||||||
}
|
}
|
||||||
shift += NSHIFT;
|
shift += NSHIFT;
|
||||||
i <<= NSHIFT;
|
i <<= NSHIFT;
|
||||||
if (bn < i)
|
if (bn < i)
|
||||||
break;
|
break;
|
||||||
bn -= i;
|
bn -= i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fetch the first indirect block.
|
* Fetch the first indirect block.
|
||||||
*/
|
*/
|
||||||
indir = inode->addr [NADDR-j];
|
indir = inode->addr [NADDR-j];
|
||||||
if (indir == 0) {
|
if (indir == 0) {
|
||||||
if (! fs_block_alloc (inode->fs, &indir)) {
|
if (! fs_block_alloc (inode->fs, &indir)) {
|
||||||
alloc_error: fprintf (stderr, "swap: cannot allocate indirect block\n");
|
alloc_error:
|
||||||
exit (-1);
|
fprintf (stderr, "swap: cannot allocate indirect block\n");
|
||||||
}
|
exit (-1);
|
||||||
if (verbose)
|
}
|
||||||
printf ("swap: allocate indirect block %d (j=%d)\n", indir, j);
|
if (verbose)
|
||||||
memset (block, 0, BSDFS_BSIZE);
|
printf ("swap: allocate indirect block %d (j=%d)\n", indir, j);
|
||||||
if (! fs_write_block (inode->fs, indir, (unsigned char*) block)) {
|
memset (block, 0, BSDFS_BSIZE);
|
||||||
write_error: fprintf (stderr, "swap: cannot write indirect block %d\n", indir);
|
if (! fs_write_block (inode->fs, indir, (unsigned char*) block)) {
|
||||||
exit (-1);
|
write_error:
|
||||||
}
|
fprintf (stderr, "swap: cannot write indirect block %d\n", indir);
|
||||||
inode->addr [NADDR-j] = indir;
|
exit (-1);
|
||||||
}
|
}
|
||||||
|
inode->addr [NADDR-j] = indir;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fetch through the indirect blocks
|
* Fetch through the indirect blocks
|
||||||
*/
|
*/
|
||||||
for (; ; j++) {
|
for (; ; j++) {
|
||||||
if (! fs_read_block (inode->fs, indir, (unsigned char*) block)) {
|
if (! fs_read_block (inode->fs, indir, (unsigned char*) block)) {
|
||||||
fprintf (stderr, "swap: cannot read indirect block %d\n", indir);
|
fprintf (stderr, "swap: cannot read indirect block %d\n", indir);
|
||||||
exit (-1);
|
exit (-1);
|
||||||
}
|
}
|
||||||
shift -= NSHIFT;
|
shift -= NSHIFT;
|
||||||
i = (bn >> shift) & NMASK;
|
i = (bn >> shift) & NMASK;
|
||||||
if (j == 3) {
|
if (j == 3) {
|
||||||
block[i] = inode->fs->isize + lbn;
|
block[i] = inode->fs->isize + lbn;
|
||||||
if (! fs_write_block (inode->fs, indir, (unsigned char*) block))
|
if (! fs_write_block (inode->fs, indir, (unsigned char*) block))
|
||||||
goto write_error;
|
goto write_error;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (block[i] != 0) {
|
if (block[i] != 0) {
|
||||||
indir = block [i];
|
indir = block [i];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Allocate new indirect block. */
|
/* Allocate new indirect block. */
|
||||||
if (! fs_block_alloc (inode->fs, &newb))
|
if (! fs_block_alloc (inode->fs, &newb))
|
||||||
goto alloc_error;
|
goto alloc_error;
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf ("swap: allocate new block %d (j=%d)\n", newb, j);
|
printf ("swap: allocate new block %d (j=%d)\n", newb, j);
|
||||||
block[i] = newb;
|
block[i] = newb;
|
||||||
if (! fs_write_block (inode->fs, indir, (unsigned char*) block))
|
if (! fs_write_block (inode->fs, indir, (unsigned char*) block))
|
||||||
goto write_error;
|
goto write_error;
|
||||||
memset (block, 0, BSDFS_BSIZE);
|
memset (block, 0, BSDFS_BSIZE);
|
||||||
if (! fs_write_block (inode->fs, newb, (unsigned char*) block)) {
|
if (! fs_write_block (inode->fs, newb, (unsigned char*) block)) {
|
||||||
fprintf (stderr, "swap: cannot write block %d\n", newb);
|
fprintf (stderr, "swap: cannot write block %d\n", newb);
|
||||||
exit (-1);
|
exit (-1);
|
||||||
}
|
}
|
||||||
indir = newb;
|
indir = newb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_swap_file (fs_t *fs)
|
static int create_swap_file (fs_t *fs)
|
||||||
{
|
{
|
||||||
fs_inode_t inode;
|
fs_inode_t inode;
|
||||||
unsigned lbn;
|
unsigned lbn;
|
||||||
|
|
||||||
memset (&inode, 0, sizeof(inode));
|
memset (&inode, 0, sizeof(inode));
|
||||||
inode.mode = INODE_MODE_FREG | 0400;
|
inode.mode = INODE_MODE_FREG | 0400;
|
||||||
inode.fs = fs;
|
inode.fs = fs;
|
||||||
inode.number = BSDFS_SWAP_INODE;
|
inode.number = BSDFS_SWAP_INODE;
|
||||||
inode.size = fs->swapsz * BSDFS_BSIZE;
|
inode.size = fs->swapsz * BSDFS_BSIZE;
|
||||||
inode.flags = /*SYS_IMMUTABLE |*/ USER_IMMUTABLE | USER_NODUMP;
|
inode.flags = /*SYS_IMMUTABLE |*/ USER_IMMUTABLE | USER_NODUMP;
|
||||||
inode.nlink = 1;
|
inode.nlink = 1;
|
||||||
inode.dirty = 1;
|
inode.dirty = 1;
|
||||||
|
|
||||||
time (&inode.ctime);
|
time (&inode.ctime);
|
||||||
time (&inode.atime);
|
time (&inode.atime);
|
||||||
time (&inode.mtime);
|
time (&inode.mtime);
|
||||||
|
|
||||||
for (lbn=0; lbn<fs->swapsz; lbn++)
|
for (lbn=0; lbn<fs->swapsz; lbn++)
|
||||||
map_block_swap (&inode, lbn);
|
map_block_swap (&inode, lbn);
|
||||||
|
|
||||||
if (! fs_inode_save (&inode, 0)) {
|
if (! fs_inode_save (&inode, 0)) {
|
||||||
fprintf (stderr, "swap: cannot save file inode\n");
|
fprintf (stderr, "swap: cannot save file inode\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_create (fs_t *fs, const char *filename, unsigned kbytes,
|
int fs_create (fs_t *fs, const char *filename, unsigned kbytes,
|
||||||
unsigned swap_kbytes)
|
unsigned swap_kbytes)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
unsigned char buf [BSDFS_BSIZE];
|
unsigned char buf [BSDFS_BSIZE];
|
||||||
off_t bytes, offset;
|
off_t bytes, offset;
|
||||||
|
|
||||||
memset (fs, 0, sizeof (*fs));
|
memset (fs, 0, sizeof (*fs));
|
||||||
fs->filename = filename;
|
fs->filename = filename;
|
||||||
fs->seek = 0;
|
fs->seek = 0;
|
||||||
|
|
||||||
fs->fd = open (fs->filename, O_CREAT | O_RDWR, 0666);
|
fs->fd = open (fs->filename, O_CREAT | O_RDWR, 0666);
|
||||||
if (fs->fd < 0)
|
if (fs->fd < 0)
|
||||||
return 0;
|
return 0;
|
||||||
fs->writable = 1;
|
fs->writable = 1;
|
||||||
|
|
||||||
/* get total disk size
|
/* get total disk size
|
||||||
* and inode block size */
|
* and inode block size */
|
||||||
bytes = (off_t) kbytes * 1024ULL;
|
bytes = (off_t) kbytes * 1024ULL;
|
||||||
fs->fsize = bytes / BSDFS_BSIZE;
|
fs->fsize = bytes / BSDFS_BSIZE;
|
||||||
fs->isize = 1 + (fs->fsize / 16 + BSDFS_INODES_PER_BLOCK - 1) /
|
fs->isize = 1 + (fs->fsize / 16 + BSDFS_INODES_PER_BLOCK - 1) /
|
||||||
BSDFS_INODES_PER_BLOCK;
|
BSDFS_INODES_PER_BLOCK;
|
||||||
if (fs->isize < 2)
|
if (fs->isize < 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* make sure the file is of proper size */
|
/* make sure the file is of proper size */
|
||||||
offset = lseek (fs->fd, bytes-1, SEEK_SET);
|
offset = lseek (fs->fd, bytes-1, SEEK_SET);
|
||||||
if (offset != bytes-1)
|
if (offset != bytes-1)
|
||||||
return 0;
|
return 0;
|
||||||
if (write (fs->fd, "", 1) != 1) {
|
if (write (fs->fd, "", 1) != 1) {
|
||||||
perror ("write");
|
perror ("write");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
lseek (fs->fd, 0, SEEK_SET);
|
lseek (fs->fd, 0, SEEK_SET);
|
||||||
|
|
||||||
/* build a list of free blocks */
|
/* build a list of free blocks */
|
||||||
fs->swapsz = swap_kbytes * 1024 / BSDFS_BSIZE;
|
fs->swapsz = swap_kbytes * 1024 / BSDFS_BSIZE;
|
||||||
fs_block_free (fs, 0);
|
fs_block_free (fs, 0);
|
||||||
for (n = fs->fsize - 1; n >= fs->isize + fs->swapsz; n--)
|
for (n = fs->fsize - 1; n >= fs->isize + fs->swapsz; n--)
|
||||||
if (! fs_block_free (fs, n))
|
if (! fs_block_free (fs, n))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* initialize inodes */
|
/* initialize inodes */
|
||||||
memset (buf, 0, BSDFS_BSIZE);
|
memset (buf, 0, BSDFS_BSIZE);
|
||||||
if (! fs_seek (fs, BSDFS_BSIZE))
|
if (! fs_seek (fs, BSDFS_BSIZE))
|
||||||
return 0;
|
return 0;
|
||||||
for (n=1; n < fs->isize; n++) {
|
for (n=1; n < fs->isize; n++) {
|
||||||
if (! fs_write (fs, buf, BSDFS_BSIZE))
|
if (! fs_write (fs, buf, BSDFS_BSIZE))
|
||||||
return 0;
|
return 0;
|
||||||
fs->tinode += BSDFS_INODES_PER_BLOCK;
|
fs->tinode += BSDFS_INODES_PER_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* legacy empty inode 1 */
|
/* legacy empty inode 1 */
|
||||||
if (! create_inode1 (fs))
|
if (! create_inode1 (fs))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* lost+found directory */
|
/* lost+found directory */
|
||||||
if (! create_lost_found_directory (fs))
|
if (! create_lost_found_directory (fs))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* root directory */
|
/* root directory */
|
||||||
if (! create_root_directory (fs))
|
if (! create_root_directory (fs))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* swap file */
|
/* swap file */
|
||||||
if (fs->swapsz != 0 && ! create_swap_file (fs))
|
if (fs->swapsz != 0 && ! create_swap_file (fs))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* build a list of free inodes */
|
/* build a list of free inodes */
|
||||||
if (! inode_build_list (fs))
|
if (! inode_build_list (fs))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* write out super block */
|
/* write out super block */
|
||||||
return fs_sync (fs, 1);
|
return fs_sync (fs, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,68 +29,68 @@ extern int verbose;
|
|||||||
|
|
||||||
int fs_file_create (fs_t *fs, fs_file_t *file, const char *name, int mode)
|
int fs_file_create (fs_t *fs, fs_file_t *file, const char *name, int mode)
|
||||||
{
|
{
|
||||||
if (! fs_inode_by_name (fs, &file->inode, name, INODE_OP_CREATE, mode)) {
|
if (! fs_inode_by_name (fs, &file->inode, name, INODE_OP_CREATE, mode)) {
|
||||||
fprintf (stderr, "%s: inode open failed\n", name);
|
fprintf (stderr, "%s: inode open failed\n", name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((file->inode.mode & INODE_MODE_FMT) == INODE_MODE_FDIR) {
|
if ((file->inode.mode & INODE_MODE_FMT) == INODE_MODE_FDIR) {
|
||||||
/* Cannot open directory on write. */
|
/* Cannot open directory on write. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fs_inode_truncate (&file->inode, 0);
|
fs_inode_truncate (&file->inode, 0);
|
||||||
fs_inode_save (&file->inode, 0);
|
fs_inode_save (&file->inode, 0);
|
||||||
file->writable = 1;
|
file->writable = 1;
|
||||||
file->offset = 0;
|
file->offset = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_file_open (fs_t *fs, fs_file_t *file, const char *name, int wflag)
|
int fs_file_open (fs_t *fs, fs_file_t *file, const char *name, int wflag)
|
||||||
{
|
{
|
||||||
if (! fs_inode_by_name (fs, &file->inode, name, INODE_OP_LOOKUP, 0)) {
|
if (! fs_inode_by_name (fs, &file->inode, name, INODE_OP_LOOKUP, 0)) {
|
||||||
fprintf (stderr, "%s: inode open failed\n", name);
|
fprintf (stderr, "%s: inode open failed\n", name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (wflag && (file->inode.mode & INODE_MODE_FMT) == INODE_MODE_FDIR) {
|
if (wflag && (file->inode.mode & INODE_MODE_FMT) == INODE_MODE_FDIR) {
|
||||||
/* Cannot open directory on write. */
|
/* Cannot open directory on write. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
file->writable = wflag;
|
file->writable = wflag;
|
||||||
file->offset = 0;
|
file->offset = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_file_read (fs_file_t *file, unsigned char *data, unsigned long bytes)
|
int fs_file_read (fs_file_t *file, unsigned char *data, unsigned long bytes)
|
||||||
{
|
{
|
||||||
if (! fs_inode_read (&file->inode, file->offset, data, bytes)) {
|
if (! fs_inode_read (&file->inode, file->offset, data, bytes)) {
|
||||||
fprintf (stderr, "inode %d: file read failed, %lu bytes at offset %lu\n",
|
fprintf (stderr, "inode %d: file read failed, %lu bytes at offset %lu\n",
|
||||||
file->inode.number, bytes, file->offset);
|
file->inode.number, bytes, file->offset);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
file->offset += bytes;
|
file->offset += bytes;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_file_write (fs_file_t *file, unsigned char *data, unsigned long bytes)
|
int fs_file_write (fs_file_t *file, unsigned char *data, unsigned long bytes)
|
||||||
{
|
{
|
||||||
if (! file->writable)
|
if (! file->writable)
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_inode_write (&file->inode, file->offset, data, bytes)) {
|
if (! fs_inode_write (&file->inode, file->offset, data, bytes)) {
|
||||||
fprintf (stderr, "inode %d: file write failed, %lu bytes at offset %lu\n",
|
fprintf (stderr, "inode %d: file write failed, %lu bytes at offset %lu\n",
|
||||||
file->inode.number, bytes, file->offset);
|
file->inode.number, bytes, file->offset);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
file->offset += bytes;
|
file->offset += bytes;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_file_close (fs_file_t *file)
|
int fs_file_close (fs_file_t *file)
|
||||||
{
|
{
|
||||||
if (file->writable) {
|
if (file->writable) {
|
||||||
if (! fs_inode_save (&file->inode, 0)) {
|
if (! fs_inode_save (&file->inode, 0)) {
|
||||||
fprintf (stderr, "inode %d: file close failed\n",
|
fprintf (stderr, "inode %d: file close failed\n",
|
||||||
file->inode.number);
|
file->inode.number);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,249 +43,249 @@ unsigned kbytes;
|
|||||||
unsigned swap_kbytes;
|
unsigned swap_kbytes;
|
||||||
|
|
||||||
static const char *program_version =
|
static const char *program_version =
|
||||||
"BSD 2.x file system utility, version 1.1\n"
|
"BSD 2.x file system utility, version 1.1\n"
|
||||||
"Copyright (C) 2011-2014 Serge Vakulenko";
|
"Copyright (C) 2011-2014 Serge Vakulenko";
|
||||||
|
|
||||||
static const char *program_bug_address = "<serge@vak.ru>";
|
static const char *program_bug_address = "<serge@vak.ru>";
|
||||||
|
|
||||||
static struct option program_options[] = {
|
static struct option program_options[] = {
|
||||||
{ "help", no_argument, 0, 'h' },
|
{ "help", no_argument, 0, 'h' },
|
||||||
{ "version", no_argument, 0, 'V' },
|
{ "version", no_argument, 0, 'V' },
|
||||||
{ "verbose", no_argument, 0, 'v' },
|
{ "verbose", no_argument, 0, 'v' },
|
||||||
{ "add", no_argument, 0, 'a' },
|
{ "add", no_argument, 0, 'a' },
|
||||||
{ "extract", no_argument, 0, 'x' },
|
{ "extract", no_argument, 0, 'x' },
|
||||||
{ "check", no_argument, 0, 'c' },
|
{ "check", no_argument, 0, 'c' },
|
||||||
{ "fix", no_argument, 0, 'f' },
|
{ "fix", no_argument, 0, 'f' },
|
||||||
{ "mount", no_argument, 0, 'm' },
|
{ "mount", no_argument, 0, 'm' },
|
||||||
{ "new", required_argument, 0, 'n' },
|
{ "new", required_argument, 0, 'n' },
|
||||||
{ "swap", required_argument, 0, 's' },
|
{ "swap", required_argument, 0, 's' },
|
||||||
{ "manifest", required_argument, 0, 'M' },
|
{ "manifest", required_argument, 0, 'M' },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static void print_help (char *progname)
|
static void print_help (char *progname)
|
||||||
{
|
{
|
||||||
char *p = strrchr (progname, '/');
|
char *p = strrchr (progname, '/');
|
||||||
if (p)
|
if (p)
|
||||||
progname = p+1;
|
progname = p+1;
|
||||||
|
|
||||||
printf ("%s\n", program_version);
|
printf ("%s\n", program_version);
|
||||||
printf ("This program is free software; it comes with ABSOLUTELY NO WARRANTY;\n"
|
printf ("This program is free software; it comes with ABSOLUTELY NO WARRANTY;\n"
|
||||||
"see the GNU General Public License for more details.\n");
|
"see the GNU General Public License for more details.\n");
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf ("Usage:\n");
|
printf ("Usage:\n");
|
||||||
printf (" %s [--verbose] filesys.img\n", progname);
|
printf (" %s [--verbose] filesys.img\n", progname);
|
||||||
printf (" %s --add filesys.img files...\n", progname);
|
printf (" %s --add filesys.img files...\n", progname);
|
||||||
printf (" %s --extract filesys.img\n", progname);
|
printf (" %s --extract filesys.img\n", progname);
|
||||||
printf (" %s --check [--fix] filesys.img\n", progname);
|
printf (" %s --check [--fix] filesys.img\n", progname);
|
||||||
printf (" %s --new=kbytes [--swap=kbytes] [--manifest=file] filesys.img [dir]\n", progname);
|
printf (" %s --new=kbytes [--swap=kbytes] [--manifest=file] filesys.img [dir]\n", progname);
|
||||||
printf (" %s --mount filesys.img dir\n", progname);
|
printf (" %s --mount filesys.img dir\n", progname);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf ("Options:\n");
|
printf ("Options:\n");
|
||||||
printf (" -a, --add Add files to filesystem.\n");
|
printf (" -a, --add Add files to filesystem.\n");
|
||||||
printf (" -x, --extract Extract all files.\n");
|
printf (" -x, --extract Extract all files.\n");
|
||||||
printf (" -c, --check Check filesystem, use -c -f to fix.\n");
|
printf (" -c, --check Check filesystem, use -c -f to fix.\n");
|
||||||
printf (" -f, --fix Fix bugs in filesystem.\n");
|
printf (" -f, --fix Fix bugs in filesystem.\n");
|
||||||
printf (" -n NUM, --new=NUM Create new filesystem, size in kbytes.\n");
|
printf (" -n NUM, --new=NUM Create new filesystem, size in kbytes.\n");
|
||||||
printf (" Add files from specified directory (optional)\n");
|
printf (" Add files from specified directory (optional)\n");
|
||||||
printf (" -s NUM, --swap=NUM Size of swap area in kbytes.\n");
|
printf (" -s NUM, --swap=NUM Size of swap area in kbytes.\n");
|
||||||
printf (" -M file, --manifest=file List of files and attributes to create.\n");
|
printf (" -M file, --manifest=file List of files and attributes to create.\n");
|
||||||
printf (" -m, --mount Mount the filesystem.\n");
|
printf (" -m, --mount Mount the filesystem.\n");
|
||||||
printf (" -v, --verbose Be verbose.\n");
|
printf (" -v, --verbose Be verbose.\n");
|
||||||
printf (" -V, --version Print version information and then exit.\n");
|
printf (" -V, --version Print version information and then exit.\n");
|
||||||
printf (" -h, --help Print this message.\n");
|
printf (" -h, --help Print this message.\n");
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
printf ("Report bugs to \"%s\".\n", program_bug_address);
|
printf ("Report bugs to \"%s\".\n", program_bug_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_inode (fs_inode_t *inode,
|
void print_inode (fs_inode_t *inode,
|
||||||
char *dirname, char *filename, FILE *out)
|
char *dirname, char *filename, FILE *out)
|
||||||
{
|
{
|
||||||
fprintf (out, "%s/%s", dirname, filename);
|
fprintf (out, "%s/%s", dirname, filename);
|
||||||
switch (inode->mode & INODE_MODE_FMT) {
|
switch (inode->mode & INODE_MODE_FMT) {
|
||||||
case INODE_MODE_FDIR:
|
case INODE_MODE_FDIR:
|
||||||
if (filename[0] != 0)
|
if (filename[0] != 0)
|
||||||
fprintf (out, "/");
|
fprintf (out, "/");
|
||||||
break;
|
break;
|
||||||
case INODE_MODE_FCHR:
|
case INODE_MODE_FCHR:
|
||||||
fprintf (out, " - char %d %d",
|
fprintf (out, " - char %d %d",
|
||||||
inode->addr[1] >> 8, inode->addr[1] & 0xff);
|
inode->addr[1] >> 8, inode->addr[1] & 0xff);
|
||||||
break;
|
break;
|
||||||
case INODE_MODE_FBLK:
|
case INODE_MODE_FBLK:
|
||||||
fprintf (out, " - block %d %d",
|
fprintf (out, " - block %d %d",
|
||||||
inode->addr[1] >> 8, inode->addr[1] & 0xff);
|
inode->addr[1] >> 8, inode->addr[1] & 0xff);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf (out, " - %lu bytes", inode->size);
|
fprintf (out, " - %lu bytes", inode->size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf (out, "\n");
|
fprintf (out, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_indirect_block (fs_t *fs, unsigned int bno, FILE *out)
|
void print_indirect_block (fs_t *fs, unsigned int bno, FILE *out)
|
||||||
{
|
{
|
||||||
unsigned short nb;
|
unsigned short nb;
|
||||||
unsigned char data [BSDFS_BSIZE];
|
unsigned char data [BSDFS_BSIZE];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
fprintf (out, " [%d]", bno);
|
fprintf (out, " [%d]", bno);
|
||||||
if (! fs_read_block (fs, bno, data)) {
|
if (! fs_read_block (fs, bno, data)) {
|
||||||
fprintf (stderr, "read error at block %d\n", bno);
|
fprintf (stderr, "read error at block %d\n", bno);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (i=0; i<BSDFS_BSIZE-2; i+=2) {
|
for (i=0; i<BSDFS_BSIZE-2; i+=2) {
|
||||||
nb = data [i+1] << 8 | data [i];
|
nb = data [i+1] << 8 | data [i];
|
||||||
if (nb)
|
if (nb)
|
||||||
fprintf (out, " %d", nb);
|
fprintf (out, " %d", nb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_double_indirect_block (fs_t *fs, unsigned int bno, FILE *out)
|
void print_double_indirect_block (fs_t *fs, unsigned int bno, FILE *out)
|
||||||
{
|
{
|
||||||
unsigned short nb;
|
unsigned short nb;
|
||||||
unsigned char data [BSDFS_BSIZE];
|
unsigned char data [BSDFS_BSIZE];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
fprintf (out, " [%d]", bno);
|
fprintf (out, " [%d]", bno);
|
||||||
if (! fs_read_block (fs, bno, data)) {
|
if (! fs_read_block (fs, bno, data)) {
|
||||||
fprintf (stderr, "read error at block %d\n", bno);
|
fprintf (stderr, "read error at block %d\n", bno);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (i=0; i<BSDFS_BSIZE-2; i+=2) {
|
for (i=0; i<BSDFS_BSIZE-2; i+=2) {
|
||||||
nb = data [i+1] << 8 | data [i];
|
nb = data [i+1] << 8 | data [i];
|
||||||
if (nb)
|
if (nb)
|
||||||
print_indirect_block (fs, nb, out);
|
print_indirect_block (fs, nb, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_triple_indirect_block (fs_t *fs, unsigned int bno, FILE *out)
|
void print_triple_indirect_block (fs_t *fs, unsigned int bno, FILE *out)
|
||||||
{
|
{
|
||||||
unsigned short nb;
|
unsigned short nb;
|
||||||
unsigned char data [BSDFS_BSIZE];
|
unsigned char data [BSDFS_BSIZE];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
fprintf (out, " [%d]", bno);
|
fprintf (out, " [%d]", bno);
|
||||||
if (! fs_read_block (fs, bno, data)) {
|
if (! fs_read_block (fs, bno, data)) {
|
||||||
fprintf (stderr, "read error at block %d\n", bno);
|
fprintf (stderr, "read error at block %d\n", bno);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (i=0; i<BSDFS_BSIZE-2; i+=2) {
|
for (i=0; i<BSDFS_BSIZE-2; i+=2) {
|
||||||
nb = data [i+1] << 8 | data [i];
|
nb = data [i+1] << 8 | data [i];
|
||||||
if (nb)
|
if (nb)
|
||||||
print_indirect_block (fs, nb, out);
|
print_indirect_block (fs, nb, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_inode_blocks (fs_inode_t *inode, FILE *out)
|
void print_inode_blocks (fs_inode_t *inode, FILE *out)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((inode->mode & INODE_MODE_FMT) == INODE_MODE_FCHR ||
|
if ((inode->mode & INODE_MODE_FMT) == INODE_MODE_FCHR ||
|
||||||
(inode->mode & INODE_MODE_FMT) == INODE_MODE_FBLK)
|
(inode->mode & INODE_MODE_FMT) == INODE_MODE_FBLK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fprintf (out, " ");
|
fprintf (out, " ");
|
||||||
for (i=0; i<NDADDR; ++i) {
|
for (i=0; i<NDADDR; ++i) {
|
||||||
if (inode->addr[i] == 0)
|
if (inode->addr[i] == 0)
|
||||||
continue;
|
continue;
|
||||||
fprintf (out, " %d", inode->addr[i]);
|
fprintf (out, " %d", inode->addr[i]);
|
||||||
}
|
}
|
||||||
if (inode->addr[NDADDR] != 0)
|
if (inode->addr[NDADDR] != 0)
|
||||||
print_indirect_block (inode->fs, inode->addr[NDADDR], out);
|
print_indirect_block (inode->fs, inode->addr[NDADDR], out);
|
||||||
if (inode->addr[NDADDR+1] != 0)
|
if (inode->addr[NDADDR+1] != 0)
|
||||||
print_double_indirect_block (inode->fs,
|
print_double_indirect_block (inode->fs,
|
||||||
inode->addr[NDADDR+1], out);
|
inode->addr[NDADDR+1], out);
|
||||||
if (inode->addr[NDADDR+2] != 0)
|
if (inode->addr[NDADDR+2] != 0)
|
||||||
print_triple_indirect_block (inode->fs,
|
print_triple_indirect_block (inode->fs,
|
||||||
inode->addr[NDADDR+2], out);
|
inode->addr[NDADDR+2], out);
|
||||||
fprintf (out, "\n");
|
fprintf (out, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void extract_inode (fs_inode_t *inode, char *path)
|
void extract_inode (fs_inode_t *inode, char *path)
|
||||||
{
|
{
|
||||||
int fd, n, mode;
|
int fd, n, mode;
|
||||||
unsigned long offset;
|
unsigned long offset;
|
||||||
unsigned char data [BSDFS_BSIZE];
|
unsigned char data [BSDFS_BSIZE];
|
||||||
|
|
||||||
/* Allow read/write for user. */
|
/* Allow read/write for user. */
|
||||||
mode = (inode->mode & 0777) | 0600;
|
mode = (inode->mode & 0777) | 0600;
|
||||||
fd = open (path, O_CREAT | O_RDWR, mode);
|
fd = open (path, O_CREAT | O_RDWR, mode);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
perror (path);
|
perror (path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (offset = 0; offset < inode->size; offset += BSDFS_BSIZE) {
|
for (offset = 0; offset < inode->size; offset += BSDFS_BSIZE) {
|
||||||
n = inode->size - offset;
|
n = inode->size - offset;
|
||||||
if (n > BSDFS_BSIZE)
|
if (n > BSDFS_BSIZE)
|
||||||
n = BSDFS_BSIZE;
|
n = BSDFS_BSIZE;
|
||||||
if (! fs_inode_read (inode, offset, data, n)) {
|
if (! fs_inode_read (inode, offset, data, n)) {
|
||||||
fprintf (stderr, "%s: read error at offset %ld\n",
|
fprintf (stderr, "%s: read error at offset %ld\n",
|
||||||
path, offset);
|
path, offset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (write (fd, data, n) != n) {
|
if (write (fd, data, n) != n) {
|
||||||
fprintf (stderr, "%s: write error\n", path);
|
fprintf (stderr, "%s: write error\n", path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close (fd);
|
close (fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void extractor (fs_inode_t *dir, fs_inode_t *inode,
|
void extractor (fs_inode_t *dir, fs_inode_t *inode,
|
||||||
char *dirname, char *filename, void *arg)
|
char *dirname, char *filename, void *arg)
|
||||||
{
|
{
|
||||||
FILE *out = arg;
|
FILE *out = arg;
|
||||||
char *path, *relpath;
|
char *path, *relpath;
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
print_inode (inode, dirname, filename, out);
|
print_inode (inode, dirname, filename, out);
|
||||||
|
|
||||||
if ((inode->mode & INODE_MODE_FMT) != INODE_MODE_FDIR &&
|
if ((inode->mode & INODE_MODE_FMT) != INODE_MODE_FDIR &&
|
||||||
(inode->mode & INODE_MODE_FMT) != INODE_MODE_FREG)
|
(inode->mode & INODE_MODE_FMT) != INODE_MODE_FREG)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
path = alloca (strlen (dirname) + strlen (filename) + 2);
|
path = alloca (strlen (dirname) + strlen (filename) + 2);
|
||||||
strcpy (path, dirname);
|
strcpy (path, dirname);
|
||||||
strcat (path, "/");
|
strcat (path, "/");
|
||||||
strcat (path, filename);
|
strcat (path, filename);
|
||||||
for (relpath=path; *relpath == '/'; relpath++)
|
for (relpath=path; *relpath == '/'; relpath++)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((inode->mode & INODE_MODE_FMT) == INODE_MODE_FDIR) {
|
if ((inode->mode & INODE_MODE_FMT) == INODE_MODE_FDIR) {
|
||||||
if (mkdir (relpath, 0775) < 0 && errno != EEXIST)
|
if (mkdir (relpath, 0775) < 0 && errno != EEXIST)
|
||||||
perror (relpath);
|
perror (relpath);
|
||||||
/* Scan subdirectory. */
|
/* Scan subdirectory. */
|
||||||
fs_directory_scan (inode, path, extractor, arg);
|
fs_directory_scan (inode, path, extractor, arg);
|
||||||
} else {
|
} else {
|
||||||
extract_inode (inode, relpath);
|
extract_inode (inode, relpath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scanner (fs_inode_t *dir, fs_inode_t *inode,
|
void scanner (fs_inode_t *dir, fs_inode_t *inode,
|
||||||
char *dirname, char *filename, void *arg)
|
char *dirname, char *filename, void *arg)
|
||||||
{
|
{
|
||||||
FILE *out = arg;
|
FILE *out = arg;
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
print_inode (inode, dirname, filename, out);
|
print_inode (inode, dirname, filename, out);
|
||||||
|
|
||||||
if (verbose > 1) {
|
if (verbose > 1) {
|
||||||
/* Print a list of blocks. */
|
/* Print a list of blocks. */
|
||||||
print_inode_blocks (inode, out);
|
print_inode_blocks (inode, out);
|
||||||
if (verbose > 2) {
|
if (verbose > 2) {
|
||||||
fs_inode_print (inode, out);
|
fs_inode_print (inode, out);
|
||||||
printf ("--------\n");
|
printf ("--------\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((inode->mode & INODE_MODE_FMT) == INODE_MODE_FDIR &&
|
if ((inode->mode & INODE_MODE_FMT) == INODE_MODE_FDIR &&
|
||||||
inode->number != BSDFS_ROOT_INODE) {
|
inode->number != BSDFS_ROOT_INODE) {
|
||||||
/* Scan subdirectory. */
|
/* Scan subdirectory. */
|
||||||
path = alloca (strlen (dirname) + strlen (filename) + 2);
|
path = alloca (strlen (dirname) + strlen (filename) + 2);
|
||||||
strcpy (path, dirname);
|
strcpy (path, dirname);
|
||||||
strcat (path, "/");
|
strcat (path, "/");
|
||||||
strcat (path, filename);
|
strcat (path, filename);
|
||||||
fs_directory_scan (inode, path, scanner, arg);
|
fs_directory_scan (inode, path, scanner, arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -293,46 +293,46 @@ void scanner (fs_inode_t *dir, fs_inode_t *inode,
|
|||||||
*/
|
*/
|
||||||
void add_directory (fs_t *fs, char *name)
|
void add_directory (fs_t *fs, char *name)
|
||||||
{
|
{
|
||||||
fs_inode_t dir, parent;
|
fs_inode_t dir, parent;
|
||||||
char buf [BSDFS_BSIZE], *p;
|
char buf [BSDFS_BSIZE], *p;
|
||||||
|
|
||||||
/* Open parent directory. */
|
/* Open parent directory. */
|
||||||
strcpy (buf, name);
|
strcpy (buf, name);
|
||||||
p = strrchr (buf, '/');
|
p = strrchr (buf, '/');
|
||||||
if (p)
|
if (p)
|
||||||
*p = 0;
|
*p = 0;
|
||||||
else
|
else
|
||||||
*buf = 0;
|
*buf = 0;
|
||||||
if (! fs_inode_by_name (fs, &parent, buf, INODE_OP_LOOKUP, 0)) {
|
if (! fs_inode_by_name (fs, &parent, buf, INODE_OP_LOOKUP, 0)) {
|
||||||
fprintf (stderr, "%s: cannot open directory\n", buf);
|
fprintf (stderr, "%s: cannot open directory\n", buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create directory. */
|
/* Create directory. */
|
||||||
int done = fs_inode_by_name (fs, &dir, name, INODE_OP_CREATE, INODE_MODE_FDIR | 0777);
|
int done = fs_inode_by_name (fs, &dir, name, INODE_OP_CREATE, INODE_MODE_FDIR | 0777);
|
||||||
if (! done) {
|
if (! done) {
|
||||||
fprintf (stderr, "%s: directory inode create failed\n", name);
|
fprintf (stderr, "%s: directory inode create failed\n", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (done == 1) {
|
if (done == 1) {
|
||||||
/* The directory already existed. */
|
/* The directory already existed. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fs_inode_save (&dir, 0);
|
fs_inode_save (&dir, 0);
|
||||||
|
|
||||||
/* Make parent link '..' */
|
/* Make parent link '..' */
|
||||||
strcpy (buf, name);
|
strcpy (buf, name);
|
||||||
strcat (buf, "/..");
|
strcat (buf, "/..");
|
||||||
if (! fs_inode_by_name (fs, &dir, buf, INODE_OP_LINK, parent.number)) {
|
if (! fs_inode_by_name (fs, &dir, buf, INODE_OP_LINK, parent.number)) {
|
||||||
fprintf (stderr, "%s: dotdot link failed\n", name);
|
fprintf (stderr, "%s: dotdot link failed\n", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (! fs_inode_get (fs, &parent, parent.number)) {
|
if (! fs_inode_get (fs, &parent, parent.number)) {
|
||||||
fprintf (stderr, "inode %d: cannot open parent\n", parent.number);
|
fprintf (stderr, "inode %d: cannot open parent\n", parent.number);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
++parent.nlink;
|
++parent.nlink;
|
||||||
fs_inode_save (&parent, 1);
|
fs_inode_save (&parent, 1);
|
||||||
/*printf ("*** inode %d: increment link counter to %d\n", parent.number, parent.nlink);*/
|
/*printf ("*** inode %d: increment link counter to %d\n", parent.number, parent.nlink);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,25 +341,25 @@ void add_directory (fs_t *fs, char *name)
|
|||||||
*/
|
*/
|
||||||
void add_device (fs_t *fs, char *name, char *spec)
|
void add_device (fs_t *fs, char *name, char *spec)
|
||||||
{
|
{
|
||||||
fs_inode_t dev;
|
fs_inode_t dev;
|
||||||
int majr, minr;
|
int majr, minr;
|
||||||
char type;
|
char type;
|
||||||
|
|
||||||
if (sscanf (spec, "%c%d:%d", &type, &majr, &minr) != 3 ||
|
if (sscanf (spec, "%c%d:%d", &type, &majr, &minr) != 3 ||
|
||||||
(type != 'c' && type != 'b') ||
|
(type != 'c' && type != 'b') ||
|
||||||
majr < 0 || majr > 255 || minr < 0 || minr > 255) {
|
majr < 0 || majr > 255 || minr < 0 || minr > 255) {
|
||||||
fprintf (stderr, "%s: invalid device specification\n", spec);
|
fprintf (stderr, "%s: invalid device specification\n", spec);
|
||||||
fprintf (stderr, "expected c<major>:<minor> or b<major>:<minor>\n");
|
fprintf (stderr, "expected c<major>:<minor> or b<major>:<minor>\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (! fs_inode_by_name (fs, &dev, name, INODE_OP_CREATE, 0666 |
|
if (! fs_inode_by_name (fs, &dev, name, INODE_OP_CREATE, 0666 |
|
||||||
((type == 'b') ? INODE_MODE_FBLK : INODE_MODE_FCHR))) {
|
((type == 'b') ? INODE_MODE_FBLK : INODE_MODE_FCHR))) {
|
||||||
fprintf (stderr, "%s: device inode create failed\n", name);
|
fprintf (stderr, "%s: device inode create failed\n", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dev.addr[1] = majr << 8 | minr;
|
dev.addr[1] = majr << 8 | minr;
|
||||||
time (&dev.mtime);
|
time (&dev.mtime);
|
||||||
fs_inode_save (&dev, 1);
|
fs_inode_save (&dev, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -368,54 +368,54 @@ void add_device (fs_t *fs, char *name, char *spec)
|
|||||||
*/
|
*/
|
||||||
void add_file (fs_t *fs, char *name)
|
void add_file (fs_t *fs, char *name)
|
||||||
{
|
{
|
||||||
fs_file_t file;
|
fs_file_t file;
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
unsigned char data [BSDFS_BSIZE];
|
unsigned char data [BSDFS_BSIZE];
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char *p;
|
char *p;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printf ("%s\n", name);
|
printf ("%s\n", name);
|
||||||
}
|
}
|
||||||
p = strrchr (name, '/');
|
p = strrchr (name, '/');
|
||||||
if (p && p[1] == 0) {
|
if (p && p[1] == 0) {
|
||||||
*p = 0;
|
*p = 0;
|
||||||
add_directory (fs, name);
|
add_directory (fs, name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p = strrchr (name, '!');
|
p = strrchr (name, '!');
|
||||||
if (p) {
|
if (p) {
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
add_device (fs, name, p);
|
add_device (fs, name, p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fd = fopen (name, "r");
|
fd = fopen (name, "r");
|
||||||
if (! fd) {
|
if (! fd) {
|
||||||
perror (name);
|
perror (name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stat (name, &st);
|
stat (name, &st);
|
||||||
if (! fs_file_create (fs, &file, name, st.st_mode)) {
|
if (! fs_file_create (fs, &file, name, st.st_mode)) {
|
||||||
fprintf (stderr, "%s: cannot create\n", name);
|
fprintf (stderr, "%s: cannot create\n", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
len = fread (data, 1, sizeof (data), fd);
|
len = fread (data, 1, sizeof (data), fd);
|
||||||
/* printf ("read %d bytes from %s\n", len, name);*/
|
/* printf ("read %d bytes from %s\n", len, name);*/
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
perror (name);
|
perror (name);
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
break;
|
break;
|
||||||
if (! fs_file_write (&file, data, len)) {
|
if (! fs_file_write (&file, data, len)) {
|
||||||
fprintf (stderr, "%s: write error\n", name);
|
fprintf (stderr, "%s: write error\n", name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
file.inode.mtime = st.st_mtime;
|
file.inode.mtime = st.st_mtime;
|
||||||
file.inode.dirty = 1;
|
file.inode.dirty = 1;
|
||||||
fs_file_close (&file);
|
fs_file_close (&file);
|
||||||
fclose (fd);
|
fclose (fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -424,156 +424,157 @@ void add_file (fs_t *fs, char *name)
|
|||||||
*/
|
*/
|
||||||
void add_contents (fs_t *fs, const char *dirname, const char *manifest)
|
void add_contents (fs_t *fs, const char *dirname, const char *manifest)
|
||||||
{
|
{
|
||||||
printf ("TODO: add contents from directory '%s'\n", dirname);
|
printf ("TODO: add contents from directory '%s'\n", dirname);
|
||||||
if (manifest)
|
if (manifest)
|
||||||
printf ("TODO: use manifest '%s'\n", manifest);
|
printf ("TODO: use manifest '%s'\n", manifest);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
int main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i, key;
|
int i, key;
|
||||||
fs_t fs;
|
fs_t fs;
|
||||||
fs_inode_t inode;
|
fs_inode_t inode;
|
||||||
const char *manifest = 0;
|
const char *manifest = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
key = getopt_long (argc, argv, "vaxmMn:cfs:",
|
key = getopt_long (argc, argv, "vaxmMn:cfs:",
|
||||||
program_options, 0);
|
program_options, 0);
|
||||||
if (key == -1)
|
if (key == -1)
|
||||||
break;
|
break;
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'v':
|
case 'v':
|
||||||
++verbose;
|
++verbose;
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
++add;
|
++add;
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
++extract;
|
++extract;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
++newfs;
|
++newfs;
|
||||||
kbytes = strtol (optarg, 0, 0);
|
kbytes = strtol (optarg, 0, 0);
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
++check;
|
++check;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
++fix;
|
++fix;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
++mount;
|
++mount;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
swap_kbytes = strtol (optarg, 0, 0);
|
swap_kbytes = strtol (optarg, 0, 0);
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
manifest = optarg;
|
manifest = optarg;
|
||||||
break;
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
printf ("%s\n", program_version);
|
printf ("%s\n", program_version);
|
||||||
return 0;
|
return 0;
|
||||||
case 'h':
|
case 'h':
|
||||||
print_help (argv[0]);
|
print_help (argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
print_help (argv[0]);
|
print_help (argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i = optind;
|
i = optind;
|
||||||
if ((! add && ! mount && ! newfs && i != argc-1) ||
|
if ((! add && ! mount && ! newfs && i != argc-1) ||
|
||||||
(add && i >= argc) ||
|
(add && i >= argc) ||
|
||||||
(newfs && i != argc-1 && i != argc-2) ||
|
(newfs && i != argc-1 && i != argc-2) ||
|
||||||
(mount && i != argc-2) ||
|
(mount && i != argc-2) ||
|
||||||
(extract + newfs + check + add + mount > 1) ||
|
(extract + newfs + check + add + mount > 1) ||
|
||||||
(newfs && kbytes < BSDFS_BSIZE * 10 / 1024)) {
|
(newfs && kbytes < BSDFS_BSIZE * 10 / 1024))
|
||||||
print_help (argv[0]);
|
{
|
||||||
return -1;
|
print_help (argv[0]);
|
||||||
}
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (newfs) {
|
if (newfs) {
|
||||||
/* Create new filesystem. */
|
/* Create new filesystem. */
|
||||||
if (! fs_create (&fs, argv[i], kbytes, swap_kbytes)) {
|
if (! fs_create (&fs, argv[i], kbytes, swap_kbytes)) {
|
||||||
fprintf (stderr, "%s: cannot create filesystem\n", argv[i]);
|
fprintf (stderr, "%s: cannot create filesystem\n", argv[i]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
printf ("Created filesystem %s - %u kbytes\n", argv[i], kbytes);
|
printf ("Created filesystem %s - %u kbytes\n", argv[i], kbytes);
|
||||||
|
|
||||||
if (i == argc-2) {
|
if (i == argc-2) {
|
||||||
/* Add the contents from the specified directory.
|
/* Add the contents from the specified directory.
|
||||||
* Use the optional manifest file. */
|
* Use the optional manifest file. */
|
||||||
add_contents (&fs, argv[i+1], manifest);
|
add_contents (&fs, argv[i+1], manifest);
|
||||||
}
|
}
|
||||||
fs_close (&fs);
|
fs_close (&fs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check) {
|
if (check) {
|
||||||
/* Check filesystem for errors, and optionally fix them. */
|
/* Check filesystem for errors, and optionally fix them. */
|
||||||
if (! fs_open (&fs, argv[i], fix)) {
|
if (! fs_open (&fs, argv[i], fix)) {
|
||||||
fprintf (stderr, "%s: cannot open\n", argv[i]);
|
fprintf (stderr, "%s: cannot open\n", argv[i]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fs_check (&fs);
|
fs_check (&fs);
|
||||||
fs_close (&fs);
|
fs_close (&fs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add or extract or info. */
|
/* Add or extract or info. */
|
||||||
if (! fs_open (&fs, argv[i], (add + mount != 0))) {
|
if (! fs_open (&fs, argv[i], (add + mount != 0))) {
|
||||||
fprintf (stderr, "%s: cannot open\n", argv[i]);
|
fprintf (stderr, "%s: cannot open\n", argv[i]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extract) {
|
if (extract) {
|
||||||
/* Extract all files to current directory. */
|
/* Extract all files to current directory. */
|
||||||
if (! fs_inode_get (&fs, &inode, BSDFS_ROOT_INODE)) {
|
if (! fs_inode_get (&fs, &inode, BSDFS_ROOT_INODE)) {
|
||||||
fprintf (stderr, "%s: cannot get inode 1\n", argv[i]);
|
fprintf (stderr, "%s: cannot get inode 1\n", argv[i]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fs_directory_scan (&inode, "", extractor, (void*) stdout);
|
fs_directory_scan (&inode, "", extractor, (void*) stdout);
|
||||||
fs_close (&fs);
|
fs_close (&fs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (add) {
|
if (add) {
|
||||||
/* Add files i+1..argc-1 to filesystem. */
|
/* Add files i+1..argc-1 to filesystem. */
|
||||||
while (++i < argc)
|
while (++i < argc)
|
||||||
add_file (&fs, argv[i]);
|
add_file (&fs, argv[i]);
|
||||||
fs_sync (&fs, 0);
|
fs_sync (&fs, 0);
|
||||||
fs_close (&fs);
|
fs_close (&fs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mount) {
|
if (mount) {
|
||||||
/* Mount the filesystem. */
|
/* Mount the filesystem. */
|
||||||
if (++i >= argc) {
|
if (++i >= argc) {
|
||||||
print_help (argv[0]);
|
print_help (argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return fs_mount(&fs, argv[i]);
|
return fs_mount(&fs, argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print the structure of flesystem. */
|
/* Print the structure of flesystem. */
|
||||||
fs_print (&fs, stdout);
|
fs_print (&fs, stdout);
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printf ("--------\n");
|
printf ("--------\n");
|
||||||
if (! fs_inode_get (&fs, &inode, BSDFS_ROOT_INODE)) {
|
if (! fs_inode_get (&fs, &inode, BSDFS_ROOT_INODE)) {
|
||||||
fprintf (stderr, "%s: cannot get inode 1\n", argv[i]);
|
fprintf (stderr, "%s: cannot get inode 1\n", argv[i]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
printf ("/\n");
|
printf ("/\n");
|
||||||
if (verbose > 1) {
|
if (verbose > 1) {
|
||||||
/* Print a list of blocks. */
|
/* Print a list of blocks. */
|
||||||
print_inode_blocks (&inode, stdout);
|
print_inode_blocks (&inode, stdout);
|
||||||
if (verbose > 2) {
|
if (verbose > 2) {
|
||||||
fs_inode_print (&inode, stdout);
|
fs_inode_print (&inode, stdout);
|
||||||
printf ("--------\n");
|
printf ("--------\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fs_directory_scan (&inode, "", scanner, (void*) stdout);
|
fs_directory_scan (&inode, "", scanner, (void*) stdout);
|
||||||
}
|
}
|
||||||
fs_close (&fs);
|
fs_close (&fs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
1340
tools/fsutil/inode.c
1340
tools/fsutil/inode.c
File diff suppressed because it is too large
Load Diff
@@ -32,298 +32,300 @@ extern int verbose;
|
|||||||
|
|
||||||
int fs_seek (fs_t *fs, unsigned long offset)
|
int fs_seek (fs_t *fs, unsigned long offset)
|
||||||
{
|
{
|
||||||
/* printf ("seek %ld, block %ld\n", offset, offset / BSDFS_BSIZE);*/
|
/* printf ("seek %ld, block %ld\n", offset, offset / BSDFS_BSIZE);*/
|
||||||
if (lseek (fs->fd, offset, 0) < 0) {
|
if (lseek (fs->fd, offset, 0) < 0) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf ("error seeking %ld, block %ld\n",
|
printf ("error seeking %ld, block %ld\n",
|
||||||
offset, offset / BSDFS_BSIZE);
|
offset, offset / BSDFS_BSIZE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fs->seek = offset;
|
fs->seek = offset;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_read8 (fs_t *fs, unsigned char *val)
|
int fs_read8 (fs_t *fs, unsigned char *val)
|
||||||
{
|
{
|
||||||
if (read (fs->fd, val, 1) != 1) {
|
if (read (fs->fd, val, 1) != 1) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf ("error read8, seek %ld block %ld\n", fs->seek, fs->seek / BSDFS_BSIZE);
|
printf ("error read8, seek %ld block %ld\n", fs->seek, fs->seek / BSDFS_BSIZE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_read16 (fs_t *fs, unsigned short *val)
|
int fs_read16 (fs_t *fs, unsigned short *val)
|
||||||
{
|
{
|
||||||
unsigned char data [2];
|
unsigned char data [2];
|
||||||
|
|
||||||
if (read (fs->fd, data, 2) != 2) {
|
if (read (fs->fd, data, 2) != 2) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf ("error read16, seek %ld block %ld\n", fs->seek, fs->seek / BSDFS_BSIZE);
|
printf ("error read16, seek %ld block %ld\n", fs->seek, fs->seek / BSDFS_BSIZE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*val = data[1] << 8 | data[0];
|
*val = data[1] << 8 | data[0];
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_read32 (fs_t *fs, unsigned *val)
|
int fs_read32 (fs_t *fs, unsigned *val)
|
||||||
{
|
{
|
||||||
unsigned char data [4];
|
unsigned char data [4];
|
||||||
|
|
||||||
if (read (fs->fd, data, 4) != 4) {
|
if (read (fs->fd, data, 4) != 4) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf ("error read32, seek %ld block %ld\n", fs->seek, fs->seek / BSDFS_BSIZE);
|
printf ("error read32, seek %ld block %ld\n", fs->seek, fs->seek / BSDFS_BSIZE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*val = (unsigned long) data[0] | (unsigned long) data[1] << 8 |
|
*val = (unsigned long) data[0] | (unsigned long) data[1] << 8 |
|
||||||
data[2] << 16 | data[3] << 24;
|
data[2] << 16 | data[3] << 24;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_write8 (fs_t *fs, unsigned char val)
|
int fs_write8 (fs_t *fs, unsigned char val)
|
||||||
{
|
{
|
||||||
if (write (fs->fd, &val, 1) != 1)
|
if (write (fs->fd, &val, 1) != 1)
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_write16 (fs_t *fs, unsigned short val)
|
int fs_write16 (fs_t *fs, unsigned short val)
|
||||||
{
|
{
|
||||||
unsigned char data [2];
|
unsigned char data [2];
|
||||||
|
|
||||||
data[0] = val;
|
data[0] = val;
|
||||||
data[1] = val >> 8;
|
data[1] = val >> 8;
|
||||||
if (write (fs->fd, data, 2) != 2)
|
if (write (fs->fd, data, 2) != 2)
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_write32 (fs_t *fs, unsigned val)
|
int fs_write32 (fs_t *fs, unsigned val)
|
||||||
{
|
{
|
||||||
unsigned char data [4];
|
unsigned char data [4];
|
||||||
|
|
||||||
data[0] = val;
|
data[0] = val;
|
||||||
data[1] = val >> 8;
|
data[1] = val >> 8;
|
||||||
data[2] = val >> 16;
|
data[2] = val >> 16;
|
||||||
data[3] = val >> 24;
|
data[3] = val >> 24;
|
||||||
if (write (fs->fd, data, 4) != 4)
|
if (write (fs->fd, data, 4) != 4)
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_read (fs_t *fs, unsigned char *data, int bytes)
|
int fs_read (fs_t *fs, unsigned char *data, int bytes)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
while (bytes > 0) {
|
while (bytes > 0) {
|
||||||
len = bytes;
|
len = bytes;
|
||||||
if (len > 16*BSDFS_BSIZE)
|
if (len > 16*BSDFS_BSIZE)
|
||||||
len = 16*BSDFS_BSIZE;
|
len = 16*BSDFS_BSIZE;
|
||||||
if (read (fs->fd, data, len) != len)
|
if (read (fs->fd, data, len) != len)
|
||||||
return 0;
|
return 0;
|
||||||
data += len;
|
data += len;
|
||||||
bytes -= len;
|
bytes -= len;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_write (fs_t *fs, unsigned char *data, int bytes)
|
int fs_write (fs_t *fs, unsigned char *data, int bytes)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (! fs->writable)
|
if (! fs->writable)
|
||||||
return 0;
|
return 0;
|
||||||
while (bytes > 0) {
|
while (bytes > 0) {
|
||||||
len = bytes;
|
len = bytes;
|
||||||
if (len > 16*BSDFS_BSIZE)
|
if (len > 16*BSDFS_BSIZE)
|
||||||
len = 16*BSDFS_BSIZE;
|
len = 16*BSDFS_BSIZE;
|
||||||
if (write (fs->fd, data, len) != len)
|
if (write (fs->fd, data, len) != len)
|
||||||
return 0;
|
return 0;
|
||||||
data += len;
|
data += len;
|
||||||
bytes -= len;
|
bytes -= len;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_open (fs_t *fs, const char *filename, int writable)
|
int fs_open (fs_t *fs, const char *filename, int writable)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned magic;
|
unsigned magic;
|
||||||
|
|
||||||
memset (fs, 0, sizeof (*fs));
|
memset (fs, 0, sizeof (*fs));
|
||||||
fs->filename = filename;
|
fs->filename = filename;
|
||||||
fs->seek = 0;
|
fs->seek = 0;
|
||||||
|
|
||||||
fs->fd = open (fs->filename, writable ? O_RDWR : O_RDONLY);
|
fs->fd = open (fs->filename, writable ? O_RDWR : O_RDONLY);
|
||||||
if (fs->fd < 0)
|
if (fs->fd < 0)
|
||||||
return 0;
|
return 0;
|
||||||
fs->writable = writable;
|
fs->writable = writable;
|
||||||
|
|
||||||
if (! fs_read32 (fs, &magic) || /* magic word */
|
if (! fs_read32 (fs, &magic) || /* magic word */
|
||||||
magic != FSMAGIC1) {
|
magic != FSMAGIC1) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf ("fs_open: bad magic1 = %08x, expected %08x\n",
|
printf ("fs_open: bad magic1 = %08x, expected %08x\n",
|
||||||
magic, FSMAGIC1);
|
magic, FSMAGIC1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (! fs_read32 (fs, &fs->isize)) /* size in blocks of I list */
|
if (! fs_read32 (fs, &fs->isize)) /* size in blocks of I list */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_read32 (fs, &fs->fsize)) /* size in blocks of entire volume */
|
if (! fs_read32 (fs, &fs->fsize)) /* size in blocks of entire volume */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_read32 (fs, &fs->swapsz)) /* size in blocks of swap area */
|
if (! fs_read32 (fs, &fs->swapsz)) /* size in blocks of swap area */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_read32 (fs, &fs->nfree)) /* number of in core free blocks */
|
if (! fs_read32 (fs, &fs->nfree)) /* number of in core free blocks */
|
||||||
return 0;
|
return 0;
|
||||||
for (i=0; i<NICFREE; ++i) { /* in core free blocks */
|
for (i=0; i<NICFREE; ++i) { /* in core free blocks */
|
||||||
if (! fs_read32 (fs, &fs->free[i]))
|
if (! fs_read32 (fs, &fs->free[i]))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (! fs_read32 (fs, &fs->ninode)) /* number of in core I nodes */
|
if (! fs_read32 (fs, &fs->ninode)) /* number of in core I nodes */
|
||||||
return 0;
|
return 0;
|
||||||
for (i=0; i<NICINOD; ++i) { /* in core free I nodes */
|
for (i=0; i<NICINOD; ++i) { /* in core free I nodes */
|
||||||
if (! fs_read32 (fs, &fs->inode[i]))
|
if (! fs_read32 (fs, &fs->inode[i]))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (! fs_read32 (fs, &fs->flock))
|
if (! fs_read32 (fs, &fs->flock))
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_read32 (fs, &fs->fmod))
|
if (! fs_read32 (fs, &fs->fmod))
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_read32 (fs, &fs->ilock))
|
if (! fs_read32 (fs, &fs->ilock))
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_read32 (fs, &fs->ronly))
|
if (! fs_read32 (fs, &fs->ronly))
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_read32 (fs, (unsigned*) &fs->utime))
|
if (! fs_read32 (fs, (unsigned*) &fs->utime))
|
||||||
return 0; /* current date of last update */
|
return 0; /* current date of last update */
|
||||||
if (! fs_read32 (fs, &fs->tfree)) /* total free blocks */
|
if (! fs_read32 (fs, &fs->tfree)) /* total free blocks */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_read32 (fs, &fs->tinode)) /* total free inodes */
|
if (! fs_read32 (fs, &fs->tinode)) /* total free inodes */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_read (fs, (unsigned char*) fs->fsmnt, MAXMNTLEN))
|
if (! fs_read (fs, (unsigned char*) fs->fsmnt, MAXMNTLEN))
|
||||||
return 0; /* ordinary file mounted on */
|
return 0; /* ordinary file mounted on */
|
||||||
if (! fs_read32 (fs, &fs->lasti)) /* start place for circular search */
|
if (! fs_read32 (fs, &fs->lasti)) /* start place for circular search */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_read32 (fs, &fs->nbehind)) /* est # free inodes before s_lasti */
|
if (! fs_read32 (fs, &fs->nbehind)) /* est # free inodes before s_lasti */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_read32 (fs, &fs->flags)) /* mount time flags */
|
if (! fs_read32 (fs, &fs->flags)) /* mount time flags */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_read32 (fs, &magic) || /* magic word */
|
if (! fs_read32 (fs, &magic) || /* magic word */
|
||||||
magic != FSMAGIC2) {
|
magic != FSMAGIC2) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf ("fs_open: bad magic2 = %08x, expected %08x\n",
|
printf ("fs_open: bad magic2 = %08x, expected %08x\n",
|
||||||
magic, FSMAGIC2);
|
magic, FSMAGIC2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_sync (fs_t *fs, int force)
|
int fs_sync (fs_t *fs, int force)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (! fs->writable)
|
if (! fs->writable)
|
||||||
return 0;
|
return 0;
|
||||||
if (! force && ! fs->dirty)
|
if (! force && ! fs->dirty)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
time (&fs->utime);
|
time (&fs->utime);
|
||||||
if (! fs_seek (fs, 0))
|
if (! fs_seek (fs, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (! fs_write32 (fs, FSMAGIC1)) /* magic word */
|
if (! fs_write32 (fs, FSMAGIC1)) /* magic word */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write32 (fs, fs->isize)) /* size in blocks of I list */
|
if (! fs_write32 (fs, fs->isize)) /* size in blocks of I list */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write32 (fs, fs->fsize)) /* size in blocks of entire volume */
|
if (! fs_write32 (fs, fs->fsize)) /* size in blocks of entire volume */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write32 (fs, fs->swapsz)) /* size in blocks of swap area */
|
if (! fs_write32 (fs, fs->swapsz)) /* size in blocks of swap area */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write32 (fs, fs->nfree)) /* number of in core free blocks */
|
if (! fs_write32 (fs, fs->nfree)) /* number of in core free blocks */
|
||||||
return 0;
|
return 0;
|
||||||
for (i=0; i<NICFREE; ++i) { /* in core free blocks */
|
for (i=0; i<NICFREE; ++i) { /* in core free blocks */
|
||||||
if (! fs_write32 (fs, fs->free[i]))
|
if (! fs_write32 (fs, fs->free[i]))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (! fs_write32 (fs, fs->ninode)) /* number of in core I nodes */
|
if (! fs_write32 (fs, fs->ninode)) /* number of in core I nodes */
|
||||||
return 0;
|
return 0;
|
||||||
for (i=0; i<NICINOD; ++i) { /* in core free I nodes */
|
for (i=0; i<NICINOD; ++i) { /* in core free I nodes */
|
||||||
if (! fs_write32 (fs, fs->inode[i]))
|
if (! fs_write32 (fs, fs->inode[i]))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (! fs_write32 (fs, fs->flock))
|
if (! fs_write32 (fs, fs->flock))
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write32 (fs, fs->fmod))
|
if (! fs_write32 (fs, fs->fmod))
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write32 (fs, fs->ilock))
|
if (! fs_write32 (fs, fs->ilock))
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write32 (fs, fs->ronly))
|
if (! fs_write32 (fs, fs->ronly))
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write32 (fs, fs->utime)) /* current date of last update */
|
if (! fs_write32 (fs, fs->utime)) /* current date of last update */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write32 (fs, fs->tfree)) /* total free blocks */
|
if (! fs_write32 (fs, fs->tfree)) /* total free blocks */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write32 (fs, fs->tinode)) /* total free inodes */
|
if (! fs_write32 (fs, fs->tinode)) /* total free inodes */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write (fs, (unsigned char*) fs->fsmnt, MAXMNTLEN))
|
if (! fs_write (fs, (unsigned char*) fs->fsmnt, MAXMNTLEN))
|
||||||
return 0; /* ordinary file mounted on */
|
return 0; /* ordinary file mounted on */
|
||||||
if (! fs_write32 (fs, 0)) /* lasti*/
|
if (! fs_write32 (fs, 0)) /* lasti*/
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write32 (fs, 0)) /* nbehind */
|
if (! fs_write32 (fs, 0)) /* nbehind */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write32 (fs, 0)) /* flags */
|
if (! fs_write32 (fs, 0)) /* flags */
|
||||||
return 0;
|
return 0;
|
||||||
if (! fs_write32 (fs, FSMAGIC2)) /* magic word */
|
if (! fs_write32 (fs, FSMAGIC2)) /* magic word */
|
||||||
return 0;
|
return 0;
|
||||||
fs->dirty = 0;
|
fs->dirty = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fs_print (fs_t *fs, FILE *out)
|
void fs_print (fs_t *fs, FILE *out)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
fprintf (out, " File: %s\n", fs->filename);
|
fprintf (out, " File: %s\n", fs->filename);
|
||||||
fprintf (out, " Volume size: %u blocks\n", fs->fsize);
|
fprintf (out, " Volume size: %u blocks\n", fs->fsize);
|
||||||
fprintf (out, " Inode list size: %u blocks\n", fs->isize);
|
fprintf (out, " Inode list size: %u blocks\n", fs->isize);
|
||||||
fprintf (out, " Swap size: %u blocks\n", fs->swapsz);
|
fprintf (out, " Swap size: %u blocks\n", fs->swapsz);
|
||||||
fprintf (out, " Total free blocks: %u blocks\n", fs->tfree);
|
fprintf (out, " Total free blocks: %u blocks\n", fs->tfree);
|
||||||
fprintf (out, " Total free inodes: %u inodes\n", fs->tinode);
|
fprintf (out, " Total free inodes: %u inodes\n", fs->tinode);
|
||||||
fprintf (out, " Last mounted on: %.*s\n", MAXMNTLEN,
|
fprintf (out, " Last mounted on: %.*s\n", MAXMNTLEN,
|
||||||
fs->fsmnt[0] ? fs->fsmnt : "(none)");
|
fs->fsmnt[0] ? fs->fsmnt : "(none)");
|
||||||
fprintf (out, " In-core free list: %u blocks", fs->nfree);
|
fprintf (out, " In-core free list: %u blocks", fs->nfree);
|
||||||
if (verbose)
|
if (verbose) {
|
||||||
for (i=0; i < NICFREE && i < fs->nfree; ++i) {
|
for (i=0; i < NICFREE && i < fs->nfree; ++i) {
|
||||||
if (i % 10 == 0)
|
if (i % 10 == 0)
|
||||||
fprintf (out, "\n ");
|
fprintf (out, "\n ");
|
||||||
fprintf (out, " %u", fs->free[i]);
|
fprintf (out, " %u", fs->free[i]);
|
||||||
}
|
}
|
||||||
fprintf (out, "\n");
|
}
|
||||||
|
fprintf (out, "\n");
|
||||||
|
|
||||||
fprintf (out, " In-core free inodes: %u inodes", fs->ninode);
|
fprintf (out, " In-core free inodes: %u inodes", fs->ninode);
|
||||||
if (verbose)
|
if (verbose) {
|
||||||
for (i=0; i < NICINOD && i < fs->ninode; ++i) {
|
for (i=0; i < NICINOD && i < fs->ninode; ++i) {
|
||||||
if (i % 10 == 0)
|
if (i % 10 == 0)
|
||||||
fprintf (out, "\n ");
|
fprintf (out, "\n ");
|
||||||
fprintf (out, " %u", fs->inode[i]);
|
fprintf (out, " %u", fs->inode[i]);
|
||||||
}
|
}
|
||||||
fprintf (out, "\n");
|
}
|
||||||
if (verbose) {
|
fprintf (out, "\n");
|
||||||
// fprintf (out, " Free list lock: %u\n", fs->flock);
|
if (verbose) {
|
||||||
// fprintf (out, " Inode list lock: %u\n", fs->ilock);
|
// fprintf (out, " Free list lock: %u\n", fs->flock);
|
||||||
// fprintf (out, "Super block modified: %u\n", fs->fmod);
|
// fprintf (out, " Inode list lock: %u\n", fs->ilock);
|
||||||
// fprintf (out, " Mounted read-only: %u\n", fs->ronly);
|
// fprintf (out, "Super block modified: %u\n", fs->fmod);
|
||||||
// fprintf (out, " Circ.search start: %u\n", fs->lasti);
|
// fprintf (out, " Mounted read-only: %u\n", fs->ronly);
|
||||||
// fprintf (out, " Circ.search behind: %u\n", fs->nbehind);
|
// fprintf (out, " Circ.search start: %u\n", fs->lasti);
|
||||||
// fprintf (out, " Mount flags: 0x%x\n", fs->flags);
|
// fprintf (out, " Circ.search behind: %u\n", fs->nbehind);
|
||||||
}
|
// fprintf (out, " Mount flags: 0x%x\n", fs->flags);
|
||||||
|
}
|
||||||
|
|
||||||
fprintf (out, " Last update time: %s", ctime (&fs->utime));
|
fprintf (out, " Last update time: %s", ctime (&fs->utime));
|
||||||
}
|
}
|
||||||
|
|
||||||
void fs_close (fs_t *fs)
|
void fs_close (fs_t *fs)
|
||||||
{
|
{
|
||||||
if (fs->fd < 0)
|
if (fs->fd < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
close (fs->fd);
|
close (fs->fd);
|
||||||
fs->fd = -1;
|
fs->fd = -1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user