8 /*===========================================================================*
10 *===========================================================================*/
11 int fs_readwrite(message
*fs_m_in
, message
*fs_m_out
)
16 off_t position
, f_size
;
17 unsigned int nrbytes
, cum_io
;
24 inumb
= (pino_t
) fs_m_in
->REQ_INODE_NR
;
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
);
33 /* Get the values from the request message */
34 rw_flag
= (fs_m_in
->m_type
== REQ_READ
? READING
: WRITING
);
35 gid
= (cp_grant_id_t
) fs_m_in
->REQ_GRANT
;
36 nrbytes
= (unsigned) fs_m_in
->REQ_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
) {
53 put_block(rip
->i_dev
, rip
->i_num
);
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
);
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
);
75 position
+= (signed) nrbytes
; /* Update position */
79 /* On write, update file size and access time. */
80 if (rw_flag
== WRITING
) {
81 rip
->i_size
= position
;
83 memmove(bp
->b_data
, bp
->b_data
+nrbytes
, rip
->i_size
- nrbytes
);
84 rip
->i_size
-= nrbytes
;
87 if (rw_flag
== READING
) rip
->i_update
|= ATIME
;
88 if (rw_flag
== WRITING
) rip
->i_update
|= CTIME
| MTIME
;
89 fs_m_out
->RES_NBYTES
= (size_t) cum_io
;
90 fs_m_out
->RES_SEEK_POS_LO
= rip
->i_size
;
93 put_block(rip
->i_dev
, rip
->i_num
);