コード例 #1
0
void exfat_put_node(struct exfat* ef, struct exfat_node* node)
{
	if (--node->references < 0)
	{
		char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
		exfat_get_name(node, buffer, sizeof(buffer) - 1);
		exfat_bug("reference counter of `%s' is below zero", buffer);
	}

	if (node->references == 0)
	{
		/* FIXME handle I/O error */
		if (exfat_flush_node(ef, node) != 0)
			exfat_bug("node flush failed");
		if (node->flags & EXFAT_ATTRIB_UNLINKED)
		{
			/* free all clusters and node structure itself */
			exfat_truncate(ef, node, 0, true);
			free(node);
		}
		/* FIXME handle I/O error */
		if (exfat_flush(ef) != 0)
			exfat_bug("flush failed");
	}
}
コード例 #2
0
static int fuse_exfat_flush(const char* path, struct fuse_file_info* fi)
{
	/*
	   This handler may be called by FUSE on close() syscall. FUSE also deals
	   with removals of open files, so we don't free clusters on close but
	   only on rmdir and unlink. If the FUSE implementation does not call this
	   handler we will flush node on release. See fuse_exfat_relase() above.
	*/
	exfat_debug("[%s] %s", __func__, path);
	return exfat_flush_node(&ef, get_node(fi));
}
コード例 #3
0
static int fuse_exfat_truncate(const char* path, off_t size)
{
	struct exfat_node* node;
	int rc;

	exfat_debug("[%s] %s, %"PRId64, __func__, path, size);

	rc = exfat_lookup(&ef, &node, path);
	if (rc != 0)
		return rc;

	rc = exfat_truncate(&ef, node, size, true);
	if (rc != 0)
	{
		exfat_flush_node(&ef, node);	/* ignore return code */
		exfat_put_node(&ef, node);
		return rc;
	}
	rc = exfat_flush_node(&ef, node);
	exfat_put_node(&ef, node);
	return rc;
}
コード例 #4
0
static int fuse_exfat_release(const char* path, struct fuse_file_info* fi)
{
	/*
	   This handler is called by FUSE on close() syscall. If the FUSE
	   implementation does not call flush handler, we will flush node here.
	   But in this case we will not be able to return an error to the caller.
	   See fuse_exfat_flush() below.
	*/
	exfat_debug("[%s] %s", __func__, path);
 	exfat_flush_node(&ef, get_node(fi));
	exfat_put_node(&ef, get_node(fi));
	return 0; /* FUSE ignores this return value */
}
コード例 #5
0
static int fuse_exfat_utimens(const char* path, const struct timespec tv[2])
{
	struct exfat_node* node;
	int rc;

	exfat_debug("[%s] %s", __func__, path);

	rc = exfat_lookup(&ef, &node, path);
	if (rc != 0)
		return rc;

	exfat_utimes(node, tv);
	rc = exfat_flush_node(&ef, node);
	exfat_put_node(&ef, node);
	return rc;
}
コード例 #6
0
void exfat_put_node(struct exfat* ef, struct exfat_node* node)
{
    if (--node->references < 0)
    {
        char buffer[EXFAT_NAME_MAX + 1];
        exfat_get_name(node, buffer, EXFAT_NAME_MAX);
        exfat_bug("reference counter of `%s' is below zero", buffer);
    }

    if (node->references == 0)
    {
        if (node->flags & EXFAT_ATTRIB_DIRTY)
            exfat_flush_node(ef, node);
        if (node->flags & EXFAT_ATTRIB_UNLINKED)
        {
            /* free all clusters and node structure itself */
            exfat_truncate(ef, node, 0);
            free(node);
        }
        if (ef->cmap.dirty)
            exfat_flush_cmap(ef);
    }
}