1#ifndef AMIGAFFS_H 2#define AMIGAFFS_H 3 4#include <linux/types.h> 5#include <linux/locks.h> 6 7#include <asm/byteorder.h> 8 9/* AmigaOS allows file names with up to 30 characters length. 10 * Names longer than that will be silently truncated. If you 11 * want to disallow this, comment out the following #define. 12 * Creating filesystem objects with longer names will then 13 * result in an error (ENAMETOOLONG). 14 */ 15/*#define AFFS_NO_TRUNCATE */ 16 17/* Ugly macros make the code more pretty. */ 18 19#define GET_END_PTR(st,p,sz) ((st *)((char *)(p)+((sz)-sizeof(st)))) 20#define AFFS_GET_HASHENTRY(data,hashkey) be32_to_cpu(((struct dir_front *)data)->hashtable[hashkey]) 21#define AFFS_BLOCK(sb, bh, blk) (AFFS_HEAD(bh)->table[(sb)->u.affs_sb.s_hashsize-1-(blk)]) 22 23static inline void 24affs_set_blocksize(struct super_block *sb, int size) 25{ 26 set_blocksize(sb->s_dev, size); 27 sb->s_blocksize = size; 28} 29static inline struct buffer_head * 30affs_bread(struct super_block *sb, int block) 31{ 32 pr_debug(KERN_DEBUG "affs_bread: %d\n", block); 33 if (block >= AFFS_SB->s_reserved && block < AFFS_SB->s_partition_size) 34 return sb_bread(sb, block); 35 return NULL; 36} 37static inline struct buffer_head * 38affs_getblk(struct super_block *sb, int block) 39{ 40 pr_debug(KERN_DEBUG "affs_getblk: %d\n", block); 41 if (block >= AFFS_SB->s_reserved && block < AFFS_SB->s_partition_size) 42 return sb_getblk(sb, block); 43 return NULL; 44} 45static inline struct buffer_head * 46affs_getzeroblk(struct super_block *sb, int block) 47{ 48 struct buffer_head *bh; 49 pr_debug(KERN_DEBUG "affs_getzeroblk: %d\n", block); 50 if (block >= AFFS_SB->s_reserved && block < AFFS_SB->s_partition_size) { 51 bh = sb_getblk(sb, block); 52 lock_buffer(bh); 53 memset(bh->b_data, 0 , sb->s_blocksize); 54 mark_buffer_uptodate(bh, 1); 55 unlock_buffer(bh); 56 return bh; 57 } 58 return NULL; 59} 60static inline struct buffer_head * 61affs_getemptyblk(struct super_block *sb, int block) 62{ 63 struct buffer_head *bh; 64 pr_debug(KERN_DEBUG "affs_getemptyblk: %d\n", block); 65 if (block >= AFFS_SB->s_reserved && block < AFFS_SB->s_partition_size) { 66 bh = sb_getblk(sb, block); 67 wait_on_buffer(bh); 68 mark_buffer_uptodate(bh, 1); 69 return bh; 70 } 71 return NULL; 72} 73static inline void 74affs_brelse(struct buffer_head *bh) 75{ 76 if (bh) 77 pr_debug(KERN_DEBUG "affs_brelse: %ld\n", bh->b_blocknr); 78 brelse(bh); 79} 80 81static inline void 82affs_adjust_checksum(struct buffer_head *bh, u32 val) 83{ 84 u32 tmp = be32_to_cpu(((u32 *)bh->b_data)[5]); 85 ((u32 *)bh->b_data)[5] = cpu_to_be32(tmp - val); 86} 87static inline void 88affs_adjust_bitmapchecksum(struct buffer_head *bh, u32 val) 89{ 90 u32 tmp = be32_to_cpu(((u32 *)bh->b_data)[0]); 91 ((u32 *)bh->b_data)[0] = cpu_to_be32(tmp - val); 92} 93 94static inline void 95affs_lock_link(struct inode *inode) 96{ 97 down(&AFFS_INODE->i_link_lock); 98} 99static inline void 100affs_unlock_link(struct inode *inode) 101{ 102 up(&AFFS_INODE->i_link_lock); 103} 104static inline void 105affs_lock_dir(struct inode *inode) 106{ 107 down(&AFFS_INODE->i_hash_lock); 108} 109static inline void 110affs_unlock_dir(struct inode *inode) 111{ 112 up(&AFFS_INODE->i_hash_lock); 113} 114static inline void 115affs_lock_ext(struct inode *inode) 116{ 117 down(&AFFS_INODE->i_ext_lock); 118} 119static inline void 120affs_unlock_ext(struct inode *inode) 121{ 122 up(&AFFS_INODE->i_ext_lock); 123} 124 125#ifdef __LITTLE_ENDIAN 126#define BO_EXBITS 0x18UL 127#elif defined(__BIG_ENDIAN) 128#define BO_EXBITS 0x00UL 129#else 130#error Endianness must be known for affs to work. 131#endif 132 133#define FS_OFS 0x444F5300 134#define FS_FFS 0x444F5301 135#define FS_INTLOFS 0x444F5302 136#define FS_INTLFFS 0x444F5303 137#define FS_DCOFS 0x444F5304 138#define FS_DCFFS 0x444F5305 139#define MUFS_FS 0x6d754653 /* 'muFS' */ 140#define MUFS_OFS 0x6d754600 /* 'muF\0' */ 141#define MUFS_FFS 0x6d754601 /* 'muF\1' */ 142#define MUFS_INTLOFS 0x6d754602 /* 'muF\2' */ 143#define MUFS_INTLFFS 0x6d754603 /* 'muF\3' */ 144#define MUFS_DCOFS 0x6d754604 /* 'muF\4' */ 145#define MUFS_DCFFS 0x6d754605 /* 'muF\5' */ 146 147#define T_SHORT 2 148#define T_LIST 16 149#define T_DATA 8 150 151#define ST_LINKFILE -4 152#define ST_FILE -3 153#define ST_ROOT 1 154#define ST_USERDIR 2 155#define ST_SOFTLINK 3 156#define ST_LINKDIR 4 157 158#define AFFS_ROOT_BMAPS 25 159 160#define AFFS_HEAD(bh) ((struct affs_head *)(bh)->b_data) 161#define AFFS_TAIL(sb, bh) ((struct affs_tail *)((bh)->b_data+(sb)->s_blocksize-sizeof(struct affs_tail))) 162#define AFFS_ROOT_HEAD(bh) ((struct affs_root_head *)(bh)->b_data) 163#define AFFS_ROOT_TAIL(sb, bh) ((struct affs_root_tail *)((bh)->b_data+(sb)->s_blocksize-sizeof(struct affs_root_tail))) 164#define AFFS_DATA_HEAD(bh) ((struct affs_data_head *)(bh)->b_data) 165#define AFFS_DATA(bh) (((struct affs_data_head *)(bh)->b_data)->data) 166 167struct affs_date { 168 u32 days; 169 u32 mins; 170 u32 ticks; 171}; 172 173struct affs_short_date { 174 u16 days; 175 u16 mins; 176 u16 ticks; 177}; 178 179struct affs_root_head { 180 u32 ptype; 181 u32 spare1; 182 u32 spare2; 183 u32 hash_size; 184 u32 spare3; 185 u32 checksum; 186 u32 hashtable[1]; 187}; 188 189struct affs_root_tail { 190 u32 bm_flag; 191 u32 bm_blk[AFFS_ROOT_BMAPS]; 192 u32 bm_ext; 193 struct affs_date root_change; 194 u8 disk_name[32]; 195 u32 spare1; 196 u32 spare2; 197 struct affs_date disk_change; 198 struct affs_date disk_create; 199 u32 spare3; 200 u32 spare4; 201 u32 dcache; 202 u32 stype; 203}; 204 205struct affs_head { 206 u32 ptype; 207 u32 key; 208 u32 block_count; 209 u32 spare1; 210 u32 first_data; 211 u32 checksum; 212 u32 table[1]; 213}; 214 215struct affs_tail { 216 u32 spare1; 217 u16 uid; 218 u16 gid; 219 u32 protect; 220 u32 size; 221 u8 comment[92]; 222 struct affs_date change; 223 u8 name[32]; 224 u32 spare2; 225 u32 original; 226 u32 link_chain; 227 u32 spare[5]; 228 u32 hash_chain; 229 u32 parent; 230 u32 extension; 231 u32 stype; 232}; 233 234struct slink_front 235{ 236 u32 ptype; 237 u32 key; 238 u32 spare1[3]; 239 u32 checksum; 240 u8 symname[1]; /* depends on block size */ 241}; 242 243struct affs_data_head 244{ 245 u32 ptype; 246 u32 key; 247 u32 sequence; 248 u32 size; 249 u32 next; 250 u32 checksum; 251 u8 data[1]; /* depends on block size */ 252}; 253 254/* Permission bits */ 255 256#define FIBF_OTR_READ 0x8000 257#define FIBF_OTR_WRITE 0x4000 258#define FIBF_OTR_EXECUTE 0x2000 259#define FIBF_OTR_DELETE 0x1000 260#define FIBF_GRP_READ 0x0800 261#define FIBF_GRP_WRITE 0x0400 262#define FIBF_GRP_EXECUTE 0x0200 263#define FIBF_GRP_DELETE 0x0100 264 265#define FIBF_HIDDEN 0x0080 266#define FIBF_SCRIPT 0x0040 267#define FIBF_PURE 0x0020 /* no use under linux */ 268#define FIBF_ARCHIVED 0x0010 /* never set, always cleared on write */ 269#define FIBF_NOREAD 0x0008 /* 0 means allowed */ 270#define FIBF_NOWRITE 0x0004 /* 0 means allowed */ 271#define FIBF_NOEXECUTE 0x0002 /* 0 means allowed, ignored under linux */ 272#define FIBF_NODELETE 0x0001 /* 0 means allowed */ 273 274#define FIBF_OWNER 0x000F /* Bits pertaining to owner */ 275#define FIBF_MASK 0xEE0E /* Bits modified by Linux */ 276 277#endif 278