You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2020/01/09 12:38:37 UTC

[incubator-nuttx] branch pr66 updated (255f300 -> e83f401)

This is an automated email from the ASF dual-hosted git repository.

acassis pushed a change to branch pr66
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.


    from 255f300  arch: k210: Applied changes doned for fe310 recently.
     new 58f55d7  drivers: mtd: smart: Fix handling of duplicate sector in smartfs
     new 6ede4b1  drivers: mtd: smart: Fix initialize sector sequence value in smartfs
     new 82508e4  drivers: mtd: smart: Fix error handling in smartfs mtd driver
     new 14c58b0  drivers: mtd: smart: SPI-Flash recovery from the initial error state
     new d15e755  drivers: mtd: smart: Check CRC of duplicate sectors
     new 60927c5  drivers: mtd: smart: Fix duplicate sector selection in SmartFS
     new e83f401  drivers: mtd: smart: Add smartfs fsck feature

The 7 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 drivers/mtd/Kconfig |  15 ++
 drivers/mtd/smart.c | 626 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 629 insertions(+), 12 deletions(-)


[incubator-nuttx] 03/07: drivers: mtd: smart: Fix error handling in smartfs mtd driver

Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch pr66
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 82508e4e2fb54459e0d327bec5c959e392bcca09
Author: Alin Jerpelea <al...@sony.com>
AuthorDate: Tue Jan 30 16:52:07 2018 +0900

    drivers: mtd: smart: Fix error handling in smartfs mtd driver
    
    Add error handling in relocate sector.
---
 drivers/mtd/smart.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/smart.c b/drivers/mtd/smart.c
index eb5fa1e..406c793 100644
--- a/drivers/mtd/smart.c
+++ b/drivers/mtd/smart.c
@@ -3220,6 +3220,11 @@ static int smart_relocate_sector(FAR struct smart_struct_s *dev,
 
   ret = MTD_BWRITE(dev->mtd, newsector * dev->mtdblkspersector,
                    dev->mtdblkspersector, (FAR uint8_t *) dev->rwbuffer);
+  if (ret != dev->mtdblkspersector)
+    {
+      ferr("Error writing to new sector %d\n", newsector);
+      goto errout;
+    }
 
 #else   /* CONFIG_MTD_SMART_ENABLE_CRC */
 
@@ -3233,6 +3238,11 @@ static int smart_relocate_sector(FAR struct smart_struct_s *dev,
 
   ret = MTD_BWRITE(dev->mtd, newsector * dev->mtdblkspersector,
                    dev->mtdblkspersector, (FAR uint8_t *) dev->rwbuffer);
+  if (ret != dev->mtdblkspersector)
+    {
+      ferr("Error writing to new sector %d\n", newsector);
+      goto errout;
+    }
 
   /* Commit the sector */
 
@@ -3266,10 +3276,7 @@ static int smart_relocate_sector(FAR struct smart_struct_s *dev,
       ferr("ERROR: Error %d releasing old sector %d\n" -ret, oldsector);
     }
 
-#ifndef CONFIG_MTD_SMART_ENABLE_CRC
 errout:
-#endif
-
   return ret;
 }
 


[incubator-nuttx] 04/07: drivers: mtd: smart: SPI-Flash recovery from the initial error state

Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch pr66
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 14c58b0f8c9f1fce8a61b26c98b36ddbb88ede51
Author: Alin Jerpelea <al...@sony.com>
AuthorDate: Tue May 15 06:52:16 2018 +0900

    drivers: mtd: smart: SPI-Flash recovery from the initial error state
    
    The FLASH may be not erased in the initial delivery state.
    Just in case for the recovery of this fatal situation,
    after once erasing the sector, return the sector as a free sector.
---
 drivers/mtd/smart.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/mtd/smart.c b/drivers/mtd/smart.c
index 406c793..d5cd676 100644
--- a/drivers/mtd/smart.c
+++ b/drivers/mtd/smart.c
@@ -3780,6 +3780,21 @@ retry:
           dev->lastallocblock = allocblock;
           break;
         }
+      else
+        {
+          /* The FLASH may be not erased in the initial delivery state.
+           * Just in case for the recovery of this fatal situation,
+           * after once erasing the sector, return the sector as a free sector.
+           */
+
+          if (1 == dev->availsectperblk)
+            {
+              MTD_ERASE(dev->mtd, allocblock, 1);
+              physicalsector = i;
+              dev->lastallocblock = allocblock;
+              break;
+            }
+        }
     }
 
   if (physicalsector == 0xffff)


