diff options
Diffstat (limited to 'fs/ufs/util.h')
-rw-r--r-- | fs/ufs/util.h | 263 |
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) { |