1 /*
2  * volume_id - reads filesystem label and uuid
3  *
4  * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
5  *
6  *	This library is free software; you can redistribute it and/or
7  *	modify it under the terms of the GNU Lesser General Public
8  *	License as published by the Free Software Foundation; either
9  *	version 2.1 of the License, or (at your option) any later version.
10  *
11  *	This library is distributed in the hope that it will be useful,
12  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  *	Lesser General Public License for more details.
15  *
16  *	You should have received a copy of the GNU Lesser General Public
17  *	License along with this library; if not, write to the Free Software
18  *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 //config:config FEATURE_VOLUMEID_SYSV
21 //config:	bool "sysv filesystem"
22 //config:	default y
23 //config:	depends on VOLUMEID
24 
25 //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_SYSV) += sysv.o
26 
27 #include "volume_id_internal.h"
28 
29 #define SYSV_NICINOD			100
30 #define SYSV_NICFREE			50
31 
32 struct sysv_super {
33 	uint16_t	s_isize;
34 	uint16_t	s_pad0;
35 	uint32_t	s_fsize;
36 	uint16_t	s_nfree;
37 	uint16_t	s_pad1;
38 	uint32_t	s_free[SYSV_NICFREE];
39 	uint16_t	s_ninode;
40 	uint16_t	s_pad2;
41 	uint16_t	s_inode[SYSV_NICINOD];
42 	uint8_t		s_flock;
43 	uint8_t		s_ilock;
44 	uint8_t		s_fmod;
45 	uint8_t		s_ronly;
46 	uint32_t	s_time;
47 	uint16_t	s_dinfo[4];
48 	uint32_t	s_tfree;
49 	uint16_t	s_tinode;
50 	uint16_t	s_pad3;
51 	uint8_t		s_fname[6];
52 	uint8_t		s_fpack[6];
53 	uint32_t	s_fill[12];
54 	uint32_t	s_state;
55 	uint32_t	s_magic;
56 	uint32_t	s_type;
57 } PACKED;
58 
59 #define XENIX_NICINOD				100
60 #define XENIX_NICFREE				100
61 
62 struct xenix_super {
63 	uint16_t	s_isize;
64 	uint32_t	s_fsize;
65 	uint16_t	s_nfree;
66 	uint32_t	s_free[XENIX_NICFREE];
67 	uint16_t	s_ninode;
68 	uint16_t	s_inode[XENIX_NICINOD];
69 	uint8_t		s_flock;
70 	uint8_t		s_ilock;
71 	uint8_t		s_fmod;
72 	uint8_t		s_ronly;
73 	uint32_t	s_time;
74 	uint32_t	s_tfree;
75 	uint16_t	s_tinode;
76 	uint16_t	s_dinfo[4];
77 	uint8_t		s_fname[6];
78 	uint8_t		s_fpack[6];
79 	uint8_t		s_clean;
80 	uint8_t		s_fill[371];
81 	uint32_t	s_magic;
82 	uint32_t	s_type;
83 } PACKED;
84 
85 #define SYSV_SUPERBLOCK_BLOCK			0x01
86 #define SYSV_MAGIC				0xfd187e20
87 #define XENIX_SUPERBLOCK_BLOCK			0x18
88 #define XENIX_MAGIC				0x2b5544
89 #define SYSV_MAX_BLOCKSIZE			0x800
90 
volume_id_probe_sysv(struct volume_id * id)91 int FAST_FUNC volume_id_probe_sysv(struct volume_id *id /*,uint64_t off*/)
92 {
93 #define off ((uint64_t)0)
94 	struct sysv_super *vs;
95 	struct xenix_super *xs;
96 	unsigned boff;
97 
98 	dbg("probing at offset 0x%llx", (unsigned long long) off);
99 
100 	for (boff = 0x200; boff <= SYSV_MAX_BLOCKSIZE; boff <<= 1) {
101 		vs = volume_id_get_buffer(id, off + (boff * SYSV_SUPERBLOCK_BLOCK), 0x200);
102 		if (vs == NULL)
103 			return -1;
104 
105 		if (vs->s_magic == cpu_to_le32(SYSV_MAGIC) || vs->s_magic == cpu_to_be32(SYSV_MAGIC)) {
106 //			volume_id_set_label_raw(id, vs->s_fname, 6);
107 			volume_id_set_label_string(id, vs->s_fname, 6);
108 			IF_FEATURE_BLKID_TYPE(id->type = "sysv");
109 			goto found;
110 		}
111 	}
112 
113 	for (boff = 0x200; boff <= SYSV_MAX_BLOCKSIZE; boff <<= 1) {
114 		xs = volume_id_get_buffer(id, off + (boff + XENIX_SUPERBLOCK_BLOCK), 0x200);
115 		if (xs == NULL)
116 			return -1;
117 
118 		if (xs->s_magic == cpu_to_le32(XENIX_MAGIC) || xs->s_magic == cpu_to_be32(XENIX_MAGIC)) {
119 //			volume_id_set_label_raw(id, xs->s_fname, 6);
120 			volume_id_set_label_string(id, xs->s_fname, 6);
121 			IF_FEATURE_BLKID_TYPE(id->type = "xenix";)
122 			goto found;
123 		}
124 	}
125 
126 	return -1;
127 
128  found:
129 //	volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
130 	return 0;
131 }
132