summaryrefslogtreecommitdiffstats
path: root/fs/ufs/util.h
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ufs/util.h')
-rw-r--r--fs/ufs/util.h263
1 files changed, 203 insertions, 60 deletions
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index 7443f9fc9..02e6fe98a 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -19,73 +19,166 @@
#define max(x,y) ((x)>(y)?(x):(y))
+
/*
- * current filesystem state; method depends on flags
+ * macros used for retyping
*/
-#define ufs_state(usb3) \
- (((flags & UFS_ST_MASK) == UFS_ST_OLD) \
- ? (usb3)->fs_u.fs_sun.fs_state /* old normal way */ \
- : (usb3)->fs_u.fs_44.fs_state /* 4.4BSD way */)
+#define UCPI_UBH ((struct ufs_buffer_head *)ucpi)
+#define USPI_UBH ((struct ufs_buffer_head *)uspi)
+
+
/*
- * namlen, its format depends of flags
+ * macros used for accesing structures
*/
-#define ufs_namlen(de) _ufs_namlen_(de,flags,swab)
-static inline __u16 _ufs_namlen_(struct ufs_dir_entry * de, unsigned flags, unsigned swab) {
- if ((flags & UFS_DE_MASK) == UFS_DE_OLD) {
- return SWAB16(de->d_u.d_namlen);
- } else /* UFS_DE_44BSD */ {
- return de->d_u.d_44.d_namlen;
+#define ufs_get_fs_state(usb3) _ufs_get_fs_state_(usb3,flags,swab)
+static inline __s32 _ufs_get_fs_state_(struct ufs_super_block_third * usb3,
+ unsigned flags, unsigned swab)
+{
+ if ((flags & UFS_ST_MASK) == UFS_ST_SUN)
+ return SWAB32((usb3)->fs_u.fs_sun.fs_state);
+ else
+ return SWAB32((usb3)->fs_u.fs_44.fs_state);
+}
+
+#define ufs_set_fs_state(usb3,value) _ufs_set_fs_state_(usb3,value,flags,swab)
+static inline void _ufs_set_fs_state_(struct ufs_super_block_third * usb3,
+ __s32 value, unsigned flags, unsigned swab)
+{
+ if ((flags & UFS_ST_MASK) == UFS_ST_SUN)
+ (usb3)->fs_u.fs_sun.fs_state = SWAB32(value);
+ else
+ (usb3)->fs_u.fs_44.fs_state = SWAB32(value);
+}
+
+#define ufs_get_fs_qbmask(usb3) _ufs_get_fs_qbmask_(usb3,flags,swab)
+static inline __u64 _ufs_get_fs_qbmask_(struct ufs_super_block_third * usb3,
+ unsigned flags, unsigned swab)
+{
+ __u64 tmp;
+ if ((flags & UFS_ST_MASK) == UFS_ST_SUN) {
+ ((u32 *)&tmp)[0] = usb3->fs_u.fs_sun.fs_qbmask[0];
+ ((u32 *)&tmp)[1] = usb3->fs_u.fs_sun.fs_qbmask[1];
+ }
+ else {
+ ((u32 *)&tmp)[0] = usb3->fs_u.fs_44.fs_qbmask[0];
+ ((u32 *)&tmp)[1] = usb3->fs_u.fs_44.fs_qbmask[1];
}
+ return SWAB64(tmp);
}
-/*
- * Here is how the uid is computed:
- * if the file system is 4.2BSD, get it from oldids.
- * if it has sun extension and oldids is USEEFT, get it from ui_sun.
- * if it is 4.4 or Hurd, get it from ui_44 (which is the same as from ui_hurd).
- */
-#define ufs_uid(inode) _ufs_uid_(inode,flags,swab)
-static inline __u32 _ufs_uid_(struct ufs_inode * inode, unsigned flags, unsigned swab) {
+#define ufs_get_fs_qfmask(usb3) _ufs_get_fs_qfmask_(usb3,flags,swab)
+static inline __u64 _ufs_get_fs_qfmask_(struct ufs_super_block_third * usb3,
+ unsigned flags, unsigned swab)
+{
+ __u64 tmp;
+ if ((flags & UFS_ST_MASK) == UFS_ST_SUN) {
+ ((u32 *)&tmp)[0] = usb3->fs_u.fs_sun.fs_qfmask[0];
+ ((u32 *)&tmp)[1] = usb3->fs_u.fs_sun.fs_qfmask[1];
+ }
+ else {
+ ((u32 *)&tmp)[0] = usb3->fs_u.fs_44.fs_qfmask[0];
+ ((u32 *)&tmp)[1] = usb3->fs_u.fs_44.fs_qfmask[1];
+ }
+ return SWAB64(tmp);
+}
+
+#define ufs_get_de_namlen(de) \
+ (((flags & UFS_DE_MASK) == UFS_DE_OLD) \
+ ? SWAB16(de->d_u.d_namlen) \
+ : de->d_u.d_44.d_namlen)
+
+#define ufs_set_de_namlen(de,value) \
+ (((flags & UFS_DE_MASK) == UFS_DE_OLD) \
+ ? (de->d_u.d_namlen = SWAB16(value)) \
+ : (de->d_u.d_44.d_namlen = value))
+
+#define ufs_set_de_type(de,mode) _ufs_set_de_type_(de,mode,flags,swab)
+static inline void _ufs_set_de_type_(struct ufs_dir_entry * de, int mode,
+ unsigned flags, unsigned swab)
+{
+ if ((flags & UFS_DE_MASK) == UFS_DE_44BSD) {
+ switch (mode & S_IFMT) {
+ case S_IFSOCK: de->d_u.d_44.d_type = DT_SOCK; break;
+ case S_IFLNK: de->d_u.d_44.d_type = DT_LNK; break;
+ case S_IFREG: de->d_u.d_44.d_type = DT_REG; break;
+ case S_IFBLK: de->d_u.d_44.d_type = DT_BLK; break;
+ case S_IFDIR: de->d_u.d_44.d_type = DT_DIR; break;
+ case S_IFCHR: de->d_u.d_44.d_type = DT_CHR; break;
+ case S_IFIFO: de->d_u.d_44.d_type = DT_FIFO; break;
+ default: de->d_u.d_44.d_type = DT_UNKNOWN;
+ }
+ }
+}
+
+#define ufs_get_inode_uid(inode) _ufs_get_inode_uid_(inode,flags,swab)
+static inline __u32 _ufs_get_inode_uid_(struct ufs_inode * inode,
+ unsigned flags, unsigned swab)
+{
switch (flags & UFS_UID_MASK) {
case UFS_UID_EFT:
return SWAB32(inode->ui_u3.ui_sun.ui_uid);
case UFS_UID_44BSD:
return SWAB32(inode->ui_u3.ui_44.ui_uid);
- case UFS_UID_OLD:
default:
return SWAB16(inode->ui_u1.oldids.ui_suid);
}
}
-#define ufs_gid(inode) _ufs_gid_(inode,flags,swab)
-static inline __u32 _ufs_gid_(struct ufs_inode * inode, unsigned flags, unsigned swab) {
+#define ufs_set_inode_uid(inode,value) _ufs_set_inode_uid_(inode,value,flags,swab)
+static inline void _ufs_set_inode_uid_(struct ufs_inode * inode, __u32 value,
+ unsigned flags, unsigned swab)
+{
+ inode->ui_u1.oldids.ui_suid = SWAB16(value);
+ switch (flags & UFS_UID_MASK) {
+ case UFS_UID_EFT:
+ inode->ui_u3.ui_sun.ui_uid = SWAB32(value);
+ break;
+ case UFS_UID_44BSD:
+ inode->ui_u3.ui_44.ui_uid = SWAB32(value);
+ break;
+ }
+}
+
+#define ufs_get_inode_gid(inode) _ufs_get_inode_gid_(inode,flags,swab)
+static inline __u32 _ufs_get_inode_gid_(struct ufs_inode * inode,
+ unsigned flags, unsigned swab)
+{
switch (flags & UFS_UID_MASK) {
case UFS_UID_EFT:
return SWAB32(inode->ui_u3.ui_sun.ui_gid);
case UFS_UID_44BSD:
return SWAB32(inode->ui_u3.ui_44.ui_gid);
- case UFS_UID_OLD:
default:
return SWAB16(inode->ui_u1.oldids.ui_sgid);
}
}
-/*
- * macros used to avoid needless retyping
- */
-#define UCPI_UBH ((struct ufs_buffer_head *)ucpi)
-#define USPI_UBH ((struct ufs_buffer_head *)uspi)
+#define ufs_set_inode_gid(inode,value) _ufs_set_inode_gid_(inode,value,flags,swab)
+static inline void _ufs_set_inode_gid_(struct ufs_inode * inode, __u32 value,
+ unsigned flags, unsigned swab)
+{
+ inode->ui_u1.oldids.ui_sgid = SWAB16(value);
+ switch (flags & UFS_UID_MASK) {
+ case UFS_UID_EFT:
+ inode->ui_u3.ui_sun.ui_gid = SWAB32(value);
+ break;
+ case UFS_UID_44BSD:
+ inode->ui_u3.ui_44.ui_gid = SWAB32(value);
+ break;
+ }
+}
+
+
/*
* These functions manipulate ufs buffers
*/
#define ubh_bread(dev,fragment,size) _ubh_bread_(uspi,dev,fragment,size)
extern struct ufs_buffer_head * _ubh_bread_(struct ufs_sb_private_info *, kdev_t, unsigned, unsigned);
-#define ubh_bread2(dev,fragment,size) _ubh_bread2_(uspi,dev,fragment,size)
-extern struct ufs_buffer_head * _ubh_bread2_(struct ufs_sb_private_info *, kdev_t, unsigned, unsigned);
+extern struct ufs_buffer_head * ubh_bread_uspi(struct ufs_sb_private_info *, kdev_t, unsigned, unsigned);
extern void ubh_brelse (struct ufs_buffer_head *);
-extern void ubh_brelse2 (struct ufs_buffer_head *);
+extern void ubh_brelse_uspi (struct ufs_sb_private_info *);
extern void ubh_mark_buffer_dirty (struct ufs_buffer_head *, int);
extern void ubh_mark_buffer_uptodate (struct ufs_buffer_head *, int);
extern void ubh_ll_rw_block (int, unsigned, struct ufs_buffer_head **);
@@ -98,6 +191,8 @@ 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);
+
+
/*
* macros to get important structures from ufs_buffer_head
*/
@@ -115,25 +210,29 @@ extern void _ubh_memcpyubh_(struct ufs_sb_private_info *, struct ufs_buffer_head
#define ubh_get_ucg(ubh) \
((struct ufs_cylinder_group *)((ubh)->bh[0]->b_data))
+
/*
* Extract byte from ufs_buffer_head
* Extract the bits for a block from a map inside ufs_buffer_head
*/
#define ubh_get_addr8(ubh,begin) \
- ((u8*)(ubh)->bh[(begin) >> uspi->s_fshift]->b_data + ((begin) & ~uspi->s_fmask))
+ ((u8*)(ubh)->bh[(begin) >> uspi->s_fshift]->b_data + \
+ ((begin) & ~uspi->s_fmask))
#define ubh_get_addr16(ubh,begin) \
- (((u16*)((ubh)->bh[(begin) >> (uspi->s_fshift-1)]->b_data)) + ((begin) & (uspi->fsize>>1) - 1)))
+ (((u16*)((ubh)->bh[(begin) >> (uspi->s_fshift-1)]->b_data)) + \
+ ((begin) & (uspi->fsize>>1) - 1)))
#define ubh_get_addr32(ubh,begin) \
- (((u32*)((ubh)->bh[(begin) >> (BLOCK_SIZE_BITS-2)]->b_data)) + \
- ((begin) & ((BLOCK_SIZE>>2) - 1)))
+ (((u32*)((ubh)->bh[(begin) >> (uspi->s_fshift-2)]->b_data)) + \
+ ((begin) & ((uspi->s_fsize>>2) - 1)))
#define ubh_get_addr ubh_get_addr8
#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
*/
@@ -188,45 +287,90 @@ extern void _ubh_memcpyubh_(struct ufs_sb_private_info *, struct ufs_buffer_head
#define ubh_isclr(ubh,begin,bit) (!ubh_isset(ubh,begin,bit))
-#define ubh_find_first_zero_bit(ubh,begin,size) \
- _ubh_find_next_zero_bit_(uspi,ubh,begin,size,0)
-#define ubh_find_next_zero_bit(ubh,begin,size,offset) \
- _ubh_find_next_zero_bit_(uspi,ubh,begin,size,offset)
+#define ubh_find_first_zero_bit(ubh,begin,size) _ubh_find_next_zero_bit_(uspi,ubh,begin,size,0)
+#define ubh_find_next_zero_bit(ubh,begin,size,offset) _ubh_find_next_zero_bit_(uspi,ubh,begin,size,offset)
static inline unsigned _ubh_find_next_zero_bit_(
struct ufs_sb_private_info * uspi, struct ufs_buffer_head * ubh,
unsigned begin, unsigned size, unsigned offset)
{
- unsigned base, rest;
+ unsigned base, count, pos;
+ size -= offset;
begin <<= 3;
- size += begin;
offset += begin;
- base = offset >> (uspi->s_fshift + 3);
- offset &= ((uspi->s_fsize << 3) - 1);
+ base = offset >> uspi->s_bpfshift;
+ offset &= uspi->s_bpfmask;
for (;;) {
- rest = min (size, uspi->s_fsize << 3);
- size -= rest;
- offset = ext2_find_next_zero_bit (ubh->bh[base]->b_data, rest, offset);
- if (offset < rest || !size)
+ count = min (size + offset, uspi->s_bpf);
+ size -= count - offset;
+ pos = ext2_find_next_zero_bit (ubh->bh[base]->b_data, count, offset);
+ if (pos < count || !size)
break;
base++;
offset = 0;
}
- return (base << (uspi->s_fshift + 3)) + offset - begin;
+ return (base << uspi->s_bpfshift) + pos - begin;
+}
+
+static inline unsigned find_last_zero_bit (unsigned char * bitmap,
+ unsigned size, unsigned offset)
+{
+ unsigned bit, i;
+ unsigned char * mapp;
+ unsigned char map;
+
+ mapp = bitmap + (size >> 3);
+ map = *mapp--;
+ bit = 1 << (size & 7);
+ for (i = size; i > offset; i--) {
+ if ((map & bit) == 0)
+ break;
+ if ((i & 7) != 0) {
+ bit >>= 1;
+ } else {
+ map = *mapp--;
+ bit = 1 << 7;
+ }
+ }
+ return i;
+}
+
+#define ubh_find_last_zero_bit(ubh,begin,size,offset) _ubh_find_last_zero_bit_(uspi,ubh,begin,size,offset)
+static inline unsigned _ubh_find_last_zero_bit_(
+ struct ufs_sb_private_info * uspi, struct ufs_buffer_head * ubh,
+ unsigned begin, unsigned start, unsigned end)
+{
+ unsigned base, count, pos, size;
+
+ size = start - end;
+ begin <<= 3;
+ start += begin;
+ base = start >> uspi->s_bpfshift;
+ start &= uspi->s_bpfmask;
+ for (;;) {
+ count = min (size + (uspi->s_bpf - start), uspi->s_bpf)
+ - (uspi->s_bpf - start);
+ size -= count;
+ pos = find_last_zero_bit (ubh->bh[base]->b_data,
+ start, start - count);
+ if (pos > start - count || !size)
+ break;
+ base--;
+ start = uspi->s_bpf;
+ }
+ return (base << uspi->s_bpfshift) + pos - begin;
}
-#define ubh_isblockclear(ubh,begin,block) \
- (!_ubh_isblockset_(uspi,ubh,begin,block))
-#define ubh_isblockset(ubh,begin,block) \
- _ubh_isblockset_(uspi,ubh,begin,block)
+#define ubh_isblockclear(ubh,begin,block) (!_ubh_isblockset_(uspi,ubh,begin,block))
+#define ubh_isblockset(ubh,begin,block) _ubh_isblockset_(uspi,ubh,begin,block)
static inline int _ubh_isblockset_(struct ufs_sb_private_info * uspi,
struct ufs_buffer_head * ubh, unsigned begin, unsigned block)
{
switch (uspi->s_fpb) {
case 8:
- return (*ubh_get_addr (ubh, begin + block) == 0xff);
+ return (*ubh_get_addr (ubh, begin + block) == 0xff);
case 4:
return (*ubh_get_addr (ubh, begin + (block >> 1)) == (0x0f << ((block & 0x01) << 2)));
case 2:
@@ -243,8 +387,8 @@ static inline void _ubh_clrblock_(struct ufs_sb_private_info * uspi,
{
switch (uspi->s_fpb) {
case 8:
- *ubh_get_addr (ubh, begin + block) = 0x00;
- return;
+ *ubh_get_addr (ubh, begin + block) = 0x00;
+ return;
case 4:
*ubh_get_addr (ubh, begin + (block >> 1)) &= ~(0x0f << ((block & 0x01) << 2));
return;
@@ -263,8 +407,8 @@ static inline void _ubh_setblock_(struct ufs_sb_private_info * uspi,
{
switch (uspi->s_fpb) {
case 8:
- *ubh_get_addr(ubh, begin + block) = 0xff;
- return;
+ *ubh_get_addr(ubh, begin + block) = 0xff;
+ return;
case 4:
*ubh_get_addr(ubh, begin + (block >> 1)) |= (0x0f << ((block & 0x01) << 2));
return;
@@ -301,8 +445,7 @@ static inline void ufs_fragacct (struct super_block * sb, unsigned blockmap,
ADD_SWAB32(fraglist[fragsize], cnt);
}
-#define ubh_scanc(ubh,begin,size,table,mask) \
- _ubh_scanc_(uspi,ubh,begin,size,table,mask)
+#define ubh_scanc(ubh,begin,size,table,mask) _ubh_scanc_(uspi,ubh,begin,size,table,mask)
static inline unsigned _ubh_scanc_(struct ufs_sb_private_info * uspi, struct ufs_buffer_head * ubh,
unsigned begin, unsigned size, unsigned char * table, unsigned char mask)
{