grub-devel
[Top][All Lists]
Advanced

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

Re: [PATCH] FAT, UFS and mtime


From: phcoder
Subject: Re: [PATCH] FAT, UFS and mtime
Date: Sun, 15 Mar 2009 12:16:46 +0100
User-agent: Thunderbird 2.0.0.19 (X11/20090105)

UFS part (not related to mtime)
2009-03-15  Vladimir Serbinenko  <address@hidden>

        UFS improvements

        * fs/ufs.c (GRUB_UFS_BSD_DIRENT): new definition
        (struct grub_ufs_dirent): added fields for non-BSD dirents
        (grub_ufs_get_file_block): fixed double indirect handling
        (grub_ufs_find_file): support for non-BSD dirents
        (grub_ufs_dir): support for non-BSD dirents


Robert Millan wrote:
On Sun, Mar 01, 2009 at 05:25:10PM +0100, phcoder wrote:
Hello all. It seems that gcc has trouble with -m32 when structure is passed as argument. So I replaced that part by a pointer. Also I made some improvements to ufs code to support solaris branch of ufs. I tested it also with freebsd and netbsd's branch and it works fine on it too. As my 3 FS patches: mtime, FAT and UFS are interdependent I submit a patch with all 3 features. If it's really necessary I can split them but it requires a lot of unnecessary work

Please do.  It is definitely confusing to review patches that merge
unrelated things.

Also, please don't include the changelog entry in your patch, since those
break too easily.  Just paste it at the top of your mail.



--

Regards
Vladimir 'phcoder' Serbinenko
diff --git a/fs/ufs.c b/fs/ufs.c
index e6eacd3..9a3cd69 100644
--- a/fs/ufs.c
+++ b/fs/ufs.c
@@ -54,6 +54,8 @@
                            grub_le_to_cpu##bits1 (data->inode.field) : \
                            grub_le_to_cpu##bits2 (data->inode2.field))
 #define INODE_SIZE(data) INODE_ENDIAN (data,size,32,64)
+#define INODE_NBLOCKS(data) INODE_ENDIAN (data,nblocks,32,64)
+
 #define INODE_MODE(data) INODE_ENDIAN (data,mode,16,16)
 #define INODE_BLKSZ(data) (data->ufs_type == UFS1 ? 4 : 8)
 #define INODE_DIRBLOCKS(data,blk) INODE_ENDIAN \
@@ -174,8 +176,15 @@ struct grub_ufs_dirent
 {
   grub_uint32_t ino;
   grub_uint16_t direntlen;
-  grub_uint8_t filetype;
-  grub_uint8_t namelen;
+  union
+  {
+    grub_uint16_t namelen;
+    struct
+    {
+      grub_uint8_t filetype_bsd;
+      grub_uint8_t namelen_bsd;      
+    };
+  };
 } __attribute__ ((packed));
 
 /* Information about a "mounted" ufs filesystem.  */
@@ -234,22 +243,23 @@ grub_ufs_get_file_block (struct grub_ufs_data *data, 
unsigned int blk)
   blk -= indirsz;
   
   /* Double indirect block.  */
-  if (blk < UFS_BLKSZ (sblock) / indirsz)
+  if (blk < indirsz * indirsz)
     {
       grub_uint32_t indir[UFS_BLKSZ (sblock) >> 2];
       
       grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 1) << log2_blksz,
                      0, sizeof (indir), (char *) indir);
       grub_disk_read (data->disk,
-                     (data->ufs_type == UFS1) ?
-                     indir[blk / indirsz] : indir [(blk / indirsz) << 1],
+                     ((data->ufs_type == UFS1) ?
+                     indir[blk / indirsz] : indir [(blk / indirsz) << 1]) 
+                     << log2_blksz,
                      0, sizeof (indir), (char *) indir);
       
       return (data->ufs_type == UFS1) ?
             indir[blk % indirsz] : indir[(blk % indirsz) << 1];
     }
 
-
+  
   grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
              "ufs does not support triple indirect blocks");
   return 0;
@@ -386,9 +396,8 @@ grub_ufs_lookup_symlink (struct grub_ufs_data *data, int 
ino)
   
   if (++data->linknest > GRUB_UFS_MAX_SYMLNK_CNT)
     return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
-  
-  if (INODE_SIZE (data) < (GRUB_UFS_DIRBLKS + GRUB_UFS_INDIRBLKS
-                         * INODE_BLKSZ (data)))
+
+  if (INODE_NBLOCKS (data) == 0)
     grub_strcpy (symlink, (char *) INODE (data, symlink));
   else
     {
@@ -447,6 +456,7 @@ grub_ufs_find_file (struct grub_ufs_data *data, const char 
*path)
   do
     {
       struct grub_ufs_dirent dirent;
+      int namelen;
       
       if (grub_strlen (name) == 0)
        return GRUB_ERR_NONE;
@@ -454,15 +464,18 @@ grub_ufs_find_file (struct grub_ufs_data *data, const 
char *path)
       if (grub_ufs_read_file (data, 0, pos, sizeof (dirent),
                              (char *) &dirent) < 0)
        return grub_errno;
+
+      namelen = (data->ufs_type == UFS2)
+       ? dirent.namelen_bsd : grub_le_to_cpu16 (dirent.namelen);
       
       {
-       char filename[dirent.namelen + 1];
+       char filename[namelen + 1];
 
        if (grub_ufs_read_file (data, 0, pos + sizeof (dirent),
-                               dirent.namelen, filename) < 0)
+                               namelen, filename) < 0)
          return grub_errno;
        
-       filename[dirent.namelen] = '\0';
+       filename[namelen] = '\0';
        
        if (!grub_strcmp (name, filename))
          {
@@ -595,21 +608,25 @@ grub_ufs_dir (grub_device_t device, const char *path,
   while (pos < INODE_SIZE (data))
     {
       struct grub_ufs_dirent dirent;
+      int namelen;
       
       if (grub_ufs_read_file (data, 0, pos, sizeof (dirent),
                              (char *) &dirent) < 0)
        break;
+
+      namelen = (data->ufs_type == UFS2)
+       ? dirent.namelen_bsd : grub_le_to_cpu16 (dirent.namelen);
       
       {
-       char filename[dirent.namelen + 1];
+       char filename[namelen + 1];
        struct grub_dirhook_info info;
        grub_memset (&info, 0, sizeof (info));
        
        if (grub_ufs_read_file (data, 0, pos + sizeof (dirent),
-                               dirent.namelen, filename) < 0)
+                               namelen, filename) < 0)
          break;
        
-       filename[dirent.namelen] = '\0';
+       filename[namelen] = '\0';
        if (data->ufs_type == UFS1)
          {
            struct grub_ufs_inode inode;

reply via email to

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