bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Another fatfs patch


From: Marco Gerards
Subject: Another fatfs patch
Date: 16 Jul 2003 01:15:49 +0200
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

Hi,

This patch fixes reading in fatfs. There were still some issues,
especially when using big partitions created by MSDOS.
(I found out about this thanks to Barry deFreese. He tested fatfs, the
CVS version and the version with this patch applied).


I removed a check in fat.c because some filesystems created by MSDOS
do not pass this test :). (And the test was completely wrong btw ;)).

I also removed some dead code in pager.c that only produced some
warnings.

I hope all other stuff is obvious (well, it is to me ;)). If it is
not, please ask me! :)

Thanks,
Marco

2003-07-14  Marco Gerards  <metgerards@student.han.nl>

        * fat.c (fat_read_sblock): Don't test if the root dir size is
          a multiple of sectors_per_cluster. Reported by Barry
          deFreese (bddebian@cox.net).
        * fatfs.h (LOG2_BLOCKS_PER_CLUSTER): New macro.
        (FAT_FIRST_CLUSTER_BLOCK): Likewise.
        (fat_first_cluster_byte): Macro removed.
        * inode.c (read_node): Correctly setup diskfs_root_node for FAT32
          filesystems.
        * pager.c (fat_getcluster): Check for reading beyond allocsize
          correctly for file systems with a clustersize > vm_page_size.
        
        (file_pager_read_small_page): Don't use byte offsets when
        calculating the block.
        (file_pager_read_huge_page): Likewise.
        (pending_clusters_write): Likewise.
        (file_pager_write_small_page): Likewise.
        
        (STAT_INC): Macro removed.
        (file_pager_read_huge_page): Don't call STAT_INC anymore.
        (file_pager_write_huge_pager): Likewise.
        (diskfs_grow): Likewise.

