Sun Oct 3 05:46:48 2010 UTC ()
- Correctly handle rename whith overwritten destination
- Keep track of file name to avoid lookups when we can. This makes sure we
  do not have two cookies for the same inode, a situation that cause wreak
  havoc when we come to remove or rename a node.
- Do not use PUFFS_FLAG_BUILDPATH at all, since we now track file names
- In open, queue requests after checking for access, as there is no merit
  to queue a will-be-denied request while we can deny it immediatly
- request reclaim of removed nodes at inactive stage


(manu)
diff -r1.4 -r1.5 src/lib/libperfuse/debug.c
diff -r1.18 -r1.19 src/lib/libperfuse/ops.c
diff -r1.9 -r1.10 src/lib/libperfuse/perfuse.c
diff -r1.13 -r1.14 src/lib/libperfuse/perfuse_priv.h
diff -r1.7 -r1.8 src/lib/libperfuse/subr.c

cvs diff -r1.4 -r1.5 src/lib/libperfuse/debug.c (expand / switch to unified diff)

--- src/lib/libperfuse/debug.c 2010/09/29 08:01:10 1.4
+++ src/lib/libperfuse/debug.c 2010/10/03 05:46:47 1.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: debug.c,v 1.4 2010/09/29 08:01:10 manu Exp $ */ 1/* $NetBSD: debug.c,v 1.5 2010/10/03 05:46:47 manu Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved. 4 * Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
5 *  5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 *  14 *
@@ -74,27 +74,27 @@ const struct perfuse_opcode perfuse_opco @@ -74,27 +74,27 @@ const struct perfuse_opcode perfuse_opco
74 { FUSE_BMAP, "BMAP" }, 74 { FUSE_BMAP, "BMAP" },
75 { FUSE_DESTROY, "DESTROY" }, 75 { FUSE_DESTROY, "DESTROY" },
76 { FUSE_IOCTL, "IOCTL" }, 76 { FUSE_IOCTL, "IOCTL" },
77 { FUSE_POLL, "POLL" }, 77 { FUSE_POLL, "POLL" },
78 { FUSE_CUSE_INIT, "CUSE_INIT" }, 78 { FUSE_CUSE_INIT, "CUSE_INIT" },
79 { 0, "UNKNOWN" }, 79 { 0, "UNKNOWN" },
80}; 80};
81 81
82const char *perfuse_qtypestr[] = {  82const char *perfuse_qtypestr[] = {
83 "READDIR", 83 "READDIR",
84 "READ", 84 "READ",
85 "WRITE", 85 "WRITE",
86 "AFTERWRITE", 86 "AFTERWRITE",
87 "OPEN" 87 "OPEN",
88 "AFTERXCHG" 88 "AFTERXCHG"
89}; 89};
90 90
91const char * 91const char *
92perfuse_opname(opcode) 92perfuse_opname(opcode)
93 int opcode; 93 int opcode;
94{ 94{
95 const struct perfuse_opcode *po; 95 const struct perfuse_opcode *po;
96 96
97 for (po = perfuse_opcode; po->opcode; po++) { 97 for (po = perfuse_opcode; po->opcode; po++) {
98 if (po->opcode == opcode) 98 if (po->opcode == opcode)
99 return po->opname; 99 return po->opname;
100 } 100 }

cvs diff -r1.18 -r1.19 src/lib/libperfuse/ops.c (expand / switch to unified diff)

--- src/lib/libperfuse/ops.c 2010/09/29 08:01:10 1.18
+++ src/lib/libperfuse/ops.c 2010/10/03 05:46:47 1.19
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ops.c,v 1.18 2010/09/29 08:01:10 manu Exp $ */ 1/* $NetBSD: ops.c,v 1.19 2010/10/03 05:46:47 manu Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved. 4 * Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
5 *  5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 *  14 *
@@ -174,51 +174,59 @@ xchg_msg(pu, opc, pm, len, wait) @@ -174,51 +174,59 @@ xchg_msg(pu, opc, pm, len, wait)
174{ 174{
175 struct perfuse_state *ps; 175 struct perfuse_state *ps;
176 struct perfuse_node_data *pnd; 176 struct perfuse_node_data *pnd;
177 int error; 177 int error;
178 178
179 ps = puffs_getspecific(pu); 179 ps = puffs_getspecific(pu);
180 pnd = NULL; 180 pnd = NULL;
181 if ((struct puffs_node *)opc != NULL) 181 if ((struct puffs_node *)opc != NULL)
182 pnd = PERFUSE_NODE_DATA(opc); 182 pnd = PERFUSE_NODE_DATA(opc);
183 183
184#ifdef PERFUSE_DEBUG 184#ifdef PERFUSE_DEBUG
185 if ((perfuse_diagflags & PDF_FILENAME) && (opc != 0)) 185 if ((perfuse_diagflags & PDF_FILENAME) && (opc != 0))
186 DPRINTF("file = \"%s\" flags = 0x%x\n",  186 DPRINTF("file = \"%s\" flags = 0x%x\n",
187 (char *)PNPATH((struct puffs_node *)opc),  187 perfuse_node_path(opc),
188 PERFUSE_NODE_DATA(opc)->pnd_flags); 188 PERFUSE_NODE_DATA(opc)->pnd_flags);
189#endif 189#endif
190 if (pnd) 190 if (pnd)
191 pnd->pnd_flags |= PND_INXCHG; 191 pnd->pnd_flags |= PND_INXCHG;
192 192
193 error = ps->ps_xchg_msg(pu, pm, len, wait); 193 error = ps->ps_xchg_msg(pu, pm, len, wait);
194 194
195 if (pnd) { 195 if (pnd) {
196 pnd->pnd_flags &= ~PND_INXCHG; 196 pnd->pnd_flags &= ~PND_INXCHG;
197 (void)dequeue_requests(ps, opc, PCQ_AFTERXCHG, DEQUEUE_ALL); 197 (void)dequeue_requests(ps, opc, PCQ_AFTERXCHG, DEQUEUE_ALL);
198 } 198 }
199 199
200 return error; 200 return error;
201} 201}
202 202
203static int 203static int
204no_access(opc, pcr, mode) 204no_access(opc, pcr, mode)
205 puffs_cookie_t opc; 205 puffs_cookie_t opc;
206 const struct puffs_cred *pcr; 206 const struct puffs_cred *pcr;
207 mode_t mode; 207 mode_t mode;
208{ 208{
209 struct puffs_node *pn; 209 struct puffs_node *pn;
210 struct vattr *va; 210 struct vattr *va;
211 211
 212 /*
 213 * pcr is NULL for self open through fsync or readdir.
 214 * In both case, access control is useless, as it was
 215 * done before, at open time.
 216 */
 217 if (pcr == NULL)
 218 return 0;
 219
212 pn = (struct puffs_node *)opc; 220 pn = (struct puffs_node *)opc;
213 va = puffs_pn_getvap(pn); 221 va = puffs_pn_getvap(pn);
214 222
215 return puffs_access(va->va_type, va->va_mode,  223 return puffs_access(va->va_type, va->va_mode,
216 va->va_uid, va->va_gid, 224 va->va_uid, va->va_gid,
217 mode, pcr); 225 mode, pcr);
218} 226}
219 227
220static void 228static void
221fuse_attr_to_vap(ps, vap, fa) 229fuse_attr_to_vap(ps, vap, fa)
222 struct perfuse_state *ps; 230 struct perfuse_state *ps;
223 struct vattr *vap; 231 struct vattr *vap;
224 struct fuse_attr *fa; 232 struct fuse_attr *fa;
@@ -281,62 +289,93 @@ node_lookup_dir_nodot(pu, opc, name, nam @@ -281,62 +289,93 @@ node_lookup_dir_nodot(pu, opc, name, nam
281 *pnp = (struct puffs_node *)opc; 289 *pnp = (struct puffs_node *)opc;
282 return 0; 290 return 0;
283 } 291 }
284 292
285 /* 293 /*
286 * For .. we just forget the name part 294 * For .. we just forget the name part
287 */ 295 */
288 if (strncmp(name, "..", namelen) == 0) 296 if (strncmp(name, "..", namelen) == 0)
289 namelen = 0; 297 namelen = 0;
290 298
291 namelen = PNPLEN(dpn) + 1 + namelen + 1; 299 namelen = PNPLEN(dpn) + 1 + namelen + 1;
292 if ((path = malloc(namelen)) == NULL) 300 if ((path = malloc(namelen)) == NULL)
293 DERR(EX_OSERR, "malloc failed"); 301 DERR(EX_OSERR, "malloc failed");
294 (void)snprintf(path, namelen, "%s/%s", (char *)PNPATH(dpn), name); 302 (void)snprintf(path, namelen, "%s/%s",
 303 perfuse_node_path((puffs_cookie_t)dpn), name);
