Only nuke directory entry in remove and clear data completely only

when the node is reclaimed.  This makes dtfs preserve unix open file
semantics.
This commit is contained in:
pooka 2006-10-25 18:18:16 +00:00
parent bda8cd7266
commit f9b7e6e829
4 changed files with 70 additions and 63 deletions

View File

@ -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)

View File

@ -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 *);

View File

@ -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

View File

@ -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;
}