Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=252e211e90ce56bf005cb533ad5a297c18c19407
Commit:     252e211e90ce56bf005cb533ad5a297c18c19407
Parent:     ef2fb67989d30fea475bb01c5b7ca44adbce5dea
Author:     Mark Fortescue <[EMAIL PROTECTED]>
AuthorDate: Tue Oct 16 23:26:31 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Wed Oct 17 08:42:49 2007 -0700

    Add in SunOS 4.1.x compatible mode for UFS
    
    Add in support for SunOS 4.1.x flavor of BSD 4.2 UFS filing system Macros 
have
    been put in to alow suport for the old static table Cylinder Groups but this
    implementation does not use them yet.
    
    This also fixes Solaris UFS filing system access by disabling fast symbolic
    links as Sun's version of UFS does not support on-disk fast symbolic links.
    
    Tested by:
      Ppartitioning a new disk using SunOS 4.1.1, creating a UFS filing system 
on
      one of the partitions and writing some files to the filing system.
      Using Linux-2.6.22 (patched) to read the files and then write a shed load 
of
      files to the UFS partition.
      Using SunOS 4.1.1 to verify the filing system is OK and to check the 
files.
    The test host is a sun4c SS1 Clone.
    
    [EMAIL PROTECTED]: coding style fixes]
    [EMAIL PROTECTED]: fix oops]
    Signed-off-by: Mark Fortescue <[EMAIL PROTECTED]>
    Cc: Evgeniy Dushistov <[EMAIL PROTECTED]>
    Signed-off-by: Alexey Dobriyan <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 fs/ufs/super.c         |   41 +++++++++++++++++++++++++++++------
 fs/ufs/util.h          |   50 +++++++++++++++++++++++++++++++++----------
 include/linux/ufs_fs.h |   55 ++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 123 insertions(+), 23 deletions(-)

diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index c5bdea7..87f6b51 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -286,7 +286,7 @@ void ufs_warning (struct super_block * sb, const char * 
function,
 }
 
 enum {
-       Opt_type_old, Opt_type_sunx86, Opt_type_sun, Opt_type_44bsd,
+       Opt_type_old, Opt_type_sunx86, Opt_type_sun, Opt_type_sunos, 
Opt_type_44bsd,
        Opt_type_ufs2, Opt_type_hp, Opt_type_nextstepcd, Opt_type_nextstep,
        Opt_type_openstep, Opt_onerror_panic, Opt_onerror_lock,
        Opt_onerror_umount, Opt_onerror_repair, Opt_err
@@ -296,6 +296,7 @@ static match_table_t tokens = {
        {Opt_type_old, "ufstype=old"},
        {Opt_type_sunx86, "ufstype=sunx86"},
        {Opt_type_sun, "ufstype=sun"},
+       {Opt_type_sunos, "ufstype=sunos"},
        {Opt_type_44bsd, "ufstype=44bsd"},
        {Opt_type_ufs2, "ufstype=ufs2"},
        {Opt_type_ufs2, "ufstype=5xbsd"},
@@ -339,6 +340,10 @@ static int ufs_parse_options (char * options, unsigned * 
mount_options)
                        ufs_clear_opt (*mount_options, UFSTYPE);
                        ufs_set_opt (*mount_options, UFSTYPE_SUN);
                        break;
+               case Opt_type_sunos:
+                       ufs_clear_opt(*mount_options, UFSTYPE);
+                       ufs_set_opt(*mount_options, UFSTYPE_SUNOS);
+                       break;
                case Opt_type_44bsd:
                        ufs_clear_opt (*mount_options, UFSTYPE);
                        ufs_set_opt (*mount_options, UFSTYPE_44BSD);
@@ -654,8 +659,8 @@ static int ufs_fill_super(struct super_block *sb, void 
*data, int silent)
                ufs_set_opt (sbi->s_mount_opt, UFSTYPE_OLD);
        }
 
-       sbi->s_uspi = uspi =
-               kmalloc (sizeof(struct ufs_sb_private_info), GFP_KERNEL);
+       uspi = kzalloc(sizeof(struct ufs_sb_private_info), GFP_KERNEL);
+       sbi->s_uspi = uspi;
        if (!uspi)
                goto failed;
        uspi->s_dirblksize = UFS_SECTOR_SIZE;
@@ -692,10 +697,22 @@ static int ufs_fill_super(struct super_block *sb, void 
*data, int silent)
                uspi->s_fshift = 10;
                uspi->s_sbsize = super_block_size = 2048;
                uspi->s_sbbase = 0;
-               uspi->s_maxsymlinklen = 56;
+               uspi->s_maxsymlinklen = 0; /* Not supported on disk */
                flags |= UFS_DE_OLD | UFS_UID_EFT | UFS_ST_SUN | UFS_CG_SUN;
                break;
 
+       case UFS_MOUNT_UFSTYPE_SUNOS:
+               UFSD(("ufstype=sunos\n"))
+               uspi->s_fsize = block_size = 1024;
+               uspi->s_fmask = ~(1024 - 1);
+               uspi->s_fshift = 10;
+               uspi->s_sbsize = 2048;
+               super_block_size = 2048;
+               uspi->s_sbbase = 0;
+               uspi->s_maxsymlinklen = 0; /* Not supported on disk */
+               flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_SUNOS | UFS_CG_SUN;
+               break;
+
        case UFS_MOUNT_UFSTYPE_SUNx86:
                UFSD("ufstype=sunx86\n");
                uspi->s_fsize = block_size = 1024;
@@ -703,7 +720,7 @@ static int ufs_fill_super(struct super_block *sb, void 
*data, int silent)
                uspi->s_fshift = 10;
                uspi->s_sbsize = super_block_size = 2048;
                uspi->s_sbbase = 0;
-               uspi->s_maxsymlinklen = 56;
+               uspi->s_maxsymlinklen = 0; /* Not supported on disk */
                flags |= UFS_DE_OLD | UFS_UID_EFT | UFS_ST_SUNx86 | UFS_CG_SUN;
                break;
 
@@ -805,11 +822,18 @@ again:
        if (!ubh) 
             goto failed;
 
-       
        usb1 = ubh_get_usb_first(uspi);
        usb2 = ubh_get_usb_second(uspi);
        usb3 = ubh_get_usb_third(uspi);
 
+       /* Sort out mod used on SunOS 4.1.3 for fs_state */
+       uspi->s_postblformat = fs32_to_cpu(sb, usb3->fs_postblformat);
+       if (((flags & UFS_ST_MASK) == UFS_ST_SUNOS) &&
+           (uspi->s_postblformat != UFS_42POSTBLFMT)) {
+               flags &= ~UFS_ST_MASK;
+               flags |=  UFS_ST_SUN;
+       }
+
        /*
         * Check ufs magic number
         */
@@ -904,6 +928,7 @@ magic_found:
        if (((flags & UFS_ST_MASK) == UFS_ST_44BSD) ||
          ((flags & UFS_ST_MASK) == UFS_ST_OLD) ||
          (((flags & UFS_ST_MASK) == UFS_ST_SUN || 
+           (flags & UFS_ST_MASK) == UFS_ST_SUNOS ||
          (flags & UFS_ST_MASK) == UFS_ST_SUNx86) && 
          (ufs_get_fs_state(sb, usb1, usb3) == (UFS_FSOK - fs32_to_cpu(sb, 
usb1->fs_time))))) {
                switch(usb1->fs_clean) {
@@ -995,7 +1020,6 @@ magic_found:
        uspi->s_contigsumsize = fs32_to_cpu(sb, 
usb3->fs_un2.fs_44.fs_contigsumsize);
        uspi->s_qbmask = ufs_get_fs_qbmask(sb, usb3);
        uspi->s_qfmask = ufs_get_fs_qfmask(sb, usb3);
-       uspi->s_postblformat = fs32_to_cpu(sb, usb3->fs_postblformat);
        uspi->s_nrpos = fs32_to_cpu(sb, usb3->fs_nrpos);
        uspi->s_postbloff = fs32_to_cpu(sb, usb3->fs_postbloff);
        uspi->s_rotbloff = fs32_to_cpu(sb, usb3->fs_rotbloff);
@@ -1077,6 +1101,7 @@ static void ufs_write_super(struct super_block *sb)
        if (!(sb->s_flags & MS_RDONLY)) {
                usb1->fs_time = cpu_to_fs32(sb, get_seconds());
                if ((flags & UFS_ST_MASK) == UFS_ST_SUN 
+                 || (flags & UFS_ST_MASK) == UFS_ST_SUNOS
                  || (flags & UFS_ST_MASK) == UFS_ST_SUNx86)
                        ufs_set_fs_state(sb, usb1, usb3,
                                        UFS_FSOK - fs32_to_cpu(sb, 
usb1->fs_time));
@@ -1146,6 +1171,7 @@ static int ufs_remount (struct super_block *sb, int 
*mount_flags, char *data)
                ufs_put_super_internal(sb);
                usb1->fs_time = cpu_to_fs32(sb, get_seconds());
                if ((flags & UFS_ST_MASK) == UFS_ST_SUN
+                 || (flags & UFS_ST_MASK) == UFS_ST_SUNOS
                  || (flags & UFS_ST_MASK) == UFS_ST_SUNx86) 
                        ufs_set_fs_state(sb, usb1, usb3,
                                UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time));
@@ -1162,6 +1188,7 @@ static int ufs_remount (struct super_block *sb, int 
*mount_flags, char *data)
                return -EINVAL;
 #else
                if (ufstype != UFS_MOUNT_UFSTYPE_SUN && 
+                   ufstype != UFS_MOUNT_UFSTYPE_SUNOS &&
                    ufstype != UFS_MOUNT_UFSTYPE_44BSD &&
                    ufstype != UFS_MOUNT_UFSTYPE_SUNx86 &&
                    ufstype != UFS_MOUNT_UFSTYPE_UFS2) {
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index 79a340a..b26fc4d 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -38,6 +38,10 @@ ufs_get_fs_state(struct super_block *sb, struct 
ufs_super_block_first *usb1,
                 struct ufs_super_block_third *usb3)
 {
        switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
+       case UFS_ST_SUNOS:
+               if (fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT)
+                       return fs32_to_cpu(sb, usb1->fs_u0.fs_sun.fs_state);
+               /* Fall Through to UFS_ST_SUN */
        case UFS_ST_SUN:
                return fs32_to_cpu(sb, usb3->fs_un2.fs_sun.fs_state);
        case UFS_ST_SUNx86:
@@ -53,6 +57,12 @@ ufs_set_fs_state(struct super_block *sb, struct 
ufs_super_block_first *usb1,
                 struct ufs_super_block_third *usb3, s32 value)
 {
        switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
+       case UFS_ST_SUNOS:
+               if (fs32_to_cpu(sb, usb3->fs_postblformat == UFS_42POSTBLFMT)) {
+                       usb1->fs_u0.fs_sun.fs_state = cpu_to_fs32(sb, value);
+                       break;
+               }
+               /* Fall Through to UFS_ST_SUN */
        case UFS_ST_SUN:
                usb3->fs_un2.fs_sun.fs_state = cpu_to_fs32(sb, value);
                break;
@@ -81,6 +91,7 @@ ufs_get_fs_qbmask(struct super_block *sb, struct 
ufs_super_block_third *usb3)
        __fs64 tmp;
 
        switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
+       case UFS_ST_SUNOS:
        case UFS_ST_SUN:
                ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sun.fs_qbmask[0];
                ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sun.fs_qbmask[1];
@@ -104,6 +115,7 @@ ufs_get_fs_qfmask(struct super_block *sb, struct 
ufs_super_block_third *usb3)
        __fs64 tmp;
 
        switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
+       case UFS_ST_SUNOS:
        case UFS_ST_SUN:
                ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sun.fs_qfmask[0];
                ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sun.fs_qfmask[1];
@@ -179,10 +191,12 @@ static inline u32
 ufs_get_inode_uid(struct super_block *sb, struct ufs_inode *inode)
 {
        switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) {
-       case UFS_UID_EFT:
-               return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_uid);
        case UFS_UID_44BSD:
                return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_uid);
+       case UFS_UID_EFT:
+               if (inode->ui_u1.oldids.ui_suid == 0xFFFF)
+                       return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_uid);
+               /* Fall through */
        default:
                return fs16_to_cpu(sb, inode->ui_u1.oldids.ui_suid);
        }
@@ -192,24 +206,31 @@ static inline void
 ufs_set_inode_uid(struct super_block *sb, struct ufs_inode *inode, u32 value)
 {
        switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) {
-       case UFS_UID_EFT:
-               inode->ui_u3.ui_sun.ui_uid = cpu_to_fs32(sb, value);
-               break;
        case UFS_UID_44BSD:
                inode->ui_u3.ui_44.ui_uid = cpu_to_fs32(sb, value);
+               inode->ui_u1.oldids.ui_suid = cpu_to_fs16(sb, value);
+               break;
+       case UFS_UID_EFT:
+               inode->ui_u3.ui_sun.ui_uid = cpu_to_fs32(sb, value);
+               if (value > 0xFFFF)
+                       value = 0xFFFF;
+               /* Fall through */
+       default:
+               inode->ui_u1.oldids.ui_suid = cpu_to_fs16(sb, value);
                break;
        }
-       inode->ui_u1.oldids.ui_suid = cpu_to_fs16(sb, value); 
 }
 
 static inline u32
 ufs_get_inode_gid(struct super_block *sb, struct ufs_inode *inode)
 {
        switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) {
-       case UFS_UID_EFT:
-               return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_gid);
        case UFS_UID_44BSD:
                return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_gid);
+       case UFS_UID_EFT:
+               if (inode->ui_u1.oldids.ui_suid == 0xFFFF)
+                       return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_gid);
+               /* Fall through */
        default:
                return fs16_to_cpu(sb, inode->ui_u1.oldids.ui_sgid);
        }