[incubator-nuttx] 05/07: drivers: mtd: smart: Check CRC of duplicate sectors

Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch pr66
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit d15e755335cbb100c0ca3af722ede1c4d2c20c9b
Author: Alin Jerpelea <al...@sony.com>
AuthorDate: Thu Jan 9 12:57:52 2020 +0100

    drivers: mtd: smart: Check CRC of duplicate sectors
    
    In the illegal case by power-loss, when the multiple logical sectors are
    duplicated, we compare the sequence number of each sector and select the newer
    sector. Just in case, add CRC check for the newer sector. If the newer sector
    has CRC error, then we use the older sector.
    
    Signed-off-by: Alin Jerpelea <al...@sony.com>
---
 drivers/mtd/smart.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 58 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/smart.c b/drivers/mtd/smart.c
index d5cd676..e011195 100644
--- a/drivers/mtd/smart.c
+++ b/drivers/mtd/smart.c
@@ -391,6 +391,9 @@ static inline int smart_allocsector(FAR struct smart_struct_s *dev,
 #endif
 static int smart_readsector(FAR struct smart_struct_s *dev, unsigned long arg);
 
+#ifdef CONFIG_MTD_SMART_ENABLE_CRC
+static int smart_validate_crc(FAR struct smart_struct_s *dev);
+#endif
 #ifdef CONFIG_MTD_SMART_WEAR_LEVEL
 static int smart_read_wearstatus(FAR struct smart_struct_s *dev);
 static int smart_relocate_static_data(FAR struct smart_struct_s *dev, uint16_t block);
@@ -1865,6 +1868,7 @@ static int smart_scan(FAR struct smart_struct_s *dev)
   uint16_t  totalsectors;
   uint16_t  sectorsize, prerelease;
   uint16_t  logicalsector;
+  uint16_t  winner;
   uint16_t  loser;
   uint32_t  readaddress;
   uint32_t  offset;
@@ -1999,6 +2003,8 @@ static int smart_scan(FAR struct smart_struct_s *dev)
     {
       finfo("Scan sector %d\n", sector);
 
+      winner = sector;
+
       /* Calculate the read address for this sector */
 
       readaddress = sector * dev->mtdblkspersector * dev->geo.blocksize;
@@ -2278,9 +2284,9 @@ static int smart_scan(FAR struct smart_struct_s *dev)
             {
               /* Seq 2 is the winner ... bigger or it wrapped */
 
+              winner = sector;
 #ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
               loser = dev->smap[logicalsector];
-              dev->smap[logicalsector] = sector;
 #else
               loser = dupsector;
 #endif
@@ -2290,7 +2296,56 @@ static int smart_scan(FAR struct smart_struct_s *dev)
               /* We keep the original mapping and seq2 is the loser */
 
               loser = sector;
+#ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
+              winner = dev->smap[logicalsector];
+#else
+              winner = smart_cache_lookup(dev, logicalsector);
+#endif
+            }
+
+          finfo("Duplicate Sector winner=%d, loser=%d\n", winner, loser);
+
+#ifdef CONFIG_MTD_SMART_ENABLE_CRC
+          /* Check CRC of the winner sector just in case */
+
+          ret = MTD_BREAD(dev->mtd, winner * dev->mtdblkspersector,
+                          dev->mtdblkspersector, (FAR uint8_t *) dev->rwbuffer);
+          if (ret == dev->mtdblkspersector)
+            {
+              /* Validate the CRC of the read-back data */
+
+              ret = smart_validate_crc(dev);
+            }
+
+          if (ret != OK)
+            {
+              /* The winner sector has CRC error, so we select the loser sector.
+               * After swapping the winner and the loser sector, we will release
+               * the loser sector with CRC error.
+               */
+
+              if (sector == winner)
+                {
+                  /* winner: sector(CRC error) -> origin
+                   * loser : origin            -> sector(CRC error)
+                   */
+
+                  winner = loser;
+                  loser = sector;
+                }
+              else
+                {
+                  /* winner: origin(CRC error) -> sector
+                   * loser : sector            -> origin(CRC error)
+                   */
+
+                  loser = winner;
+                  winner = sector;
+                }
+
+              finfo("Duplicate Sector winner=%d, loser=%d\n", winner, loser);
             }
+#endif  /* CONFIG_MTD_SMART_ENABLE_CRC */
 
           /* Now release the loser sector */
 
@@ -2326,7 +2381,7 @@ static int smart_scan(FAR struct smart_struct_s *dev)
 #ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
       /* Update the logical to physical sector map */
 
-      dev->smap[logicalsector] = sector;
+      dev->smap[logicalsector] = winner;
 #else
       /* Mark the logical sector as used in the bitmap */
 
@@ -2334,7 +2389,7 @@ static int smart_scan(FAR struct smart_struct_s *dev)
 
       if (logicalsector < SMART_FIRST_ALLOC_SECTOR)
         {
-          smart_add_sector_to_cache(dev, logicalsector, sector, __LINE__);
+          smart_add_sector_to_cache(dev, logicalsector, winner, __LINE__);
         }
 #endif
     }


[incubator-nuttx] 01/07: drivers: mtd: smart: Fix handling of duplicate sector in smartfs

Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch pr66
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 58f55d707f959f05dd28757458712f44484ec97e
Author: Alin Jerpelea <al...@sony.com>
AuthorDate: Thu Jan 11 00:43:39 2018 +0900

    drivers: mtd: smart: Fix handling of duplicate sector in smartfs
    
    In smartfs scan, if duplicate logical sector is found on the device,
    then smartfs selects the winner sector by comparing sequence number,
    and the loser sector is soon released. Fix a bug this loser sector
    is registered into logical-to-physical sector mapping table.
---
 drivers/mtd/smart.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/mtd/smart.c b/drivers/mtd/smart.c
index b7a5954..8f59a53 100644
--- a/drivers/mtd/smart.c
+++ b/drivers/mtd/smart.c
@@ -1991,6 +1991,10 @@ static int smart_scan(FAR struct smart_struct_s *dev)
 
   /* Now scan the MTD device */
 
+  /* At first, set the loser sector as the invalid value */
+
+  loser = totalsectors;
+
   for (sector = 0; sector < totalsectors; sector++)
     {
       finfo("Scan sector %d\n", sector);
@@ -2312,6 +2316,13 @@ static int smart_scan(FAR struct smart_struct_s *dev)
             }
         }
 
