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 static char getdents_buf
[GETDENTS_BUFSIZ
];
23 #define RW_BUFSIZ (128 << 10)
24 static char rw_buf
[RW_BUFSIZ
];
27 /*===========================================================================*
29 *===========================================================================*/
30 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
.m_vfs_fs_readwrite
.inode
)) == 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
= fs_m_in
.m_vfs_fs_readwrite
.grant
;
48 pos
= fs_m_in
.m_vfs_fs_readwrite
.seek_pos
;
49 nrbytes
= bytes_left
= fs_m_in
.m_vfs_fs_readwrite
.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
);
71 update_timens(pn
, ATIME
, NULL
);
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 ((u_quad_t
)(pos
+ bytes_left
) > pn
->pn_va
.va_size
)
80 va
.va_size
= bytes_left
+ pos
;
81 va
.va_ctime
= va
.va_mtime
= clock_timespec();
82 va
.va_atime
= pn
->pn_va
.va_atime
;
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
);
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
.m_fs_vfs_readwrite
.seek_pos
= pos
+ bytes_done
;
102 fs_m_out
.m_fs_vfs_readwrite
.nbytes
= bytes_done
;
108 /*===========================================================================*
110 *===========================================================================*/
111 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 int fs_getdents(void)
125 register struct puffs_node
*pn
;
128 size_t size
, buf_left
;
133 PUFFS_MAKECRED(pcr
, &global_kcred
);
135 ino
= fs_m_in
.m_vfs_fs_getdents
.inode
;
136 gid
= fs_m_in
.m_vfs_fs_getdents
.grant
;
137 size
= buf_left
= fs_m_in
.m_vfs_fs_getdents
.mem_size
;
138 pos
= fs_m_in
.m_vfs_fs_getdents
.seek_pos
;
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
);
169 if (r
!= OK
) return(r
);
172 update_timens(pn
, ATIME
, NULL
);
174 fs_m_out
.m_fs_vfs_getdents
.nbytes
= written
;
175 fs_m_out
.m_fs_vfs_getdents
.seek_pos
= pos
;