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