Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs into for-2.6.34-incoming
[safe/jmp/linux-2.6] / fs / ufs / util.h
index e95d1c4..23ceed8 100644 (file)
@@ -38,13 +38,17 @@ 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_u2.fs_sun.fs_state);
+               return fs32_to_cpu(sb, usb3->fs_un2.fs_sun.fs_state);
        case UFS_ST_SUNx86:
                return fs32_to_cpu(sb, usb1->fs_u1.fs_sunx86.fs_state);
        case UFS_ST_44BSD:
        default:
-               return fs32_to_cpu(sb, usb3->fs_u2.fs_44.fs_state);
+               return fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_state);
        }
 }
 
@@ -53,14 +57,20 @@ 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_u2.fs_sun.fs_state = cpu_to_fs32(sb, value);
+               usb3->fs_un2.fs_sun.fs_state = cpu_to_fs32(sb, value);
                break;
        case UFS_ST_SUNx86:
                usb1->fs_u1.fs_sunx86.fs_state = cpu_to_fs32(sb, value);
                break;
        case UFS_ST_44BSD:
-               usb3->fs_u2.fs_44.fs_state = cpu_to_fs32(sb, value);
+               usb3->fs_un2.fs_44.fs_state = cpu_to_fs32(sb, value);
                break;
        }
 }
@@ -70,7 +80,7 @@ ufs_get_fs_npsect(struct super_block *sb, struct ufs_super_block_first *usb1,
                  struct ufs_super_block_third *usb3)
 {
        if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86)
-               return fs32_to_cpu(sb, usb3->fs_u2.fs_sunx86.fs_npsect);
+               return fs32_to_cpu(sb, usb3->fs_un2.fs_sunx86.fs_npsect);
        else
                return fs32_to_cpu(sb, usb1->fs_u1.fs_sun.fs_npsect);
 }
@@ -81,17 +91,18 @@ 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_u2.fs_sun.fs_qbmask[0];
-               ((__fs32 *)&tmp)[1] = usb3->fs_u2.fs_sun.fs_qbmask[1];
+               ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sun.fs_qbmask[0];
+               ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sun.fs_qbmask[1];
                break;
        case UFS_ST_SUNx86:
-               ((__fs32 *)&tmp)[0] = usb3->fs_u2.fs_sunx86.fs_qbmask[0];
-               ((__fs32 *)&tmp)[1] = usb3->fs_u2.fs_sunx86.fs_qbmask[1];
+               ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sunx86.fs_qbmask[0];
+               ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sunx86.fs_qbmask[1];
                break;
        case UFS_ST_44BSD:
-               ((__fs32 *)&tmp)[0] = usb3->fs_u2.fs_44.fs_qbmask[0];
-               ((__fs32 *)&tmp)[1] = usb3->fs_u2.fs_44.fs_qbmask[1];
+               ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_44.fs_qbmask[0];
+               ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_44.fs_qbmask[1];
                break;
        }
 
@@ -104,17 +115,18 @@ 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_u2.fs_sun.fs_qfmask[0];
-               ((__fs32 *)&tmp)[1] = usb3->fs_u2.fs_sun.fs_qfmask[1];
+               ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sun.fs_qfmask[0];
+               ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sun.fs_qfmask[1];
                break;
        case UFS_ST_SUNx86:
-               ((__fs32 *)&tmp)[0] = usb3->fs_u2.fs_sunx86.fs_qfmask[0];
-               ((__fs32 *)&tmp)[1] = usb3->fs_u2.fs_sunx86.fs_qfmask[1];
+               ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sunx86.fs_qfmask[0];
+               ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sunx86.fs_qfmask[1];
                break;
        case UFS_ST_44BSD:
-               ((__fs32 *)&tmp)[0] = usb3->fs_u2.fs_44.fs_qfmask[0];
-               ((__fs32 *)&tmp)[1] = usb3->fs_u2.fs_44.fs_qfmask[1];
+               ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_44.fs_qfmask[0];
+               ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_44.fs_qfmask[1];
                break;
        }
 
@@ -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,18 +240,26 @@ 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 *);
 extern void ufs_set_inode_dev(struct super_block *, struct ufs_inode_info *, dev_t);
