All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] MINIX file system version 3 support
@ 2010-07-28  3:25 Fam Zheng
  2010-09-08 15:26 ` Vladimir 'φ-coder/phcoder' Serbinenko
  2011-04-10 18:39 ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 2 replies; 11+ messages in thread
From: Fam Zheng @ 2010-07-28  3:25 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: Erik van der Kouwe


[-- Attachment #1.1: Type: text/plain, Size: 288 bytes --]

Hi,

To support MINIX file system version 3, this patch adds a new module named
'minix3'. It reuses most of the code in minix.mod, and handles the latest
MINIX file system version 3.

The requested assignment information has also been sent to assign@gnu.org.

-- 
Best Regards!
Fam Zheng

[-- Attachment #1.2: Type: text/html, Size: 406 bytes --]

[-- Attachment #2: grub_minix_fs.patch --]
[-- Type: application/octet-stream, Size: 15263 bytes --]

=== modified file 'conf/common.rmk'
--- conf/common.rmk	2010-07-06 18:27:55 +0000
+++ conf/common.rmk	2010-07-28 00:59:27 +0000
@@ -32,7 +32,7 @@
 	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c		\
 	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c	\
 	fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c	\
-	fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c		\
+	fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/minix3.c\
 	fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c		\
 	\
 	partmap/msdos.c partmap/bsdlabel.c partmap/apple.c \
@@ -55,7 +55,7 @@
 	lib/hexdump.c lib/crc.c commands/blocklist.c commands/ls.c 	\
 	\
 	fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c			\
-	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c fs/minix3.c\
 	fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c	\
 	fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c fs/befs.c 	\
 	fs/befs_be.c fs/tar.c			\
@@ -234,7 +234,7 @@
 pkglib_MODULES += fshelp.mod fat.mod ufs1.mod ufs2.mod ext2.mod ntfs.mod \
 	ntfscomp.mod minix.mod hfs.mod jfs.mod iso9660.mod xfs.mod	\
 	affs.mod sfs.mod hfsplus.mod reiserfs.mod cpio.mod tar.mod	\
-	udf.mod	afs.mod afs_be.mod befs.mod befs_be.mod
+	udf.mod	afs.mod afs_be.mod befs.mod befs_be.mod minix3.mod
 
 # For fshelp.mod.
 fshelp_mod_SOURCES = fs/fshelp.c
@@ -276,6 +276,11 @@
 minix_mod_CFLAGS = $(COMMON_CFLAGS)
 minix_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For minix3.mod.
+minix3_mod_SOURCES = fs/minix3.c
+minix3_mod_CFLAGS = $(COMMON_CFLAGS)
+minix3_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For nilfs2.mod.
 pkglib_MODULES += nilfs2.mod
 nilfs2_mod_SOURCES = fs/nilfs2.c

=== modified file 'conf/i386-pc.rmk'
--- conf/i386-pc.rmk	2010-07-06 18:27:55 +0000
+++ conf/i386-pc.rmk	2010-07-28 00:59:27 +0000
@@ -70,7 +70,7 @@
 	kern/emu/mm.c kern/fs.c kern/env.c kern/list.c fs/fshelp.c	\
 									\
 	fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c			\
-	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c fs/minix3.c\
 	fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c		\
 	fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c			\
 	fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c			\

=== modified file 'conf/sparc64-ieee1275.rmk'
--- conf/sparc64-ieee1275.rmk	2010-07-06 18:27:55 +0000
+++ conf/sparc64-ieee1275.rmk	2010-07-28 00:59:27 +0000
@@ -54,7 +54,7 @@
 	fs/fshelp.c							\
 									\
 	fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c			\
-	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c		\
+	fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c fs/minix3.c\
 	fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c		\
 	fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c			\
 	fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c			\

=== modified file 'fs/minix.c'
--- fs/minix.c	2009-12-25 00:04:51 +0000
+++ fs/minix.c	2010-07-28 01:38:07 +0000
@@ -20,6 +20,7 @@
 #include <grub/err.h>
 #include <grub/file.h>
 #include <grub/mm.h>
+#include <grub/partition.h>
 #include <grub/misc.h>
 #include <grub/disk.h>
 #include <grub/dl.h>
@@ -27,9 +28,9 @@
 
 #define GRUB_MINIX_MAGIC	0x137F
 #define GRUB_MINIX2_MAGIC	0x2468
+#define GRUB_MINIX3_MAGIC	0x4D5A
 #define GRUB_MINIX_MAGIC_30	0x138F
 #define GRUB_MINIX2_MAGIC_30	0x2478
-#define GRUB_MINIX_BSIZE	1024U
 #define GRUB_MINIX_LOG2_BSIZE	1
 #define GRUB_MINIX_ROOT_INODE	1
 #define GRUB_MINIX_MAX_SYMLNK_CNT	8
@@ -38,11 +39,22 @@
 #define GRUB_MINIX_IFDIR	0040000U
 #define GRUB_MINIX_IFLNK	0120000U
 
+#ifdef GRUB_MOD_MINIX3
+#define GRUB_MINIX_INODE(data,field) (data->inode3.field)
+#else
 #define GRUB_MINIX_INODE(data,field) (data->version == 1 ? \
                            data->inode.  field : data->inode2.  field)
+#endif
+
+#ifdef GRUB_MOD_MINIX3
+#define GRUB_MINIX_INODE_ENDIAN(data,field,bits1,bits2) \
+                           (grub_le_to_cpu##bits2 (data->inode3.field))
+#else
 #define GRUB_MINIX_INODE_ENDIAN(data,field,bits1,bits2) (data->version == 1 ?	\
                         grub_le_to_cpu##bits1 (data->inode.field) :		\
                         grub_le_to_cpu##bits2 (data->inode2.field))
+#endif
+
 #define GRUB_MINIX_INODE_SIZE(data) GRUB_MINIX_INODE_ENDIAN (data,size,16,32)
 #define GRUB_MINIX_INODE_MODE(data) GRUB_MINIX_INODE_ENDIAN (data,mode,16,16)
 #define GRUB_MINIX_INODE_DIR_ZONES(data,blk) GRUB_MINIX_INODE_ENDIAN		\
@@ -54,19 +66,41 @@
 #define GRUB_MINIX_INODE_BLKSZ(data) (data->version == 1 ? 2 : 4)
 #define GRUB_MINIX_LOG2_ZONESZ	(GRUB_MINIX_LOG2_BSIZE				\
 				 + grub_le_to_cpu16 (sblock->log2_zone_size))
-#define GRUB_MINIX_ZONESZ	(GRUB_MINIX_BSIZE 				\
+#define GRUB_MINIX_ZONESZ	(blocksize 				\
 				 << grub_le_to_cpu16 (sblock->log2_zone_size))
 
 struct grub_minix_sblock
 {
+#ifdef GRUB_MOD_MINIX3
+  grub_uint32_t inode_cnt;
+#else
   grub_uint16_t inode_cnt;
+#endif
+
   grub_uint16_t zone_cnt;
   grub_uint16_t inode_bmap_size;
   grub_uint16_t zone_bmap_size;
   grub_uint16_t first_data_zone;
   grub_uint16_t log2_zone_size;
+  
+#ifdef GRUB_MOD_MINIX3
+  grub_uint16_t pad;
+#endif
+
   grub_uint32_t max_file_size;
+
+#ifdef GRUB_MOD_MINIX3
+  grub_uint32_t zones;
+#endif
+
   grub_uint16_t magic;
+
+#ifdef GRUB_MOD_MINIX3
+  /* V3 only fields */
+  grub_uint16_t pad2;
+  grub_uint16_t block_size;
+  grub_uint8_t disk_version; 
+#endif
 };
 
 struct grub_minix_inode
@@ -99,12 +133,36 @@
 
 };
 
+#ifdef GRUB_MOD_MINIX3
+struct grub_minix3_inode
+{
+  grub_uint16_t mode;
+  grub_uint16_t nlinks;
+  grub_uint16_t uid;
+  grub_uint8_t gid;
+  grub_uint8_t pad_;
+  grub_uint32_t size;
+  grub_uint32_t atime;
+  grub_uint32_t mtime;
+  grub_uint32_t ctime;
+  grub_uint32_t dir_zones[7];
+  grub_uint32_t indir_zone;
+  grub_uint32_t double_indir_zone;
+  grub_uint32_t unused;
+
+};
+#endif
+
+
 /* Information about a "mounted" minix filesystem.  */
 struct grub_minix_data
 {
   struct grub_minix_sblock sblock;
   struct grub_minix_inode inode;
   struct grub_minix2_inode inode2;
+#ifdef GRUB_MOD_MINIX3
+  struct grub_minix3_inode inode3;
+#endif
   int ino;
   int linknest;
   grub_disk_t disk;
@@ -113,21 +171,38 @@
 };
 
 static grub_dl_t my_mod;
-\f
+static unsigned int blocksize;
+
+
 static grub_err_t grub_minix_find_file (struct grub_minix_data *data,
 					const char *path);
 
 static int
 grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
 {
+#ifndef GRUB_MOD_MINIX3
   struct grub_minix_sblock *sblock = &data->sblock;
+#endif
   int indir;
-
   auto int grub_get_indir (int, int);
 
+#ifdef GRUB_MOD_MINIX3
+  unsigned int first_dbl_indir;
+  unsigned int indir_capacity;
+  indir_capacity=blocksize/4;
+#endif
+
   /* Read the block pointer in ZONE, on the offset NUM.  */
   int grub_get_indir (int zone, int num)
     {
+#ifdef GRUB_MOD_MINIX3
+      grub_uint32_t indir32;
+	grub_disk_read (data->disk,
+			zone * (blocksize / GRUB_DISK_SECTOR_SIZE),
+			sizeof (grub_uint32_t) * num,
+			sizeof (grub_uint32_t), (char *) &indir32);
+	return grub_le_to_cpu32 (indir32);
+#else
       if (data->version == 1)
 	{
 	  grub_uint16_t indir16;
@@ -146,6 +221,7 @@
 			  sizeof (grub_uint32_t), (char *) &indir32);
 	  return grub_le_to_cpu32 (indir32);
 	}
+#endif
     }
 
   /* Direct block.  */
@@ -153,25 +229,46 @@
     return GRUB_MINIX_INODE_DIR_ZONES (data, blk);
 
   /* Indirect block.  */
+#ifdef GRUB_MOD_MINIX3
+  first_dbl_indir=indir_capacity+7;
+  if (blk < first_dbl_indir)
+    {
+      blk -= 7;
+      indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk);
+      return indir;
+    }
+#else
   blk -= 7;
   if (blk < GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
     {
       indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk);
       return indir;
     }
+#endif
 
   /* Double indirect block.  */
+#ifdef GRUB_MOD_MINIX3
+  blk -= first_dbl_indir;
+  if (blk < indir_capacity * indir_capacity)
+    {
+		
+      indir = grub_get_indir (GRUB_MINIX_INODE_DINDIR_ZONE (data),
+			      blk / indir_capacity);
+      indir = grub_get_indir (indir, blk % indir_capacity);
+
+      return indir;
+    }
+#else
   blk -= GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data);
   if (blk < (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
       * (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data)))
     {
       indir = grub_get_indir (GRUB_MINIX_INODE_DINDIR_ZONE (data),
 			      blk / GRUB_MINIX_ZONESZ);
-
       indir = grub_get_indir (indir, blk % GRUB_MINIX_ZONESZ);
-
       return indir;
     }
+#endif
 
   /* This should never happen.  */
   grub_error (GRUB_ERR_OUT_OF_RANGE, "file bigger than maximum size");
@@ -188,22 +285,24 @@
 					 unsigned offset, unsigned length),
 		      int pos, grub_disk_addr_t len, char *buf)
 {
+#ifndef GRUB_MOD_MINIX3
   struct grub_minix_sblock *sblock = &data->sblock;
+#endif
   int i;
   int blockcnt;
 
   /* Adjust len so it we can't read past the end of the file.  */
   if (len + pos > GRUB_MINIX_INODE_SIZE (data))
     len = GRUB_MINIX_INODE_SIZE (data) - pos;
-
-  blockcnt = (len + pos + GRUB_MINIX_BSIZE - 1) / GRUB_MINIX_BSIZE;
-
-  for (i = pos / GRUB_MINIX_BSIZE; i < blockcnt; i++)
+    
+  blockcnt = (len + pos + blocksize - 1);
+  blockcnt /= blocksize;
+
+  for (i = pos / blocksize; i < blockcnt; i++)
     {
       int blknr;
-      int blockoff = pos % GRUB_MINIX_BSIZE;
-      int blockend = GRUB_MINIX_BSIZE;
-
+      int blockoff = pos % blocksize;
+      int blockend = blocksize;
       int skipfirst = 0;
 
       blknr = grub_minix_get_file_block (data, i);
@@ -213,28 +312,33 @@
       /* Last block.  */
       if (i == blockcnt - 1)
 	{
-	  blockend = (len + pos) % GRUB_MINIX_BSIZE;
-
+	  blockend = (len + pos);
+	  blockend %= blocksize;
 	  if (!blockend)
-	    blockend = GRUB_MINIX_BSIZE;
+	    blockend = blocksize;
 	}
 
       /* First block.  */
-      if (i == (pos / (int) GRUB_MINIX_BSIZE))
+      if (i == (pos / (int) blocksize))
 	{
 	  skipfirst = blockoff;
 	  blockend -= skipfirst;
 	}
 
       data->disk->read_hook = read_hook;
+#ifdef GRUB_MOD_MINIX3
+      grub_disk_read (data->disk, 
+		      blknr * (data->sblock.block_size/GRUB_DISK_SECTOR_SIZE),
+		      skipfirst, blockend, buf);
+#else
       grub_disk_read (data->disk, blknr << GRUB_MINIX_LOG2_ZONESZ,
 		      skipfirst, blockend, buf);
-
+#endif
       data->disk->read_hook = 0;
       if (grub_errno)
 	return -1;
 
-      buf += GRUB_MINIX_BSIZE - skipfirst;
+      buf += blocksize - skipfirst;
     }
 
   return len;
@@ -250,6 +354,7 @@
 
   /* Block in which the inode is stored.  */
   int block;
+  if(ino==0) return GRUB_ERR_BAD_ARGUMENT;
   data->ino = ino;
 
   /* The first inode in minix is inode 1.  */
@@ -259,6 +364,19 @@
 	    + grub_le_to_cpu16 (sblock->zone_bmap_size))
 	   << GRUB_MINIX_LOG2_BSIZE);
 
+#ifdef GRUB_MOD_MINIX3
+  block = ((2 + grub_le_to_cpu16 (sblock->inode_bmap_size)
+	  + grub_le_to_cpu16 (sblock->zone_bmap_size))
+	  * (sblock->block_size / GRUB_DISK_SECTOR_SIZE));
+	  block += ino / (GRUB_DISK_SECTOR_SIZE
+		      / sizeof (struct grub_minix3_inode));
+  int offs = (ino
+	  % (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix3_inode))
+	  * sizeof (struct grub_minix3_inode));
+	
+  grub_disk_read (data->disk, block, offs,
+		      sizeof (struct grub_minix3_inode),&data->inode3);
+#else
   if (data->version == 1)
     {
       block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
@@ -280,7 +398,7 @@
       grub_disk_read (data->disk, block, offs,
 		      sizeof (struct grub_minix2_inode),&data->inode2);
     }
-
+#endif
   return GRUB_ERR_NONE;
 }
 
@@ -348,16 +466,20 @@
 
   do
     {
+#ifdef GRUB_MOD_MINIX3
+      grub_uint32_t ino;
+#else
       grub_uint16_t ino;
+#endif
       char filename[data->filename_size + 1];
 
       if (grub_strlen (name) == 0)
 	return GRUB_ERR_NONE;
 
-      if (grub_minix_read_file (data, 0, pos, sizeof (ino),
+      if (grub_minix_read_file (data, 0, pos, sizeof(ino),
 				(char *) &ino) < 0)
 	return grub_errno;
-      if (grub_minix_read_file (data, 0, pos + sizeof (ino),
+      if (grub_minix_read_file (data, 0, pos + sizeof(ino),
 				data->filename_size, (char *) filename)< 0)
 	return grub_errno;
 
@@ -422,7 +544,15 @@
 		  sizeof (struct grub_minix_sblock),&data->sblock);
   if (grub_errno)
     goto fail;
-
+#ifdef GRUB_MOD_MINIX3
+  if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX3_MAGIC)
+    {
+      data->version = 3;
+      data->filename_size = 60;
+    }
+  else
+    goto fail;
+#else
   if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC)
     {
       data->version = 1;
@@ -445,10 +575,15 @@
     }
   else
     goto fail;
-
+#endif
   data->disk = disk;
   data->linknest = 0;
 
+#ifdef GRUB_MOD_MINIX3
+  blocksize = data->sblock.block_size;
+#else
+  blocksize = 1024;
+#endif
   return data;
 
  fail:
@@ -456,7 +591,7 @@
   grub_error (GRUB_ERR_BAD_FS, "not a minix filesystem");
   return 0;
 }
-\f
+
 static grub_err_t
 grub_minix_dir (grub_device_t device, const char *path,
 		  int (*hook) (const char *filename,
@@ -488,7 +623,11 @@
 
   while (pos < GRUB_MINIX_INODE_SIZE (data))
     {
+#ifdef GRUB_MOD_MINIX3
+      grub_uint32_t ino;
+#else
       grub_uint16_t ino;
+#endif
       char filename[data->filename_size + 1];
       int dirino = data->ino;
       struct grub_dirhook_info info;
@@ -505,17 +644,20 @@
 	return grub_errno;
       filename[data->filename_size] = '\0';
 
-      /* The filetype is not stored in the dirent.  Read the inode to
-	 find out the filetype.  This *REALLY* sucks.  */
-      grub_minix_read_inode (data, grub_le_to_cpu16 (ino));
-      info.dir = ((GRUB_MINIX_INODE_MODE (data)
-		   & GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR);
-      if (hook (filename, &info) ? 1 : 0)
-	break;
+      if(ino)
+	{
+	  /* It's a valid dirent only when ino > 0
+	    The filetype is not stored in the dirent.  Read the inode to
+	    find out the filetype.  This *REALLY* sucks.  */
+	  grub_minix_read_inode (data, grub_le_to_cpu16 (ino));
+	  info.dir = ((GRUB_MINIX_INODE_MODE (data)
+		      & GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR);
+	  if (hook (filename, &info) ? 1 : 0)
+	    break;
 
       /* Load the old inode back in.  */
       grub_minix_read_inode (data, dirino);
-
+	}
       pos += sizeof (ino) + data->filename_size;
     }
 
@@ -582,33 +724,37 @@
   return GRUB_ERR_NONE;
 }
 
-
-static grub_err_t
-grub_minix_label (grub_device_t device __attribute ((unused)),
-		char **label __attribute ((unused)))
-{
-  return GRUB_ERR_NONE;
-}
-
 \f
 static struct grub_fs grub_minix_fs =
   {
+#ifdef GRUB_MOD_MINIX3
+    .name = "minix3",
+#else
     .name = "minix",
+#endif
     .dir = grub_minix_dir,
     .open = grub_minix_open,
     .read = grub_minix_read,
     .close = grub_minix_close,
-    .label = grub_minix_label,
+    .label = 0,
     .next = 0
   };
 
+#ifdef GRUB_MOD_MINIX3
+GRUB_MOD_INIT(minix3)
+#else
 GRUB_MOD_INIT(minix)
+#endif
 {
   grub_fs_register (&grub_minix_fs);
   my_mod = mod;
 }
 
+#ifdef GRUB_MOD_MINIX3
+GRUB_MOD_FINI(minix3)
+#else
 GRUB_MOD_FINI(minix)
+#endif
 {
   grub_fs_unregister (&grub_minix_fs);
 }

=== added file 'fs/minix3.c'
--- fs/minix3.c	1970-01-01 00:00:00 +0000
+++ fs/minix3.c	2010-07-28 00:59:27 +0000
@@ -0,0 +1,2 @@
+#define GRUB_MOD_MINIX3
+#include "minix.c"

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2011-05-05 23:59 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-28  3:25 [PATCH] MINIX file system version 3 support Fam Zheng
2010-09-08 15:26 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-02-19  8:43   ` Fam Cook
2011-02-19  8:44     ` Fam Cook
2011-02-19 12:52     ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-04-10 18:39 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-04-11  1:01   ` Feiran Zheng
2011-05-05 22:59     ` Feiran Zheng
2011-05-05 23:05       ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-05-05 23:34         ` Feiran Zheng
2011-05-05 23:59           ` Vladimir 'φ-coder/phcoder' Serbinenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.