11.15Schs/* $NetBSD: readufs_ffs.c,v 1.15 2022/11/17 06:40:39 chs Exp $ */ 21.3Sitohy/* from Id: readufs_ffs.c,v 1.6 2003/04/08 09:19:32 itohy Exp */ 31.1Sminoura 41.1Sminoura/* 51.1Sminoura * FS specific support for 4.2BSD Fast Filesystem 61.1Sminoura * 71.13Sitohy * Written in 1999, 2002, 2003 by ITOH Yasufumi. 81.1Sminoura * Public domain. 91.1Sminoura * 101.1Sminoura * Intended to be used for boot programs (first stage). 111.1Sminoura * DON'T ADD ANY FANCY FEATURE. THIS SHALL BE COMPACT. 121.1Sminoura */ 131.1Sminoura 141.3Sitohy#include "readufs.h" 151.3Sitohy 161.1Sminoura#include <ufs/ffs/fs.h> 171.1Sminoura 181.10Sdslstatic int get_ffs_inode(ino32_t ino, union ufs_dinode *dibuf); 191.1Sminoura 201.1Sminoura#define fsi (*ufsinfo) 211.1Sminoura#define fsi_ffs fsi.fs_u.u_ffs 221.1Sminoura 231.1Sminoura/* 241.1Sminoura * Read and check superblock. 251.1Sminoura * If it is an FFS, save information from the superblock. 261.1Sminoura */ 271.1Sminouraint 281.12Sceggertry_ffs(void) 291.1Sminoura{ 301.1Sminoura union { 311.1Sminoura struct fs sblk; 321.3Sitohy unsigned char pad[SBLOCKSIZE]; 331.1Sminoura } buf; 341.1Sminoura struct ufs_info *ufsinfo = &ufs_info; 351.3Sitohy static const int sblocs[] = SBLOCKSEARCH; 361.3Sitohy const int *sbl; 371.3Sitohy int magic; 381.1Sminoura 391.1Sminoura#ifdef DEBUG_WITH_STDIO 401.1Sminoura printf("trying FFS\n"); 411.1Sminoura#endif 421.1Sminoura /* read FFS superblock */ 431.3Sitohy for (sbl = sblocs; ; sbl++) { 441.3Sitohy if (*sbl == -1) 451.3Sitohy return 1; 461.1Sminoura 471.3Sitohy RAW_READ(&buf, (daddr_t) btodb(*sbl), SBLOCKSIZE); 481.3Sitohy 491.3Sitohy magic = buf.sblk.fs_magic; 501.1Sminoura#ifdef DEBUG_WITH_STDIO 511.3Sitohy printf("FFS: sblk: pos %d magic 0x%x\n", btodb(*sbl), magic); 521.1Sminoura#endif 531.7Sdsl#ifdef USE_UFS1 541.7Sdsl if (magic == FS_UFS1_MAGIC 551.7Sdsl && !(buf.sblk.fs_old_flags & FS_FLAGS_UPDATED)) { 561.6Sdsl if (*sbl == SBLOCK_UFS2) 571.6Sdsl /* might be an alternate suberblock */ 581.6Sdsl continue; 591.7Sdsl break; 601.6Sdsl } 611.7Sdsl#endif 621.7Sdsl if (*sbl != buf.sblk.fs_sblockloc) 631.7Sdsl /* must be an alternate suberblock */ 641.7Sdsl continue; 651.1Sminoura 661.3Sitohy#ifdef USE_UFS1 671.7Sdsl if (magic == FS_UFS1_MAGIC) { 681.3Sitohy break; 691.7Sdsl } 701.3Sitohy#endif 711.3Sitohy#ifdef USE_UFS2 721.15Schs if (magic == FS_UFS2_MAGIC || magic == FS_UFS2EA_MAGIC) { 731.3Sitohy#ifdef USE_UFS1 741.3Sitohy fsi.ufstype = UFSTYPE_UFS2; 751.3Sitohy#endif 761.3Sitohy break; 771.3Sitohy } 781.3Sitohy#endif 791.3Sitohy } 801.3Sitohy 811.3Sitohy /* 821.3Sitohy * XXX <ufs/ffs/fs.h> always uses fs_magic 831.3Sitohy * (UFS1 only or UFS2 only is impossible) 841.3Sitohy */ 851.3Sitohy fsi_ffs.magic = magic; 861.3Sitohy#ifdef DEBUG_WITH_STDIO 871.15Schs printf("FFS: detected UFS%d format\n", 881.15Schs (magic == FS_UFS2_MAGIC || magic == FS_UFS2EA_MAGIC) + 1); 891.3Sitohy#endif 901.1Sminoura 911.1Sminoura /* This partition looks like an FFS. */ 921.1Sminoura fsi.fstype = UFSTYPE_FFS; 931.1Sminoura fsi.get_inode = get_ffs_inode; 941.1Sminoura 951.1Sminoura /* Get information from the superblock. */ 961.1Sminoura fsi.bsize = buf.sblk.fs_bsize; 971.1Sminoura fsi.fsbtodb = buf.sblk.fs_fsbtodb; 981.1Sminoura fsi.nindir = buf.sblk.fs_nindir; 991.1Sminoura 1001.1Sminoura fsi_ffs.iblkno = buf.sblk.fs_iblkno; 1011.3Sitohy fsi_ffs.old_cgoffset = buf.sblk.fs_old_cgoffset; 1021.3Sitohy fsi_ffs.old_cgmask = buf.sblk.fs_old_cgmask; 1031.1Sminoura fsi_ffs.fragshift = buf.sblk.fs_fragshift; 1041.1Sminoura fsi_ffs.inopb = buf.sblk.fs_inopb; 1051.1Sminoura fsi_ffs.ipg = buf.sblk.fs_ipg; 1061.1Sminoura fsi_ffs.fpg = buf.sblk.fs_fpg; 1071.1Sminoura 1081.1Sminoura return 0; 1091.1Sminoura} 1101.1Sminoura 1111.1Sminoura/* for inode macros */ 1121.1Sminoura#define fs_ipg fs_u.u_ffs.ipg 1131.1Sminoura#define fs_iblkno fs_u.u_ffs.iblkno 1141.3Sitohy#define fs_old_cgoffset fs_u.u_ffs.old_cgoffset 1151.3Sitohy#define fs_old_cgmask fs_u.u_ffs.old_cgmask 1161.1Sminoura#define fs_fpg fs_u.u_ffs.fpg 1171.3Sitohy#define fs_magic fs_u.u_ffs.magic 1181.1Sminoura#define fs_inopb fs_u.u_ffs.inopb 1191.1Sminoura#define fs_fragshift fs_u.u_ffs.fragshift 1201.1Sminoura#define fs_fsbtodb fsbtodb 1211.1Sminoura 1221.1Sminoura/* 1231.1Sminoura * Get inode from disk. 1241.1Sminoura */ 1251.1Sminourastatic int 1261.11Sdslget_ffs_inode(ino32_t ino, union ufs_dinode *dibuf) 1271.1Sminoura{ 1281.1Sminoura struct ufs_info *ufsinfo = &ufs_info; 1291.3Sitohy union ufs_dinode *buf = alloca((size_t) fsi.bsize); 1301.3Sitohy union ufs_dinode *di; 1311.3Sitohy unsigned ioff; 1321.1Sminoura 1331.14Sdholland RAW_READ(buf, FFS_FSBTODB(&fsi, ino_to_fsba(&fsi, ino)), 1341.1Sminoura (size_t) fsi.bsize); 1351.1Sminoura 1361.3Sitohy ioff = ino_to_fsbo(&fsi, ino); 1371.3Sitohy 1381.3Sitohy#if defined(USE_UFS1) && defined(USE_UFS2) 1391.3Sitohy if (ufsinfo->ufstype == UFSTYPE_UFS1) 1401.3Sitohy di = (void *) &(&buf->di1)[ioff]; 1411.3Sitohy else { 1421.3Sitohy di = (void *) &(&buf->di2)[ioff]; 1431.3Sitohy 1441.3Sitohy /* XXX for DI_SIZE() macro */ 1451.3Sitohy di->di1.di_size = di->di2.di_size; 1461.3Sitohy } 1471.3Sitohy#else 1481.3Sitohy di = &buf[ioff]; 1491.3Sitohy#endif 1501.3Sitohy 1511.1Sminoura#ifdef DEBUG_WITH_STDIO 1521.3Sitohy printf("FFS: dinode(%d): mode 0%o, nlink %d, size %u\n", 1531.3Sitohy ino, di->di_common.di_mode, di->di_common.di_nlink, 1541.3Sitohy (unsigned) DI_SIZE(di)); 1551.1Sminoura#endif 1561.1Sminoura 1571.3Sitohy if (di->di_common.di_mode == 0) 1581.1Sminoura return 1; /* unused inode (file is not found) */ 1591.1Sminoura 1601.1Sminoura *dibuf = *di; 1611.1Sminoura 1621.1Sminoura return 0; 1631.1Sminoura} 164