ZDSFS: Difference between revisions
[unchecked revision] | [unchecked revision] |
mNo edit summary |
m (Bot: Replace deprecated source tag with syntaxhighlight) |
||
(2 intermediate revisions by 2 users not shown) | |||
Line 8: | Line 8: | ||
To find the sequence of format 1 entries the OS has to read 0, 0, 3. Place the first 20 bytes into a buffer then obtain the location of the format 1 DSCBs: |
To find the sequence of format 1 entries the OS has to read 0, 0, 3. Place the first 20 bytes into a buffer then obtain the location of the format 1 DSCBs: |
||
< |
<syntaxhighlight lang="c"> |
||
void GetCHRFromVTOC(void *buffer) { |
void GetCHRFromVTOC(void *buffer) { |
||
uint16_t cyl, head; |
uint16_t cyl, head; |
||
Line 18: | Line 18: | ||
return; |
return; |
||
} |
} |
||
</syntaxhighlight> |
|||
</source> |
|||
== Format 1 DSCB == |
== Format 1 DSCB == |
||
Line 69: | Line 69: | ||
The entries are ordered in a chain-like structure, where a formatId=0 entry denotes the end of said chain. |
The entries are ordered in a chain-like structure, where a formatId=0 entry denotes the end of said chain. |
||
< |
<syntaxhighlight lang="c"> |
||
// NOTE: This code assumes EBCDIC is being used |
// NOTE: This code assumes EBCDIC is being used |
||
void CheckDSCB(struct DSCB1 *dscb, const char *name) { |
void CheckDSCB(struct DSCB1 *dscb, const char *name) { |
||
Line 90: | Line 90: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</source> |
|||
Finding the files is just a matter of reading records until reaching the end of the head, then incrementing heads and after reading the last head in the cylinder, incrementing cylinders. This also has to be done for reading files. |
Finding the files is just a matter of reading records until reaching the end of the head, then incrementing heads and after reading the last head in the cylinder, incrementing cylinders. This also has to be done for reading files. |
||
This is mostly specific to DASD devices but it's provided for clarity. |
This is mostly specific to DASD devices but it's provided for clarity. |
||
< |
<syntaxhighlight lang="c"> |
||
// NOTE: This code assumes EBCDIC is being used |
// NOTE: This code assumes EBCDIC is being used |
||
void FindFile(const char *name) { |
void FindFile(const char *name) { |
||
Line 127: | Line 127: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</source> |
|||
== See also == |
== See also == |
||
Line 137: | Line 137: | ||
[[Category:S390]] |
[[Category:S390]] |
||
[[Category:Filesystems]] |
Latest revision as of 05:49, 9 June 2024
Filesystems |
---|
Virtual Filesystems |
Disk Filesystems |
CD/DVD Filesystems |
Network Filesystems |
Flash Filesystems |
ZDSFS is the normal filesystem used on virtually all DASD disks.
VTOC
The filesystem uses DSCBs to hold the information of all files in the VTOC table (Volume's Table Of Contents). This table is found after the DASD's IPL which usually means the VTOC is at record 3, cylinder 0 and head 0.
To find the sequence of format 1 entries the OS has to read 0, 0, 3. Place the first 20 bytes into a buffer then obtain the location of the format 1 DSCBs:
void GetCHRFromVTOC(void *buffer) {
uint16_t cyl, head;
uint8_t rec;
memcpy(&cyl, buffer + 15, 2); /* 15-16 */
memcpy(&head, buffer + 17, 2); /* 17-18 */
memcpy(&rec, buffer + 19, 1); /* 19-19 */
return;
}
Format 1 DSCB
Name | Size | Usage |
---|---|---|
DS1NAM | 44 | Name of dataset |
DS1FMTID | 1 | Format Id |
UNUSED | 80 | |
EXT_TYPE | 1 | |
SEQUENCE_NUMBER |
1 | |
START_CC | 2 | Starting cylinder |
START_HH | 2 | Starting head |
END_CC | 2 | Ending cylinder |
END_HH | 2 | Ending head |
This entry describes a dataset (file) general information, including location and name. This is generally what most people will search for.
The entries are ordered in a chain-like structure, where a formatId=0 entry denotes the end of said chain.
// NOTE: This code assumes EBCDIC is being used
void CheckDSCB(struct DSCB1 *dscb, const char *name) {
if(dscb1.ds1fmtid == '1') {
dscb1.ds1fmtid = ' ';
if(!memcmp(&dscb1.ds1dsnam, name, strlen(name))) {
// Dataset found
cyl = dscb1.start_cc;
head = dscb1.start_hh;
rec = 1;
kprintf("DATASET %s @ CYL=%i,HEAD=%i,RECORD=%i\n", name, (int)cyl, (int)head, (int)rec);
// The kernel now should use Cyl, Head and the Rec locations provided to read the dataset
kpanic("TODO: Use cyl, head and rec to read the file\n");
}
} else if(dscb1.ds1dsnam[0] == '\0') {
// Not found
kpanic("Could not find file %s!", name);
}
}
Finding the files is just a matter of reading records until reaching the end of the head, then incrementing heads and after reading the last head in the cylinder, incrementing cylinders. This also has to be done for reading files.
This is mostly specific to DASD devices but it's provided for clarity.
// NOTE: This code assumes EBCDIC is being used
void FindFile(const char *name) {
while(errcnt < 4) {
r = DasdReadCHR(hdl, &cyl, &head, &rec, &dscb1, sizeof(dscb1));
if(r < 0) {
++errcnt;
if(errcnt == 1) {
// If we have an error reading this record skip to the next
++rec;
} else if(errcnt == 2) {
// Next record failed?, now we need to change heads
rec = 1;
++head;
} else if(errcnt == 3) {
// Switch cylinders if we can't read new heads either
rec = 1;
head = 0;
++cyl;
}
continue;
}
errcnt = 0;
if(r >= (int)sizeof(dscb1)) {
CheckDSCB(&dscb1, name);
}
// Go to next record
++rec;
}
}
See also
Source code
- https://sourceforge.net/p/pdos/gitcode/ci/master/tree/s370/pdosutil.c#l25 Find a file from ZDSFS
External links
- https://www.ibm.com/docs/en/zos/2.3.0?topic=components-data-set-control-block-dscb-types DSCB types
- https://www.ibm.com/docs/en/zos/2.3.0?topic=dscbs-how-found Obtaining format 1 entries