Remove building with NOCRYPTO option
[minix.git] / minix / lib / libpuffs / read.c
blob5fdbe5b5045f2c996fc9d59955c55ea2b85a6c10
1 /* Created (MFS based):
2 * February 2010 (Evgeniy Ivanov)
3 */
5 #include "fs.h"
6 #include <stddef.h>
7 #include <dirent.h>
8 #include <sys/param.h>
11 #define GETDENTS_BUFSIZ 4096
12 static char getdents_buf[GETDENTS_BUFSIZ];
14 #define RW_BUFSIZ (128 * 1024)
15 static char rw_buf[RW_BUFSIZ];
18 /*===========================================================================*
19 * fs_read *
20 *===========================================================================*/
21 ssize_t fs_read(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
22 off_t pos, int call)
24 int r;
25 size_t bytes_left, bytes_done;
26 struct puffs_node *pn;
27 PUFFS_MAKECRED(pcr, &global_kcred);
29 if ((pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL) {
30 lpuffs_debug("walk failed...\n");
31 return(EINVAL);
34 if (bytes > sizeof(rw_buf))
35 bytes = sizeof(rw_buf);
36 bytes_left = bytes;
38 if (global_pu->pu_ops.puffs_node_read == NULL)
39 return(EINVAL);
41 r = global_pu->pu_ops.puffs_node_read(global_pu, pn, (uint8_t *)rw_buf,
42 pos, &bytes_left, pcr, 0);
43 if (r) {
44 lpuffs_debug("puffs_node_read failed\n");
45 return(EINVAL);
48 bytes_done = bytes - bytes_left;
50 if (bytes_done > 0) {
51 if ((r = fsdriver_copyout(data, 0, rw_buf, bytes_done)) != OK)
52 return r;
53 update_timens(pn, ATIME, NULL);
56 return (ssize_t)bytes_done;
60 /*===========================================================================*
61 * fs_write *
62 *===========================================================================*/
63 ssize_t fs_write(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
64 off_t pos, int call)
66 int r;
67 size_t bytes_left;
68 struct puffs_node *pn;
69 struct vattr va;
70 struct timespec cur_time;
71 PUFFS_MAKECRED(pcr, &global_kcred);
73 if ((pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL) {
74 lpuffs_debug("walk failed...\n");
75 return(EINVAL);
78 if (bytes > sizeof(rw_buf))
79 bytes = sizeof(rw_buf);
80 bytes_left = bytes;
82 /* At first try to change vattr */
83 if (global_pu->pu_ops.puffs_node_setattr == NULL)
84 return(EINVAL);
86 (void)clock_time(&cur_time);
88 puffs_vattr_null(&va);
89 if ((u_quad_t)(pos + bytes_left) > pn->pn_va.va_size)
90 va.va_size = bytes_left + pos;
91 va.va_ctime = va.va_mtime = cur_time;
92 va.va_atime = pn->pn_va.va_atime;
94 r = global_pu->pu_ops.puffs_node_setattr(global_pu, pn, &va, pcr);
95 if (r) return(EINVAL);
97 if ((r = fsdriver_copyin(data, 0, rw_buf, bytes)) != OK)
98 return r;
100 if (global_pu->pu_ops.puffs_node_write == NULL)
101 return(EINVAL);
103 r = global_pu->pu_ops.puffs_node_write(global_pu, pn, (uint8_t *)rw_buf,
104 pos, &bytes_left, pcr, 0);
105 if (r != OK) return(EINVAL);
107 return (ssize_t)(bytes - bytes_left);
111 /*===========================================================================*
112 * fs_getdents *
113 *===========================================================================*/
114 ssize_t fs_getdents(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
115 off_t *pos)
117 int r;
118 register struct puffs_node *pn;
119 size_t buf_left, written;
120 struct dirent *dent;
121 int eofflag = 0;
122 PUFFS_MAKECRED(pcr, &global_kcred);
124 if ((pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL) {
125 lpuffs_debug("walk failed...\n");
126 return(EINVAL);
129 if (bytes > sizeof(getdents_buf))
130 bytes = sizeof(getdents_buf);
131 memset(getdents_buf, 0, sizeof(getdents_buf)); /* Avoid leaking any data */
133 buf_left = bytes;
135 dent = (struct dirent*) getdents_buf;
137 r = global_pu->pu_ops.puffs_node_readdir(global_pu, pn, dent, pos,
138 &buf_left, pcr, &eofflag, 0, 0);
139 if (r) {
140 lpuffs_debug("puffs_node_readdir returned error\n");
141 return(EINVAL);
144 assert(buf_left <= bytes);
145 written = bytes - buf_left;
147 if (written == 0 && !eofflag) {
148 lpuffs_debug("The user's buffer is too small\n");
149 return(EINVAL);
152 if (written) {
153 if ((r = fsdriver_copyout(data, 0, getdents_buf, written)) != OK)
154 return r;
157 update_timens(pn, ATIME, NULL);
159 /* The puffs readdir call has already updated the position. */
160 return written;