7 /*===========================================================================*
9 *===========================================================================*/
10 int fs_readwrite(message
*fs_m_in
, message
*fs_m_out
)
15 off_t position
, f_size
;
16 unsigned int nrbytes
, cum_io
;
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
);
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
);
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
);
63 position
+= (signed) nrbytes
; /* Update position */
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
;
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
;
86 put_block(rip
->i_dev
, rip
->i_num
);