295 304
296 error = node_lookup_common(pu, opc, path, pnp); 305 error = node_lookup_common(pu, opc, path, pnp);
297  306
298 free(path); 307 free(path);
299 308
300 return error; 309 return error;
301} 310}
302 311
303static int 312static int
304node_lookup_common(pu, opc, path, pnp) 313node_lookup_common(pu, opc, path, pnp)
305 struct puffs_usermount *pu; 314 struct puffs_usermount *pu;
306 puffs_cookie_t opc; 315 puffs_cookie_t opc;
307 const char *path; 316 const char *path;
308 struct puffs_node **pnp; 317 struct puffs_node **pnp;
309{ 318{
310 struct perfuse_state *ps; 319 struct perfuse_state *ps;
 320 struct perfuse_node_data *pnd;
311 perfuse_msg_t *pm; 321 perfuse_msg_t *pm;
312 struct fuse_entry_out *feo; 322 struct fuse_entry_out *feo;
313 struct puffs_node *pn; 323 struct puffs_node *pn;
314 size_t len; 324 size_t len;
315 int error; 325 int error;
316 326
317 ps = puffs_getspecific(pu); 327 ps = puffs_getspecific(pu);
318 328
 329#ifdef PERFUSE_DEBUG
 330 if (perfuse_diagflags & PDF_FILENAME)
 331 DPRINTF("%s: opc = %p, file = \"%s\" looking up \"%s\"\n",
 332 __func__, (void *)opc, perfuse_node_path(opc), path);
 333#endif
 334 /*
 335 * Is the node already known?
 336 */
 337 TAILQ_FOREACH(pnd, &PERFUSE_NODE_DATA(opc)->pnd_children, pnd_next) {
 338 if ((pnd->pnd_flags & PND_REMOVED) ||
 339 (strcmp(pnd->pnd_name, path) != 0))
 340 continue;
 341
 342 /*
 343 * We have a match
 344 */
 345 if (pnp != NULL)
 346 *pnp = (struct puffs_node *)(pnd->pnd_pn);
 347
 348#ifdef PERFUSE_DEBUG
 349 if (perfuse_diagflags & PDF_FILENAME)
 350 DPRINTF("%s: opc = %p, file = \"%s\" found "
 351 "cookie = %p, ino = %"PRId64" for \"%s\"\n",
 352 __func__, (void *)opc, perfuse_node_path(opc),
 353 (void *)pnd->pnd_pn, pnd->pnd_ino, path);
 354#endif
 355 return 0;
 356 }
 357
319 len = strlen(path) + 1; 358 len = strlen(path) + 1;
320 359
321 pm = ps->ps_new_msg(pu, opc, FUSE_LOOKUP, len, NULL); 360 pm = ps->ps_new_msg(pu, opc, FUSE_LOOKUP, len, NULL);
322 (void)strlcpy(_GET_INPAYLOAD(ps, pm, char *), path, len); 361 (void)strlcpy(_GET_INPAYLOAD(ps, pm, char *), path, len);
323 362
324 if ((error = xchg_msg(pu, opc, pm, sizeof(*feo), wait_reply)) != 0) 363 if ((error = xchg_msg(pu, opc, pm, sizeof(*feo), wait_reply)) != 0)
325 goto out; 364 goto out;
326 365
327 feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out); 366 feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out);
328 367
329 pn = perfuse_new_pn(pu, opc); 368 pn = perfuse_new_pn(pu, path, opc);
330 PERFUSE_NODE_DATA(pn)->pnd_ino = feo->nodeid; 369 PERFUSE_NODE_DATA(pn)->pnd_ino = feo->nodeid;
331 370
332 fuse_attr_to_vap(ps, &pn->pn_va, &feo->attr); 371 fuse_attr_to_vap(ps, &pn->pn_va, &feo->attr);
333 372
334 if (pnp != NULL) 373 if (pnp != NULL)
335 *pnp = pn; 374 *pnp = pn;
336 375
337#ifdef PERFUSE_DEBUG 376#ifdef PERFUSE_DEBUG
338 if (perfuse_diagflags & PDF_FILENAME) 377 if (perfuse_diagflags & PDF_FILENAME)
339 DPRINTF("%s: opc = %p, looked up opc = %p, ino = %"PRId64" " 378 DPRINTF("%s: opc = %p, looked up opc = %p, ino = %"PRId64" "
340 "file = \"%s\"\n", __func__, (void *)opc, pn,  379 "file = \"%s\"\n", __func__, (void *)opc, pn,
341 feo->nodeid, path); 380 feo->nodeid, path);
342#endif 381#endif
@@ -366,56 +405,65 @@ node_mk_common(pu, opc, pni, pcn, pm) @@ -366,56 +405,65 @@ node_mk_common(pu, opc, pni, pcn, pm)
366 struct fuse_entry_out *feo; 405 struct fuse_entry_out *feo;
367 struct fuse_setattr_in *fsi; 406 struct fuse_setattr_in *fsi;
368 int error; 407 int error;
369 408
370 ps = puffs_getspecific(pu); 409 ps = puffs_getspecific(pu);
371 410
372 if ((error = xchg_msg(pu, opc, pm, sizeof(*feo), wait_reply)) != 0) 411 if ((error = xchg_msg(pu, opc, pm, sizeof(*feo), wait_reply)) != 0)
373 goto out; 412 goto out;
374 413
375 feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out); 414 feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out);
376 if (feo->nodeid == PERFUSE_UNKNOWN_INO) 415 if (feo->nodeid == PERFUSE_UNKNOWN_INO)
377 DERRX(EX_SOFTWARE, "%s: no ino", __func__); 416 DERRX(EX_SOFTWARE, "%s: no ino", __func__);
378 417
379 pn = perfuse_new_pn(pu, opc); 418 pn = perfuse_new_pn(pu, pcn->pcn_name, opc);
380 PERFUSE_NODE_DATA(pn)->pnd_ino = feo->nodeid; 419 PERFUSE_NODE_DATA(pn)->pnd_ino = feo->nodeid;
381 420
382 fuse_attr_to_vap(ps, &pn->pn_va, &feo->attr); 421 fuse_attr_to_vap(ps, &pn->pn_va, &feo->attr);
383 puffs_newinfo_setcookie(pni, pn); 422 puffs_newinfo_setcookie(pni, pn);
 423
 424#ifdef PERFUSE_DEBUG
 425 if (perfuse_diagflags & PDF_FILENAME)
 426 DPRINTF("%s: opc = %p, file = \"%s\", flags = 0x%x "
 427 "ino = %"PRId64"\n",
 428 __func__, (void *)pn, pcn->pcn_name,
 429 PERFUSE_NODE_DATA(pn)->pnd_flags, feo->nodeid);
 430#endif
384 ps->ps_destroy_msg(pm); 431 ps->ps_destroy_msg(pm);
385  432
386 /*  433 /*
387 * Set owner and group 434 * Set owner and group
388 */ 435 */
389 (void)puffs_cred_getuid(pcn->pcn_cred, &pn->pn_va.va_uid); 436 (void)puffs_cred_getuid(pcn->pcn_cred, &pn->pn_va.va_uid);
390 (void)puffs_cred_getgid(pcn->pcn_cred, &pn->pn_va.va_gid); 437 (void)puffs_cred_getgid(pcn->pcn_cred, &pn->pn_va.va_gid);
391 438
392 pm = ps->ps_new_msg(pu, (puffs_cookie_t)pn,  439 pm = ps->ps_new_msg(pu, (puffs_cookie_t)pn,
393 FUSE_SETATTR, sizeof(*fsi), NULL); 440 FUSE_SETATTR, sizeof(*fsi), NULL);
394 fsi = GET_INPAYLOAD(ps, pm, fuse_setattr_in); 441 fsi = GET_INPAYLOAD(ps, pm, fuse_setattr_in);
395 fsi->uid = pn->pn_va.va_uid; 442 fsi->uid = pn->pn_va.va_uid;
396 fsi->gid = pn->pn_va.va_gid; 443 fsi->gid = pn->pn_va.va_gid;
397 fsi->valid = FUSE_FATTR_UID|FUSE_FATTR_GID; 444 fsi->valid = FUSE_FATTR_UID|FUSE_FATTR_GID;
398 445
399 /* 446 /*
400 * A fuse_attr_out is returned, but we ignore it. 447 * A fuse_attr_out is returned, but we ignore it.
401 */ 448 */
402 error = xchg_msg(pu, (puffs_cookie_t)pn,  449 error = xchg_msg(pu, (puffs_cookie_t)pn,
403 pm, sizeof(struct fuse_attr_out), wait_reply); 450 pm, sizeof(struct fuse_attr_out), wait_reply);
404 451
405 /* 452 /*
406 * The parent directory needs a sync 453 * The parent directory needs a sync
407 */ 454 */
408 PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY; 455 PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY;
 456
