1 /* Created (MFS based):
2 * June 2011 (Evgeniy Ivanov)
7 /*===========================================================================*
9 *===========================================================================*/
10 int fs_create(ino_t dir_nr
, char *name
, mode_t mode
, uid_t uid
, gid_t gid
,
11 struct fsdriver_node
*node
)
14 struct puffs_node
*pn_dir
;
15 struct puffs_node
*pn
;
16 struct puffs_newinfo pni
;
17 struct puffs_kcn pkcnp
;
18 PUFFS_MAKECRED(pcr
, &global_kcred
);
19 struct puffs_cn pcn
= {&pkcnp
, (struct puffs_cred
*) __UNCONST(pcr
), {0,0,0}};
21 struct timespec cur_time
;
23 if (global_pu
->pu_ops
.puffs_node_create
== NULL
) {
24 lpuffs_debug("No puffs_node_create");
28 /* Copy the last component (i.e., file name) */
29 pcn
.pcn_namelen
= strlen(name
);
30 assert(pcn
.pcn_namelen
<= NAME_MAX
);
31 strcpy(pcn
.pcn_name
, name
);
33 /* Get last directory pnode (i.e., directory that will hold the new pnode) */
34 if ((pn_dir
= puffs_pn_nodewalk(global_pu
, find_inode_cb
, &dir_nr
)) == NULL
)
37 memset(&pni
, 0, sizeof(pni
));
38 pni
.pni_cookie
= (void** )&pn
;
40 (void)clock_time(&cur_time
);
42 memset(&va
, 0, sizeof(va
));
47 va
.va_atime
= va
.va_mtime
= va
.va_ctime
= cur_time
;
50 r
= puffs_path_pcnbuild(global_pu
, &pcn
, pn_dir
);
52 lpuffs_debug("pathbuild error\n");
57 r
= global_pu
->pu_ops
.puffs_node_create(global_pu
, pn_dir
, &pni
, &pcn
, &va
);
60 global_pu
->pu_pathfree(global_pu
, &pcn
.pcn_po_full
);
62 struct puffs_node
*_pn
;
64 _pn
= PU_CMAP(global_pu
, pn
);
65 _pn
->pn_po
= pcn
.pcn_po_full
;
77 update_timens(pn_dir
, MTIME
| CTIME
, &cur_time
);
80 node
->fn_ino_nr
= pn
->pn_va
.va_fileid
;
81 node
->fn_mode
= pn
->pn_va
.va_mode
;
82 node
->fn_size
= pn
->pn_va
.va_size
;
83 node
->fn_uid
= pn
->pn_va
.va_uid
;
84 node
->fn_gid
= pn
->pn_va
.va_gid
;
85 node
->fn_dev
= NO_DEV
;
91 /*===========================================================================*
93 *===========================================================================*/
94 int fs_mknod(ino_t dir_nr
, char *name
, mode_t mode
, uid_t uid
, gid_t gid
,
98 struct puffs_node
*pn_dir
;
99 struct puffs_node
*pn
;
100 struct puffs_newinfo pni
;
101 struct puffs_kcn pkcnp
;
102 PUFFS_MAKECRED(pcr
, &global_kcred
);
103 struct puffs_cn pcn
= {&pkcnp
, (struct puffs_cred
*) __UNCONST(pcr
), {0,0,0}};
105 struct timespec cur_time
;
107 if (global_pu
->pu_ops
.puffs_node_mknod
== NULL
) {
108 lpuffs_debug("No puffs_node_mknod");
112 /* Copy the last component */
113 pcn
.pcn_namelen
= strlen(name
);
114 assert(pcn
.pcn_namelen
<= NAME_MAX
);
115 strcpy(pcn
.pcn_name
, name
);
117 /* Get last directory pnode */
118 if ((pn_dir
= puffs_pn_nodewalk(global_pu
, find_inode_cb
, &dir_nr
)) == NULL
)
121 memset(&pni
, 0, sizeof(pni
));
122 pni
.pni_cookie
= (void** )&pn
;
124 (void)clock_time(&cur_time
);
126 memset(&va
, 0, sizeof(va
));
132 va
.va_atime
= va
.va_mtime
= va
.va_ctime
= cur_time
;
135 if (puffs_path_pcnbuild(global_pu
, &pcn
, pn_dir
) != 0) {
136 lpuffs_debug("pathbuild error\n");
141 r
= global_pu
->pu_ops
.puffs_node_mknod(global_pu
, pn_dir
, &pni
, &pcn
, &va
);
144 global_pu
->pu_pathfree(global_pu
, &pcn
.pcn_po_full
);
146 struct puffs_node
*_pn
;
148 _pn
= PU_CMAP(global_pu
, pn
);
149 _pn
->pn_po
= pcn
.pcn_po_full
;
158 update_timens(pn_dir
, MTIME
| CTIME
, &cur_time
);
164 /*===========================================================================*
166 *===========================================================================*/
167 int fs_mkdir(ino_t dir_nr
, char *name
, mode_t mode
, uid_t uid
, gid_t gid
)
170 struct puffs_node
*pn_dir
;
171 struct puffs_node
*pn
;
172 struct puffs_newinfo pni
;
173 struct puffs_kcn pkcnp
;
174 PUFFS_MAKECRED(pcr
, &global_kcred
);
175 struct puffs_cn pcn
= {&pkcnp
, (struct puffs_cred
*) __UNCONST(pcr
), {0,0,0}};
177 struct timespec cur_time
;
179 if (global_pu
->pu_ops
.puffs_node_mkdir
== NULL
) {
180 lpuffs_debug("No puffs_node_mkdir");
184 /* Copy the last component */
185 pcn
.pcn_namelen
= strlen(name
);
186 assert(pcn
.pcn_namelen
<= NAME_MAX
);
187 strcpy(pcn
.pcn_name
, name
);
189 /* Get last directory pnode */
190 if ((pn_dir
= puffs_pn_nodewalk(global_pu
, find_inode_cb
, &dir_nr
)) == NULL
)
193 (void)clock_time(&cur_time
);
195 memset(&pni
, 0, sizeof(pni
));
196 pni
.pni_cookie
= (void** )&pn
;
198 memset(&va
, 0, sizeof(va
));
203 va
.va_atime
= va
.va_mtime
= va
.va_ctime
= cur_time
;
206 r
= puffs_path_pcnbuild(global_pu
, &pcn
, pn_dir
);
208 lpuffs_debug("pathbuild error\n");
213 r
= global_pu
->pu_ops
.puffs_node_mkdir(global_pu
, pn_dir
, &pni
, &pcn
, &va
);
216 global_pu
->pu_pathfree(global_pu
, &pcn
.pcn_po_full
);
218 struct puffs_node
*_pn
;
220 _pn
= PU_CMAP(global_pu
, pn
);
221 _pn
->pn_po
= pcn
.pcn_po_full
;
230 update_timens(pn_dir
, MTIME
| CTIME
, &cur_time
);
236 /*===========================================================================*
238 *===========================================================================*/
239 int fs_slink(ino_t dir_nr
, char *name
, uid_t uid
, gid_t gid
,
240 struct fsdriver_data
*data
, size_t bytes
)
243 struct pnode
*pn
; /* pnode containing symbolic link */
244 struct pnode
*pn_dir
; /* directory containing link */
245 char target
[PATH_MAX
+ 1]; /* target path */
246 struct puffs_newinfo pni
;
247 struct puffs_kcn pkcnp
;
248 PUFFS_MAKECRED(pcr
, &global_kcred
);
249 struct puffs_cn pcn
= {&pkcnp
, (struct puffs_cred
*) __UNCONST(pcr
), {0,0,0}};
251 struct timespec cur_time
;
253 /* Copy the link name's last component */
254 pcn
.pcn_namelen
= strlen(name
);
255 if (pcn
.pcn_namelen
> NAME_MAX
)
256 return(ENAMETOOLONG
);
257 strcpy(pcn
.pcn_name
, name
);
259 if (bytes
>= PATH_MAX
)
260 return(ENAMETOOLONG
);
262 /* Copy the target path (note that it's not null terminated) */
263 if ((r
= fsdriver_copyin(data
, 0, target
, bytes
)) != OK
)
266 target
[bytes
] = '\0';
268 if (strlen(target
) != bytes
) {
269 /* This can happen if the user provides a buffer
270 * with a \0 in it. This can cause a lot of trouble
271 * when the symlink is used later. We could just use
272 * the strlen() value, but we want to let the user
273 * know he did something wrong. ENAMETOOLONG doesn't
274 * exactly describe the error, but there is no
277 return(ENAMETOOLONG
);
280 if ((pn_dir
= puffs_pn_nodewalk(global_pu
, find_inode_cb
, &dir_nr
)) == NULL
)
283 memset(&pni
, 0, sizeof(pni
));
284 pni
.pni_cookie
= (void** )&pn
;
286 (void)clock_time(&cur_time
);
288 memset(&va
, 0, sizeof(va
));
290 va
.va_mode
= (I_SYMBOLIC_LINK
| RWX_MODES
);
293 va
.va_atime
= va
.va_mtime
= va
.va_ctime
= cur_time
;
296 r
= puffs_path_pcnbuild(global_pu
, &pcn
, pn_dir
);
298 lpuffs_debug("pathbuild error\n");
303 r
= global_pu
->pu_ops
.puffs_node_symlink(global_pu
, pn_dir
, &pni
, &pcn
, &va
, target
);
306 global_pu
->pu_pathfree(global_pu
, &pcn
.pcn_po_full
);
308 struct puffs_node
*_pn
;
310 _pn
= PU_CMAP(global_pu
, pn
);
311 _pn
->pn_po
= pcn
.pcn_po_full
;