Skip to content

Commit

Permalink
Update exfat to newest commits
Browse files Browse the repository at this point in the history
Change-Id: If15df21a556d39e6325ca8338345b698b9d8759d
  • Loading branch information
bigbiff committed Mar 7, 2013
1 parent cdcfee4 commit 998716f
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 99 deletions.
20 changes: 4 additions & 16 deletions exfat/exfat-fuse/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
#error FUSE 2.6 or later is required
#endif

const char* default_options = "ro_fallback,allow_other,blkdev,big_writes";
const char* default_options = "ro_fallback,allow_other,blkdev,big_writes,"
"defer_permissions";

struct exfat ef;

Expand Down Expand Up @@ -79,7 +80,7 @@ static int fuse_exfat_truncate(const char* path, off64_t size)
if (rc != 0)
return rc;

rc = exfat_truncate(&ef, node, size);
rc = exfat_truncate(&ef, node, size, true);
exfat_put_node(&ef, node);
return rc;
}
Expand Down Expand Up @@ -343,19 +344,6 @@ static char* add_option(char* options, const char* name, const char* value)
return options;
}

static char* add_fsname_option(char* options, const char* spec)
{
char spec_abs[PATH_MAX];

if (realpath(spec, spec_abs) == NULL)
{
free(options);
exfat_error("failed to get absolute path for `%s'", spec);
return NULL;
}
return add_option(options, "fsname", spec_abs);
}