409out: 457out:
410 ps->ps_destroy_msg(pm); 458 ps->ps_destroy_msg(pm);
411 459
412 return error; 460 return error;
413} 461}
414 462
415static ssize_t 463static ssize_t
416fuse_to_dirent(pu, opc, fd, fd_len) 464fuse_to_dirent(pu, opc, fd, fd_len)
417 struct puffs_usermount *pu; 465 struct puffs_usermount *pu;
418 puffs_cookie_t opc; 466 puffs_cookie_t opc;
419 struct fuse_dirent *fd; 467 struct fuse_dirent *fd;
420 size_t fd_len; 468 size_t fd_len;
421{ 469{
@@ -985,27 +1033,27 @@ perfuse_node_create(pu, opc, pni, pcn, v @@ -985,27 +1033,27 @@ perfuse_node_create(pu, opc, pni, pcn, v
985 len = sizeof(*feo) + sizeof(*foo); 1033 len = sizeof(*feo) + sizeof(*foo);
986 if ((error = xchg_msg(pu, opc, pm, len, wait_reply)) != 0) 1034 if ((error = xchg_msg(pu, opc, pm, len, wait_reply)) != 0)
987 goto out; 1035 goto out;
988 1036
989 feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out); 1037 feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out);
990 foo = (struct fuse_open_out *)(void *)(feo + 1); 1038 foo = (struct fuse_open_out *)(void *)(feo + 1);
991 if (feo->nodeid == PERFUSE_UNKNOWN_INO) 1039 if (feo->nodeid == PERFUSE_UNKNOWN_INO)
992 DERRX(EX_SOFTWARE, "%s: no ino", __func__); 1040 DERRX(EX_SOFTWARE, "%s: no ino", __func__);
993  1041
994 /* 1042 /*
995 * Save the file handle and inode in node private data  1043 * Save the file handle and inode in node private data
996 * so that we can reuse it later 1044 * so that we can reuse it later
997 */ 1045 */
998 pn = perfuse_new_pn(pu, opc); 1046 pn = perfuse_new_pn(pu, name, opc);
999 perfuse_new_fh((puffs_cookie_t)pn, foo->fh, FWRITE); 1047 perfuse_new_fh((puffs_cookie_t)pn, foo->fh, FWRITE);
1000 PERFUSE_NODE_DATA(pn)->pnd_ino = feo->nodeid; 1048 PERFUSE_NODE_DATA(pn)->pnd_ino = feo->nodeid;
1001 1049
1002 fuse_attr_to_vap(ps, &pn->pn_va, &feo->attr); 1050 fuse_attr_to_vap(ps, &pn->pn_va, &feo->attr);
1003 puffs_newinfo_setcookie(pni, pn); 1051 puffs_newinfo_setcookie(pni, pn);
1004 1052
1005 /* 1053 /*
1006 * The parent directory needs a sync 1054 * The parent directory needs a sync
1007 */ 1055 */
1008 PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY; 1056 PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY;
1009 1057
1010#ifdef PERFUSE_DEBUG 1058#ifdef PERFUSE_DEBUG
1011 if (perfuse_diagflags & (PDF_FH|PDF_FILENAME)) 1059 if (perfuse_diagflags & (PDF_FH|PDF_FILENAME))
@@ -1105,35 +1153,26 @@ perfuse_node_open(pu, opc, mode, pcr) @@ -1105,35 +1153,26 @@ perfuse_node_open(pu, opc, mode, pcr)
1105 struct fuse_open_out *foo; 1153 struct fuse_open_out *foo;
1106 struct puffs_node *pn; 1154 struct puffs_node *pn;
1107 int error; 1155 int error;
1108  1156
1109 ps = puffs_getspecific(pu); 1157 ps = puffs_getspecific(pu);
1110 pn = (struct puffs_node *)opc; 1158 pn = (struct puffs_node *)opc;
1111 pnd = PERFUSE_NODE_DATA(opc); 1159 pnd = PERFUSE_NODE_DATA(opc);
1112 pm = NULL; 1160 pm = NULL;
1113 error = 0; 1161 error = 0;
1114 1162
1115 if (pnd->pnd_flags & PND_REMOVED) 1163 if (pnd->pnd_flags & PND_REMOVED)
1116 return ENOENT; 1164 return ENOENT;
1117 1165
1118 /* 
1119 * Queue open on a node so that we do not open 
1120 * twice. This would be better with read and 
1121 * write distinguished. 
1122 */ 
1123 while (pnd->pnd_flags & PND_INOPEN) 
1124 requeue_request(pu, opc, PCQ_OPEN); 
1125 pnd->pnd_flags |= PND_INOPEN; 
1126 
1127 if (puffs_pn_getvap(pn)->va_type == VDIR) { 1166 if (puffs_pn_getvap(pn)->va_type == VDIR) {
1128 op = FUSE_OPENDIR; 1167 op = FUSE_OPENDIR;
1129 pmode = PUFFS_VREAD|PUFFS_VEXEC; 1168 pmode = PUFFS_VREAD|PUFFS_VEXEC;
1130 } else { 1169 } else {
1131 op = FUSE_OPEN; 1170 op = FUSE_OPEN;
1132 if (mode & FWRITE) 1171 if (mode & FWRITE)
1133 pmode = PUFFS_VWRITE|PUFFS_VREAD; 1172 pmode = PUFFS_VWRITE|PUFFS_VREAD;
1134 else 1173 else
1135 pmode = PUFFS_VREAD; 1174 pmode = PUFFS_VREAD;
1136 } 1175 }
1137 1176
1138 /* 1177 /*
1139 * Opening a directory require R-X on the directory 1178 * Opening a directory require R-X on the directory
@@ -1156,54 +1195,62 @@ perfuse_node_open(pu, opc, mode, pcr) @@ -1156,54 +1195,62 @@ perfuse_node_open(pu, opc, mode, pcr)
1156 * if we already have write handle. Just ask for 1195 * if we already have write handle. Just ask for
1157 * inactive, in case the node was open by a create 1196 * inactive, in case the node was open by a create
1158 * operation (we are not allowed to call puffs_setback 1197 * operation (we are not allowed to call puffs_setback
1159 * at create time, puffs interface forbids it) 1198 * at create time, puffs interface forbids it)
1160 */ 1199 */
1161 if (((mode & FREAD) && (pnd->pnd_flags & PND_RFH)) || 1200 if (((mode & FREAD) && (pnd->pnd_flags & PND_RFH)) ||
1162 ((mode & FREAD) && (pnd->pnd_flags & PND_WFH)) || 1201 ((mode & FREAD) && (pnd->pnd_flags & PND_WFH)) ||
1163 ((mode & FWRITE) && (pnd->pnd_flags & PND_WFH))) { 1202 ((mode & FWRITE) && (pnd->pnd_flags & PND_WFH))) {
1164 error = 0; 1203 error = 0;
1165 goto out; 1204 goto out;
1166 } 1205 }
1167  1206
1168 /* 1207 /*
 1208 * Queue open on a node so that we do not open
 1209 * twice. This would be better with read and
 1210 * write distinguished.
 1211 */
 1212 while (pnd->pnd_flags & PND_INOPEN)
 1213 requeue_request(pu, opc, PCQ_OPEN);
 1214 pnd->pnd_flags |= PND_INOPEN;
 1215
 1216 /*
1169 * Convert PUFFS mode to FUSE mode: convert FREAD/FWRITE 1217 * Convert PUFFS mode to FUSE mode: convert FREAD/FWRITE
1170 * to O_RDONLY/O_WRONLY while perserving the other options. 1218 * to O_RDONLY/O_WRONLY while perserving the other options.
1171 */ 1219 */
1172 fmode = mode & ~(FREAD|FWRITE); 1220 fmode = mode & ~(FREAD|FWRITE);
1173 fmode |= (mode & FWRITE) ? O_RDWR : O_RDONLY; 1221 fmode |= (mode & FWRITE) ? O_RDWR : O_RDONLY;
1174 1222
1175 pm = ps->ps_new_msg(pu, opc, op, sizeof(*foi), pcr); 1223 pm = ps->ps_new_msg(pu, opc, op, sizeof(*foi), pcr);
1176 foi = GET_INPAYLOAD(ps, pm, fuse_open_in); 1224 foi = GET_INPAYLOAD(ps, pm, fuse_open_in);
1177 foi->flags = fmode; 1225 foi->flags = fmode;
1178 foi->unused = 0; 1226 foi->unused = 0;
1179 1227
1180 if ((error = xchg_msg(pu, opc, pm, sizeof(*foo), wait_reply)) != 0) 1228 if ((error = xchg_msg(pu, opc, pm, sizeof(*foo), wait_reply)) != 0)
1181 goto out; 1229 goto out;
1182 1230
1183 foo = GET_OUTPAYLOAD(ps, pm, fuse_open_out); 1231 foo = GET_OUTPAYLOAD(ps, pm, fuse_open_out);
1184 1232
1185 /* 1233 /*
1186 * Save the file handle in node private data  1234 * Save the file handle in node private data
1187 * so that we can reuse it later 1235 * so that we can reuse it later
1188 */ 1236 */
1189 perfuse_new_fh(opc, foo->fh, mode); 1237 perfuse_new_fh(opc, foo->fh, mode);
1190  1238
1191#ifdef PERFUSE_DEBUG 1239#ifdef PERFUSE_DEBUG
1192 if (perfuse_diagflags & (PDF_FH|PDF_FILENAME)) 1240 if (perfuse_diagflags & (PDF_FH|PDF_FILENAME))
1193 DPRINTF("%s: opc = %p, file = \"%s\", " 1241 DPRINTF("%s: opc = %p, file = \"%s\", "
1194 "ino = %"PRId64", %s%sfh = 0x%"PRIx64"\n", 1242 "ino = %"PRId64", %s%sfh = 0x%"PRIx64"\n",
1195 __func__, (void *)opc,  1243 __func__, (void *)opc, perfuse_node_path(opc),
1196 (char *)PNPATH((struct puffs_node *)opc), 
1197 pnd->pnd_ino, mode & FREAD ? "r" : "", 1244 pnd->pnd_ino, mode & FREAD ? "r" : "",
1198 mode & FWRITE ? "w" : "", foo->fh); 1245 mode & FWRITE ? "w" : "", foo->fh);
1199#endif 1246#endif
1200 1247
1201out: 1248out:
1202 if (pm != NULL) 1249 if (pm != NULL)
1203 ps->ps_destroy_msg(pm); 1250 ps->ps_destroy_msg(pm);
1204 1251
1205 pnd->pnd_flags &= ~PND_INOPEN; 1252 pnd->pnd_flags &= ~PND_INOPEN;
1206 (void)dequeue_requests(ps, opc, PCQ_OPEN, DEQUEUE_ALL); 1253 (void)dequeue_requests(ps, opc, PCQ_OPEN, DEQUEUE_ALL);
1207 1254
1208 return error; 1255 return error;
1209} 1256}
@@ -1631,28 +1678,27 @@ perfuse_node_fsync(pu, opc, pcr, flags,  @@ -1631,28 +1678,27 @@ perfuse_node_fsync(pu, opc, pcr, flags,
1631 1678
1632 if (puffs_pn_getvap((struct puffs_node *)opc)->va_type == VDIR)  1679 if (puffs_pn_getvap((struct puffs_node *)opc)->va_type == VDIR)
1633 op = FUSE_FSYNCDIR; 1680 op = FUSE_FSYNCDIR;
1634 else /* VREG but also other types such as VLNK */ 1681 else /* VREG but also other types such as VLNK */
1635 op = FUSE_FSYNC; 1682 op = FUSE_FSYNC;
1636 1683
1637 /* 1684 /*
1638 * Do not sync if there are no change to sync 1685 * Do not sync if there are no change to sync
1639 * XXX remove that test on files if we implement mmap 1686 * XXX remove that test on files if we implement mmap
1640 */ 1687 */
1641#ifdef PERFUSE_DEBUG 1688#ifdef PERFUSE_DEBUG
1642 if (perfuse_diagflags & PDF_SYNC) 1689 if (perfuse_diagflags & PDF_SYNC)
1643 DPRINTF("%s: TEST opc = %p, file = \"%s\" is %sdirty\n",  1690 DPRINTF("%s: TEST opc = %p, file = \"%s\" is %sdirty\n",
1644 __func__, (void*)opc, 1691 __func__, (void*)opc, perfuse_node_path(opc),
1645 (char *)PNPATH((struct puffs_node *)opc), 
1646 pnd->pnd_flags & PND_DIRTY ? "" : "not "); 1692 pnd->pnd_flags & PND_DIRTY ? "" : "not ");
1647#endif 1693#endif
1648 if (!(pnd->pnd_flags & PND_DIRTY)) 1694 if (!(pnd->pnd_flags & PND_DIRTY))
1649 return 0; 1695 return 0;
1650 1696
1651 /* 1697 /*
1652 * It seems NetBSD can call fsync without open first 1698 * It seems NetBSD can call fsync without open first
1653 * glusterfs complain in such a situation: 1699 * glusterfs complain in such a situation:
1654 * "FSYNC() ERR => -1 (Invalid argument)" 1700 * "FSYNC() ERR => -1 (Invalid argument)"
1655 * The file will be closed at inactive time. 1701 * The file will be closed at inactive time.
1656 *  1702 *
1657 * We open the directory for reading in order to sync. 1703 * We open the directory for reading in order to sync.
1658 * This sounds rather counterintuitive, but it works. 1704 * This sounds rather counterintuitive, but it works.
@@ -1685,28 +1731,27 @@ perfuse_node_fsync(pu, opc, pcr, flags,  @@ -1685,28 +1731,27 @@ perfuse_node_fsync(pu, opc, pcr, flags,
1685 if ((error = xchg_msg(pu, opc, pm,  1731 if ((error = xchg_msg(pu, opc, pm,
1686 NO_PAYLOAD_REPLY_LEN, wait_reply)) != 0) 1732 NO_PAYLOAD_REPLY_LEN, wait_reply)) != 0)
1687 goto out;  1733 goto out;
1688 1734
1689 /* 1735 /*
1690 * No reply beyond fuse_out_header: nothing to do on success 1736 * No reply beyond fuse_out_header: nothing to do on success
1691 * just clear the dirty flag 1737 * just clear the dirty flag
1692 */ 1738 */
1693 pnd->pnd_flags &= ~PND_DIRTY; 1739 pnd->pnd_flags &= ~PND_DIRTY;
1694 1740
1695#ifdef PERFUSE_DEBUG 1741#ifdef PERFUSE_DEBUG
1696 if (perfuse_diagflags & PDF_SYNC) 1742 if (perfuse_diagflags & PDF_SYNC)
1697 DPRINTF("%s: CLEAR opc = %p, file = \"%s\"\n",  1743 DPRINTF("%s: CLEAR opc = %p, file = \"%s\"\n",
1698 __func__, (void*)opc, 1744 __func__, (void*)opc, perfuse_node_path(opc));
1699 (char *)PNPATH((struct puffs_node *)opc)); 
1700#endif 1745#endif
1701 1746
1702out: 1747out:
1703 /* 1748 /*
1704 * ENOSYS is not returned to kernel, 1749 * ENOSYS is not returned to kernel,
1705 */ 1750 */
1706 if (error == ENOSYS) 1751 if (error == ENOSYS)
1707 error = 0; 1752 error = 0;
1708 1753
1709 if (pm != NULL) 1754 if (pm != NULL)
1710 ps->ps_destroy_msg(pm); 1755 ps->ps_destroy_msg(pm);
1711 1756
1712 return error; 1757 return error;
@@ -1762,40 +1807,39 @@ perfuse_node_remove(pu, opc, targ, pcn) @@ -1762,40 +1807,39 @@ perfuse_node_remove(pu, opc, targ, pcn)
1762 */ 1807 */
1763 if (no_access((puffs_cookie_t)pnd->pnd_parent, 1808 if (no_access((puffs_cookie_t)pnd->pnd_parent,
1764 pcn->pcn_cred, PUFFS_VWRITE|PUFFS_VEXEC)) 1809 pcn->pcn_cred, PUFFS_VWRITE|PUFFS_VEXEC))
1765 return EACCES; 1810 return EACCES;
1766 1811
1767#ifdef PERFUSE_DEBUG 1812#ifdef PERFUSE_DEBUG
1768 if (targ == NULL) 1813 if (targ == NULL)
1769 DERRX(EX_SOFTWARE, "%s: targ is NULL", __func__); 1814 DERRX(EX_SOFTWARE, "%s: targ is NULL", __func__);
1770 1815
1771 if (perfuse_diagflags & (PDF_FH|PDF_FILENAME)) 1816 if (perfuse_diagflags & (PDF_FH|PDF_FILENAME))
1772 DPRINTF("%s: opc = %p, remove opc = %p, file = \"%s\"\n", 1817 DPRINTF("%s: opc = %p, remove opc = %p, file = \"%s\"\n",
1773 __func__, (void *)opc, (void *)targ, pcn->pcn_name); 1818 __func__, (void *)opc, (void *)targ, pcn->pcn_name);
1774#endif 1819#endif
1775 
1776 ps = puffs_getspecific(pu); 
1777 pnd = PERFUSE_NODE_DATA(opc); 
1778 name = pcn->pcn_name; 
1779 len = pcn->pcn_namelen + 1; 
1780 
1781 /* 1820 /*
1782 * Await for all operations on the deleted node to drain,  1821 * Await for all operations on the deleted node to drain,
1783 * as the filesystem may be confused to have it deleted 1822 * as the filesystem may be confused to have it deleted
1784 * during a getattr 1823 * during a getattr
1785 */ 1824 */
1786 while (PERFUSE_NODE_DATA(targ)->pnd_flags & PND_INXCHG) 1825 while (PERFUSE_NODE_DATA(targ)->pnd_flags & PND_INXCHG)
1787 requeue_request(pu, targ, PCQ_AFTERXCHG); 1826 requeue_request(pu, targ, PCQ_AFTERXCHG);
1788 1827
 1828 ps = puffs_getspecific(pu);
 1829 pnd = PERFUSE_NODE_DATA(opc);
 1830 name = pcn->pcn_name;
 1831 len = pcn->pcn_namelen + 1;
 1832
1789 pm = ps->ps_new_msg(pu, opc, FUSE_UNLINK, len, pcn->pcn_cred); 1833 pm = ps->ps_new_msg(pu, opc, FUSE_UNLINK, len, pcn->pcn_cred);
1790 path = _GET_INPAYLOAD(ps, pm, char *); 1834 path = _GET_INPAYLOAD(ps, pm, char *);
1791 (void)strlcpy(path, name, len); 1835 (void)strlcpy(path, name, len);
1792 1836
1793 if ((error = xchg_msg(pu, opc, pm, UNSPEC_REPLY_LEN, wait_reply)) != 0) 1837 if ((error = xchg_msg(pu, opc, pm, UNSPEC_REPLY_LEN, wait_reply)) != 0)
1794 goto out; 1838 goto out;
1795 1839
1796 PERFUSE_NODE_DATA(targ)->pnd_flags |= PND_REMOVED; 1840 PERFUSE_NODE_DATA(targ)->pnd_flags |= PND_REMOVED;
1797 if (!(PERFUSE_NODE_DATA(targ)->pnd_flags & PND_OPEN)) 1841 if (!(PERFUSE_NODE_DATA(targ)->pnd_flags & PND_OPEN))
1798 puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N2); 1842 puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N2);
1799 1843
1800 /* 1844 /*
1801 * The parent directory needs a sync 1845 * The parent directory needs a sync
@@ -1910,68 +1954,62 @@ perfuse_node_rename(pu, opc, src, pcn_sr @@ -1910,68 +1954,62 @@ perfuse_node_rename(pu, opc, src, pcn_sr
1910 1954
1911 len = sizeof(*fri) + oldname_len + newname_len; 1955 len = sizeof(*fri) + oldname_len + newname_len;
1912 pm = ps->ps_new_msg(pu, opc, FUSE_RENAME, len, pcn_src->pcn_cred); 1956 pm = ps->ps_new_msg(pu, opc, FUSE_RENAME, len, pcn_src->pcn_cred);
1913 fri = GET_INPAYLOAD(ps, pm, fuse_rename_in); 1957 fri = GET_INPAYLOAD(ps, pm, fuse_rename_in);
1914 fri->newdir = PERFUSE_NODE_DATA(targ_dir)->pnd_ino; 1958 fri->newdir = PERFUSE_NODE_DATA(targ_dir)->pnd_ino;
1915 np = (char *)(void *)(fri + 1); 1959 np = (char *)(void *)(fri + 1);
1916 (void)strlcpy(np, oldname, oldname_len); 1960 (void)strlcpy(np, oldname, oldname_len);
1917 np += oldname_len; 1961 np += oldname_len;
1918 (void)strlcpy(np, newname, newname_len); 1962 (void)strlcpy(np, newname, newname_len);
1919 1963
1920 if ((error = xchg_msg(pu, opc, pm, UNSPEC_REPLY_LEN, wait_reply)) != 0) 1964 if ((error = xchg_msg(pu, opc, pm, UNSPEC_REPLY_LEN, wait_reply)) != 0)
1921 goto out; 1965 goto out;
1922 1966
1923 PERFUSE_NODE_DATA(opc)->pnd_childcount--; 1967 if (opc != targ_dir) {
1924 PERFUSE_NODE_DATA(targ_dir)->pnd_childcount++; 1968 struct perfuse_node_data *srcdir_pnd;
 1969 struct perfuse_node_data *dstdir_pnd;
 1970 struct perfuse_node_data *src_pnd;
 1971
 1972 srcdir_pnd = PERFUSE_NODE_DATA(opc);
 1973 dstdir_pnd = PERFUSE_NODE_DATA(targ_dir);
 1974 src_pnd = PERFUSE_NODE_DATA(src);
1925 1975
1926 PERFUSE_NODE_DATA(src)->pnd_parent = targ_dir; 1976 TAILQ_REMOVE(&srcdir_pnd->pnd_children, src_pnd, pnd_next);
 1977 TAILQ_INSERT_TAIL(&dstdir_pnd->pnd_children, src_pnd, pnd_next);
1927 1978
1928 PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY; 1979 srcdir_pnd->pnd_childcount--;
1929 PERFUSE_NODE_DATA(targ_dir)->pnd_flags |= PND_DIRTY; 1980 dstdir_pnd->pnd_childcount++;
1930 1981
1931 if ((struct puffs_node *)targ != NULL) { 1982 src_pnd->pnd_parent = targ_dir;
1932 struct perfuse_node_data *targ_pnd; 
1933 struct perfuse_node_data *src_pnd; 
1934 1983
1935 /* 1984 PERFUSE_NODE_DATA(targ_dir)->pnd_flags |= PND_DIRTY;
1936 * We overwrite a node. src must be freed, as it  
1937 * is associated in kernel with the old path. We 
1938 * therefore have to transfer perfuse_node_data 
1939 * from src to targ. 
1940 *  
1941 * src cannot be destroyed here as setback is not 
1942 * allowed in rename operation. The node is tagged 
1943 * with PND_REMOVED, it will be disposed at inactive 
1944 * time. 
1945 */ 
1946 targ_pnd = PERFUSE_NODE_DATA(targ); 
1947 src_pnd = PERFUSE_NODE_DATA(src); 
1948 puffs_pn_setpriv((struct puffs_node *)targ, src_pnd); 
1949 puffs_pn_setpriv((struct puffs_node *)src, targ_pnd); 
1950 
1951 PERFUSE_NODE_DATA(src)->pnd_flags |= PND_REMOVED; 
1952 } 1985 }
1953 1986
 1987 (void)strlcpy(PERFUSE_NODE_DATA(src)->pnd_name, newname, MAXPATHLEN);
 1988
 1989 PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY;
 1990
 1991 if ((struct puffs_node *)targ != NULL)
 1992 PERFUSE_NODE_DATA(targ)->pnd_flags |= PND_REMOVED;
 1993
