]> git.sven.stormbind.net Git - sven/exfatprogs.git/commitdiff
New upstream version 1.2.1 upstream/1.2.1
authorSven Hoexter <sven@stormbind.net>
Tue, 23 May 2023 11:59:09 +0000 (13:59 +0200)
committerSven Hoexter <sven@stormbind.net>
Tue, 23 May 2023 11:59:09 +0000 (13:59 +0200)
14 files changed:
Makefile.in
NEWS
configure
exfat2img/exfat2img.c
fsck/fsck.c
fsck/repair.c
fsck/repair.h
include/exfat_dir.h
include/libexfat.h.rej [deleted file]
include/version.h
include/version.h.rej [deleted file]
lib/exfat_dir.c
lib/libexfat.c
manpages/fsck.exfat.8

index 76de3b7d315fcea401ad8aaef8ca3714acf7f6d8..e1c0b64780a92f4e19a91de8ce77945b94026cd9 100644 (file)
@@ -198,7 +198,7 @@ am__DIST_COMMON = $(dist_man8_MANS) $(srcdir)/Makefile.in \
        $(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)
diff --git a/NEWS b/NEWS
index f845397154c665cae2eb31cb82a433ae2955517c..f371d621e6aa836dc2b6ea638347d057acddae62 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,10 @@
+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
 ======================================
 
index 436be7a39c84b4499a6680e8c2fd744619dd76ef..c2938e993527cea2077a61f965ee94d22fd07d42 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /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>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # 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'
 
@@ -1325,7 +1325,7 @@ if test "$ac_init_help" = "long"; then
   # 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]...
 
@@ -1396,7 +1396,7 @@ fi
 
 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
 
@@ -1508,7 +1508,7 @@ fi
 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.
@@ -1786,7 +1786,7 @@ cat >config.log <<_ACEOF
 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 $@
@@ -2654,7 +2654,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='exfatprogs'
- VERSION='1.2.0'
+ VERSION='1.2.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -13256,7 +13256,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # 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
@@ -13323,7 +13323,7 @@ _ACEOF
 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\\"
 
index 81e86d2f12b4da5132e9b1e5b6fe54bcba53d104..be1f0f3861857c4ad034546a9f9616ad3f8786b3 100644 (file)
@@ -754,7 +754,7 @@ static ssize_t read_stream(int fd, void *buf, size_t len)
                } else if (ret == 0) {
                        return 0;
                }
-               buf += (size_t)ret;
+               buf = (char *)buf + (size_t)ret;
                read_len += (size_t)ret;
        }
        return read_len;
index 219d7237e1b3ece0b13cb487d4fd2ca38549a3d5..cd9ee9a193e344af59482af52256cbe98b4c5896 100644 (file)
@@ -103,21 +103,31 @@ static void usage(char *name)
 })
 
 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))) {
@@ -215,6 +225,38 @@ static int check_clus_chain(struct exfat_de_iter *de_iter,
        }
 
        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))
index 92b1c3f90799868297bc3290f3a4e00d5c109b46..ab46f85a6b0e0bb6e066ed53b3ae6b663948a2d9 100644 (file)
@@ -61,6 +61,7 @@ static struct exfat_repair_problem problems[] = {
        {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)
index dc3cc50c0468bf9a3ab7031f14d0f7d5146959f4..ea897475f7ad3865a854aba4e84085b2212cd5bf 100644 (file)
@@ -23,7 +23,7 @@
 #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;
 
index 3bc5b51c6f4c9f028a76394ca72a3b906c2c43e0..12e154600b1f28747b6cd3f356e534a8a835b468 100644 (file)
@@ -75,6 +75,7 @@ int exfat_update_file_dentry_set(struct exfat *exfat,
 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);
diff --git a/include/libexfat.h.rej b/include/libexfat.h.rej
deleted file mode 100644 (file)
index 63c0a8b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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 */
index b0348d6a3a0d43a64fd7f8723a5bd837b0694320..f0b250ce59682f3c8d1cef37a3dc0661d03633f0 100644 (file)
@@ -5,6 +5,6 @@
 
 #ifndef _VERSION_H
 
-#define EXFAT_PROGS_VERSION "1.2.0"
+#define EXFAT_PROGS_VERSION "1.2.1"
 
 #endif /* !_VERSION_H */
diff --git a/include/version.h.rej b/include/version.h.rej
deleted file mode 100644 (file)
index e7c2573..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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 */
index 499b672f34fb977553c464f0dc64f32855df1b55..7c145f4a54978893f03ea6f07e81d001fca14324 100644 (file)
@@ -35,10 +35,11 @@ static ssize_t write_block(struct exfat_de_iter *iter, unsigned int block)
        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,
@@ -677,7 +678,7 @@ int exfat_update_file_dentry_set(struct exfat *exfat,
        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) +
@@ -804,7 +805,7 @@ static int exfat_alloc_cluster(struct exfat *exfat, struct exfat_inode *inode,
        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");
index d7c1df1ca655d34400c30d9e5aef80e54f63d8dc..4fd4ac6686e37dcf8a8aa0b6e5b2e1b7ee8019a5 100644 (file)
@@ -15,6 +15,7 @@
 #include <errno.h>
 #include <wchar.h>
 #include <limits.h>
+#include <assert.h>
 
 #include "exfat_ondisk.h"
 #include "libexfat.h"
@@ -748,8 +749,7 @@ off_t exfat_s2o(struct exfat *exfat, off_t sect)
 
 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) <<
index 3b247d5f6b7eda40e1ed01b289824e7e2971afd9..5faecf0321537537f277ccbf976a991f82039264 100644 (file)
@@ -42,7 +42,7 @@ Files share the same cluster.  Cluster chains for files except one are broken.
 .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 -