+      /* Test if this sector is loser of duplicate logical sector */
+
+      if (sector == loser)
+        {
+          continue;
+        }
+
 #ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
       /* Update the logical to physical sector map */
 


[incubator-nuttx] 07/07: drivers: mtd: smart: Add smartfs fsck feature

Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch pr66
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit e83f401e43ea2b33da95b8d6164a88598fa21e02
Author: Alin Jerpelea <al...@sony.com>
AuthorDate: Thu Jan 9 13:01:04 2020 +0100

    drivers: mtd: smart: Add smartfs fsck feature
    
    Support fsck to check and repair the smartfs file system. If the power
    loss occurs during writing into the flash, the dead space are created
    in flash after the next power cycle. To avoid this problem, introduce
    fsck and keep the consistency of file system in initializing smartfs.
    
    Signed-off-by: Alin Jerpelea <al...@sony.com>
---
 drivers/mtd/Kconfig |  15 ++
 drivers/mtd/smart.c | 506 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 521 insertions(+)

diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index a80159d..e987fd6 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -775,6 +775,21 @@ config SMART_CRC_16
 
 endchoice # CRC level selection
 
+config MTD_SMART_FSCK
+	bool "Enable SMART file system check"
+	default n
+	depends on FS_WRITABLE
+	---help---
+		Enables fsck to check and repair the SMART file system.
+
+config MTD_SMART_FSCK_ENABLE_CRC
+	bool "Enable SMART file system CRC check during fsck"
+	default n
+	depends on MTD_SMART_FSCK && MTD_SMART_ENABLE_CRC
+	---help---
+		Enables CRC check during fsck. It's possible to check the file
+		system strictly, but it takes long time to do fsck.
+
 config MTD_SMART_MINIMIZE_RAM
 	bool "Minimize SMART RAM usage using logical sector cache"
 	depends on MTD_SMART
diff --git a/drivers/mtd/smart.c b/drivers/mtd/smart.c
index f9c9b2a..fcf767d 100644
--- a/drivers/mtd/smart.c
+++ b/drivers/mtd/smart.c
@@ -156,6 +156,10 @@
 #define SMART_WEARFLAGS_FORCE_REORG         0x01
 #define SMART_WEARFLAGS_WRITE_NEEDED        0x02
 