1954#ifdef PERFUSE_DEBUG 1994#ifdef PERFUSE_DEBUG
1955 if (perfuse_diagflags & PDF_FILENAME) 1995 if (perfuse_diagflags & PDF_FILENAME)
1956 DPRINTF("%s: nodeid = %"PRId64" file = \"%s\" renamed \"%s\" " 1996 DPRINTF("%s: nodeid = %"PRId64" file = \"%s\" renamed \"%s\" "
1957 "from nodeid = %"PRId64" \"%s\" " 1997 "nodeid = %"PRId64" -> nodeid = %"PRId64" \"%s\"\n",
1958 "to nodeid = %"PRId64" \"%s\"\n", 1998 __func__, PERFUSE_NODE_DATA(src)->pnd_ino,
1959 __func__,  1999 pcn_src->pcn_name, pcn_targ->pcn_name,
1960 PERFUSE_NODE_DATA(src)->pnd_ino, pcn_src->pcn_name, 2000 PERFUSE_NODE_DATA(opc)->pnd_ino,
1961 pcn_targ->pcn_name, PERFUSE_NODE_DATA(opc)->pnd_ino, 
1962 (char *)PNPATH((struct puffs_node *)targ_dir), 
1963 PERFUSE_NODE_DATA(targ_dir)->pnd_ino, 2001 PERFUSE_NODE_DATA(targ_dir)->pnd_ino,
1964 (char *)PNPATH((struct puffs_node *)opc)); 2002 perfuse_node_path(targ_dir));
1965#endif 2003#endif
1966 2004
1967out: 2005out:
1968 if (pm != NULL) 2006 if (pm != NULL)
1969 ps->ps_destroy_msg(pm); 2007 ps->ps_destroy_msg(pm);
1970 2008
1971 return error; 2009 return error;
1972} 2010}
1973 2011
1974int 2012int
1975perfuse_node_mkdir(pu, opc, pni, pcn, vap) 2013perfuse_node_mkdir(pu, opc, pni, pcn, vap)
1976 struct puffs_usermount *pu; 2014 struct puffs_usermount *pu;
1977 puffs_cookie_t opc; 2015 puffs_cookie_t opc;
@@ -2034,52 +2072,51 @@ perfuse_node_rmdir(pu, opc, targ, pcn) @@ -2034,52 +2072,51 @@ perfuse_node_rmdir(pu, opc, targ, pcn)
2034 */ 2072 */
2035 if (no_access((puffs_cookie_t)pnd->pnd_parent, 2073 if (no_access((puffs_cookie_t)pnd->pnd_parent,
2036 pcn->pcn_cred, PUFFS_VWRITE|PUFFS_VEXEC)) 2074 pcn->pcn_cred, PUFFS_VWRITE|PUFFS_VEXEC))
2037 return EACCES; 2075 return EACCES;
2038 2076
2039 /* 2077 /*
2040 * Await for all operations on the deleted node to drain,  2078 * Await for all operations on the deleted node to drain,
2041 * as the filesystem may be confused to have it deleted 2079 * as the filesystem may be confused to have it deleted
2042 * during a getattr 2080 * during a getattr
2043 */ 2081 */
2044 while (PERFUSE_NODE_DATA(targ)->pnd_flags & PND_INXCHG) 2082 while (PERFUSE_NODE_DATA(targ)->pnd_flags & PND_INXCHG)
2045 requeue_request(pu, targ, PCQ_AFTERXCHG); 2083 requeue_request(pu, targ, PCQ_AFTERXCHG);
2046 2084
2047 
2048 ps = puffs_getspecific(pu); 2085 ps = puffs_getspecific(pu);
2049 name = pcn->pcn_name; 2086 name = pcn->pcn_name;
2050 len = pcn->pcn_namelen + 1; 2087 len = pcn->pcn_namelen + 1;
2051 2088
2052 pm = ps->ps_new_msg(pu, opc, FUSE_RMDIR, len, pcn->pcn_cred); 2089 pm = ps->ps_new_msg(pu, opc, FUSE_RMDIR, len, pcn->pcn_cred);
2053 path = _GET_INPAYLOAD(ps, pm, char *); 2090 path = _GET_INPAYLOAD(ps, pm, char *);
2054 (void)strlcpy(path, name, len); 2091 (void)strlcpy(path, name, len);
2055 2092
2056 if ((error = xchg_msg(pu, opc, pm, UNSPEC_REPLY_LEN, wait_reply)) != 0) 2093 if ((error = xchg_msg(pu, opc, pm, UNSPEC_REPLY_LEN, wait_reply)) != 0)
2057 goto out; 2094 goto out;
2058 2095
2059 PERFUSE_NODE_DATA(targ)->pnd_flags |= PND_REMOVED; 2096 PERFUSE_NODE_DATA(targ)->pnd_flags |= PND_REMOVED;
2060 if (!(PERFUSE_NODE_DATA(targ)->pnd_flags & PND_OPEN)) 2097 if (!(PERFUSE_NODE_DATA(targ)->pnd_flags & PND_OPEN))
2061 puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N2); 2098 puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N2);
2062 2099
2063 /* 2100 /*
2064 * The parent directory needs a sync 2101 * The parent directory needs a sync
2065 */ 2102 */
2066 PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY; 2103 PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY;
2067 2104
2068#ifdef PERFUSE_DEBUG 2105#ifdef PERFUSE_DEBUG
2069 if (perfuse_diagflags & PDF_FILENAME) 2106 if (perfuse_diagflags & PDF_FILENAME)
2070 DPRINTF("%s: remove nodeid = %"PRId64" file = \"%s\"\n", 2107 DPRINTF("%s: remove nodeid = %"PRId64" file = \"%s\"\n",
2071 __func__, PERFUSE_NODE_DATA(targ)->pnd_ino, 2108 __func__, PERFUSE_NODE_DATA(targ)->pnd_ino,
2072 (char *)PNPATH((struct puffs_node *)targ)); 2109 perfuse_node_path(targ));
2073#endif 2110#endif
2074out: 2111out:
2075 ps->ps_destroy_msg(pm); 2112 ps->ps_destroy_msg(pm);
2076 2113
2077 return error; 2114 return error;
2078} 2115}
2079 2116
2080/* vap is unused */ 2117/* vap is unused */
2081/* ARGSUSED4 */ 2118/* ARGSUSED4 */
2082int 2119int
2083perfuse_node_symlink(pu, opc, pni, pcn_src, vap, link_target) 2120perfuse_node_symlink(pu, opc, pni, pcn_src, vap, link_target)
2084 struct puffs_usermount *pu; 2121 struct puffs_usermount *pu;
2085 puffs_cookie_t opc; 2122 puffs_cookie_t opc;
@@ -2359,41 +2396,41 @@ perfuse_node_reclaim(pu, opc) @@ -2359,41 +2396,41 @@ perfuse_node_reclaim(pu, opc)
2359 pnd = PERFUSE_NODE_DATA(opc); 2396 pnd = PERFUSE_NODE_DATA(opc);
2360 2397
2361 /* 2398 /*
2362 * Never forget the root. 2399 * Never forget the root.
2363 */ 2400 */
2364 if (pnd->pnd_ino == FUSE_ROOT_ID) 2401 if (pnd->pnd_ino == FUSE_ROOT_ID)
2365 return 0; 2402 return 0;
2366 2403
2367 pnd->pnd_flags |= PND_RECLAIMED; 2404 pnd->pnd_flags |= PND_RECLAIMED;
2368 2405
2369#ifdef PERFUSE_DEBUG 2406#ifdef PERFUSE_DEBUG
2370 if (perfuse_diagflags & PDF_RECLAIM) 2407 if (perfuse_diagflags & PDF_RECLAIM)
2371 DPRINTF("%s (nodeid %"PRId64") reclaimed\n",  2408 DPRINTF("%s (nodeid %"PRId64") reclaimed\n",
2372 (char *)PNPATH((struct puffs_node *)opc), pnd->pnd_ino); 2409 perfuse_node_path(opc), pnd->pnd_ino);
2373#endif 2410#endif
2374 2411
2375 pn_root = puffs_getroot(pu); 2412 pn_root = puffs_getroot(pu);
2376 pn = (struct puffs_node *)opc; 2413 pn = (struct puffs_node *)opc;
2377 while (pn != pn_root) { 2414 while (pn != pn_root) {
2378 struct puffs_node *parent_pn; 2415 struct puffs_node *parent_pn;
2379  2416
2380 pnd = PERFUSE_NODE_DATA(pn); 2417 pnd = PERFUSE_NODE_DATA(pn);
2381 2418
2382#ifdef PERFUSE_DEBUG 2419#ifdef PERFUSE_DEBUG
2383 if (perfuse_diagflags & PDF_RECLAIM) 2420 if (perfuse_diagflags & PDF_RECLAIM)
2384 DPRINTF("%s (nodeid %"PRId64") is %sreclaimed, " 2421 DPRINTF("%s (nodeid %"PRId64") is %sreclaimed, "
2385 "has childcount %d %s%s%s%s, pending ops:%s%s%s\n",  2422 "has childcount %d %s%s%s%s, pending ops:%s%s%s\n",
2386 (char *)PNPATH(pn), pnd->pnd_ino, 2423 perfuse_node_path((puffs_cookie_t)pn), pnd->pnd_ino,
2387 pnd->pnd_flags & PND_RECLAIMED ? "" : "not ", 2424 pnd->pnd_flags & PND_RECLAIMED ? "" : "not ",
2388 pnd->pnd_childcount, 2425 pnd->pnd_childcount,
2389 pnd->pnd_flags & PND_OPEN ? "open " : "not open", 2426 pnd->pnd_flags & PND_OPEN ? "open " : "not open",
2390 pnd->pnd_flags & PND_RFH ? "r" : "", 2427 pnd->pnd_flags & PND_RFH ? "r" : "",
2391 pnd->pnd_flags & PND_WFH ? "w" : "", 2428 pnd->pnd_flags & PND_WFH ? "w" : "",
2392 pnd->pnd_flags & PND_BUSY ? "" : " none", 2429 pnd->pnd_flags & PND_BUSY ? "" : " none",
2393 pnd->pnd_flags & PND_INREADDIR ? " readdir" : "", 2430 pnd->pnd_flags & PND_INREADDIR ? " readdir" : "",
2394 pnd->pnd_flags & PND_INWRITE ? " write" : "", 2431 pnd->pnd_flags & PND_INWRITE ? " write" : "",
2395 pnd->pnd_flags & PND_INOPEN ? " open" : ""); 2432 pnd->pnd_flags & PND_INOPEN ? " open" : "");
2396#endif 2433#endif
2397 2434
2398 if (!(pnd->pnd_flags & PND_RECLAIMED) || 2435 if (!(pnd->pnd_flags & PND_RECLAIMED) ||
2399 (pnd->pnd_childcount != 0)) 2436 (pnd->pnd_childcount != 0))
@@ -2430,28 +2467,30 @@ perfuse_node_reclaim(pu, opc) @@ -2430,28 +2467,30 @@ perfuse_node_reclaim(pu, opc)
2430 perfuse_destroy_pn(pu, pn); 2467 perfuse_destroy_pn(pu, pn);
2431 2468
2432 pn = parent_pn; 2469 pn = parent_pn;
2433 } 2470 }
2434 2471
2435 return 0; 2472 return 0;
2436} 2473}
2437 2474
2438int  2475int
2439perfuse_node_inactive(pu, opc) 2476perfuse_node_inactive(pu, opc)
2440 struct puffs_usermount *pu; 2477 struct puffs_usermount *pu;
2441 puffs_cookie_t opc; 2478 puffs_cookie_t opc;
2442{ 2479{
 2480 struct perfuse_state *ps;
2443 struct perfuse_node_data *pnd; 2481 struct perfuse_node_data *pnd;
2444 2482
 2483 ps = puffs_getspecific(pu);
2445 pnd = PERFUSE_NODE_DATA(opc); 2484 pnd = PERFUSE_NODE_DATA(opc);
2446 2485
2447 if (!(pnd->pnd_flags & (PND_OPEN|PND_REMOVED))) 2486 if (!(pnd->pnd_flags & (PND_OPEN|PND_REMOVED)))
2448 return 0; 2487 return 0;
2449 2488
2450 /* 2489 /*
2451 * Make sure all operation are finished 2490 * Make sure all operation are finished
2452 * There can be an ongoing write. Other 2491 * There can be an ongoing write. Other
2453 * operation wait for all data before  2492 * operation wait for all data before
2454 * the close/inactive. 2493 * the close/inactive.
2455 */ 2494 */
2456 while (pnd->pnd_flags & PND_INWRITE) 2495 while (pnd->pnd_flags & PND_INWRITE)
2457 requeue_request(pu, opc, PCQ_AFTERWRITE); 2496 requeue_request(pu, opc, PCQ_AFTERWRITE);
@@ -2471,31 +2510,38 @@ perfuse_node_inactive(pu, opc) @@ -2471,31 +2510,38 @@ perfuse_node_inactive(pu, opc)
2471 */ 2510 */
2472 if (pnd->pnd_flags & PND_DIRTY) 2511 if (pnd->pnd_flags & PND_DIRTY)
2473 (void)perfuse_node_fsync(pu, opc, NULL, 0, 0, 0); 2512 (void)perfuse_node_fsync(pu, opc, NULL, 0, 0, 0);
2474  2513
2475 /* 2514 /*
2476 * Close handles 2515 * Close handles
2477 */ 2516 */
2478 if (pnd->pnd_flags & PND_WFH) 2517 if (pnd->pnd_flags & PND_WFH)
2479 (void)perfuse_node_close_common(pu, opc, FWRITE); 2518 (void)perfuse_node_close_common(pu, opc, FWRITE);
2480 2519
2481 if (pnd->pnd_flags & PND_RFH) 2520 if (pnd->pnd_flags & PND_RFH)
2482 (void)perfuse_node_close_common(pu, opc, FREAD); 2521 (void)perfuse_node_close_common(pu, opc, FREAD);
2483 2522
2484 pnd->pnd_flags &= ~PND_INOPEN; 2523 /*
2485 2524 * This will cause a reclaim to be sent
 2525 */
2486 if (pnd->pnd_flags & PND_REMOVED) 2526 if (pnd->pnd_flags & PND_REMOVED)
2487 puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N1); 2527 puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N1);
2488 2528
 2529 /*
 2530 * Schedule awaiting operations
 2531 */
 2532 pnd->pnd_flags &= ~PND_INOPEN;
 2533 (void)dequeue_requests(ps, opc, PCQ_OPEN, DEQUEUE_ALL);
 2534
