8 /*===========================================================================*
10 *===========================================================================*/
11 int fs_readwrite(message
*fs_m_in
, message
*fs_m_out
)
16 off_t position
, f_size
;
17 size_t nrbytes
, cum_io
;
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
);
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
) {
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 */
78 /* On write, update file size and access time. */
79 if (rw_flag
== WRITING
) {
80 rip
->i_size
= position
;
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
;
94 put_block(rip
->i_dev
, rip
->i_num
);