1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
/* Get mach device info
Copyright (C) 1995 Free Software Foundation, Inc.
Written by Miles Bader <miles@gnu.ai.mit.edu>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <device/device.h>
#include "priv.h"
/* Returns a send right to for the mach device called NAME, and returns it in
PORT. Other values returned are START, the first valid offset, SIZE, the
the number of blocks after START, and BLOCK_SIZE, the units in which the
device is addressed.
The device is opened for reading, and if the diskfs global variable
DISKFS_READ_ONLY is false, writing.
If NAME cannot be opened and this is a bootstrap filename, the user will
be prompted for new names until a valid one is found. */
error_t
diskfs_get_mach_device (char *name,
mach_port_t *port,
off_t *start, off_t *size, size_t *block_size)
{
error_t err = 0;
do
{
mach_port_t dev_master;
err = get_privileged_ports (0, &dev_master);
if (err)
return err;
err = device_open (dev_master,
(diskfs_readonly ? 0 : D_WRITE) | D_READ,
name, port);
if (err == D_NO_SUCH_DEVICE && diskfs_boot_flags)
/* If this is a bootstrap filesystem, prompt the user to give us
another name rather than just crashing. */
{
char *line = 0;
size_t linesz = 0;
ssize_t len;
printf ("Cannot open device %s\n", name);
printf ("Open instead: ");
fflush (stdout);
len = getline (&line, &linesz, stdin);
if (len > 2)
name = line;
}
mach_port_deallocate (mach_task_self (), dev_master);
}
while (err == D_NO_SUCH_DEVICE && diskfs_boot_flags);
if (!err)
{
unsigned sizes_len = DEV_GET_SIZE_COUNT;
size_t sizes[DEV_GET_SIZE_COUNT];
err = device_get_status (*port, DEV_GET_SIZE, sizes, &sizes_len);
assert (sizes_len == DEV_GET_SIZE_COUNT);
*start = 0;
*size = sizes[DEV_GET_SIZE_DEVICE_SIZE];
*block_size = sizes[DEV_GET_SIZE_RECORD_SIZE];
if (*block_size > 1)
*size /= *block_size;
}
return err;
}
|