+#define SET_BITMAP(m, n) do { (m)[(n) / 8] |= 1 << ((n) % 8); } while (0)
+#define CLR_BITMAP(m, n) do { (m)[(n) / 8] &= ~(1 << ((n) % 8)); } while (0)
+#define ISSET_BITMAP(m, n) ((m)[(n) / 8] & (1 << ((n) % 8)))
+
 #ifdef CONFIG_MTD_SMART_WEAR_LEVEL
 
 /****************************************************************************
@@ -364,6 +368,36 @@ typedef uint32_t crc_t;
 
 #endif
 
+/* Following two definitions copied from internal definition of fs/smartfs.
+ * Because needed to search chain_header and entry_header.
+ */
+
+#if defined(CONFIG_MTD_SMART_ENABLE_CRC) && defined(CONFIG_SMART_CRC_32)
+struct smart_chain_header_s
+{
+  uint8_t           nextsector[4];/* Next logical sector in the chain */
+  uint8_t           used[4];      /* Number of bytes used in this sector */
+  uint8_t           type;         /* Type of sector entry (file or dir) */
+};
+#else
+struct smart_chain_header_s
+{
+  uint8_t           type;         /* Type of sector entry (file or dir) */
+  uint8_t           nextsector[2];/* Next logical sector in the chain */
+  uint8_t           used[2];      /* Number of bytes used in this sector */
+};
+#endif
+
+struct smart_entry_header_s
+{
+  uint16_t          flags;        /* Flags, including permissions:
+                                      15:   Empty entry
+                                      14:   Active entry
+                                      12-0: Permissions bits */
+  int16_t           firstsector;  /* Sector number of the name */
+  uint32_t          utc;          /* Time stamp */
+};
+
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
@@ -402,6 +436,10 @@ static int smart_relocate_static_data(FAR struct smart_struct_s *dev, uint16_t b
 static int smart_relocate_sector(FAR struct smart_struct_s *dev,
                  uint16_t oldsector, uint16_t newsector);
 
+#ifdef CONFIG_MTD_SMART_FSCK
+static int smart_fsck(FAR struct smart_struct_s *dev);
+#endif
+
 #ifdef CONFIG_SMART_DEV_LOOP
 static ssize_t smart_loop_read(FAR struct file *filep, FAR char *buffer,
                  size_t buflen);
@@ -2475,6 +2513,9 @@ static int smart_scan(FAR struct smart_struct_s *dev)
 #endif  /* CONFIG_MTD_SMART_CONVERT_WEAR_FORMAT */
 #endif  /* CONFIG_MTD_SMART_WEAR_LEVEL && SMART_STATUS_VERSION == 1 */
 
+#ifdef CONFIG_MTD_SMART_FSCK
+  smart_fsck(dev);
+#endif
 #ifdef CONFIG_MTD_SMART_WEAR_LEVEL
   /* Read the wear leveling status bits */
 
@@ -5512,6 +5553,471 @@ ok_out:
   return ret;
 }
 