@@ -219,14 +240,19 @@ static inline void
 ufs_set_inode_gid(struct super_block *sb, struct ufs_inode *inode, u32 value)
 {
        switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) {
-       case UFS_UID_EFT:
-               inode->ui_u3.ui_sun.ui_gid = cpu_to_fs32(sb, value);
-               break;
        case UFS_UID_44BSD:
                inode->ui_u3.ui_44.ui_gid = cpu_to_fs32(sb, value);
+               inode->ui_u1.oldids.ui_sgid =  cpu_to_fs16(sb, value);
+               break;
+       case UFS_UID_EFT:
+               inode->ui_u3.ui_sun.ui_gid = cpu_to_fs32(sb, value);
+               if (value > 0xFFFF)
+                       value = 0xFFFF;
+               /* Fall through */
+       default:
+               inode->ui_u1.oldids.ui_sgid =  cpu_to_fs16(sb, value);
                break;
        }
-       inode->ui_u1.oldids.ui_sgid =  cpu_to_fs16(sb, value);
 }
 
 extern dev_t ufs_get_inode_dev(struct super_block *, struct ufs_inode_info *);
diff --git a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h
index daeba22..52730d2 100644
--- a/include/linux/ufs_fs.h
+++ b/include/linux/ufs_fs.h
@@ -170,8 +170,9 @@ typedef __u16 __bitwise __fs16;
 #define UFS_ST_MASK            0x00000700      /* mask for the following */
 #define UFS_ST_OLD             0x00000000
 #define UFS_ST_44BSD           0x00000100
