From f9b7e6e8290c44d0b321d2202eacf1a56d27d8b0 Mon Sep 17 00:00:00 2001 From: pooka Date: Wed, 25 Oct 2006 18:18:16 +0000 Subject: [PATCH] Only nuke directory entry in remove and clear data completely only when the node is reclaimed. This makes dtfs preserve unix open file semantics. --- share/examples/puffs/dtfs/dtfs.c | 4 +- share/examples/puffs/dtfs/dtfs.h | 7 +-- share/examples/puffs/dtfs/dtfs_subr.c | 77 +++++++++----------------- share/examples/puffs/dtfs/dtfs_vnops.c | 45 ++++++++++++--- 4 files changed, 70 insertions(+), 63 deletions(-) diff --git a/share/examples/puffs/dtfs/dtfs.c b/share/examples/puffs/dtfs/dtfs.c index 3556db7e1c27..fc193b0ea85f 100644 --- a/share/examples/puffs/dtfs/dtfs.c +++ b/share/examples/puffs/dtfs/dtfs.c @@ -1,4 +1,4 @@ -/* $NetBSD: dtfs.c,v 1.1 2006/10/23 00:44:53 pooka Exp $ */ +/* $NetBSD: dtfs.c,v 1.2 2006/10/25 18:18:16 pooka Exp $ */ /* * Copyright (c) 2006 Antti Kantee. All Rights Reserved. @@ -87,6 +87,8 @@ main(int argc, char *argv[]) pvn.puffs_link = dtfs_link; pvn.puffs_symlink = dtfs_symlink; pvn.puffs_readlink = dtfs_readlink; + pvn.puffs_reclaim = dtfs_reclaim; + pvn.puffs_inactive = dtfs_inactive; if ((pu = puffs_mount(&pvfs, &pvn, argv[1], 0, FSNAME, flags, 0)) == NULL) diff --git a/share/examples/puffs/dtfs/dtfs.h b/share/examples/puffs/dtfs/dtfs.h index 1d0d519a7693..45d80dc04e3b 100644 --- a/share/examples/puffs/dtfs/dtfs.h +++ b/share/examples/puffs/dtfs/dtfs.h @@ -1,4 +1,4 @@ -/* $NetBSD: dtfs.h,v 1.1 2006/10/23 00:44:53 pooka Exp $ */ +/* $NetBSD: dtfs.h,v 1.2 2006/10/25 18:18:16 pooka Exp $ */ /* * Copyright (c) 2006 Antti Kantee. All Rights Reserved. @@ -86,10 +86,9 @@ struct dtfs_file * dtfs_newfile(void); struct dtfs_dirent * dtfs_dirgetnth(struct dtfs_file *, int); struct dtfs_dirent * dtfs_dirgetbyname(struct dtfs_file *, const char *); -int dtfs_nukefile(struct puffs_node *, struct puffs_node *, +void dtfs_nukenode(struct puffs_node *, struct puffs_node *, const char *); -int dtfs_nukedir(struct puffs_node *, struct puffs_node *, - const char *); +void dtfs_freenode(struct puffs_node *); void dtfs_setsize(struct puffs_node *, off_t, int); void dtfs_adddent(struct puffs_node *, struct dtfs_dirent *); diff --git a/share/examples/puffs/dtfs/dtfs_subr.c b/share/examples/puffs/dtfs/dtfs_subr.c index 71c892e51745..e64e9949d891 100644 --- a/share/examples/puffs/dtfs/dtfs_subr.c +++ b/share/examples/puffs/dtfs/dtfs_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: dtfs_subr.c,v 1.1 2006/10/23 00:44:53 pooka Exp $ */ +/* $NetBSD: dtfs_subr.c,v 1.2 2006/10/25 18:18:16 pooka Exp $ */ /* * Copyright (c) 2006 Antti Kantee. All Rights Reserved. @@ -167,8 +167,8 @@ dtfs_dirgetbyname(struct dtfs_file *searchdir, const char *fname) /* * common nuke, kill dirent from parent node */ -static int -nukenode(struct puffs_node *nukeme, struct puffs_node *pn_parent, +void +dtfs_nukenode(struct puffs_node *nukeme, struct puffs_node *pn_parent, const char *fname) { struct dtfs_dirent *dfd; @@ -185,61 +185,36 @@ nukenode(struct puffs_node *nukeme, struct puffs_node *pn_parent, dtfs_removedent(pn_parent, dfd); free(dfd); - - if (nukeme->pn_va.va_nlink == 0) { - /* we don't keep track of symlink length now */ - if (nukeme->pn_va.va_type == VREG) { - assert(dtm->dtm_fsizes >= nukeme->pn_va.va_size); - dtm->dtm_fsizes -= nukeme->pn_va.va_size; - } - puffs_putpnode(nukeme); - return 1; - } - - return 0; } -int -dtfs_nukefile(struct puffs_node *pn, struct puffs_node *pn_parent, - const char *fname) +/* free lingering information */ +void +dtfs_freenode(struct puffs_node *pn) { - struct dtfs_file *nuke_f; - enum vtype type; + struct dtfs_file *df = DTFS_PTOF(pn); + struct dtfs_mount *dtm; - if (pn->pn_va.va_type == VDIR) - return EISDIR; + assert(pn->pn_va.va_nlink == 0); + dtm = pn->pn_mnt->pu_privdata; - nuke_f = pn->pn_data; - type = pn->pn_type; - if (nukenode(pn, pn_parent, fname)) { - /* well, it's this or disgusting use of union properties ;{} */ - switch (type) { - case VREG: - free(nuke_f->df_data); - break; - case VLNK: - free(nuke_f->df_linktarget); - break; - default: - assert(0); - break; - } + switch (pn->pn_type) { + case VREG: + assert(dtm->dtm_fsizes >= pn->pn_va.va_size); + dtm->dtm_fsizes -= pn->pn_va.va_size; + free(df->df_data); + break; + case VLNK: + free(df->df_linktarget); + break; + case VDIR: + break; + default: + assert(0); + break; } - return 0; -} - -int -dtfs_nukedir(struct puffs_node *pn, struct puffs_node *pn_parent, - const char *dname) -{ - struct dtfs_file *nuke_d; - - nuke_d = pn->pn_data; - if (!LIST_EMPTY(&nuke_d->df_dirents)) - return ENOTEMPTY; - - return nukenode(pn, pn_parent, dname); + free(df); + puffs_putpnode(pn); } void diff --git a/share/examples/puffs/dtfs/dtfs_vnops.c b/share/examples/puffs/dtfs/dtfs_vnops.c index 05190d64c321..f59fefeebdb4 100644 --- a/share/examples/puffs/dtfs/dtfs_vnops.c +++ b/share/examples/puffs/dtfs/dtfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: dtfs_vnops.c,v 1.2 2006/10/23 16:20:39 pooka Exp $ */ +/* $NetBSD: dtfs_vnops.c,v 1.3 2006/10/25 18:18:16 pooka Exp $ */ /* * Copyright (c) 2006 Antti Kantee. All Rights Reserved. @@ -116,7 +116,7 @@ dtfs_create(struct puffs_usermount *pu, void *opc, void **newnode, puffs_setvattr(&pn_new->pn_va, va); *newnode = pn_new; - + return 0; } @@ -125,8 +125,14 @@ dtfs_remove(struct puffs_usermount *pu, void *opc, void *targ, const struct puffs_cn *pcn) { struct puffs_node *pn_parent = opc; + struct puffs_node *pn = targ; - return dtfs_nukefile(targ, pn_parent, pcn->pcn_name); + if (pn->pn_va.va_type == VDIR) + return EISDIR; + + dtfs_nukenode(targ, pn_parent, pcn->pcn_name); + + return 0; } int @@ -136,8 +142,6 @@ dtfs_mkdir(struct puffs_usermount *pu, void *opc, void **newnode, struct puffs_node *pn_parent = opc; struct puffs_node *pn_new; - assert(va->va_type == VDIR); - pn_new = dtfs_genfile(pn_parent, pcn->pcn_name, VDIR); puffs_setvattr(&pn_new->pn_va, va); @@ -151,8 +155,14 @@ dtfs_rmdir(struct puffs_usermount *pu, void *opc, void *targ, const struct puffs_cn *pcn) { struct puffs_node *pn_parent = opc; + struct dtfs_file *df = DTFS_CTOF(targ); - return dtfs_nukedir(targ, pn_parent, pcn->pcn_name); + if (!LIST_EMPTY(&df->df_dirents)) + return ENOTEMPTY; + + dtfs_nukenode(targ, pn_parent, pcn->pcn_name); + + return 0; } int @@ -209,7 +219,7 @@ dtfs_rename(struct puffs_usermount *pu, void *opc, void *src, /* if there's a target file, nuke it for atomic replacement */ if (pn_tfile) { assert(pn_tfile->pn_type != VDIR); /* XXX? */ - dtfs_nukefile(pn_tfile, pn_sdir, pcn_targ->pcn_name); + dtfs_nukenode(pn_tfile, pn_sdir, pcn_targ->pcn_name); } /* out with the old */ @@ -342,3 +352,24 @@ dtfs_write(struct puffs_usermount *pu, void *opc, uint8_t *buf, return 0; } + +int +dtfs_reclaim(struct puffs_usermount *pu, void *opc, pid_t pid) +{ + struct puffs_node *pn = opc; + + if (pn->pn_va.va_nlink == 0) + dtfs_freenode(pn); + + return 0; +} + +int +dtfs_inactive(struct puffs_usermount *pu, void *opc, pid_t pid, int *refcount) +{ + struct puffs_node *pn = opc; + + *refcount = pn->pn_va.va_nlink; + + return 0; +}