Common subdirectories: /home/marco/src/hurdcvs/hurd/fatfs/CVS and fatfs/CVS
diff -up /home/marco/src/hurdcvs/hurd/fatfs/fat.c fatfs/fat.c
--- /home/marco/src/hurdcvs/hurd/fatfs/fat.c    2002-12-03 21:52:59.000000000 
+0100
+++ fatfs/fat.c 2003-07-16 00:11:14.000000000 +0200
@@ -1,5 +1,5 @@
 /* fat.c - Support for FAT filesystems.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002,03 Free Software Foundation, Inc.
    Written by Marcus Brinkmann.
 
    This file is part of the GNU Hurd.
@@ -151,8 +151,8 @@ fat_read_sblock (void)
     error (1, 0, "Number of total sectors is zero");
 
   if (bytes_per_sector & (store->block_size - 1))
-    error (1, 0, "Block size of filesystem is not a multiple of the block size 
"
-          "of the store");
+    error (1, 0, "Block size of filesystem is not"
+          " a multiple of the block size of the store");
 
   if (read_word (sblock->reserved_sectors) == 0)
     error (1, 0, "Number of reserved sectors is zero");
@@ -164,14 +164,13 @@ fat_read_sblock (void)
   if (sectors_per_fat == 0)
     error (1, 0, "Number of sectors per fat is zero");
 
-  nr_of_root_dir_sectors = ((read_word (sblock->nr_of_root_dirents) * 
FAT_DIR_REC_LEN)
-                     - 1) / bytes_per_sector + 1;
-  if (nr_of_root_dir_sectors & (sectors_per_cluster - 1))
-    error (1, 0, "Number of root dir sectors is not a multiple of 
sectors_per_cluster");
+  nr_of_root_dir_sectors = ((read_word (sblock->nr_of_root_dirents) *
+                            FAT_DIR_REC_LEN) - 1) / bytes_per_sector + 1;
 
   first_root_dir_byte = (read_word (sblock->reserved_sectors)
     + (sblock->nr_of_fat_tables * sectors_per_fat)) << log2_bytes_per_sector;
-  first_data_sector = (first_root_dir_byte >> log2_bytes_per_sector) + 
nr_of_root_dir_sectors;
+  first_data_sector = (first_root_dir_byte >> log2_bytes_per_sector) 
+    + nr_of_root_dir_sectors;
   first_data_byte = first_data_sector << log2_bytes_per_sector;
 
   nr_of_clusters = (total_sectors - first_data_sector) / sectors_per_cluster;
diff -up /home/marco/src/hurdcvs/hurd/fatfs/fatfs.h fatfs/fatfs.h
--- /home/marco/src/hurdcvs/hurd/fatfs/fatfs.h  2002-12-03 21:52:59.000000000 
+0100
+++ fatfs/fatfs.h       2003-07-16 00:25:19.000000000 +0200
@@ -1,5 +1,5 @@
 /* fatfs.h - Interface for fatfs.
-   Copyright (C) 1997, 1999, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1999, 2002, 2003 Free Software Foundation, Inc.
    Written by Thomas Bushnell, n/BSG and Marcus Brinkmann.
 
    This file is part of the GNU Hurd.
@@ -95,12 +95,16 @@ extern vm_address_t zerocluster;
 extern struct dirrect dr_root_node;
 
 
+#define LOG2_BLOCKS_PER_CLUSTER                                \
+ (log2_bytes_per_cluster - store->log2_block_size)
+
 #define round_cluster(offs)                                    \
   ((((offs) + bytes_per_cluster - 1)                           \
     >> log2_bytes_per_cluster) << log2_bytes_per_cluster)
 
-#define fat_first_cluster_byte(cluster) \
- (first_data_byte + ((cluster - 2) << log2_bytes_per_cluster))
+#define FAT_FIRST_CLUSTER_BLOCK(cluster)       \
+  (((cluster - 2) << LOG2_BLOCKS_PER_CLUSTER) +        \
+   (first_data_byte >> store->log2_block_size))
 
 void drop_pager_softrefs (struct node *);
 void allow_pager_softrefs (struct node *);
diff -up /home/marco/src/hurdcvs/hurd/fatfs/inode.c fatfs/inode.c
--- /home/marco/src/hurdcvs/hurd/fatfs/inode.c  2003-07-08 00:11:35.000000000 
+0200
+++ fatfs/inode.c       2003-07-16 00:09:48.000000000 +0200
@@ -329,8 +329,8 @@ read_node (struct node *np, vm_address_t
       st->st_mode = S_IFDIR | 0777;
       /* When we read in the node the first time, diskfs_root_node is
         zero.  */