+#ifdef CONFIG_MTD_SMART_FSCK
+
+/****************************************************************************
+ * Name: smart_fsck_crc
+ *
+ * Description: Validate CRC to check smartfs filesystem
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_MTD_SMART_FSCK_ENABLE_CRC
+static int smart_fsck_crc(FAR struct smart_struct_s *dev, uint16_t physsector)
+{
+  int ret;
+
+  ret = MTD_BREAD(dev->mtd, physsector * dev->mtdBlksPerSector,
+                  dev->mtdBlksPerSector, (FAR uint8_t *)dev->rwbuffer);
+  if (ret != dev->mtdBlksPerSector)
+    {
+      ferr("ERROR: Error reading phys sector %d\n", physsector);
+      return ret;
+    }
+
+  ret = smart_validate_crc(dev);
+  if (ret != OK)
+    {
+      ferr("ERROR: Error validating sector %d CRC\n", physsector);
+      return ret;
+    }
+  return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: smart_fsck_file
+ *
+ * Description: fsck for file entry
+ *
+ ****************************************************************************/
+
+static int smart_fsck_file(FAR struct smart_struct_s *dev,
+                           FAR uint8_t *checkmap, uint16_t logsector)
+{
+  int                               ret = OK;
+  ssize_t                           size;
+  uint32_t                          readaddress;
+  FAR struct smart_sect_header_s    *header;
+  FAR struct smart_chain_header_s   *chain;
+  FAR uint8_t                       *usedmap;
+  size_t                            mapsize;
+  uint16_t                          physsector;
+  int                               i;
+
+  if (logsector >= dev->totalsectors)
+    {
+      ret = -EINVAL;
+      return ret;
+    }
+
+  /* Allocate a bitmap table for sectors this file is using */
+
+  mapsize = (dev->totalsectors + 7) / 8;
+  usedmap = (FAR uint8_t *)kmm_zalloc(mapsize);
+  if (!usedmap)
+    {
+      ferr("ERROR: Out of memory used map\n");
+      return OK;
+    }
+
+  do
+    {
+      /* Read the header for file sector */
+
+#ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
+      physsector = dev->sMap[logsector];
+#else
+      physsector = smart_cache_lookup(dev, logsector);
+#endif
+
+      if (physsector >= dev->totalsectors)
+        {
+          ret = -ENXIO;
+          ferr("ERROR: Invalid phys sector %d\n", physsector);
+          break;
+        }
+
+#ifdef CONFIG_MTD_SMART_FSCK_ENABLE_CRC
+      if (smart_fsck_crc(dev, physsector) != OK)
+        {
+          ret = -ENOENT;
+          ferr("ERROR: CRC phys sector %d\n", physsector);
+          break;
+        }
+#endif
+
+      readaddress = physsector * dev->mtdBlksPerSector * dev->geo.blocksize;
+      size = MTD_READ(dev->mtd, readaddress,
+                      sizeof(struct smart_sect_header_s) + sizeof(struct smart_chain_header_s),
+                      (uint8_t *)dev->rwbuffer);
+      if (size != (sizeof(struct smart_sect_header_s) + sizeof(struct smart_chain_header_s)))
+        {
+          ret = -EIO;
+          ferr("Error reading phys sector %d\n", physsector);
+          break;
+        }
+
+      header = (struct smart_sect_header_s *)&dev->rwbuffer[0];
+      chain = (struct smart_chain_header_s *)&dev->rwbuffer[sizeof(struct smart_sect_header_s)];
+
+      /* Test if the sector has live data (not free or not released) */
+
+      if (((header->status & SMART_STATUS_COMMITTED) ==
+           (CONFIG_SMARTFS_ERASEDSTATE & SMART_STATUS_COMMITTED)) ||
+          ((header->status & SMART_STATUS_RELEASED) !=
+           (CONFIG_SMARTFS_ERASEDSTATE & SMART_STATUS_RELEASED)))
+        {
+          ret = -ENOENT;
+          ferr("ERROR: status(%02x) phys sector %d\n", header->status, physsector);
+          break;
+        }
+
+      SET_BITMAP(usedmap, logsector);
+
+      /* next logical sector */
+
+      logsector = *(uint16_t *)chain->nextsector;
+    }
+  while (logsector != 0xffff);
+
+  if (ret == OK)
+    {
+      /* These sectors in use are not removed */
+
+      for (i = 0; i < mapsize; i++)
+        {
+          checkmap[i] &= ~usedmap[i];
+        }
+    }
+  else
+    {
+      /* This file has any corruption, these sectors will be removed */
+
+      for (i = 0; i < mapsize; i++)
+        {
+          checkmap[i] |= usedmap[i];
+        }
+    }
+
+  kmm_free(usedmap);
+  return ret;
+}
+
+/****************************************************************************
+ * Name: smart_fsck_directory
+ *
+ * Description: fsck for directory entry
+ *
+ ****************************************************************************/
+
+static int smart_fsck_directory(FAR struct smart_struct_s *dev,
+                                FAR uint8_t *checkmap, uint16_t logsector)
+{
+  int                               ret = OK;
+  int                               relocate = 0;
+  ssize_t                           size;
+  FAR uint8_t                       *rwbuffer;
+  FAR struct smart_sect_header_s    *header;
+  FAR struct smart_chain_header_s   *chain;
+  FAR struct smart_entry_header_s   *entry;
+  uint16_t                          entrysector;
+  uint16_t                          physsector;
+  uint16_t                          nextsector;
+  uint16_t                          newsector;
+  int                               entrysize;
+  FAR uint8_t                       *bottom;
+  FAR uint8_t                       *cur;
+#ifdef CONFIG_DEBUG_FS_INFO
+  char                              entryname[dev->namesize + 1];
+#endif
+
+  if ((logsector < SMART_FIRST_DIR_SECTOR) || (logsector >= dev->totalsectors))
+    {
+      ret = -EINVAL;
+      ferr("ERROR: Invalid log sector %d\n", logsector);
+      return ret;
+    }
+
+  /* Allocate sector buffer for Directory entry */
+
+  rwbuffer = (uint8_t *)kmm_malloc(dev->sectorsize);
+  if (!rwbuffer)
+    {
+      ferr("ERROR: Out of memory sector buffer\n");
+      return OK;
+    }
+
+  /* Read the Directory entry sector */
+
+#ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
+  physsector = dev->sMap[logsector];
+#else
+  physsector = smart_cache_lookup(dev, logsector);
+#endif
+  if (physsector >= dev->totalsectors)
+    {
+      ret = -ENXIO;
+      ferr("ERROR: Invalid phys sector %d\n", physsector);
+      goto errout;
+    }
+
+  size = MTD_BREAD(dev->mtd, physsector * dev->mtdBlksPerSector,
+                   dev->mtdBlksPerSector, rwbuffer);
+  if (size != dev->mtdBlksPerSector)
+    {
+      ret = -EIO;
+      ferr("ERROR: reading phys sector %d\n", physsector);
+      goto errout;
+    }
+
+  header = (struct smart_sect_header_s *)&rwbuffer[0];
+  chain = (struct smart_chain_header_s *)&rwbuffer[sizeof(struct smart_sect_header_s)];
+  entry = (struct smart_entry_header_s *)&rwbuffer[sizeof(struct smart_sect_header_s) +
+                                                   sizeof(struct smart_chain_header_s)];
+
+#ifdef CONFIG_MTD_SMART_FSCK_ENABLE_CRC
+  /* Check CRC */
+
+  if (smart_fsck_crc(dev, physsector) != OK)
+    {
+      ret = -ENOENT;
+      ferr("ERROR: CRC phys sector %d\n", physsector);
+      goto errout;
+    }
+#endif
+
+  /* Test if the sector has live data (not free or not released) */
+
+  if (((header->status & SMART_STATUS_COMMITTED) ==
+       (CONFIG_SMARTFS_ERASEDSTATE & SMART_STATUS_COMMITTED)) ||
+      ((header->status & SMART_STATUS_RELEASED) !=
+       (CONFIG_SMARTFS_ERASEDSTATE & SMART_STATUS_RELEASED)))
+    {
+      ret = -ENOENT;
+      ferr("ERROR: status(%02x) phys sector %d\n", header->status, physsector);
+      goto errout;
+    }
+
+  /* Check next sector recursively */
+
+  nextsector = *(uint16_t *)chain->nextsector;
+
+  if (nextsector != 0xffff)
+    {
+      finfo("Check next log sector %d\n", nextsector);
+
+      ret = smart_fsck_directory(dev, checkmap, nextsector);
+
+      if (ret != OK)
+        {
+          /* Invalidate the next sector */
+
+          ferr("Invalidate next log sector %d\n", nextsector);
+
+          *(uint16_t *)chain->nextsector = 0xffff;
+        }
+    }
+
+#define SMARTFS_DIRENT_EMPTY      0x8000  /* Set to non-erase state when entry used */
+#define SMARTFS_DIRENT_ACTIVE     0x4000  /* Set to erase state when entry is active */
+#define SMARTFS_DIRENT_TYPE       0x2000  /* Indicates the type of entry (file/dir) */
+#define SMARTFS_DIRENT_DELETING   0x1000  /* Directory entry is being deleted */
+#define SMARTFS_DIRENT_RESERVED   0x0E00  /* Reserved bits */
+
+  /* Check file or directory under this directory entry */
+
+  entrysize = sizeof(struct smart_entry_header_s) + dev->namesize;
+  bottom = rwbuffer + dev->sectorsize;
+  cur = &rwbuffer[sizeof(struct smart_sect_header_s) + sizeof(struct smart_chain_header_s)];
+
+  while ((cur + entrysize) <= bottom)
+    {
+      ret = OK;
+
+      entry = (struct smart_entry_header_s *)cur;
+
+      if (entry->flags == 0xffff)
+        {
+          /* Test if the empty entry is exist or not? */
+
+          break;
+        }
+
+#ifdef CONFIG_DEBUG_FS_INFO
+      strncpy(entryname, (const char *)(cur + sizeof(struct smart_entry_header_s)), dev->namesize);
+      entryname[dev->namesize] = '\0';
+#endif
+      finfo("Check entry (name=%s flags=%02x logsector=%02x)\n",
+            entryname, entry->flags, entry->firstsector);
+
+      if (entry->flags & SMARTFS_DIRENT_ACTIVE)
+        {
+          entrysector = entry->firstsector;
+
+          if (entry->flags & SMARTFS_DIRENT_TYPE)
+            {
+              /* This entry is for directory */
+
+              ret = smart_fsck_directory(dev, checkmap, entrysector);
+            }
+          else
+            {
+              /* This entry is for file */
+
+              ret = smart_fsck_file(dev, checkmap, entrysector);
+            }
+        }
+
+      if (ret != OK)
+        {
+          finfo("Remove entry (name=%s flags=%02x)\n", entryname, entry->flags);
+          if ((cur + (2 * entrysize)) <= bottom)
+            {
+              /* Truncate the current entry and overwrite with next entries */
+
+              memmove(cur, cur + entrysize, bottom - (cur + entrysize));
+              memset(bottom - entrysize, CONFIG_SMARTFS_ERASEDSTATE, entrysize);
+            }
+          else
+            {
+              /* Only erase the current entry if next entry does not exist */
+
+              memset(cur, CONFIG_SMARTFS_ERASEDSTATE, entrysize);
+              cur += entrysize;
+            }
+          relocate = 1;
+        }
+      else
+        {
+          cur += entrysize;
+        }
+    }
+
+  /* Relocate sector */
+
+  if (relocate)
+    {
+      newsector = smart_findfreephyssector(dev, FALSE);
+      if (newsector == 0xffff)
+        {
+          ret = -ENOSPC;
+          ferr("Can't find a free sector for relocation\n");
+          goto errout;
+        }
+      memcpy(dev->rwbuffer, rwbuffer, dev->sectorsize);
+
+      ret = smart_relocate_sector(dev, physsector, newsector);
+      if (ret < 0)
+        {
+          ret = -EIO;
+          ferr("Can't relocate\n");
+          goto errout;
+        }
+
+      /* Update the variables */
+
+#ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
+      dev->sMap[*((FAR uint16_t *)header->logicalsector)] = newsector;
+#else
+      smart_update_cache(dev, *((FAR uint16_t *)header->logicalsector), newsector);
+#endif
+
+#ifdef CONFIG_MTD_SMART_PACK_COUNTS
+      smart_add_count(dev, dev->freecount, newsector / dev->sectorsPerBlk, -1);
+#else
+      dev->freecount[newsector / dev->sectorsPerBlk]--;
+#endif
+    }
+
+  kmm_free(rwbuffer);
+  CLR_BITMAP(checkmap, logsector);
+  return OK;
+
+errout:
+  kmm_free(rwbuffer);
+  SET_BITMAP(checkmap, logsector);
+  return ret;
+}
+
+/****************************************************************************
+ * Name: smart_fsck
+ *
+ * Description: Check and repair the file system
+ *
+ ****************************************************************************/
+
+static int smart_fsck(FAR struct smart_struct_s *dev)
+{
+  uint16_t      logsector;
+#ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
+  uint16_t      physsector;
+#endif
+  FAR uint8_t   *checkmap;
+  size_t        mapsize;
+  uint8_t       rootdirentries;
+  int           x;
+
+  finfo("Entry\n");
+
+  /* Allocate a bitmap table for filesystem check */
+
+  mapsize = (dev->totalsectors + 7) / 8;
+  checkmap = (FAR uint8_t *)kmm_zalloc(mapsize);
+  if (!checkmap)
+    {
+      ferr("ERROR: Out of memory fsck map\n");
+      return -ENOMEM;
+    }
+
+  /* Set all of the sectors have live data into the check bitmap */
+
+#ifndef CONFIG_MTD_SMART_MINIMIZE_RAM
+  for (logsector = 0; logsector < dev->totalsectors; logsector++)
+    {
+      physsector = dev->sMap[logsector];
+      if (physsector < dev->totalsectors)
+        {
+          SET_BITMAP(checkmap, logsector);
+        }
+    }
+#else
+  memcpy(checkmap, dev->sBitMap, mapsize);
+#endif
+
+  /* Check if the sector can be available from root directories */
+
+#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
+  rootdirentries = dev->rootdirentries;
+#else
+  rootdirentries = 1;
+#endif
+
+  for (x = 0; x < rootdirentries; x++)
+    {
+      smart_fsck_directory(dev, checkmap, SMART_FIRST_DIR_SECTOR + x);
+    }
+
+  /* Release the invalid sector except for format or directory entry sector */
+
+  for (logsector = SMART_FIRST_ALLOC_SECTOR;
+       logsector < dev->totalsectors; logsector++)
+    {
+      if (ISSET_BITMAP(checkmap, logsector))
+        {
+          smart_freesector(dev, logsector);
+        }
+    }
+
+  /* Free the bitmap table for filesystem check */
+
+  kmm_free(checkmap);
+
+  return OK;
+}
+
+#endif /* CONFIG_MTD_SMART_FSCK */
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/


