From: David van Moolenbroek Date: Sun, 24 Aug 2014 10:37:12 +0000 (+0000) Subject: isofs: use libdriver X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zpipe.c?a=commitdiff_plain;h=e2dc2c89547965bb9ed2971496cb30c1d89543fe;p=minix.git isofs: use libdriver Change-Id: I5ced800eec92f651f31d9c77c3129fe837ca4614 --- diff --git a/minix/fs/iso9660fs/Makefile b/minix/fs/iso9660fs/Makefile index 69f05c7d5..17f1cc20b 100644 --- a/minix/fs/iso9660fs/Makefile +++ b/minix/fs/iso9660fs/Makefile @@ -1,11 +1,11 @@ # Makefile for ISO9660 fs PROG= isofs SRCS= main.c table.c mount.c super.c inode.c \ - link.c utility.c misc.c path.c read.c susp.c susp_rock_ridge.c stadir.c + link.c utility.c path.c read.c susp.c susp_rock_ridge.c stadir.c -DPADD+= ${LIBBDEV} ${LIBSYS} -LDADD+= -lbdev -lsys -lc -lminixfs +DPADD+= ${LIBFSDRIVER} ${LIBBDEV} ${LIBSYS} ${LIBMINIXFS} +LDADD+= -lfsdriver -lbdev -lsys -lc -lminixfs -CPPFLAGS+= -DNR_BUFS=100 -Wall +CPPFLAGS+= -DNR_BUFS=100 .include diff --git a/minix/fs/iso9660fs/const.h b/minix/fs/iso9660fs/const.h index 4443afd68..81e80b5ac 100644 --- a/minix/fs/iso9660fs/const.h +++ b/minix/fs/iso9660fs/const.h @@ -1,7 +1,7 @@ #define GETDENTS_BUFSIZ 1024 -#define ISO9660_STANDARD_ID "CD001" /* Standard code for ISO9660 file systems */ +#define ISO9660_STANDARD_ID "CD001" /* Standard code for ISO9660 FS */ #define NR_INODE_RECORDS 64 #define NR_DIR_EXTENT_RECORDS NR_INODE_RECORDS * 16 @@ -43,9 +43,6 @@ #define ISO9660_MAX_FILE_ID_LEN 32 #define ISO9660_RRIP_MAX_FILE_ID_LEN 256 -#define END_OF_FILE (-104) /* eof detected */ - /* Miscellaneous constants */ #define SYS_UID ((uid_t) 0) /* uid_t for processes PM and INIT */ #define SYS_GID ((gid_t) 0) /* gid_t for processes PM and INIT */ - diff --git a/minix/fs/iso9660fs/glo.h b/minix/fs/iso9660fs/glo.h index 877e9e70a..01e667582 100644 --- a/minix/fs/iso9660fs/glo.h +++ b/minix/fs/iso9660fs/glo.h @@ -4,32 +4,8 @@ #define EXTERN #endif -#include - -/* The following variables are used for returning results to the caller. */ - -EXTERN int err_code; /* temporary storage for error number */ -EXTERN int rdwt_err; /* status of last disk i/o request */ - -EXTERN int(*fs_call_vec[]) (void); - -EXTERN message fs_m_in; /* contains the input message of the request */ -EXTERN message fs_m_out; /* contains the output message of the request */ -EXTERN int FS_STATE; - -EXTERN uid_t caller_uid; -EXTERN gid_t caller_gid; - -EXTERN int req_nr; /* request number to the server */ - -EXTERN short path_processed; /* number of characters processed */ -EXTERN char user_path[PATH_MAX+1]; /* pathname to be processed */ -EXTERN char *vfs_slink_storage; -EXTERN int symloop; - -EXTERN int unmountdone; - EXTERN dev_t fs_dev; /* the device that is handled by this FS proc */ -EXTERN char fs_dev_label[16]; /* Name of the device driver that is handled */ EXTERN struct opt opt; /* global mount options */ + +extern struct fsdriver isofs_table; /* function call table */ diff --git a/minix/fs/iso9660fs/inc.h b/minix/fs/iso9660fs/inc.h index 8bc447cc9..6037dc69b 100644 --- a/minix/fs/iso9660fs/inc.h +++ b/minix/fs/iso9660fs/inc.h @@ -21,6 +21,10 @@ #include #include +#include +#include +#include + #include #include #include @@ -32,8 +36,11 @@ #include #include +#include + #define b_data(bp) ((char *) (bp->data)) +#include "const.h" #include "proto.h" #include "super.h" #include "glo.h" diff --git a/minix/fs/iso9660fs/inode.c b/minix/fs/iso9660fs/inode.c index 331772046..4b12c660c 100644 --- a/minix/fs/iso9660fs/inode.c +++ b/minix/fs/iso9660fs/inode.c @@ -5,32 +5,25 @@ */ #include "inc.h" -#include -#include static struct inode inodes[NR_INODE_RECORDS]; static struct buf* fetch_inode(struct dir_extent *extent, size_t *offset); -int fs_putnode() +int fs_putnode(ino_t ino_nr, unsigned int count) { /* * Find the inode specified by the request message and decrease its * counter. */ - int count = fs_m_in.m_vfs_fs_putnode.count; - struct inode *i_node = find_inode(fs_m_in.m_vfs_fs_putnode.inode); + struct inode *i_node; - if (i_node == NULL) { - printf("put_inode: trying to free unused inode\n"); - panic("fs_putnode failed"); - } - if (count <= 0) { - printf("put_inode: bad value for count: %d\n", count); - panic("fs_putnode failed"); + if ((i_node = find_inode(ino_nr)) == NULL) { + printf("ISOFS: trying to free unused inode\n"); + return EINVAL; } if (count > i_node->i_count) { - printf("put_inode: count too high: %d > %d\n", count, i_node->i_count); - panic("fs_putnode failed"); + printf("ISOFS: put_node count too high\n"); + return EINVAL; } i_node->i_count -= count - 1; @@ -38,7 +31,7 @@ int fs_putnode() return OK; } -struct inode* alloc_inode() +struct inode* alloc_inode(void) { /* * Return a free inode from the pool. @@ -112,7 +105,8 @@ struct inode* get_inode(ino_t i) extent->location = i / v_pri.logical_block_size_l; extent->length = 1; - if (read_inode(i_node, extent, i % v_pri.logical_block_size_l, NULL) != OK) { + if (read_inode(i_node, extent, i % v_pri.logical_block_size_l, + NULL) != OK) { free_extent(extent); put_inode(i_node); return NULL; @@ -127,16 +121,14 @@ void put_inode(struct inode *i_node) if (i_node == NULL) return; - if (i_node->i_count <= 0) - panic("put_inode: i_count already below 1: %d", i_node->i_count); + assert(i_node->i_count > 0); i_node->i_count--; } void dup_inode(struct inode *i_node) { - if (i_node == NULL) - panic("dup_inode: trying to duplicate NULL inode"); + assert(i_node != NULL); i_node->i_count++; } @@ -153,7 +145,7 @@ static struct buf* fetch_inode(struct dir_extent *extent, size_t *offset) */ bp = read_extent_block(extent, *offset / v_pri.logical_block_size_l); while (bp != NULL) { - dir_rec = (struct iso9660_dir_record*)(b_data(bp) + *offset % + dir_rec = (struct iso9660_dir_record*)(b_data(bp) + *offset % v_pri.logical_block_size_l); if (dir_rec->length == 0) { *offset -= *offset % v_pri.logical_block_size_l; @@ -163,8 +155,9 @@ static struct buf* fetch_inode(struct dir_extent *extent, size_t *offset) break; } - put_block(bp); - bp = read_extent_block(extent, *offset / v_pri.logical_block_size_l); + lmfs_put_block(bp, FULL_DATA_BLOCK); + bp = read_extent_block(extent, *offset / + v_pri.logical_block_size_l); } return bp; @@ -181,12 +174,13 @@ int read_inode(struct inode *i_node, struct dir_extent *extent, size_t offset, if (bp == NULL) return EOF; - dir_rec = (struct iso9660_dir_record*)(b_data(bp) + offset % + dir_rec = (struct iso9660_dir_record*)(b_data(bp) + offset % v_pri.logical_block_size_l); /* Parse basic ISO 9660 specs. */ - if (check_dir_record(dir_rec, offset % v_pri.logical_block_size_l) != OK) { - put_block(bp); + if (check_dir_record(dir_rec, + offset % v_pri.logical_block_size_l) != OK) { + lmfs_put_block(bp, FULL_DATA_BLOCK); return EINVAL; } @@ -199,18 +193,20 @@ int read_inode(struct inode *i_node, struct dir_extent *extent, size_t offset, read_inode_iso9660(i_node, dir_rec); /* Parse extensions. */ - read_inode_susp(i_node, dir_rec, bp, offset % v_pri.logical_block_size_l); + read_inode_susp(i_node, dir_rec, bp, + offset % v_pri.logical_block_size_l); offset += dir_rec->length; read_inode_extents(i_node, dir_rec, extent, &offset); - put_block(bp); + lmfs_put_block(bp, FULL_DATA_BLOCK); if (new_offset != NULL) *new_offset = offset; return OK; } -void read_inode_iso9660(struct inode *i, const struct iso9660_dir_record *dir_rec) +void read_inode_iso9660(struct inode *i, + const struct iso9660_dir_record *dir_rec) { char *cp; @@ -233,7 +229,8 @@ void read_inode_iso9660(struct inode *i, const struct iso9660_dir_record *dir_re if ((dir_rec->file_flags & D_TYPE) == D_DIRECTORY) { i->i_stat.st_mode = S_IFDIR; - i->i_stat.st_ino = i->extent->location * v_pri.logical_block_size_l; + i->i_stat.st_ino = + i->extent->location * v_pri.logical_block_size_l; } else i->i_stat.st_mode = S_IFREG; @@ -259,11 +256,13 @@ void read_inode_iso9660(struct inode *i, const struct iso9660_dir_record *dir_re /* Initialize stat. */ i->i_stat.st_dev = fs_dev; i->i_stat.st_blksize = v_pri.logical_block_size_l; - i->i_stat.st_blocks = dir_rec->data_length_l / v_pri.logical_block_size_l; + i->i_stat.st_blocks = + dir_rec->data_length_l / v_pri.logical_block_size_l; i->i_stat.st_nlink = 1; } -void read_inode_extents(struct inode *i, const struct iso9660_dir_record *dir_rec, +void read_inode_extents(struct inode *i, + const struct iso9660_dir_record *dir_rec, struct dir_extent *extent, size_t *offset) { struct buf *bp; @@ -275,7 +274,8 @@ void read_inode_extents(struct inode *i, const struct iso9660_dir_record *dir_re * No need to search extents if file is empty or has final directory * record flag set. */ - if (cur_extent == NULL || ((dir_rec->file_flags & D_NOT_LAST_EXTENT) == 0)) + if (cur_extent == NULL || + ((dir_rec->file_flags & D_NOT_LAST_EXTENT) == 0)) return; while (!done) { @@ -283,24 +283,27 @@ void read_inode_extents(struct inode *i, const struct iso9660_dir_record *dir_re if (bp == NULL) return; - bp = read_extent_block(extent, *offset / v_pri.logical_block_size_l); - extent_rec = (struct iso9660_dir_record*)(b_data(bp) + *offset % - v_pri.logical_block_size_l); + bp = read_extent_block(extent, + *offset / v_pri.logical_block_size_l); + extent_rec = (struct iso9660_dir_record*)(b_data(bp) + + *offset % v_pri.logical_block_size_l); - if (check_dir_record(dir_rec, *offset % v_pri.logical_block_size_l) != OK) { - put_block(bp); + if (check_dir_record(dir_rec, + *offset % v_pri.logical_block_size_l) != OK) { + lmfs_put_block(bp, FULL_DATA_BLOCK); return; } /* Extent entries should share the same name. */ if ((dir_rec->length_file_id == extent_rec->length_file_id) && - (memcmp(dir_rec->file_id, extent_rec->file_id, dir_rec->length_file_id) == 0)) { + (memcmp(dir_rec->file_id, extent_rec->file_id, + dir_rec->length_file_id) == 0)) { /* Add the extent at the end of the linked list. */ cur_extent->next = alloc_extent(); cur_extent->next->location = dir_rec->loc_extent_l + - dir_rec->ext_attr_rec_length; + dir_rec->ext_attr_rec_length; cur_extent->next->length = dir_rec->data_length_l / - v_pri.logical_block_size_l; + v_pri.logical_block_size_l; if (dir_rec->data_length_l % v_pri.logical_block_size_l) cur_extent->next->length++; @@ -317,7 +320,7 @@ void read_inode_extents(struct inode *i, const struct iso9660_dir_record *dir_re if ((dir_rec->file_flags & D_NOT_LAST_EXTENT) == 0) done = TRUE; - put_block(bp); + lmfs_put_block(bp, FULL_DATA_BLOCK); } } @@ -336,11 +339,12 @@ void read_inode_susp(struct inode *i, const struct iso9660_dir_record *dir_rec, if(dir_rec->length - susp_offset >= 4) { susp_size = dir_rec->length - susp_offset; - /* Initialize rrii_dir_record structure with known, sane data. */ + /* Initialize record with known, sane data. */ memcpy(rrii_data.mtime, dir_rec->rec_date, ISO9660_SIZE_DATE7); memcpy(rrii_data.atime, dir_rec->rec_date, ISO9660_SIZE_DATE7); memcpy(rrii_data.ctime, dir_rec->rec_date, ISO9660_SIZE_DATE7); - memcpy(rrii_data.birthtime, dir_rec->rec_date, ISO9660_SIZE_DATE7); + memcpy(rrii_data.birthtime, dir_rec->rec_date, + ISO9660_SIZE_DATE7); rrii_data.d_mode = i->i_stat.st_mode; rrii_data.uid = 0; @@ -349,7 +353,8 @@ void read_inode_susp(struct inode *i, const struct iso9660_dir_record *dir_rec, rrii_data.file_id_rrip[0] = '\0'; rrii_data.slink_rrip[0] = '\0'; - parse_susp_buffer(&rrii_data, b_data(bp)+offset+susp_offset, susp_size); + parse_susp_buffer(&rrii_data, b_data(bp)+offset+susp_offset, + susp_size); /* Copy back data from rrii_dir_record structure. */ i->i_stat.st_atime = date7_to_time_t(rrii_data.atime); @@ -363,9 +368,11 @@ void read_inode_susp(struct inode *i, const struct iso9660_dir_record *dir_rec, i->i_stat.st_rdev = rrii_data.rdev; if (rrii_data.file_id_rrip[0] != '\0') - strlcpy(i->i_name, rrii_data.file_id_rrip, ISO9660_RRIP_MAX_FILE_ID_LEN); + strlcpy(i->i_name, rrii_data.file_id_rrip, + sizeof(i->i_name)); if (rrii_data.slink_rrip[0] != '\0') - strlcpy(i->s_link, rrii_data.slink_rrip, ISO9660_RRIP_MAX_FILE_ID_LEN); + strlcpy(i->s_link, rrii_data.slink_rrip, + sizeof(i->s_link)); } } @@ -381,4 +388,3 @@ int check_dir_record(const struct iso9660_dir_record *d, size_t offset) return OK; } - diff --git a/minix/fs/iso9660fs/link.c b/minix/fs/iso9660fs/link.c index 7e7d2a7d4..5f5f8bbfb 100644 --- a/minix/fs/iso9660fs/link.c +++ b/minix/fs/iso9660fs/link.c @@ -1,36 +1,24 @@ #include "inc.h" -#include -#include -#include -#ifdef __NBSD_LIBC -#include -#endif -#include "proto.h" -int fs_rdlink() +ssize_t fs_rdlink(ino_t ino_nr, struct fsdriver_data *data, size_t bytes) { - struct inode *i_node; /* target inode */ - int r; /* return value */ - size_t copylen; + struct inode *i_node; + size_t len; + int r; /* Try to get inode according to its index */ - i_node = find_inode(fs_m_in.m_vfs_fs_rdlink.inode); - if (i_node == NULL) + if ((i_node = find_inode(ino_nr)) == NULL) return EINVAL; /* no inode found */ - if(!S_ISLNK(i_node->i_stat.st_mode)) - r = EACCES; - else { - /* Passed all checks */ - copylen = MIN( (size_t) fs_m_in.m_vfs_fs_rdlink.mem_size, NAME_MAX); + if (!S_ISLNK(i_node->i_stat.st_mode)) + return EACCES; - r = sys_safecopyto(VFS_PROC_NR, - (cp_grant_id_t) fs_m_in.m_vfs_fs_rdlink.grant, - (vir_bytes) 0, - (vir_bytes) i_node->s_link, - copylen); - } + len = strlen(i_node->s_link); + if (len > bytes) + len = bytes; - return r; -} + if ((r = fsdriver_copyout(data, 0, i_node->s_link, len)) != OK) + return r; + return len; +} diff --git a/minix/fs/iso9660fs/main.c b/minix/fs/iso9660fs/main.c index d0b53ebe4..2dd3267b6 100644 --- a/minix/fs/iso9660fs/main.c +++ b/minix/fs/iso9660fs/main.c @@ -4,88 +4,17 @@ */ #include "inc.h" -#include -#include -#include "const.h" -#include "glo.h" - -/* Declare some local functions. */ -static void get_work(message *m_in); - -/* SEF functions and variables. */ -static void sef_local_startup(void); -static int sef_cb_init_fresh(int type, sef_init_info_t *info); -static void sef_cb_signal_handler(int signo); +#include static struct optset optset_table[] = { - { "norock", OPT_BOOL, &opt.norock, TRUE }, - { NULL, 0, NULL, 0 } + { "norock", OPT_BOOL, &opt.norock, TRUE }, + { NULL, 0, NULL, 0 } }; -int main(int argc, char *argv[]) { - endpoint_t who_e; - int ind, error, transid; - - /* SEF local startup. */ - env_setargs(argc, argv); - sef_local_startup(); - - while (TRUE) { - /* Wait for request message. */ - get_work(&fs_m_in); - - transid = TRNS_GET_ID(fs_m_in.m_type); - fs_m_in.m_type = TRNS_DEL_ID(fs_m_in.m_type); - if (fs_m_in.m_type == 0) { - assert(!IS_VFS_FS_TRANSID(transid)); - fs_m_in.m_type = transid; /* Backwards compat. */ - transid = 0; - } - else - assert(IS_VFS_FS_TRANSID(transid)); - - error = OK; - - caller_uid = -1; /* To trap errors */ - caller_gid = -1; - - who_e = fs_m_in.m_source; /* source of the request */ - - if (who_e != VFS_PROC_NR) { /* If the message is not for us just - * continue */ - continue; - } - - req_nr = fs_m_in.m_type; - - if (req_nr < FS_BASE) { - fs_m_in.m_type += FS_BASE; - req_nr = fs_m_in.m_type; - } - - ind = req_nr - FS_BASE; - - if (ind < 0 || ind >= NREQS) - error = EINVAL; - else - error = (*fs_call_vec[ind])(); /* Process the request calling - * the appropriate function. */ - - fs_m_out.m_type = error; - if (IS_VFS_FS_TRANSID(transid)) { - /* If a transaction ID was set, reset it */ - fs_m_out.m_type = TRNS_ADD_ID(fs_m_out.m_type, transid); - } - reply(who_e, &fs_m_out); /* returns the response to VFS */ - } -} - -/*===========================================================================* - * sef_local_startup * - *===========================================================================*/ -static void sef_local_startup() +static int sef_cb_init_fresh(int __unused type, + sef_init_info_t * __unused info) { - /* Initialize the Minix file server. */ + /* Initialize the iso9660fs server. */ int i; /* Defaults */ @@ -96,26 +25,10 @@ static void sef_local_startup() if (!strcmp(env_argv[i], "-o")) optset_parse(optset_table, env_argv[++i]); - /* Register init callbacks. */ - sef_setcb_init_fresh(sef_cb_init_fresh); - sef_setcb_init_restart(sef_cb_init_fail); - - /* No live update support for now. */ - - /* Register signal callbacks. */ - sef_setcb_signal_handler(sef_cb_signal_handler); - - /* Let SEF perform startup. */ - sef_startup(); - - lmfs_buf_pool(10); -} - -static int sef_cb_init_fresh(int type, sef_init_info_t *info) -{ - /* Initialize the iso9660fs server. */ setenv("TZ","",1); /* Used to calculate the time */ + lmfs_buf_pool(NR_BUFS); + return OK; } @@ -124,25 +37,31 @@ static void sef_cb_signal_handler(int signo) /* Only check for termination signal, ignore anything else. */ if (signo != SIGTERM) return; - /* No need to do a sync, as this is a read-only file system. */ - - /* - * If the file system has already been unmounted, exit immediately. - * We might not get another message. - */ - if (unmountdone) exit(0); + fsdriver_terminate(); } -static void get_work(message *m_in) +static void sef_local_startup(void) { - int s; /* receive status */ - if (OK != (s = sef_receive(ANY, m_in))) /* wait for message */ - panic("sef_receive failed: %d", s); + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fail); + + /* No live update support for now. */ + + /* Register signal callbacks. */ + sef_setcb_signal_handler(sef_cb_signal_handler); + + /* Let SEF perform startup. */ + sef_startup(); } -void reply(int who, message *m_out) +int main(int argc, char *argv[]) { - if (OK != ipc_send(who, m_out)) /* send the message */ - printf("ISOFS(%d) was unable to send reply\n", sef_self()); -} + /* SEF local startup. */ + env_setargs(argc, argv); + sef_local_startup(); + fsdriver_task(&isofs_table); + + return 0; +} diff --git a/minix/fs/iso9660fs/misc.c b/minix/fs/iso9660fs/misc.c deleted file mode 100644 index d0ded206d..000000000 --- a/minix/fs/iso9660fs/misc.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "inc.h" -#include -#include -#include - -int fs_sync() -{ - /* Always mounted read only, so nothing to sync */ - return OK; /* sync() can't fail */ -} - -int fs_new_driver(void) -{ - /* Set a new driver endpoint for this device. */ - dev_t dev; - cp_grant_id_t label_gid; - size_t label_len; - char label[sizeof(fs_dev_label)]; - int r; - - dev = fs_m_in.m_vfs_fs_new_driver.device; - label_gid = fs_m_in.m_vfs_fs_new_driver.grant; - label_len = fs_m_in.m_vfs_fs_new_driver.path_len; - - if (label_len > sizeof(label)) - return EINVAL; - - r = sys_safecopyfrom(fs_m_in.m_source, label_gid, (vir_bytes) 0, - (vir_bytes) label, label_len); - - if (r != OK) { - printf("ISOFS: fs_new_driver safecopyfrom failed (%d)\n", r); - return EINVAL; - } - - bdev_driver(dev, label); - return OK; -} - diff --git a/minix/fs/iso9660fs/mount.c b/minix/fs/iso9660fs/mount.c index 423644d32..9cbe06a70 100644 --- a/minix/fs/iso9660fs/mount.c +++ b/minix/fs/iso9660fs/mount.c @@ -1,35 +1,16 @@ #include "inc.h" #include -#include -#include "const.h" -#include "glo.h" -int fs_readsuper() { - cp_grant_id_t label_gid; - size_t label_len; - int r = OK; - - fs_dev = fs_m_in.m_vfs_fs_readsuper.device; - label_gid = fs_m_in.m_vfs_fs_readsuper.grant; - label_len = fs_m_in.m_vfs_fs_readsuper.path_len; - - if (label_len > sizeof(fs_dev_label)) - return EINVAL; - - r = sys_safecopyfrom(fs_m_in.m_source, label_gid, 0, (vir_bytes)fs_dev_label, - label_len); - if (r != OK) { - printf("ISOFS %s:%d safecopyfrom failed: %d\n", __FILE__, __LINE__, r); - return EINVAL; - } +int fs_mount(dev_t dev, unsigned int __unused flags, + struct fsdriver_node *root_node, unsigned int *res_flags) +{ + int r; - /* Map the driver label for this major */ - bdev_driver(fs_dev, fs_dev_label); + fs_dev = dev; /* Open the device the file system lives on in read only mode */ - if (bdev_open(fs_dev, BDEV_R_BIT) != OK) { + if (bdev_open(fs_dev, BDEV_R_BIT) != OK) return EINVAL; - } /* Read the superblock */ r = read_vds(&v_pri, fs_dev); @@ -39,51 +20,44 @@ int fs_readsuper() { } /* Return some root inode properties */ - fs_m_out.m_fs_vfs_readsuper.inode = v_pri.inode_root->i_stat.st_ino; - fs_m_out.m_fs_vfs_readsuper.mode = v_pri.inode_root->i_stat.st_mode; - fs_m_out.m_fs_vfs_readsuper.file_size = v_pri.inode_root->i_stat.st_size; - fs_m_out.m_fs_vfs_readsuper.uid = SYS_UID; /* Always root */ - fs_m_out.m_fs_vfs_readsuper.gid = SYS_GID; /* operator */ - fs_m_out.m_fs_vfs_readsuper.flags = RES_NOFLAGS; + root_node->fn_ino_nr = v_pri.inode_root->i_stat.st_ino; + root_node->fn_mode = v_pri.inode_root->i_stat.st_mode; + root_node->fn_size = v_pri.inode_root->i_stat.st_size; + root_node->fn_uid = SYS_UID; /* Always root */ + root_node->fn_gid = SYS_GID; /* operator */ + root_node->fn_dev = NO_DEV; + + *res_flags = RES_NOFLAGS; return r; } -int fs_mountpoint() +int fs_mountpt(ino_t ino_nr) { /* * This function looks up the mount point, it checks the condition * whether the partition can be mounted on the inode or not. */ - struct inode *rip; - int r = OK; - /* Temporarily open the file. */ - if ((rip = find_inode(fs_m_in.m_vfs_fs_mountpoint.inode)) == NULL) + if ((rip = find_inode(ino_nr)) == NULL) return EINVAL; if (rip->i_mountpoint) - r = EBUSY; + return EBUSY; - /* If the inode is not a dir returns error */ + /* The inode must be a directory. */ if ((rip->i_stat.st_mode & I_TYPE) != I_DIRECTORY) - r = ENOTDIR; - - put_inode(rip); + return ENOTDIR; - if (r == OK) - rip->i_mountpoint = TRUE; + rip->i_mountpoint = TRUE; - return r; + return OK; } -int fs_unmount(void) +void fs_unmount(void) { release_vol_pri_desc(&v_pri); /* Release the super block */ - bdev_close(fs_dev); - unmountdone = TRUE; - return OK; + bdev_close(fs_dev); } - diff --git a/minix/fs/iso9660fs/path.c b/minix/fs/iso9660fs/path.c index 30ab4af7c..df800fd21 100644 --- a/minix/fs/iso9660fs/path.c +++ b/minix/fs/iso9660fs/path.c @@ -1,92 +1,14 @@ #include "inc.h" -#include -#include -#include -#include -static char *get_name(char *name, char string[NAME_MAX+1]); -static int ltraverse(struct inode *rip, char *suffix); -static int parse_path(ino_t dir_ino, ino_t root_ino, int flags, struct - inode **res_inop, size_t *offsetp, int *symlinkp); - - -/*===========================================================================* - * fs_lookup * - *===========================================================================*/ -int fs_lookup() { - cp_grant_id_t grant; - int r, len, flags, symlinks = 0; - size_t offset = 0; - ino_t dir_ino, root_ino; - struct inode *dir = 0; - - grant = fs_m_in.m_vfs_fs_lookup.grant_path; - len = fs_m_in.m_vfs_fs_lookup.path_len; /* including terminating nul */ - dir_ino = fs_m_in.m_vfs_fs_lookup.dir_ino; - root_ino = fs_m_in.m_vfs_fs_lookup.root_ino; - flags = fs_m_in.m_vfs_fs_lookup.flags; - caller_uid = fs_m_in.m_vfs_fs_lookup.uid; - caller_gid = fs_m_in.m_vfs_fs_lookup.gid; - - /* Check length. */ - if(len > sizeof(user_path)) - return E2BIG; /* too big for buffer */ - if(len < 1) - return EINVAL; /* too small */ - - /* Copy the pathname and set up caller's user and group id */ - r = sys_safecopyfrom(VFS_PROC_NR, grant, 0, (vir_bytes) user_path, - (phys_bytes) len); - if (r != OK) { - printf("ISOFS %s:%d sys_safecopyfrom failed: %d\n", - __FILE__, __LINE__, r); - return r; - } - - /* Verify this is a null-terminated path. */ - if(user_path[len-1] != '\0') - return EINVAL; - - /* Lookup inode */ - r = parse_path(dir_ino, root_ino, flags, &dir, &offset, &symlinks); - - if(r == ELEAVEMOUNT || r == ESYMLINK) { - /* Report offset and the error */ - fs_m_out.m_fs_vfs_lookup.offset = offset; - fs_m_out.m_fs_vfs_lookup.symloop = symlinks; - return r; - } - - if (r != OK && r != EENTERMOUNT) - return r; - - fs_m_out.m_fs_vfs_lookup.inode = dir->i_stat.st_ino; - fs_m_out.m_fs_vfs_lookup.mode = dir->i_stat.st_mode; - fs_m_out.m_fs_vfs_lookup.file_size = dir->i_stat.st_size; - fs_m_out.m_fs_vfs_lookup.device = dir->i_stat.st_rdev; - fs_m_out.m_fs_vfs_lookup.symloop = 0; - fs_m_out.m_fs_vfs_lookup.uid = dir->i_stat.st_uid; - fs_m_out.m_fs_vfs_lookup.gid = dir->i_stat.st_gid; - - if (r == EENTERMOUNT) { - fs_m_out.m_fs_vfs_lookup.offset = offset; - put_inode(dir); - } - - return r; -} - -/* The search dir actually performs the operation of searching for the - * compoent ``string" in ldir_ptr. It returns the response and the number of - * the inode in numb. */ -/*===========================================================================* - * search_dir * - *===========================================================================*/ -int search_dir( +static int search_dir( struct inode *ldir_ptr, /* dir record parent */ char string[NAME_MAX], /* component to search for */ ino_t *numb /* pointer to new dir record */ ) { + /* The search_dir function performs the operation of searching for the + * component ``string" in ldir_ptr. It returns the response and the + * number of the inode in numb. + */ struct inode *dir_tmp; size_t pos = 0; int r; @@ -109,7 +31,8 @@ int search_dir( * inodes stay consistent. */ if (strcmp(string, "..") == 0) { - if (ldir_ptr->i_stat.st_ino == v_pri.inode_root->i_stat.st_ino) { + if (ldir_ptr->i_stat.st_ino == + v_pri.inode_root->i_stat.st_ino) { *numb = v_pri.inode_root->i_stat.st_ino; return OK; } @@ -141,8 +64,10 @@ int search_dir( } if ((strcmp(dir_tmp->i_name, string) == 0) || - (strcmp(dir_tmp->i_name, "..") && strcmp(string, "..") == 0)) { - if (dir_tmp->i_stat.st_ino == v_pri.inode_root->i_stat.st_ino) { + (strcmp(dir_tmp->i_name, "..") && + strcmp(string, "..") == 0)) { + if (dir_tmp->i_stat.st_ino == + v_pri.inode_root->i_stat.st_ino) { *numb = v_pri.inode_root->i_stat.st_ino; put_inode(dir_tmp); return OK; @@ -157,295 +82,37 @@ int search_dir( } } - -/*===========================================================================* - * parse_path * - *===========================================================================*/ -static int parse_path( -ino_t dir_ino, -ino_t root_ino, -int flags, -struct inode **res_inop, -size_t *offsetp, -int *symlinkp -) { - int r; - char string[NAME_MAX+1]; - char *cp, *ncp; - struct inode *start_dir = 0, *old_dir = 0; - - /* Find starting inode inode according to the request message */ - if ((start_dir = find_inode(dir_ino)) == NULL) { - printf("ISOFS: couldn't find starting inode %llu\n", dir_ino); - return ENOENT; - } - - cp = user_path; - dup_inode(start_dir); - - /* Scan the path component by component. */ - while (TRUE) { - if (cp[0] == '\0') { - /* Empty path */ - *res_inop = start_dir; - *offsetp += cp-user_path; - - /* Return EENTERMOUNT if we are at a mount point */ - if (start_dir->i_mountpoint) - return EENTERMOUNT; - - return OK; - } - - if (cp[0] == '/') { - /* - * Special case code. If the remaining path consists of - * just slashes, we need to look up '.' - */ - while(cp[0] == '/') - cp++; - if (cp[0] == '\0') { - strlcpy(string, ".", NAME_MAX + 1); - ncp = cp; - } - else - ncp = get_name(cp, string); - } - else - /* Just get the first component */ - ncp = get_name(cp, string); - - /* Special code for '..'. A process is not allowed to leave a chrooted - * environment. A lookup of '..' at the root of a mounted filesystem - * has to return ELEAVEMOUNT. - */ - if (strcmp(string, "..") == 0) { - - /* This condition is not necessary since it will never be the root filesystem */ - /* if (start_dir == v_pri.inode_root) { */ - /* cp = ncp; */ - /* continue; /\* Just ignore the '..' at a process' */ - /* * root. */ - /* *\/ */ - /* } */ - - if (start_dir == v_pri.inode_root) { - /* Climbing up mountpoint. */ - put_inode(start_dir); - *res_inop = NULL; - *offsetp += cp-user_path; - return ELEAVEMOUNT; - } - } - else { - /* Only check for a mount point if we are not looking for '..'. */ - if (start_dir->i_mountpoint) { - *res_inop = start_dir; - *offsetp += cp-user_path; - return EENTERMOUNT; - } - } - - /* There is more path. Keep parsing. */ - old_dir = start_dir; - - r = advance(old_dir, string, &start_dir); - - if (r != OK) { - put_inode(old_dir); - return r; - } - - /* The call to advance() succeeded. Fetch next component. */ - if (S_ISLNK(start_dir->i_stat.st_mode)) { - - if (ncp[0] == '\0' && (flags & PATH_RET_SYMLINK)) { - put_inode(old_dir); - *res_inop = start_dir; - *offsetp += ncp - user_path; - return OK; - } - - /* Extract path name from the symlink file */ - r = ltraverse(start_dir, ncp); - ncp = user_path; - *offsetp = 0; - - /* Symloop limit reached? */ - if (++(*symlinkp) > _POSIX_SYMLOOP_MAX) - r = ELOOP; - - if (r != OK) { - put_inode(old_dir); - put_inode(start_dir); - return r; - } - - if (ncp[0] == '/') { - put_inode(old_dir); - put_inode(start_dir); - return ESYMLINK; - } - - put_inode(start_dir); - dup_inode(old_dir); - start_dir = old_dir; - } - - put_inode(old_dir); - cp = ncp; - } -} - -/*===========================================================================* - * ltraverse * - *===========================================================================*/ -static int ltraverse( -struct inode *rip, /* symbolic link */ -char *suffix) /* current remaining path. Has to point in the - * user_path buffer - */ +int fs_lookup(ino_t dir_nr, char *name, struct fsdriver_node *node, + int *is_mountpt) { - /* Traverse a symbolic link. Copy the link text from the inode and insert - * the text into the path. Return error code or report success. Base - * directory has to be determined according to the first character of the - * new pathname. - */ - - size_t llen; /* length of link */ - size_t slen; /* length of suffix */ - char *sp; /* start of link text */ - - llen = strlen(rip->s_link); - sp = rip->s_link; - slen = strlen(suffix); - - /* The path we're parsing looks like this: - * /already/processed/path/ or - * /already/processed/path//not/yet/processed/path - * After expanding the , the path will look like - * or - * /not/yet/processed - * In both cases user_path must have enough room to hold . - * However, in the latter case we have to move /not/yet/processed to the - * right place first, before we expand . When strlen() is - * smaller than strlen(/already/processes/path), we move the suffix to the - * left. Is strlen() greater then we move it to the right. Else - * we do nothing. + /* Given a directory and a component of a path, look up the component + * in the directory, find the inode, open it, and return its details. */ - - if (slen > 0) { /* Do we have path after the link? */ - /* For simplicity we require that suffix starts with a slash */ - if (suffix[0] != '/') { - panic("ltraverse: suffix does not start with a slash"); - } - - /* To be able to expand the , we have to move the 'suffix' - * to the right place. - */ - if (slen + llen + 1 > sizeof(user_path)) - return ENAMETOOLONG;/* +suffix+\0 does not fit*/ - if ((unsigned) (suffix - user_path) != llen) { - /* Move suffix left or right */ - memmove(&user_path[llen], suffix, slen+1); - } - } - else { - if (llen + 1 > sizeof(user_path)) - return ENAMETOOLONG; /* + \0 does not fix */ - - /* Set terminating nul */ - user_path[llen]= '\0'; - } - - /* Everything is set, now copy the expanded link to user_path */ - memmove(user_path, sp, llen); - - return OK; -} - -/*===========================================================================* - * advance * - *===========================================================================*/ -int advance( -struct inode *dirp, /* inode for directory to be searched */ -char string[NAME_MAX], /* component name to look for */ -struct inode **resp) /* resulting inode */ -{ - /* Given a directory and a component of a path, look up the component in - * the directory, find the inode, open it, and return a pointer to its inode - * slot. - */ - - struct inode *rip = NULL; + struct inode *dirp, *rip; + ino_t ino_nr; int r; - ino_t numb; - - /* If 'string' is empty, yield same inode straight away. */ - if (string[0] == '\0') - return ENOENT; - /* Check for NULL. */ - if (dirp == NULL) + /* Find the starting inode. */ + if ((dirp = find_inode(dir_nr)) == NULL) return EINVAL; - /* If 'string' is not present in the directory, signal error. */ - if ( (r = search_dir(dirp, string, &numb)) != OK) + /* Look up the directory entry. */ + if ((r = search_dir(dirp, name, &ino_nr)) != OK) return r; - /* The component has been found in the directory. Get inode. */ - if ( (rip = get_inode((int) numb)) == NULL) - return err_code; - - *resp= rip; - return OK; -} - -/*===========================================================================* - * get_name * - *===========================================================================*/ -static char *get_name( -char *path_name, /* path name to parse */ -char string[NAME_MAX+1]) /* component extracted from 'old_name' */ -{ - /* Given a pointer to a path name in fs space, 'path_name', copy the first - * component to 'string' (truncated if necessary, always nul terminated). - * A pointer to the string after the first component of the name as yet - * unparsed is returned. Roughly speaking, - * 'get_name' = 'path_name' - 'string'. - * - * This routine follows the standard convention that /usr/ast, /usr//ast, - * //usr///ast and /usr/ast/ are all equivalent. - */ - size_t len; - char *cp, *ep; - - cp = path_name; + /* The component has been found in the directory. Get the inode. */ + if ((rip = get_inode(ino_nr)) == NULL) + return EIO; /* FIXME: this could have multiple causes */ - /* Skip leading slashes */ - while (cp[0] == '/') - cp++; + /* Return its details to the caller. */ + node->fn_ino_nr = rip->i_stat.st_ino; + node->fn_mode = rip->i_stat.st_mode; + node->fn_size = rip->i_stat.st_size; + node->fn_uid = rip->i_stat.st_uid; + node->fn_gid = rip->i_stat.st_gid; + node->fn_dev = rip->i_stat.st_rdev; - /* Find the end of the first component */ - ep = cp; - while(ep[0] != '\0' && ep[0] != '/') - ep++; + *is_mountpt = rip->i_mountpoint; - len = ep-cp; - - /* Truncate the amount to be copied if it exceeds NAME_MAX */ - if (len > NAME_MAX) - len = NAME_MAX; - - /* Special case of the string at cp is empty */ - if (len == 0) - /* Return "." */ - strlcpy(string, ".", NAME_MAX + 1); - else { - memcpy(string, cp, len); - string[len]= '\0'; - } - - return ep; + return OK; } - diff --git a/minix/fs/iso9660fs/proto.h b/minix/fs/iso9660fs/proto.h index fbcc7055b..106c76490 100644 --- a/minix/fs/iso9660fs/proto.h +++ b/minix/fs/iso9660fs/proto.h @@ -7,19 +7,10 @@ struct iso9660_dir_record; struct iso9660_vol_pri_desc; struct inode; -#include - -#define get_block(n) lmfs_get_block(fs_dev, n, NORMAL) -#define put_block(n) lmfs_put_block(n, FULL_DATA_BLOCK) - -/* main.c */ -int main(int argc, char *argv[]); -void reply(int who, message *m_out); - /* inode.c */ -int fs_putnode(void); +int fs_putnode(ino_t ino_nr, unsigned int count); -struct inode* alloc_inode(); +struct inode* alloc_inode(void); struct inode* find_inode(ino_t i); void put_inode(struct inode *i); void dup_inode(struct inode *i_node); @@ -27,49 +18,41 @@ struct inode* get_inode(ino_t i); int read_inode(struct inode *i_node, struct dir_extent *extent, size_t offset, size_t *new_offset); -void read_inode_iso9660(struct inode *i, const struct iso9660_dir_record *dir_rec); -void read_inode_extents(struct inode *i, const struct iso9660_dir_record *dir_rec, - struct dir_extent *extent, size_t *offset); +void read_inode_iso9660(struct inode *i, + const struct iso9660_dir_record *dir_rec); +void read_inode_extents(struct inode *i, + const struct iso9660_dir_record *dir_rec, struct dir_extent *extent, + size_t *offset); void read_inode_susp(struct inode *i, const struct iso9660_dir_record *dir_rec, struct buf *bp, size_t offset); int check_dir_record(const struct iso9660_dir_record *d, size_t offset); /* link.c */ -int fs_rdlink(void); - -/* misc.c */ -int fs_sync(void); -int fs_new_driver(void); +ssize_t fs_rdlink(ino_t ino_nr, struct fsdriver_data *data, size_t bytes); /* mount.c */ -int fs_readsuper(void); -int fs_mountpoint(void); -int fs_unmount(void); +int fs_mount(dev_t dev, unsigned int flags, struct fsdriver_node *root_node, + unsigned int *res_flags); +int fs_mountpt(ino_t ino_nr); +void fs_unmount(void); /* path.c */ -int fs_lookup(void); -int advance(struct inode *dirp, char string[NAME_MAX], struct - inode **resp); -int search_dir(struct inode *ldir_ptr, char string [NAME_MAX], ino_t *numb); +int fs_lookup(ino_t ino_nr, char *name, struct fsdriver_node *node, + int *is_mountpt); /* read.c */ -int fs_read(void); -int fs_bread(void); -int fs_getdents(void); -int read_chunk(struct inode *rip, u64_t position, unsigned off, int - chunk, unsigned left, cp_grant_id_t gid, unsigned buf_off, int - block_size, int *completed, int rw); - +ssize_t fs_read(ino_t ino_nr, struct fsdriver_data *data, size_t bytes, + off_t pos, int call); +ssize_t fs_getdents(ino_t ino_nr, struct fsdriver_data *data, size_t bytes, + off_t *pos); /* stadir.c */ -int fs_stat(void); -int fs_statvfs(void); +int fs_stat(ino_t ino_nr, struct stat *statbuf); +int fs_statvfs(struct statvfs *st); /* super.c */ int release_vol_pri_desc(struct iso9660_vol_pri_desc *v_pri); -int create_vol_pri_desc(struct iso9660_vol_pri_desc *v_pri, char *buf, - size_t address); int read_vds(struct iso9660_vol_pri_desc *v_pri, dev_t dev); /* susp.c */ @@ -77,16 +60,14 @@ int parse_susp(struct rrii_dir_record *dir, char *buffer); void parse_susp_buffer(struct rrii_dir_record *dir, char *buffer, u32_t size); /* susp_rock_ridge.c */ -void parse_susp_rock_ridge_sl(struct rrii_dir_record *dir, char *buffer, int length); +void parse_susp_rock_ridge_sl(struct rrii_dir_record *dir, char *buffer, + int length); int parse_susp_rock_ridge(struct rrii_dir_record *dir, char *buffer); /* utility.c */ -struct dir_extent* alloc_extent(); +struct dir_extent* alloc_extent(void); void free_extent(struct dir_extent *extent); struct buf* read_extent_block(struct dir_extent *e, size_t block); size_t get_extent_absolute_block_id(struct dir_extent *e, size_t block); time_t date7_to_time_t(const u8_t *date); -int do_noop(void); -int no_sys(void); - diff --git a/minix/fs/iso9660fs/read.c b/minix/fs/iso9660fs/read.c index d0e3b6406..30d2e42e3 100644 --- a/minix/fs/iso9660fs/read.c +++ b/minix/fs/iso9660fs/read.c @@ -1,168 +1,97 @@ #include "inc.h" -#include -#include -#include -#include -#include static char getdents_buf[GETDENTS_BUFSIZ]; -int fs_read(void) +ssize_t fs_read(ino_t ino_nr, struct fsdriver_data *data, size_t bytes, + off_t pos, int __unused call) { - int r = OK, chunk, block_size, completed, rw; - size_t nrbytes, off, cum_io; - cp_grant_id_t gid; - off_t position, f_size, bytes_left; + size_t off, chunk, block_size, cum_io; + off_t f_size; struct inode *i_node; - - switch(fs_m_in.m_type) { - case REQ_READ: rw = READING; break; - case REQ_PEEK: rw = PEEKING; break; - default: panic("odd m_type"); - } + struct buf *bp; + int r; /* Try to get inode according to its index. */ - i_node = find_inode(fs_m_in.m_vfs_fs_readwrite.inode); - if (i_node == NULL) + if ((i_node = find_inode(ino_nr)) == NULL) return EINVAL; /* No inode found. */ - position = fs_m_in.m_vfs_fs_readwrite.seek_pos; - nrbytes = fs_m_in.m_vfs_fs_readwrite.nbytes; /* Number of bytes to read. */ - block_size = v_pri.logical_block_size_l; - gid = fs_m_in.m_vfs_fs_readwrite.grant; - f_size = i_node->i_stat.st_size; - rdwt_err = OK; /* Set to EIO if disk error occurs. */ - cum_io = 0; - - /* Split the transfer into chunks that don't span two blocks. */ - while (nrbytes != 0) { - off = position % block_size; + f_size = i_node->i_stat.st_size; + if (pos >= f_size) + return 0; /* EOF */ - chunk = MIN(nrbytes, block_size - off); - if (chunk < 0) - chunk = block_size - off; + /* Limit the request to the remainder of the file size. */ + if ((off_t)bytes > f_size - pos) + bytes = (size_t)(f_size - pos); - bytes_left = f_size - position; - if (position >= f_size) - break; /* We are beyond EOF. */ - if (chunk > bytes_left) - chunk = (int32_t) bytes_left; - - /* Read or write 'chunk' bytes. */ - r = read_chunk(i_node, position, off, chunk, - (uint32_t) nrbytes, gid, cum_io, block_size, - &completed, rw); - - if (r != OK) - break; /* EOF reached. */ - if (rdwt_err < 0) - break; - - /* Update counters and pointers. */ - nrbytes -= chunk; /* Bytes yet to be read. */ - cum_io += chunk; /* Bytes read so far. */ - position += chunk; /* Position within the file. */ - } - - fs_m_out.m_fs_vfs_readwrite.seek_pos = position; - - if (rdwt_err != OK) - r = rdwt_err; /* Check for disk error. */ - if (rdwt_err == END_OF_FILE) - r = OK; - - fs_m_out.m_fs_vfs_readwrite.nbytes = cum_io; - return r; -} - -int fs_bread(void) -{ - int r = OK, rw_flag, chunk, block_size, completed; - size_t nrbytes, off, cum_io; - cp_grant_id_t gid; - off_t position; - struct inode *i_node; - - r = OK; - - rw_flag = (fs_m_in.m_type == REQ_BREAD ? READING : WRITING); - gid = fs_m_in.m_vfs_fs_breadwrite.grant; - position = fs_m_in.m_vfs_fs_breadwrite.seek_pos; - nrbytes = fs_m_in.m_vfs_fs_breadwrite.nbytes; block_size = v_pri.logical_block_size_l; - i_node = v_pri.inode_root; - - if(rw_flag == WRITING) - return EIO; /* Not supported */ + cum_io = 0; - rdwt_err = OK; /* set to EIO if disk error occurs */ + lmfs_reset_rdwt_err(); + r = OK; - cum_io = 0; /* Split the transfer into chunks that don't span two blocks. */ - while (nrbytes != 0) { - off = (unsigned int)(position % block_size); /* offset in blk*/ + while (bytes > 0) { + off = pos % block_size; - chunk = MIN(nrbytes, block_size - off); - if (chunk < 0) - chunk = block_size - off; + chunk = block_size - off; + if (chunk > bytes) + chunk = bytes; /* Read 'chunk' bytes. */ - r = read_chunk(i_node, position, off, chunk, (unsigned) nrbytes, - gid, cum_io, block_size, &completed, READING); + bp = read_extent_block(i_node->extent, pos / block_size); + if (bp == NULL) + panic("bp not valid in rw_chunk; this can't happen"); + + r = fsdriver_copyout(data, cum_io, b_data(bp)+off, chunk); + + lmfs_put_block(bp, FULL_DATA_BLOCK); if (r != OK) - break; /* EOF reached */ - if (rdwt_err < 0) + break; /* EOF reached. */ + if (lmfs_rdwt_err() < 0) break; /* Update counters and pointers. */ - nrbytes -= chunk; /* bytes yet to be read */ - cum_io += chunk; /* bytes read so far */ - position += chunk; /* position within the file */ + bytes -= chunk; /* Bytes yet to be read. */ + cum_io += chunk; /* Bytes read so far. */ + pos += chunk; /* Position within the file. */ } - fs_m_out.m_fs_vfs_breadwrite.seek_pos = position; - - if (rdwt_err != OK) - r = rdwt_err; /* check for disk error */ - if (rdwt_err == END_OF_FILE) + if (lmfs_rdwt_err() != OK) + r = lmfs_rdwt_err(); /* Check for disk error. */ + if (lmfs_rdwt_err() == END_OF_FILE) r = OK; - fs_m_out.m_fs_vfs_breadwrite.nbytes = cum_io; - - return r; + return (r == OK) ? cum_io : r; } -int fs_getdents(void) +ssize_t fs_getdents(ino_t ino_nr, struct fsdriver_data *data, size_t bytes, + off_t *pos) { + struct fsdriver_dentry fsdentry; struct inode *i_node, *i_node_tmp; - ino_t ino; - cp_grant_id_t gid; - size_t old_pos = 0, cur_pos, new_pos, tmpbuf_off = 0, userbuf_off = 0, grant_size; - struct dirent *dirp; - int r, len, reclen; + size_t cur_pos, new_pos; + int r, len; char *cp; - /* Get input parameters */ - ino = fs_m_in.m_vfs_fs_getdents.inode; - gid = fs_m_in.m_vfs_fs_getdents.grant; - cur_pos = fs_m_in.m_vfs_fs_getdents.seek_pos; - grant_size = fs_m_in.m_vfs_fs_getdents.mem_size; - - //memset(getdents_buf, '\0', GETDENTS_BUFSIZ); /* Avoid leaking any data */ + if ((i_node = find_inode(ino_nr)) == NULL) + return EINVAL; - if ((i_node = get_inode(ino)) == NULL) + if (*pos < 0 || *pos > SSIZE_MAX) return EINVAL; - while (TRUE) { + fsdriver_dentry_init(&fsdentry, data, bytes, getdents_buf, + sizeof(getdents_buf)); + + r = OK; + + for (cur_pos = (size_t)*pos; ; cur_pos = new_pos) { i_node_tmp = alloc_inode(); r = read_inode(i_node_tmp, i_node->extent, cur_pos, &new_pos); if ((r != OK) || (new_pos >= i_node->i_stat.st_size)) { - put_inode(i_node); put_inode(i_node_tmp); break; } - cur_pos = new_pos; /* Compute the length of the name */ cp = memchr(i_node_tmp->i_name, '\0', NAME_MAX); @@ -171,91 +100,18 @@ int fs_getdents(void) else len = cp - i_node_tmp->i_name; - /* Compute record length; also does alignment. */ - reclen = _DIRENT_RECLEN(dirp, len); - - /* If the new record does not fit, then copy the buffer - * and start from the beginning. */ - if (tmpbuf_off + reclen > GETDENTS_BUFSIZ || - userbuf_off + tmpbuf_off + reclen > grant_size) { - r = sys_safecopyto(VFS_PROC_NR, gid, userbuf_off, - (vir_bytes)getdents_buf, tmpbuf_off); - - if (r != OK) - panic("fs_getdents: sys_safecopyto failed: %d", r); - - /* Check if the user grant buffer is filled. */ - if (userbuf_off + tmpbuf_off + reclen > grant_size) { - fs_m_out.m_fs_vfs_getdents.nbytes = userbuf_off + tmpbuf_off; - fs_m_out.m_fs_vfs_getdents.seek_pos = old_pos; - return OK; - } - - userbuf_off += tmpbuf_off; - tmpbuf_off = 0; - } - - /* The standard data structure is created using the - * data in the buffer. */ - dirp = (struct dirent *) &getdents_buf[tmpbuf_off]; - dirp->d_fileno = i_node_tmp->i_stat.st_ino; - dirp->d_reclen = reclen; - dirp->d_type = fs_mode_to_type(i_node_tmp->i_stat.st_mode); - dirp->d_namlen = len; - - memcpy(dirp->d_name, i_node_tmp->i_name, len); - dirp->d_name[len]= '\0'; + r = fsdriver_dentry_add(&fsdentry, i_node_tmp->i_stat.st_ino, + i_node_tmp->i_name, len, + IFTODT(i_node_tmp->i_stat.st_mode)); - tmpbuf_off += reclen; put_inode(i_node_tmp); - old_pos = cur_pos; - } - - if (tmpbuf_off != 0) { - r = sys_safecopyto(VFS_PROC_NR, gid, userbuf_off, - (vir_bytes) getdents_buf, tmpbuf_off); - - if (r != OK) - panic("fs_getdents: sys_safecopyto failed: %d", r); - - userbuf_off += tmpbuf_off; + if (r <= 0) + break; } - fs_m_out.m_fs_vfs_getdents.nbytes = userbuf_off; - fs_m_out.m_fs_vfs_getdents.seek_pos = cur_pos; - - return OK; -} - -int read_chunk( -struct inode *i_node, /* pointer to inode for file to be rd/wr */ -u64_t position, /* position within file to read or write */ -unsigned off, /* off within the current block */ -int chunk, /* number of bytes to read or write */ -unsigned left, /* max number of bytes wanted after position */ -cp_grant_id_t gid, /* grant */ -unsigned buf_off, /* offset in grant */ -int block_size, /* block size of FS operating on */ -int *completed, /* number of bytes copied */ -int rw) /* READING or PEEKING */ -{ - struct buf *bp; - int r = OK; - - *completed = 0; + if (r >= 0 && (r = fsdriver_dentry_finish(&fsdentry)) >= 0) + *pos = cur_pos; - bp = read_extent_block(i_node->extent, position / block_size); - if (bp == NULL) - panic("bp not valid in rw_chunk; this can't happen"); - - if(rw == READING) { - r = sys_safecopyto(VFS_PROC_NR, gid, buf_off, - (vir_bytes) (b_data(bp)+off), - (phys_bytes) chunk); - } - - put_block(bp); return r; } - diff --git a/minix/fs/iso9660fs/stadir.c b/minix/fs/iso9660fs/stadir.c index 5ea10463d..1f1978608 100644 --- a/minix/fs/iso9660fs/stadir.c +++ b/minix/fs/iso9660fs/stadir.c @@ -1,46 +1,29 @@ #include "inc.h" -#include #include #include -#include -#include -#include -#include - -int fs_stat() +int fs_stat(ino_t ino_nr, struct stat *statbuf) { - int r = EINVAL; /* return value */ - struct inode *dir; + struct inode *rip; + + if ((rip = find_inode(ino_nr)) == NULL) + return EINVAL; - if ((dir = get_inode(fs_m_in.m_vfs_fs_stat.inode)) != NULL) { - r = sys_safecopyto(fs_m_in.m_source, fs_m_in.m_vfs_fs_stat.grant, - 0, (vir_bytes) &dir->i_stat, - (phys_bytes) sizeof(dir->i_stat)); - put_inode(dir); - } + *statbuf = rip->i_stat; - return r; + return OK; } -int fs_statvfs() +int fs_statvfs(struct statvfs *st) { - int r; - struct statvfs st; - - memset(&st, 0, sizeof(st)); - - st.f_bsize = v_pri.logical_block_size_l; - st.f_frsize = st.f_bsize; - st.f_iosize = st.f_bsize; - st.f_blocks = v_pri.volume_space_size_l; - st.f_namemax = NAME_MAX; - - /* Copy the struct to user space. */ - r = sys_safecopyto(fs_m_in.m_source, fs_m_in.m_vfs_fs_statvfs.grant, 0, - (vir_bytes) &st, (phys_bytes) sizeof(st)); - - return r; + st->f_flag = ST_NOTRUNC; + st->f_bsize = v_pri.logical_block_size_l; + st->f_frsize = st->f_bsize; + st->f_iosize = st->f_bsize; + st->f_blocks = v_pri.volume_space_size_l; + st->f_namemax = NAME_MAX; + + return OK; } void fs_blockstats(u64_t *blocks, u64_t *free, u64_t *used) @@ -48,4 +31,3 @@ void fs_blockstats(u64_t *blocks, u64_t *free, u64_t *used) *used = *blocks = v_pri.volume_space_size_l; *free = 0; } - diff --git a/minix/fs/iso9660fs/super.c b/minix/fs/iso9660fs/super.c index df5a37353..4d55c3027 100644 --- a/minix/fs/iso9660fs/super.c +++ b/minix/fs/iso9660fs/super.c @@ -21,8 +21,8 @@ int release_vol_pri_desc(struct iso9660_vol_pri_desc *vol_pri) return OK; } -int create_vol_pri_desc(struct iso9660_vol_pri_desc *vol_pri, char *buf, - size_t address) +static int create_vol_pri_desc(struct iso9660_vol_pri_desc *vol_pri, char *buf, + size_t __unused address) { /* * This function fullfill the super block data structure using the @@ -38,7 +38,8 @@ int create_vol_pri_desc(struct iso9660_vol_pri_desc *vol_pri, char *buf, memcpy(vol_pri, buf, 2048); /* Check various fields for consistency. */ - if ((memcmp(vol_pri->standard_id, "CD001", ISO9660_SIZE_STANDARD_ID) != 0) || + if ((memcmp(vol_pri->standard_id, "CD001", + ISO9660_SIZE_STANDARD_ID) != 0) || (vol_pri->vd_version != 1) || (vol_pri->logical_block_size_l < 2048) || (vol_pri->file_struct_ver != 1)) @@ -51,8 +52,10 @@ int create_vol_pri_desc(struct iso9660_vol_pri_desc *vol_pri, char *buf, root = alloc_inode(); extent = alloc_extent(); - extent->location = root_record->loc_extent_l + root_record->ext_attr_rec_length; - extent->length = root_record->data_length_l / vol_pri->logical_block_size_l; + extent->location = + root_record->loc_extent_l + root_record->ext_attr_rec_length; + extent->length = + root_record->data_length_l / vol_pri->logical_block_size_l; if (root_record->data_length_l % vol_pri->logical_block_size_l) extent->length++; @@ -72,8 +75,8 @@ int create_vol_pri_desc(struct iso9660_vol_pri_desc *vol_pri, char *buf, int read_vds(struct iso9660_vol_pri_desc *vol_pri, dev_t dev) { /* - * This function reads from a ISO9660 filesystem (in the device dev) the - * super block and saves it in vol_pri. + * This function reads from a ISO9660 filesystem (in the device dev) + * the super block and saves it in vol_pri. */ size_t offset; int vol_ok = FALSE, vol_pri_flag = FALSE; @@ -81,10 +84,12 @@ int read_vds(struct iso9660_vol_pri_desc *vol_pri, dev_t dev) static char sbbuf[ISO9660_MIN_BLOCK_SIZE]; int i = 0; - for(offset = ISO9660_SUPER_BLOCK_POSITION; !vol_ok && i++ < MAX_ATTEMPTS; + for(offset = ISO9660_SUPER_BLOCK_POSITION; + !vol_ok && i++ < MAX_ATTEMPTS; offset += ISO9660_MIN_BLOCK_SIZE) { /* Read the sector of the super block. */ - r = bdev_read(dev, offset, sbbuf, ISO9660_MIN_BLOCK_SIZE, BDEV_NOFLAGS); + r = bdev_read(dev, offset, sbbuf, ISO9660_MIN_BLOCK_SIZE, + BDEV_NOFLAGS); if (r != ISO9660_MIN_BLOCK_SIZE) { /* Damaged sector or what? */ @@ -109,4 +114,3 @@ int read_vds(struct iso9660_vol_pri_desc *vol_pri, dev_t dev) else return OK; /* otherwise. */ } - diff --git a/minix/fs/iso9660fs/susp.c b/minix/fs/iso9660fs/susp.c index 034f9d5ad..2556a7020 100644 --- a/minix/fs/iso9660fs/susp.c +++ b/minix/fs/iso9660fs/susp.c @@ -44,13 +44,13 @@ int parse_susp(struct rrii_dir_record *dir, char *buffer) ca_length = v_pri.logical_block_size_l - ca_offset; } - ca_bp = get_block(ca_block_nr); + ca_bp = lmfs_get_block(fs_dev, ca_block_nr, NORMAL); if (ca_bp == NULL) { return EINVAL; } parse_susp_buffer(dir, b_data(ca_bp) + ca_offset, ca_length); - put_block(ca_bp); + lmfs_put_block(ca_bp, FULL_DATA_BLOCK); return OK; } diff --git a/minix/fs/iso9660fs/table.c b/minix/fs/iso9660fs/table.c index 5a5cf1ba3..7f4d37756 100644 --- a/minix/fs/iso9660fs/table.c +++ b/minix/fs/iso9660fs/table.c @@ -8,40 +8,25 @@ #include "inc.h" -int (*fs_call_vec[])(void) = { - no_sys, /* 0: not used */ - no_sys, /* 1: not used */ - fs_putnode, /* 2 */ - no_sys, /* 3: not used */ - no_sys, /* 4: not used */ - no_sys, /* 5: not used */ - no_sys, /* 6: not used */ - do_noop, /* 7 */ - fs_stat, /* 8 */ - no_sys, /* 9: not used */ - fs_statvfs, /* 10 */ - fs_bread, /* 11 */ - no_sys, /* 12: not used */ - no_sys, /* 13: not used */ - no_sys, /* 14: not used */ - fs_unmount, /* 15 */ - fs_sync, /* 16 */ - fs_new_driver, /* 17 */ - no_sys, /* 18: not_used */ - fs_read, /* 19 */ - no_sys, /* 20: not used */ - no_sys, /* 21: not used */ - no_sys, /* 22: not used */ - no_sys, /* 23: not used */ - no_sys, /* 24: not used */ - no_sys, /* 25: not used */ - fs_lookup, /* 26 */ - fs_mountpoint, /* 27 */ - fs_readsuper, /* 28 */ - no_sys, /* 29: not used */ - fs_rdlink, /* 30 */ - fs_getdents, /* 31 */ - no_sys, /* 32 */ - no_sys, /* 33 */ -} ; - +struct fsdriver isofs_table = { + .fdr_mount = fs_mount, + .fdr_unmount = fs_unmount, + .fdr_lookup = fs_lookup, + .fdr_putnode = fs_putnode, + .fdr_read = fs_read, +#if 0 /* FIXME: isofs uses subpage block sizes */ + .fdr_peek = fs_read, +#endif + .fdr_getdents = fs_getdents, + .fdr_rdlink = fs_rdlink, + .fdr_stat = fs_stat, + .fdr_mountpt = fs_mountpt, + .fdr_statvfs = fs_statvfs, + .fdr_driver = lmfs_driver, + .fdr_bread = lmfs_bio, + .fdr_bwrite = lmfs_bio, +#if 0 /* FIXME: isofs uses subpage block sizes */ + .fdr_bpeek = lmfs_bio, +#endif + .fdr_bflush = lmfs_bflush +}; diff --git a/minix/fs/iso9660fs/utility.c b/minix/fs/iso9660fs/utility.c index 5a7e02407..e1729170c 100644 --- a/minix/fs/iso9660fs/utility.c +++ b/minix/fs/iso9660fs/utility.c @@ -1,13 +1,8 @@ #include "inc.h" -#include -#include -#include -#include -#include static struct dir_extent dir_extents[NR_DIR_EXTENT_RECORDS]; -struct dir_extent* alloc_extent() +struct dir_extent* alloc_extent(void) { /* Return a free extent from the pool. */ int i; @@ -46,7 +41,7 @@ struct buf* read_extent_block(struct dir_extent *e, size_t block) if (block_id == 0 || block_id >= v_pri.volume_space_size_l) return NULL; - return get_block(block_id); + return lmfs_get_block(fs_dev, block_id, NORMAL); } size_t get_extent_absolute_block_id(struct dir_extent *e, size_t block) @@ -70,7 +65,9 @@ size_t get_extent_absolute_block_id(struct dir_extent *e, size_t block) time_t date7_to_time_t(const u8_t *date) { - /* This function converts from the ISO 9660 7-byte time format to a time_t. */ + /* This function converts from the ISO 9660 7-byte time format to a + * time_t. + */ struct tm ltime; signed char time_zone = (signed char)date[6]; @@ -88,16 +85,3 @@ time_t date7_to_time_t(const u8_t *date) return mktime(<ime); } - -int do_noop(void) -{ - /* Do not do anything. */ - return OK; -} - -int no_sys(void) -{ - /* Somebody has used an illegal system call number */ - return EINVAL; -} -