diff options
Diffstat (limited to 'libdiskfs')
-rw-r--r-- | libdiskfs/filedev.c | 80 |
1 files changed, 41 insertions, 39 deletions
diff --git a/libdiskfs/filedev.c b/libdiskfs/filedev.c index ab600e8c..e0ae7f4c 100644 --- a/libdiskfs/filedev.c +++ b/libdiskfs/filedev.c @@ -45,7 +45,7 @@ diskfs_get_file_device (char *name, int _ints[num_ints], *ints = _ints; mach_port_t _ports[num_ports], *ports = _ports; off_t _offsets[num_offsets], *offsets = _offsets; - char *_data[data_len], **data = _data; + char _data[data_len], *data = _data; file_t node = file_name_lookup (name, diskfs_readonly ? O_RDONLY : O_RDWR, 0); @@ -67,15 +67,24 @@ diskfs_get_file_device (char *name, else if (ints[0] != STORAGE_DEVICE) err = ENODEV; - if (!err && blocksize) + if (!err && block_size) *block_size = ints[2]; - if (!err && port) - /* Extract the device port. */ - if (num_ports != 1) - err = EGRATUITOUS; - else - *port = ports[0]; + if (!err && (start || size)) + /* Extract the device block addresses. */ + { + size_t runs_len = ints[3]; + if (runs_len != 2) + /* We can't handle anything but a contiguous set of blocks. */ + err = ENODEV; /* XXX */ + else + { + if (start) + *start = offsets[0]; + if (size) + *size = offsets[1]; + } + } if (!err && dev_name) /* Extract the device name into DEV_NAME. */ @@ -88,47 +97,40 @@ diskfs_get_file_device (char *name, { *dev_name = malloc (name_len); if (*dev_name) - strcpy (*dev_name, dev_name_buf); + strcpy (*dev_name, data); else err = ENOMEM; } } - if (!err && (start || size)) - /* Extract the device block addresses. */ - { - size_t runs_len = ints[3]; - if (runs_len != 2) - /* We can't handle anything but a contiguous set of blocks. */ - err = ENODEV; /* XXX */ - else - { - if (start) - *start = offsets[0]; - if (size) - *size = offsets[1]; - } - } + if (!err && port) + /* Extract the device port. */ + if (num_ports != 1) + err = EGRATUITOUS; + else + *port = ports[0]; + + /* Deallocate things we don't care about or that we've made copies of. */ + + for (i = 0; i < num_ports; i++) + if (MACH_PORT_VALID (ports[i])) + mach_port_deallocate (mach_task_self (), ports[i]); + +#define DISCARD_MEM(v, vl, b) \ + if (v != b) \ + vm_deallocate (mach_task_self (), (vm_address_t)v, vl * sizeof *v); + DISCARD_MEM (ports, num_ports, _ports); + DISCARD_MEM (ints, num_ints, _ints); + DISCARD_MEM (offsets, num_offsets, _offsets); + DISCARD_MEM (data, data_len, _data); /* Note that we don't deallocate NODE unless we're returning an error, which should prevent the information returned by file_get_storage_info from changing. */ - + if (err) - /* We got an error, so deallocate everything we got back from the device. */ - { - for (i = 0; i < num_ports; i++) - if (MACH_PORT_VALID (ports[i])) - mach_port_deallocate (mach_task_self (), ports[i]); -#define DISCARD_MEM(v, vl, b) \ - if (v != b) \ - vm_deallocate (mach_task_self (), (vm_address_t)v, vl * sizeof *v); - DISCARD_MEM (ports, num_ports, _ports); - DISCARD_MEM (ints, num_ints, _ints); - DISCARD_MEM (offsets, num_offsets, _offsets); - DISCARD_MEM (data, data_len, _data); - mach_port_deallocate (mach_task_self (), node); - } + /* We got an error, deallocate everything. */ + mach_port_deallocate (mach_task_self (), node); return err; } |