tools/llvm: Do not build with symbols
[minix3.git] / minix / fs / pfs / read.c
blobd7a8ff877cdd26ae8a73c09c6b25c216a3e9afb4
1 #include "fs.h"
2 #include "buf.h"
3 #include "inode.h"
4 #include <minix/com.h>
5 #include <string.h>
8 /*===========================================================================*
9 * fs_readwrite *
10 *===========================================================================*/
11 int fs_readwrite(message *fs_m_in, message *fs_m_out)
13 int r, rw_flag;
14 struct buf *bp;
15 cp_grant_id_t gid;
16 off_t position, f_size;
17 size_t nrbytes, cum_io;
18 mode_t mode_word;
19 struct inode *rip;
20 ino_t inumb;
22 r = OK;
23 cum_io = 0;
24 inumb = fs_m_in->m_vfs_fs_readwrite.inode;
26 /* Find the inode referred */
27 if ((rip = find_inode(inumb)) == NULL) return(EINVAL);
29 mode_word = rip->i_mode & I_TYPE;
30 if (mode_word != I_NAMED_PIPE) return(EIO);
31 f_size = rip->i_size;
33 /* Get the values from the request message */
34 rw_flag = (fs_m_in->m_type == REQ_READ ? READING : WRITING);
35 gid = fs_m_in->m_vfs_fs_readwrite.grant;
36 nrbytes = fs_m_in->m_vfs_fs_readwrite.nbytes;
38 /* We can't read beyond the max file position */
39 if (nrbytes > PIPE_BUF) return(EFBIG);
41 /* Mark inode in use */
42 if ((get_inode(rip->i_dev, rip->i_num)) == NULL) return(err_code);
43 if ((bp = get_block(rip->i_dev, rip->i_num)) == NULL) return(err_code);
45 if (rw_flag == WRITING) {
46 /* Check in advance to see if file will grow too big. */
47 /* Casting nrbytes to signed is safe, because it's guaranteed not to
48 * be beyond max signed value (i.e., MAX_FILE_POS).
50 position = rip->i_size;
51 if ((unsigned) position + nrbytes > PIPE_BUF) {
52 put_inode(rip);
53 put_block(rip->i_dev, rip->i_num);
54 return(EFBIG);
56 } else {
57 position = 0;
58 if (nrbytes > rip->i_size) {
59 /* There aren't that many bytes to read */
60 nrbytes = rip->i_size;
64 if (rw_flag == READING) {
65 /* Copy a chunk from the block buffer to user space. */
66 r = sys_safecopyto(fs_m_in->m_source, gid, (vir_bytes) 0,
67 (vir_bytes) (bp->b_data+position), (size_t) nrbytes);
68 } else {
69 /* Copy a chunk from user space to the block buffer. */
70 r = sys_safecopyfrom(fs_m_in->m_source, gid, (vir_bytes) 0,
71 (vir_bytes) (bp->b_data+position), (size_t) nrbytes);
74 if (r == OK) {
75 position += (signed) nrbytes; /* Update position */
76 cum_io += nrbytes;
78 /* On write, update file size and access time. */
79 if (rw_flag == WRITING) {
80 rip->i_size = position;
81 } else {
82 memmove(bp->b_data, bp->b_data+nrbytes, rip->i_size - nrbytes);
83 rip->i_size -= nrbytes;
86 if (rw_flag == READING) rip->i_update |= ATIME;
87 if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
90 fs_m_out->m_fs_vfs_readwrite.nbytes = cum_io;
91 fs_m_out->m_fs_vfs_readwrite.seek_pos = rip->i_size;
93 put_inode(rip);
94 put_block(rip->i_dev, rip->i_num);
96 return(r);