tty: try more often to get the config byte.
[minix.git] / servers / pfs / read.c
blobbd763abe48d0b2fbcadc9f294d66ff55373259d5
1 #include "fs.h"
2 #include "buf.h"
3 #include <minix/com.h>
4 #include <string.h>
5 #include <minix/u64.h>
6 #include "inode.h"
9 /*===========================================================================*
10 * fs_readwrite *
11 *===========================================================================*/
12 PUBLIC int fs_readwrite(void)
14 int r, rw_flag;
15 struct buf *bp;
16 cp_grant_id_t gid;
17 off_t position, f_size;
18 unsigned int nrbytes, cum_io;
19 mode_t mode_word;
20 struct inode *rip;
21 ino_t inumb;
23 r = OK;
24 cum_io = 0;
25 inumb = fs_m_in.REQ_INODE_NR;
26 rw_flag = (fs_m_in.m_type == REQ_READ ? READING : WRITING);
28 /* Find the inode referred */
29 if ((rip = find_inode(inumb)) == NIL_INODE) return(EINVAL);
31 mode_word = rip->i_mode & I_TYPE;
32 if (mode_word != I_NAMED_PIPE) return(EIO);
33 f_size = rip->i_size;
35 /* Get the values from the request message */
36 rw_flag = (fs_m_in.m_type == REQ_READ ? READING : WRITING);
37 gid = fs_m_in.REQ_GRANT;
38 position = fs_m_in.REQ_SEEK_POS_LO;
39 nrbytes = (unsigned) fs_m_in.REQ_NBYTES;
41 if (rw_flag == WRITING) {
42 /* Check in advance to see if file will grow too big. */
43 if (position > PIPE_BUF - nrbytes) return(EFBIG);
46 /* Mark inode in use */
47 if ((get_inode(rip->i_dev, rip->i_num)) == NIL_INODE) return(err_code);
48 if ((bp = get_block(rip->i_dev, rip->i_num)) == NIL_BUF) return(err_code);
50 if (rw_flag == READING) {
51 /* Copy a chunk from the block buffer to user space. */
52 r = sys_safecopyto(FS_PROC_NR, gid, 0,
53 (vir_bytes) (bp->b_data+position), (phys_bytes) nrbytes, D);
54 } else {
55 /* Copy a chunk from user space to the block buffer. */
56 r = sys_safecopyfrom(FS_PROC_NR, gid, 0,
57 (vir_bytes) (bp->b_data+position), (phys_bytes) nrbytes, D);
60 if (r == OK) {
61 position += nrbytes; /* Update position */
62 cum_io += nrbytes;
65 fs_m_out.RES_SEEK_POS_LO = position; /* It might change later and the VFS
66 has to know this value */
68 /* On write, update file size and access time. */
69 if (rw_flag == WRITING) {
70 if (position > f_size) rip->i_size = position;
71 } else {
72 if(position >= rip->i_size) {
73 /* All data in the pipe is read, so reset pipe pointers */
74 rip->i_size = 0; /* no data left */
75 position = 0; /* reset reader(s) */
79 bp->b_bytes = position;
80 if (rw_flag == READING) rip->i_update |= ATIME;
81 if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
82 fs_m_out.RES_NBYTES = cum_io;
83 put_inode(rip);
84 put_block(rip->i_dev, rip->i_num);
86 return(r);