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


##########
fs/fat/fs_fat32.c:
##########
@@ -2840,12 +2848,37 @@ static int fat_truncate(FAR struct file *filep, off_t 
length)
     }
   else
     {
+      off_t savepos;
+
       /* Otherwise we are extending the file.  This is essentially the same
        * as a write except that (1) we write zeros and (2) we don't update
        * the file position.
        */
 
+      ret = fat_shared_invalidate(fs, ff->ff_shared);
+      if (ret < 0)
+        {
+          goto errout_with_lock;
+        }
+
+      /* Position the traversal cursor at EOF. The caller's file offset
+       * can be anywhere, and a newly opened handle starts at the first
+       * cluster of the file.
+       */
+
+      savepos      = filep->f_pos;
+      filep->f_pos = oldsize;
+      ret          = fat_get_sectors(filep, false);
+      filep->f_pos = savepos;
+      if (ret < 0)
+        {
+          fat_shared_reset_cursors(fs, ff->ff_shared);
+          goto errout_with_lock;
+        }
+
+      ff->ff_bflags |= FFBUFF_MODIFIED;
       ret = fat_dirextend(fs, ff, length);

Review Comment:
   A failed extension keeps the clusters it allocated. With 1 free cluster, 
ftruncate(fd, size + 10 clusters) returns ENOSPC, the free count stays 0, and 
after a remount the chain has 3 clusters for a size that needs 2. The PR body 
lists recovery after an extension runs out of space.
   
   Fix: when `fat_dirextend()` fails, cut the chain back to `oldsize`.



##########
fs/fat/fs_fat32.c:
##########
@@ -2840,12 +2848,37 @@ static int fat_truncate(FAR struct file *filep, off_t 
length)
     }
   else
     {
+      off_t savepos;
+
       /* Otherwise we are extending the file.  This is essentially the same
        * as a write except that (1) we write zeros and (2) we don't update
        * the file position.
        */
 
+      ret = fat_shared_invalidate(fs, ff->ff_shared);
+      if (ret < 0)
+        {
+          goto errout_with_lock;
+        }
+
+      /* Position the traversal cursor at EOF. The caller's file offset
+       * can be anywhere, and a newly opened handle starts at the first
+       * cluster of the file.
+       */
+
+      savepos      = filep->f_pos;
+      filep->f_pos = oldsize;
+      ret          = fat_get_sectors(filep, false);

Review Comment:
   ftruncate() on a full volume returns EIO when the file is empty or ends at a 
cluster boundary, and ENOSPC when it ends inside a cluster: `fat_get_sectors()` 
turns a 0 from `fat_extendchain()` into -EIO. On a RAM disk with FAT12/16/32: 
errno 5, 5, 28.
   
   Fix: return -ENOSPC from `fat_get_sectors()` when `fat_extendchain()` 
returns 0 (both calls).



-- 
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