readufs_lfs.c revision 1.1.6.2 1 1.1.6.2 thorpej /* $Id: readufs_lfs.c,v 1.1.6.2 2002/01/10 19:50:29 thorpej Exp $ */
2 1.1.6.2 thorpej
3 1.1.6.2 thorpej /*
4 1.1.6.2 thorpej * FS specific support for 4.4BSD Log-structured Filesystem
5 1.1.6.2 thorpej *
6 1.1.6.2 thorpej * Written by ITOH, Yasufumi (itohy (at) netbsd.org).
7 1.1.6.2 thorpej * Public domain.
8 1.1.6.2 thorpej *
9 1.1.6.2 thorpej * Intended to be used for boot programs (first stage).
10 1.1.6.2 thorpej * DON'T ADD ANY FANCY FEATURE. THIS SHALL BE COMPACT.
11 1.1.6.2 thorpej */
12 1.1.6.2 thorpej
13 1.1.6.2 thorpej #include <sys/types.h>
14 1.1.6.2 thorpej #include <sys/param.h>
15 1.1.6.2 thorpej #include <sys/mount.h>
16 1.1.6.2 thorpej #include <ufs/ufs/dinode.h>
17 1.1.6.2 thorpej #include <ufs/lfs/lfs.h>
18 1.1.6.2 thorpej
19 1.1.6.2 thorpej #include "readufs.h"
20 1.1.6.2 thorpej
21 1.1.6.2 thorpej static int get_lfs_inode __P((ino_t ino, struct dinode *dibuf));
22 1.1.6.2 thorpej
23 1.1.6.2 thorpej static struct dinode ifile_dinode;
24 1.1.6.2 thorpej
25 1.1.6.2 thorpej #define fsi (*ufsinfo)
26 1.1.6.2 thorpej #define fsi_lfs fsi.fs_u.u_lfs
27 1.1.6.2 thorpej
28 1.1.6.2 thorpej /*
29 1.1.6.2 thorpej * Read and check superblock.
30 1.1.6.2 thorpej * If it is an LFS, save information from the superblock.
31 1.1.6.2 thorpej */
32 1.1.6.2 thorpej int
33 1.1.6.2 thorpej try_lfs()
34 1.1.6.2 thorpej {
35 1.1.6.2 thorpej struct ufs_info *ufsinfo = &ufs_info;
36 1.1.6.2 thorpej struct dlfs sblk, sblk2;
37 1.1.6.2 thorpej struct dlfs *s = &sblk;
38 1.1.6.2 thorpej
39 1.1.6.2 thorpej #ifdef DEBUG_WITH_STDIO
40 1.1.6.2 thorpej printf("trying LFS\n");
41 1.1.6.2 thorpej #endif
42 1.1.6.2 thorpej /* read primary superblock */
43 1.1.6.2 thorpej RAW_READ(&sblk, btodb(LFS_LABELPAD), sizeof sblk);
44 1.1.6.2 thorpej
45 1.1.6.2 thorpej #ifdef DEBUG_WITH_STDIO
46 1.1.6.2 thorpej printf("LFS: sblk: magic: 0x%x, version: %d\n",
47 1.1.6.2 thorpej sblk.dlfs_magic, sblk.dlfs_version);
48 1.1.6.2 thorpej #endif
49 1.1.6.2 thorpej
50 1.1.6.2 thorpej if (sblk.dlfs_magic != LFS_MAGIC)
51 1.1.6.2 thorpej return 1;
52 1.1.6.2 thorpej
53 1.1.6.2 thorpej #ifdef DEBUG_WITH_STDIO
54 1.1.6.2 thorpej printf("sboff[1]: %d\n", sblk.dlfs_sboffs[1]);
55 1.1.6.2 thorpej #endif
56 1.1.6.2 thorpej
57 1.1.6.2 thorpej if (sblk.dlfs_sboffs[1] > 0) {
58 1.1.6.2 thorpej /* read secondary superblock */
59 1.1.6.2 thorpej RAW_READ(&sblk2,
60 1.1.6.2 thorpej (unsigned int) sblk.dlfs_sboffs[1], sizeof sblk2);
61 1.1.6.2 thorpej
62 1.1.6.2 thorpej #ifdef DEBUG_WITH_STDIO
63 1.1.6.2 thorpej printf("LFS: sblk2: magic: 0x%x, version: %d\n",
64 1.1.6.2 thorpej sblk2.dlfs_magic, sblk2.dlfs_version);
65 1.1.6.2 thorpej #endif
66 1.1.6.2 thorpej
67 1.1.6.2 thorpej if (sblk2.dlfs_magic == LFS_MAGIC &&
68 1.1.6.2 thorpej sblk.dlfs_tstamp > sblk2.dlfs_tstamp)
69 1.1.6.2 thorpej s = &sblk2;
70 1.1.6.2 thorpej }
71 1.1.6.2 thorpej
72 1.1.6.2 thorpej /* This partition looks like an LFS. */
73 1.1.6.2 thorpej fsi.get_inode = get_lfs_inode;
74 1.1.6.2 thorpej /* Disk addr in inode is in disk sector --- no shifting. */
75 1.1.6.2 thorpej fsi.iblkshift = 0;
76 1.1.6.2 thorpej
77 1.1.6.2 thorpej /* Get information from the superblock. */
78 1.1.6.2 thorpej fsi.bsize = s->dlfs_bsize;
79 1.1.6.2 thorpej fsi.fsbtodb = s->dlfs_fsbtodb;
80 1.1.6.2 thorpej fsi.nindir = s->dlfs_nindir;
81 1.1.6.2 thorpej
82 1.1.6.2 thorpej fsi_lfs.idaddr = s->dlfs_idaddr;
83 1.1.6.2 thorpej fsi_lfs.inopb = s->dlfs_inopb;
84 1.1.6.2 thorpej fsi_lfs.ifpb = s->dlfs_ifpb;
85 1.1.6.2 thorpej fsi_lfs.cleansz = s->dlfs_cleansz;
86 1.1.6.2 thorpej fsi_lfs.segtabsz = s->dlfs_segtabsz;
87 1.1.6.2 thorpej
88 1.1.6.2 thorpej /* ifile is always used to look-up other inodes, so keep its inode. */
89 1.1.6.2 thorpej if (get_lfs_inode(LFS_IFILE_INUM, &ifile_dinode))
90 1.1.6.2 thorpej return 1; /* OOPS, failed to find inode of ifile! */
91 1.1.6.2 thorpej
92 1.1.6.2 thorpej fsi.fstype = UFSTYPE_LFS;
93 1.1.6.2 thorpej
94 1.1.6.2 thorpej return 0;
95 1.1.6.2 thorpej }
96 1.1.6.2 thorpej
97 1.1.6.2 thorpej /*
98 1.1.6.2 thorpej * Get inode from disk.
99 1.1.6.2 thorpej */
100 1.1.6.2 thorpej static int
101 1.1.6.2 thorpej get_lfs_inode(ino, dibuf)
102 1.1.6.2 thorpej ino_t ino;
103 1.1.6.2 thorpej struct dinode *dibuf;
104 1.1.6.2 thorpej {
105 1.1.6.2 thorpej struct ufs_info *ufsinfo = &ufs_info;
106 1.1.6.2 thorpej ufs_daddr_t daddr;
107 1.1.6.2 thorpej char *buf = alloca(fsi.bsize);
108 1.1.6.2 thorpej struct dinode *di;
109 1.1.6.2 thorpej int cnt;
110 1.1.6.2 thorpej
111 1.1.6.2 thorpej /* Get fs block which contains the specified inode. */
112 1.1.6.2 thorpej if (ino == LFS_IFILE_INUM)
113 1.1.6.2 thorpej daddr = fsi_lfs.idaddr;
114 1.1.6.2 thorpej else {
115 1.1.6.2 thorpej #ifdef DEBUG_WITH_STDIO
116 1.1.6.2 thorpej printf("LFS: ino: %d\nifpb: %d, cleansz: %d, segtabsz: %d, bsize: %d\n",
117 1.1.6.2 thorpej ino, fsi_lfs.ifpb, fsi_lfs.cleansz, fsi_lfs.segtabsz, fsi.bsize);
118 1.1.6.2 thorpej #endif
119 1.1.6.2 thorpej ufs_read(&ifile_dinode, buf,
120 1.1.6.2 thorpej ino / fsi_lfs.ifpb + fsi_lfs.cleansz +
121 1.1.6.2 thorpej fsi_lfs.segtabsz,
122 1.1.6.2 thorpej fsi.bsize);
123 1.1.6.2 thorpej daddr = ((IFILE *) buf + ino % fsi_lfs.ifpb)->if_daddr;
124 1.1.6.2 thorpej }
125 1.1.6.2 thorpej #ifdef DEBUG_WITH_STDIO
126 1.1.6.2 thorpej printf("LFS(%d): daddr: %d\n", ino, daddr);
127 1.1.6.2 thorpej #endif
128 1.1.6.2 thorpej
129 1.1.6.2 thorpej if (daddr == LFS_UNUSED_DADDR)
130 1.1.6.2 thorpej return 1;
131 1.1.6.2 thorpej
132 1.1.6.2 thorpej /* Read the inode block. */
133 1.1.6.2 thorpej RAW_READ(buf, (unsigned int) daddr, fsi.bsize);
134 1.1.6.2 thorpej
135 1.1.6.2 thorpej /* Search for the inode. */
136 1.1.6.2 thorpej cnt = fsi_lfs.inopb;
137 1.1.6.2 thorpej di = (struct dinode *) buf + (cnt - 1);
138 1.1.6.2 thorpej
139 1.1.6.2 thorpej for ( ; cnt--; di--)
140 1.1.6.2 thorpej if (di->di_inumber == ino)
141 1.1.6.2 thorpej goto found;
142 1.1.6.2 thorpej /* not found */
143 1.1.6.2 thorpej return 1;
144 1.1.6.2 thorpej
145 1.1.6.2 thorpej found:
146 1.1.6.2 thorpej #ifdef DEBUG_WITH_STDIO
147 1.1.6.2 thorpej printf("LFS: dinode(%d): mode 0%o, nlink %d, inumber %d, size %d, uid %d, gid %d, db[0] %d\n",
148 1.1.6.2 thorpej ino, di->di_mode, di->di_nlink, di->di_inumber,
149 1.1.6.2 thorpej (int)di->di_size, di->di_uid, di->di_gid, di->di_db[0]);
150 1.1.6.2 thorpej #endif
151 1.1.6.2 thorpej
152 1.1.6.2 thorpej *dibuf = *di;
153 1.1.6.2 thorpej
154 1.1.6.2 thorpej return 0;
155 1.1.6.2 thorpej }
156