50 |
mach_port_t default_pager; |
mach_port_t default_pager; |
51 |
|
|
52 |
off_t tmpfs_page_limit, tmpfs_space_used; |
off_t tmpfs_page_limit, tmpfs_space_used; |
53 |
|
mode_t tmpfs_root_mode = -1; |
54 |
|
|
55 |
error_t |
error_t |
56 |
diskfs_set_statfs (struct statfs *st) |
diskfs_set_statfs (struct statfs *st) |
96 |
|
|
97 |
int diskfs_synchronous = 0; |
int diskfs_synchronous = 0; |
98 |
|
|
99 |
|
static const struct argp_option options[] = |
100 |
|
{ |
101 |
|
{"mode", 'm', "MODE", 0, "Permissions (octal) for root directory"}, |
102 |
|
{NULL,} |
103 |
|
}; |
104 |
|
|
105 |
|
struct option_values |
106 |
|
{ |
107 |
|
off_t size; |
108 |
|
mode_t mode; |
109 |
|
}; |
110 |
|
|
111 |
/* Parse a command line option. */ |
/* Parse a command line option. */ |
112 |
static error_t |
static error_t |
114 |
{ |
{ |
115 |
/* We save our parsed values in this structure, hung off STATE->hook. |
/* We save our parsed values in this structure, hung off STATE->hook. |
116 |
Only after parsing all options successfully will we use these values. */ |
Only after parsing all options successfully will we use these values. */ |
117 |
struct |
struct option_values *values = state->hook; |
|
{ |
|
|
off_t size; |
|
|
} *values = state->hook; |
|
118 |
|
|
119 |
switch (key) |
switch (key) |
120 |
{ |
{ |
124 |
if (values == 0) |
if (values == 0) |
125 |
return ENOMEM; |
return ENOMEM; |
126 |
state->hook = values; |
state->hook = values; |
127 |
bzero (values, sizeof *values); |
values->size = 0; |
128 |
|
values->mode = -1; |
129 |
|
break; |
130 |
|
case ARGP_KEY_FINI: |
131 |
|
free (values); |
132 |
|
state->hook = 0; |
133 |
|
break; |
134 |
|
|
135 |
|
case 'm': /* --mode=OCTAL */ |
136 |
|
{ |
137 |
|
char *end = NULL; |
138 |
|
mode_t mode = strtoul (state->argv[state->next], &end, 8); |
139 |
|
if (end == NULL || end == arg) |
140 |
|
{ |
141 |
|
argp_error (state, "argument must be an octal number"); |
142 |
|
return EINVAL; |
143 |
|
} |
144 |
|
if (mode & S_IFMT) |
145 |
|
{ |
146 |
|
argp_error (state, "invalid bits in mode"); |
147 |
|
return EINVAL; |
148 |
|
} |
149 |
|
values->mode = mode; |
150 |
|
} |
151 |
break; |
break; |
152 |
|
|
153 |
case ARGP_KEY_NO_ARGS: |
case ARGP_KEY_NO_ARGS: |
200 |
case ARGP_KEY_SUCCESS: |
case ARGP_KEY_SUCCESS: |
201 |
/* All options parse successfully, so implement ours if possible. */ |
/* All options parse successfully, so implement ours if possible. */ |
202 |
tmpfs_page_limit = values->size / vm_page_size; |
tmpfs_page_limit = values->size / vm_page_size; |
203 |
|
tmpfs_root_mode = values->mode; |
204 |
break; |
break; |
205 |
|
|
206 |
default: |
default: |
294 |
set properly, it is safe to export our fsys control port to the |
set properly, it is safe to export our fsys control port to the |
295 |
outside world. */ |
outside world. */ |
296 |
realnode = diskfs_startup_diskfs (bootstrap, 0); |
realnode = diskfs_startup_diskfs (bootstrap, 0); |
297 |
|
diskfs_root_node->dn_stat.st_mode = S_IFDIR; |
298 |
|
|
299 |
/* Propagate permissions, owner, etc. from underlying node to |
/* Propagate permissions, owner, etc. from underlying node to |
300 |
the root directory of the new (empty) filesystem. */ |
the root directory of the new (empty) filesystem. */ |
302 |
if (err) |
if (err) |
303 |
{ |
{ |
304 |
error (0, err, "cannot stat underlying node"); |
error (0, err, "cannot stat underlying node"); |
305 |
diskfs_root_node->dn_stat.st_mode = S_IFDIR | 0777 | S_ISVTX; |
if (tmpfs_root_mode == -1) |
306 |
|
diskfs_root_node->dn_stat.st_mode |= 0777 | S_ISVTX; |
307 |
|
else |
308 |
|
diskfs_root_node->dn_stat.st_mode |= tmpfs_root_mode; |
309 |
diskfs_root_node->dn_set_ctime = 1; |
diskfs_root_node->dn_set_ctime = 1; |
310 |
diskfs_root_node->dn_set_mtime = 1; |
diskfs_root_node->dn_set_mtime = 1; |
311 |
diskfs_root_node->dn_set_atime = 1; |
diskfs_root_node->dn_set_atime = 1; |
312 |
} |
} |
313 |
else |
else |
314 |
{ |
{ |
315 |
diskfs_root_node->dn_stat.st_mode = S_IFDIR | (st.st_mode &~ S_IFMT); |
if (tmpfs_root_mode == -1) |
316 |
if (S_ISREG(st.st_mode) && (st.st_mode & 0111) == 0) |
{ |
317 |
/* There are no execute bits set, as by default on a plain file. |
diskfs_root_node->dn_stat.st_mode |= st.st_mode &~ S_IFMT; |
318 |
For the virtual directory, set execute bits where read bits are |
if (S_ISREG (st.st_mode) && (st.st_mode & 0111) == 0) |
319 |
set on the underlying plain file. */ |
/* There are no execute bits set, as by default on a plain file. |
320 |
diskfs_root_node->dn_stat.st_mode |= (st.st_mode & 0444) >> 2; |
For the virtual directory, set execute bits where read bits are |
321 |
|
set on the underlying plain file. */ |
322 |
|
diskfs_root_node->dn_stat.st_mode |= (st.st_mode & 0444) >> 2; |
323 |
|
} |
324 |
|
else |
325 |
|
diskfs_root_node->dn_stat.st_mode |= tmpfs_root_mode; |
326 |
diskfs_root_node->dn_stat.st_uid = st.st_uid; |
diskfs_root_node->dn_stat.st_uid = st.st_uid; |
327 |
diskfs_root_node->dn_stat.st_author = st.st_author; |
diskfs_root_node->dn_stat.st_author = st.st_author; |
328 |
diskfs_root_node->dn_stat.st_gid = st.st_gid; |
diskfs_root_node->dn_stat.st_gid = st.st_gid; |