-      if (diskfs_root_node == 0 ||
-         (np == diskfs_root_node && (fat_type == FAT12 || fat_type == FAT16)))
+      if ((diskfs_root_node == 0 || np == diskfs_root_node) &&
+         (fat_type == FAT12 || fat_type == FAT16))
        {
          st->st_size = read_dword (dr->file_size);
          np->allocsize = nr_of_root_dir_sectors << log2_bytes_per_sector;
diff -up /home/marco/src/hurdcvs/hurd/fatfs/pager.c fatfs/pager.c
--- /home/marco/src/hurdcvs/hurd/fatfs/pager.c  2002-12-03 21:52:59.000000000 
+0100
+++ fatfs/pager.c       2003-07-16 00:26:40.000000000 +0200
@@ -1,5 +1,5 @@
 /* pager.c - Pager for fatfs.
-   Copyright (C) 1997, 1999, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1999, 2002, 2003 Free Software Foundation, Inc.
    Written by Thomas Bushnell, n/BSG and Marcus Brinkmann.
 
    This file is part of the GNU Hurd.
@@ -36,8 +36,6 @@ spin_lock_t node_to_page_lock = SPIN_LOC
 #define MAY_CACHE 1
 #endif
 
-#define STAT_INC(field) /* nop */0
-
 #define MAX_FREE_PAGE_BUFS 32
 
 static spin_lock_t free_page_bufs_lock = SPIN_LOCK_INITIALIZER;
@@ -106,7 +104,8 @@ find_cluster (struct node *node, vm_offs
       rwlock_reader_lock (*lock);
     }
 
-  if (offset + bytes_per_cluster > node->allocsize)
+  if ((offset + vm_page_size > node->allocsize) &&
+      (offset + bytes_per_cluster > node->allocsize))
     return EIO;
 
   err = fat_getcluster (node, offset >> log2_bytes_per_cluster, 0, cluster);
@@ -178,9 +177,10 @@ file_pager_read_small_page (struct node 
   if (!err)
     {
       err = store_read (store,
-                       (fat_first_cluster_byte(cluster) +
-                        (page % bytes_per_cluster)) >> store->log2_block_size,
+                       FAT_FIRST_CLUSTER_BLOCK (cluster) +
+                       ((page % bytes_per_cluster) >> store->log2_block_size),
                        vm_page_size, (void **) buf, &read);
+
       if (read != vm_page_size)
        err = EIO;
     }
@@ -215,7 +215,7 @@ file_pager_read_huge_page (struct node *
     {
       if (num_pending_clusters > 0)
         {
-          size_t dev_block = fat_first_cluster_byte(pending_clusters) >> 
store->log2_block_size;
+         size_t dev_block = FAT_FIRST_CLUSTER_BLOCK (pending_clusters);
           size_t amount = num_pending_clusters << log2_bytes_per_cluster;
          /* The buffer we try to read into; on the first read, we pass in a
             size of zero, so that the read is guaranteed to allocate a new
@@ -224,8 +224,6 @@ file_pager_read_huge_page (struct node *
          void *new_buf = *buf + offs;
          size_t new_len = offs == 0 ? 0 : vm_page_size - offs;
 
-          STAT_INC (file_pagein_reads);
-         
          err = store_read (store, dev_block, amount, &new_buf, &new_len);
          if (err)
            return err;
@@ -244,7 +242,6 @@ file_pager_read_huge_page (struct node *
                {
                  memcpy (*buf + offs, new_buf, new_len);
                   free_page_buf (new_buf); /* Return NEW_BUF to our pool.  */
-                  STAT_INC (file_pagein_freed_bufs);
                }
            }
          
@@ -255,8 +252,6 @@ file_pager_read_huge_page (struct node *
       return 0;
     }
 
-  STAT_INC (file_pageins);
- 
   *writelock = 0;
 
   if (page >= node->allocsize)
@@ -317,7 +312,8 @@ pending_clusters_write (struct pending_c
   if (pc->num > 0)
     {
       error_t err;
-      size_t dev_block = fat_first_cluster_byte(pc->cluster) >> 
store->log2_block_size;
+      size_t dev_block = FAT_FIRST_CLUSTER_BLOCK (pc->cluster);
+
       size_t length = pc->num << log2_bytes_per_cluster, amount;
 
       if (pc->offs > 0)
@@ -393,8 +389,6 @@ file_pager_write_huge_page (struct node 
   else if (offset + left > node->allocsize)
     left = node->allocsize - offset;
 
-  STAT_INC (file_pageouts);
-
   while (left > 0)
     {
       err = find_cluster (node, offset, &cluster, &lock);
@@ -477,10 +471,10 @@ file_pager_write_small_page (struct node
 
   if (!err)
     {
-      err = store_write (store,
-                        (fat_first_cluster_byte(cluster) +
-                         (offset % bytes_per_cluster)) >> 
store->log2_block_size,
-                         (void **) buf, vm_page_size, &write);
+      err = store_write (store, FAT_FIRST_CLUSTER_BLOCK (cluster) +
+                        ((offset % bytes_per_cluster) >>
+                         store->log2_block_size),
+                        (void **) buf, vm_page_size, &write);
       if (write != vm_page_size)
        err = EIO;
     }
@@ -640,8 +634,6 @@ diskfs_grow (struct node *node, loff_t s
            new_size = (end_cluster - 1) >> log2_bytes_per_cluster;
        }
       
-      STAT_INC (file_grows);
-
       node->allocsize = new_size;
 
       rwlock_writer_unlock (&dn->alloc_lock);





reply via email to

[Prev in Thread] Current Thread [Next in Thread]