$(top_srcdir)/build-aux/install-sh \
$(top_srcdir)/build-aux/ltmain.sh \
$(top_srcdir)/build-aux/missing COPYING NEWS build-aux/compile \
- build-aux/config.guess build-aux/config.sub build-aux/depcomp \
+ build-aux/config.guess build-aux/config.sub \
build-aux/install-sh build-aux/ltmain.sh build-aux/missing
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
+exfatprogs 1.2.1 - released 2023-05-17
+======================================
+
+CHANGES :
+ * fsck.exfat: Repair zero size directory.
+ * fsck.exfat: Four small clean-ups.
+
exfatprogs 1.2.0 - released 2022-10-28
======================================
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for exfatprogs 1.2.0.
+# Generated by GNU Autoconf 2.69 for exfatprogs 1.2.1.
#
# Report bugs to <linkinjeon@kernel.org>.
#
# Identity of this package.
PACKAGE_NAME='exfatprogs'
PACKAGE_TARNAME='exfatprogs'
-PACKAGE_VERSION='1.2.0'
-PACKAGE_STRING='exfatprogs 1.2.0'
+PACKAGE_VERSION='1.2.1'
+PACKAGE_STRING='exfatprogs 1.2.1'
PACKAGE_BUGREPORT='linkinjeon@kernel.org'
PACKAGE_URL='https://github.com/exfatprogs/exfatprogs'
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures exfatprogs 1.2.0 to adapt to many kinds of systems.
+\`configure' configures exfatprogs 1.2.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of exfatprogs 1.2.0:";;
+ short | recursive ) echo "Configuration of exfatprogs 1.2.1:";;
esac
cat <<\_ACEOF
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-exfatprogs configure 1.2.0
+exfatprogs configure 1.2.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by exfatprogs $as_me 1.2.0, which was
+It was created by exfatprogs $as_me 1.2.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
# Define the identity of the package.
PACKAGE='exfatprogs'
- VERSION='1.2.0'
+ VERSION='1.2.1'
cat >>confdefs.h <<_ACEOF
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by exfatprogs $as_me 1.2.0, which was
+This file was extended by exfatprogs $as_me 1.2.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-exfatprogs config.status 1.2.0
+exfatprogs config.status 1.2.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
} else if (ret == 0) {
return 0;
}
- buf += (size_t)ret;
+ buf = (char *)buf + (size_t)ret;
read_len += (size_t)ret;
}
return read_len;
})
static int check_clus_chain(struct exfat_de_iter *de_iter,
- struct exfat_inode *node)
+ struct exfat_inode *node)
{
struct exfat *exfat = de_iter->exfat;
struct exfat_dentry *stream_de;
- clus_t clus, prev, next;
+ clus_t clus, prev, next, new_clus;
uint64_t count, max_count;
+ int err;
clus = node->first_clus;
prev = EXFAT_EOF_CLUSTER;
count = 0;
max_count = DIV_ROUND_UP(node->size, exfat->clus_size);
- if (node->size == 0 && node->first_clus == EXFAT_FREE_CLUSTER)
+ if (node->size == 0 && node->first_clus == EXFAT_FREE_CLUSTER) {
+ /* locate a cluster for the empty dir if the dir starts with EXFAT_FREE_CLUSTER */
+ if (node->attr & ATTR_SUBDIR) {
+ if (repair_file_ask(de_iter, node,
+ ER_DE_FIRST_CLUS,
+ "size %#" PRIx64 ", but the first cluster %#x",
+ node->size, node->first_clus))
+ goto allocate_cluster;
+ return -EINVAL;
+ }
return 0;
-
+ }
/* the first cluster is wrong */
if ((node->size == 0 && node->first_clus != EXFAT_FREE_CLUSTER) ||
(node->size > 0 && !exfat_heap_clus(exfat, node->first_clus))) {
}
return 0;
+allocate_cluster:
+ exfat_de_iter_get_dirty(de_iter, 1, &stream_de);
+ err = exfat_find_free_cluster(exfat, exfat->start_clu, &new_clus);
+ if (err) {
+ exfat->start_clu = EXFAT_FIRST_CLUSTER;
+ exfat_err("failed to find a free cluster\n");
+ return -ENOSPC;
+ }
+ exfat->start_clu = new_clus;
+
+ if (exfat_set_fat(exfat, new_clus, EXFAT_EOF_CLUSTER))
+ return -EIO;
+
+ /* zero out the new cluster */
+ if (exfat_write(exfat->blk_dev->dev_fd, exfat->zero_cluster,
+ exfat->clus_size, exfat_c2o(exfat, new_clus)) !=
+ (ssize_t)exfat->clus_size) {
+ exfat_err("failed to fill new cluster with zeroes\n");
+ return -EIO;
+ }
+
+ /* modify the number of cluster form 0 to 1 */
+ count = 1;
+ stream_de->stream_start_clu = cpu_to_le32(new_clus);
+ stream_de->stream_size = cpu_to_le64(count * exfat->clus_size);
+ stream_de->stream_valid_size = cpu_to_le64(count * exfat->clus_size);
+ stream_de->dentry.stream.flags |= EXFAT_SF_CONTIGUOUS;
+ node->first_clus = new_clus;
+ node->size = count * exfat->clus_size;
+ node->is_contiguous = true;
+ exfat_bitmap_set(exfat->alloc_bitmap, new_clus);
+ return 1;
truncate_file:
node->size = count * exfat->clus_size;
if (!exfat_heap_clus(exfat, prev))
{ER_FILE_LARGER_SIZE, ERF_PREEN_YES, ERP_TRUNCATE, 0, 0, 0},
{ER_FILE_DUPLICATED_CLUS, ERF_PREEN_YES, ERP_TRUNCATE, 0, 0, 0},
{ER_FILE_ZERO_NOFAT, ERF_PREEN_YES, ERP_FIX, 0, 0, 0},
+ {ER_DE_FIRST_CLUS, ERF_PREEN_YES, ERP_FIX, 0, 0, 0}
};
static struct exfat_repair_problem *find_problem(er_problem_code_t prcode)
#define ER_FILE_LARGER_SIZE 0x00002005
#define ER_FILE_DUPLICATED_CLUS 0x00002006
#define ER_FILE_ZERO_NOFAT 0x00002007
-
+#define ER_DE_FIRST_CLUS 0x00002008
typedef unsigned int er_problem_code_t;
struct exfat_fsck;
int exfat_build_file_dentry_set(struct exfat *exfat, const char *name,
unsigned short attr, struct exfat_dentry **dentry_set,
int *dentry_count);
+int exfat_find_free_cluster(struct exfat *exfat, clus_t start, clus_t *new_clu);
int exfat_add_dentry_set(struct exfat *exfat, struct exfat_dentry_loc *loc,
struct exfat_dentry *dset, int dcount,
bool need_next_loc);
+++ /dev/null
-diff a/include/libexfat.h b/include/libexfat.h (rejected hunks)
-@@ -35,6 +35,7 @@
- #define VOLUME_LABEL_BUFFER_SIZE (VOLUME_LABEL_MAX_LEN*MB_LEN_MAX+1)
-
- /* Upcase tabel macro */
-+#define EXFAT_UPCASE_TABLE_CHARS (0x10000)
- #define EXFAT_UPCASE_TABLE_SIZE (5836)
-
- /* Flags for tune.exfat and exfatlabel */
#ifndef _VERSION_H
-#define EXFAT_PROGS_VERSION "1.2.0"
+#define EXFAT_PROGS_VERSION "1.2.1"
#endif /* !_VERSION_H */
+++ /dev/null
-diff a/include/version.h b/include/version.h (rejected hunks)
-@@ -6,6 +6,6 @@
- #ifndef _VERSION_H
-
- #define EXFAT_PROGS_VERSION "1.1.2"
--#define WEBOS_EXFAT_PROGS_VERSION "webos-1.1.2-8"
-+#define WEBOS_EXFAT_PROGS_VERSION "webos-1.1.2-9"
-
- #endif /* !_VERSION_H */
unsigned int i;
desc = &iter->buffer_desc[block & 0x01];
- device_offset = exfat_c2o(exfat, desc->p_clus) + desc->offset;
for (i = 0; i < iter->read_size / iter->write_size; i++) {
if (desc->dirty[i]) {
+ device_offset = exfat_c2o(exfat, desc->p_clus) +
+ desc->offset;
if (exfat_write(exfat->blk_dev->dev_fd,
desc->buffer + i * iter->write_size,
iter->write_size,
return 0;
}
-static int find_free_cluster(struct exfat *exfat,
+int exfat_find_free_cluster(struct exfat *exfat,
clus_t start, clus_t *new_clu)
{
clus_t end = le32_to_cpu(exfat->bs->bsx.clu_count) +
if ((need_dset && !inode->dentry_set) || inode->is_contiguous)
return -EINVAL;
- err = find_free_cluster(exfat, exfat->start_clu, new_clu);
+ err = exfat_find_free_cluster(exfat, exfat->start_clu, new_clu);
if (err) {
exfat->start_clu = EXFAT_FIRST_CLUSTER;
exfat_err("failed to find an free cluster\n");
#include <errno.h>
#include <wchar.h>
#include <limits.h>
+#include <assert.h>
#include "exfat_ondisk.h"
#include "libexfat.h"
off_t exfat_c2o(struct exfat *exfat, unsigned int clus)
{
- if (clus < EXFAT_FIRST_CLUSTER)
- return ~0L;
+ assert(clus >= EXFAT_FIRST_CLUSTER);
return exfat_s2o(exfat, le32_to_cpu(exfat->bs->bsx.clu_offset) +
((off_t)(clus - EXFAT_FIRST_CLUSTER) <<
.IP -
Start cluster number is invalid. The cluster number and file size are changed to 0.
.IP -
-Checksum value of direcotry entry set is invalid. Directory entry set is deleted.
+Checksum value of directory entry set is invalid. Directory entry set is deleted.
.IP -
Bad hash value of a file name. The hash value is changed properly.
.IP -