[incubator-nuttx] 06/07: drivers: mtd: smart: Fix duplicate sector selection in SmartFS

Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch pr66
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 60927c5fb6a353994341601f55071c618e97682b
Author: Alin Jerpelea <al...@sony.com>
AuthorDate: Thu Dec 28 18:27:21 2017 +0900

    drivers: mtd: smart: Fix duplicate sector selection in SmartFS
    
    Add care for 16-bit sequence without CRC.
---
 drivers/mtd/smart.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/smart.c b/drivers/mtd/smart.c
index e011195..f9c9b2a 100644
--- a/drivers/mtd/smart.c
+++ b/drivers/mtd/smart.c
@@ -1874,6 +1874,7 @@ static int smart_scan(FAR struct smart_struct_s *dev)
   uint32_t  offset;
   uint16_t  seq1;
   uint16_t  seq2;
+  uint16_t  seqwrap;
   struct    smart_sect_header_s header;
 #ifdef CONFIG_MTD_SMART_MINIMIZE_RAM
   int       dupsector;
@@ -2179,7 +2180,8 @@ static int smart_scan(FAR struct smart_struct_s *dev)
            */
 
 #if SMART_STATUS_VERSION == 1
-          if (header.status & SMART_STATUS_CRC)
+          if ((header.status & SMART_STATUS_CRC) !=
+                  (CONFIG_SMARTFS_ERASEDSTATE & SMART_STATUS_CRC))
             {
               seq2 = header.seq;
             }