-#define UFS_ST_SUN             0x00000200
-#define UFS_ST_SUNx86          0x00000400
+#define UFS_ST_SUN             0x00000200 /* Solaris */
+#define UFS_ST_SUNOS           0x00000300
+#define UFS_ST_SUNx86          0x00000400 /* Solaris x86 */
 /*cylinder group encoding */
 #define UFS_CG_MASK            0x00003000      /* mask for the following */
 #define UFS_CG_OLD             0x00000000
@@ -204,6 +205,7 @@ typedef __u16 __bitwise __fs16;
 #define UFS_MOUNT_UFSTYPE_SUNx86       0x00000400
 #define UFS_MOUNT_UFSTYPE_HP           0x00000800
 #define UFS_MOUNT_UFSTYPE_UFS2         0x00001000
+#define UFS_MOUNT_UFSTYPE_SUNOS                0x00002000
 
 #define ufs_clear_opt(o,opt)   o &= ~UFS_MOUNT_##opt
 #define ufs_set_opt(o,opt)     o |= UFS_MOUNT_##opt
@@ -374,7 +376,14 @@ struct ufs_csum_core {
  * struct ufs_super_block_(first,second,third) instead.
  */
 struct ufs_super_block {
-       __fs32  fs_link;        /* UNUSED */
+       union {
+               struct {
+                       __fs32  fs_link;        /* UNUSED */
+               } fs_42;
+               struct {
+                       __fs32  fs_state;       /* file system state flag */
+               } fs_sun;
+       } fs_u0;
        __fs32  fs_rlink;       /* UNUSED */
        __fs32  fs_sblkno;      /* addr of super-block in filesys */
        __fs32  fs_cblkno;      /* offset of cyl-block in filesys */
@@ -545,6 +554,15 @@ struct ufs_super_block {
 #define        CG_MAGIC        0x090255
 #define ufs_cg_chkmagic(sb, ucg) \
        (fs32_to_cpu((sb), (ucg)->cg_magic) == CG_MAGIC)
+/*
+ * Macros for access to old cylinder group array structures
+ */
+#define ufs_ocg_blktot(sb, ucg)      fs32_to_cpu((sb), ((struct 
ufs_old_cylinder_group *)(ucg))->cg_btot)
+#define ufs_ocg_blks(sb, ucg, cylno) fs32_to_cpu((sb), ((struct 
ufs_old_cylinder_group *)(ucg))->cg_b[cylno])
+#define ufs_ocg_inosused(sb, ucg)    fs32_to_cpu((sb), ((struct 
ufs_old_cylinder_group *)(ucg))->cg_iused)
+#define ufs_ocg_blksfree(sb, ucg)    fs32_to_cpu((sb), ((struct 
ufs_old_cylinder_group *)(ucg))->cg_free)
+#define ufs_ocg_chkmagic(sb, ucg) \
+       (fs32_to_cpu((sb), ((struct ufs_old_cylinder_group *)(ucg))->cg_magic) 
== CG_MAGIC)
 
 /*
  * size of this structure is 172 B
@@ -590,6 +608,28 @@ struct     ufs_cylinder_group {
 /* actually longer */
 };
 
