From 32e916ad53e93a83366b144933d5a7340f3fdfbd Mon Sep 17 00:00:00 2001 From: Thomas Veerman Date: Mon, 25 Mar 2013 16:08:04 +0000 Subject: [PATCH] VFS: use 64-bit file offsets in all requests Change-Id: I735c4068135474aff2c397f4bc9fb147a618b453 --- include/minix/vfsif.h | 9 ++- servers/vfs/device.c | 4 +- servers/vfs/exec.c | 16 ++--- servers/vfs/file.h | 2 +- servers/vfs/filedes.c | 6 +- servers/vfs/lock.c | 6 +- servers/vfs/misc.c | 10 +-- servers/vfs/open.c | 105 +++++++++++------------------ servers/vfs/path.c | 4 +- servers/vfs/proto.h | 22 +++--- servers/vfs/read.c | 32 +++------ servers/vfs/request.c | 152 +++++++++++++++++++++++++++++------------- servers/vfs/select.c | 6 +- servers/vfs/table.c | 2 +- servers/vfs/vnode.h | 3 - 15 files changed, 193 insertions(+), 186 deletions(-) diff --git a/include/minix/vfsif.h b/include/minix/vfsif.h index e34f5c8de..8049917ec 100644 --- a/include/minix/vfsif.h +++ b/include/minix/vfsif.h @@ -58,12 +58,13 @@ #define RES_PROTO m9_s3 /* RES_PROTO is defined as follows: - * |----------------| - * 7V 4CR 0 - * 15 0 + * |--------------------------------| + * 8O7 V 4 CR 0 + * 15 0 * mentioned bits are inclusive * CR: bits 4-0 encode no. concurrent requests are supported by FS * V: bits 7-5 encode version of protocol + * O: bit 8 encodes support for 64-bit file offsets */ #define RES_PROTO_CR_SHIFT 0 #define RES_PROTO_CR_MASK 0x1F @@ -76,6 +77,8 @@ #define VFS_FS_PROTO_PUT_VERSION(b,v) \ ((b) |= (((v) << RES_PROTO_V_SHIFT) & RES_PROTO_V_MASK)) #define VFS_FS_CURRENT_VERSION 1 /* Current version */ +#define RES_PROTO_BIGOFFT_SHIFT 8 +#define VFS_FS_PROTO_BIGOFFT(b) (b & RES_PROTO_BIGOFFT_SHIFT) /* VFS/FS flags */ #define REQ_RDONLY 001 diff --git a/servers/vfs/device.c b/servers/vfs/device.c index ab42a2238..f0647bad3 100644 --- a/servers/vfs/device.c +++ b/servers/vfs/device.c @@ -395,7 +395,7 @@ int dev_io( dev_t dev, /* major-minor device number */ endpoint_t proc_e, /* in whose address space is buf? */ void *buf, /* virtual address of the buffer */ - u64_t pos, /* byte position */ + off_t pos, /* byte position */ size_t bytes, /* how many bytes to transfer */ int flags, /* special flags, like O_NONBLOCK */ int suspend_reopen /* Just suspend the process */ @@ -680,7 +680,7 @@ int do_ioctl(message *UNUSED(m_out)) if (S_ISBLK(vp->v_mode)) r = bdev_ioctl(dev, who_e, ioctlrequest, argx); else - r = dev_io(VFS_DEV_IOCTL, dev, who_e, argx, ((u64_t)(0)), + r = dev_io(VFS_DEV_IOCTL, dev, who_e, argx, 0, ioctlrequest, f->filp_flags, suspend_reopen); } diff --git a/servers/vfs/exec.c b/servers/vfs/exec.c index c936c6bf2..e72fe6bae 100644 --- a/servers/vfs/exec.c +++ b/servers/vfs/exec.c @@ -558,9 +558,8 @@ char path[PATH_MAX]; /* path to script file */ */ enum { INSERT=FALSE, REPLACE=TRUE }; int n, r; - off_t pos; + off_t pos, new_pos; char *sp, *interp = NULL; - u64_t new_pos; unsigned int cum_io; char buf[_MAX_BLOCK_SIZE]; @@ -570,8 +569,8 @@ char path[PATH_MAX]; /* path to script file */ pos = 0; /* Read from the start of the file */ /* Issue request */ - r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, ((u64_t)(pos)), READING, - VFS_PROC_NR, (vir_bytes) buf, _MAX_BLOCK_SIZE, &new_pos, &cum_io); + r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, pos, READING, VFS_PROC_NR, + (vir_bytes) buf, _MAX_BLOCK_SIZE, &new_pos, &cum_io); if (r != OK) return(r); n = vp->v_size; @@ -687,7 +686,7 @@ static int read_seg(struct exec_info *execi, off_t off, vir_bytes seg_addr, size * partially initialized. */ int r; - u64_t new_pos; + off_t new_pos; unsigned int cum_io; struct vnode *vp = ((struct vfs_exec_info *) execi->opaque)->vp; @@ -695,7 +694,7 @@ static int read_seg(struct exec_info *execi, off_t off, vir_bytes seg_addr, size if (off + seg_bytes > LONG_MAX) return(EIO); if ((unsigned long) vp->v_size < off+seg_bytes) return(EIO); - if ((r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, ((u64_t)(off)), READING, + if ((r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, off, READING, execi->proc_e, (vir_bytes) seg_addr, seg_bytes, &new_pos, &cum_io)) != OK) { printf("VFS: read_seg: req_readwrite failed (data)\n"); @@ -730,9 +729,8 @@ static void clo_exec(struct fproc *rfp) static int map_header(struct vfs_exec_info *execi) { int r; - u64_t new_pos; unsigned int cum_io; - off_t pos; + off_t pos, new_pos; static char hdr[PAGE_SIZE]; /* Assume that header is not larger than a page */ pos = 0; /* Read from the start of the file */ @@ -742,7 +740,7 @@ static int map_header(struct vfs_exec_info *execi) execi->args.hdr = hdr; r = req_readwrite(execi->vp->v_fs_e, execi->vp->v_inode_nr, - ((u64_t)(pos)), READING, VFS_PROC_NR, (vir_bytes) hdr, + pos, READING, VFS_PROC_NR, (vir_bytes) hdr, execi->args.hdr_len, &new_pos, &cum_io); if (r != OK) { printf("VFS: exec: map_header: req_readwrite failed\n"); diff --git a/servers/vfs/file.h b/servers/vfs/file.h index f28001249..fcb575c5a 100644 --- a/servers/vfs/file.h +++ b/servers/vfs/file.h @@ -11,7 +11,7 @@ EXTERN struct filp { int filp_state; /* state for crash recovery */ int filp_count; /* how many file descriptors share this slot?*/ struct vnode *filp_vno; /* vnode belonging to this file */ - u64_t filp_pos; /* file position */ + off_t filp_pos; /* file position */ mutex_t filp_lock; /* lock to gain exclusive access */ struct fproc *filp_softlock; /* if not NULL; this filp didn't lock the * vnode. Another filp already holds a lock diff --git a/servers/vfs/filedes.c b/servers/vfs/filedes.c index c8c5f4c77..9ba0c0bd7 100644 --- a/servers/vfs/filedes.c +++ b/servers/vfs/filedes.c @@ -177,7 +177,7 @@ int get_fd(struct fproc *rfp, int start, mode_t bits, int *k, struct filp **fpt) assert(f->filp_count >= 0); if (f->filp_count == 0 && mutex_trylock(&f->filp_lock) == 0) { f->filp_mode = bits; - f->filp_pos = ((u64_t)(0)); + f->filp_pos = 0; f->filp_selectors = 0; f->filp_select_ops = 0; f->filp_pipe_select_ops = 0; @@ -673,8 +673,8 @@ struct filp *f; f->filp_mode = FILP_CLOSED; f->filp_count = 0; } else if (f->filp_count < 0) { - panic("VFS: invalid filp count: %d ino %d/%u", - (int) f->filp_count, (int) vp->v_dev, (unsigned int) vp->v_inode_nr); + panic("VFS: invalid filp count: %d ino %d/%llu", f->filp_count, + vp->v_dev, vp->v_inode_nr); } else { unlock_vnode(f->filp_vno); } diff --git a/servers/vfs/lock.c b/servers/vfs/lock.c index d113faa93..8d9e9ae6b 100644 --- a/servers/vfs/lock.c +++ b/servers/vfs/lock.c @@ -66,11 +66,7 @@ int req; /* either F_SETLK or F_SETLKW */ /* Compute the first and last bytes in the lock region. */ switch (flock.l_whence) { case SEEK_SET: first = 0; break; - case SEEK_CUR: - if (ex64hi(f->filp_pos) != 0) - panic("lock_op: position in file too high"); - first = ex64lo(f->filp_pos); - break; + case SEEK_CUR: first = f->filp_pos; break; case SEEK_END: first = f->filp_vno->v_size; break; default: return(EINVAL); } diff --git a/servers/vfs/misc.c b/servers/vfs/misc.c index aab889d68..f557bd5e8 100644 --- a/servers/vfs/misc.c +++ b/servers/vfs/misc.c @@ -213,11 +213,7 @@ int do_fcntl(message *UNUSED(m_out)) /* Figure out starting position base. */ switch(flock_arg.l_whence) { case SEEK_SET: start = 0; break; - case SEEK_CUR: - if (ex64hi(f->filp_pos) != 0) - panic("do_fcntl: position in file too high"); - start = ex64lo(f->filp_pos); - break; + case SEEK_CUR: start = f->filp_pos; break; case SEEK_END: start = f->filp_vno->v_size; break; default: r = EINVAL; } @@ -352,8 +348,8 @@ int dupvm(struct fproc *rfp, int pfd, int *vmfd, struct filp **newfilp) assert(f->filp_vno->v_vmnt); if (!S_ISREG(f->filp_vno->v_mode) && !S_ISBLK(f->filp_vno->v_mode)) { - printf("VFS: mmap regular/blockdev only; dev 0x%x ino %d has mode 0%o\n", - (int) f->filp_vno->v_dev, (int) f->filp_vno->v_inode_nr, (int) f->filp_vno->v_mode); + printf("VFS: mmap regular/blockdev only; dev 0x%x ino %llu has mode 0%o\n", + f->filp_vno->v_dev, f->filp_vno->v_inode_nr, f->filp_vno->v_mode); unlock_filp(f); return EINVAL; } diff --git a/servers/vfs/open.c b/servers/vfs/open.c index e4c5a1a99..769687ed2 100644 --- a/servers/vfs/open.c +++ b/servers/vfs/open.c @@ -591,17 +591,20 @@ int do_mkdir(message *UNUSED(m_out)) } /*===========================================================================* - * actual_lseek * + * actual_llseek * *===========================================================================*/ -int actual_lseek(message *m_out, int seekfd, int seekwhence, off_t offset) +int actual_llseek(struct fproc *rfp, message *m_out, int seekfd, int seekwhence, + off_t offset) { -/* Perform the lseek(ls_fd, offset, whence) system call. */ +/* Perform the llseek(ls_fd, offset, whence) system call. */ register struct filp *rfilp; int r = OK; - u64_t pos, newpos; + off_t pos, newpos; /* Check to see if the file descriptor is valid. */ - if ( (rfilp = get_filp(seekfd, VNODE_READ)) == NULL) return(err_code); + if ( (rfilp = get_filp2(rfp, seekfd, VNODE_READ)) == NULL) { + return(err_code); + } /* No lseek on pipes. */ if (S_ISFIFO(rfilp->filp_vno->v_mode)) { @@ -611,22 +614,25 @@ int actual_lseek(message *m_out, int seekfd, int seekwhence, off_t offset) /* The value of 'whence' determines the start position to use. */ switch(seekwhence) { - case SEEK_SET: pos = ((u64_t)(0)); break; - case SEEK_CUR: pos = rfilp->filp_pos; break; - case SEEK_END: pos = ((u64_t)(rfilp->filp_vno->v_size)); break; + case SEEK_SET: pos = 0; break; + case SEEK_CUR: pos = rfilp->filp_pos; break; + case SEEK_END: pos = rfilp->filp_vno->v_size; break; default: unlock_filp(rfilp); return(EINVAL); } - if (offset < 0 && -offset > pos) { /* no negative file size */ + newpos = pos + offset; + + /* Check for overflow. */ + if ((offset > 0) && (newpos <= pos)) { + r = EOVERFLOW; + } else if ((offset < 0) && (newpos >= pos)) { r = EOVERFLOW; } else { - newpos = pos + offset; - /* insert the new position into the output message */ m_out->reply_l1 = ex64lo(newpos); m_out->reply_l2 = ex64hi(newpos); - if (cmp64(newpos, rfilp->filp_pos) != 0) { + if (newpos != rfilp->filp_pos) { rfilp->filp_pos = newpos; /* Inhibit read ahead request */ @@ -640,70 +646,35 @@ int actual_lseek(message *m_out, int seekfd, int seekwhence, off_t offset) } /*===========================================================================* - * do_lseek * + * do_lseek_321 * *===========================================================================*/ -int do_lseek(message *m_out) +int do_lseek_321(message *m_out) { - return actual_lseek(m_out, job_m_in.ls_fd, job_m_in.whence, - (off_t) job_m_in.offset_lo); + int r; + + r = actual_llseek(fp, m_out, job_m_in.ls_fd, job_m_in.whence, + make64(job_m_in.offset_lo, 0)); + + /* check value is 32bit */ + if (m_out->reply_l2 != 0) { + r = EOVERFLOW; + } + + return r; } /*===========================================================================* - * actual_llseek * + * do_lseek * *===========================================================================*/ -int actual_llseek(struct fproc *rfp, message *m_out, int seekfd, int seekwhence, - u64_t offset) +int do_lseek(message *m_out) { -/* Perform the llseek(ls_fd, offset, whence) system call. */ - register struct filp *rfilp; - u64_t pos, newpos; - int r = OK; - long off_hi = ex64hi(offset); - - /* Check to see if the file descriptor is valid. */ - if ( (rfilp = get_filp2(rfp, seekfd, VNODE_READ)) == NULL) { - return(err_code); - } - - /* No lseek on pipes. */ - if (S_ISFIFO(rfilp->filp_vno->v_mode)) { - unlock_filp(rfilp); - return(ESPIPE); - } - - /* The value of 'whence' determines the start position to use. */ - switch(seekwhence) { - case SEEK_SET: pos = ((u64_t)(0)); break; - case SEEK_CUR: pos = rfilp->filp_pos; break; - case SEEK_END: pos = ((u64_t)(rfilp->filp_vno->v_size)); break; - default: unlock_filp(rfilp); return(EINVAL); - } - - newpos = pos + offset; - - /* Check for overflow. */ - if ((off_hi > 0) && cmp64(newpos, pos) < 0) - r = EINVAL; - else if ((off_hi < 0) && cmp64(newpos, pos) > 0) - r = EINVAL; - else { - /* insert the new position into the output message */ - m_out->reply_l1 = ex64lo(newpos); - m_out->reply_l2 = ex64hi(newpos); - - if (cmp64(newpos, rfilp->filp_pos) != 0) { - rfilp->filp_pos = newpos; - - /* Inhibit read ahead request */ - r = req_inhibread(rfilp->filp_vno->v_fs_e, - rfilp->filp_vno->v_inode_nr); - } - } - - unlock_filp(rfilp); - return(r); + return actual_llseek(fp, m_out, job_m_in.ls_fd, job_m_in.whence, + make64(job_m_in.offset_lo, job_m_in.offset_high)); } +/*===========================================================================* + * do_llseek * + *===========================================================================*/ int do_llseek(message *m_out) { return actual_llseek(fp, m_out, job_m_in.ls_fd, job_m_in.whence, diff --git a/servers/vfs/path.c b/servers/vfs/path.c index cf187199e..00acb6def 100644 --- a/servers/vfs/path.c +++ b/servers/vfs/path.c @@ -615,12 +615,12 @@ char ename[NAME_MAX + 1]; { #define DIR_ENTRIES 8 #define DIR_ENTRY_SIZE (sizeof(struct dirent) + NAME_MAX) - u64_t pos, new_pos; + off_t pos, new_pos; int r, consumed, totalbytes, name_len; char buf[DIR_ENTRY_SIZE * DIR_ENTRIES]; struct dirent *cur; - pos = make64(0, 0); + pos = 0; if (!S_ISDIR(dirp->v_mode)) return(EBADF); diff --git a/servers/vfs/proto.h b/servers/vfs/proto.h index b94b2d9ec..1aa35123e 100644 --- a/servers/vfs/proto.h +++ b/servers/vfs/proto.h @@ -35,7 +35,7 @@ void dev_reply(struct dmap *dp); int dev_close(dev_t dev, int filp_no); int bdev_open(dev_t dev, int access); int bdev_close(dev_t dev); -int dev_io(int op, dev_t dev, endpoint_t proc_e, void *buf, u64_t pos, +int dev_io(int op, dev_t dev, endpoint_t proc_e, void *buf, off_t pos, size_t bytes, int flags, int suspend_reopen); int gen_opcl(int op, dev_t dev, endpoint_t task_nr, int flags); int gen_io(endpoint_t driver_e, message *mess_ptr); @@ -167,7 +167,7 @@ void close_reply(void); int common_open(char path[PATH_MAX], int oflags, mode_t omode); int do_creat(void); int do_lseek(message *m_out); -int do_lseek321(message *m_out); +int do_lseek_321(message *m_out); int do_llseek(message *m_out); int do_mknod(message *m_out); int do_mkdir(message *m_out); @@ -175,7 +175,7 @@ int do_open(message *m_out); int do_slink(message *m_out); int actual_lseek(message *m_out, int seekfd, int seekwhence, off_t offset); int actual_llseek(struct fproc *rfp, message *m_out, int seekfd, - int seekwhence, u64_t offset); + int seekwhence, off_t offset); int do_vm_open(void); int do_vm_close(void); @@ -228,9 +228,9 @@ int rw_pipe(int rw_flag, endpoint_t usr, struct filp *f, char *buf, size_t req_size); /* request.c */ -int req_breadwrite(endpoint_t fs_e, endpoint_t user_e, dev_t dev, u64_t pos, +int req_breadwrite(endpoint_t fs_e, endpoint_t user_e, dev_t dev, off_t pos, unsigned int num_of_bytes, vir_bytes user_addr, int rw_flag, - u64_t *new_posp, unsigned int *cum_iop); + off_t *new_posp, unsigned int *cum_iop); int req_chmod(endpoint_t fs_e, ino_t inode_nr, mode_t rmode, mode_t *new_modep); int req_chown(endpoint_t fs_e, ino_t inode_nr, uid_t newuid, gid_t newgid, @@ -241,8 +241,8 @@ int req_flush(endpoint_t fs_e, dev_t dev); int req_fstatfs(endpoint_t fs_e, endpoint_t proc_e, vir_bytes buf); int req_statvfs(endpoint_t fs_e, endpoint_t proc_e, vir_bytes buf); int req_ftrunc(endpoint_t fs_e, ino_t inode_nr, off_t start, off_t end); -int req_getdents(endpoint_t fs_e, ino_t inode_nr, u64_t pos, char *buf, - size_t size, u64_t *new_pos, int direct, int getdents_321); +int req_getdents(endpoint_t fs_e, ino_t inode_nr, off_t pos, char *buf, + size_t size, off_t *new_pos, int direct, int getdents_321); int req_inhibread(endpoint_t fs_e, ino_t inode_nr); int req_link(endpoint_t fs_e, ino_t link_parent, char *lastc, ino_t linked_file); @@ -261,11 +261,11 @@ int req_rdlink(endpoint_t fs_e, ino_t inode_nr, endpoint_t proc_e, vir_bytes buf, size_t len, int direct); int req_readsuper(struct vmnt *vmp, char *driver_name, dev_t dev, int readonly, int isroot, struct node_details *res_nodep); -int req_readwrite(endpoint_t fs_e, ino_t inode_nr, u64_t pos, int rw_flag, +int req_readwrite(endpoint_t fs_e, ino_t inode_nr, off_t pos, int rw_flag, endpoint_t user_e, vir_bytes user_addr, unsigned int num_of_bytes, - u64_t *new_posp, unsigned int *cum_iop); -int req_bpeek(endpoint_t fs_e, dev_t dev, u64_t pos, unsigned int num_of_bytes); -int req_peek(endpoint_t fs_e, ino_t inode_nr, u64_t pos, unsigned int bytes); + off_t *new_posp, unsigned int *cum_iop); +int req_bpeek(endpoint_t fs_e, dev_t dev, off_t pos, unsigned int num_of_bytes); +int req_peek(endpoint_t fs_e, ino_t inode_nr, off_t pos, unsigned int bytes); int req_rename(endpoint_t fs_e, ino_t old_dir, char *old_name, ino_t new_dir, char *new_name); int req_rmdir(endpoint_t fs_e, ino_t inode_nr, char *lastc); diff --git a/servers/vfs/read.c b/servers/vfs/read.c index 09adbcae9..40f14fcdf 100644 --- a/servers/vfs/read.c +++ b/servers/vfs/read.c @@ -138,7 +138,7 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f, char *buf, size_t size, endpoint_t for_e) { register struct vnode *vp; - u64_t position, res_pos; + off_t position, res_pos; unsigned int cum_io, cum_io_incr, res_cum_io; int op, r; @@ -182,7 +182,7 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f, suspend_reopen); if (r >= 0) { cum_io = r; - position += r; + position += cum_io; r = OK; } } else if (S_ISBLK(vp->v_mode)) { /* Block special files. */ @@ -206,22 +206,19 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f, } else { /* Regular files */ if (rw_flag == WRITING) { /* Check for O_APPEND flag. */ - if (f->filp_flags & O_APPEND) position = ((u64_t)(vp->v_size)); + if (f->filp_flags & O_APPEND) position = vp->v_size; } /* Issue request */ if(rw_flag == PEEKING) { r = req_peek(vp->v_fs_e, vp->v_inode_nr, position, size); } else { - u64_t new_pos; + off_t new_pos; r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, position, rw_flag, for_e, (vir_bytes) buf, size, &new_pos, &cum_io_incr); if (r >= 0) { - if (ex64hi(new_pos)) - panic("read_write: bad new pos"); - position = new_pos; cum_io += cum_io_incr; } @@ -231,11 +228,8 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f, /* On write, update file size and access time. */ if (rw_flag == WRITING) { if (S_ISREG(vp->v_mode) || S_ISDIR(vp->v_mode)) { - if (cmp64ul(position, vp->v_size) > 0) { - if (ex64hi(position) != 0) { - panic("read_write: file size too big "); - } - vp->v_size = ex64lo(position); + if (position > vp->v_size) { + vp->v_size = position; } } } @@ -264,7 +258,7 @@ int do_getdents(message *UNUSED(m_out)) { /* Perform the getdents(fd, buf, size) system call. */ int r = OK, getdents_321 = 0; - u64_t new_pos; + off_t new_pos; register struct filp *rfilp; if (job_call_nr == GETDENTS_321) getdents_321 = 1; @@ -282,9 +276,6 @@ int do_getdents(message *UNUSED(m_out)) r = EBADF; if (r == OK) { - if (ex64hi(rfilp->filp_pos) != 0) - panic("do_getdents: can't handle large offsets"); - r = req_getdents(rfilp->filp_vno->v_fs_e, rfilp->filp_vno->v_inode_nr, rfilp->filp_pos, scratch(fp).io.io_buffer, scratch(fp).io.io_nbytes, &new_pos, 0, getdents_321); @@ -310,7 +301,7 @@ size_t req_size; int r, oflags, partial_pipe = 0; size_t size, cum_io, cum_io_incr; struct vnode *vp; - u64_t position, new_pos; + off_t position, new_pos; /* Must make sure we're operating on locked filp and vnode */ assert(tll_locked_by_me(&f->filp_vno->v_lock)); @@ -318,7 +309,7 @@ size_t req_size; oflags = f->filp_flags; vp = f->filp_vno; - position = ((u64_t)(0)); /* Not actually used */ + position = 0; /* Not actually used */ assert(rw_flag == READING || rw_flag == WRITING); @@ -349,14 +340,11 @@ size_t req_size; return(r); } - if (ex64hi(new_pos)) - panic("rw_pipe: bad new pos"); - cum_io += cum_io_incr; buf += cum_io_incr; req_size -= cum_io_incr; - vp->v_size = ex64lo(new_pos); + vp->v_size = new_pos; if (partial_pipe) { /* partial write on pipe with */ diff --git a/servers/vfs/request.c b/servers/vfs/request.c index 1713f8772..355516ace 100644 --- a/servers/vfs/request.c +++ b/servers/vfs/request.c @@ -36,11 +36,11 @@ int req_breadwrite( endpoint_t fs_e, endpoint_t user_e, dev_t dev, - u64_t pos, + off_t pos, unsigned int num_of_bytes, vir_bytes user_addr, int rw_flag, - u64_t *new_posp, + off_t *new_pos, unsigned int *cum_iop ) { @@ -67,7 +67,7 @@ int req_breadwrite( if (r != OK) return(r); /* Fill in response structure */ - *new_posp = make64(m.RES_SEEK_POS_LO, m.RES_SEEK_POS_HI); + *new_pos = make64(m.RES_SEEK_POS_LO, m.RES_SEEK_POS_HI); *cum_iop = m.RES_NBYTES; return(OK); @@ -76,7 +76,7 @@ int req_breadwrite( /*===========================================================================* * req_bpeek * *===========================================================================*/ -int req_bpeek(endpoint_t fs_e, dev_t dev, u64_t pos, unsigned int num_of_bytes) +int req_bpeek(endpoint_t fs_e, dev_t dev, off_t pos, unsigned int num_of_bytes) { message m; @@ -91,8 +91,6 @@ int req_bpeek(endpoint_t fs_e, dev_t dev, u64_t pos, unsigned int num_of_bytes) /* Send/rec request */ return fs_sendrec(fs_e, &m); - - return(OK); } /*===========================================================================* @@ -170,9 +168,9 @@ int req_create( cp_grant_id_t grant_id; size_t len; message m; + struct vmnt *vmp; - if (path[0] == '/') - panic("req_create: filename starts with '/'"); + vmp = find_vmnt(fs_e); len = strlen(path) + 1; grant_id = cpf_grant_direct(fs_e, (vir_bytes) path, len, CPF_READ); @@ -197,7 +195,11 @@ int req_create( res->fs_e = m.m_source; res->inode_nr = (ino_t) m.RES_INODE_NR; res->fmode = (mode_t) m.RES_MODE; - res->fsize = m.RES_FILE_SIZE_LO; + if (VFS_FS_PROTO_BIGOFFT(vmp->m_proto)) { + res->fsize = make64(m.RES_FILE_SIZE_LO, m.RES_FILE_SIZE_HI); + } else { + res->fsize = m.RES_FILE_SIZE_LO; + } res->uid = (uid_t) m.RES_UID; res->gid = (gid_t) m.RES_GID; res->dev = NO_DEV; @@ -280,14 +282,33 @@ int req_statvfs(endpoint_t fs_e, endpoint_t proc_e, vir_bytes buf) int req_ftrunc(endpoint_t fs_e, ino_t inode_nr, off_t start, off_t end) { message m; + struct vmnt *vmp; + + vmp = find_vmnt(fs_e); /* Fill in request message */ m.m_type = REQ_FTRUNC; m.REQ_INODE_NR = (pino_t) inode_nr; - m.REQ_TRC_START_LO = start; - m.REQ_TRC_START_HI = 0; /* Not used for now, so clear it. */ - m.REQ_TRC_END_LO = end; - m.REQ_TRC_END_HI = 0; /* Not used for now, so clear it. */ + + m.REQ_TRC_START_LO = ex64lo(start); + if (VFS_FS_PROTO_BIGOFFT(vmp->m_proto)) { + m.REQ_TRC_START_HI = ex64hi(start); + } else if (start > INT_MAX) { + /* FS does not support 64-bit off_t and 32 bits is not enough */ + return EINVAL; + } else { + m.REQ_TRC_START_HI = 0; + } + + m.REQ_TRC_END_LO = ex64lo(end); + if (VFS_FS_PROTO_BIGOFFT(vmp->m_proto)) { + m.REQ_TRC_END_HI = ex64hi(end); + } else if (end > INT_MAX) { + /* FS does not support 64-bit off_t and 32 bits is not enough */ + return EINVAL; + } else { + m.REQ_TRC_END_HI = 0; + } /* Send/rec request */ return fs_sendrec(fs_e, &m); @@ -300,10 +321,10 @@ int req_ftrunc(endpoint_t fs_e, ino_t inode_nr, off_t start, off_t end) int req_getdents( endpoint_t fs_e, ino_t inode_nr, - u64_t pos, + off_t pos, char *buf, size_t size, - u64_t *new_pos, + off_t *new_pos, int direct, int getdents_321 /* Set to 1 if user land expects old format */ ) @@ -374,7 +395,16 @@ int req_getdents( m.REQ_GRANT = grant_id; m.REQ_MEM_SIZE = size; m.REQ_SEEK_POS_LO = ex64lo(pos); - m.REQ_SEEK_POS_HI = 0; /* Not used for now, so clear it. */ + if (VFS_FS_PROTO_BIGOFFT(vmp->m_proto)) { + m.REQ_SEEK_POS_HI = ex64hi(pos); + } else if (pos > INT_MAX) { + /* FS does not support 64-bit off_t and 32 bits is not enough */ + if (indir_buf_src != NULL) free(indir_buf_src); + if (indir_buf_dst != NULL) free(indir_buf_dst); + return EINVAL; + } else { + m.REQ_SEEK_POS_HI = 0; + } r = fs_sendrec(fs_e, &m); cpf_revoke(grant_id); @@ -395,7 +425,11 @@ int req_getdents( } if (r == OK) { - *new_pos = ((u64_t)(m.RES_SEEK_POS_LO)); + if (VFS_FS_PROTO_BIGOFFT(vmp->m_proto)) { + *new_pos = make64(m.RES_SEEK_POS_LO, m.RES_SEEK_POS_HI); + } else { + *new_pos = m.RES_SEEK_POS_LO; + } r = m.RES_NBYTES; } @@ -521,12 +555,14 @@ int req_lookup( struct fproc *rfp ) { - int r; - size_t len; - cp_grant_id_t grant_id=0, grant_id2=0; message m; vfs_ucred_t credentials; - int flags; + int r, flags; + size_t len; + struct vmnt *vmp; + cp_grant_id_t grant_id=0, grant_id2=0; + + vmp = find_vmnt(fs_e); grant_id = cpf_grant_direct(fs_e, (vir_bytes) resolve->l_path, PATH_MAX, CPF_READ | CPF_WRITE); @@ -583,7 +619,11 @@ int req_lookup( case OK: res->inode_nr = (ino_t) m.RES_INODE_NR; res->fmode = (mode_t) m.RES_MODE; - res->fsize = m.RES_FILE_SIZE_LO; + if (VFS_FS_PROTO_BIGOFFT(vmp->m_proto)) { + res->fsize = make64(m.RES_FILE_SIZE_LO, m.RES_FILE_SIZE_HI); + } else { + res->fsize = m.RES_FILE_SIZE_LO; + } res->dev = m.RES_DEV; res->uid = (uid_t) m.RES_UID; res->gid = (gid_t) m.RES_GID; @@ -717,9 +757,12 @@ int req_newnode( struct node_details *res ) { + struct vmnt *vmp; int r; message m; + vmp = find_vmnt(fs_e); + /* Fill in request message */ m.m_type = REQ_NEWNODE; m.REQ_MODE = (pmode_t) dmode; @@ -733,7 +776,11 @@ int req_newnode( res->fs_e = m.m_source; res->inode_nr = (ino_t) m.RES_INODE_NR; res->fmode = (mode_t) m.RES_MODE; - res->fsize = m.RES_FILE_SIZE_LO; + if (VFS_FS_PROTO_BIGOFFT(vmp->m_proto)) { + res->fsize = make64(m.RES_FILE_SIZE_LO, m.RES_FILE_SIZE_HI); + } else { + res->fsize = m.RES_FILE_SIZE_LO; + } res->dev = m.RES_DEV; res->uid = (uid_t) m.RES_UID; res->gid = (gid_t) m.RES_GID; @@ -845,7 +892,7 @@ int req_readsuper( dev_t dev, int readonly, int isroot, - struct node_details *res_nodep + struct node_details *res ) { int r; @@ -879,13 +926,17 @@ int req_readsuper( if(r == OK) { /* Fill in response structure */ - res_nodep->fs_e = m.m_source; - res_nodep->inode_nr = (ino_t) m.RES_INODE_NR; + res->fs_e = m.m_source; + res->inode_nr = (ino_t) m.RES_INODE_NR; vmp->m_proto = m.RES_PROTO; - res_nodep->fmode = (mode_t) m.RES_MODE; - res_nodep->fsize = m.RES_FILE_SIZE_LO; - res_nodep->uid = (uid_t) m.RES_UID; - res_nodep->gid = (gid_t) m.RES_GID; + res->fmode = (mode_t) m.RES_MODE; + if (VFS_FS_PROTO_BIGOFFT(vmp->m_proto)) { + res->fsize = make64(m.RES_FILE_SIZE_LO, m.RES_FILE_SIZE_HI); + } else { + res->fsize = m.RES_FILE_SIZE_LO; + } + res->uid = (uid_t) m.RES_UID; + res->gid = (gid_t) m.RES_GID; } return(r); @@ -895,24 +946,23 @@ int req_readsuper( /*===========================================================================* * req_readwrite * *===========================================================================*/ -int req_readwrite(fs_e, inode_nr, pos, rw_flag, user_e, - user_addr, num_of_bytes, new_posp, cum_iop) -endpoint_t fs_e; -ino_t inode_nr; -u64_t pos; -int rw_flag; -endpoint_t user_e; -vir_bytes user_addr; -unsigned int num_of_bytes; -u64_t *new_posp; -unsigned int *cum_iop; +int req_readwrite( +endpoint_t fs_e, +ino_t inode_nr, +off_t pos, +int rw_flag, +endpoint_t user_e, +vir_bytes user_addr, +unsigned int num_of_bytes, +off_t *new_posp, +unsigned int *cum_iop) { + struct vmnt *vmp; int r; cp_grant_id_t grant_id; message m; - if (ex64hi(pos) != 0) - panic("req_readwrite: pos too large"); + vmp = find_vmnt(fs_e); grant_id = cpf_grant_magic(fs_e, user_e, user_addr, num_of_bytes, (rw_flag==READING ? CPF_WRITE:CPF_READ)); @@ -924,7 +974,13 @@ unsigned int *cum_iop; m.REQ_INODE_NR = (pino_t) inode_nr; m.REQ_GRANT = grant_id; m.REQ_SEEK_POS_LO = ex64lo(pos); - m.REQ_SEEK_POS_HI = 0; /* Not used for now, so clear it. */ + if (VFS_FS_PROTO_BIGOFFT(vmp->m_proto)) { + m.REQ_SEEK_POS_HI = ex64hi(pos); + } else if (pos > INT_MAX) { + return EINVAL; + } else { + m.REQ_SEEK_POS_HI = 0; + } m.REQ_NBYTES = num_of_bytes; /* Send/rec request */ @@ -933,7 +989,11 @@ unsigned int *cum_iop; if (r == OK) { /* Fill in response structure */ - *new_posp = ((u64_t)(m.RES_SEEK_POS_LO)); + if (VFS_FS_PROTO_BIGOFFT(vmp->m_proto)) { + *new_posp = make64(m.RES_SEEK_POS_LO, m.RES_SEEK_POS_HI); + } else { + *new_posp = m.RES_SEEK_POS_LO; + } *cum_iop = m.RES_NBYTES; } @@ -943,7 +1003,7 @@ unsigned int *cum_iop; /*===========================================================================* * req_peek * *===========================================================================*/ -int req_peek(endpoint_t fs_e, ino_t inode_nr, u64_t pos, unsigned int bytes) +int req_peek(endpoint_t fs_e, ino_t inode_nr, off_t pos, unsigned int bytes) { message m; diff --git a/servers/vfs/select.c b/servers/vfs/select.c index 53f183bf9..e70337b9f 100644 --- a/servers/vfs/select.c +++ b/servers/vfs/select.c @@ -382,8 +382,7 @@ static int select_request_async(struct filp *f, int *ops, int block) return(SUSPEND); f->filp_select_flags &= ~FSF_UPDATE; - r = dev_io(VFS_DEV_SELECT, f->filp_vno->v_sdev, rops, NULL, - ((u64_t)(0)), 0, 0, FALSE); + r = dev_io(VFS_DEV_SELECT, f->filp_vno->v_sdev, rops, NULL, 0, 0, 0, FALSE); if (r < 0 && r != SUSPEND) return(r); @@ -434,8 +433,7 @@ static int select_request_sync(struct filp *f, int *ops, int block) rops = *ops; if (block) rops |= SEL_NOTIFY; - *ops = dev_io(VFS_DEV_SELECT, f->filp_vno->v_sdev, rops, NULL, - ((u64_t)(0)), 0, 0, FALSE); + *ops = dev_io(VFS_DEV_SELECT, f->filp_vno->v_sdev, rops, NULL, 0, 0, 0,FALSE); if (*ops < 0) return(*ops); diff --git a/servers/vfs/table.c b/servers/vfs/table.c index c3cb3f54d..a4408106f 100644 --- a/servers/vfs/table.c +++ b/servers/vfs/table.c @@ -96,7 +96,7 @@ int (*call_vec[])(message *m_out) = { no_sys, /* 78 = (sysuname) */ no_sys, /* 79 = unused */ do_getdents, /* 80 = getdents_321 (to be phased out) */ - do_llseek, /* 81 = llseek */ + do_lseek, /* 81 = llseek */ do_fstatfs, /* 82 = fstatfs */ do_statvfs, /* 83 = fstatvfs */ do_fstatvfs, /* 84 = statvfs */ diff --git a/servers/vfs/vnode.h b/servers/vfs/vnode.h index 2f01d7379..e9f7cdc5e 100644 --- a/servers/vfs/vnode.h +++ b/servers/vfs/vnode.h @@ -13,9 +13,6 @@ EXTERN struct vnode { int v_ref_count; /* # times vnode used; 0 means slot is free */ int v_fs_count; /* # reference at the underlying FS */ int v_mapfs_count; /* # reference at the underlying mapped FS */ -#if 0 - int v_ref_check; /* for consistency checks */ -#endif endpoint_t v_bfs_e; /* endpoint number for the FS proces in case of a block special file */ dev_t v_dev; /* device number on which the corresponding -- 2.44.0