1
0
Files
irix-657m-src/eoe/cmd/mediad/fmt_efs.C
2022-09-29 17:59:04 +03:00

88 lines
2.2 KiB
C

#include <sys/param.h>
#include <bstring.h>
#include <diskinfo.h>
#include <sys/dvh.h>
#include <sys/file.h>
#include <sys/fs/efs.h>
#include "Device.H"
#include "Log.H"
#include "Partition.H"
#include "PartitionAddress.H"
#include "SimpleVolume.H"
class FormatDSO;
#define EFS_BLKSIZE 512
extern "C" int valid_efs(struct efs *sblk, int size); // (from libdisk)
static void
create_efs_volume(Device *device, ptinfo *pp)
{
PartitionAddress paddr(device->address(), FMT_EFS, pp->ptnum);
Partition *part = Partition::create(paddr,
device,
EFS_BLKSIZE,
pp->pstartblk,
pp->psize,
"efs");
const char *fsname = device->dev_name(FMT_EFS, pp->ptnum);
mntent mnt = { (char *) fsname, NULL, "efs", NULL, 0, 0 };
(void) SimpleVolume::create(part, mnt, "");
}
bool has_efs_superblock(Device *dev, const ptinfo *pp)
{
char sbuf[BBTOB(BTOBB(sizeof (struct efs)))];
struct efs *sb = (struct efs *) sbuf;
__uint64_t sectno = pp->pstartblk + EFS_SUPERBB;
unsigned int nsects = sizeof sbuf / EFS_BLKSIZE;
if (dev->read_data(sbuf, sectno, nsects, EFS_BLKSIZE) != 0)
{ Log::critical("can't read sector %lld of device %s: %m",
sectno, dev->name());
return false;
}
return valid_efs(sb, pp->psize) == 1;
}
extern "C"
void
inspect(FormatDSO *, Device *device)
{
// Does this device support this format?
if (!device->filesys_efs())
return;
char buf[2048];
bzero(buf, sizeof buf);
int secsize = device->sector_size(FMT_EFS);
if (secsize != EFS_BLKSIZE)
return; // Give up.
if (device->read_data(buf, 0, sizeof buf / secsize, secsize) != 0)
return;
if (valid_vh((volume_header *) buf) == -1)
return;
const char *efsname = device->dev_name(FMT_EFS, 8);
if (strncmp(efsname, "/dev/dsk/", 9))
return;
char rawfsname[30];
sprintf(rawfsname, "/dev/rdsk/%s", efsname + 9);
Log::debug("EFS inspect: rawfsname = \"%s\"", rawfsname);
unsigned token = setdiskinfo(rawfsname, "/etc/fstab", O_RDONLY);
if (token)
{ for (ptinfo *pp; pp = getpartition(token); )
if (pp->psize != 0)
{ if (has_efs_superblock(device, pp))
create_efs_volume(device, pp);
}
enddiskinfo(token);
}
}