static char* add_user_option(char* options)
{
struct passwd* pw;
Expand Down Expand Up @@ -387,7 +375,7 @@ static char* add_blksize_option(char* options, long cluster_size)

static char* add_fuse_options(char* options, const char* spec)
{
options = add_fsname_option(options, spec);
options = add_option(options, "fsname", spec);
if (options == NULL)
return NULL;
options = add_user_option(options);
Expand Down
65 changes: 26 additions & 39 deletions exfat/libexfat/cluster.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,41 +106,24 @@ cluster_t exfat_advance_cluster(const struct exfat* ef,
return node->fptr_cluster;
}

static cluster_t find_bit_and_set(uint8_t* bitmap, cluster_t start,
cluster_t end)
static cluster_t find_bit_and_set(uint8_t* bitmap, size_t start, size_t end)
{
const cluster_t mid_start = (start + 7) / 8 * 8;
const cluster_t mid_end = end / 8 * 8;
cluster_t c;
cluster_t byte;

for (c = start; c < mid_start; c++)
if (BMAP_GET(bitmap, c) == 0)
{
BMAP_SET(bitmap, c);
return c + EXFAT_FIRST_DATA_CLUSTER;
}

for (byte = mid_start / 8; byte < mid_end / 8; byte++)
if (bitmap[byte] != 0xff)
{
cluster_t bit;

for (bit = 0; bit < 8; bit++)
if (!(bitmap[byte] & (1u << bit)))
{
bitmap[byte] |= (1u << bit);
return byte * 8 + bit + EXFAT_FIRST_DATA_CLUSTER;
}
}

for (c = mid_end; c < end; c++)
if (BMAP_GET(bitmap, c) == 0)
{
BMAP_SET(bitmap, c);
return c + EXFAT_FIRST_DATA_CLUSTER;
}
const size_t start_index = start / 8;
const size_t end_index = DIV_ROUND_UP(end, 8);
size_t i;
size_t c;

for (i = start_index; i < end_index; i++)
{
if (bitmap[i] == 0xff)
continue;
for (c = MAX(i * 8, start); c < MIN((i + 1) * 8, end); c++)
if (BMAP_GET(bitmap, c) == 0)
{
BMAP_SET(bitmap, c);
return c + EXFAT_FIRST_DATA_CLUSTER;
}
}
return EXFAT_CLUSTER_END;
}

Expand All @@ -151,7 +134,7 @@ void exfat_flush_cmap(struct exfat* ef)
ef->cmap.dirty = false;
}

static void set_next_cluster(const struct exfat* ef, int contiguous,
static void set_next_cluster(const struct exfat* ef, bool contiguous,
cluster_t current, cluster_t next)
{
off64_t fat_offset;
Expand Down Expand Up @@ -204,7 +187,7 @@ static void make_noncontiguous(const struct exfat* ef, cluster_t first,
cluster_t c;

for (c = first; c < last; c++)
set_next_cluster(ef, 0, c, c + 1);
set_next_cluster(ef, false, c, c + 1);
}

static int shrink_file(struct exfat* ef, struct exfat_node* node,
Expand Down Expand Up @@ -361,7 +344,8 @@ static int erase_range(struct exfat* ef, struct exfat_node* node,
return 0;
}

int exfat_truncate(struct exfat* ef, struct exfat_node* node, uint64_t size)
int exfat_truncate(struct exfat* ef, struct exfat_node* node, uint64_t size,
bool erase)
{
uint32_t c1 = bytes2clusters(ef, node->size);
uint32_t c2 = bytes2clusters(ef, size);
Expand All @@ -381,9 +365,12 @@ int exfat_truncate(struct exfat* ef, struct exfat_node* node, uint64_t size)
if (rc != 0)
return rc;

rc = erase_range(ef, node, node->size, size);
if (rc != 0)
return rc;
if (erase)
{
rc = erase_range(ef, node, node->size, size);
if (rc != 0)
return rc;
}

exfat_update_mtime(node);
node->size = size;
Expand Down
3 changes: 2 additions & 1 deletion exfat/libexfat/exfat.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ cluster_t exfat_next_cluster(const struct exfat* ef,
cluster_t exfat_advance_cluster(const struct exfat* ef,
struct exfat_node* node, uint32_t count);
void exfat_flush_cmap(struct exfat* ef);
int exfat_truncate(struct exfat* ef, struct exfat_node* node, uint64_t size);
int exfat_truncate(struct exfat* ef, struct exfat_node* node, uint64_t size,
bool erase);
uint32_t exfat_count_free_clusters(const struct exfat* ef);
int exfat_find_used_sectors(const struct exfat* ef, off64_t* a, off64_t* b);

Expand Down
13 changes: 8 additions & 5 deletions exfat/libexfat/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
io.c (02.09.09)
exFAT file system implementation library.
Copyright (C) 2010-2012 Andrew Nayenko
Copyright (C) 2010-2013 Andrew Nayenko
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -350,10 +350,13 @@ ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node,
cluster_t cluster;
const char* bufp = buffer;
off64_t lsize, loffset, remainder;
printf("node: %s\n", node);
if (offset + size > node->size)
if (exfat_truncate(ef, node, offset + size) != 0)
return -1;

if (offset > node->size)
if (exfat_truncate(ef, node, offset, true) != 0)
return -1;
if (offset + size > node->size)
if (exfat_truncate(ef, node, offset + size, false) != 0)
return -1;
if (size == 0)
return 0;

Expand Down
73 changes: 35 additions & 38 deletions exfat/libexfat/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ void exfat_put_node(struct exfat* ef, struct exfat_node* node)
if (node->flags & EXFAT_ATTRIB_UNLINKED)
{
/* free all clusters and node structure itself */
exfat_truncate(ef, node, 0);
exfat_truncate(ef, node, 0, true);
free(node);
}
if (ef->cmap.dirty)
Expand Down Expand Up @@ -457,28 +457,49 @@ int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir)
return 0;
}

static void reset_cache(struct exfat* ef, struct exfat_node* node)
static void tree_attach(struct exfat_node* dir, struct exfat_node* node)
{
node->parent = dir;
if (dir->child)
{
dir->child->prev = node;
node->next = dir->child;
}
dir->child = node;
}

static void tree_detach(struct exfat_node* node)
{
struct exfat_node* child;
struct exfat_node* next;
if (node->prev)
node->prev->next = node->next;
else /* this is the first node in the list */
node->parent->child = node->next;
if (node->next)
node->next->prev = node->prev;
node->parent = NULL;
node->prev = NULL;
node->next = NULL;
}

for (child = node->child; child; child = next)
static void reset_cache(struct exfat* ef, struct exfat_node* node)
{
while (node->child)
{
reset_cache(ef, child);
next = child->next;
free(child);
struct exfat_node* p = node->child;
reset_cache(ef, p);
tree_detach(p);
free(p);
}
node->flags &= ~EXFAT_ATTRIB_CACHED;
if (node->references != 0)
{
char buffer[EXFAT_NAME_MAX + 1];
exfat_get_name(node, buffer, EXFAT_NAME_MAX);
exfat_warn("non-zero reference counter (%d) for `%s'",
node->references, buffer);
}
while (node->references--)
while (node->references)
exfat_put_node(ef, node);
node->child = NULL;
node->flags &= ~EXFAT_ATTRIB_CACHED;
}

void exfat_reset_cache(struct exfat* ef)
Expand Down Expand Up @@ -563,30 +584,6 @@ static void erase_entry(struct exfat* ef, struct exfat_node* node)
}
}

static void tree_detach(struct exfat_node* node)
{
if (node->prev)
node->prev->next = node->next;
else /* this is the first node in the list */
node->parent->child = node->next;
if (node->next)
node->next->prev = node->prev;
node->parent = NULL;
node->prev = NULL;
node->next = NULL;
}

static void tree_attach(struct exfat_node* dir, struct exfat_node* node)
{
node->parent = dir;
if (dir->child)
{
dir->child->prev = node;
node->next = dir->child;
}
dir->child = node;
}

static int shrink_directory(struct exfat* ef, struct exfat_node* dir,
off64_t deleted_offset)
{
Expand Down Expand Up @@ -630,7 +627,7 @@ static int shrink_directory(struct exfat* ef, struct exfat_node* dir,
new_size = CLUSTER_SIZE(*ef->sb);
if (new_size == dir->size)
return 0;
rc = exfat_truncate(ef, dir, new_size);
rc = exfat_truncate(ef, dir, new_size, true);
if (rc != 0)
return rc;
return 0;
Expand Down Expand Up @@ -676,7 +673,7 @@ static int grow_directory(struct exfat* ef, struct exfat_node* dir,
{
return exfat_truncate(ef, dir,
DIV_ROUND_UP(asize + difference, CLUSTER_SIZE(*ef->sb))
* CLUSTER_SIZE(*ef->sb));
* CLUSTER_SIZE(*ef->sb), true);
}

static int find_slot(struct exfat* ef, struct exfat_node* dir,
Expand Down Expand Up @@ -829,7 +826,7 @@ int exfat_mkdir(struct exfat* ef, const char* path)
if (rc != 0)
return 0;
/* directories always have at least one cluster */
rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb));
rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb), true);
if (rc != 0)
{
delete(ef, node);
Expand Down

0 comments on commit 998716f

Please sign in to comment.