2006-10-25 15:40:36 +02:00
|
|
|
/* This file contains the heart of the mechanism used to read (and write)
|
|
|
|
* files. Read and write requests are split up into chunks that do not cross
|
|
|
|
* block boundaries. Each chunk is then processed in turn. Reads on special
|
|
|
|
* files are also detected and handled.
|
|
|
|
*
|
|
|
|
* The entry points into this file are
|
|
|
|
* do_read: perform the READ system call by calling read_write
|
2006-11-09 17:22:54 +01:00
|
|
|
* do_getdents: read entries from a directory (GETDENTS)
|
2006-10-25 15:40:36 +02:00
|
|
|
* read_write: actually do the work of READ and WRITE
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "fs.h"
|
2013-03-25 22:09:10 +01:00
|
|
|
#include <minix/callnr.h>
|
2006-10-25 15:40:36 +02:00
|
|
|
#include <minix/com.h>
|
2006-11-27 15:21:43 +01:00
|
|
|
#include <minix/u64.h>
|
2013-03-25 22:09:10 +01:00
|
|
|
#include <minix/vfsif.h>
|
|
|
|
#include <assert.h>
|
2013-09-16 22:52:36 +02:00
|
|
|
#include <sys/dirent.h>
|
2013-03-25 22:09:10 +01:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
2006-10-25 15:40:36 +02:00
|
|
|
#include "file.h"
|
2013-03-25 22:09:10 +01:00
|
|
|
#include "scratchpad.h"
|
2006-10-25 15:40:36 +02:00
|
|
|
#include "vnode.h"
|
|
|
|
#include "vmnt.h"
|
|
|
|
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
|
2006-10-25 15:40:36 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* do_read *
|
|
|
|
*===========================================================================*/
|
2013-10-29 23:15:15 +01:00
|
|
|
int do_read(void)
|
2006-10-25 15:40:36 +02:00
|
|
|
{
|
2013-11-04 22:48:08 +01:00
|
|
|
return(do_read_write_peek(READING, job_m_in.VFS_READWRITE_FD,
|
|
|
|
job_m_in.VFS_READWRITE_BUF, (size_t) job_m_in.VFS_READWRITE_LEN));
|
2006-10-25 15:40:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*===========================================================================*
|
2012-02-13 16:28:04 +01:00
|
|
|
* lock_bsf *
|
2006-10-25 15:40:36 +02:00
|
|
|
*===========================================================================*/
|
2012-03-25 20:25:53 +02:00
|
|
|
void lock_bsf(void)
|
2012-02-13 16:28:04 +01:00
|
|
|
{
|
|
|
|
struct worker_thread *org_self;
|
|
|
|
|
|
|
|
if (mutex_trylock(&bsf_lock) == 0)
|
|
|
|
return;
|
|
|
|
|
2013-08-30 14:00:50 +02:00
|
|
|
org_self = worker_suspend();
|
2012-02-13 16:28:04 +01:00
|
|
|
|
|
|
|
if (mutex_lock(&bsf_lock) != 0)
|
|
|
|
panic("unable to lock block special file lock");
|
|
|
|
|
2013-08-30 14:00:50 +02:00
|
|
|
worker_resume(org_self);
|
2012-02-13 16:28:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* unlock_bsf *
|
|
|
|
*===========================================================================*/
|
2012-03-25 20:25:53 +02:00
|
|
|
void unlock_bsf(void)
|
2012-02-13 16:28:04 +01:00
|
|
|
{
|
|
|
|
if (mutex_unlock(&bsf_lock) != 0)
|
|
|
|
panic("failed to unlock block special file lock");
|
2012-09-27 22:23:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* check_bsf *
|
|
|
|
*===========================================================================*/
|
|
|
|
void check_bsf_lock(void)
|
|
|
|
{
|
|
|
|
int r = mutex_trylock(&bsf_lock);
|
|
|
|
|
|
|
|
if (r == -EBUSY)
|
|
|
|
panic("bsf_lock locked");
|
|
|
|
else if (r != 0)
|
|
|
|
panic("bsf_lock weird state");
|
|
|
|
|
|
|
|
/* r == 0 */
|
|
|
|
unlock_bsf();
|
2012-02-13 16:28:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
2013-05-07 14:41:07 +02:00
|
|
|
* actual_read_write_peek *
|
2012-02-13 16:28:04 +01:00
|
|
|
*===========================================================================*/
|
2013-05-07 14:41:07 +02:00
|
|
|
int actual_read_write_peek(struct fproc *rfp, int rw_flag, int io_fd,
|
|
|
|
char *io_buf, size_t io_nbytes)
|
2006-10-25 15:40:36 +02:00
|
|
|
{
|
|
|
|
/* Perform read(fd, buffer, nbytes) or write(fd, buffer, nbytes) call. */
|
2012-02-13 16:28:04 +01:00
|
|
|
struct filp *f;
|
|
|
|
tll_access_t locktype;
|
|
|
|
int r;
|
2013-01-13 22:44:38 +01:00
|
|
|
int ro = 1;
|
2012-02-13 16:28:04 +01:00
|
|
|
|
2013-01-13 22:44:38 +01:00
|
|
|
if(rw_flag == WRITING) ro = 0;
|
2006-10-25 15:40:36 +02:00
|
|
|
|
2013-05-07 14:41:07 +02:00
|
|
|
scratch(rfp).file.fd_nr = io_fd;
|
|
|
|
scratch(rfp).io.io_buffer = io_buf;
|
|
|
|
scratch(rfp).io.io_nbytes = io_nbytes;
|
2013-01-13 22:44:38 +01:00
|
|
|
|
2013-05-07 14:41:07 +02:00
|
|
|
locktype = rw_flag == WRITING ? VNODE_WRITE : VNODE_READ;
|
|
|
|
if ((f = get_filp2(rfp, scratch(rfp).file.fd_nr, locktype)) == NULL)
|
2012-02-13 16:28:04 +01:00
|
|
|
return(err_code);
|
2013-05-07 14:41:07 +02:00
|
|
|
|
|
|
|
assert(f->filp_count > 0);
|
|
|
|
|
2013-01-13 22:44:38 +01:00
|
|
|
if (((f->filp_mode) & (ro ? R_BIT : W_BIT)) == 0) {
|
2012-02-13 16:28:04 +01:00
|
|
|
unlock_filp(f);
|
2013-09-10 16:06:37 +02:00
|
|
|
return(EBADF);
|
2006-10-25 15:40:36 +02:00
|
|
|
}
|
2013-05-07 14:41:07 +02:00
|
|
|
if (scratch(rfp).io.io_nbytes == 0) {
|
2012-02-13 16:28:04 +01:00
|
|
|
unlock_filp(f);
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
return(0); /* so char special files need not check for 0*/
|
2012-02-13 16:28:04 +01:00
|
|
|
}
|
|
|
|
|
2013-05-07 14:41:07 +02:00
|
|
|
r = read_write(rfp, rw_flag, f, scratch(rfp).io.io_buffer,
|
|
|
|
scratch(rfp).io.io_nbytes, who_e);
|
2012-02-13 16:28:04 +01:00
|
|
|
|
|
|
|
unlock_filp(f);
|
|
|
|
return(r);
|
|
|
|
}
|
|
|
|
|
2013-05-07 14:41:07 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* do_read_write_peek *
|
|
|
|
*===========================================================================*/
|
|
|
|
int do_read_write_peek(int rw_flag, int io_fd, char *io_buf, size_t io_nbytes)
|
|
|
|
{
|
|
|
|
return actual_read_write_peek(fp, rw_flag, io_fd, io_buf, io_nbytes);
|
|
|
|
}
|
|
|
|
|
2012-02-13 16:28:04 +01:00
|
|
|
/*===========================================================================*
|
|
|
|
* read_write *
|
|
|
|
*===========================================================================*/
|
2013-05-07 14:41:07 +02:00
|
|
|
int read_write(struct fproc *rfp, int rw_flag, struct filp *f,
|
|
|
|
char *buf, size_t size, endpoint_t for_e)
|
2012-02-13 16:28:04 +01:00
|
|
|
{
|
|
|
|
register struct vnode *vp;
|
2013-03-25 17:08:04 +01:00
|
|
|
off_t position, res_pos;
|
2012-02-13 16:28:04 +01:00
|
|
|
unsigned int cum_io, cum_io_incr, res_cum_io;
|
2013-02-25 12:36:29 +01:00
|
|
|
int op, r;
|
2013-09-10 20:25:01 +02:00
|
|
|
dev_t dev;
|
2006-10-25 15:40:36 +02:00
|
|
|
|
|
|
|
position = f->filp_pos;
|
|
|
|
vp = f->filp_vno;
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
r = OK;
|
|
|
|
cum_io = 0;
|
2006-10-25 15:40:36 +02:00
|
|
|
|
2013-01-13 22:44:38 +01:00
|
|
|
assert(rw_flag == READING || rw_flag == WRITING || rw_flag == PEEKING);
|
|
|
|
|
2012-02-13 16:28:04 +01:00
|
|
|
if (size > SSIZE_MAX) return(EINVAL);
|
|
|
|
|
2013-09-10 20:25:01 +02:00
|
|
|
op = (rw_flag == READING ? CDEV_READ : CDEV_WRITE);
|
2013-02-25 12:36:29 +01:00
|
|
|
|
|
|
|
if (S_ISFIFO(vp->v_mode)) { /* Pipes */
|
2013-05-07 14:41:07 +02:00
|
|
|
if (rfp->fp_cum_io_partial != 0) {
|
2012-02-13 16:28:04 +01:00
|
|
|
panic("VFS: read_write: fp_cum_io_partial not clear");
|
2007-08-07 14:52:47 +02:00
|
|
|
}
|
2013-05-07 14:41:07 +02:00
|
|
|
if(rw_flag == PEEKING) {
|
|
|
|
printf("read_write: peek on pipe makes no sense\n");
|
|
|
|
return EINVAL;
|
|
|
|
}
|
2012-02-13 16:28:04 +01:00
|
|
|
r = rw_pipe(rw_flag, for_e, f, buf, size);
|
2013-02-25 12:36:29 +01:00
|
|
|
} else if (S_ISCHR(vp->v_mode)) { /* Character special files. */
|
2013-05-07 14:41:07 +02:00
|
|
|
if(rw_flag == PEEKING) {
|
|
|
|
printf("read_write: peek on char device makes no sense\n");
|
|
|
|
return EINVAL;
|
|
|
|
}
|
2008-02-22 15:26:41 +01:00
|
|
|
|
2012-04-25 14:44:42 +02:00
|
|
|
if (vp->v_sdev == NO_DEV)
|
|
|
|
panic("VFS: read_write tries to access char dev NO_DEV");
|
|
|
|
|
2008-02-22 15:26:41 +01:00
|
|
|
dev = (dev_t) vp->v_sdev;
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
|
2013-09-10 20:25:01 +02:00
|
|
|
r = cdev_io(op, dev, for_e, buf, position, size, f->filp_flags);
|
2008-02-22 15:26:41 +01:00
|
|
|
if (r >= 0) {
|
2013-09-02 17:34:44 +02:00
|
|
|
/* This should no longer happen: all calls are asynchronous. */
|
|
|
|
printf("VFS: I/O to device %x succeeded immediately!?\n", dev);
|
2008-02-22 15:26:41 +01:00
|
|
|
cum_io = r;
|
2013-09-02 17:34:44 +02:00
|
|
|
position += r;
|
2008-02-22 15:26:41 +01:00
|
|
|
r = OK;
|
2013-09-02 17:34:44 +02:00
|
|
|
} else if (r == SUSPEND) {
|
|
|
|
/* FIXME: multiple read/write operations on a single filp
|
|
|
|
* should be serialized. They currently aren't; in order to
|
|
|
|
* achieve a similar effect, we optimistically advance the file
|
|
|
|
* position here. This works under the following assumptions:
|
|
|
|
* - character drivers that use the seek position at all,
|
|
|
|
* expose a view of a statically-sized range of bytes, i.e.,
|
|
|
|
* they are basically byte-granular block devices;
|
|
|
|
* - if short I/O or an error is returned, all subsequent calls
|
|
|
|
* will return (respectively) EOF and an error;
|
|
|
|
* - the application never checks its own file seek position,
|
|
|
|
* or does not care that it may end up having seeked beyond
|
|
|
|
* the number of bytes it has actually read;
|
|
|
|
* - communication to the character driver is FIFO (this one
|
|
|
|
* is actually true! whew).
|
|
|
|
* Many improvements are possible here, but in the end,
|
|
|
|
* anything short of queuing concurrent operations will be
|
|
|
|
* suboptimal - so we settle for this hack for now.
|
|
|
|
*/
|
|
|
|
position += size;
|
2008-02-22 15:26:41 +01:00
|
|
|
}
|
2012-04-25 14:44:42 +02:00
|
|
|
} else if (S_ISBLK(vp->v_mode)) { /* Block special files. */
|
|
|
|
if (vp->v_sdev == NO_DEV)
|
|
|
|
panic("VFS: read_write tries to access block dev NO_DEV");
|
|
|
|
|
2012-02-13 16:28:04 +01:00
|
|
|
lock_bsf();
|
|
|
|
|
2013-05-07 14:41:07 +02:00
|
|
|
if(rw_flag == PEEKING) {
|
|
|
|
r = req_bpeek(vp->v_bfs_e, vp->v_sdev, position, size);
|
|
|
|
} else {
|
2013-03-07 16:55:22 +01:00
|
|
|
r = req_breadwrite(vp->v_bfs_e, for_e, vp->v_sdev, position,
|
|
|
|
size, (vir_bytes) buf, rw_flag, &res_pos, &res_cum_io);
|
2013-05-07 14:41:07 +02:00
|
|
|
if (r == OK) {
|
|
|
|
position = res_pos;
|
|
|
|
cum_io += res_cum_io;
|
|
|
|
}
|
2010-03-08 23:05:27 +01:00
|
|
|
}
|
2012-02-13 16:28:04 +01:00
|
|
|
|
|
|
|
unlock_bsf();
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
} else { /* Regular files */
|
2012-04-25 14:44:42 +02:00
|
|
|
if (rw_flag == WRITING) {
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
/* Check for O_APPEND flag. */
|
2013-03-25 17:08:04 +01:00
|
|
|
if (f->filp_flags & O_APPEND) position = vp->v_size;
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
}
|
2007-01-05 17:36:55 +01:00
|
|
|
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
/* Issue request */
|
2013-05-07 14:41:07 +02:00
|
|
|
if(rw_flag == PEEKING) {
|
|
|
|
r = req_peek(vp->v_fs_e, vp->v_inode_nr, position, size);
|
|
|
|
} else {
|
2013-03-25 17:08:04 +01:00
|
|
|
off_t new_pos;
|
2013-05-07 14:41:07 +02:00
|
|
|
r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, position,
|
2013-03-07 16:55:22 +01:00
|
|
|
rw_flag, for_e, (vir_bytes) buf, size, &new_pos,
|
|
|
|
&cum_io_incr);
|
2013-05-07 14:41:07 +02:00
|
|
|
|
|
|
|
if (r >= 0) {
|
|
|
|
position = new_pos;
|
|
|
|
cum_io += cum_io_incr;
|
|
|
|
}
|
|
|
|
}
|
2006-10-25 15:40:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* On write, update file size and access time. */
|
|
|
|
if (rw_flag == WRITING) {
|
2012-04-25 14:44:42 +02:00
|
|
|
if (S_ISREG(vp->v_mode) || S_ISDIR(vp->v_mode)) {
|
2013-03-25 17:08:04 +01:00
|
|
|
if (position > vp->v_size) {
|
|
|
|
vp->v_size = position;
|
2006-11-27 15:21:43 +01:00
|
|
|
}
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
}
|
2006-10-25 15:40:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
f->filp_pos = position;
|
2012-02-13 16:28:04 +01:00
|
|
|
|
2013-02-25 12:36:29 +01:00
|
|
|
if (r == EPIPE && rw_flag == WRITING) {
|
|
|
|
/* Process is writing, but there is no reader. Tell the kernel to
|
|
|
|
* generate s SIGPIPE signal.
|
|
|
|
*/
|
|
|
|
if (!(f->filp_flags & O_NOSIGPIPE)) {
|
2013-05-07 14:41:07 +02:00
|
|
|
sys_kill(rfp->fp_endpoint, SIGPIPE);
|
2013-02-25 12:36:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (r == OK) {
|
|
|
|
return(cum_io);
|
|
|
|
}
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
return(r);
|
2006-10-25 15:40:36 +02:00
|
|
|
}
|
|
|
|
|
2006-11-09 17:22:54 +01:00
|
|
|
/*===========================================================================*
|
|
|
|
* do_getdents *
|
|
|
|
*===========================================================================*/
|
2013-10-29 23:15:15 +01:00
|
|
|
int do_getdents(void)
|
2006-11-09 17:22:54 +01:00
|
|
|
{
|
|
|
|
/* Perform the getdents(fd, buf, size) system call. */
|
2013-08-31 21:48:15 +02:00
|
|
|
int r = OK;
|
2013-03-25 17:08:04 +01:00
|
|
|
off_t new_pos;
|
2006-11-09 17:22:54 +01:00
|
|
|
register struct filp *rfilp;
|
|
|
|
|
2013-11-04 22:48:08 +01:00
|
|
|
scratch(fp).file.fd_nr = job_m_in.VFS_READWRITE_FD;
|
|
|
|
scratch(fp).io.io_buffer = job_m_in.VFS_READWRITE_BUF;
|
|
|
|
scratch(fp).io.io_nbytes = (size_t) job_m_in.VFS_READWRITE_LEN;
|
2012-04-13 14:50:38 +02:00
|
|
|
|
2006-11-09 17:22:54 +01:00
|
|
|
/* Is the file descriptor valid? */
|
2012-04-13 14:50:38 +02:00
|
|
|
if ( (rfilp = get_filp(scratch(fp).file.fd_nr, VNODE_READ)) == NULL)
|
|
|
|
return(err_code);
|
2012-02-13 16:28:04 +01:00
|
|
|
|
2006-11-09 17:22:54 +01:00
|
|
|
if (!(rfilp->filp_mode & R_BIT))
|
2012-02-13 16:28:04 +01:00
|
|
|
r = EBADF;
|
2012-04-25 14:44:42 +02:00
|
|
|
else if (!S_ISDIR(rfilp->filp_vno->v_mode))
|
2012-02-13 16:28:04 +01:00
|
|
|
r = EBADF;
|
2006-11-09 17:22:54 +01:00
|
|
|
|
2012-02-13 16:28:04 +01:00
|
|
|
if (r == OK) {
|
|
|
|
r = req_getdents(rfilp->filp_vno->v_fs_e, rfilp->filp_vno->v_inode_nr,
|
2012-04-13 14:50:38 +02:00
|
|
|
rfilp->filp_pos, scratch(fp).io.io_buffer,
|
2013-08-31 21:48:15 +02:00
|
|
|
scratch(fp).io.io_nbytes, &new_pos, 0);
|
2006-11-09 17:22:54 +01:00
|
|
|
|
2012-02-13 16:28:04 +01:00
|
|
|
if (r > 0) rfilp->filp_pos = new_pos;
|
|
|
|
}
|
2006-11-09 17:22:54 +01:00
|
|
|
|
2012-02-13 16:28:04 +01:00
|
|
|
unlock_filp(rfilp);
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
return(r);
|
2006-11-09 17:22:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-08-07 14:52:47 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* rw_pipe *
|
|
|
|
*===========================================================================*/
|
2012-03-25 20:25:53 +02:00
|
|
|
int rw_pipe(rw_flag, usr_e, f, buf, req_size)
|
2007-08-07 14:52:47 +02:00
|
|
|
int rw_flag; /* READING or WRITING */
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
endpoint_t usr_e;
|
2007-08-07 14:52:47 +02:00
|
|
|
struct filp *f;
|
|
|
|
char *buf;
|
|
|
|
size_t req_size;
|
|
|
|
{
|
2010-04-01 15:25:05 +02:00
|
|
|
int r, oflags, partial_pipe = 0;
|
|
|
|
size_t size, cum_io, cum_io_incr;
|
2007-08-07 14:52:47 +02:00
|
|
|
struct vnode *vp;
|
2013-03-25 17:08:04 +01:00
|
|
|
off_t position, new_pos;
|
2007-08-07 14:52:47 +02:00
|
|
|
|
2012-02-13 16:28:04 +01:00
|
|
|
/* Must make sure we're operating on locked filp and vnode */
|
VFS: fix locking bugs
.sync and fsync used unnecessarily restrictive locking type
.fsync violated locking order by obtaining a vmnt lock after a filp lock
.fsync contained a TOCTOU bug
.new_node violated locking rules (didn't upgrade lock upon file creation)
.do_pipe used unnecessarily restrictive locking type
.always lock pipes exclusively; even a read operation might require to do
a write on a vnode object (update pipe size)
.when opening a file with O_TRUNC, upgrade vnode lock when truncating
.utime used unnecessarily restrictive locking type
.path parsing:
.always acquire VMNT_WRITE or VMNT_EXCL on vmnt and downgrade to
VMNT_READ if that was what was actually requested. This prevents the
following deadlock scenario:
thread A:
lock_vmnt(vmp, TLL_READSER);
lock_vnode(vp, TLL_READSER);
upgrade_vmnt_lock(vmp, TLL_WRITE);
thread B:
lock_vmnt(vmp, TLL_READ);
lock_vnode(vp, TLL_READSER);
thread A will be stuck in upgrade_vmnt_lock and thread B is stuck in
lock_vnode. This happens when, for example, thread A tries create a
new node (open.c:new_node) and thread B tries to do eat_path to
change dir (stadir.c:do_chdir). When the path is being resolved, a
vnode is always locked with VNODE_OPCL (TLL_READSER) and then
downgraded to VNODE_READ if read-only is actually requested. Thread
A locks the vmnt with VMNT_WRITE (TLL_READSER) which still allows
VMNT_READ locks. Thread B can't acquire a lock on the vnode because
thread A has it; Thread A can't upgrade its vmnt lock to VMNT_WRITE
(TLL_WRITE) because thread B has a VMNT_READ lock on it.
By serializing vmnt locks during path parsing, thread B can only
acquire a lock on vmp when thread A has completely finished its
operation.
2012-11-30 13:49:53 +01:00
|
|
|
assert(tll_locked_by_me(&f->filp_vno->v_lock));
|
2012-02-13 16:28:04 +01:00
|
|
|
assert(mutex_trylock(&f->filp_lock) == -EDEADLK);
|
|
|
|
|
2007-08-07 14:52:47 +02:00
|
|
|
oflags = f->filp_flags;
|
|
|
|
vp = f->filp_vno;
|
2013-03-25 17:08:04 +01:00
|
|
|
position = 0; /* Not actually used */
|
2012-12-11 20:46:09 +01:00
|
|
|
|
2013-05-07 14:41:07 +02:00
|
|
|
assert(rw_flag == READING || rw_flag == WRITING);
|
|
|
|
|
2007-08-07 14:52:47 +02:00
|
|
|
/* fp->fp_cum_io_partial is only nonzero when doing partial writes */
|
2012-02-13 16:28:04 +01:00
|
|
|
cum_io = fp->fp_cum_io_partial;
|
2007-08-07 14:52:47 +02:00
|
|
|
|
2013-02-25 12:36:29 +01:00
|
|
|
r = pipe_check(f, rw_flag, oflags, req_size, 0);
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
if (r <= 0) {
|
2012-02-13 16:28:04 +01:00
|
|
|
if (r == SUSPEND) pipe_suspend(f, buf, req_size);
|
|
|
|
return(r);
|
2007-08-07 14:52:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
size = r;
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
if (size < req_size) partial_pipe = 1;
|
2007-08-07 14:52:47 +02:00
|
|
|
|
|
|
|
/* Truncate read request at size. */
|
2012-12-11 20:46:09 +01:00
|
|
|
if (rw_flag == READING && size > vp->v_size) {
|
|
|
|
size = vp->v_size;
|
2007-08-07 14:52:47 +02:00
|
|
|
}
|
|
|
|
|
2012-02-13 16:28:04 +01:00
|
|
|
if (vp->v_mapfs_e == 0)
|
2010-03-05 16:05:11 +01:00
|
|
|
panic("unmapped pipe");
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
|
2010-01-27 10:30:39 +01:00
|
|
|
r = req_readwrite(vp->v_mapfs_e, vp->v_mapinode_nr, position, rw_flag, usr_e,
|
2013-03-07 16:55:22 +01:00
|
|
|
(vir_bytes) buf, size, &new_pos, &cum_io_incr);
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
|
2013-01-22 17:40:53 +01:00
|
|
|
if (r != OK) {
|
|
|
|
return(r);
|
2007-08-07 14:52:47 +02:00
|
|
|
}
|
2012-02-13 16:28:04 +01:00
|
|
|
|
2013-01-22 17:40:53 +01:00
|
|
|
cum_io += cum_io_incr;
|
|
|
|
buf += cum_io_incr;
|
|
|
|
req_size -= cum_io_incr;
|
|
|
|
|
2013-03-25 17:08:04 +01:00
|
|
|
vp->v_size = new_pos;
|
2013-01-22 17:40:53 +01:00
|
|
|
|
|
|
|
if (partial_pipe) {
|
|
|
|
/* partial write on pipe with */
|
|
|
|
/* O_NONBLOCK, return write count */
|
|
|
|
if (!(oflags & O_NONBLOCK)) {
|
|
|
|
/* partial write on pipe with req_size > PIPE_SIZE,
|
|
|
|
* non-atomic
|
|
|
|
*/
|
|
|
|
fp->fp_cum_io_partial = cum_io;
|
|
|
|
pipe_suspend(f, buf, req_size);
|
|
|
|
return(SUSPEND);
|
2007-08-07 14:52:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-22 17:40:53 +01:00
|
|
|
fp->fp_cum_io_partial = 0;
|
2007-08-07 14:52:47 +02:00
|
|
|
|
2013-01-22 17:40:53 +01:00
|
|
|
return(cum_io);
|
2007-08-07 14:52:47 +02:00
|
|
|
}
|