Add ntfs_volume_alloc() for low level utilities.

2003/06/03 10:35:17+01:00 cantab.net!aia21
Cleanup and do not destroy the ntfs device structure when unmounting a volume.

(Logical change 1.139)
edge.strict_endians
cantab.net!aia21 2003-06-03 11:07:54 +00:00
parent ed8e3db271
commit 137b10dca8
1 changed files with 70 additions and 24 deletions

View File

@ -38,14 +38,28 @@
#include "runlist.h"
/**
* Internal:
*
* __ntfs_volume_allocate -
* ntfs_volume_alloc -
*
*/
static ntfs_volume *__ntfs_volume_allocate(void)
ntfs_volume *ntfs_volume_alloc(void)
{
return (ntfs_volume*)calloc(1, sizeof(ntfs_volume));
ntfs_volume *vol;
vol = (ntfs_volume*)calloc(1, sizeof(ntfs_volume));
if (vol) {
vol->dev = NULL;
vol->vol_name = NULL;
vol->lcnbmp_ni = NULL;
vol->lcnbmp_na = NULL;
vol->mft_ni = NULL;
vol->mft_na = NULL;
vol->mftbmp_na = NULL;
vol->mftmirr_ni = NULL;
vol->mftmirr_na = NULL;
vol->upcase = NULL;
vol->attrdef = NULL;
}
return vol;
}
/**
@ -385,7 +399,7 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev, unsigned long rwflag)
const char *OK = "OK";
const char *FAILED = "FAILED";
ntfs_volume *vol;
NTFS_BOOT_SECTOR *bs = NULL;
NTFS_BOOT_SECTOR *bs;
int eo;
#ifdef DEBUG
BOOL debug = 1;
@ -398,23 +412,23 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev, unsigned long rwflag)
return NULL;
}
/* Allocate the volume structure. */
vol = __ntfs_volume_allocate();
if (!vol)
return NULL;
/* Attach the device to the volume. */
vol->dev = dev;
if (rwflag & MS_RDONLY)
NVolSetReadOnly(vol);
/* Allocate the boot sector structure. */
if (!(bs = (NTFS_BOOT_SECTOR *)malloc(sizeof(NTFS_BOOT_SECTOR))))
return NULL;
/* Allocate the volume structure. */
vol = ntfs_volume_alloc();
if (!vol)
goto error_exit;
if (rwflag & MS_RDONLY)
NVolSetReadOnly(vol);
Dprintf("Reading bootsector... ");
if (dev->d_ops->open(dev, NVolReadOnly(vol) ? O_RDONLY: O_RDWR)) {
Dputs(FAILED);
Dperror("Error opening partition device");
goto error_exit;
}
/* Attach the device to the volume. */
vol->dev = dev;
/* Now read the bootsector. */
br = ntfs_pread(dev, 0, sizeof(NTFS_BOOT_SECTOR), bs);
if (br != sizeof(NTFS_BOOT_SECTOR)) {
@ -538,8 +552,7 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev, unsigned long rwflag)
return vol;
error_exit:
eo = errno;
if (bs)
free(bs);
free(bs);
if (vol)
__ntfs_volume_release(vol);
errno = eo;
@ -896,15 +909,11 @@ error_exit:
free(m);
if (m2)
free(m2);
if (vol)
__ntfs_volume_release(vol);
__ntfs_volume_release(vol);
errno = eo;
return NULL;
}
/* External declaration for internal structure. */
extern struct ntfs_device_operations ntfs_device_disk_io_ops;
/**
* ntfs_mount - open ntfs volume
* @name: name of device/file to open
@ -938,19 +947,52 @@ ntfs_volume *ntfs_mount(const char *name, unsigned long rwflag)
dev = ntfs_device_alloc(name, 0, &ntfs_device_disk_io_ops, NULL);
if (!dev)
return NULL;
/* Call ntfs_device_mount() to do the actual mount. */
return ntfs_device_mount(dev, rwflag);
}
/**
* ntfs_device_umount - close ntfs volume
* @vol: address of ntfs_volume structure of volume to close
* @force: if true force close the volume even if it is busy
*
* Deallocate all structures (including @vol itself) associated with the ntfs
* volume @vol.
*
* Note it is up to the caller to destroy the device associated with the volume
* being unmounted after this function returns.
*
* Return 0 on success. On error return -1 with errno set appropriately
* (most likely to one of EAGAIN, EBUSY or EINVAL). The EAGAIN error means that
* an operation is in progress and if you try the close later the operation
* might be completed and the close succeed.
*
* If @force is true (i.e. not zero) this function will close the volume even
* if this means that data might be lost.
*
* @vol must have previously been returned by a call to ntfs_device_mount().
*
* @vol itself is deallocated and should no longer be dereferenced after this
* function returns success. If it returns an error then nothing has been done
* so it is safe to continue using @vol.
*/
int ntfs_device_umount(ntfs_volume *vol, const BOOL force)
{
if (!vol) {
errno = EINVAL;
return -1;
}
__ntfs_volume_release(vol);
return 0;
}
/**
* ntfs_umount - close ntfs volume
* @vol: address of ntfs_volume structure of volume to close
* @force: if true force close the volume even if it is busy
*
* Deallocate all structures (including @vol itself) associated with the ntfs
* volume @vol. Can be used on volumes mounted with ntfs_mount() as well as
* with volumes mounted with ntfs_device_mount().
* volume @vol.
*
* Return 0 on success. On error return -1 with errno set appropriately
* (most likely to one of EAGAIN, EBUSY or EINVAL). The EAGAIN error means that
@ -968,11 +1010,15 @@ ntfs_volume *ntfs_mount(const char *name, unsigned long rwflag)
*/
int ntfs_umount(ntfs_volume *vol, const BOOL force)
{
struct ntfs_device *dev;
if (!vol) {
errno = EINVAL;
return -1;
}
dev = vol->dev;
__ntfs_volume_release(vol);
ntfs_device_free(dev);
return 0;
}