Commit bdaf8529385d5126ef791e8f1914afff8cd59bcf

Authored by Greg Kroah-Hartman
1 parent a29641883f

[PATCH] devfs: Remove devfs from the init code

This patch removes the devfs code from the init/ directory.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 8 changed files with 10 additions and 172 deletions Inline Diff

include/linux/devfs_fs_kernel.h
1 #ifndef _LINUX_DEVFS_FS_KERNEL_H 1 #ifndef _LINUX_DEVFS_FS_KERNEL_H
2 #define _LINUX_DEVFS_FS_KERNEL_H 2 #define _LINUX_DEVFS_FS_KERNEL_H
3 3
4 #include <linux/fs.h> 4 #include <linux/fs.h>
5 #include <linux/spinlock.h> 5 #include <linux/spinlock.h>
6 #include <linux/types.h> 6 #include <linux/types.h>
7 #include <asm/semaphore.h> 7 #include <asm/semaphore.h>
8 8
9 static inline int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...) 9 static inline int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...)
10 { 10 {
11 return 0; 11 return 0;
12 } 12 }
13 static inline int devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...) 13 static inline int devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...)
14 { 14 {
15 return 0; 15 return 0;
16 } 16 }
17 static inline int devfs_mk_symlink(const char *name, const char *link) 17 static inline int devfs_mk_symlink(const char *name, const char *link)
18 { 18 {
19 return 0; 19 return 0;
20 } 20 }
21 static inline int devfs_mk_dir(const char *fmt, ...) 21 static inline int devfs_mk_dir(const char *fmt, ...)
22 { 22 {
23 return 0; 23 return 0;
24 } 24 }
25 static inline void devfs_remove(const char *fmt, ...) 25 static inline void devfs_remove(const char *fmt, ...)
26 { 26 {
27 } 27 }
28 static inline int devfs_register_tape(const char *name) 28 static inline int devfs_register_tape(const char *name)
29 { 29 {
30 return -1; 30 return -1;
31 } 31 }
32 static inline void devfs_unregister_tape(int num) 32 static inline void devfs_unregister_tape(int num)
33 { 33 {
34 } 34 }
35 static inline void mount_devfs_fs(void)
36 {
37 return;
38 }
39 #endif /* _LINUX_DEVFS_FS_KERNEL_H */ 35 #endif /* _LINUX_DEVFS_FS_KERNEL_H */
40 36
1 # 1 #
2 # Makefile for the linux kernel. 2 # Makefile for the linux kernel.
3 # 3 #
4 4
5 obj-y := main.o version.o mounts.o initramfs.o 5 obj-y := main.o version.o mounts.o initramfs.o
6 obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o 6 obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o
7 7
8 mounts-y := do_mounts.o 8 mounts-y := do_mounts.o
9 mounts-$(CONFIG_DEVFS_FS) += do_mounts_devfs.o
10 mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o 9 mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o
11 mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o 10 mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o
12 mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o 11 mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o
13 12
14 # files to be removed upon make clean 13 # files to be removed upon make clean
15 clean-files := ../include/linux/compile.h 14 clean-files := ../include/linux/compile.h
16 15
17 # dependencies on generated files need to be listed explicitly 16 # dependencies on generated files need to be listed explicitly
18 17
19 $(obj)/version.o: include/linux/compile.h 18 $(obj)/version.o: include/linux/compile.h
20 19
21 # compile.h changes depending on hostname, generation number, etc, 20 # compile.h changes depending on hostname, generation number, etc,
22 # so we regenerate it always. 21 # so we regenerate it always.
23 # mkcompile_h will make sure to only update the 22 # mkcompile_h will make sure to only update the
24 # actual file if its content has changed. 23 # actual file if its content has changed.
25 24
26 include/linux/compile.h: FORCE 25 include/linux/compile.h: FORCE
27 @echo ' CHK $@' 26 @echo ' CHK $@'
28 $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \ 27 $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \
29 "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(CFLAGS)" 28 "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(CFLAGS)"
30 29
1 #include <linux/module.h> 1 #include <linux/module.h>
2 #include <linux/sched.h> 2 #include <linux/sched.h>
3 #include <linux/ctype.h> 3 #include <linux/ctype.h>
4 #include <linux/fd.h> 4 #include <linux/fd.h>
5 #include <linux/tty.h> 5 #include <linux/tty.h>
6 #include <linux/suspend.h> 6 #include <linux/suspend.h>
7 #include <linux/root_dev.h> 7 #include <linux/root_dev.h>
8 #include <linux/security.h> 8 #include <linux/security.h>
9 #include <linux/delay.h> 9 #include <linux/delay.h>
10 #include <linux/mount.h> 10 #include <linux/mount.h>
11 11
12 #include <linux/nfs_fs.h> 12 #include <linux/nfs_fs.h>
13 #include <linux/nfs_fs_sb.h> 13 #include <linux/nfs_fs_sb.h>
14 #include <linux/nfs_mount.h> 14 #include <linux/nfs_mount.h>
15 15
16 #include "do_mounts.h" 16 #include "do_mounts.h"
17 17
18 extern int get_filesystem_list(char * buf); 18 extern int get_filesystem_list(char * buf);
19 19
20 int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */ 20 int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */
21 21
22 int root_mountflags = MS_RDONLY | MS_SILENT; 22 int root_mountflags = MS_RDONLY | MS_SILENT;
23 char * __initdata root_device_name; 23 char * __initdata root_device_name;
24 static char __initdata saved_root_name[64]; 24 static char __initdata saved_root_name[64];
25 25
26 dev_t ROOT_DEV; 26 dev_t ROOT_DEV;
27 27
28 static int __init load_ramdisk(char *str) 28 static int __init load_ramdisk(char *str)
29 { 29 {
30 rd_doload = simple_strtol(str,NULL,0) & 3; 30 rd_doload = simple_strtol(str,NULL,0) & 3;
31 return 1; 31 return 1;
32 } 32 }
33 __setup("load_ramdisk=", load_ramdisk); 33 __setup("load_ramdisk=", load_ramdisk);
34 34
35 static int __init readonly(char *str) 35 static int __init readonly(char *str)
36 { 36 {
37 if (*str) 37 if (*str)
38 return 0; 38 return 0;
39 root_mountflags |= MS_RDONLY; 39 root_mountflags |= MS_RDONLY;
40 return 1; 40 return 1;
41 } 41 }
42 42
43 static int __init readwrite(char *str) 43 static int __init readwrite(char *str)
44 { 44 {
45 if (*str) 45 if (*str)
46 return 0; 46 return 0;
47 root_mountflags &= ~MS_RDONLY; 47 root_mountflags &= ~MS_RDONLY;
48 return 1; 48 return 1;
49 } 49 }
50 50
51 __setup("ro", readonly); 51 __setup("ro", readonly);
52 __setup("rw", readwrite); 52 __setup("rw", readwrite);
53 53
54 static dev_t try_name(char *name, int part) 54 static dev_t try_name(char *name, int part)
55 { 55 {
56 char path[64]; 56 char path[64];
57 char buf[32]; 57 char buf[32];
58 int range; 58 int range;
59 dev_t res; 59 dev_t res;
60 char *s; 60 char *s;
61 int len; 61 int len;
62 int fd; 62 int fd;
63 unsigned int maj, min; 63 unsigned int maj, min;
64 64
65 /* read device number from .../dev */ 65 /* read device number from .../dev */
66 66
67 sprintf(path, "/sys/block/%s/dev", name); 67 sprintf(path, "/sys/block/%s/dev", name);
68 fd = sys_open(path, 0, 0); 68 fd = sys_open(path, 0, 0);
69 if (fd < 0) 69 if (fd < 0)
70 goto fail; 70 goto fail;
71 len = sys_read(fd, buf, 32); 71 len = sys_read(fd, buf, 32);
72 sys_close(fd); 72 sys_close(fd);
73 if (len <= 0 || len == 32 || buf[len - 1] != '\n') 73 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
74 goto fail; 74 goto fail;
75 buf[len - 1] = '\0'; 75 buf[len - 1] = '\0';
76 if (sscanf(buf, "%u:%u", &maj, &min) == 2) { 76 if (sscanf(buf, "%u:%u", &maj, &min) == 2) {
77 /* 77 /*
78 * Try the %u:%u format -- see print_dev_t() 78 * Try the %u:%u format -- see print_dev_t()
79 */ 79 */
80 res = MKDEV(maj, min); 80 res = MKDEV(maj, min);
81 if (maj != MAJOR(res) || min != MINOR(res)) 81 if (maj != MAJOR(res) || min != MINOR(res))
82 goto fail; 82 goto fail;
83 } else { 83 } else {
84 /* 84 /*
85 * Nope. Try old-style "0321" 85 * Nope. Try old-style "0321"
86 */ 86 */
87 res = new_decode_dev(simple_strtoul(buf, &s, 16)); 87 res = new_decode_dev(simple_strtoul(buf, &s, 16));
88 if (*s) 88 if (*s)
89 goto fail; 89 goto fail;
90 } 90 }
91 91
92 /* if it's there and we are not looking for a partition - that's it */ 92 /* if it's there and we are not looking for a partition - that's it */
93 if (!part) 93 if (!part)
94 return res; 94 return res;
95 95
96 /* otherwise read range from .../range */ 96 /* otherwise read range from .../range */
97 sprintf(path, "/sys/block/%s/range", name); 97 sprintf(path, "/sys/block/%s/range", name);
98 fd = sys_open(path, 0, 0); 98 fd = sys_open(path, 0, 0);
99 if (fd < 0) 99 if (fd < 0)
100 goto fail; 100 goto fail;
101 len = sys_read(fd, buf, 32); 101 len = sys_read(fd, buf, 32);
102 sys_close(fd); 102 sys_close(fd);
103 if (len <= 0 || len == 32 || buf[len - 1] != '\n') 103 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
104 goto fail; 104 goto fail;
105 buf[len - 1] = '\0'; 105 buf[len - 1] = '\0';
106 range = simple_strtoul(buf, &s, 10); 106 range = simple_strtoul(buf, &s, 10);
107 if (*s) 107 if (*s)
108 goto fail; 108 goto fail;
109 109
110 /* if partition is within range - we got it */ 110 /* if partition is within range - we got it */
111 if (part < range) 111 if (part < range)
112 return res + part; 112 return res + part;
113 fail: 113 fail:
114 return 0; 114 return 0;
115 } 115 }
116 116
117 /* 117 /*
118 * Convert a name into device number. We accept the following variants: 118 * Convert a name into device number. We accept the following variants:
119 * 119 *
120 * 1) device number in hexadecimal represents itself 120 * 1) device number in hexadecimal represents itself
121 * 2) /dev/nfs represents Root_NFS (0xff) 121 * 2) /dev/nfs represents Root_NFS (0xff)
122 * 3) /dev/<disk_name> represents the device number of disk 122 * 3) /dev/<disk_name> represents the device number of disk
123 * 4) /dev/<disk_name><decimal> represents the device number 123 * 4) /dev/<disk_name><decimal> represents the device number
124 * of partition - device number of disk plus the partition number 124 * of partition - device number of disk plus the partition number
125 * 5) /dev/<disk_name>p<decimal> - same as the above, that form is 125 * 5) /dev/<disk_name>p<decimal> - same as the above, that form is
126 * used when disk name of partitioned disk ends on a digit. 126 * used when disk name of partitioned disk ends on a digit.
127 * 127 *
128 * If name doesn't have fall into the categories above, we return 0. 128 * If name doesn't have fall into the categories above, we return 0.
129 * Sysfs is used to check if something is a disk name - it has 129 * Sysfs is used to check if something is a disk name - it has
130 * all known disks under bus/block/devices. If the disk name 130 * all known disks under bus/block/devices. If the disk name
131 * contains slashes, name of sysfs node has them replaced with 131 * contains slashes, name of sysfs node has them replaced with
132 * bangs. try_name() does the actual checks, assuming that sysfs 132 * bangs. try_name() does the actual checks, assuming that sysfs
133 * is mounted on rootfs /sys. 133 * is mounted on rootfs /sys.
134 */ 134 */
135 135
136 dev_t name_to_dev_t(char *name) 136 dev_t name_to_dev_t(char *name)
137 { 137 {
138 char s[32]; 138 char s[32];
139 char *p; 139 char *p;
140 dev_t res = 0; 140 dev_t res = 0;
141 int part; 141 int part;
142 142
143 #ifdef CONFIG_SYSFS 143 #ifdef CONFIG_SYSFS
144 int mkdir_err = sys_mkdir("/sys", 0700); 144 int mkdir_err = sys_mkdir("/sys", 0700);
145 if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0) 145 if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0)
146 goto out; 146 goto out;
147 #endif 147 #endif
148 148
149 if (strncmp(name, "/dev/", 5) != 0) { 149 if (strncmp(name, "/dev/", 5) != 0) {
150 unsigned maj, min; 150 unsigned maj, min;
151 151
152 if (sscanf(name, "%u:%u", &maj, &min) == 2) { 152 if (sscanf(name, "%u:%u", &maj, &min) == 2) {
153 res = MKDEV(maj, min); 153 res = MKDEV(maj, min);
154 if (maj != MAJOR(res) || min != MINOR(res)) 154 if (maj != MAJOR(res) || min != MINOR(res))
155 goto fail; 155 goto fail;
156 } else { 156 } else {
157 res = new_decode_dev(simple_strtoul(name, &p, 16)); 157 res = new_decode_dev(simple_strtoul(name, &p, 16));
158 if (*p) 158 if (*p)
159 goto fail; 159 goto fail;
160 } 160 }
161 goto done; 161 goto done;
162 } 162 }
163 name += 5; 163 name += 5;
164 res = Root_NFS; 164 res = Root_NFS;
165 if (strcmp(name, "nfs") == 0) 165 if (strcmp(name, "nfs") == 0)
166 goto done; 166 goto done;
167 res = Root_RAM0; 167 res = Root_RAM0;
168 if (strcmp(name, "ram") == 0) 168 if (strcmp(name, "ram") == 0)
169 goto done; 169 goto done;
170 170
171 if (strlen(name) > 31) 171 if (strlen(name) > 31)
172 goto fail; 172 goto fail;
173 strcpy(s, name); 173 strcpy(s, name);
174 for (p = s; *p; p++) 174 for (p = s; *p; p++)
175 if (*p == '/') 175 if (*p == '/')
176 *p = '!'; 176 *p = '!';
177 res = try_name(s, 0); 177 res = try_name(s, 0);
178 if (res) 178 if (res)
179 goto done; 179 goto done;
180 180
181 while (p > s && isdigit(p[-1])) 181 while (p > s && isdigit(p[-1]))
182 p--; 182 p--;
183 if (p == s || !*p || *p == '0') 183 if (p == s || !*p || *p == '0')
184 goto fail; 184 goto fail;
185 part = simple_strtoul(p, NULL, 10); 185 part = simple_strtoul(p, NULL, 10);
186 *p = '\0'; 186 *p = '\0';
187 res = try_name(s, part); 187 res = try_name(s, part);
188 if (res) 188 if (res)
189 goto done; 189 goto done;
190 190
191 if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p') 191 if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
192 goto fail; 192 goto fail;
193 p[-1] = '\0'; 193 p[-1] = '\0';
194 res = try_name(s, part); 194 res = try_name(s, part);
195 done: 195 done:
196 #ifdef CONFIG_SYSFS 196 #ifdef CONFIG_SYSFS
197 sys_umount("/sys", 0); 197 sys_umount("/sys", 0);
198 out: 198 out:
199 if (!mkdir_err) 199 if (!mkdir_err)
200 sys_rmdir("/sys"); 200 sys_rmdir("/sys");
201 #endif 201 #endif
202 return res; 202 return res;
203 fail: 203 fail:
204 res = 0; 204 res = 0;
205 goto done; 205 goto done;
206 } 206 }
207 207
208 static int __init root_dev_setup(char *line) 208 static int __init root_dev_setup(char *line)
209 { 209 {
210 strlcpy(saved_root_name, line, sizeof(saved_root_name)); 210 strlcpy(saved_root_name, line, sizeof(saved_root_name));
211 return 1; 211 return 1;
212 } 212 }
213 213
214 __setup("root=", root_dev_setup); 214 __setup("root=", root_dev_setup);
215 215
216 static char * __initdata root_mount_data; 216 static char * __initdata root_mount_data;
217 static int __init root_data_setup(char *str) 217 static int __init root_data_setup(char *str)
218 { 218 {
219 root_mount_data = str; 219 root_mount_data = str;
220 return 1; 220 return 1;
221 } 221 }
222 222
223 static char * __initdata root_fs_names; 223 static char * __initdata root_fs_names;
224 static int __init fs_names_setup(char *str) 224 static int __init fs_names_setup(char *str)
225 { 225 {
226 root_fs_names = str; 226 root_fs_names = str;
227 return 1; 227 return 1;
228 } 228 }
229 229
230 static unsigned int __initdata root_delay; 230 static unsigned int __initdata root_delay;
231 static int __init root_delay_setup(char *str) 231 static int __init root_delay_setup(char *str)
232 { 232 {
233 root_delay = simple_strtoul(str, NULL, 0); 233 root_delay = simple_strtoul(str, NULL, 0);
234 return 1; 234 return 1;
235 } 235 }
236 236
237 __setup("rootflags=", root_data_setup); 237 __setup("rootflags=", root_data_setup);
238 __setup("rootfstype=", fs_names_setup); 238 __setup("rootfstype=", fs_names_setup);
239 __setup("rootdelay=", root_delay_setup); 239 __setup("rootdelay=", root_delay_setup);
240 240
241 static void __init get_fs_names(char *page) 241 static void __init get_fs_names(char *page)
242 { 242 {
243 char *s = page; 243 char *s = page;
244 244
245 if (root_fs_names) { 245 if (root_fs_names) {
246 strcpy(page, root_fs_names); 246 strcpy(page, root_fs_names);
247 while (*s++) { 247 while (*s++) {
248 if (s[-1] == ',') 248 if (s[-1] == ',')
249 s[-1] = '\0'; 249 s[-1] = '\0';
250 } 250 }
251 } else { 251 } else {
252 int len = get_filesystem_list(page); 252 int len = get_filesystem_list(page);
253 char *p, *next; 253 char *p, *next;
254 254
255 page[len] = '\0'; 255 page[len] = '\0';
256 for (p = page-1; p; p = next) { 256 for (p = page-1; p; p = next) {
257 next = strchr(++p, '\n'); 257 next = strchr(++p, '\n');
258 if (*p++ != '\t') 258 if (*p++ != '\t')
259 continue; 259 continue;
260 while ((*s++ = *p++) != '\n') 260 while ((*s++ = *p++) != '\n')
261 ; 261 ;
262 s[-1] = '\0'; 262 s[-1] = '\0';
263 } 263 }
264 } 264 }
265 *s = '\0'; 265 *s = '\0';
266 } 266 }
267 267
268 static int __init do_mount_root(char *name, char *fs, int flags, void *data) 268 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
269 { 269 {
270 int err = sys_mount(name, "/root", fs, flags, data); 270 int err = sys_mount(name, "/root", fs, flags, data);
271 if (err) 271 if (err)
272 return err; 272 return err;
273 273
274 sys_chdir("/root"); 274 sys_chdir("/root");
275 ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev; 275 ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
276 printk("VFS: Mounted root (%s filesystem)%s.\n", 276 printk("VFS: Mounted root (%s filesystem)%s.\n",
277 current->fs->pwdmnt->mnt_sb->s_type->name, 277 current->fs->pwdmnt->mnt_sb->s_type->name,
278 current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ? 278 current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ?
279 " readonly" : ""); 279 " readonly" : "");
280 return 0; 280 return 0;
281 } 281 }
282 282
283 void __init mount_block_root(char *name, int flags) 283 void __init mount_block_root(char *name, int flags)
284 { 284 {
285 char *fs_names = __getname(); 285 char *fs_names = __getname();
286 char *p; 286 char *p;
287 char b[BDEVNAME_SIZE]; 287 char b[BDEVNAME_SIZE];
288 288
289 get_fs_names(fs_names); 289 get_fs_names(fs_names);
290 retry: 290 retry:
291 for (p = fs_names; *p; p += strlen(p)+1) { 291 for (p = fs_names; *p; p += strlen(p)+1) {
292 int err = do_mount_root(name, p, flags, root_mount_data); 292 int err = do_mount_root(name, p, flags, root_mount_data);
293 switch (err) { 293 switch (err) {
294 case 0: 294 case 0:
295 goto out; 295 goto out;
296 case -EACCES: 296 case -EACCES:
297 flags |= MS_RDONLY; 297 flags |= MS_RDONLY;
298 goto retry; 298 goto retry;
299 case -EINVAL: 299 case -EINVAL:
300 continue; 300 continue;
301 } 301 }
302 /* 302 /*
303 * Allow the user to distinguish between failed sys_open 303 * Allow the user to distinguish between failed sys_open
304 * and bad superblock on root device. 304 * and bad superblock on root device.
305 */ 305 */
306 __bdevname(ROOT_DEV, b); 306 __bdevname(ROOT_DEV, b);
307 printk("VFS: Cannot open root device \"%s\" or %s\n", 307 printk("VFS: Cannot open root device \"%s\" or %s\n",
308 root_device_name, b); 308 root_device_name, b);
309 printk("Please append a correct \"root=\" boot option\n"); 309 printk("Please append a correct \"root=\" boot option\n");
310 310
311 panic("VFS: Unable to mount root fs on %s", b); 311 panic("VFS: Unable to mount root fs on %s", b);
312 } 312 }
313 313
314 printk("No filesystem could mount root, tried: "); 314 printk("No filesystem could mount root, tried: ");
315 for (p = fs_names; *p; p += strlen(p)+1) 315 for (p = fs_names; *p; p += strlen(p)+1)
316 printk(" %s", p); 316 printk(" %s", p);
317 printk("\n"); 317 printk("\n");
318 panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b)); 318 panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b));
319 out: 319 out:
320 putname(fs_names); 320 putname(fs_names);
321 } 321 }
322 322
323 #ifdef CONFIG_ROOT_NFS 323 #ifdef CONFIG_ROOT_NFS
324 static int __init mount_nfs_root(void) 324 static int __init mount_nfs_root(void)
325 { 325 {
326 void *data = nfs_root_data(); 326 void *data = nfs_root_data();
327 327
328 create_dev("/dev/root", ROOT_DEV, NULL); 328 create_dev("/dev/root", ROOT_DEV);
329 if (data && 329 if (data &&
330 do_mount_root("/dev/root", "nfs", root_mountflags, data) == 0) 330 do_mount_root("/dev/root", "nfs", root_mountflags, data) == 0)
331 return 1; 331 return 1;
332 return 0; 332 return 0;
333 } 333 }
334 #endif 334 #endif
335 335
336 #if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD) 336 #if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD)
337 void __init change_floppy(char *fmt, ...) 337 void __init change_floppy(char *fmt, ...)
338 { 338 {
339 struct termios termios; 339 struct termios termios;
340 char buf[80]; 340 char buf[80];
341 char c; 341 char c;
342 int fd; 342 int fd;
343 va_list args; 343 va_list args;
344 va_start(args, fmt); 344 va_start(args, fmt);
345 vsprintf(buf, fmt, args); 345 vsprintf(buf, fmt, args);
346 va_end(args); 346 va_end(args);
347 fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); 347 fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
348 if (fd >= 0) { 348 if (fd >= 0) {
349 sys_ioctl(fd, FDEJECT, 0); 349 sys_ioctl(fd, FDEJECT, 0);
350 sys_close(fd); 350 sys_close(fd);
351 } 351 }
352 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); 352 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
353 fd = sys_open("/dev/console", O_RDWR, 0); 353 fd = sys_open("/dev/console", O_RDWR, 0);
354 if (fd >= 0) { 354 if (fd >= 0) {
355 sys_ioctl(fd, TCGETS, (long)&termios); 355 sys_ioctl(fd, TCGETS, (long)&termios);
356 termios.c_lflag &= ~ICANON; 356 termios.c_lflag &= ~ICANON;
357 sys_ioctl(fd, TCSETSF, (long)&termios); 357 sys_ioctl(fd, TCSETSF, (long)&termios);
358 sys_read(fd, &c, 1); 358 sys_read(fd, &c, 1);
359 termios.c_lflag |= ICANON; 359 termios.c_lflag |= ICANON;
360 sys_ioctl(fd, TCSETSF, (long)&termios); 360 sys_ioctl(fd, TCSETSF, (long)&termios);
361 sys_close(fd); 361 sys_close(fd);
362 } 362 }
363 } 363 }
364 #endif 364 #endif
365 365
366 void __init mount_root(void) 366 void __init mount_root(void)
367 { 367 {
368 #ifdef CONFIG_ROOT_NFS 368 #ifdef CONFIG_ROOT_NFS
369 if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { 369 if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
370 if (mount_nfs_root()) 370 if (mount_nfs_root())
371 return; 371 return;
372 372
373 printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n"); 373 printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
374 ROOT_DEV = Root_FD0; 374 ROOT_DEV = Root_FD0;
375 } 375 }
376 #endif 376 #endif
377 #ifdef CONFIG_BLK_DEV_FD 377 #ifdef CONFIG_BLK_DEV_FD
378 if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) { 378 if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
379 /* rd_doload is 2 for a dual initrd/ramload setup */ 379 /* rd_doload is 2 for a dual initrd/ramload setup */
380 if (rd_doload==2) { 380 if (rd_doload==2) {
381 if (rd_load_disk(1)) { 381 if (rd_load_disk(1)) {
382 ROOT_DEV = Root_RAM1; 382 ROOT_DEV = Root_RAM1;
383 root_device_name = NULL; 383 root_device_name = NULL;
384 } 384 }
385 } else 385 } else
386 change_floppy("root floppy"); 386 change_floppy("root floppy");
387 } 387 }
388 #endif 388 #endif
389 create_dev("/dev/root", ROOT_DEV, root_device_name); 389 create_dev("/dev/root", ROOT_DEV);
390 mount_block_root("/dev/root", root_mountflags); 390 mount_block_root("/dev/root", root_mountflags);
391 } 391 }
392 392
393 /* 393 /*
394 * Prepare the namespace - decide what/where to mount, load ramdisks, etc. 394 * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
395 */ 395 */
396 void __init prepare_namespace(void) 396 void __init prepare_namespace(void)
397 { 397 {
398 int is_floppy; 398 int is_floppy;
399 399
400 mount_devfs();
401
402 if (root_delay) { 400 if (root_delay) {
403 printk(KERN_INFO "Waiting %dsec before mounting root device...\n", 401 printk(KERN_INFO "Waiting %dsec before mounting root device...\n",
404 root_delay); 402 root_delay);
405 ssleep(root_delay); 403 ssleep(root_delay);
406 } 404 }
407 405
408 md_run_setup(); 406 md_run_setup();
409 407
410 if (saved_root_name[0]) { 408 if (saved_root_name[0]) {
411 root_device_name = saved_root_name; 409 root_device_name = saved_root_name;
412 if (!strncmp(root_device_name, "mtd", 3)) { 410 if (!strncmp(root_device_name, "mtd", 3)) {
413 mount_block_root(root_device_name, root_mountflags); 411 mount_block_root(root_device_name, root_mountflags);
414 goto out; 412 goto out;
415 } 413 }
416 ROOT_DEV = name_to_dev_t(root_device_name); 414 ROOT_DEV = name_to_dev_t(root_device_name);
417 if (strncmp(root_device_name, "/dev/", 5) == 0) 415 if (strncmp(root_device_name, "/dev/", 5) == 0)
418 root_device_name += 5; 416 root_device_name += 5;
419 } 417 }
420 418
421 is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; 419 is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
422 420
423 if (initrd_load()) 421 if (initrd_load())
424 goto out; 422 goto out;
425 423
426 if (is_floppy && rd_doload && rd_load_disk(0)) 424 if (is_floppy && rd_doload && rd_load_disk(0))
427 ROOT_DEV = Root_RAM0; 425 ROOT_DEV = Root_RAM0;
428 426
429 mount_root(); 427 mount_root();
430 out: 428 out:
431 umount_devfs("/dev");
432 sys_mount(".", "/", NULL, MS_MOVE, NULL); 429 sys_mount(".", "/", NULL, MS_MOVE, NULL);
433 sys_chroot("."); 430 sys_chroot(".");
434 security_sb_post_mountroot(); 431 security_sb_post_mountroot();
435 mount_devfs_fs ();
436 } 432 }
437 433
438 434
1 #include <linux/config.h> 1 #include <linux/config.h>
2 #include <linux/kernel.h> 2 #include <linux/kernel.h>
3 #include <linux/devfs_fs_kernel.h> 3 #include <linux/devfs_fs_kernel.h>
4 #include <linux/init.h> 4 #include <linux/init.h>
5 #include <linux/syscalls.h> 5 #include <linux/syscalls.h>
6 #include <linux/unistd.h> 6 #include <linux/unistd.h>
7 #include <linux/slab.h> 7 #include <linux/slab.h>
8 #include <linux/mount.h> 8 #include <linux/mount.h>
9 #include <linux/major.h> 9 #include <linux/major.h>
10 #include <linux/root_dev.h> 10 #include <linux/root_dev.h>
11 11
12 void change_floppy(char *fmt, ...); 12 void change_floppy(char *fmt, ...);
13 void mount_block_root(char *name, int flags); 13 void mount_block_root(char *name, int flags);
14 void mount_root(void); 14 void mount_root(void);
15 extern int root_mountflags; 15 extern int root_mountflags;
16 extern char *root_device_name; 16 extern char *root_device_name;
17 17
18 #ifdef CONFIG_DEVFS_FS 18 static inline int create_dev(char *name, dev_t dev)
19
20 void mount_devfs(void);
21 void umount_devfs(char *path);
22 int create_dev(char *name, dev_t dev, char *devfs_name);
23
24 #else
25
26 static inline void mount_devfs(void) {}
27 static inline void umount_devfs(const char *path) {}
28
29 static inline int create_dev(char *name, dev_t dev, char *devfs_name)
30 { 19 {
31 sys_unlink(name); 20 sys_unlink(name);
32 return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev)); 21 return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
33 } 22 }
34
35 #endif
36 23
37 #if BITS_PER_LONG == 32 24 #if BITS_PER_LONG == 32
38 static inline u32 bstat(char *name) 25 static inline u32 bstat(char *name)
39 { 26 {
40 struct stat64 stat; 27 struct stat64 stat;
41 if (sys_stat64(name, &stat) != 0) 28 if (sys_stat64(name, &stat) != 0)
42 return 0; 29 return 0;
43 if (!S_ISBLK(stat.st_mode)) 30 if (!S_ISBLK(stat.st_mode))
44 return 0; 31 return 0;
45 if (stat.st_rdev != (u32)stat.st_rdev) 32 if (stat.st_rdev != (u32)stat.st_rdev)
46 return 0; 33 return 0;
47 return stat.st_rdev; 34 return stat.st_rdev;
48 } 35 }
49 #else 36 #else
50 static inline u32 bstat(char *name) 37 static inline u32 bstat(char *name)
51 { 38 {
52 struct stat stat; 39 struct stat stat;
53 if (sys_newstat(name, &stat) != 0) 40 if (sys_newstat(name, &stat) != 0)
54 return 0; 41 return 0;
55 if (!S_ISBLK(stat.st_mode)) 42 if (!S_ISBLK(stat.st_mode))
56 return 0; 43 return 0;
57 return stat.st_rdev; 44 return stat.st_rdev;
58 } 45 }
59 #endif 46 #endif
60 47
61 #ifdef CONFIG_BLK_DEV_RAM 48 #ifdef CONFIG_BLK_DEV_RAM
62 49
63 int __init rd_load_disk(int n); 50 int __init rd_load_disk(int n);
64 int __init rd_load_image(char *from); 51 int __init rd_load_image(char *from);
65 52
66 #else 53 #else
67 54
68 static inline int rd_load_disk(int n) { return 0; } 55 static inline int rd_load_disk(int n) { return 0; }
69 static inline int rd_load_image(char *from) { return 0; } 56 static inline int rd_load_image(char *from) { return 0; }
70 57
71 #endif 58 #endif
72 59
73 #ifdef CONFIG_BLK_DEV_INITRD 60 #ifdef CONFIG_BLK_DEV_INITRD
74 61
75 int __init initrd_load(void); 62 int __init initrd_load(void);
76 63
77 #else 64 #else
78 65
79 static inline int initrd_load(void) { return 0; } 66 static inline int initrd_load(void) { return 0; }
80 67
81 #endif 68 #endif
82 69
83 #ifdef CONFIG_BLK_DEV_MD 70 #ifdef CONFIG_BLK_DEV_MD
84 71
85 void md_run_setup(void); 72 void md_run_setup(void);
86 73
87 #else 74 #else
88 75
89 static inline void md_run_setup(void) {} 76 static inline void md_run_setup(void) {}
90 77
91 #endif 78 #endif
92 79
init/do_mounts_devfs.c
1 File was deleted
2 #include <linux/kernel.h>
3 #include <linux/dirent.h>
4 #include <linux/string.h>
5
6 #include "do_mounts.h"
7
8 void __init mount_devfs(void)
9 {
10 sys_mount("devfs", "/dev", "devfs", 0, NULL);
11 }
12
13 void __init umount_devfs(char *path)
14 {
15 sys_umount(path, 0);
16 }
17
18 /*
19 * If the dir will fit in *buf, return its length. If it won't fit, return
20 * zero. Return -ve on error.
21 */
22 static int __init do_read_dir(int fd, void *buf, int len)
23 {
24 long bytes, n;
25 char *p = buf;
26 sys_lseek(fd, 0, 0);
27
28 for (bytes = 0; bytes < len; bytes += n) {
29 n = sys_getdents64(fd, (struct linux_dirent64 *)(p + bytes),
30 len - bytes);
31 if (n < 0)
32 return n;
33 if (n == 0)
34 return bytes;
35 }
36 return 0;
37 }
38
39 /*
40 * Try to read all of a directory. Returns the contents at *p, which
41 * is kmalloced memory. Returns the number of bytes read at *len. Returns
42 * NULL on error.
43 */
44 static void * __init read_dir(char *path, int *len)
45 {
46 int size;
47 int fd = sys_open(path, 0, 0);
48
49 *len = 0;
50 if (fd < 0)
51 return NULL;
52
53 for (size = 1 << 9; size <= (PAGE_SIZE << MAX_ORDER); size <<= 1) {
54 void *p = kmalloc(size, GFP_KERNEL);
55 int n;
56 if (!p)
57 break;
58 n = do_read_dir(fd, p, size);
59 if (n > 0) {
60 sys_close(fd);
61 *len = n;
62 return p;
63 }
64 kfree(p);
65 if (n == -EINVAL)
66 continue; /* Try a larger buffer */
67 if (n < 0)
68 break;
69 }
70 sys_close(fd);
71 return NULL;
72 }
73
74 /*
75 * recursively scan <path>, looking for a device node of type <dev>
76 */
77 static int __init find_in_devfs(char *path, unsigned dev)
78 {
79 char *end = path + strlen(path);
80 int rest = path + 64 - end;
81 int size;
82 char *p = read_dir(path, &size);
83 char *s;
84
85 if (!p)
86 return -1;
87 for (s = p; s < p + size; s += ((struct linux_dirent64 *)s)->d_reclen) {
88 struct linux_dirent64 *d = (struct linux_dirent64 *)s;
89 if (strlen(d->d_name) + 2 > rest)
90 continue;
91 switch (d->d_type) {
92 case DT_BLK:
93 sprintf(end, "/%s", d->d_name);
94 if (bstat(path) != dev)
95 break;
96 kfree(p);
97 return 0;
98 case DT_DIR:
99 if (strcmp(d->d_name, ".") == 0)
100 break;
101 if (strcmp(d->d_name, "..") == 0)
102 break;
103 sprintf(end, "/%s", d->d_name);
104 if (find_in_devfs(path, dev) < 0)
105 break;
106 kfree(p);
107 return 0;
108 }
109 }
110 kfree(p);
111 return -1;
112 }
113
114 /*
115 * create a device node called <name> which points to
116 * <devfs_name> if possible, otherwise find a device node
117 * which matches <dev> and make <name> a symlink pointing to it.
118 */
119 int __init create_dev(char *name, dev_t dev, char *devfs_name)
120 {
121 char path[64];
122
123 sys_unlink(name);
124 if (devfs_name && devfs_name[0]) {
125 if (strncmp(devfs_name, "/dev/", 5) == 0)
126 devfs_name += 5;
127 sprintf(path, "/dev/%s", devfs_name);
128 if (sys_access(path, 0) == 0)
129 return sys_symlink(devfs_name, name);
130 }
131 if (!dev)
132 return -1;
133 strcpy(path, "/dev");
134 if (find_in_devfs(path, new_encode_dev(dev)) < 0)
135 return -1;
136 return sys_symlink(path + 5, name);
137 }
138 1
init/do_mounts_initrd.c
1 #define __KERNEL_SYSCALLS__ 1 #define __KERNEL_SYSCALLS__
2 #include <linux/unistd.h> 2 #include <linux/unistd.h>
3 #include <linux/kernel.h> 3 #include <linux/kernel.h>
4 #include <linux/fs.h> 4 #include <linux/fs.h>
5 #include <linux/minix_fs.h> 5 #include <linux/minix_fs.h>
6 #include <linux/ext2_fs.h> 6 #include <linux/ext2_fs.h>
7 #include <linux/romfs_fs.h> 7 #include <linux/romfs_fs.h>
8 #include <linux/initrd.h> 8 #include <linux/initrd.h>
9 #include <linux/sched.h> 9 #include <linux/sched.h>
10 10
11 #include "do_mounts.h" 11 #include "do_mounts.h"
12 12
13 unsigned long initrd_start, initrd_end; 13 unsigned long initrd_start, initrd_end;
14 int initrd_below_start_ok; 14 int initrd_below_start_ok;
15 unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */ 15 unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */
16 static int __initdata old_fd, root_fd; 16 static int __initdata old_fd, root_fd;
17 static int __initdata mount_initrd = 1; 17 static int __initdata mount_initrd = 1;
18 18
19 static int __init no_initrd(char *str) 19 static int __init no_initrd(char *str)
20 { 20 {
21 mount_initrd = 0; 21 mount_initrd = 0;
22 return 1; 22 return 1;
23 } 23 }
24 24
25 __setup("noinitrd", no_initrd); 25 __setup("noinitrd", no_initrd);
26 26
27 static int __init do_linuxrc(void * shell) 27 static int __init do_linuxrc(void * shell)
28 { 28 {
29 static char *argv[] = { "linuxrc", NULL, }; 29 static char *argv[] = { "linuxrc", NULL, };
30 extern char * envp_init[]; 30 extern char * envp_init[];
31 31
32 sys_close(old_fd);sys_close(root_fd); 32 sys_close(old_fd);sys_close(root_fd);
33 sys_close(0);sys_close(1);sys_close(2); 33 sys_close(0);sys_close(1);sys_close(2);
34 sys_setsid(); 34 sys_setsid();
35 (void) sys_open("/dev/console",O_RDWR,0); 35 (void) sys_open("/dev/console",O_RDWR,0);
36 (void) sys_dup(0); 36 (void) sys_dup(0);
37 (void) sys_dup(0); 37 (void) sys_dup(0);
38 return execve(shell, argv, envp_init); 38 return execve(shell, argv, envp_init);
39 } 39 }
40 40
41 static void __init handle_initrd(void) 41 static void __init handle_initrd(void)
42 { 42 {
43 int error; 43 int error;
44 int pid; 44 int pid;
45 45
46 real_root_dev = new_encode_dev(ROOT_DEV); 46 real_root_dev = new_encode_dev(ROOT_DEV);
47 create_dev("/dev/root.old", Root_RAM0, NULL); 47 create_dev("/dev/root.old", Root_RAM0);
48 /* mount initrd on rootfs' /root */ 48 /* mount initrd on rootfs' /root */
49 mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY); 49 mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
50 sys_mkdir("/old", 0700); 50 sys_mkdir("/old", 0700);
51 root_fd = sys_open("/", 0, 0); 51 root_fd = sys_open("/", 0, 0);
52 old_fd = sys_open("/old", 0, 0); 52 old_fd = sys_open("/old", 0, 0);
53 /* move initrd over / and chdir/chroot in initrd root */ 53 /* move initrd over / and chdir/chroot in initrd root */
54 sys_chdir("/root"); 54 sys_chdir("/root");
55 sys_mount(".", "/", NULL, MS_MOVE, NULL); 55 sys_mount(".", "/", NULL, MS_MOVE, NULL);
56 sys_chroot("."); 56 sys_chroot(".");
57 mount_devfs_fs ();
58 57
59 current->flags |= PF_NOFREEZE; 58 current->flags |= PF_NOFREEZE;
60 pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD); 59 pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
61 if (pid > 0) { 60 if (pid > 0) {
62 while (pid != sys_wait4(-1, NULL, 0, NULL)) 61 while (pid != sys_wait4(-1, NULL, 0, NULL))
63 yield(); 62 yield();
64 } 63 }
65 64
66 /* move initrd to rootfs' /old */ 65 /* move initrd to rootfs' /old */
67 sys_fchdir(old_fd); 66 sys_fchdir(old_fd);
68 sys_mount("/", ".", NULL, MS_MOVE, NULL); 67 sys_mount("/", ".", NULL, MS_MOVE, NULL);
69 /* switch root and cwd back to / of rootfs */ 68 /* switch root and cwd back to / of rootfs */
70 sys_fchdir(root_fd); 69 sys_fchdir(root_fd);
71 sys_chroot("."); 70 sys_chroot(".");
72 sys_close(old_fd); 71 sys_close(old_fd);
73 sys_close(root_fd); 72 sys_close(root_fd);
74 umount_devfs("/old/dev");
75 73
76 if (new_decode_dev(real_root_dev) == Root_RAM0) { 74 if (new_decode_dev(real_root_dev) == Root_RAM0) {
77 sys_chdir("/old"); 75 sys_chdir("/old");
78 return; 76 return;
79 } 77 }
80 78
81 ROOT_DEV = new_decode_dev(real_root_dev); 79 ROOT_DEV = new_decode_dev(real_root_dev);
82 mount_root(); 80 mount_root();
83 81
84 printk(KERN_NOTICE "Trying to move old root to /initrd ... "); 82 printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
85 error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL); 83 error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
86 if (!error) 84 if (!error)
87 printk("okay\n"); 85 printk("okay\n");
88 else { 86 else {
89 int fd = sys_open("/dev/root.old", O_RDWR, 0); 87 int fd = sys_open("/dev/root.old", O_RDWR, 0);
90 if (error == -ENOENT) 88 if (error == -ENOENT)
91 printk("/initrd does not exist. Ignored.\n"); 89 printk("/initrd does not exist. Ignored.\n");
92 else 90 else
93 printk("failed\n"); 91 printk("failed\n");
94 printk(KERN_NOTICE "Unmounting old root\n"); 92 printk(KERN_NOTICE "Unmounting old root\n");
95 sys_umount("/old", MNT_DETACH); 93 sys_umount("/old", MNT_DETACH);
96 printk(KERN_NOTICE "Trying to free ramdisk memory ... "); 94 printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
97 if (fd < 0) { 95 if (fd < 0) {
98 error = fd; 96 error = fd;
99 } else { 97 } else {
100 error = sys_ioctl(fd, BLKFLSBUF, 0); 98 error = sys_ioctl(fd, BLKFLSBUF, 0);
101 sys_close(fd); 99 sys_close(fd);
102 } 100 }
103 printk(!error ? "okay\n" : "failed\n"); 101 printk(!error ? "okay\n" : "failed\n");
104 } 102 }
105 } 103 }
106 104
107 int __init initrd_load(void) 105 int __init initrd_load(void)
108 { 106 {
109 if (mount_initrd) { 107 if (mount_initrd) {
110 create_dev("/dev/ram", Root_RAM0, NULL); 108 create_dev("/dev/ram", Root_RAM0);
111 /* 109 /*
112 * Load the initrd data into /dev/ram0. Execute it as initrd 110 * Load the initrd data into /dev/ram0. Execute it as initrd
113 * unless /dev/ram0 is supposed to be our actual root device, 111 * unless /dev/ram0 is supposed to be our actual root device,
114 * in that case the ram disk is just set up here, and gets 112 * in that case the ram disk is just set up here, and gets
115 * mounted in the normal path. 113 * mounted in the normal path.
116 */ 114 */
117 if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) { 115 if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
118 sys_unlink("/initrd.image"); 116 sys_unlink("/initrd.image");
119 handle_initrd(); 117 handle_initrd();
120 return 1; 118 return 1;
121 } 119 }
122 } 120 }
123 sys_unlink("/initrd.image"); 121 sys_unlink("/initrd.image");
124 return 0; 122 return 0;
125 } 123 }
126 124
1 1
2 #include <linux/raid/md.h> 2 #include <linux/raid/md.h>
3 3
4 #include "do_mounts.h" 4 #include "do_mounts.h"
5 5
6 /* 6 /*
7 * When md (and any require personalities) are compiled into the kernel 7 * When md (and any require personalities) are compiled into the kernel
8 * (not a module), arrays can be assembles are boot time using with AUTODETECT 8 * (not a module), arrays can be assembles are boot time using with AUTODETECT
9 * where specially marked partitions are registered with md_autodetect_dev(), 9 * where specially marked partitions are registered with md_autodetect_dev(),
10 * and with MD_BOOT where devices to be collected are given on the boot line 10 * and with MD_BOOT where devices to be collected are given on the boot line
11 * with md=..... 11 * with md=.....
12 * The code for that is here. 12 * The code for that is here.
13 */ 13 */
14 14
15 static int __initdata raid_noautodetect, raid_autopart; 15 static int __initdata raid_noautodetect, raid_autopart;
16 16
17 static struct { 17 static struct {
18 int minor; 18 int minor;
19 int partitioned; 19 int partitioned;
20 int level; 20 int level;
21 int chunk; 21 int chunk;
22 char *device_names; 22 char *device_names;
23 } md_setup_args[MAX_MD_DEVS] __initdata; 23 } md_setup_args[MAX_MD_DEVS] __initdata;
24 24
25 static int md_setup_ents __initdata; 25 static int md_setup_ents __initdata;
26 26
27 extern int mdp_major; 27 extern int mdp_major;
28 /* 28 /*
29 * Parse the command-line parameters given our kernel, but do not 29 * Parse the command-line parameters given our kernel, but do not
30 * actually try to invoke the MD device now; that is handled by 30 * actually try to invoke the MD device now; that is handled by
31 * md_setup_drive after the low-level disk drivers have initialised. 31 * md_setup_drive after the low-level disk drivers have initialised.
32 * 32 *
33 * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which 33 * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
34 * assigns the task of parsing integer arguments to the 34 * assigns the task of parsing integer arguments to the
35 * invoked program now). Added ability to initialise all 35 * invoked program now). Added ability to initialise all
36 * the MD devices (by specifying multiple "md=" lines) 36 * the MD devices (by specifying multiple "md=" lines)
37 * instead of just one. -- KTK 37 * instead of just one. -- KTK
38 * 18May2000: Added support for persistent-superblock arrays: 38 * 18May2000: Added support for persistent-superblock arrays:
39 * md=n,0,factor,fault,device-list uses RAID0 for device n 39 * md=n,0,factor,fault,device-list uses RAID0 for device n
40 * md=n,-1,factor,fault,device-list uses LINEAR for device n 40 * md=n,-1,factor,fault,device-list uses LINEAR for device n
41 * md=n,device-list reads a RAID superblock from the devices 41 * md=n,device-list reads a RAID superblock from the devices
42 * elements in device-list are read by name_to_kdev_t so can be 42 * elements in device-list are read by name_to_kdev_t so can be
43 * a hex number or something like /dev/hda1 /dev/sdb 43 * a hex number or something like /dev/hda1 /dev/sdb
44 * 2001-06-03: Dave Cinege <dcinege@psychosis.com> 44 * 2001-06-03: Dave Cinege <dcinege@psychosis.com>
45 * Shifted name_to_kdev_t() and related operations to md_set_drive() 45 * Shifted name_to_kdev_t() and related operations to md_set_drive()
46 * for later execution. Rewrote section to make devfs compatible. 46 * for later execution. Rewrote section to make devfs compatible.
47 */ 47 */
48 static int __init md_setup(char *str) 48 static int __init md_setup(char *str)
49 { 49 {
50 int minor, level, factor, fault, partitioned = 0; 50 int minor, level, factor, fault, partitioned = 0;
51 char *pername = ""; 51 char *pername = "";
52 char *str1; 52 char *str1;
53 int ent; 53 int ent;
54 54
55 if (*str == 'd') { 55 if (*str == 'd') {
56 partitioned = 1; 56 partitioned = 1;
57 str++; 57 str++;
58 } 58 }
59 if (get_option(&str, &minor) != 2) { /* MD Number */ 59 if (get_option(&str, &minor) != 2) { /* MD Number */
60 printk(KERN_WARNING "md: Too few arguments supplied to md=.\n"); 60 printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
61 return 0; 61 return 0;
62 } 62 }
63 str1 = str; 63 str1 = str;
64 if (minor >= MAX_MD_DEVS) { 64 if (minor >= MAX_MD_DEVS) {
65 printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor); 65 printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor);
66 return 0; 66 return 0;
67 } 67 }
68 for (ent=0 ; ent< md_setup_ents ; ent++) 68 for (ent=0 ; ent< md_setup_ents ; ent++)
69 if (md_setup_args[ent].minor == minor && 69 if (md_setup_args[ent].minor == minor &&
70 md_setup_args[ent].partitioned == partitioned) { 70 md_setup_args[ent].partitioned == partitioned) {
71 printk(KERN_WARNING "md: md=%s%d, Specified more than once. " 71 printk(KERN_WARNING "md: md=%s%d, Specified more than once. "
72 "Replacing previous definition.\n", partitioned?"d":"", minor); 72 "Replacing previous definition.\n", partitioned?"d":"", minor);
73 break; 73 break;
74 } 74 }
75 if (ent >= MAX_MD_DEVS) { 75 if (ent >= MAX_MD_DEVS) {
76 printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor); 76 printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor);
77 return 0; 77 return 0;
78 } 78 }
79 if (ent >= md_setup_ents) 79 if (ent >= md_setup_ents)
80 md_setup_ents++; 80 md_setup_ents++;
81 switch (get_option(&str, &level)) { /* RAID level */ 81 switch (get_option(&str, &level)) { /* RAID level */
82 case 2: /* could be 0 or -1.. */ 82 case 2: /* could be 0 or -1.. */
83 if (level == 0 || level == LEVEL_LINEAR) { 83 if (level == 0 || level == LEVEL_LINEAR) {
84 if (get_option(&str, &factor) != 2 || /* Chunk Size */ 84 if (get_option(&str, &factor) != 2 || /* Chunk Size */
85 get_option(&str, &fault) != 2) { 85 get_option(&str, &fault) != 2) {
86 printk(KERN_WARNING "md: Too few arguments supplied to md=.\n"); 86 printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
87 return 0; 87 return 0;
88 } 88 }
89 md_setup_args[ent].level = level; 89 md_setup_args[ent].level = level;
90 md_setup_args[ent].chunk = 1 << (factor+12); 90 md_setup_args[ent].chunk = 1 << (factor+12);
91 if (level == LEVEL_LINEAR) 91 if (level == LEVEL_LINEAR)
92 pername = "linear"; 92 pername = "linear";
93 else 93 else
94 pername = "raid0"; 94 pername = "raid0";
95 break; 95 break;
96 } 96 }
97 /* FALL THROUGH */ 97 /* FALL THROUGH */
98 case 1: /* the first device is numeric */ 98 case 1: /* the first device is numeric */
99 str = str1; 99 str = str1;
100 /* FALL THROUGH */ 100 /* FALL THROUGH */
101 case 0: 101 case 0:
102 md_setup_args[ent].level = LEVEL_NONE; 102 md_setup_args[ent].level = LEVEL_NONE;
103 pername="super-block"; 103 pername="super-block";
104 } 104 }
105 105
106 printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n", 106 printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n",
107 minor, pername, str); 107 minor, pername, str);
108 md_setup_args[ent].device_names = str; 108 md_setup_args[ent].device_names = str;
109 md_setup_args[ent].partitioned = partitioned; 109 md_setup_args[ent].partitioned = partitioned;
110 md_setup_args[ent].minor = minor; 110 md_setup_args[ent].minor = minor;
111 111
112 return 1; 112 return 1;
113 } 113 }
114 114
115 #define MdpMinorShift 6 115 #define MdpMinorShift 6
116 116
117 static void __init md_setup_drive(void) 117 static void __init md_setup_drive(void)
118 { 118 {
119 int minor, i, ent, partitioned; 119 int minor, i, ent, partitioned;
120 dev_t dev; 120 dev_t dev;
121 dev_t devices[MD_SB_DISKS+1]; 121 dev_t devices[MD_SB_DISKS+1];
122 122
123 for (ent = 0; ent < md_setup_ents ; ent++) { 123 for (ent = 0; ent < md_setup_ents ; ent++) {
124 int fd; 124 int fd;
125 int err = 0; 125 int err = 0;
126 char *devname; 126 char *devname;
127 mdu_disk_info_t dinfo; 127 mdu_disk_info_t dinfo;
128 char name[16], devfs_name[16]; 128 char name[16];
129 129
130 minor = md_setup_args[ent].minor; 130 minor = md_setup_args[ent].minor;
131 partitioned = md_setup_args[ent].partitioned; 131 partitioned = md_setup_args[ent].partitioned;
132 devname = md_setup_args[ent].device_names; 132 devname = md_setup_args[ent].device_names;
133 133
134 sprintf(name, "/dev/md%s%d", partitioned?"_d":"", minor); 134 sprintf(name, "/dev/md%s%d", partitioned?"_d":"", minor);
135 sprintf(devfs_name, "/dev/md/%s%d", partitioned?"d":"", minor);
136 if (partitioned) 135 if (partitioned)
137 dev = MKDEV(mdp_major, minor << MdpMinorShift); 136 dev = MKDEV(mdp_major, minor << MdpMinorShift);
138 else 137 else
139 dev = MKDEV(MD_MAJOR, minor); 138 dev = MKDEV(MD_MAJOR, minor);
140 create_dev(name, dev, devfs_name); 139 create_dev(name, dev);
141 for (i = 0; i < MD_SB_DISKS && devname != 0; i++) { 140 for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
142 char *p; 141 char *p;
143 char comp_name[64]; 142 char comp_name[64];
144 u32 rdev; 143 u32 rdev;
145 144
146 p = strchr(devname, ','); 145 p = strchr(devname, ',');
147 if (p) 146 if (p)
148 *p++ = 0; 147 *p++ = 0;
149 148
150 dev = name_to_dev_t(devname); 149 dev = name_to_dev_t(devname);
151 if (strncmp(devname, "/dev/", 5) == 0) 150 if (strncmp(devname, "/dev/", 5) == 0)
152 devname += 5; 151 devname += 5;
153 snprintf(comp_name, 63, "/dev/%s", devname); 152 snprintf(comp_name, 63, "/dev/%s", devname);
154 rdev = bstat(comp_name); 153 rdev = bstat(comp_name);
155 if (rdev) 154 if (rdev)
156 dev = new_decode_dev(rdev); 155 dev = new_decode_dev(rdev);
157 if (!dev) { 156 if (!dev) {
158 printk(KERN_WARNING "md: Unknown device name: %s\n", devname); 157 printk(KERN_WARNING "md: Unknown device name: %s\n", devname);
159 break; 158 break;
160 } 159 }
161 160
162 devices[i] = dev; 161 devices[i] = dev;
163 162
164 devname = p; 163 devname = p;
165 } 164 }
166 devices[i] = 0; 165 devices[i] = 0;
167 166
168 if (!i) 167 if (!i)
169 continue; 168 continue;
170 169
171 printk(KERN_INFO "md: Loading md%s%d: %s\n", 170 printk(KERN_INFO "md: Loading md%s%d: %s\n",
172 partitioned ? "_d" : "", minor, 171 partitioned ? "_d" : "", minor,
173 md_setup_args[ent].device_names); 172 md_setup_args[ent].device_names);
174 173
175 fd = sys_open(name, 0, 0); 174 fd = sys_open(name, 0, 0);
176 if (fd < 0) { 175 if (fd < 0) {
177 printk(KERN_ERR "md: open failed - cannot start " 176 printk(KERN_ERR "md: open failed - cannot start "
178 "array %s\n", name); 177 "array %s\n", name);
179 continue; 178 continue;
180 } 179 }
181 if (sys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) { 180 if (sys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) {
182 printk(KERN_WARNING 181 printk(KERN_WARNING
183 "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n", 182 "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n",
184 minor); 183 minor);
185 sys_close(fd); 184 sys_close(fd);
186 continue; 185 continue;
187 } 186 }
188 187
189 if (md_setup_args[ent].level != LEVEL_NONE) { 188 if (md_setup_args[ent].level != LEVEL_NONE) {
190 /* non-persistent */ 189 /* non-persistent */
191 mdu_array_info_t ainfo; 190 mdu_array_info_t ainfo;
192 ainfo.level = md_setup_args[ent].level; 191 ainfo.level = md_setup_args[ent].level;
193 ainfo.size = 0; 192 ainfo.size = 0;
194 ainfo.nr_disks =0; 193 ainfo.nr_disks =0;
195 ainfo.raid_disks =0; 194 ainfo.raid_disks =0;
196 while (devices[ainfo.raid_disks]) 195 while (devices[ainfo.raid_disks])
197 ainfo.raid_disks++; 196 ainfo.raid_disks++;
198 ainfo.md_minor =minor; 197 ainfo.md_minor =minor;
199 ainfo.not_persistent = 1; 198 ainfo.not_persistent = 1;
200 199
201 ainfo.state = (1 << MD_SB_CLEAN); 200 ainfo.state = (1 << MD_SB_CLEAN);
202 ainfo.layout = 0; 201 ainfo.layout = 0;
203 ainfo.chunk_size = md_setup_args[ent].chunk; 202 ainfo.chunk_size = md_setup_args[ent].chunk;
204 err = sys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo); 203 err = sys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo);
205 for (i = 0; !err && i <= MD_SB_DISKS; i++) { 204 for (i = 0; !err && i <= MD_SB_DISKS; i++) {
206 dev = devices[i]; 205 dev = devices[i];
207 if (!dev) 206 if (!dev)
208 break; 207 break;
209 dinfo.number = i; 208 dinfo.number = i;
210 dinfo.raid_disk = i; 209 dinfo.raid_disk = i;
211 dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC); 210 dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC);
212 dinfo.major = MAJOR(dev); 211 dinfo.major = MAJOR(dev);
213 dinfo.minor = MINOR(dev); 212 dinfo.minor = MINOR(dev);
214 err = sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo); 213 err = sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
215 } 214 }
216 } else { 215 } else {
217 /* persistent */ 216 /* persistent */
218 for (i = 0; i <= MD_SB_DISKS; i++) { 217 for (i = 0; i <= MD_SB_DISKS; i++) {
219 dev = devices[i]; 218 dev = devices[i];
220 if (!dev) 219 if (!dev)
221 break; 220 break;
222 dinfo.major = MAJOR(dev); 221 dinfo.major = MAJOR(dev);
223 dinfo.minor = MINOR(dev); 222 dinfo.minor = MINOR(dev);
224 sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo); 223 sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
225 } 224 }
226 } 225 }
227 if (!err) 226 if (!err)
228 err = sys_ioctl(fd, RUN_ARRAY, 0); 227 err = sys_ioctl(fd, RUN_ARRAY, 0);
229 if (err) 228 if (err)
230 printk(KERN_WARNING "md: starting md%d failed\n", minor); 229 printk(KERN_WARNING "md: starting md%d failed\n", minor);
231 else { 230 else {
232 /* reread the partition table. 231 /* reread the partition table.
233 * I (neilb) and not sure why this is needed, but I cannot 232 * I (neilb) and not sure why this is needed, but I cannot
234 * boot a kernel with devfs compiled in from partitioned md 233 * boot a kernel with devfs compiled in from partitioned md
235 * array without it 234 * array without it
236 */ 235 */
237 sys_close(fd); 236 sys_close(fd);
238 fd = sys_open(name, 0, 0); 237 fd = sys_open(name, 0, 0);
239 sys_ioctl(fd, BLKRRPART, 0); 238 sys_ioctl(fd, BLKRRPART, 0);
240 } 239 }
241 sys_close(fd); 240 sys_close(fd);
242 } 241 }
243 } 242 }
244 243
245 static int __init raid_setup(char *str) 244 static int __init raid_setup(char *str)
246 { 245 {
247 int len, pos; 246 int len, pos;
248 247
249 len = strlen(str) + 1; 248 len = strlen(str) + 1;
250 pos = 0; 249 pos = 0;
251 250
252 while (pos < len) { 251 while (pos < len) {
253 char *comma = strchr(str+pos, ','); 252 char *comma = strchr(str+pos, ',');
254 int wlen; 253 int wlen;
255 if (comma) 254 if (comma)
256 wlen = (comma-str)-pos; 255 wlen = (comma-str)-pos;
257 else wlen = (len-1)-pos; 256 else wlen = (len-1)-pos;
258 257
259 if (!strncmp(str, "noautodetect", wlen)) 258 if (!strncmp(str, "noautodetect", wlen))
260 raid_noautodetect = 1; 259 raid_noautodetect = 1;
261 if (strncmp(str, "partitionable", wlen)==0) 260 if (strncmp(str, "partitionable", wlen)==0)
262 raid_autopart = 1; 261 raid_autopart = 1;
263 if (strncmp(str, "part", wlen)==0) 262 if (strncmp(str, "part", wlen)==0)
264 raid_autopart = 1; 263 raid_autopart = 1;
265 pos += wlen+1; 264 pos += wlen+1;
266 } 265 }
267 return 1; 266 return 1;
268 } 267 }
269 268
270 __setup("raid=", raid_setup); 269 __setup("raid=", raid_setup);
271 __setup("md=", md_setup); 270 __setup("md=", md_setup);
272 271
273 void __init md_run_setup(void) 272 void __init md_run_setup(void)
274 { 273 {
275 create_dev("/dev/md0", MKDEV(MD_MAJOR, 0), "md/0"); 274 create_dev("/dev/md0", MKDEV(MD_MAJOR, 0));
276 if (raid_noautodetect) 275 if (raid_noautodetect)
277 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n"); 276 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
278 else { 277 else {
279 int fd = sys_open("/dev/md0", 0, 0); 278 int fd = sys_open("/dev/md0", 0, 0);
280 if (fd >= 0) { 279 if (fd >= 0) {
281 sys_ioctl(fd, RAID_AUTORUN, raid_autopart); 280 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
282 sys_close(fd); 281 sys_close(fd);
283 } 282 }
284 } 283 }
285 md_setup_drive(); 284 md_setup_drive();
286 } 285 }
287 286
1 1
2 #include <linux/kernel.h> 2 #include <linux/kernel.h>
3 #include <linux/fs.h> 3 #include <linux/fs.h>
4 #include <linux/minix_fs.h> 4 #include <linux/minix_fs.h>
5 #include <linux/ext2_fs.h> 5 #include <linux/ext2_fs.h>
6 #include <linux/romfs_fs.h> 6 #include <linux/romfs_fs.h>
7 #include <linux/cramfs_fs.h> 7 #include <linux/cramfs_fs.h>
8 #include <linux/initrd.h> 8 #include <linux/initrd.h>
9 #include <linux/string.h> 9 #include <linux/string.h>
10 10
11 #include "do_mounts.h" 11 #include "do_mounts.h"
12 12
13 #define BUILD_CRAMDISK 13 #define BUILD_CRAMDISK
14 14
15 int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */ 15 int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */
16 16
17 static int __init prompt_ramdisk(char *str) 17 static int __init prompt_ramdisk(char *str)
18 { 18 {
19 rd_prompt = simple_strtol(str,NULL,0) & 1; 19 rd_prompt = simple_strtol(str,NULL,0) & 1;
20 return 1; 20 return 1;
21 } 21 }
22 __setup("prompt_ramdisk=", prompt_ramdisk); 22 __setup("prompt_ramdisk=", prompt_ramdisk);
23 23
24 int __initdata rd_image_start; /* starting block # of image */ 24 int __initdata rd_image_start; /* starting block # of image */
25 25
26 static int __init ramdisk_start_setup(char *str) 26 static int __init ramdisk_start_setup(char *str)
27 { 27 {
28 rd_image_start = simple_strtol(str,NULL,0); 28 rd_image_start = simple_strtol(str,NULL,0);
29 return 1; 29 return 1;
30 } 30 }
31 __setup("ramdisk_start=", ramdisk_start_setup); 31 __setup("ramdisk_start=", ramdisk_start_setup);
32 32
33 static int __init crd_load(int in_fd, int out_fd); 33 static int __init crd_load(int in_fd, int out_fd);
34 34
35 /* 35 /*
36 * This routine tries to find a RAM disk image to load, and returns the 36 * This routine tries to find a RAM disk image to load, and returns the
37 * number of blocks to read for a non-compressed image, 0 if the image 37 * number of blocks to read for a non-compressed image, 0 if the image
38 * is a compressed image, and -1 if an image with the right magic 38 * is a compressed image, and -1 if an image with the right magic
39 * numbers could not be found. 39 * numbers could not be found.
40 * 40 *
41 * We currently check for the following magic numbers: 41 * We currently check for the following magic numbers:
42 * minix 42 * minix
43 * ext2 43 * ext2
44 * romfs 44 * romfs
45 * cramfs 45 * cramfs
46 * gzip 46 * gzip
47 */ 47 */
48 static int __init 48 static int __init
49 identify_ramdisk_image(int fd, int start_block) 49 identify_ramdisk_image(int fd, int start_block)
50 { 50 {
51 const int size = 512; 51 const int size = 512;
52 struct minix_super_block *minixsb; 52 struct minix_super_block *minixsb;
53 struct ext2_super_block *ext2sb; 53 struct ext2_super_block *ext2sb;
54 struct romfs_super_block *romfsb; 54 struct romfs_super_block *romfsb;
55 struct cramfs_super *cramfsb; 55 struct cramfs_super *cramfsb;
56 int nblocks = -1; 56 int nblocks = -1;
57 unsigned char *buf; 57 unsigned char *buf;
58 58
59 buf = kmalloc(size, GFP_KERNEL); 59 buf = kmalloc(size, GFP_KERNEL);
60 if (buf == 0) 60 if (buf == 0)
61 return -1; 61 return -1;
62 62
63 minixsb = (struct minix_super_block *) buf; 63 minixsb = (struct minix_super_block *) buf;
64 ext2sb = (struct ext2_super_block *) buf; 64 ext2sb = (struct ext2_super_block *) buf;
65 romfsb = (struct romfs_super_block *) buf; 65 romfsb = (struct romfs_super_block *) buf;
66 cramfsb = (struct cramfs_super *) buf; 66 cramfsb = (struct cramfs_super *) buf;
67 memset(buf, 0xe5, size); 67 memset(buf, 0xe5, size);
68 68
69 /* 69 /*
70 * Read block 0 to test for gzipped kernel 70 * Read block 0 to test for gzipped kernel
71 */ 71 */
72 sys_lseek(fd, start_block * BLOCK_SIZE, 0); 72 sys_lseek(fd, start_block * BLOCK_SIZE, 0);
73 sys_read(fd, buf, size); 73 sys_read(fd, buf, size);
74 74
75 /* 75 /*
76 * If it matches the gzip magic numbers, return -1 76 * If it matches the gzip magic numbers, return -1
77 */ 77 */
78 if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) { 78 if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
79 printk(KERN_NOTICE 79 printk(KERN_NOTICE
80 "RAMDISK: Compressed image found at block %d\n", 80 "RAMDISK: Compressed image found at block %d\n",
81 start_block); 81 start_block);
82 nblocks = 0; 82 nblocks = 0;
83 goto done; 83 goto done;
84 } 84 }
85 85
86 /* romfs is at block zero too */ 86 /* romfs is at block zero too */
87 if (romfsb->word0 == ROMSB_WORD0 && 87 if (romfsb->word0 == ROMSB_WORD0 &&
88 romfsb->word1 == ROMSB_WORD1) { 88 romfsb->word1 == ROMSB_WORD1) {
89 printk(KERN_NOTICE 89 printk(KERN_NOTICE
90 "RAMDISK: romfs filesystem found at block %d\n", 90 "RAMDISK: romfs filesystem found at block %d\n",
91 start_block); 91 start_block);
92 nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; 92 nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
93 goto done; 93 goto done;
94 } 94 }
95 95
96 if (cramfsb->magic == CRAMFS_MAGIC) { 96 if (cramfsb->magic == CRAMFS_MAGIC) {
97 printk(KERN_NOTICE 97 printk(KERN_NOTICE
98 "RAMDISK: cramfs filesystem found at block %d\n", 98 "RAMDISK: cramfs filesystem found at block %d\n",
99 start_block); 99 start_block);
100 nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS; 100 nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
101 goto done; 101 goto done;
102 } 102 }
103 103
104 /* 104 /*
105 * Read block 1 to test for minix and ext2 superblock 105 * Read block 1 to test for minix and ext2 superblock
106 */ 106 */
107 sys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0); 107 sys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
108 sys_read(fd, buf, size); 108 sys_read(fd, buf, size);
109 109
110 /* Try minix */ 110 /* Try minix */
111 if (minixsb->s_magic == MINIX_SUPER_MAGIC || 111 if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
112 minixsb->s_magic == MINIX_SUPER_MAGIC2) { 112 minixsb->s_magic == MINIX_SUPER_MAGIC2) {
113 printk(KERN_NOTICE 113 printk(KERN_NOTICE
114 "RAMDISK: Minix filesystem found at block %d\n", 114 "RAMDISK: Minix filesystem found at block %d\n",
115 start_block); 115 start_block);
116 nblocks = minixsb->s_nzones << minixsb->s_log_zone_size; 116 nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
117 goto done; 117 goto done;
118 } 118 }
119 119
120 /* Try ext2 */ 120 /* Try ext2 */
121 if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { 121 if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
122 printk(KERN_NOTICE 122 printk(KERN_NOTICE
123 "RAMDISK: ext2 filesystem found at block %d\n", 123 "RAMDISK: ext2 filesystem found at block %d\n",
124 start_block); 124 start_block);
125 nblocks = le32_to_cpu(ext2sb->s_blocks_count) << 125 nblocks = le32_to_cpu(ext2sb->s_blocks_count) <<
126 le32_to_cpu(ext2sb->s_log_block_size); 126 le32_to_cpu(ext2sb->s_log_block_size);
127 goto done; 127 goto done;
128 } 128 }
129 129
130 printk(KERN_NOTICE 130 printk(KERN_NOTICE
131 "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n", 131 "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
132 start_block); 132 start_block);
133 133
134 done: 134 done:
135 sys_lseek(fd, start_block * BLOCK_SIZE, 0); 135 sys_lseek(fd, start_block * BLOCK_SIZE, 0);
136 kfree(buf); 136 kfree(buf);
137 return nblocks; 137 return nblocks;
138 } 138 }
139 139
140 int __init rd_load_image(char *from) 140 int __init rd_load_image(char *from)
141 { 141 {
142 int res = 0; 142 int res = 0;
143 int in_fd, out_fd; 143 int in_fd, out_fd;
144 unsigned long rd_blocks, devblocks; 144 unsigned long rd_blocks, devblocks;
145 int nblocks, i, disk; 145 int nblocks, i, disk;
146 char *buf = NULL; 146 char *buf = NULL;
147 unsigned short rotate = 0; 147 unsigned short rotate = 0;
148 #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) 148 #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
149 char rotator[4] = { '|' , '/' , '-' , '\\' }; 149 char rotator[4] = { '|' , '/' , '-' , '\\' };
150 #endif 150 #endif
151 151
152 out_fd = sys_open("/dev/ram", O_RDWR, 0); 152 out_fd = sys_open("/dev/ram", O_RDWR, 0);
153 if (out_fd < 0) 153 if (out_fd < 0)
154 goto out; 154 goto out;
155 155
156 in_fd = sys_open(from, O_RDONLY, 0); 156 in_fd = sys_open(from, O_RDONLY, 0);
157 if (in_fd < 0) 157 if (in_fd < 0)
158 goto noclose_input; 158 goto noclose_input;
159 159
160 nblocks = identify_ramdisk_image(in_fd, rd_image_start); 160 nblocks = identify_ramdisk_image(in_fd, rd_image_start);
161 if (nblocks < 0) 161 if (nblocks < 0)
162 goto done; 162 goto done;
163 163
164 if (nblocks == 0) { 164 if (nblocks == 0) {
165 #ifdef BUILD_CRAMDISK 165 #ifdef BUILD_CRAMDISK
166 if (crd_load(in_fd, out_fd) == 0) 166 if (crd_load(in_fd, out_fd) == 0)
167 goto successful_load; 167 goto successful_load;
168 #else 168 #else
169 printk(KERN_NOTICE 169 printk(KERN_NOTICE
170 "RAMDISK: Kernel does not support compressed " 170 "RAMDISK: Kernel does not support compressed "
171 "RAM disk images\n"); 171 "RAM disk images\n");
172 #endif 172 #endif
173 goto done; 173 goto done;
174 } 174 }
175 175
176 /* 176 /*
177 * NOTE NOTE: nblocks is not actually blocks but 177 * NOTE NOTE: nblocks is not actually blocks but
178 * the number of kibibytes of data to load into a ramdisk. 178 * the number of kibibytes of data to load into a ramdisk.
179 * So any ramdisk block size that is a multiple of 1KiB should 179 * So any ramdisk block size that is a multiple of 1KiB should
180 * work when the appropriate ramdisk_blocksize is specified 180 * work when the appropriate ramdisk_blocksize is specified
181 * on the command line. 181 * on the command line.
182 * 182 *
183 * The default ramdisk_blocksize is 1KiB and it is generally 183 * The default ramdisk_blocksize is 1KiB and it is generally
184 * silly to use anything else, so make sure to use 1KiB 184 * silly to use anything else, so make sure to use 1KiB
185 * blocksize while generating ext2fs ramdisk-images. 185 * blocksize while generating ext2fs ramdisk-images.
186 */ 186 */
187 if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0) 187 if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
188 rd_blocks = 0; 188 rd_blocks = 0;
189 else 189 else
190 rd_blocks >>= 1; 190 rd_blocks >>= 1;
191 191
192 if (nblocks > rd_blocks) { 192 if (nblocks > rd_blocks) {
193 printk("RAMDISK: image too big! (%dKiB/%ldKiB)\n", 193 printk("RAMDISK: image too big! (%dKiB/%ldKiB)\n",
194 nblocks, rd_blocks); 194 nblocks, rd_blocks);
195 goto done; 195 goto done;
196 } 196 }
197 197
198 /* 198 /*
199 * OK, time to copy in the data 199 * OK, time to copy in the data
200 */ 200 */
201 if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0) 201 if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
202 devblocks = 0; 202 devblocks = 0;
203 else 203 else
204 devblocks >>= 1; 204 devblocks >>= 1;
205 205
206 if (strcmp(from, "/initrd.image") == 0) 206 if (strcmp(from, "/initrd.image") == 0)
207 devblocks = nblocks; 207 devblocks = nblocks;
208 208
209 if (devblocks == 0) { 209 if (devblocks == 0) {
210 printk(KERN_ERR "RAMDISK: could not determine device size\n"); 210 printk(KERN_ERR "RAMDISK: could not determine device size\n");
211 goto done; 211 goto done;
212 } 212 }
213 213
214 buf = kmalloc(BLOCK_SIZE, GFP_KERNEL); 214 buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
215 if (buf == 0) { 215 if (buf == 0) {
216 printk(KERN_ERR "RAMDISK: could not allocate buffer\n"); 216 printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
217 goto done; 217 goto done;
218 } 218 }
219 219
220 printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ", 220 printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ",
221 nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : ""); 221 nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
222 for (i = 0, disk = 1; i < nblocks; i++) { 222 for (i = 0, disk = 1; i < nblocks; i++) {
223 if (i && (i % devblocks == 0)) { 223 if (i && (i % devblocks == 0)) {
224 printk("done disk #%d.\n", disk++); 224 printk("done disk #%d.\n", disk++);
225 rotate = 0; 225 rotate = 0;
226 if (sys_close(in_fd)) { 226 if (sys_close(in_fd)) {
227 printk("Error closing the disk.\n"); 227 printk("Error closing the disk.\n");
228 goto noclose_input; 228 goto noclose_input;
229 } 229 }
230 change_floppy("disk #%d", disk); 230 change_floppy("disk #%d", disk);
231 in_fd = sys_open(from, O_RDONLY, 0); 231 in_fd = sys_open(from, O_RDONLY, 0);
232 if (in_fd < 0) { 232 if (in_fd < 0) {
233 printk("Error opening disk.\n"); 233 printk("Error opening disk.\n");
234 goto noclose_input; 234 goto noclose_input;
235 } 235 }
236 printk("Loading disk #%d... ", disk); 236 printk("Loading disk #%d... ", disk);
237 } 237 }
238 sys_read(in_fd, buf, BLOCK_SIZE); 238 sys_read(in_fd, buf, BLOCK_SIZE);
239 sys_write(out_fd, buf, BLOCK_SIZE); 239 sys_write(out_fd, buf, BLOCK_SIZE);
240 #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) 240 #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
241 if (!(i % 16)) { 241 if (!(i % 16)) {
242 printk("%c\b", rotator[rotate & 0x3]); 242 printk("%c\b", rotator[rotate & 0x3]);
243 rotate++; 243 rotate++;
244 } 244 }
245 #endif 245 #endif
246 } 246 }
247 printk("done.\n"); 247 printk("done.\n");
248 248
249 successful_load: 249 successful_load:
250 res = 1; 250 res = 1;
251 done: 251 done:
252 sys_close(in_fd); 252 sys_close(in_fd);
253 noclose_input: 253 noclose_input:
254 sys_close(out_fd); 254 sys_close(out_fd);
255 out: 255 out:
256 kfree(buf); 256 kfree(buf);
257 sys_unlink("/dev/ram"); 257 sys_unlink("/dev/ram");
258 return res; 258 return res;
259 } 259 }
260 260
261 int __init rd_load_disk(int n) 261 int __init rd_load_disk(int n)
262 { 262 {
263 if (rd_prompt) 263 if (rd_prompt)
264 change_floppy("root floppy disk to be loaded into RAM disk"); 264 change_floppy("root floppy disk to be loaded into RAM disk");
265 create_dev("/dev/root", ROOT_DEV, root_device_name); 265 create_dev("/dev/root", ROOT_DEV);
266 create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL); 266 create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n));
267 return rd_load_image("/dev/root"); 267 return rd_load_image("/dev/root");
268 } 268 }
269 269
270 #ifdef BUILD_CRAMDISK 270 #ifdef BUILD_CRAMDISK
271 271
272 /* 272 /*
273 * gzip declarations 273 * gzip declarations
274 */ 274 */
275 275
276 #define OF(args) args 276 #define OF(args) args
277 277
278 #ifndef memzero 278 #ifndef memzero
279 #define memzero(s, n) memset ((s), 0, (n)) 279 #define memzero(s, n) memset ((s), 0, (n))
280 #endif 280 #endif
281 281
282 typedef unsigned char uch; 282 typedef unsigned char uch;
283 typedef unsigned short ush; 283 typedef unsigned short ush;
284 typedef unsigned long ulg; 284 typedef unsigned long ulg;
285 285
286 #define INBUFSIZ 4096 286 #define INBUFSIZ 4096
287 #define WSIZE 0x8000 /* window size--must be a power of two, and */ 287 #define WSIZE 0x8000 /* window size--must be a power of two, and */
288 /* at least 32K for zip's deflate method */ 288 /* at least 32K for zip's deflate method */
289 289
290 static uch *inbuf; 290 static uch *inbuf;
291 static uch *window; 291 static uch *window;
292 292
293 static unsigned insize; /* valid bytes in inbuf */ 293 static unsigned insize; /* valid bytes in inbuf */
294 static unsigned inptr; /* index of next byte to be processed in inbuf */ 294 static unsigned inptr; /* index of next byte to be processed in inbuf */
295 static unsigned outcnt; /* bytes in output buffer */ 295 static unsigned outcnt; /* bytes in output buffer */
296 static int exit_code; 296 static int exit_code;
297 static int unzip_error; 297 static int unzip_error;
298 static long bytes_out; 298 static long bytes_out;
299 static int crd_infd, crd_outfd; 299 static int crd_infd, crd_outfd;
300 300
301 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) 301 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
302 302
303 /* Diagnostic functions (stubbed out) */ 303 /* Diagnostic functions (stubbed out) */
304 #define Assert(cond,msg) 304 #define Assert(cond,msg)
305 #define Trace(x) 305 #define Trace(x)
306 #define Tracev(x) 306 #define Tracev(x)
307 #define Tracevv(x) 307 #define Tracevv(x)
308 #define Tracec(c,x) 308 #define Tracec(c,x)
309 #define Tracecv(c,x) 309 #define Tracecv(c,x)
310 310
311 #define STATIC static 311 #define STATIC static
312 #define INIT __init 312 #define INIT __init
313 313
314 static int __init fill_inbuf(void); 314 static int __init fill_inbuf(void);
315 static void __init flush_window(void); 315 static void __init flush_window(void);
316 static void __init *malloc(size_t size); 316 static void __init *malloc(size_t size);
317 static void __init free(void *where); 317 static void __init free(void *where);
318 static void __init error(char *m); 318 static void __init error(char *m);
319 static void __init gzip_mark(void **); 319 static void __init gzip_mark(void **);
320 static void __init gzip_release(void **); 320 static void __init gzip_release(void **);
321 321
322 #include "../lib/inflate.c" 322 #include "../lib/inflate.c"
323 323
324 static void __init *malloc(size_t size) 324 static void __init *malloc(size_t size)
325 { 325 {
326 return kmalloc(size, GFP_KERNEL); 326 return kmalloc(size, GFP_KERNEL);
327 } 327 }
328 328
329 static void __init free(void *where) 329 static void __init free(void *where)
330 { 330 {
331 kfree(where); 331 kfree(where);
332 } 332 }
333 333
334 static void __init gzip_mark(void **ptr) 334 static void __init gzip_mark(void **ptr)
335 { 335 {
336 } 336 }
337 337
338 static void __init gzip_release(void **ptr) 338 static void __init gzip_release(void **ptr)
339 { 339 {
340 } 340 }
341 341
342 342
343 /* =========================================================================== 343 /* ===========================================================================
344 * Fill the input buffer. This is called only when the buffer is empty 344 * Fill the input buffer. This is called only when the buffer is empty
345 * and at least one byte is really needed. 345 * and at least one byte is really needed.
346 * Returning -1 does not guarantee that gunzip() will ever return. 346 * Returning -1 does not guarantee that gunzip() will ever return.
347 */ 347 */
348 static int __init fill_inbuf(void) 348 static int __init fill_inbuf(void)
349 { 349 {
350 if (exit_code) return -1; 350 if (exit_code) return -1;
351 351
352 insize = sys_read(crd_infd, inbuf, INBUFSIZ); 352 insize = sys_read(crd_infd, inbuf, INBUFSIZ);
353 if (insize == 0) { 353 if (insize == 0) {
354 error("RAMDISK: ran out of compressed data"); 354 error("RAMDISK: ran out of compressed data");
355 return -1; 355 return -1;
356 } 356 }
357 357
358 inptr = 1; 358 inptr = 1;
359 359
360 return inbuf[0]; 360 return inbuf[0];
361 } 361 }
362 362
363 /* =========================================================================== 363 /* ===========================================================================
364 * Write the output window window[0..outcnt-1] and update crc and bytes_out. 364 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
365 * (Used for the decompressed data only.) 365 * (Used for the decompressed data only.)
366 */ 366 */
367 static void __init flush_window(void) 367 static void __init flush_window(void)
368 { 368 {
369 ulg c = crc; /* temporary variable */ 369 ulg c = crc; /* temporary variable */
370 unsigned n, written; 370 unsigned n, written;
371 uch *in, ch; 371 uch *in, ch;
372 372
373 written = sys_write(crd_outfd, window, outcnt); 373 written = sys_write(crd_outfd, window, outcnt);
374 if (written != outcnt && unzip_error == 0) { 374 if (written != outcnt && unzip_error == 0) {
375 printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n", 375 printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
376 written, outcnt, bytes_out); 376 written, outcnt, bytes_out);
377 unzip_error = 1; 377 unzip_error = 1;
378 } 378 }
379 in = window; 379 in = window;
380 for (n = 0; n < outcnt; n++) { 380 for (n = 0; n < outcnt; n++) {
381 ch = *in++; 381 ch = *in++;
382 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); 382 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
383 } 383 }
384 crc = c; 384 crc = c;
385 bytes_out += (ulg)outcnt; 385 bytes_out += (ulg)outcnt;
386 outcnt = 0; 386 outcnt = 0;
387 } 387 }
388 388
389 static void __init error(char *x) 389 static void __init error(char *x)
390 { 390 {
391 printk(KERN_ERR "%s\n", x); 391 printk(KERN_ERR "%s\n", x);
392 exit_code = 1; 392 exit_code = 1;
393 unzip_error = 1; 393 unzip_error = 1;
394 } 394 }
395 395
396 static int __init crd_load(int in_fd, int out_fd) 396 static int __init crd_load(int in_fd, int out_fd)
397 { 397 {
398 int result; 398 int result;
399 399
400 insize = 0; /* valid bytes in inbuf */ 400 insize = 0; /* valid bytes in inbuf */
401 inptr = 0; /* index of next byte to be processed in inbuf */ 401 inptr = 0; /* index of next byte to be processed in inbuf */
402 outcnt = 0; /* bytes in output buffer */ 402 outcnt = 0; /* bytes in output buffer */
403 exit_code = 0; 403 exit_code = 0;
404 bytes_out = 0; 404 bytes_out = 0;
405 crc = (ulg)0xffffffffL; /* shift register contents */ 405 crc = (ulg)0xffffffffL; /* shift register contents */
406 406
407 crd_infd = in_fd; 407 crd_infd = in_fd;
408 crd_outfd = out_fd; 408 crd_outfd = out_fd;
409 inbuf = kmalloc(INBUFSIZ, GFP_KERNEL); 409 inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
410 if (inbuf == 0) { 410 if (inbuf == 0) {
411 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n"); 411 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
412 return -1; 412 return -1;
413 } 413 }
414 window = kmalloc(WSIZE, GFP_KERNEL); 414 window = kmalloc(WSIZE, GFP_KERNEL);
415 if (window == 0) { 415 if (window == 0) {
416 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n"); 416 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
417 kfree(inbuf); 417 kfree(inbuf);
418 return -1; 418 return -1;
419 } 419 }
420 makecrc(); 420 makecrc();
421 result = gunzip(); 421 result = gunzip();
422 if (unzip_error) 422 if (unzip_error)
423 result = 1; 423 result = 1;
424 kfree(inbuf); 424 kfree(inbuf);
425 kfree(window); 425 kfree(window);
426 return result; 426 return result;
427 } 427 }
428 428
429 #endif /* BUILD_CRAMDISK */ 429 #endif /* BUILD_CRAMDISK */
430 430