2489 return 0; 2535 return 0;
2490} 2536}
2491 2537
2492 2538
2493/* ARGSUSED0 */ 2539/* ARGSUSED0 */
2494int  2540int
2495perfuse_node_print(pu, opc) 2541perfuse_node_print(pu, opc)
2496 struct puffs_usermount *pu; 2542 struct puffs_usermount *pu;
2497 puffs_cookie_t opc; 2543 puffs_cookie_t opc;
2498{ 2544{
2499 DERRX(EX_SOFTWARE, "%s: UNIMPLEMENTED (FATAL)", __func__); 2545 DERRX(EX_SOFTWARE, "%s: UNIMPLEMENTED (FATAL)", __func__);
2500 return 0; 2546 return 0;
2501} 2547}
@@ -2804,28 +2850,27 @@ perfuse_node_write(pu, opc, buf, offset, @@ -2804,28 +2850,27 @@ perfuse_node_write(pu, opc, buf, offset,
2804 if (ioflag & (IO_SYNC|IO_DSYNC)) 2850 if (ioflag & (IO_SYNC|IO_DSYNC))
2805 ps->ps_syncwrites++; 2851 ps->ps_syncwrites++;
2806 else 2852 else
2807 ps->ps_asyncwrites++; 2853 ps->ps_asyncwrites++;
2808 2854
2809 /* 2855 /*
2810 * Remember to sync the file 2856 * Remember to sync the file
2811 */ 2857 */
2812 pnd->pnd_flags |= PND_DIRTY; 2858 pnd->pnd_flags |= PND_DIRTY;
2813 2859
2814#ifdef PERFUSE_DEBUG 2860#ifdef PERFUSE_DEBUG
2815 if (perfuse_diagflags & PDF_SYNC) 2861 if (perfuse_diagflags & PDF_SYNC)
2816 DPRINTF("%s: DIRTY opc = %p, file = \"%s\"\n",  2862 DPRINTF("%s: DIRTY opc = %p, file = \"%s\"\n",
2817 __func__, (void*)opc, 2863 __func__, (void*)opc, perfuse_node_path(opc));
2818 (char *)PNPATH((struct puffs_node *)opc)); 
2819#endif 2864#endif
2820out: 2865out:
2821 if (pm != NULL) 2866 if (pm != NULL)
2822 ps->ps_destroy_msg(pm); 2867 ps->ps_destroy_msg(pm);
2823 2868
2824 /* 2869 /*
2825 * If there are no more queued write, we can resume 2870 * If there are no more queued write, we can resume
2826 * an operation awaiting write completion. 2871 * an operation awaiting write completion.
2827 */  2872 */
2828 pnd->pnd_flags &= ~PND_INWRITE; 2873 pnd->pnd_flags &= ~PND_INWRITE;
2829 if (dequeue_requests(ps, opc, PCQ_WRITE, 1) == 0) 2874 if (dequeue_requests(ps, opc, PCQ_WRITE, 1) == 0)
2830 (void)dequeue_requests(ps, opc, PCQ_AFTERWRITE, DEQUEUE_ALL); 2875 (void)dequeue_requests(ps, opc, PCQ_AFTERWRITE, DEQUEUE_ALL);
2831 2876

cvs diff -r1.9 -r1.10 src/lib/libperfuse/perfuse.c (expand / switch to unified diff)

--- src/lib/libperfuse/perfuse.c 2010/09/29 08:01:10 1.9
+++ src/lib/libperfuse/perfuse.c 2010/10/03 05:46:47 1.10
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: perfuse.c,v 1.9 2010/09/29 08:01:10 manu Exp $ */ 1/* $NetBSD: perfuse.c,v 1.10 2010/10/03 05:46:47 manu Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved. 4 * Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
5 *  5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 *  14 *
@@ -48,27 +48,26 @@ static struct perfuse_state *init_state( @@ -48,27 +48,26 @@ static struct perfuse_state *init_state(
48static int get_fd(const char *); 48static int get_fd(const char *);
49 49
50static struct perfuse_state * 50static struct perfuse_state *
51init_state(void) 51init_state(void)
52{ 52{
53 struct perfuse_state *ps; 53 struct perfuse_state *ps;
54 54
55 if ((ps = malloc(sizeof(*ps))) == NULL) 55 if ((ps = malloc(sizeof(*ps))) == NULL)
56 DERR(EX_OSERR, "malloc failed"); 56 DERR(EX_OSERR, "malloc failed");
57 57
58 (void)memset(ps, 0, sizeof(*ps)); 58 (void)memset(ps, 0, sizeof(*ps));
59 ps->ps_max_write = UINT_MAX; 59 ps->ps_max_write = UINT_MAX;
60 ps->ps_max_readahead = UINT_MAX; 60 ps->ps_max_readahead = UINT_MAX;
61 TAILQ_INIT(&ps->ps_pnd); 
62  61
63 return ps; 62 return ps;
64} 63}
65 64
66 65
67static int 66static int
68get_fd(data) 67get_fd(data)
69 const char *data; 68 const char *data;
70{ 69{
71 char *string; 70 char *string;
72 const char fdopt[] = "fd="; 71 const char fdopt[] = "fd=";
73 char *lastp; 72 char *lastp;
74 char *opt; 73 char *opt;
@@ -401,38 +400,35 @@ perfuse_init(pc, pmi) @@ -401,38 +400,35 @@ perfuse_init(pc, pmi)
401 PUFFSOP_SET(pops, perfuse, node, readlink); 400 PUFFSOP_SET(pops, perfuse, node, readlink);
402 PUFFSOP_SET(pops, perfuse, node, reclaim); 401 PUFFSOP_SET(pops, perfuse, node, reclaim);
403 PUFFSOP_SET(pops, perfuse, node, inactive); 402 PUFFSOP_SET(pops, perfuse, node, inactive);
404 PUFFSOP_SET(pops, perfuse, node, print); 403 PUFFSOP_SET(pops, perfuse, node, print);
405 PUFFSOP_SET(pops, perfuse, node, advlock); 404 PUFFSOP_SET(pops, perfuse, node, advlock);
406 PUFFSOP_SET(pops, perfuse, node, read); 405 PUFFSOP_SET(pops, perfuse, node, read);
407 PUFFSOP_SET(pops, perfuse, node, write); 406 PUFFSOP_SET(pops, perfuse, node, write);
408 407
409 puffs_flags = PUFFS_KFLAG_WTCACHE; 408 puffs_flags = PUFFS_KFLAG_WTCACHE;
410 409
411 if (perfuse_diagflags & PDF_PUFFS) 410 if (perfuse_diagflags & PDF_PUFFS)
412 puffs_flags |= PUFFS_FLAG_OPDUMP; 411 puffs_flags |= PUFFS_FLAG_OPDUMP;
413 412
414 if (perfuse_diagflags & PDF_FILENAME) 
415 puffs_flags |= PUFFS_FLAG_BUILDPATH; 
416 
417 if ((pu = puffs_init(pops, _PATH_PUFFS, name, ps, puffs_flags)) == NULL) 413 if ((pu = puffs_init(pops, _PATH_PUFFS, name, ps, puffs_flags)) == NULL)
418 DERR(EX_OSERR, "puffs_init failed"); 414 DERR(EX_OSERR, "puffs_init failed");
419 415
420 ps->ps_pu = pu; 416 ps->ps_pu = pu;
421 417
422 /* 418 /*
423 * Setup filesystem root 419 * Setup filesystem root
424 */ 420 */
425 pn_root = perfuse_new_pn(pu, NULL); 421 pn_root = perfuse_new_pn(pu, "", NULL);
426 PERFUSE_NODE_DATA(pn_root)->pnd_ino = FUSE_ROOT_ID;  422 PERFUSE_NODE_DATA(pn_root)->pnd_ino = FUSE_ROOT_ID;
427 PERFUSE_NODE_DATA(pn_root)->pnd_parent = pn_root; 423 PERFUSE_NODE_DATA(pn_root)->pnd_parent = pn_root;
428 puffs_setroot(pu, pn_root); 424 puffs_setroot(pu, pn_root);
429 ps->ps_fsid = pn_root->pn_va.va_fsid; 425 ps->ps_fsid = pn_root->pn_va.va_fsid;
430  426
431 po_root = puffs_getrootpathobj(pu); 427 po_root = puffs_getrootpathobj(pu);
432 if ((po_root->po_path = strdup("/")) == NULL) 428 if ((po_root->po_path = strdup("/")) == NULL)
433 DERRX(EX_OSERR, "perfuse_mount_start() failed"); 429 DERRX(EX_OSERR, "perfuse_mount_start() failed");
434  430
435 po_root->po_len = 1; 431 po_root->po_len = 1;
436 puffs_path_buildhash(pu, po_root); 432 puffs_path_buildhash(pu, po_root);
437 433
438 puffs_vattr_null(&pn_root->pn_va); 434 puffs_vattr_null(&pn_root->pn_va);

cvs diff -r1.13 -r1.14 src/lib/libperfuse/perfuse_priv.h (expand / switch to unified diff)

--- src/lib/libperfuse/perfuse_priv.h 2010/09/29 08:01:10 1.13
+++ src/lib/libperfuse/perfuse_priv.h 2010/10/03 05:46:47 1.14
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: perfuse_priv.h,v 1.13 2010/09/29 08:01:10 manu Exp $ */ 1/* $NetBSD: perfuse_priv.h,v 1.14 2010/10/03 05:46:47 manu Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved. 4 * Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
5 *  5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 *  14 *
@@ -55,28 +55,26 @@ struct perfuse_state { @@ -55,28 +55,26 @@ struct perfuse_state {
55 uint64_t ps_asyncwrites; 55 uint64_t ps_asyncwrites;
56 char *ps_source; 56 char *ps_source;
57 char *ps_target; 57 char *ps_target;
58 char *ps_filesystemtype; 58 char *ps_filesystemtype;
59 int ps_mountflags; 59 int ps_mountflags;
60 uint64_t ps_unique; 60 uint64_t ps_unique;
61 perfuse_new_msg_fn ps_new_msg; 61 perfuse_new_msg_fn ps_new_msg;
62 perfuse_xchg_msg_fn ps_xchg_msg; 62 perfuse_xchg_msg_fn ps_xchg_msg;
63 perfuse_destroy_msg_fn ps_destroy_msg; 63 perfuse_destroy_msg_fn ps_destroy_msg;
64 perfuse_get_inhdr_fn ps_get_inhdr; 64 perfuse_get_inhdr_fn ps_get_inhdr;
65 perfuse_get_inpayload_fn ps_get_inpayload; 65 perfuse_get_inpayload_fn ps_get_inpayload;
66 perfuse_get_outhdr_fn ps_get_outhdr; 66 perfuse_get_outhdr_fn ps_get_outhdr;
67 perfuse_get_outpayload_fn ps_get_outpayload; 67 perfuse_get_outpayload_fn ps_get_outpayload;
68 TAILQ_HEAD(, perfuse_node_data) ps_pnd; 
69 int ps_pnd_count; 
70}; 68};
71 69
72 70
73enum perfuse_qtype {  71enum perfuse_qtype {
74 PCQ_READDIR,  72 PCQ_READDIR,
75 PCQ_READ, 73 PCQ_READ,
76 PCQ_WRITE, 74 PCQ_WRITE,
77 PCQ_AFTERWRITE, 75 PCQ_AFTERWRITE,
78 PCQ_OPEN, 76 PCQ_OPEN,
79 PCQ_AFTERXCHG 77 PCQ_AFTERXCHG
80}; 78};
81 79
82#ifdef PERFUSE_DEBUG 80#ifdef PERFUSE_DEBUG
@@ -110,53 +108,56 @@ struct perfuse_node_data { @@ -110,53 +108,56 @@ struct perfuse_node_data {
110#define PND_REMOVED 0x020 /* Node was removed */ 108#define PND_REMOVED 0x020 /* Node was removed */
111#define PND_INWRITE 0x040 /* write in progress */ 109#define PND_INWRITE 0x040 /* write in progress */
112#define PND_INOPEN 0x100 /* open in progress */ 110#define PND_INOPEN 0x100 /* open in progress */
113#define PND_GOTSIZE 0x200 /* pnd_size was set */ 111#define PND_GOTSIZE 0x200 /* pnd_size was set */
114#define PND_INXCHG 0x400 /* FUSE exchange in progress */ 112#define PND_INXCHG 0x400 /* FUSE exchange in progress */
115 113
116#define PND_OPEN (PND_RFH|PND_WFH) /* File is open */ 114#define PND_OPEN (PND_RFH|PND_WFH) /* File is open */
117#define PND_BUSY (PND_INREADDIR|PND_INWRITE|PND_INOPEN) 115#define PND_BUSY (PND_INREADDIR|PND_INWRITE|PND_INOPEN)
118 puffs_cookie_t pnd_parent; 116 puffs_cookie_t pnd_parent;
119 int pnd_childcount; 117 int pnd_childcount;
120 time_t pnd_timestamp; 118 time_t pnd_timestamp;
121 TAILQ_ENTRY(perfuse_node_data) pnd_next; 119 TAILQ_ENTRY(perfuse_node_data) pnd_next;
122 puffs_cookie_t pnd_pn; 120 puffs_cookie_t pnd_pn;
 121 char pnd_name[MAXPATHLEN]; /* node name */
 122 TAILQ_HEAD(,perfuse_node_data) pnd_children;
123}; 123};
124 124
125#define PERFUSE_NODE_DATA(opc) \ 125#define PERFUSE_NODE_DATA(opc) \
126 ((struct perfuse_node_data *)puffs_pn_getpriv((struct puffs_node *)opc)) 126 ((struct perfuse_node_data *)puffs_pn_getpriv((struct puffs_node *)opc))
127 127
128 128
129#define UNSPEC_REPLY_LEN PERFUSE_UNSPEC_REPLY_LEN /* shorter! */ 129#define UNSPEC_REPLY_LEN PERFUSE_UNSPEC_REPLY_LEN /* shorter! */
130#define NO_PAYLOAD_REPLY_LEN 0 130#define NO_PAYLOAD_REPLY_LEN 0
131 131
132#define GET_INHDR(ps, pm) ps->ps_get_inhdr(pm) 132#define GET_INHDR(ps, pm) ps->ps_get_inhdr(pm)
133#define GET_INPAYLOAD(ps, pm, type) \ 133#define GET_INPAYLOAD(ps, pm, type) \
134 (struct type *)(void *)ps->ps_get_inpayload(pm) 134 (struct type *)(void *)ps->ps_get_inpayload(pm)
135#define _GET_INPAYLOAD(ps, pm, type) (type)ps->ps_get_inpayload(pm) 135#define _GET_INPAYLOAD(ps, pm, type) (type)ps->ps_get_inpayload(pm)
136#define GET_OUTHDR(ps, pm) ps->ps_get_outhdr(pm) 136#define GET_OUTHDR(ps, pm) ps->ps_get_outhdr(pm)
137#define GET_OUTPAYLOAD(ps, pm, type) \ 137#define GET_OUTPAYLOAD(ps, pm, type) \
138 (struct type *)(void *)ps->ps_get_outpayload(pm) 138 (struct type *)(void *)ps->ps_get_outpayload(pm)
139#define _GET_OUTPAYLOAD(ps, pm, type) (type)ps->ps_get_outpayload(pm) 139#define _GET_OUTPAYLOAD(ps, pm, type) (type)ps->ps_get_outpayload(pm)
140 140
141__BEGIN_DECLS 141__BEGIN_DECLS
142 142
143struct puffs_node *perfuse_new_pn(struct puffs_usermount *,  143struct puffs_node *perfuse_new_pn(struct puffs_usermount *, const char *,
144 struct puffs_node *); 144 struct puffs_node *);
145void perfuse_destroy_pn(struct puffs_usermount *, struct puffs_node *); 145void perfuse_destroy_pn(struct puffs_usermount *, struct puffs_node *);
146void perfuse_new_fh(puffs_cookie_t, uint64_t, int); 146void perfuse_new_fh(puffs_cookie_t, uint64_t, int);
147void perfuse_destroy_fh(puffs_cookie_t, uint64_t); 147void perfuse_destroy_fh(puffs_cookie_t, uint64_t);
148uint64_t perfuse_get_fh(puffs_cookie_t, int); 148uint64_t perfuse_get_fh(puffs_cookie_t, int);
149uint64_t perfuse_next_unique(struct puffs_usermount *); 149uint64_t perfuse_next_unique(struct puffs_usermount *);
 150char *perfuse_node_path(puffs_cookie_t);