@@ -2266,21 +2268,25 @@ static int smart_scan(FAR struct smart_struct_s *dev)
             }
 
 #if SMART_STATUS_VERSION == 1
-          if (header.status & SMART_STATUS_CRC)
+          if ((header.status & SMART_STATUS_CRC) !=
+                  (CONFIG_SMARTFS_ERASEDSTATE & SMART_STATUS_CRC))
             {
               seq1 = header.seq;
+              seqwrap = 0xf0;
             }
           else
             {
               seq1 = *((FAR uint16_t *) &header.seq);
+              seqwrap = 0xfff0;
             }
 #else
           seq1 = header.seq;
+          seqwrap = 0xf0;
 #endif
 
           /* Now determine who wins */
 
-          if ((seq1 > 0xfff0 && seq2 < 10) || seq2 > seq1)
+          if ((seq1 > seqwrap && seq2 < 10) || seq2 > seq1)
             {
               /* Seq 2 is the winner ... bigger or it wrapped */
 
@@ -3222,7 +3228,8 @@ static int smart_relocate_sector(FAR struct smart_struct_s *dev,
   /* Increment the sequence number and clear the "commit" flag */
 
 #if SMART_STATUS_VERSION == 1
-  if (header->status & SMART_STATUS_CRC)
+  if ((header->status & SMART_STATUS_CRC) !=
+          (CONFIG_SMARTFS_ERASEDSTATE & SMART_STATUS_CRC))
     {
 #endif
       /* Using 8-bit sequence */
@@ -4571,7 +4578,8 @@ static int smart_writesector(FAR struct smart_struct_s *dev,
       /* Update the sequence number to indicate the sector was moved */
 
 #if SMART_STATUS_VERSION == 1
-      if (header->status & SMART_STATUS_CRC)
+      if ((header->status & SMART_STATUS_CRC) !=
+              (CONFIG_SMARTFS_ERASEDSTATE & SMART_STATUS_CRC))
         {
 #endif
           header->seq++;


[incubator-nuttx] 02/07: drivers: mtd: smart: Fix initialize sector sequence value in smartfs

Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch pr66
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 6ede4b125209f4fd90be7017012894f53fd505ef
Author: Alin Jerpelea <al...@sony.com>
AuthorDate: Thu Jan 11 01:55:49 2018 +0900

    drivers: mtd: smart: Fix initialize sector sequence value in smartfs
    
    Fix initialization of sequence value into sector header and also avoid
    unaligned memory access when CONFIG_MTD_SMART_ENABLE_CRC=n.
---
 drivers/mtd/smart.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/smart.c b/drivers/mtd/smart.c
index 8f59a53..eb5fa1e 100644
--- a/drivers/mtd/smart.c
+++ b/drivers/mtd/smart.c
@@ -4213,7 +4213,7 @@ static int smart_write_alloc_sector(FAR struct smart_struct_s *dev,
 #ifdef CONFIG_MTD_SMART_ENABLE_CRC
   header->seq = 0;
 #else
-  *((FAR uint16_t *) &header->crc8) = 0;
+  *((FAR uint16_t *) &header->seq) = 0;
 #endif  /* CONFIG_MTD_SMART_ENABLE_CRC */
 #else
   header->seq = 0;