1 /* Created (MFS based):
2 * February 2010 (Evgeniy Ivanov)
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 /*===========================================================================*
20 *===========================================================================*/
21 ssize_t
fs_read(ino_t ino_nr
, struct fsdriver_data
*data
, size_t bytes
,
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");
34 if (bytes
> sizeof(rw_buf
))
35 bytes
= sizeof(rw_buf
);
38 if (global_pu
->pu_ops
.puffs_node_read
== NULL
)
41 r
= global_pu
->pu_ops
.puffs_node_read(global_pu
, pn
, (uint8_t *)rw_buf
,
42 pos
, &bytes_left
, pcr
, 0);
44 lpuffs_debug("puffs_node_read failed\n");
48 bytes_done
= bytes
- bytes_left
;
51 if ((r
= fsdriver_copyout(data
, 0, rw_buf
, bytes_done
)) != OK
)
53 update_timens(pn
, ATIME
, NULL
);
56 return (ssize_t
)bytes_done
;
60 /*===========================================================================*
62 *===========================================================================*/
63 ssize_t
fs_write(ino_t ino_nr
, struct fsdriver_data
*data
, size_t bytes
,
68 struct puffs_node
*pn
;
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");
78 if (bytes
> sizeof(rw_buf
))
79 bytes
= sizeof(rw_buf
);
82 /* At first try to change vattr */
83 if (global_pu
->pu_ops
.puffs_node_setattr
== NULL
)
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
)
100 if (global_pu
->pu_ops
.puffs_node_write
== NULL
)
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 /*===========================================================================*
113 *===========================================================================*/
114 ssize_t
fs_getdents(ino_t ino_nr
, struct fsdriver_data
*data
, size_t bytes
,
118 register struct puffs_node
*pn
;
119 size_t buf_left
, written
;
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");
129 if (bytes
> sizeof(getdents_buf
))
130 bytes
= sizeof(getdents_buf
);
131 memset(getdents_buf
, 0, sizeof(getdents_buf
)); /* Avoid leaking any data */
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);
140 lpuffs_debug("puffs_node_readdir returned error\n");
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");
153 if ((r
= fsdriver_copyout(data
, 0, getdents_buf
, written
)) != OK
)
157 update_timens(pn
, ATIME
, NULL
);
159 /* The puffs readdir call has already updated the position. */