error_t trivfs_goaway (struct trivfs_control *fsys, int flags) { struct dev *const device = fsys->hook; error_t err; int force = (flags & FSYS_GOAWAY_FORCE); int nosync = (flags & FSYS_GOAWAY_NOSYNC); struct port_class *root_port_class = fsys->protid_class; mutex_lock (&device->lock); if (device->store == NULL) /* The device is not actually open. XXX note that exitting here nukes non-io users, like someone in the middle of a stat who will get SIGLOST or something. */ exit (0); /* Wait until all pending rpcs are done. */ err = ports_inhibit_class_rpcs (root_port_class); if (err == EINTR || (err && !force)) { mutex_unlock (&device->lock); return err; } if (force && nosync) /* Exit with extreme prejudice. */ exit (0); if (!force && ports_count_class (root_port_class) > 0) /* Still users, so don't exit. */ goto busy; if (! nosync) /* Sync the device here, if necessary, so that closing it won't result in any I/O (which could get hung up trying to use one of our pagers). */ dev_sync (device, 1); /* devpager_shutdown may sync the pagers as side-effect (if NOSYNC is 0), so we put that first in this test. */ if (dev_stop_paging (device, nosync) || force) /* Bye-bye. */ { if (! nosync) /* If NOSYNC is true, we don't close DEV, as that could cause data to be written back. */ dev_close (device); exit (0); } busy: /* Allow normal operations to proceed. */ ports_enable_class (root_port_class); ports_resume_class_rpcs (root_port_class); mutex_unlock (&device->lock); /* Complain that there are still users. */ return EBUSY; }
error_t trivfs_S_file_syncfs (struct trivfs_protid *cred, mach_port_t reply, mach_msg_type_name_t reply_type, int wait, int dochildren) { if (cred) return dev_sync (((struct open *)cred->po->hook)->dev, wait); else return EOPNOTSUPP; }
/* Sync this filesystem. */ kern_return_t trivfs_S_fsys_syncfs (struct trivfs_control *cntl, mach_port_t reply, mach_msg_type_name_t replytype, int wait, int dochildren) { struct dev *dev = cntl->hook; if (dev) return dev_sync (dev, wait); else return 0; }
/* Directly extract the configuration from the NVRAM device */ static ssize_t c3725_nvram_extract_config(vm_instance_t *vm,u_char **buffer) { u_char *base_ptr,*ios_ptr,*cfg_ptr,*end_ptr; m_uint32_t start,nvlen; m_uint16_t magic1,magic2; struct vdevice *nvram_dev; off_t nvram_size; int fd; if ((nvram_dev = dev_get_by_name(vm,"rom"))) dev_sync(nvram_dev); fd = vm_mmap_open_file(vm,"rom",&base_ptr,&nvram_size); if (fd == -1) return(-1); ios_ptr = base_ptr + C3725_NVRAM_OFFSET; end_ptr = base_ptr + nvram_size; if ((ios_ptr + 0x30) >= end_ptr) { vm_error(vm,"NVRAM file too small\n"); return(-1); } magic1 = ntohs(*PTR_ADJUST(m_uint16_t *,ios_ptr,0x06)); magic2 = ntohs(*PTR_ADJUST(m_uint16_t *,ios_ptr,0x08)); if ((magic1 != 0xF0A5) || (magic2 != 0xABCD)) { vm_error(vm,"unable to find IOS magic numbers (0x%x,0x%x)!\n", magic1,magic2); return(-1); } start = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x10)) + 1; nvlen = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x18)); if (!(*buffer = malloc(nvlen+1))) { vm_error(vm,"unable to allocate config buffer (%u bytes)\n",nvlen); return(-1); } cfg_ptr = ios_ptr + start + 0x08; if ((cfg_ptr + nvlen) > end_ptr) { vm_error(vm,"NVRAM file too small\n"); return(-1); } memcpy(*buffer,cfg_ptr,nvlen-1); (*buffer)[nvlen-1] = 0; return(nvlen-1); }