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:
parent
bda8cd7266
commit
f9b7e6e829
@ -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)
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user