1
0
Files
irix-657m-src/eoe/cmd/efs/nlib/libefs.h
2022-09-29 17:59:04 +03:00

255 lines
7.7 KiB
C

/*
* libefs.a declarations
*
* libefs is a useful collection of subprograms to manipulate EFS data
* structures (superblock, bitmap, inodes, extents, directories).
* The similarity to kernel EFS ends at the data structures -- there's no
* attempt to mimic the kernel's allocation policies, etc.
*
* Even though these subprograms are used in mkfs and fsr this collection
* does not presume to be a well designed library. User beware: some
* routines do _not_ mix well with others, and some routines expect
* prerequisite callers and most routines don't expend much effort
* checking arguments.
*
* $Revision: 1.11 $
*/
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <sys/syssgi.h>
#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <values.h>
#include <sys/fs/efs.h>
#ifdef BIG
extern int __efs_block_size;
#define __EFS_SWITCH_VAL __efs_block_size
#else
#define EFS_BBSIZE BBSIZE
#define EFS_BIG_BBSIZE BBSIZE
#define EFS_SMALL_BBSIZE BBSIZE
#define EFS_BBTOB(x) BBTOB(x)
#define EFS_BTOBB(x) ((int)BTOBB(x))
#define EFS_BTOBBT(x) ((int)BTOBBT(x))
#endif
#define ISDOT(namep, len) ((len) == 1 && *(namep) == '.')
#define ISDOTORDOTDOT(np, len) (*(np) == '.' && \
((len) == 1 || ((len) == 2 && *((np)+1) == '.')))
/*
* All libefs.a reads and writes are by block mostly because >2gb file
* systems must be read using the SGI-special block read/write system call.
*/
#define efs_readb(fd, buf, blk, nblks) \
efs_rdwrb(SGI_READB, fd, buf, blk, nblks)
#define efs_writeb(fd, buf, blk, nblks) \
efs_rdwrb(SGI_WRITEB, fd, buf, blk, nblks)
extern efs_rdwrb(int rdwr, int fd, char *buf, efs_daddr_t blk, int nblks);
#define bset(bp, b) (*((bp) + ((b) >> 3)) |= 1 << ((b) & 7))
#define bclr(bp, b) (*((bp) + ((b) >> 3)) &= ~(1 << ((b) & 7)))
#define btst(bp, b) (*((bp) + ((b) >> 3)) & (1 << ((b) & 7)))
#define tstfree btst
typedef struct efs_mount {
struct efs *m_fs;
dev_t m_dev;
int m_fd;
struct efs_dinode **m_ilist;
char *m_devname; /* used only in debug/error printing */
char *m_bitmap;
char *m_progname;
int active; /* GUI uses to bypass failed units */
char tofile[40];
} EFS_MOUNT;
/*
* initialize libefs. arg is function for printing error messages from
* within the library -- default is fprintf(stderr, )
*/
extern void efs_init(int (*func)(const char *,...));
extern int (*efs_errpr)(const char*, ...);
extern int _efsprintf(const char*, ...);
extern char *devnm(dev_t);
extern char filetype(ushort);
/*
* efs_mount() open(2)s the specified file system device (must be a char dev)
* with the given mode (bits defined in <fcntl.h>), mallocs space for and reads
* in the superblock (m_fs) and saves the devname in a malloc'ed buffer
* (m_devname). efs_umount() * closes the device file and frees the malloc'ed
* space for m_fs, m_devname, and the specified struct efs_mount itself.
*/
extern EFS_MOUNT *efs_mount(char *devname, int rw);
extern void efs_umount(EFS_MOUNT* mp);
extern long efs_checksum(struct efs *fs);
/* Some handy macros to compute file system capacity from superblock data */
#define CAPACITYBLKS(fs) ((fs)->fs_ncg * ((fs)->fs_cgfsize - (fs)->fs_cgisize))
#define CAPACITYINODES(fs) ((fs)->fs_ncg * (fs)->fs_cgisize * EFS_INOPBB - 2)
/*
* efs_iget() returns a pointer to a _static_buffer_ containing the disk inode
* for the specified inode. efs_igetcg() mallocs and reads in all inode blocks
* for the specified cylinder group. efs_getextents() mallocs and copies/reads
* the extents for the file specified by the struct efs_dinode. efs_figet()
* returns a pointer to the inum within an internally maintained pool of
* i-lists it reads using efs_igetcg() XXX there is no "free" analog
*/
extern struct efs_dinode *efs_iget(EFS_MOUNT *mp, efs_ino_t inum);
extern struct efs_dinode *efs_figet(EFS_MOUNT *mp, efs_ino_t inum);
extern struct efs_dinode *efs_igetcg(EFS_MOUNT *mp, int cgno);
extern extent *efs_getextents(EFS_MOUNT *mp, struct efs_dinode *di,
efs_ino_t inum);
/*
* efs_iput writes a single inode back to disk.
*/
extern int efs_iput(EFS_MOUNT *mp, struct efs_dinode *dip, efs_ino_t ino);
/*
* Create a new inode.
*/
extern void efs_mknod(EFS_MOUNT *mp, efs_ino_t ino, ushort mode, ushort uid,
ushort gid);
/*
* malloc and read in the bitmap for the specified mounted file system
*/
extern int efs_bget(EFS_MOUNT *mp);
extern int efs_bput(EFS_MOUNT *mp);
extern void efs_bfree(EFS_MOUNT *mp);
/*
* read in all inodes, dirblks and indirect extents using the efs_dinode
* as an "in-core" inode
*/
extern efs_ino_t efs_readinodes(EFS_MOUNT *mp, FILE *progress, int *blkcount,
int flags);
#define DIDATA(d,t) ((t)(&(d)->di_u.di_extents[0]))
typedef struct {
char *dirblkp; /* if directory */
int dirblocks; /* " */
extent *ex; /* if indirect extents */
int indirblks;
} didata;
/*
* Number of blocks of indirect extents.
* Assumes 1) ne > EFS_DIRECTECTEXTENTS,
* and 2) each indirect extent is fully packed.
*/
#define INDIRBLKS(ne) (ne * sizeof(extent) / BBSIZE + 1)
#define DATABLKS(ex, ne) \
(((ex) + (ne) - 1)->ex_offset + ((ex) + (ne) - 1)->ex_length)
#define INUMTODI(mp, inum) \
mp->m_ilist[EFS_ITOCG(mp->m_fs, inum)] + \
inum % (mp->m_fs->fs_cgisize*EFS_INOPBB)
/*
* print inode, superblock and bitmap
*/
extern void efs_prino(FILE *fp, EFS_MOUNT *mp,
efs_ino_t inum, struct efs_dinode *dip, extent *ext, char *name,
int nl);
extern prsuper(FILE *fp, EFS_MOUNT *mp);
extern prbit(FILE *fp, EFS_MOUNT *mp);
/*
* map name to inum
*/
extern efs_ino_t efs_namei(EFS_MOUNT *mp, char *filename);
/*
* directory stuff
* XXX this should present either a getdents(2) or opendir(3) interface
*/
typedef struct {
char *dir_blkp;
int dir_nblocks;
int dir_curblk;
int dir_curslot;
EFS_MOUNT *dir_mp;
} EFS_DIR;
extern EFS_DIR *efs_opendir(EFS_MOUNT *mp, char *filename);
extern EFS_DIR *efs_opendiri(EFS_MOUNT *mp, efs_ino_t inum);
extern EFS_DIR *efs_opendirb(char *dp, int nblocks);
extern struct efs_dent *efs_readdir(EFS_DIR *dirp);
extern void efs_closedir(EFS_DIR *dirp);
extern char *efs_getdirblks(int fd, struct efs_dinode *dp, extent *ex,
efs_ino_t inum);
extern void efs_rewinddir(EFS_DIR *dirp);
/*
* "ftw"
*/
extern void efs_walk(EFS_MOUNT *mp, efs_ino_t inum, char *dirname, int flags,
void (*dodent)(EFS_MOUNT *mp, struct efs_dent *, char *, int));
extern void efs_ddent(EFS_MOUNT *, struct efs_dent *dentp, char *dirname,
int flags);
#define DO_EXT 0x00000001
#define DO_RECURSE 0x00000002
extern void efs_extend(EFS_MOUNT *mp, struct efs_dinode *di, int incr);
extern efs_daddr_t efs_bmap(EFS_MOUNT *mp, struct efs_dinode *di, off_t offset,
off_t count);
/*
* Enter the given name/inode pair into the given directory.
*/
extern void efs_enter(EFS_MOUNT *mp, efs_ino_t dirinum, efs_ino_t inum,
char *name);
/*
* Extend the given file by allocating data blocks.
*/
extern void efs_extend(EFS_MOUNT *mp, struct efs_dinode *di, int incr);
/*
* Make the lost+found directory. Just grow it, sinces its already
* got "." and "..".
*/
extern void efs_mklostandfound(EFS_MOUNT *mp, efs_ino_t ino);
extern efs_ino_t efs_allocino(EFS_MOUNT *mp);
extern dev_t efs_getdev(union di_addr *di);
extern void efs_putdev(dev_t dev, union di_addr *di);
/*
* Creates a new regular file at the given inode and name.
* (This doesn't make the directory entry).
*/
extern void efs_newregfile(EFS_MOUNT *mp, efs_ino_t ino, char *name);
/*
* Write into a file. Data is always appended.
*/
extern void efs_write(EFS_MOUNT *mp, efs_ino_t ino, char *data, int len);
extern void error(void);