9 /*===========================================================================*
11 *===========================================================================*/
12 PUBLIC
int fs_readwrite(void)
17 off_t position
, f_size
;
18 unsigned int nrbytes
, cum_io
;
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
);
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
);
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
);
61 position
+= nrbytes
; /* Update position */
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
;
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
;
84 put_block(rip
->i_dev
, rip
->i_num
);