+extern int __ufs_write_begin(struct file *file, struct address_space *mapping,
+               loff_t pos, unsigned len, unsigned flags,
+               struct page **pagep, void **fsdata);
 
 /*
  * These functions manipulate ufs buffers
@@ -242,7 +271,7 @@ extern void ubh_brelse (struct ufs_buffer_head *);
 extern void ubh_brelse_uspi (struct ufs_sb_private_info *);
 extern void ubh_mark_buffer_dirty (struct ufs_buffer_head *);
 extern void ubh_mark_buffer_uptodate (struct ufs_buffer_head *, int);
-extern void ubh_ll_rw_block (int, unsigned, struct ufs_buffer_head **);
+extern void ubh_ll_rw_block(int, struct ufs_buffer_head *);
 extern void ubh_wait_on_buffer (struct ufs_buffer_head *);
 extern void ubh_bforget (struct ufs_buffer_head *);
 extern int  ubh_buffer_dirty (struct ufs_buffer_head *);
@@ -251,6 +280,14 @@ extern void _ubh_ubhcpymem_(struct ufs_sb_private_info *, unsigned char *, struc
 #define ubh_memcpyubh(ubh,mem,size) _ubh_memcpyubh_(uspi,ubh,mem,size)
 extern void _ubh_memcpyubh_(struct ufs_sb_private_info *, struct ufs_buffer_head *, unsigned char *, unsigned);
 
+/* This functions works with cache pages*/
+extern struct page *ufs_get_locked_page(struct address_space *mapping,
+                                       pgoff_t index);
+static inline void ufs_put_locked_page(struct page *page)
+{
+       unlock_page(page);
+       page_cache_release(page);
+}
 
 
 /*
@@ -291,42 +328,42 @@ static inline void *get_usb_offset(struct ufs_sb_private_info *uspi,
 
 #define ubh_get_addr16(ubh,begin) \
        (((__fs16*)((ubh)->bh[(begin) >> (uspi->s_fshift-1)]->b_data)) + \
-       ((begin) & (uspi->fsize>>1) - 1)))
+       ((begin) & ((uspi->fsize>>1) - 1)))
 
 #define ubh_get_addr32(ubh,begin) \
        (((__fs32*)((ubh)->bh[(begin) >> (uspi->s_fshift-2)]->b_data)) + \
        ((begin) & ((uspi->s_fsize>>2) - 1)))
 
+#define ubh_get_addr64(ubh,begin) \
+       (((__fs64*)((ubh)->bh[(begin) >> (uspi->s_fshift-3)]->b_data)) + \
+       ((begin) & ((uspi->s_fsize>>3) - 1)))
+
 #define ubh_get_addr ubh_get_addr8
 
+static inline void *ubh_get_data_ptr(struct ufs_sb_private_info *uspi,
+                                    struct ufs_buffer_head *ubh,
+                                    u64 blk)
+{
+       if (uspi->fs_magic == UFS2_MAGIC)
+               return ubh_get_addr64(ubh, blk);
+       else
+               return ubh_get_addr32(ubh, blk);
+}
+
 #define ubh_blkmap(ubh,begin,bit) \
        ((*ubh_get_addr(ubh, (begin) + ((bit) >> 3)) >> ((bit) & 7)) & (0xff >> (UFS_MAXFRAG - uspi->s_fpb)))
 
-
-/*
- * Macros for access to superblock array structures
- */
-#define ubh_postbl(ubh,cylno,i) \
-       ((uspi->s_postblformat != UFS_DYNAMICPOSTBLFMT) \
-       ? (*(__s16*)(ubh_get_addr(ubh, \
-       (unsigned)(&((struct ufs_super_block *)0)->fs_opostbl) \
-       + (((cylno) * 16 + (i)) << 1) ) )) \
-       : (*(__s16*)(ubh_get_addr(ubh, \
-       uspi->s_postbloff + (((cylno) * uspi->s_nrpos + (i)) << 1) ))))
-
-#define ubh_rotbl(ubh,i) \
-       ((uspi->s_postblformat != UFS_DYNAMICPOSTBLFMT) \
-       ? (*(__u8*)(ubh_get_addr(ubh, \
-       (unsigned)(&((struct ufs_super_block *)0)->fs_space) + (i)))) \
-       : (*(__u8*)(ubh_get_addr(ubh, uspi->s_rotbloff + (i)))))
-
 /*
  * Determine the number of available frags given a
  * percentage to hold in reserve.
  */
-#define ufs_freespace(usb, percentreserved) \
-       (ufs_blkstofrags(fs32_to_cpu(sb, (usb)->fs_cstotal.cs_nbfree)) + \
-       fs32_to_cpu(sb, (usb)->fs_cstotal.cs_nffree) - (uspi->s_dsize * (percentreserved) / 100))
+static inline u64
+ufs_freespace(struct ufs_sb_private_info *uspi, int percentreserved)
+{
+       return ufs_blkstofrags(uspi->cs_total.cs_nbfree) +
+               uspi->cs_total.cs_nffree -
+               (uspi->s_dsize * (percentreserved) / 100);
+}
 
 /*
  * Macros to access cylinder group array structures
@@ -513,3 +550,46 @@ static inline void ufs_fragacct (struct super_block * sb, unsigned blockmap,
        if (fragsize > 0 && fragsize < uspi->s_fpb)
                fs32_add(sb, &fraglist[fragsize], cnt);
 }
+
+static inline void *ufs_get_direct_data_ptr(struct ufs_sb_private_info *uspi,
+                                           struct ufs_inode_info *ufsi,
+                                           unsigned blk)
+{
+       BUG_ON(blk > UFS_TIND_BLOCK);
+       return uspi->fs_magic == UFS2_MAGIC ?
+               (void *)&ufsi->i_u1.u2_i_data[blk] :
+               (void *)&ufsi->i_u1.i_data[blk];
+}
+
+static inline u64 ufs_data_ptr_to_cpu(struct super_block *sb, void *p)
+{
+       return UFS_SB(sb)->s_uspi->fs_magic == UFS2_MAGIC ?
+               fs64_to_cpu(sb, *(__fs64 *)p) :
+               fs32_to_cpu(sb, *(__fs32 *)p);
+}
+
+static inline void ufs_cpu_to_data_ptr(struct super_block *sb, void *p, u64 val)
+{
+       if (UFS_SB(sb)->s_uspi->fs_magic == UFS2_MAGIC)
+               *(__fs64 *)p = cpu_to_fs64(sb, val);
+       else
+               *(__fs32 *)p = cpu_to_fs32(sb, val);
+}
+
+static inline void ufs_data_ptr_clear(struct ufs_sb_private_info *uspi,
+                                     void *p)
+{
+       if (uspi->fs_magic == UFS2_MAGIC)
+               *(__fs64 *)p = 0;
+       else
+               *(__fs32 *)p = 0;
+}
+
+static inline int ufs_is_data_ptr_zero(struct ufs_sb_private_info *uspi,
+                                      void *p)
+{
+       if (uspi->fs_magic == UFS2_MAGIC)
+               return *(__fs64 *)p == 0;
+       else
+               return *(__fs32 *)p == 0;
+}