int gfs_create_file(char *name, int *IOP_list, int num_iops)
name. The application has the option of specifying the number of IOPs it wishes the file to be created on, and even which IOPs. This call implicitly creates a subfile on each IOP.
int gfs_open_file(char *name)
int gfs_close_file(int file_id)
int gfs_delete_file(char *name)
name. This implicitly deletes all of the files subfiles and their forks.
int gfs_create_fork(int file_id, int subfile, char *name)
subfileof the previously opened file
int gfs_all_create(int file_id, char *name)
namein each subfile of the open file
int gfs_open_fork(int file_id, int subfile, char *name)
subfileof the previously opened file
file. Return either an open fork ID or an error code.
int gfs_all_open(int file_id, int *fork_ids, char *name)
namein each subfile of the previously opened file
file. The array,
fork_ids, is filled with fork IDs. This call returns the number of forks opened or an error code.
int gfs_extend_fork(int fork_id, ulong_t size)
sizebytes long. Explictly extending a file increases the likelihood that a file will have good disk locality.
int gfs_close_fork(int fork_id)
int gfs_all_close(int file_id, int *fork_ids)
gfs_all_open()call, but it is not required.
int gfs_delete_fork(int file_id, int subfile, char *name)
subfileof the open file
int gfs_all_delete(int file_id, char *name)
namein each subfile of the file
int gfs_read(int fork_id, char *buf, ulong_t offset, ulong_t size)
read(), reading a contiguous range of
sizebytes, and storing them in memory at
buf. Unlike Unix, however, Galley does not maintain an implicit file pointer, marking the location of the previous access. As a result, the application must explicitly indicate the starting offset of the request in the fork.
int gfs_read_block(int fork_id, char *buf, int block)
gfs_read()). Specifically, Galley is able to schedule disk accesses intelligently, reducing the amount of time that is wasted seeking from one portion of the disk to another. Galley is also able to reduce the number of messages that are exchanged between the CP and IOP. For example, rather than sending 512 messages, each with 64 bytes of data, Galley can pack those pieces into a single 32768 byte message.
int gfs_read_strided(int fork_id, char *buf, ulong_t offset, ulong_t size, int file_stride, int mem_stride, int quant)
offset, Galley will read
sizebytes. The offset of each record is
file_stridebytes greater than the previous record's offset. The records will be stored in memory at
mem_stridebytes between each record.
file_stride is equal to
then data will be read contiguously from disk (as with the
gfs_read() call), but will be scattered in
memory. On the other hand, if
mem_stride is equal to
size, then data will be gathered from disk, but
stored contiguously in memory. Of course, the more adventurous
programmer may scatter and gather in the same operation. Note also
mem_stride may be
int gfs_read_nested(int fork_id, char *buf, ulong_t offset, ulong_t size, struct gfs_stride *vector, int levels)
vectoris a pointer to an array of
(file_stride, mem_stride, quantity)triples listed from the innermost level of nesting to the outermost. The number of levels of nesting is indicated by
levels. As with the
gfs_strided()call, appropriate choices of
mem_strideallow the application a wide array of scatter/gather possibilities.
int gfs_read_listio(int fork_id, char *buf, struct gfs_list *list, int quant)
listpoints to a vector of
(file_offset, memory_offset, size)triples, and
quantindicates how many triples are in the vector. Unlike the previous interfaces, the
listiointerface does not require that the requests exhibit any sort of regularity. Although this interface does not reduce the amount of work performed by the application (it must still calculate every offset explicitly), it does allow Galley to perform the same optimizations as other batched requests.
gfs_handleas the first parameter of each call. For example, a
gfs_read(fork_id, buf, offset, size)becomes
gfs_nb_read(handle, fork_id, buf, offset, size). A non-blocking call cannot return the amount of data transferred, since that information is not available at the time the call is made. So, non-blocking calls simply return an error code if one or more parameters to the call are invalid.
There are a number of extra calls required to support non-blocking I/O.
int gfs_test(gfs_handle handle)
int gfs_wait(gfs_handle h)
wait()for a non-blocking operation to complete before the handle may be reused.
int gfs_free_handle(gfs_handle h)