Пример #1
0
static int
init_dev(dev_info_t* dev)
{
	char buffer[BSD_LABEL_BUFFER];
	struct disklabel *dl;
	uint64_t bs;
	int ok;

	devinfo = dev;
	dmadat = &__dmadat;

	/*
	 * First try offset 0. This is the typical GPT case where we have no
	 * further partitioning (as well as the degenerate MBR case where
	 * the bsdlabel has a 0 offset).
	 */
	devinfo->partoff = 0;
	ok = fsread(0, NULL, 0);
	if (ok >= 0)
		return (ok);

	/*
	 * Next, we look for a bsdlabel. This is technically located in sector
	 * 1. For 4k sectors, this offset is 4096, for 512b sectors it's
	 * 512. However, we have to fall back to 512 here because we create
	 * images that assume 512 byte blocks, but these can be put on devices
	 * who have 4k (or other) block sizes. If there's a crazy block size, we
	 * skip the 'at one sector' and go stright to checking at 512 bytes.
	 * There are other offsets that are historic, but we don't probe those
	 * since they were never used for MBR disks on FreeBSD on systems that
	 * could boot UEFI. UEFI is little endian only, as are BSD labels. We
	 * will retry fsread(0) only if there's a label found with a non-zero
	 * offset.
	 */
	if (dskread(buffer, 0, BSD_LABEL_BUFFER / DEV_BSIZE) != 0)
		return (-1);
	dl = NULL;
	bs = devinfo->dev->Media->BlockSize;
	if (bs != 0 && bs <= BSD_LABEL_BUFFER / 2)
		dl = (struct disklabel *)&buffer[bs];
	if (dl == NULL || dl->d_magic != BSD_MAGIC || dl->d_magic2 != BSD_MAGIC)
		dl = (struct disklabel *)&buffer[BSD_LABEL_OFFSET];
	if (dl->d_magic != BSD_MAGIC || dl->d_magic2 != BSD_MAGIC ||
	    dl->d_partitions[0].p_offset == 0)
		return (-1);
	devinfo->partoff = dl->d_partitions[0].p_offset;
	return (fsread(0, NULL, 0));
}
Пример #2
0
static ssize_t
fsstat(ufs_ino_t inode)
{
#ifndef UFS2_ONLY
	static struct ufs1_dinode dp1;
#endif
#ifndef UFS1_ONLY
	static struct ufs2_dinode dp2;
#endif
	static struct fs fs;
	static ufs_ino_t inomap;
	char *blkbuf;
	void *indbuf;
	size_t n, size;
	static ufs2_daddr_t blkmap, indmap;

	blkbuf = dmadat->blkbuf;
	indbuf = dmadat->indbuf;
	if (!dsk_meta) {
		inomap = 0;
		for (n = 0; sblock_try[n] != -1; n++) {
			if (dskread(dmadat->sbbuf, sblock_try[n] / DEV_BSIZE,
			    SBLOCKSIZE / DEV_BSIZE))
				return -1;
			memcpy(&fs, dmadat->sbbuf, sizeof(struct fs));
			if ((
#if defined(UFS1_ONLY)
			    fs.fs_magic == FS_UFS1_MAGIC
#elif defined(UFS2_ONLY)
			    (fs.fs_magic == FS_UFS2_MAGIC &&
			    fs.fs_sblockloc == sblock_try[n])
#else
			    fs.fs_magic == FS_UFS1_MAGIC ||
			    (fs.fs_magic == FS_UFS2_MAGIC &&
			    fs.fs_sblockloc == sblock_try[n])
#endif
			    ) &&
			    fs.fs_bsize <= MAXBSIZE &&
			    fs.fs_bsize >= (int32_t)sizeof(struct fs))
				break;
		}
		if (sblock_try[n] == -1) {
			return -1;
		}
		dsk_meta++;
	} else
		memcpy(&fs, dmadat->sbbuf, sizeof(struct fs));
	if (!inode)
		return 0;
	if (inomap != inode) {
		n = IPERVBLK(&fs);
		if (dskread(blkbuf, INO_TO_VBA(&fs, n, inode), DBPERVBLK))
			return -1;
		n = INO_TO_VBO(n, inode);
#if defined(UFS1_ONLY)
		memcpy(&dp1, (struct ufs1_dinode *)blkbuf + n,
		    sizeof(struct ufs1_dinode));
#elif defined(UFS2_ONLY)
		memcpy(&dp2, (struct ufs2_dinode *)blkbuf + n,
		    sizeof(struct ufs2_dinode));
#else
		if (fs.fs_magic == FS_UFS1_MAGIC)
			memcpy(&dp1, (struct ufs1_dinode *)(void *)blkbuf + n,
			    sizeof(struct ufs1_dinode));
		else
			memcpy(&dp2, (struct ufs2_dinode *)(void *)blkbuf + n,
			    sizeof(struct ufs2_dinode));
#endif
		inomap = inode;
		fs_off = 0;
		blkmap = indmap = 0;
	}
	size = DIP(di_size);
	n = size - fs_off;
	return (n);
}