casaroli commented on code in PR #19536:
URL: https://github.com/apache/nuttx/pull/19536#discussion_r3673217707


##########
fs/xipfs/xipfs_flash.c:
##########
@@ -0,0 +1,456 @@
+/****************************************************************************
+ * fs/xipfs/xipfs_flash.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ *
+ * Every media access in xipfs funnels through this file.  That is
+ * deliberate: on a single NOR die without read-while-write, an erase stalls
+ * all fetches from the die, so erase slicing, running the erase routine
+ * from RAM and erase-suspend/resume all have to be introduced here once the
+ * actual NOR part is known.  Keeping the chokepoint from the start means
+ * adding them later is a local change rather than a refactor.
+ *
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <nuttx/fs/ioctl.h>
+#include <nuttx/kmalloc.h>
+
+#include "xipfs.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: xipfs_flash_fault
+ *
+ * Description:
+ *   Test hook modelling a power loss at an arbitrary flash operation.  When
+ *   the countdown reaches zero the operation fails and the medium latches
+ *   dead for the remainder of the run, which is what a real power cut looks
+ *   like to the code above: no further write or erase ever completes.
+ *
+ *   A real cut tears exactly the one operation that was in flight at the
+ *   instant power dropped; everything nominally after it simply never runs.
+ *   So only the first failing operation reports XIPFS_OP_FAIL_TORN, and only
+ *   when the caller armed torn mode -- every operation past the dead latch
+ *   fails clean, having never touched the medium.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_FS_XIPFS_FAULT_INJECT
+enum xipfs_fault_e
+{
+  XIPFS_OP_PROCEED = 0,   /* Not the injected point; run the operation      */
+  XIPFS_OP_FAIL_CLEAN,    /* Fail with the medium left untouched            */
+  XIPFS_OP_FAIL_TORN      /* Fail after half of the operation has landed    */
+};
+
+static enum xipfs_fault_e xipfs_flash_fault(FAR struct xipfs_mount_s *fs)
+{
+  if (fs->media_dead)
+    {
+      return XIPFS_OP_FAIL_CLEAN;
+    }
+
+  if (fs->fault_countdown < 0)
+    {
+      return XIPFS_OP_PROCEED;
+    }
+
+  if (fs->fault_countdown == 0)
+    {
+      finfo("xipfs: injected %s media failure\n",
+            fs->fault_mode == XIPFS_FAULT_TORN ? "torn" : "clean");
+      fs->media_dead = true;
+      return fs->fault_mode == XIPFS_FAULT_TORN ?
+             XIPFS_OP_FAIL_TORN : XIPFS_OP_FAIL_CLEAN;
+    }
+
+  fs->fault_countdown--;
+  return XIPFS_OP_PROCEED;
+}
+
+/****************************************************************************
+ * Name: xipfs_flash_tear_write
+ *
+ * Description:
+ *   Model a NOR page program cut short by power loss: the first half of the
+ *   page reaches the medium and the rest is left at the erased value, so a
+ *   reader sees a page that is neither its old contents nor the intended new
+ *   ones -- which is what makes a torn metadata generation fail its CRC
+ *   rather than look valid.  Every xipfs write is a single read/write block,
+ *   so the tear is expressed by reprogramming that block with its tail
+ *   replaced by the erased value; a transient allocation failure simply
+ *   leaves the operation a clean one, still a legitimate power-loss outcome.
+ *
+ ****************************************************************************/
+
+static void xipfs_flash_tear_write(FAR struct xipfs_mount_s *fs,
+                                   uint32_t block, uint32_t offset,
+                                   FAR const void *buffer, size_t nbytes)
+{
+  off_t        byteoff = (off_t)block * fs->geo.erasesize + offset;
+  size_t       half    = nbytes / 2;
+  FAR uint8_t *torn;
+
+  torn = kmm_malloc(nbytes);
+  if (torn == NULL)
+    {
+      return;
+    }
+
+  memcpy(torn, buffer, half);
+  memset(torn + half, 0xff, nbytes - half);

Review Comment:
   this is simulating a nor, so i think we should keep 0xff.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to