- 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
This commit is contained in:
parent
7ad510fcea
commit
2ff0ea03a7
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: debug.c,v 1.4 2010/09/29 08:01:10 manu Exp $ */
|
||||
/* $NetBSD: debug.c,v 1.5 2010/10/03 05:46:47 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
|
||||
@ -84,7 +84,7 @@ const char *perfuse_qtypestr[] = {
|
||||
"READ",
|
||||
"WRITE",
|
||||
"AFTERWRITE",
|
||||
"OPEN"
|
||||
"OPEN",
|
||||
"AFTERXCHG"
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ops.c,v 1.18 2010/09/29 08:01:10 manu Exp $ */
|
||||
/* $NetBSD: ops.c,v 1.19 2010/10/03 05:46:47 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
|
||||
@ -184,7 +184,7 @@ xchg_msg(pu, opc, pm, len, wait)
|
||||
#ifdef PERFUSE_DEBUG
|
||||
if ((perfuse_diagflags & PDF_FILENAME) && (opc != 0))
|
||||
DPRINTF("file = \"%s\" flags = 0x%x\n",
|
||||
(char *)PNPATH((struct puffs_node *)opc),
|
||||
perfuse_node_path(opc),
|
||||
PERFUSE_NODE_DATA(opc)->pnd_flags);
|
||||
#endif
|
||||
if (pnd)
|
||||
@ -209,6 +209,14 @@ no_access(opc, pcr, mode)
|
||||
struct puffs_node *pn;
|
||||
struct vattr *va;
|
||||
|
||||
/*
|
||||
* pcr is NULL for self open through fsync or readdir.
|
||||
* In both case, access control is useless, as it was
|
||||
* done before, at open time.
|
||||
*/
|
||||
if (pcr == NULL)
|
||||
return 0;
|
||||
|
||||
pn = (struct puffs_node *)opc;
|
||||
va = puffs_pn_getvap(pn);
|
||||
|
||||
@ -291,7 +299,8 @@ node_lookup_dir_nodot(pu, opc, name, namelen, pnp)
|
||||
namelen = PNPLEN(dpn) + 1 + namelen + 1;
|
||||
if ((path = malloc(namelen)) == NULL)
|
||||
DERR(EX_OSERR, "malloc failed");
|
||||
(void)snprintf(path, namelen, "%s/%s", (char *)PNPATH(dpn), name);
|
||||
(void)snprintf(path, namelen, "%s/%s",
|
||||
perfuse_node_path((puffs_cookie_t)dpn), name);
|
||||
|
||||
error = node_lookup_common(pu, opc, path, pnp);
|
||||
|
||||
@ -308,6 +317,7 @@ node_lookup_common(pu, opc, path, pnp)
|
||||
struct puffs_node **pnp;
|
||||
{
|
||||
struct perfuse_state *ps;
|
||||
struct perfuse_node_data *pnd;
|
||||
perfuse_msg_t *pm;
|
||||
struct fuse_entry_out *feo;
|
||||
struct puffs_node *pn;
|
||||
@ -316,6 +326,35 @@ node_lookup_common(pu, opc, path, pnp)
|
||||
|
||||
ps = puffs_getspecific(pu);
|
||||
|
||||
#ifdef PERFUSE_DEBUG
|
||||
if (perfuse_diagflags & PDF_FILENAME)
|
||||
DPRINTF("%s: opc = %p, file = \"%s\" looking up \"%s\"\n",
|
||||
__func__, (void *)opc, perfuse_node_path(opc), path);
|
||||
#endif
|
||||
/*
|
||||
* Is the node already known?
|
||||
*/
|
||||
TAILQ_FOREACH(pnd, &PERFUSE_NODE_DATA(opc)->pnd_children, pnd_next) {
|
||||
if ((pnd->pnd_flags & PND_REMOVED) ||
|
||||
(strcmp(pnd->pnd_name, path) != 0))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* We have a match
|
||||
*/
|
||||
if (pnp != NULL)
|
||||
*pnp = (struct puffs_node *)(pnd->pnd_pn);
|
||||
|
||||
#ifdef PERFUSE_DEBUG
|
||||
if (perfuse_diagflags & PDF_FILENAME)
|
||||
DPRINTF("%s: opc = %p, file = \"%s\" found "
|
||||
"cookie = %p, ino = %"PRId64" for \"%s\"\n",
|
||||
__func__, (void *)opc, perfuse_node_path(opc),
|
||||
(void *)pnd->pnd_pn, pnd->pnd_ino, path);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = strlen(path) + 1;
|
||||
|
||||
pm = ps->ps_new_msg(pu, opc, FUSE_LOOKUP, len, NULL);
|
||||
@ -326,7 +365,7 @@ node_lookup_common(pu, opc, path, pnp)
|
||||
|
||||
feo = GET_OUTPAYLOAD(ps, pm, fuse_entry_out);
|
||||
|
||||
pn = perfuse_new_pn(pu, opc);
|
||||
pn = perfuse_new_pn(pu, path, opc);
|
||||
PERFUSE_NODE_DATA(pn)->pnd_ino = feo->nodeid;
|
||||
|
||||
fuse_attr_to_vap(ps, &pn->pn_va, &feo->attr);
|
||||
@ -376,13 +415,21 @@ node_mk_common(pu, opc, pni, pcn, pm)
|
||||
if (feo->nodeid == PERFUSE_UNKNOWN_INO)
|
||||
DERRX(EX_SOFTWARE, "%s: no ino", __func__);
|
||||
|
||||
pn = perfuse_new_pn(pu, opc);
|
||||
pn = perfuse_new_pn(pu, pcn->pcn_name, opc);
|
||||
PERFUSE_NODE_DATA(pn)->pnd_ino = feo->nodeid;
|
||||
|
||||
fuse_attr_to_vap(ps, &pn->pn_va, &feo->attr);
|
||||
puffs_newinfo_setcookie(pni, pn);
|
||||
|
||||
#ifdef PERFUSE_DEBUG
|
||||
if (perfuse_diagflags & PDF_FILENAME)
|
||||
DPRINTF("%s: opc = %p, file = \"%s\", flags = 0x%x "
|
||||
"ino = %"PRId64"\n",
|
||||
__func__, (void *)pn, pcn->pcn_name,
|
||||
PERFUSE_NODE_DATA(pn)->pnd_flags, feo->nodeid);
|
||||
#endif
|
||||
ps->ps_destroy_msg(pm);
|
||||
|
||||
|
||||
/*
|
||||
* Set owner and group
|
||||
*/
|
||||
@ -406,6 +453,7 @@ node_mk_common(pu, opc, pni, pcn, pm)
|
||||
* The parent directory needs a sync
|
||||
*/
|
||||
PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY;
|
||||
|
||||
out:
|
||||
ps->ps_destroy_msg(pm);
|
||||
|
||||
@ -995,7 +1043,7 @@ perfuse_node_create(pu, opc, pni, pcn, vap)
|
||||
* Save the file handle and inode in node private data
|
||||
* so that we can reuse it later
|
||||
*/
|
||||
pn = perfuse_new_pn(pu, opc);
|
||||
pn = perfuse_new_pn(pu, name, opc);
|
||||
perfuse_new_fh((puffs_cookie_t)pn, foo->fh, FWRITE);
|
||||
PERFUSE_NODE_DATA(pn)->pnd_ino = feo->nodeid;
|
||||
|
||||
@ -1115,15 +1163,6 @@ perfuse_node_open(pu, opc, mode, pcr)
|
||||
if (pnd->pnd_flags & PND_REMOVED)
|
||||
return ENOENT;
|
||||
|
||||
/*
|
||||
* Queue open on a node so that we do not open
|
||||
* twice. This would be better with read and
|
||||
* write distinguished.
|
||||
*/
|
||||
while (pnd->pnd_flags & PND_INOPEN)
|
||||
requeue_request(pu, opc, PCQ_OPEN);
|
||||
pnd->pnd_flags |= PND_INOPEN;
|
||||
|
||||
if (puffs_pn_getvap(pn)->va_type == VDIR) {
|
||||
op = FUSE_OPENDIR;
|
||||
pmode = PUFFS_VREAD|PUFFS_VEXEC;
|
||||
@ -1165,6 +1204,15 @@ perfuse_node_open(pu, opc, mode, pcr)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue open on a node so that we do not open
|
||||
* twice. This would be better with read and
|
||||
* write distinguished.
|
||||
*/
|
||||
while (pnd->pnd_flags & PND_INOPEN)
|
||||
requeue_request(pu, opc, PCQ_OPEN);
|
||||
pnd->pnd_flags |= PND_INOPEN;
|
||||
|
||||
/*
|
||||
* Convert PUFFS mode to FUSE mode: convert FREAD/FWRITE
|
||||
* to O_RDONLY/O_WRONLY while perserving the other options.
|
||||
@ -1192,8 +1240,7 @@ perfuse_node_open(pu, opc, mode, pcr)
|
||||
if (perfuse_diagflags & (PDF_FH|PDF_FILENAME))
|
||||
DPRINTF("%s: opc = %p, file = \"%s\", "
|
||||
"ino = %"PRId64", %s%sfh = 0x%"PRIx64"\n",
|
||||
__func__, (void *)opc,
|
||||
(char *)PNPATH((struct puffs_node *)opc),
|
||||
__func__, (void *)opc, perfuse_node_path(opc),
|
||||
pnd->pnd_ino, mode & FREAD ? "r" : "",
|
||||
mode & FWRITE ? "w" : "", foo->fh);
|
||||
#endif
|
||||
@ -1641,8 +1688,7 @@ perfuse_node_fsync(pu, opc, pcr, flags, offlo, offhi)
|
||||
#ifdef PERFUSE_DEBUG
|
||||
if (perfuse_diagflags & PDF_SYNC)
|
||||
DPRINTF("%s: TEST opc = %p, file = \"%s\" is %sdirty\n",
|
||||
__func__, (void*)opc,
|
||||
(char *)PNPATH((struct puffs_node *)opc),
|
||||
__func__, (void*)opc, perfuse_node_path(opc),
|
||||
pnd->pnd_flags & PND_DIRTY ? "" : "not ");
|
||||
#endif
|
||||
if (!(pnd->pnd_flags & PND_DIRTY))
|
||||
@ -1695,8 +1741,7 @@ perfuse_node_fsync(pu, opc, pcr, flags, offlo, offhi)
|
||||
#ifdef PERFUSE_DEBUG
|
||||
if (perfuse_diagflags & PDF_SYNC)
|
||||
DPRINTF("%s: CLEAR opc = %p, file = \"%s\"\n",
|
||||
__func__, (void*)opc,
|
||||
(char *)PNPATH((struct puffs_node *)opc));
|
||||
__func__, (void*)opc, perfuse_node_path(opc));
|
||||
#endif
|
||||
|
||||
out:
|
||||
@ -1772,12 +1817,6 @@ perfuse_node_remove(pu, opc, targ, pcn)
|
||||
DPRINTF("%s: opc = %p, remove opc = %p, file = \"%s\"\n",
|
||||
__func__, (void *)opc, (void *)targ, pcn->pcn_name);
|
||||
#endif
|
||||
|
||||
ps = puffs_getspecific(pu);
|
||||
pnd = PERFUSE_NODE_DATA(opc);
|
||||
name = pcn->pcn_name;
|
||||
len = pcn->pcn_namelen + 1;
|
||||
|
||||
/*
|
||||
* Await for all operations on the deleted node to drain,
|
||||
* as the filesystem may be confused to have it deleted
|
||||
@ -1786,6 +1825,11 @@ perfuse_node_remove(pu, opc, targ, pcn)
|
||||
while (PERFUSE_NODE_DATA(targ)->pnd_flags & PND_INXCHG)
|
||||
requeue_request(pu, targ, PCQ_AFTERXCHG);
|
||||
|
||||
ps = puffs_getspecific(pu);
|
||||
pnd = PERFUSE_NODE_DATA(opc);
|
||||
name = pcn->pcn_name;
|
||||
len = pcn->pcn_namelen + 1;
|
||||
|
||||
pm = ps->ps_new_msg(pu, opc, FUSE_UNLINK, len, pcn->pcn_cred);
|
||||
path = _GET_INPAYLOAD(ps, pm, char *);
|
||||
(void)strlcpy(path, name, len);
|
||||
@ -1920,48 +1964,42 @@ perfuse_node_rename(pu, opc, src, pcn_src, targ_dir, targ, pcn_targ)
|
||||
if ((error = xchg_msg(pu, opc, pm, UNSPEC_REPLY_LEN, wait_reply)) != 0)
|
||||
goto out;
|
||||
|
||||
PERFUSE_NODE_DATA(opc)->pnd_childcount--;
|
||||
PERFUSE_NODE_DATA(targ_dir)->pnd_childcount++;
|
||||
if (opc != targ_dir) {
|
||||
struct perfuse_node_data *srcdir_pnd;
|
||||
struct perfuse_node_data *dstdir_pnd;
|
||||
struct perfuse_node_data *src_pnd;
|
||||
|
||||
srcdir_pnd = PERFUSE_NODE_DATA(opc);
|
||||
dstdir_pnd = PERFUSE_NODE_DATA(targ_dir);
|
||||
src_pnd = PERFUSE_NODE_DATA(src);
|
||||
|
||||
PERFUSE_NODE_DATA(src)->pnd_parent = targ_dir;
|
||||
TAILQ_REMOVE(&srcdir_pnd->pnd_children, src_pnd, pnd_next);
|
||||
TAILQ_INSERT_TAIL(&dstdir_pnd->pnd_children, src_pnd, pnd_next);
|
||||
|
||||
srcdir_pnd->pnd_childcount--;
|
||||
dstdir_pnd->pnd_childcount++;
|
||||
|
||||
src_pnd->pnd_parent = targ_dir;
|
||||
|
||||
PERFUSE_NODE_DATA(targ_dir)->pnd_flags |= PND_DIRTY;
|
||||
}
|
||||
|
||||
(void)strlcpy(PERFUSE_NODE_DATA(src)->pnd_name, newname, MAXPATHLEN);
|
||||
|
||||
PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY;
|
||||
PERFUSE_NODE_DATA(targ_dir)->pnd_flags |= PND_DIRTY;
|
||||
|
||||
if ((struct puffs_node *)targ != NULL) {
|
||||
struct perfuse_node_data *targ_pnd;
|
||||
struct perfuse_node_data *src_pnd;
|
||||
|
||||
/*
|
||||
* We overwrite a node. src must be freed, as it
|
||||
* is associated in kernel with the old path. We
|
||||
* therefore have to transfer perfuse_node_data
|
||||
* from src to targ.
|
||||
*
|
||||
* src cannot be destroyed here as setback is not
|
||||
* allowed in rename operation. The node is tagged
|
||||
* with PND_REMOVED, it will be disposed at inactive
|
||||
* time.
|
||||
*/
|
||||
targ_pnd = PERFUSE_NODE_DATA(targ);
|
||||
src_pnd = PERFUSE_NODE_DATA(src);
|
||||
puffs_pn_setpriv((struct puffs_node *)targ, src_pnd);
|
||||
puffs_pn_setpriv((struct puffs_node *)src, targ_pnd);
|
||||
|
||||
PERFUSE_NODE_DATA(src)->pnd_flags |= PND_REMOVED;
|
||||
}
|
||||
if ((struct puffs_node *)targ != NULL)
|
||||
PERFUSE_NODE_DATA(targ)->pnd_flags |= PND_REMOVED;
|
||||
|
||||
#ifdef PERFUSE_DEBUG
|
||||
if (perfuse_diagflags & PDF_FILENAME)
|
||||
DPRINTF("%s: nodeid = %"PRId64" file = \"%s\" renamed \"%s\" "
|
||||
"from nodeid = %"PRId64" \"%s\" "
|
||||
"to nodeid = %"PRId64" \"%s\"\n",
|
||||
__func__,
|
||||
PERFUSE_NODE_DATA(src)->pnd_ino, pcn_src->pcn_name,
|
||||
pcn_targ->pcn_name, PERFUSE_NODE_DATA(opc)->pnd_ino,
|
||||
(char *)PNPATH((struct puffs_node *)targ_dir),
|
||||
"nodeid = %"PRId64" -> nodeid = %"PRId64" \"%s\"\n",
|
||||
__func__, PERFUSE_NODE_DATA(src)->pnd_ino,
|
||||
pcn_src->pcn_name, pcn_targ->pcn_name,
|
||||
PERFUSE_NODE_DATA(opc)->pnd_ino,
|
||||
PERFUSE_NODE_DATA(targ_dir)->pnd_ino,
|
||||
(char *)PNPATH((struct puffs_node *)opc));
|
||||
perfuse_node_path(targ_dir));
|
||||
#endif
|
||||
|
||||
out:
|
||||
@ -2044,7 +2082,6 @@ perfuse_node_rmdir(pu, opc, targ, pcn)
|
||||
while (PERFUSE_NODE_DATA(targ)->pnd_flags & PND_INXCHG)
|
||||
requeue_request(pu, targ, PCQ_AFTERXCHG);
|
||||
|
||||
|
||||
ps = puffs_getspecific(pu);
|
||||
name = pcn->pcn_name;
|
||||
len = pcn->pcn_namelen + 1;
|
||||
@ -2069,7 +2106,7 @@ perfuse_node_rmdir(pu, opc, targ, pcn)
|
||||
if (perfuse_diagflags & PDF_FILENAME)
|
||||
DPRINTF("%s: remove nodeid = %"PRId64" file = \"%s\"\n",
|
||||
__func__, PERFUSE_NODE_DATA(targ)->pnd_ino,
|
||||
(char *)PNPATH((struct puffs_node *)targ));
|
||||
perfuse_node_path(targ));
|
||||
#endif
|
||||
out:
|
||||
ps->ps_destroy_msg(pm);
|
||||
@ -2369,7 +2406,7 @@ perfuse_node_reclaim(pu, opc)
|
||||
#ifdef PERFUSE_DEBUG
|
||||
if (perfuse_diagflags & PDF_RECLAIM)
|
||||
DPRINTF("%s (nodeid %"PRId64") reclaimed\n",
|
||||
(char *)PNPATH((struct puffs_node *)opc), pnd->pnd_ino);
|
||||
perfuse_node_path(opc), pnd->pnd_ino);
|
||||
#endif
|
||||
|
||||
pn_root = puffs_getroot(pu);
|
||||
@ -2383,7 +2420,7 @@ perfuse_node_reclaim(pu, opc)
|
||||
if (perfuse_diagflags & PDF_RECLAIM)
|
||||
DPRINTF("%s (nodeid %"PRId64") is %sreclaimed, "
|
||||
"has childcount %d %s%s%s%s, pending ops:%s%s%s\n",
|
||||
(char *)PNPATH(pn), pnd->pnd_ino,
|
||||
perfuse_node_path((puffs_cookie_t)pn), pnd->pnd_ino,
|
||||
pnd->pnd_flags & PND_RECLAIMED ? "" : "not ",
|
||||
pnd->pnd_childcount,
|
||||
pnd->pnd_flags & PND_OPEN ? "open " : "not open",
|
||||
@ -2440,8 +2477,10 @@ perfuse_node_inactive(pu, opc)
|
||||
struct puffs_usermount *pu;
|
||||
puffs_cookie_t opc;
|
||||
{
|
||||
struct perfuse_state *ps;
|
||||
struct perfuse_node_data *pnd;
|
||||
|
||||
ps = puffs_getspecific(pu);
|
||||
pnd = PERFUSE_NODE_DATA(opc);
|
||||
|
||||
if (!(pnd->pnd_flags & (PND_OPEN|PND_REMOVED)))
|
||||
@ -2481,11 +2520,18 @@ perfuse_node_inactive(pu, opc)
|
||||
if (pnd->pnd_flags & PND_RFH)
|
||||
(void)perfuse_node_close_common(pu, opc, FREAD);
|
||||
|
||||
pnd->pnd_flags &= ~PND_INOPEN;
|
||||
|
||||
/*
|
||||
* This will cause a reclaim to be sent
|
||||
*/
|
||||
if (pnd->pnd_flags & PND_REMOVED)
|
||||
puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N1);
|
||||
|
||||
/*
|
||||
* Schedule awaiting operations
|
||||
*/
|
||||
pnd->pnd_flags &= ~PND_INOPEN;
|
||||
(void)dequeue_requests(ps, opc, PCQ_OPEN, DEQUEUE_ALL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2814,8 +2860,7 @@ perfuse_node_write(pu, opc, buf, offset, resid, pcr, ioflag)
|
||||
#ifdef PERFUSE_DEBUG
|
||||
if (perfuse_diagflags & PDF_SYNC)
|
||||
DPRINTF("%s: DIRTY opc = %p, file = \"%s\"\n",
|
||||
__func__, (void*)opc,
|
||||
(char *)PNPATH((struct puffs_node *)opc));
|
||||
__func__, (void*)opc, perfuse_node_path(opc));
|
||||
#endif
|
||||
out:
|
||||
if (pm != NULL)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: perfuse.c,v 1.9 2010/09/29 08:01:10 manu Exp $ */
|
||||
/* $NetBSD: perfuse.c,v 1.10 2010/10/03 05:46:47 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
|
||||
@ -58,7 +58,6 @@ init_state(void)
|
||||
(void)memset(ps, 0, sizeof(*ps));
|
||||
ps->ps_max_write = UINT_MAX;
|
||||
ps->ps_max_readahead = UINT_MAX;
|
||||
TAILQ_INIT(&ps->ps_pnd);
|
||||
|
||||
return ps;
|
||||
}
|
||||
@ -411,9 +410,6 @@ perfuse_init(pc, pmi)
|
||||
if (perfuse_diagflags & PDF_PUFFS)
|
||||
puffs_flags |= PUFFS_FLAG_OPDUMP;
|
||||
|
||||
if (perfuse_diagflags & PDF_FILENAME)
|
||||
puffs_flags |= PUFFS_FLAG_BUILDPATH;
|
||||
|
||||
if ((pu = puffs_init(pops, _PATH_PUFFS, name, ps, puffs_flags)) == NULL)
|
||||
DERR(EX_OSERR, "puffs_init failed");
|
||||
|
||||
@ -422,7 +418,7 @@ perfuse_init(pc, pmi)
|
||||
/*
|
||||
* Setup filesystem root
|
||||
*/
|
||||
pn_root = perfuse_new_pn(pu, NULL);
|
||||
pn_root = perfuse_new_pn(pu, "", NULL);
|
||||
PERFUSE_NODE_DATA(pn_root)->pnd_ino = FUSE_ROOT_ID;
|
||||
PERFUSE_NODE_DATA(pn_root)->pnd_parent = pn_root;
|
||||
puffs_setroot(pu, pn_root);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: perfuse_priv.h,v 1.13 2010/09/29 08:01:10 manu Exp $ */
|
||||
/* $NetBSD: perfuse_priv.h,v 1.14 2010/10/03 05:46:47 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
|
||||
@ -65,8 +65,6 @@ struct perfuse_state {
|
||||
perfuse_get_inpayload_fn ps_get_inpayload;
|
||||
perfuse_get_outhdr_fn ps_get_outhdr;
|
||||
perfuse_get_outpayload_fn ps_get_outpayload;
|
||||
TAILQ_HEAD(, perfuse_node_data) ps_pnd;
|
||||
int ps_pnd_count;
|
||||
};
|
||||
|
||||
|
||||
@ -120,6 +118,8 @@ struct perfuse_node_data {
|
||||
time_t pnd_timestamp;
|
||||
TAILQ_ENTRY(perfuse_node_data) pnd_next;
|
||||
puffs_cookie_t pnd_pn;
|
||||
char pnd_name[MAXPATHLEN]; /* node name */
|
||||
TAILQ_HEAD(,perfuse_node_data) pnd_children;
|
||||
};
|
||||
|
||||
#define PERFUSE_NODE_DATA(opc) \
|
||||
@ -140,13 +140,14 @@ struct perfuse_node_data {
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct puffs_node *perfuse_new_pn(struct puffs_usermount *,
|
||||
struct puffs_node *perfuse_new_pn(struct puffs_usermount *, const char *,
|
||||
struct puffs_node *);
|
||||
void perfuse_destroy_pn(struct puffs_usermount *, struct puffs_node *);
|
||||
void perfuse_new_fh(puffs_cookie_t, uint64_t, int);
|
||||
void perfuse_destroy_fh(puffs_cookie_t, uint64_t);
|
||||
uint64_t perfuse_get_fh(puffs_cookie_t, int);
|
||||
uint64_t perfuse_next_unique(struct puffs_usermount *);
|
||||
char *perfuse_node_path(puffs_cookie_t);
|
||||
int perfuse_node_close_common(struct puffs_usermount *, puffs_cookie_t, int);
|
||||
|
||||
char *perfuse_fs_mount(int, ssize_t);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: subr.c,v 1.7 2010/09/29 08:01:10 manu Exp $ */
|
||||
/* $NetBSD: subr.c,v 1.8 2010/10/03 05:46:47 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
|
||||
@ -36,9 +36,12 @@
|
||||
|
||||
#include "perfuse_priv.h"
|
||||
|
||||
static size_t node_path(puffs_cookie_t, char *, size_t);
|
||||
|
||||
struct puffs_node *
|
||||
perfuse_new_pn(pu, parent)
|
||||
perfuse_new_pn(pu, name, parent)
|
||||
struct puffs_usermount *pu;
|
||||
const char *name;
|
||||
struct puffs_node *parent;
|
||||
{
|
||||
struct perfuse_state *ps;
|
||||
@ -61,13 +64,18 @@ perfuse_new_pn(pu, parent)
|
||||
pnd->pnd_parent = parent;
|
||||
pnd->pnd_timestamp = time(NULL);
|
||||
pnd->pnd_pn = (puffs_cookie_t)pn;
|
||||
(void)strlcpy(pnd->pnd_name, name, MAXPATHLEN);
|
||||
TAILQ_INIT(&pnd->pnd_pcq);
|
||||
TAILQ_INIT(&pnd->pnd_children);
|
||||
|
||||
TAILQ_INSERT_TAIL(&ps->ps_pnd, pnd, pnd_next);
|
||||
ps->ps_pnd_count++;
|
||||
if (parent != NULL) {
|
||||
struct perfuse_node_data *parent_pnd;
|
||||
|
||||
if (parent != NULL)
|
||||
PERFUSE_NODE_DATA(parent)->pnd_childcount++;
|
||||
parent_pnd = PERFUSE_NODE_DATA(parent);
|
||||
TAILQ_INSERT_TAIL(&parent_pnd->pnd_children, pnd, pnd_next);
|
||||
|
||||
parent_pnd->pnd_childcount++;
|
||||
}
|
||||
|
||||
return pn;
|
||||
}
|
||||
@ -83,8 +91,12 @@ perfuse_destroy_pn(pu, pn)
|
||||
ps = puffs_getspecific(pu);
|
||||
pnd = PERFUSE_NODE_DATA(pn);
|
||||
|
||||
TAILQ_REMOVE(&ps->ps_pnd, pnd, pnd_next);
|
||||
ps->ps_pnd_count--;
|
||||
if (pnd->pnd_parent != NULL) {
|
||||
struct perfuse_node_data *parent_pnd;
|
||||
|
||||
parent_pnd = PERFUSE_NODE_DATA(pnd->pnd_parent);
|
||||
TAILQ_REMOVE(&parent_pnd->pnd_children, pnd, pnd_next);
|
||||
}
|
||||
|
||||
if ((pnd = puffs_pn_getpriv(pn)) != NULL) {
|
||||
if (pnd->pnd_parent != NULL)
|
||||
@ -197,3 +209,34 @@ perfuse_get_fh(opc, mode)
|
||||
return FUSE_UNKNOWN_FH;
|
||||
}
|
||||
|
||||
static size_t
|
||||
node_path(opc, buf, buflen)
|
||||
puffs_cookie_t opc;
|
||||
char *buf;
|
||||
size_t buflen;
|
||||
{
|
||||
struct perfuse_node_data *pnd;
|
||||
size_t written;
|
||||
|
||||
pnd = PERFUSE_NODE_DATA(opc);
|
||||
if (pnd->pnd_parent == opc)
|
||||
return 0;
|
||||
|
||||
written = node_path(pnd->pnd_parent, buf, buflen);
|
||||
buf += written;
|
||||
buflen -= written;
|
||||
|
||||
return written + snprintf(buf, buflen, "/%s", pnd->pnd_name);
|
||||
}
|
||||
|
||||
char *
|
||||
perfuse_node_path(opc)
|
||||
puffs_cookie_t opc;
|
||||
{
|
||||
static char buf[MAXPATHLEN + 1];
|
||||
|
||||
if (node_path(opc, buf, sizeof(buf)) == 0)
|
||||
sprintf(buf, "/");
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user