mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zdsfs: add online vtoc refresh
Enable zdsfs to access datasets that were created after zdsfs was mounted without the need to remount zdsfs. This is done by re-reading the VTOC with every readdir system call. To ensure a consistent VTOC state the DASD device is reserved for every VTOC read and released afterwards. Signed-off-by: Stefan Haberland <sth@linux.ibm.com> Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
e9c030f202
commit
bc053a975a
@@ -1741,7 +1741,7 @@ static void dasdview_print_vtoc_raw(dasdview_info_t *info)
|
||||
" rc=%d\n", rc);
|
||||
exit(-1);
|
||||
}
|
||||
rc = lzds_dasd_read_rawvtoc(info->dasd);
|
||||
rc = lzds_dasd_alloc_rawvtoc(info->dasd);
|
||||
if (rc == EINVAL) {
|
||||
zt_error_print("dasdview: Cannot read VTOC because disk does"
|
||||
" not contain valid VOL1 label.\n",
|
||||
|
||||
@@ -170,6 +170,10 @@ struct hd_geometry {
|
||||
#define BIODASDDISABLE _IO(DASD_IOCTL_LETTER, 0)
|
||||
/* Enable the volume (for Linux) */
|
||||
#define BIODASDENABLE _IO(DASD_IOCTL_LETTER, 1)
|
||||
/* Reserve the device for the current LPAR */
|
||||
#define BIODASDRSRV _IO(DASD_IOCTL_LETTER, 2)
|
||||
/* Release the device for the current LPAR */
|
||||
#define BIODASDRLSE _IO(DASD_IOCTL_LETTER, 3)
|
||||
/* Get information on a dasd device (enhanced) */
|
||||
#define BIODASDINFO2 _IOR(DASD_IOCTL_LETTER, 3, dasd_information2_t)
|
||||
/* #define BIODASDFORMAT _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */
|
||||
@@ -203,5 +207,7 @@ int dasd_get_geo(const char *device, struct hd_geometry *geo);
|
||||
int dasd_get_info(const char *device, dasd_information2_t *info);
|
||||
int dasd_is_ro(const char *device, bool *ro);
|
||||
int dasd_reread_partition_table(const char *device, int ntries);
|
||||
int dasd_disk_reserve(const char *device);
|
||||
int dasd_disk_release(const char *device);
|
||||
|
||||
#endif /* LIB_DASD_BASE_H */
|
||||
|
||||
@@ -112,6 +112,8 @@
|
||||
*/
|
||||
#define LIB_LIBZDS_H
|
||||
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_list.h"
|
||||
#include "vtoc.h"
|
||||
|
||||
|
||||
@@ -328,11 +330,74 @@ struct pds_member_entry {
|
||||
*/
|
||||
struct zdsroot;
|
||||
|
||||
/**
|
||||
* @struct raw_vtoc
|
||||
* @brief The VTOC is a directory of data sets on one DASD
|
||||
*
|
||||
* As the VTOC is the data area on the DASD that describes all data sets,
|
||||
* this library will often have to refer to the various records in the VTOC.
|
||||
* To make this more efficient, we will read the whole VTOC once and identify
|
||||
* all elements (DSCBs). The raw data of the VTOC tracks and the index to the
|
||||
* DSCBs is stored.
|
||||
*/
|
||||
struct raw_vtoc {
|
||||
/** @brief The raw track data */
|
||||
char *rawdata;
|
||||
/** @brief This size of the raw track data in bytes */
|
||||
unsigned long long rawdatasize;
|
||||
/** @brief An array with pointers to the various DSCBs in the rawdata */
|
||||
char **vtocindex;
|
||||
/** @brief Number of entries in the index */
|
||||
unsigned int vtocindexcount;
|
||||
/** @brief Number of records per VTOC track
|
||||
*
|
||||
* @note While the DS4DEVDT field in the format 4 DSCB names the number
|
||||
* if DSCBs per VTOC track, we count the records, which is DS4DEVDT + 1
|
||||
* for record 0.
|
||||
*/
|
||||
unsigned int vtoc_rec_per_track;
|
||||
/** @brief The track number at which the vtoc begins on the DASD */
|
||||
unsigned int vtoctrackoffset;
|
||||
/** @brief Start record of VTOC.
|
||||
*
|
||||
* The rawdata contains full tracks. This is the number of the first
|
||||
* record that actually belongs to the VTOC
|
||||
*/
|
||||
unsigned int vtocrecno;
|
||||
/** @brief The DASD this vtoc was read from */
|
||||
struct dasd *dasd;
|
||||
/** @brief Detailed error messages in case of a problem */
|
||||
struct errorlog *log;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct dasd
|
||||
* @brief Represents one physical device, may have a vtoc
|
||||
*/
|
||||
struct dasd;
|
||||
struct dasd {
|
||||
/** @brief List head used to store a list of DASDs in struct zdsroot */
|
||||
struct util_list_node list;
|
||||
/** @brief Name of the block device, e.g. /dev/dasde */
|
||||
char *device;
|
||||
/** @brief File descriptor for the block device.
|
||||
*
|
||||
* The device is kept open for as along as the library uses it.
|
||||
* This lets the system know that the device is still in use.
|
||||
*/
|
||||
int inusefd;
|
||||
/* @brief where to find the volume label */
|
||||
unsigned int label_block;
|
||||
/** @brief Device geometry. How many cylinders does the DASD have. */
|
||||
unsigned int cylinders;
|
||||
/** @brief Device geometry. How many heads does the DASD have. */
|
||||
unsigned int heads;
|
||||
/** @brief The VTOC data that has been read from this device */
|
||||
struct raw_vtoc *rawvtoc;
|
||||
/** @brief The volume label that has been read from this device */
|
||||
volume_label_t *vlabel;
|
||||
/** @brief Detailed error messages in case of a problem */
|
||||
struct errorlog *log;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct dasditerator
|
||||
@@ -350,12 +415,6 @@ struct dasditerator;
|
||||
*/
|
||||
struct dasdhandle;
|
||||
|
||||
/**
|
||||
* @struct raw_vtoc
|
||||
* @brief The VTOC is a directory of data sets on one dasd
|
||||
*/
|
||||
struct raw_vtoc;
|
||||
|
||||
/**
|
||||
* @struct dscbiterator
|
||||
* @brief allows to iterate over all DSCBs in a vtoc
|
||||
@@ -572,7 +631,13 @@ int lzds_dasd_get_vlabel(struct dasd *dasd, struct volume_label **vlabel);
|
||||
* @brief Read the vtoc data from device. The data as stored as part
|
||||
* of the struct dasd.
|
||||
*/
|
||||
int lzds_dasd_read_rawvtoc(struct dasd *dasd);
|
||||
int lzds_dasd_read_rawvtoc(struct dasd *dasd, struct raw_vtoc *vtoc);
|
||||
|
||||
/**
|
||||
* @brief Read the vtoc data from device. The data as stored as part
|
||||
* of the struct dasd.
|
||||
*/
|
||||
int lzds_dasd_alloc_rawvtoc(struct dasd *dasd);
|
||||
|
||||
/**
|
||||
* @brief Get the previously read raw_vtoc data.
|
||||
@@ -787,6 +852,8 @@ int lzds_zdsroot_extract_datasets_from_dasd(struct zdsroot *root,
|
||||
struct dasd *dasd);
|
||||
|
||||
|
||||
void lzds_dslist_free(struct zdsroot *root);
|
||||
|
||||
|
||||
/** @} */ /* end of group libzds_functions_high */
|
||||
|
||||
|
||||
@@ -261,3 +261,42 @@ int dasd_reread_partition_table(const char *device, int ntries)
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reserve DASD disk.
|
||||
*
|
||||
* @param[in] device node device node's name
|
||||
*
|
||||
* @retval 0 in case of success
|
||||
* @retval errno in case of failure
|
||||
*
|
||||
*/
|
||||
int dasd_disk_reserve(const char *device)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = dasd_open_device(device, O_RDONLY);
|
||||
RUN_IOCTL(fd, BIODASDRSRV, NULL);
|
||||
dasd_close_device(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release DASD disk
|
||||
*
|
||||
* @param[in] device node device node's name
|
||||
*
|
||||
* @retval 0 in case of success
|
||||
* @retval errno in case of failure
|
||||
*/
|
||||
int dasd_disk_release(const char *device)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = dasd_open_device(device, O_RDONLY);
|
||||
RUN_IOCTL(fd, BIODASDRLSE, NULL);
|
||||
dasd_close_device(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
184
libzds/libzds.c
184
libzds/libzds.c
@@ -22,8 +22,6 @@
|
||||
#include "lib/dasd_base.h"
|
||||
#include "lib/libzds.h"
|
||||
#include "lib/u2s.h"
|
||||
#include "lib/util_base.h"
|
||||
#include "lib/util_list.h"
|
||||
#include "lib/vtoc.h"
|
||||
|
||||
/** @cond PRIVATE */
|
||||
@@ -70,42 +68,6 @@ struct errormsg {
|
||||
char text[ERRORMSG];
|
||||
};
|
||||
|
||||
/**
|
||||
* As the VTOC is the data area on the DASD that describes all data sets,
|
||||
* this library will often have to refer to the various records in the VTOC.
|
||||
* To make this more efficiant, we will read the whole VTOC once and identify
|
||||
* all elements (DSCBs). The raw data of the VTOC tracks and the index to the
|
||||
* DSCBs is stored.
|
||||
*/
|
||||
struct raw_vtoc {
|
||||
/** @brief The raw track data */
|
||||
char *rawdata;
|
||||
/** @brief This size of the raw track data in bytes */
|
||||
unsigned long long rawdatasize;
|
||||
/** @brief An array with pointers to the various DSCBs in the rawdata */
|
||||
char **vtocindex;
|
||||
/** @brief Number of entries in the index */
|
||||
unsigned int vtocindexcount;
|
||||
/** @brief Number of records per VTOC track
|
||||
*
|
||||
* @note While the DS4DEVDT field in the format 4 DSCB names the number
|
||||
* if DSCBs per VTOC track, we count the records, which is DS4DEVDT + 1
|
||||
* for record 0.
|
||||
*/
|
||||
unsigned int vtoc_rec_per_track;
|
||||
/** @brief The track number in which the vtoc begins on the DASD */
|
||||
unsigned int vtoctrackoffset;
|
||||
/** @brief Start record of VTOC.
|
||||
*
|
||||
* The rawdata contains full tracks. This is the number of the first
|
||||
* record that actually belongs to the VTOC */
|
||||
unsigned int vtocrecno;
|
||||
/** @brief The DASD this vtoc was read from */
|
||||
struct dasd *dasd;
|
||||
/** @brief Detailed error messages in case of a problem */
|
||||
struct errorlog *log;
|
||||
};
|
||||
|
||||
struct dscbiterator {
|
||||
/** @brief The raw_vtoc this iterator refers to */
|
||||
struct raw_vtoc *rawvtoc;
|
||||
@@ -113,31 +75,6 @@ struct dscbiterator {
|
||||
unsigned int i;
|
||||
};
|
||||
|
||||
struct dasd {
|
||||
/** @brief List head used to store a list of DASDs in struct zdsroot */
|
||||
struct util_list_node list;
|
||||
/** @brief Name of the block device, e.g. /dev/dasde */
|
||||
char *device;
|
||||
/** @brief File descriptor for the block device.
|
||||
*
|
||||
* The device is kept open for as along as the library uses it.
|
||||
* This lets the system know that the device is still in use.
|
||||
*/
|
||||
int inusefd;
|
||||
/* @brief where to find the volume label */
|
||||
unsigned int label_block;
|
||||
/** @brief Device geometry. How many cylinders does the DASD have. */
|
||||
unsigned int cylinders;
|
||||
/** @brief Device geometry. How many heads does the DASD have. */
|
||||
unsigned int heads;
|
||||
/** @brief The VTOC data that has been read from this device */
|
||||
struct raw_vtoc *rawvtoc;
|
||||
/** @brief The volume label that has been read from this device */
|
||||
volume_label_t *vlabel;
|
||||
/** @brief Detailed error messages in case of a problem */
|
||||
struct errorlog *log;
|
||||
};
|
||||
|
||||
struct dasdhandle {
|
||||
/** @brief The struct dasd this context relates to */
|
||||
struct dasd *dasd;
|
||||
@@ -412,6 +349,29 @@ int lzds_zdsroot_alloc(struct zdsroot **root)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* It should be noted that this frees all structures that are owned by the
|
||||
* root structure as well. For example, a pointer to a struct dasd that
|
||||
* has been returned by lzds_zdsroot_add_device is not valid anymore.
|
||||
*
|
||||
* @param[in] root Reference to the zdsroot structure that is to be freed.
|
||||
*/
|
||||
void lzds_dslist_free(struct zdsroot *root)
|
||||
{
|
||||
struct dataset *ds, *nextds;
|
||||
int i;
|
||||
|
||||
util_list_iterate_safe(root->datasetlist, ds, nextds) {
|
||||
util_list_remove(root->datasetlist, ds);
|
||||
dataset_free_memberlist(ds);
|
||||
for (i = 0; i < MAXVOLUMESPERDS; ++i)
|
||||
free(ds->dsp[i]);
|
||||
errorlog_free(ds->log);
|
||||
free(ds);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It should be noted that this frees all structures that are owned by the
|
||||
* root structure as well. For example, a pointer to a struct dasd that
|
||||
@@ -422,8 +382,6 @@ int lzds_zdsroot_alloc(struct zdsroot **root)
|
||||
void lzds_zdsroot_free(struct zdsroot *root)
|
||||
{
|
||||
struct dasd *dasd, *nextdasd;
|
||||
struct dataset *ds, *nextds;
|
||||
int i;
|
||||
|
||||
if (!root)
|
||||
return;
|
||||
@@ -433,15 +391,7 @@ void lzds_zdsroot_free(struct zdsroot *root)
|
||||
dasd_free(dasd);
|
||||
}
|
||||
util_list_free(root->dasdlist);
|
||||
|
||||
util_list_iterate_safe(root->datasetlist, ds, nextds) {
|
||||
util_list_remove(root->datasetlist, ds);
|
||||
dataset_free_memberlist(ds);
|
||||
for (i = 0; i < MAXVOLUMESPERDS; ++i)
|
||||
free(ds->dsp[i]);
|
||||
errorlog_free(ds->log);
|
||||
free(ds);
|
||||
}
|
||||
lzds_dslist_free(root);
|
||||
util_list_free(root->datasetlist);
|
||||
errorlog_free(root->log);
|
||||
free(root);
|
||||
@@ -1443,7 +1393,7 @@ int lzds_raw_vtoc_get_dscb_from_cchhb(struct raw_vtoc *rv, cchhb_t *p,
|
||||
* - EPROTO The VTOC data is not in a valid format.
|
||||
* - EIO Other I/O error
|
||||
*/
|
||||
int lzds_dasd_read_rawvtoc(struct dasd *dasd)
|
||||
int lzds_dasd_read_rawvtoc(struct dasd *dasd, struct raw_vtoc *rawvtoc)
|
||||
{
|
||||
unsigned long long vtoctrckno, vtocrecno;
|
||||
unsigned int vtoctrack_start, vtoctrack_end, vtocindexsize;
|
||||
@@ -1455,26 +1405,11 @@ int lzds_dasd_read_rawvtoc(struct dasd *dasd)
|
||||
format4_label_t *f4;
|
||||
unsigned long long rawvtocsize;
|
||||
|
||||
struct raw_vtoc *rawvtoc = NULL;
|
||||
volume_label_t *vlabel = NULL;
|
||||
char *trackdata = NULL;
|
||||
char vol1[] = {0xe5, 0xd6, 0xd3, 0xf1, 0x00}; /* "VOL1" in EBCDIC */
|
||||
|
||||
errorlog_clear(dasd->log);
|
||||
/* cleanup the old rawvtoc structures before we read new ones */
|
||||
rawvtoc = dasd->rawvtoc;
|
||||
dasd->rawvtoc = NULL;
|
||||
if (rawvtoc) {
|
||||
free(rawvtoc->rawdata);
|
||||
free(rawvtoc->vtocindex);
|
||||
free(rawvtoc);
|
||||
}
|
||||
|
||||
rawvtoc = malloc(sizeof(*rawvtoc));
|
||||
if (!rawvtoc)
|
||||
return ENOMEM;
|
||||
memset(rawvtoc, 0, sizeof(*rawvtoc));
|
||||
rawvtoc->dasd = dasd;
|
||||
|
||||
rc = lzds_dasd_get_vlabel(dasd, &vlabel);
|
||||
if (rc) {
|
||||
@@ -1611,13 +1546,49 @@ int lzds_dasd_read_rawvtoc(struct dasd *dasd)
|
||||
++i;
|
||||
}
|
||||
|
||||
dasd->rawvtoc = rawvtoc;
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
free(rawvtoc->vtocindex);
|
||||
free(trackdata);
|
||||
free(rawvtoc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param[in] dasd The struct dasd that represents the device we want to read
|
||||
* the VTOC from.
|
||||
* @return 0 on success, otherwise one of the following error codes:
|
||||
* - ENOMEM Could not allocate internal structure due to lack of memory.
|
||||
* - EINVAL The volume label has not yet been read or it is not valid.
|
||||
* - EPROTO The VTOC data is not in a valid format.
|
||||
* - EIO Other I/O error
|
||||
*/
|
||||
int lzds_dasd_alloc_rawvtoc(struct dasd *dasd)
|
||||
{
|
||||
struct raw_vtoc *rawvtoc = NULL;
|
||||
int rc;
|
||||
|
||||
/* cleanup the old rawvtoc structures before we read new ones */
|
||||
rawvtoc = dasd->rawvtoc;
|
||||
dasd->rawvtoc = NULL;
|
||||
if (rawvtoc) {
|
||||
free(rawvtoc->rawdata);
|
||||
free(rawvtoc->vtocindex);
|
||||
free(rawvtoc);
|
||||
}
|
||||
|
||||
rawvtoc = malloc(sizeof(*rawvtoc));
|
||||
if (!rawvtoc)
|
||||
return ENOMEM;
|
||||
memset(rawvtoc, 0, sizeof(*rawvtoc));
|
||||
rawvtoc->dasd = dasd;
|
||||
|
||||
rc = lzds_dasd_read_rawvtoc(dasd, rawvtoc);
|
||||
if (rc) {
|
||||
free(rawvtoc->vtocindex);
|
||||
free(rawvtoc);
|
||||
} else {
|
||||
dasd->rawvtoc = rawvtoc;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2261,6 +2232,7 @@ out1:
|
||||
static int dataset_merge_dataset(struct dataset *baseds, struct dataset *newds)
|
||||
{
|
||||
int k, l, dspcount;
|
||||
|
||||
for (k = 0; k < MAXVOLUMESPERDS; ++k) {
|
||||
/* if both datasets have a part in position k,
|
||||
* then something is wrong */
|
||||
@@ -2280,18 +2252,20 @@ static int dataset_merge_dataset(struct dataset *baseds, struct dataset *newds)
|
||||
* Since dsp[0] may not be set yet, we loop over the
|
||||
* base dsp array until we find an entry.
|
||||
*/
|
||||
for (l = 0; l < MAXVOLUMESPERDS; ++l)
|
||||
if (baseds->dsp[l]) {
|
||||
if (memcmp(baseds->dsp[l]->f1->DS1DSSN,
|
||||
newds->dsp[k]->f1->DS1DSSN,
|
||||
MAXVOLSER))
|
||||
return errorlog_add_message(
|
||||
&baseds->log, NULL, EPROTO,
|
||||
"merge dataset: part %d has incompatible"
|
||||
" base volume serial\n", k);
|
||||
else
|
||||
break;
|
||||
}
|
||||
for (l = 0; l < MAXVOLUMESPERDS; ++l) {
|
||||
if (!baseds->dsp[l])
|
||||
continue;
|
||||
if (memcmp(baseds->dsp[l]->f1->DS1DSSN,
|
||||
newds->dsp[k]->f1->DS1DSSN,
|
||||
MAXVOLSER))
|
||||
return errorlog_add_message(
|
||||
&baseds->log, NULL, EPROTO,
|
||||
"merge dataset: part %d has incompatible base volume serial\n",
|
||||
k);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
baseds->dsp[k] = newds->dsp[k];
|
||||
baseds->dspcount++;
|
||||
|
||||
|
||||
@@ -53,6 +53,8 @@ struct zdsfs_info {
|
||||
};
|
||||
|
||||
static struct zdsfs_info zdsfsinfo;
|
||||
static int zdsfs_create_meta_data_buffer(struct zdsfs_info *);
|
||||
static int zdsfs_verify_datasets(void);
|
||||
|
||||
struct zdsfs_file_info {
|
||||
struct dshandle *dsh;
|
||||
@@ -193,6 +195,48 @@ static int zdsfs_getattr(const char *path, struct stat *stbuf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void zdsfs_read_device(struct dasd *newdasd, const char *device)
|
||||
{
|
||||
struct errorlog *log;
|
||||
int rc;
|
||||
|
||||
rc = dasd_disk_reserve(device);
|
||||
if (rc) {
|
||||
fprintf(stderr, "error when reserving device %s: %s\n",
|
||||
device, strerror(rc));
|
||||
lzds_dasd_get_errorlog(newdasd, &log);
|
||||
lzds_errorlog_fprint(log, stderr);
|
||||
exit(1);
|
||||
}
|
||||
rc = lzds_dasd_alloc_rawvtoc(newdasd);
|
||||
if (rc) {
|
||||
fprintf(stderr, "error when reading VTOC from device %s: %s\n",
|
||||
device, strerror(rc));
|
||||
lzds_dasd_get_errorlog(newdasd, &log);
|
||||
lzds_errorlog_fprint(log, stderr);
|
||||
exit(1);
|
||||
}
|
||||
rc = lzds_zdsroot_extract_datasets_from_dasd(zdsfsinfo.zdsroot,
|
||||
newdasd);
|
||||
if (rc) {
|
||||
fprintf(stderr,
|
||||
"error when extracting data sets from dasd %s: %s\n",
|
||||
device, strerror(rc));
|
||||
lzds_zdsroot_get_errorlog(zdsfsinfo.zdsroot, &log);
|
||||
lzds_errorlog_fprint(log, stderr);
|
||||
exit(1);
|
||||
}
|
||||
rc = dasd_disk_release(device);
|
||||
if (rc) {
|
||||
fprintf(stderr, "error when releasing device %s: %s\n",
|
||||
device, strerror(rc));
|
||||
lzds_dasd_get_errorlog(newdasd, &log);
|
||||
lzds_errorlog_fprint(log, stderr);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int zdsfs_statfs(const char *UNUSED(path), struct statvfs *statvfs)
|
||||
{
|
||||
struct dasditerator *dasdit;
|
||||
@@ -239,6 +283,33 @@ static int zdsfs_statfs(const char *UNUSED(path), struct statvfs *statvfs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int zdsfs_update_vtoc(void)
|
||||
{
|
||||
struct dasditerator *dasdit;
|
||||
struct dasd *dasd;
|
||||
int rc;
|
||||
|
||||
lzds_dslist_free(zdsfsinfo.zdsroot);
|
||||
rc = lzds_zdsroot_alloc_dasditerator(zdsfsinfo.zdsroot, &dasdit);
|
||||
if (rc)
|
||||
return -ENOMEM;
|
||||
|
||||
while (!lzds_dasditerator_get_next_dasd(dasdit, &dasd))
|
||||
zdsfs_read_device(dasd, dasd->device);
|
||||
|
||||
lzds_dasditerator_free(dasdit);
|
||||
rc = zdsfs_verify_datasets();
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = zdsfs_create_meta_data_buffer(&zdsfsinfo);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zdsfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
||||
off_t UNUSED(offset), struct fuse_file_info *UNUSED(fi))
|
||||
{
|
||||
@@ -252,6 +323,10 @@ static int zdsfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
||||
int rc;
|
||||
int ispds, issupported;
|
||||
|
||||
rc = zdsfs_update_vtoc();
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* we have two type of directories
|
||||
* type one: the root directory contains all data sets
|
||||
*/
|
||||
@@ -328,6 +403,9 @@ static int zdsfs_open(const char *path, struct fuse_file_info *fi)
|
||||
goto error1;
|
||||
|
||||
if (strcmp(path, "/"METADATAFILE) == 0) {
|
||||
rc = zdsfs_update_vtoc();
|
||||
if (rc)
|
||||
return rc;
|
||||
zfi->dsh = NULL;
|
||||
zfi->is_metadata_file = 1;
|
||||
zfi->metaread = 0;
|
||||
@@ -595,6 +673,7 @@ static int zdsfs_verify_datasets(void)
|
||||
if (rc)
|
||||
return ENOMEM;
|
||||
while (!lzds_dsiterator_get_next_dataset(dsit, &ds)) {
|
||||
lzds_dataset_get_name(ds, &dsname);
|
||||
lzds_dataset_get_is_complete(ds, &iscomplete);
|
||||
if (!iscomplete) {
|
||||
lzds_dataset_get_name(ds, &dsname);
|
||||
@@ -821,23 +900,7 @@ static void zdsfs_process_device(const char *device)
|
||||
lzds_errorlog_fprint(log, stderr);
|
||||
exit(1);
|
||||
}
|
||||
rc = lzds_dasd_read_rawvtoc(newdasd);
|
||||
if (rc) {
|
||||
fprintf(stderr, "error when reading VTOC from device %s:"
|
||||
" %s\n", device, strerror(rc));
|
||||
lzds_dasd_get_errorlog(newdasd, &log);
|
||||
lzds_errorlog_fprint(log, stderr);
|
||||
exit(1);
|
||||
}
|
||||
rc = lzds_zdsroot_extract_datasets_from_dasd(zdsfsinfo.zdsroot,
|
||||
newdasd);
|
||||
if (rc) {
|
||||
fprintf(stderr, "error when extracting data sets from dasd %s:"
|
||||
" %s\n", device, strerror(rc));
|
||||
lzds_zdsroot_get_errorlog(zdsfsinfo.zdsroot, &log);
|
||||
lzds_errorlog_fprint(log, stderr);
|
||||
exit(1);
|
||||
}
|
||||
zdsfs_read_device(newdasd, device);
|
||||
}
|
||||
|
||||
static void zdsfs_process_device_file(const char *devfile)
|
||||
|
||||
Reference in New Issue
Block a user