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