/*
* Copyright (c) 2006 Antti Kantee. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Well, as you can probably see, this interface has the slight problem
* of assuming file creation will always be successful, or at least not
* giving a reason for the failure. Be sure to do better when you
* implement your own fs.
*/
struct puffs_node *
dtfs_genfile(struct puffs_node *dir, const struct puffs_cn *pcn,
enum vtype type)
{
struct dtfs_file *dff;
struct dtfs_dirent *dfd;
struct dtfs_mount *dtm;
struct puffs_node *newpn;
uid_t uid;
int rv;
switch (pn->pn_va.va_type) {
case VREG:
assert(dtm->dtm_fsizes >= pn->pn_va.va_size);
dtm->dtm_fsizes -= pn->pn_va.va_size;
for (i = 0; i < BLOCKNUM(df->df_datalen, DTFS_BLOCKSHIFT); i++)
free(df->df_blocks[i]);
if (df->df_datalen > i << DTFS_BLOCKSHIFT)
free(df->df_blocks[i]);
break;
case VLNK:
free(df->df_linktarget);
break;
case VCHR:
case VBLK:
case VDIR:
case VSOCK:
case VFIFO:
break;
default:
assert(0);
break;
}
if (shrinks)
for (i = newblocks; i < df->df_numblocks; i++)
free(df->df_blocks[i]);
df->df_blocks = erealloc(df->df_blocks,
newblocks * sizeof(uint8_t *));
/*
* if extended, set storage to zero
* to match correct behaviour
*/
if (!shrinks) {
for (i = df->df_numblocks; i < newblocks; i++) {
df->df_blocks[i] = emalloc(DTFS_BLOCKSIZE);
memset(df->df_blocks[i], 0, DTFS_BLOCKSIZE);
}
}