+/* Historic Cylinder group info */
+struct ufs_old_cylinder_group {
+       __fs32  cg_link;                /* linked list of cyl groups */
+       __fs32  cg_rlink;               /* for incore cyl groups     */
+       __fs32  cg_time;                /* time last written */
+       __fs32  cg_cgx;                 /* we are the cgx'th cylinder group */
+       __fs16  cg_ncyl;                /* number of cyl's this cg */
+       __fs16  cg_niblk;               /* number of inode blocks this cg */
+       __fs32  cg_ndblk;               /* number of data blocks this cg */
+       struct  ufs_csum cg_cs;         /* cylinder summary information */
+       __fs32  cg_rotor;               /* position of last used block */
+       __fs32  cg_frotor;              /* position of last used frag */
+       __fs32  cg_irotor;              /* position of last used inode */
+       __fs32  cg_frsum[8];            /* counts of available frags */
+       __fs32  cg_btot[32];            /* block totals per cylinder */
+       __fs16  cg_b[32][8];            /* positions of free blocks */
+       __u8    cg_iused[256];          /* used inode map */
+       __fs32  cg_magic;               /* magic number */
+       __u8    cg_free[1];             /* free block map */
+/* actually longer */
+};
+
 /*
  * structure of an on-disk inode
  */
@@ -796,7 +836,14 @@ struct ufs_sb_private_info {
  *     ufs_super_block_third   356
  */
 struct ufs_super_block_first {
-       __fs32  fs_link;
+       union {
+               struct {
+                       __fs32  fs_link;        /* UNUSED */
+               } fs_42;
+               struct {
+                       __fs32  fs_state;       /* file system state flag */
+               } fs_sun;
+       } fs_u0;
        __fs32  fs_rlink;
        __fs32  fs_sblkno;
        __fs32  fs_cblkno;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to