223 |
if (np->dn->translator) |
if (np->dn->translator) |
224 |
free (np->dn->translator); |
free (np->dn->translator); |
225 |
|
|
226 |
|
/* It is safe to unlock diskfs_node_refcnt_lock here for a while because |
227 |
|
all references to the node have been deleted. */ |
228 |
|
if (np->dn->dirnode) |
229 |
|
{ |
230 |
|
spin_unlock (&diskfs_node_refcnt_lock); |
231 |
|
diskfs_nrele (np->dn->dirnode); |
232 |
|
spin_lock (&diskfs_node_refcnt_lock); |
233 |
|
} |
234 |
|
|
235 |
assert (!np->dn->pager); |
assert (!np->dn->pager); |
236 |
|
|
237 |
free (np->dn); |
free (np->dn); |
264 |
static error_t |
static error_t |
265 |
read_node (struct node *np, vm_address_t buf) |
read_node (struct node *np, vm_address_t buf) |
266 |
{ |
{ |
267 |
/* XXX This needs careful investigation */ |
/* XXX This needs careful investigation. */ |
268 |
error_t err; |
error_t err; |
269 |
struct stat *st = &np->dn_stat; |
struct stat *st = &np->dn_stat; |
270 |
struct disknode *dn = np->dn; |
struct disknode *dn = np->dn; |
276 |
vm_size_t buflen = 0; |
vm_size_t buflen = 0; |
277 |
int our_buf = 0; |
int our_buf = 0; |
278 |
|
|
279 |
|
st->st_fstype = FSTYPE_MSLOSS; |
280 |
|
st->st_fsid = getpid (); |
281 |
|
st->st_ino = np->cache_id; |
282 |
|
st->st_gen = 0; |
283 |
|
st->st_rdev = 0; |
284 |
|
|
285 |
|
st->st_nlink = 1; |
286 |
|
st->st_uid = fs_uid; |
287 |
|
st->st_gid = fs_gid; |
288 |
|
|
289 |
|
st->st_rdev = 0; |
290 |
|
|
291 |
|
np->dn->translator = 0; |
292 |
|
np->dn->translen = 0; |
293 |
|
|
294 |
|
st->st_flags = 0; |
295 |
|
|
296 |
|
/* FIXME: If we are called through diskfs_alloc_node for a newly |
297 |
|
allocated node that has no directory entry yet, only set a |
298 |
|
minimal amount of data until the dirent is created (and we get |
299 |
|
called a second time?). */ |
300 |
|
if (vk.dir_inode == 0 && vk.dir_offset == (void *) 2) |
301 |
|
return 0; |
302 |
|
|
303 |
if (vk.dir_inode == 0) |
if (vk.dir_inode == 0) |
304 |
dr = &dr_root_node; |
dr = &dr_root_node; |
305 |
else |
else |
310 |
by libdiskfs. The only case it is not locked is for NFS |
by libdiskfs. The only case it is not locked is for NFS |
311 |
(fsys_getfile) and we disabled that. */ |
(fsys_getfile) and we disabled that. */ |
312 |
dp = ifind (vk.dir_inode); |
dp = ifind (vk.dir_inode); |
313 |
|
assert (dp); |
314 |
|
|
315 |
/* Map in the directory contents. */ |
/* Map in the directory contents. */ |
316 |
memobj = diskfs_get_filemap (dp, prot); |
memobj = diskfs_get_filemap (dp, prot); |
328 |
dr = (struct dirrect *) (buf + vk.dir_offset); |
dr = (struct dirrect *) (buf + vk.dir_offset); |
329 |
} |
} |
330 |
|
|
331 |
st->st_fstype = FSTYPE_MSLOSS; |
/* Files in fatfs depend on the directory that hold the file. */ |
332 |
st->st_fsid = getpid (); |
np->dn->dirnode = dp; |
333 |
st->st_ino = np->cache_id; |
if (dp) |
334 |
st->st_gen = 0; |
dp->references++; |
|
st->st_rdev = 0; |
|
|
|
|
|
st->st_nlink = 1; |
|
|
st->st_uid = fs_uid; |
|
|
st->st_gid = fs_gid; |
|
|
|
|
|
st->st_rdev = 0; |
|
|
|
|
|
np->dn->translator = 0; |
|
|
np->dn->translen = 0; |
|
|
|
|
|
st->st_flags = 0; |
|
|
|
|
|
/* If we are called for a newly allocated node that has no directory |
|
|
entry yet, only set a minimal amount of data until the dirent is |
|
|
created (and we get called a second time?). */ |
|
|
/* We will avoid this by overriding the relevant functions. |
|
|
if (dr == (void *)1) |
|
|
return 0; |
|
|
*/ |
|
335 |
|
|
336 |
rwlock_reader_lock(&np->dn->dirent_lock); |
rwlock_reader_lock(&np->dn->dirent_lock); |
337 |
|
|
478 |
{ |
{ |
479 |
assert (!diskfs_readonly); |
assert (!diskfs_readonly); |
480 |
|
|
481 |
err = diskfs_cached_lookup (vk.dir_inode, &dp); |
dp = np->dn->dirnode; |
482 |
if (err) |
assert (dp); |
483 |
return; |
|
484 |
|
mutex_lock (&dp->lock); |
485 |
|
|
486 |
/* Map in the directory contents. */ |
/* Map in the directory contents. */ |
487 |
memobj = diskfs_get_filemap (dp, prot); |
memobj = diskfs_get_filemap (dp, prot); |
488 |
|
|
489 |
if (memobj == MACH_PORT_NULL) |
if (memobj == MACH_PORT_NULL) |
490 |
return; |
{ |
491 |
|
mutex_unlock (&dp->lock); |
492 |
|
/* FIXME: We shouldn't ignore this error. */ |
493 |
|
return; |
494 |
|
} |
495 |
|
|
496 |
buflen = round_page (dp->dn_stat.st_size); |
buflen = round_page (dp->dn_stat.st_size); |
497 |
err = vm_map (mach_task_self (), |
err = vm_map (mach_task_self (), |
506 |
|
|
507 |
write_dword (dr->file_size, st->st_size); |
write_dword (dr->file_size, st->st_size); |
508 |
|
|
509 |
/* Write time. */ |
/* Write time. */ |
510 |
fat_from_epoch ((unsigned char *) &dr->write_date, |
fat_from_epoch ((unsigned char *) &dr->write_date, |
511 |
(unsigned char *) &dr->write_time, &st->st_mtime); |
(unsigned char *) &dr->write_time, &st->st_mtime); |
512 |
|
|
514 |
np->dn_stat_dirty = 0; |
np->dn_stat_dirty = 0; |
515 |
|
|
516 |
munmap ((caddr_t) buf, buflen); |
munmap ((caddr_t) buf, buflen); |
517 |
diskfs_nput (dp); |
mutex_unlock (&dp->lock); |
518 |
} |
} |
519 |
} |
} |
520 |
|
|
764 |
|
|
765 |
assert (!diskfs_readonly); |
assert (!diskfs_readonly); |
766 |
|
|
767 |
err = vi_new((struct vi_key) {0,1} /* XXX not allocated yet */, &inum, &inode); |
/* FIXME: We use a magic key here that signals read_node that we are |
768 |
|
not entered in any directory yet. */ |
769 |
|
err = vi_new((struct vi_key) {0,2}, &inum, &inode); |
770 |
if (err) |
if (err) |
771 |
return err; |
return err; |
772 |
|
|
774 |
if (err) |
if (err) |
775 |
return err; |
return err; |
776 |
|
|
777 |
|
/* FIXME: We know that readnode couldn't put this in. */ |
778 |
|
np->dn->dirnode = dir; |
779 |
|
dir->references++; |
780 |
|
|
781 |
*node = np; |
*node = np; |
782 |
return 0; |
return 0; |
783 |
} |
} |