1 /* $NetBSD: readufs_ffs.c,v 1.1 2014/02/24 07:23:43 skrll Exp $ */ 2 /* from Id: readufs_ffs.c,v 1.8 2004/06/12 04:26:39 itohy Exp */ 3 4 /* 5 * FS specific support for 4.2BSD Fast Filesystem 6 * 7 * Written in 1999, 2002, 2003 by ITOH Yasufumi. 8 * Public domain. 9 * 10 * Intended to be used for boot programs (first stage). 11 * DON'T ADD ANY FANCY FEATURE. THIS SHALL BE COMPACT. 12 */ 13 14 #include "readufs.h" 15 16 #include <ufs/ffs/fs.h> 17 18 #define fsi (*ufsinfo) 19 #define fsi_ffs fsi.fs_u.u_ffs 20 21 /* 22 * Read and check superblock. 23 * If it is an FFS, save information from the superblock. 24 */ 25 int 26 try_ffs(void) 27 { 28 union { 29 struct fs sblk; 30 unsigned char pad[SBLOCKSIZE]; 31 } buf; 32 struct ufs_info *ufsinfo = &ufs_info; 33 static int sblocs[] = SBLOCKSEARCH; 34 int *sbl; 35 int magic; 36 37 #ifdef DEBUG_WITH_STDIO 38 printf("trying FFS\n"); 39 #endif 40 /* read FFS superblock */ 41 for (sbl = sblocs; ; sbl++) { 42 if (*sbl == -1) 43 return 1; 44 45 RAW_READ(&buf, (daddr_t) btodb(*sbl), SBLOCKSIZE); 46 47 magic = buf.sblk.fs_magic; 48 #ifdef DEBUG_WITH_STDIO 49 printf("FFS: sblk: pos %d magic 0x%x\n", btodb(*sbl), magic); 50 #endif 51 #ifdef USE_UFS1 52 if (magic == FS_UFS1_MAGIC 53 && !(buf.sblk.fs_old_flags & FS_FLAGS_UPDATED)) { 54 if (*sbl == SBLOCK_UFS2) 55 /* might be an alternate suberblock */ 56 continue; 57 break; 58 } 59 #endif 60 if (*sbl != buf.sblk.fs_sblockloc) 61 /* must be an alternate suberblock */ 62 continue; 63 64 #ifdef USE_UFS1 65 if (magic == FS_UFS1_MAGIC) 66 break; 67 #endif 68 #ifdef USE_UFS2 69 if (magic == FS_UFS2_MAGIC) { 70 #ifdef USE_UFS1 71 fsi.ufstype = UFSTYPE_UFS2; 72 #endif 73 break; 74 } 75 #endif 76 } 77 78 /* 79 * XXX <ufs/ffs/fs.h> always uses fs_magic 80 * (UFS1 only or UFS2 only is impossible) 81 */ 82 fsi_ffs.magic = magic; 83 #ifdef DEBUG_WITH_STDIO 84 printf("FFS: detected UFS%d format\n", (magic == FS_UFS2_MAGIC) + 1); 85 #endif 86 87 /* This partition looks like an FFS. */ 88 fsi.fstype = UFSTYPE_FFS; 89 #if 0 90 fsi.get_inode = get_ffs_inode; 91 #endif 92 93 /* Get information from the superblock. */ 94 fsi.bsize = buf.sblk.fs_bsize; 95 fsi.fsbtodb = buf.sblk.fs_fsbtodb; 96 fsi.nindir = buf.sblk.fs_nindir; 97 98 fsi_ffs.iblkno = buf.sblk.fs_iblkno; 99 fsi_ffs.old_cgoffset = buf.sblk.fs_old_cgoffset; 100 fsi_ffs.old_cgmask = buf.sblk.fs_old_cgmask; 101 fsi_ffs.fragshift = buf.sblk.fs_fragshift; 102 fsi_ffs.inopb = buf.sblk.fs_inopb; 103 fsi_ffs.ipg = buf.sblk.fs_ipg; 104 fsi_ffs.fpg = buf.sblk.fs_fpg; 105 106 return 0; 107 } 108 109 /* for inode macros */ 110 #define fs_ipg fs_u.u_ffs.ipg 111 #define fs_iblkno fs_u.u_ffs.iblkno 112 #define fs_old_cgoffset fs_u.u_ffs.old_cgoffset 113 #define fs_old_cgmask fs_u.u_ffs.old_cgmask 114 #define fs_fpg fs_u.u_ffs.fpg 115 #define fs_magic fs_u.u_ffs.magic 116 #define fs_inopb fs_u.u_ffs.inopb 117 #define fs_fragshift fs_u.u_ffs.fragshift 118 #define fs_fsbtodb fsbtodb 119 120 /* 121 * Get inode from disk. 122 */ 123 int 124 get_ffs_inode(ino32_t ino, union ufs_dinode *dibuf) 125 { 126 struct ufs_info *ufsinfo = &ufs_info; 127 union ufs_dinode *buf = alloca((size_t) fsi.bsize); 128 union ufs_dinode *di; 129 unsigned ioff; 130 131 RAW_READ(buf, FFS_FSBTODB(&fsi, ino_to_fsba(&fsi, ino)), 132 (size_t) fsi.bsize); 133 134 ioff = ino_to_fsbo(&fsi, ino); 135 136 #if defined(USE_UFS1) && defined(USE_UFS2) 137 if (ufsinfo->ufstype == UFSTYPE_UFS1) 138 di = (void *) &(&buf->di1)[ioff]; 139 else { 140 di = (void *) &(&buf->di2)[ioff]; 141 142 /* XXX for DI_SIZE() macro */ 143 di->di1.di_size = di->di2.di_size; 144 } 145 #else 146 di = &buf[ioff]; 147 #endif 148 149 #ifdef DEBUG_WITH_STDIO 150 printf("FFS: dinode(%d): mode 0%o, nlink %d, size %u\n", 151 ino, di->di_common.di_mode, di->di_common.di_nlink, 152 (unsigned) DI_SIZE(di)); 153 #endif 154 155 if (di->di_common.di_mode == 0) 156 return 1; /* unused inode (file is not found) */ 157 158 *dibuf = *di; 159 160 return 0; 161 } 162