VM: make mapping types explicit
[minix.git] / servers / pfs / read.c
blob691c0fddce5b749494d811ccf73befae44d57e9d
1 #include "fs.h"
2 #include "buf.h"
3 #include <minix/com.h>
4 #include "inode.h"
7 /*===========================================================================*
8 * fs_readwrite *
9 *===========================================================================*/
10 int fs_readwrite(message *fs_m_in, message *fs_m_out)
12 int r, rw_flag;
13 struct buf *bp;
14 cp_grant_id_t gid;
15 off_t position, f_size;
16 unsigned int nrbytes, cum_io;
17 mode_t mode_word;
18 struct inode *rip;
19 ino_t inumb;
21 r = OK;
22 cum_io = 0;
23 inumb = (ino_t) fs_m_in->REQ_INODE_NR;
25 /* Find the inode referred */
26 if ((rip = find_inode(inumb)) == NULL) return(EINVAL);
28 mode_word = rip->i_mode & I_TYPE;
29 if (mode_word != I_NAMED_PIPE) return(EIO);
30 f_size = rip->i_size;
32 /* Get the values from the request message */
33 rw_flag = (fs_m_in->m_type == REQ_READ ? READING : WRITING);
34 gid = (cp_grant_id_t) fs_m_in->REQ_GRANT;
35 position = fs_m_in->REQ_SEEK_POS_LO;
36 nrbytes = (unsigned) fs_m_in->REQ_NBYTES;
38 /* We can't read beyond the max file position */
39 if (nrbytes > MAX_FILE_POS) return(EFBIG);
41 if (rw_flag == WRITING) {
42 /* Check in advance to see if file will grow too big. */
43 /* Casting nrbytes to signed is safe, because it's guaranteed not to
44 be beyond max signed value (i.e., MAX_FILE_POS). */
45 if (position > PIPE_BUF - (signed) nrbytes) return(EFBIG);
48 /* Mark inode in use */
49 if ((get_inode(rip->i_dev, rip->i_num)) == NULL) return(err_code);
50 if ((bp = get_block(rip->i_dev, rip->i_num)) == NULL) return(err_code);
52 if (rw_flag == READING) {
53 /* Copy a chunk from the block buffer to user space. */
54 r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) 0,
55 (vir_bytes) (bp->b_data+position), (size_t) nrbytes);
56 } else {
57 /* Copy a chunk from user space to the block buffer. */
58 r = sys_safecopyfrom(VFS_PROC_NR, gid, (vir_bytes) 0,
59 (vir_bytes) (bp->b_data+position), (size_t) nrbytes);
62 if (r == OK) {
63 position += (signed) nrbytes; /* Update position */
64 cum_io += nrbytes;
67 fs_m_out->RES_SEEK_POS_LO = position; /* It might change later and the VFS
68 has to know this value */
70 /* On write, update file size and access time. */
71 if (rw_flag == WRITING) {
72 if (position > f_size) rip->i_size = position;
73 } else {
74 if(position >= rip->i_size) {
75 /* All data in the pipe is read, so reset pipe pointers */
76 rip->i_size = 0; /* no data left */
77 position = 0; /* reset reader(s) */
81 bp->b_bytes = position;
82 if (rw_flag == READING) rip->i_update |= ATIME;
83 if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
84 fs_m_out->RES_NBYTES = (size_t) cum_io;
85 put_inode(rip);
86 put_block(rip->i_dev, rip->i_num);
88 return(r);