1 /* Created (MFS based):
2 * February 2010 (Evgeniy Ivanov)
10 #include <minix/com.h>
11 #include <minix/u64.h>
12 #include <minix/vfsif.h>
14 #include <sys/param.h>
17 #include "puffs_priv.h"
20 #define GETDENTS_BUFSIZ 4096
21 PRIVATE
char getdents_buf
[GETDENTS_BUFSIZ
];
23 #define RW_BUFSIZ (128 << 10)
24 PRIVATE
char rw_buf
[RW_BUFSIZ
];
27 /*===========================================================================*
29 *===========================================================================*/
30 PUBLIC
int fs_readwrite(void)
35 size_t nrbytes
, bytes_left
, bytes_done
= 0;
36 struct puffs_node
*pn
;
38 PUFFS_MAKECRED(pcr
, &global_kcred
);
40 if ((pn
= puffs_pn_nodewalk(global_pu
, 0, &fs_m_in
.REQ_INODE_NR
)) == NULL
) {
41 lpuffs_debug("walk failed...\n");
45 /* Get the values from the request message */
46 rw_flag
= (fs_m_in
.m_type
== REQ_READ
? READING
: WRITING
);
47 gid
= (cp_grant_id_t
) fs_m_in
.REQ_GRANT
;
48 pos
= (off_t
) fs_m_in
.REQ_SEEK_POS_LO
;
49 nrbytes
= bytes_left
= (size_t) fs_m_in
.REQ_NBYTES
;
51 if (nrbytes
> RW_BUFSIZ
)
52 nrbytes
= bytes_left
= RW_BUFSIZ
;
54 memset(getdents_buf
, '\0', GETDENTS_BUFSIZ
); /* Avoid leaking any data */
56 if (rw_flag
== READING
) {
57 if (global_pu
->pu_ops
.puffs_node_read
== NULL
)
60 r
= global_pu
->pu_ops
.puffs_node_read(global_pu
, pn
, (uint8_t *)rw_buf
,
61 pos
, &bytes_left
, pcr
, 0);
63 lpuffs_debug("puffs_node_read failed\n");
67 bytes_done
= nrbytes
- bytes_left
;
69 r
= sys_safecopyto(VFS_PROC_NR
, gid
, (vir_bytes
) 0,
70 (vir_bytes
) rw_buf
, bytes_done
, D
);
71 update_times(pn
, ATIME
, 0);
73 } else if (rw_flag
== WRITING
) {
74 /* At first try to change vattr */
75 if (global_pu
->pu_ops
.puffs_node_setattr
== NULL
)
78 puffs_vattr_null(&va
);
79 if ( (pos
+ bytes_left
) > pn
->pn_va
.va_size
)
80 va
.va_size
= bytes_left
+ pos
;
81 va
.va_ctime
.tv_sec
= va
.va_mtime
.tv_sec
= clock_time();
82 va
.va_atime
.tv_sec
= pn
->pn_va
.va_atime
.tv_sec
;
84 r
= global_pu
->pu_ops
.puffs_node_setattr(global_pu
, pn
, &va
, pcr
);
85 if (r
) return(EINVAL
);
87 r
= sys_safecopyfrom(VFS_PROC_NR
, gid
, (vir_bytes
) 0,
88 (vir_bytes
) rw_buf
, nrbytes
, D
);
89 if (r
!= OK
) return(EINVAL
);
91 if (global_pu
->pu_ops
.puffs_node_write
== NULL
)
94 r
= global_pu
->pu_ops
.puffs_node_write(global_pu
, pn
, (uint8_t *)rw_buf
,
95 pos
, &bytes_left
, pcr
, 0);
96 bytes_done
= nrbytes
- bytes_left
;
99 if (r
!= OK
) return(EINVAL
);
101 fs_m_out
.RES_SEEK_POS_LO
= pos
+ bytes_done
;
102 fs_m_out
.RES_NBYTES
= bytes_done
;
108 /*===========================================================================*
110 *===========================================================================*/
111 PUBLIC
int fs_breadwrite(void)
113 /* We do not support breads/writes */
114 panic("bread write requested, but FS doesn't support it!\n");
119 /*===========================================================================*
121 *===========================================================================*/
122 PUBLIC
int fs_getdents(void)
125 register struct puffs_node
*pn
;
128 size_t size
, buf_left
;
133 PUFFS_MAKECRED(pcr
, &global_kcred
);
135 ino
= (ino_t
) fs_m_in
.REQ_INODE_NR
;
136 gid
= (gid_t
) fs_m_in
.REQ_GRANT
;
137 size
= buf_left
= (size_t) fs_m_in
.REQ_MEM_SIZE
;
138 pos
= (off_t
) fs_m_in
.REQ_SEEK_POS_LO
;
140 if ((pn
= puffs_pn_nodewalk(global_pu
, 0, &ino
)) == NULL
) {
141 lpuffs_debug("walk failed...\n");
145 if (GETDENTS_BUFSIZ
< size
)
146 size
= buf_left
= GETDENTS_BUFSIZ
;
147 memset(getdents_buf
, '\0', GETDENTS_BUFSIZ
); /* Avoid leaking any data */
149 dent
= (struct dirent
*) getdents_buf
;
151 r
= global_pu
->pu_ops
.puffs_node_readdir(global_pu
, pn
, dent
, &pos
,
152 &buf_left
, pcr
, &eofflag
, 0, 0);
154 lpuffs_debug("puffs_node_readdir returned error\n");
158 assert(buf_left
<= size
);
159 written
= size
- buf_left
;
161 if (written
== 0 && !eofflag
) {
162 lpuffs_debug("The user's buffer is too small\n");
167 r
= sys_safecopyto(VFS_PROC_NR
, gid
, (vir_bytes
) 0,
168 (vir_bytes
) getdents_buf
, written
, D
);
169 if (r
!= OK
) return(r
);
172 update_times(pn
, ATIME
, 0);
174 fs_m_out
.RES_NBYTES
= written
;
175 fs_m_out
.RES_SEEK_POS_LO
= pos
;