150int perfuse_node_close_common(struct puffs_usermount *, puffs_cookie_t, int); 151int perfuse_node_close_common(struct puffs_usermount *, puffs_cookie_t, int);
151 152
152char *perfuse_fs_mount(int, ssize_t); 153char *perfuse_fs_mount(int, ssize_t);
153 154
154 155
155/* 156/*
156 * opc.c - filesystem operations 157 * opc.c - filesystem operations
157 */ 158 */
158int perfuse_fs_unmount(struct puffs_usermount *, int); 159int perfuse_fs_unmount(struct puffs_usermount *, int);
159int perfuse_fs_statvfs(struct puffs_usermount *, struct statvfs *); 160int perfuse_fs_statvfs(struct puffs_usermount *, struct statvfs *);
160int perfuse_fs_sync(struct puffs_usermount *, int, 161int perfuse_fs_sync(struct puffs_usermount *, int,
161 const struct puffs_cred *); 162 const struct puffs_cred *);
162int perfuse_fs_fhtonode(struct puffs_usermount *, void *, size_t, 163int perfuse_fs_fhtonode(struct puffs_usermount *, void *, size_t,

cvs diff -r1.7 -r1.8 src/lib/libperfuse/subr.c (expand / switch to unified diff)

--- src/lib/libperfuse/subr.c 2010/09/29 08:01:10 1.7
+++ src/lib/libperfuse/subr.c 2010/10/03 05:46:47 1.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: subr.c,v 1.7 2010/09/29 08:01:10 manu Exp $ */ 1/* $NetBSD: subr.c,v 1.8 2010/10/03 05:46:47 manu Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved. 4 * Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
5 *  5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 *  14 *
@@ -26,75 +26,87 @@ @@ -26,75 +26,87 @@
26 */  26 */
27 27
28#include <stdio.h> 28#include <stdio.h>
29#include <stdlib.h> 29#include <stdlib.h>
30#include <err.h> 30#include <err.h>
31#include <errno.h> 31#include <errno.h>
32#include <sysexits.h> 32#include <sysexits.h>
33#include <syslog.h> 33#include <syslog.h>
34#include <puffs.h> 34#include <puffs.h>
35#include <paths.h> 35#include <paths.h>
36 36
37#include "perfuse_priv.h" 37#include "perfuse_priv.h"
38 38
 39static size_t node_path(puffs_cookie_t, char *, size_t);
 40
39struct puffs_node * 41struct puffs_node *
40perfuse_new_pn(pu, parent) 42perfuse_new_pn(pu, name, parent)
41 struct puffs_usermount *pu; 43 struct puffs_usermount *pu;
 44 const char *name;
42 struct puffs_node *parent; 45 struct puffs_node *parent;
43{ 46{
44 struct perfuse_state *ps; 47 struct perfuse_state *ps;
45 struct puffs_node *pn; 48 struct puffs_node *pn;
46 struct perfuse_node_data *pnd; 49 struct perfuse_node_data *pnd;
47 50
48 ps = puffs_getspecific(pu); 51 ps = puffs_getspecific(pu);
49 52
50 if ((pnd = malloc(sizeof(*pnd))) == NULL) 53 if ((pnd = malloc(sizeof(*pnd))) == NULL)
51 DERR(EX_OSERR, "malloc failed"); 54 DERR(EX_OSERR, "malloc failed");
52 55
53 if ((pn = puffs_pn_new(pu, pnd)) == NULL) 56 if ((pn = puffs_pn_new(pu, pnd)) == NULL)
54 DERR(EX_SOFTWARE, "puffs_pn_new failed"); 57 DERR(EX_SOFTWARE, "puffs_pn_new failed");
55 58
56 (void)memset(pnd, 0, sizeof(*pnd)); 59 (void)memset(pnd, 0, sizeof(*pnd));
57 pnd->pnd_rfh = FUSE_UNKNOWN_FH; 60 pnd->pnd_rfh = FUSE_UNKNOWN_FH;
58 pnd->pnd_wfh = FUSE_UNKNOWN_FH; 61 pnd->pnd_wfh = FUSE_UNKNOWN_FH;
59 pnd->pnd_ino = PERFUSE_UNKNOWN_INO; 62 pnd->pnd_ino = PERFUSE_UNKNOWN_INO;
60 pnd->pnd_nlookup = 1; 63 pnd->pnd_nlookup = 1;
61 pnd->pnd_parent = parent; 64 pnd->pnd_parent = parent;
62 pnd->pnd_timestamp = time(NULL); 65 pnd->pnd_timestamp = time(NULL);
63 pnd->pnd_pn = (puffs_cookie_t)pn; 66 pnd->pnd_pn = (puffs_cookie_t)pn;
 67 (void)strlcpy(pnd->pnd_name, name, MAXPATHLEN);
64 TAILQ_INIT(&pnd->pnd_pcq); 68 TAILQ_INIT(&pnd->pnd_pcq);
 69 TAILQ_INIT(&pnd->pnd_children);
 70
 71 if (parent != NULL) {
 72 struct perfuse_node_data *parent_pnd;
65 73
66 TAILQ_INSERT_TAIL(&ps->ps_pnd, pnd, pnd_next); 74 parent_pnd = PERFUSE_NODE_DATA(parent);
67 ps->ps_pnd_count++; 75 TAILQ_INSERT_TAIL(&parent_pnd->pnd_children, pnd, pnd_next);
68 76
69 if (parent != NULL) 77 parent_pnd->pnd_childcount++;
70 PERFUSE_NODE_DATA(parent)->pnd_childcount++; 78 }
71 79
72 return pn; 80 return pn;
73} 81}
74 82
75void 83void
76perfuse_destroy_pn(pu, pn) 84perfuse_destroy_pn(pu, pn)
77 struct puffs_usermount *pu; 85 struct puffs_usermount *pu;
78 struct puffs_node *pn; 86 struct puffs_node *pn;
79{ 87{
80 struct perfuse_state *ps; 88 struct perfuse_state *ps;
81 struct perfuse_node_data *pnd; 89 struct perfuse_node_data *pnd;
82 90
83 ps = puffs_getspecific(pu); 91 ps = puffs_getspecific(pu);
84 pnd = PERFUSE_NODE_DATA(pn); 92 pnd = PERFUSE_NODE_DATA(pn);
85 93
86 TAILQ_REMOVE(&ps->ps_pnd, pnd, pnd_next); 94 if (pnd->pnd_parent != NULL) {
87 ps->ps_pnd_count--; 95 struct perfuse_node_data *parent_pnd;
 96
 97 parent_pnd = PERFUSE_NODE_DATA(pnd->pnd_parent);
 98 TAILQ_REMOVE(&parent_pnd->pnd_children, pnd, pnd_next);
 99 }
88 100
89 if ((pnd = puffs_pn_getpriv(pn)) != NULL) { 101 if ((pnd = puffs_pn_getpriv(pn)) != NULL) {
90 if (pnd->pnd_parent != NULL) 102 if (pnd->pnd_parent != NULL)
91 PERFUSE_NODE_DATA(pnd->pnd_parent)->pnd_childcount--; 103 PERFUSE_NODE_DATA(pnd->pnd_parent)->pnd_childcount--;
92 104
93 if (pnd->pnd_dirent != NULL) 105 if (pnd->pnd_dirent != NULL)
94 free(pnd->pnd_dirent); 106 free(pnd->pnd_dirent);
95 107
96 if (pnd->pnd_all_fd != NULL) 108 if (pnd->pnd_all_fd != NULL)
97 free(pnd->pnd_all_fd); 109 free(pnd->pnd_all_fd);
98#ifdef PERFUSE_DEBUG 110#ifdef PERFUSE_DEBUG
99 if (pnd->pnd_flags & PND_OPEN) 111 if (pnd->pnd_flags & PND_OPEN)
100 DERRX(EX_SOFTWARE, "%s: file open", __func__); 112 DERRX(EX_SOFTWARE, "%s: file open", __func__);
@@ -187,13 +199,44 @@ perfuse_get_fh(opc, mode) @@ -187,13 +199,44 @@ perfuse_get_fh(opc, mode)
187 199
188 if (mode & FREAD) { 200 if (mode & FREAD) {
189 if (pnd->pnd_flags & PND_RFH) 201 if (pnd->pnd_flags & PND_RFH)
190 return pnd->pnd_rfh; 202 return pnd->pnd_rfh;
191 203
192 if (pnd->pnd_flags & PND_WFH) 204 if (pnd->pnd_flags & PND_WFH)
193 return pnd->pnd_wfh; 205 return pnd->pnd_wfh;
194 206
195 } 207 }
196 208
197 return FUSE_UNKNOWN_FH; 209 return FUSE_UNKNOWN_FH;
198} 210}
199 211
 212static size_t
 213node_path(opc, buf, buflen)
 214 puffs_cookie_t opc;
 215 char *buf;
 216 size_t buflen;
 217{
 218 struct perfuse_node_data *pnd;
 219 size_t written;
 220
 221 pnd = PERFUSE_NODE_DATA(opc);
 222 if (pnd->pnd_parent == opc)
 223 return 0;
 224
 225 written = node_path(pnd->pnd_parent, buf, buflen);
 226 buf += written;
 227 buflen -= written;
 228
 229 return written + snprintf(buf, buflen, "/%s", pnd->pnd_name);
 230}
 231
 232char *
 233perfuse_node_path(opc)
 234 puffs_cookie_t opc;
 235{
 236 static char buf[MAXPATHLEN + 1];
 237
 238 if (node_path(opc, buf, sizeof(buf)) == 0)
 239 sprintf(buf, "/");
 240
 241 return buf;
 242}