1 /* $NetBSD: readufs_ffs.c,v 1.11 2009/03/14 15:36:15 dsl Exp $ */
2 /* from Id: readufs_ffs.c,v 1.6 2003/04/08 09:19:32 itohy Exp */
5 * FS specific support for 4.2BSD Fast Filesystem
7 * Written in 1999, 2002, 2003 by ITOH Yasufumi (itohy@NetBSD.org).
10 * Intended to be used for boot programs (first stage).
11 * DON'T ADD ANY FANCY FEATURE. THIS SHALL BE COMPACT.
16 #include <ufs/ffs/fs.h>
18 static int get_ffs_inode(ino32_t ino
, union ufs_dinode
*dibuf
);
20 #define fsi (*ufsinfo)
21 #define fsi_ffs fsi.fs_u.u_ffs
24 * Read and check superblock.
25 * If it is an FFS, save information from the superblock.
32 unsigned char pad
[SBLOCKSIZE
];
34 struct ufs_info
*ufsinfo
= &ufs_info
;
35 static const int sblocs
[] = SBLOCKSEARCH
;
39 #ifdef DEBUG_WITH_STDIO
40 printf("trying FFS\n");
42 /* read FFS superblock */
43 for (sbl
= sblocs
; ; sbl
++) {
47 RAW_READ(&buf
, (daddr_t
) btodb(*sbl
), SBLOCKSIZE
);
49 magic
= buf
.sblk
.fs_magic
;
50 #ifdef DEBUG_WITH_STDIO
51 printf("FFS: sblk: pos %d magic 0x%x\n", btodb(*sbl
), magic
);
54 if (magic
== FS_UFS1_MAGIC
55 && !(buf
.sblk
.fs_old_flags
& FS_FLAGS_UPDATED
)) {
56 if (*sbl
== SBLOCK_UFS2
)
57 /* might be an alternate suberblock */
62 if (*sbl
!= buf
.sblk
.fs_sblockloc
)
63 /* must be an alternate suberblock */
67 if (magic
== FS_UFS1_MAGIC
) {
72 if (magic
== FS_UFS2_MAGIC
) {
74 fsi
.ufstype
= UFSTYPE_UFS2
;
82 * XXX <ufs/ffs/fs.h> always uses fs_magic
83 * (UFS1 only or UFS2 only is impossible)
85 fsi_ffs
.magic
= magic
;
86 #ifdef DEBUG_WITH_STDIO
87 printf("FFS: detected UFS%d format\n", (magic
== FS_UFS2_MAGIC
) + 1);
90 /* This partition looks like an FFS. */
91 fsi
.fstype
= UFSTYPE_FFS
;
92 fsi
.get_inode
= get_ffs_inode
;
94 /* Get information from the superblock. */
95 fsi
.bsize
= buf
.sblk
.fs_bsize
;
96 fsi
.fsbtodb
= buf
.sblk
.fs_fsbtodb
;
97 fsi
.nindir
= buf
.sblk
.fs_nindir
;
99 fsi_ffs
.iblkno
= buf
.sblk
.fs_iblkno
;
100 fsi_ffs
.old_cgoffset
= buf
.sblk
.fs_old_cgoffset
;
101 fsi_ffs
.old_cgmask
= buf
.sblk
.fs_old_cgmask
;
102 fsi_ffs
.fragshift
= buf
.sblk
.fs_fragshift
;
103 fsi_ffs
.inopb
= buf
.sblk
.fs_inopb
;
104 fsi_ffs
.ipg
= buf
.sblk
.fs_ipg
;
105 fsi_ffs
.fpg
= buf
.sblk
.fs_fpg
;
110 /* for inode macros */
111 #define fs_ipg fs_u.u_ffs.ipg
112 #define fs_iblkno fs_u.u_ffs.iblkno
113 #define fs_old_cgoffset fs_u.u_ffs.old_cgoffset
114 #define fs_old_cgmask fs_u.u_ffs.old_cgmask
115 #define fs_fpg fs_u.u_ffs.fpg
116 #define fs_magic fs_u.u_ffs.magic
117 #define fs_inopb fs_u.u_ffs.inopb
118 #define fs_fragshift fs_u.u_ffs.fragshift
119 #define fs_fsbtodb fsbtodb
122 * Get inode from disk.
125 get_ffs_inode(ino32_t ino
, union ufs_dinode
*dibuf
)
127 struct ufs_info
*ufsinfo
= &ufs_info
;
128 union ufs_dinode
*buf
= alloca((size_t) fsi
.bsize
);
129 union ufs_dinode
*di
;
132 RAW_READ(buf
, fsbtodb(&fsi
, ino_to_fsba(&fsi
, ino
)),
135 ioff
= ino_to_fsbo(&fsi
, ino
);
137 #if defined(USE_UFS1) && defined(USE_UFS2)
138 if (ufsinfo
->ufstype
== UFSTYPE_UFS1
)
139 di
= (void *) &(&buf
->di1
)[ioff
];
141 di
= (void *) &(&buf
->di2
)[ioff
];
143 /* XXX for DI_SIZE() macro */
144 di
->di1
.di_size
= di
->di2
.di_size
;
150 #ifdef DEBUG_WITH_STDIO
151 printf("FFS: dinode(%d): mode 0%o, nlink %d, size %u\n",
152 ino
, di
->di_common
.di_mode
, di
->di_common
.di_nlink
,
153 (unsigned) DI_SIZE(di
));
156 if (di
->di_common
.di_mode
== 0)
157 return 1; /* unused inode (file is not found) */