Root/
1 | /* |
2 | * linux/fs/ufs/util.h |
3 | * |
4 | * Copyright (C) 1998 |
5 | * Daniel Pirkl <daniel.pirkl@email.cz> |
6 | * Charles University, Faculty of Mathematics and Physics |
7 | */ |
8 | |
9 | #include <linux/buffer_head.h> |
10 | #include <linux/fs.h> |
11 | #include "swab.h" |
12 | |
13 | |
14 | /* |
15 | * some useful macros |
16 | */ |
17 | #define in_range(b,first,len) ((b)>=(first)&&(b)<(first)+(len)) |
18 | |
19 | /* |
20 | * functions used for retyping |
21 | */ |
22 | static inline struct ufs_buffer_head *UCPI_UBH(struct ufs_cg_private_info *cpi) |
23 | { |
24 | return &cpi->c_ubh; |
25 | } |
26 | static inline struct ufs_buffer_head *USPI_UBH(struct ufs_sb_private_info *spi) |
27 | { |
28 | return &spi->s_ubh; |
29 | } |
30 | |
31 | |
32 | |
33 | /* |
34 | * macros used for accessing structures |
35 | */ |
36 | static inline s32 |
37 | ufs_get_fs_state(struct super_block *sb, struct ufs_super_block_first *usb1, |
38 | struct ufs_super_block_third *usb3) |
39 | { |
40 | switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { |
41 | case UFS_ST_SUNOS: |
42 | if (fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT) |
43 | return fs32_to_cpu(sb, usb1->fs_u0.fs_sun.fs_state); |
44 | /* Fall Through to UFS_ST_SUN */ |
45 | case UFS_ST_SUN: |
46 | return fs32_to_cpu(sb, usb3->fs_un2.fs_sun.fs_state); |
47 | case UFS_ST_SUNx86: |
48 | return fs32_to_cpu(sb, usb1->fs_u1.fs_sunx86.fs_state); |
49 | case UFS_ST_44BSD: |
50 | default: |
51 | return fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_state); |
52 | } |
53 | } |
54 | |
55 | static inline void |
56 | ufs_set_fs_state(struct super_block *sb, struct ufs_super_block_first *usb1, |
57 | struct ufs_super_block_third *usb3, s32 value) |
58 | { |
59 | switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { |
60 | case UFS_ST_SUNOS: |
61 | if (fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT) { |
62 | usb1->fs_u0.fs_sun.fs_state = cpu_to_fs32(sb, value); |
63 | break; |
64 | } |
65 | /* Fall Through to UFS_ST_SUN */ |
66 | case UFS_ST_SUN: |
67 | usb3->fs_un2.fs_sun.fs_state = cpu_to_fs32(sb, value); |
68 | break; |
69 | case UFS_ST_SUNx86: |
70 | usb1->fs_u1.fs_sunx86.fs_state = cpu_to_fs32(sb, value); |
71 | break; |
72 | case UFS_ST_44BSD: |
73 | usb3->fs_un2.fs_44.fs_state = cpu_to_fs32(sb, value); |
74 | break; |
75 | } |
76 | } |
77 | |
78 | static inline u32 |
79 | ufs_get_fs_npsect(struct super_block *sb, struct ufs_super_block_first *usb1, |
80 | struct ufs_super_block_third *usb3) |
81 | { |
82 | if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86) |
83 | return fs32_to_cpu(sb, usb3->fs_un2.fs_sunx86.fs_npsect); |
84 | else |
85 | return fs32_to_cpu(sb, usb1->fs_u1.fs_sun.fs_npsect); |
86 | } |
87 | |
88 | static inline u64 |
89 | ufs_get_fs_qbmask(struct super_block *sb, struct ufs_super_block_third *usb3) |
90 | { |
91 | __fs64 tmp; |
92 | |
93 | switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { |
94 | case UFS_ST_SUNOS: |
95 | case UFS_ST_SUN: |
96 | ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sun.fs_qbmask[0]; |
97 | ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sun.fs_qbmask[1]; |
98 | break; |
99 | case UFS_ST_SUNx86: |
100 | ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sunx86.fs_qbmask[0]; |
101 | ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sunx86.fs_qbmask[1]; |
102 | break; |
103 | case UFS_ST_44BSD: |
104 | ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_44.fs_qbmask[0]; |
105 | ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_44.fs_qbmask[1]; |
106 | break; |
107 | } |
108 | |
109 | return fs64_to_cpu(sb, tmp); |
110 | } |
111 | |
112 | static inline u64 |
113 | ufs_get_fs_qfmask(struct super_block *sb, struct ufs_super_block_third *usb3) |
114 | { |
115 | __fs64 tmp; |
116 | |
117 | switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { |
118 | case UFS_ST_SUNOS: |
119 | case UFS_ST_SUN: |
120 | ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sun.fs_qfmask[0]; |
121 | ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sun.fs_qfmask[1]; |
122 | break; |
123 | case UFS_ST_SUNx86: |
124 | ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sunx86.fs_qfmask[0]; |
125 | ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sunx86.fs_qfmask[1]; |
126 | break; |
127 | case UFS_ST_44BSD: |
128 | ((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_44.fs_qfmask[0]; |
129 | ((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_44.fs_qfmask[1]; |
130 | break; |
131 | } |
132 | |
133 | return fs64_to_cpu(sb, tmp); |
134 | } |
135 | |
136 | static inline u16 |
137 | ufs_get_de_namlen(struct super_block *sb, struct ufs_dir_entry *de) |
138 | { |
139 | if ((UFS_SB(sb)->s_flags & UFS_DE_MASK) == UFS_DE_OLD) |
140 | return fs16_to_cpu(sb, de->d_u.d_namlen); |
141 | else |
142 | return de->d_u.d_44.d_namlen; /* XXX this seems wrong */ |
143 | } |
144 | |
145 | static inline void |
146 | ufs_set_de_namlen(struct super_block *sb, struct ufs_dir_entry *de, u16 value) |
147 | { |
148 | if ((UFS_SB(sb)->s_flags & UFS_DE_MASK) == UFS_DE_OLD) |
149 | de->d_u.d_namlen = cpu_to_fs16(sb, value); |
150 | else |
151 | de->d_u.d_44.d_namlen = value; /* XXX this seems wrong */ |
152 | } |
153 | |
154 | static inline void |
155 | ufs_set_de_type(struct super_block *sb, struct ufs_dir_entry *de, int mode) |
156 | { |
157 | if ((UFS_SB(sb)->s_flags & UFS_DE_MASK) != UFS_DE_44BSD) |
158 | return; |
159 | |
160 | /* |
161 | * TODO turn this into a table lookup |
162 | */ |
163 | switch (mode & S_IFMT) { |
164 | case S_IFSOCK: |
165 | de->d_u.d_44.d_type = DT_SOCK; |
166 | break; |
167 | case S_IFLNK: |
168 | de->d_u.d_44.d_type = DT_LNK; |
169 | break; |
170 | case S_IFREG: |
171 | de->d_u.d_44.d_type = DT_REG; |
172 | break; |
173 | case S_IFBLK: |
174 | de->d_u.d_44.d_type = DT_BLK; |
175 | break; |
176 | case S_IFDIR: |
177 | de->d_u.d_44.d_type = DT_DIR; |
178 | break; |
179 | case S_IFCHR: |
180 | de->d_u.d_44.d_type = DT_CHR; |
181 | break; |
182 | case S_IFIFO: |
183 | de->d_u.d_44.d_type = DT_FIFO; |
184 | break; |
185 | default: |
186 | de->d_u.d_44.d_type = DT_UNKNOWN; |
187 | } |
188 | } |
189 | |
190 | static inline u32 |
191 | ufs_get_inode_uid(struct super_block *sb, struct ufs_inode *inode) |
192 | { |
193 | switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) { |
194 | case UFS_UID_44BSD: |
195 | return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_uid); |
196 | case UFS_UID_EFT: |
197 | if (inode->ui_u1.oldids.ui_suid == 0xFFFF) |
198 | return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_uid); |
199 | /* Fall through */ |
200 | default: |
201 | return fs16_to_cpu(sb, inode->ui_u1.oldids.ui_suid); |
202 | } |
203 | } |
204 | |
205 | static inline void |
206 | ufs_set_inode_uid(struct super_block *sb, struct ufs_inode *inode, u32 value) |
207 | { |
208 | switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) { |
209 | case UFS_UID_44BSD: |
210 | inode->ui_u3.ui_44.ui_uid = cpu_to_fs32(sb, value); |
211 | inode->ui_u1.oldids.ui_suid = cpu_to_fs16(sb, value); |
212 | break; |
213 | case UFS_UID_EFT: |
214 | inode->ui_u3.ui_sun.ui_uid = cpu_to_fs32(sb, value); |
215 | if (value > 0xFFFF) |
216 | value = 0xFFFF; |
217 | /* Fall through */ |
218 | default: |
219 | inode->ui_u1.oldids.ui_suid = cpu_to_fs16(sb, value); |
220 | break; |
221 | } |
222 | } |
223 | |
224 | static inline u32 |
225 | ufs_get_inode_gid(struct super_block *sb, struct ufs_inode *inode) |
226 | { |
227 | switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) { |
228 | case UFS_UID_44BSD: |
229 | return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_gid); |
230 | case UFS_UID_EFT: |
231 | if (inode->ui_u1.oldids.ui_suid == 0xFFFF) |
232 | return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_gid); |
233 | /* Fall through */ |
234 | default: |
235 | return fs16_to_cpu(sb, inode->ui_u1.oldids.ui_sgid); |
236 | } |
237 | } |
238 | |
239 | static inline void |
240 | ufs_set_inode_gid(struct super_block *sb, struct ufs_inode *inode, u32 value) |
241 | { |
242 | switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) { |
243 | case UFS_UID_44BSD: |
244 | inode->ui_u3.ui_44.ui_gid = cpu_to_fs32(sb, value); |
245 | inode->ui_u1.oldids.ui_sgid = cpu_to_fs16(sb, value); |
246 | break; |
247 | case UFS_UID_EFT: |
248 | inode->ui_u3.ui_sun.ui_gid = cpu_to_fs32(sb, value); |
249 | if (value > 0xFFFF) |
250 | value = 0xFFFF; |
251 | /* Fall through */ |
252 | default: |
253 | inode->ui_u1.oldids.ui_sgid = cpu_to_fs16(sb, value); |
254 | break; |
255 | } |
256 | } |
257 | |
258 | extern dev_t ufs_get_inode_dev(struct super_block *, struct ufs_inode_info *); |
259 | extern void ufs_set_inode_dev(struct super_block *, struct ufs_inode_info *, dev_t); |
260 | extern int __ufs_write_begin(struct file *file, struct address_space *mapping, |
261 | loff_t pos, unsigned len, unsigned flags, |
262 | struct page **pagep, void **fsdata); |
263 | |
264 | /* |
265 | * These functions manipulate ufs buffers |
266 | */ |
267 | #define ubh_bread(sb,fragment,size) _ubh_bread_(uspi,sb,fragment,size) |
268 | extern struct ufs_buffer_head * _ubh_bread_(struct ufs_sb_private_info *, struct super_block *, u64 , u64); |
269 | extern struct ufs_buffer_head * ubh_bread_uspi(struct ufs_sb_private_info *, struct super_block *, u64, u64); |
270 | extern void ubh_brelse (struct ufs_buffer_head *); |
271 | extern void ubh_brelse_uspi (struct ufs_sb_private_info *); |
272 | extern void ubh_mark_buffer_dirty (struct ufs_buffer_head *); |
273 | extern void ubh_mark_buffer_uptodate (struct ufs_buffer_head *, int); |
274 | extern void ubh_ll_rw_block(int, struct ufs_buffer_head *); |
275 | extern void ubh_wait_on_buffer (struct ufs_buffer_head *); |
276 | extern void ubh_bforget (struct ufs_buffer_head *); |
277 | extern int ubh_buffer_dirty (struct ufs_buffer_head *); |
278 | #define ubh_ubhcpymem(mem,ubh,size) _ubh_ubhcpymem_(uspi,mem,ubh,size) |
279 | extern void _ubh_ubhcpymem_(struct ufs_sb_private_info *, unsigned char *, struct ufs_buffer_head *, unsigned); |
280 | #define ubh_memcpyubh(ubh,mem,size) _ubh_memcpyubh_(uspi,ubh,mem,size) |
281 | extern void _ubh_memcpyubh_(struct ufs_sb_private_info *, struct ufs_buffer_head *, unsigned char *, unsigned); |
282 | |
283 | /* This functions works with cache pages*/ |
284 | extern struct page *ufs_get_locked_page(struct address_space *mapping, |
285 | pgoff_t index); |
286 | static inline void ufs_put_locked_page(struct page *page) |
287 | { |
288 | unlock_page(page); |
289 | page_cache_release(page); |
290 | } |
291 | |
292 | |
293 | /* |
294 | * macros and inline function to get important structures from ufs_sb_private_info |
295 | */ |
296 | |
297 | static inline void *get_usb_offset(struct ufs_sb_private_info *uspi, |
298 | unsigned int offset) |
299 | { |
300 | unsigned int index; |
301 | |
302 | index = offset >> uspi->s_fshift; |
303 | offset &= ~uspi->s_fmask; |
304 | return uspi->s_ubh.bh[index]->b_data + offset; |
305 | } |
306 | |
307 | #define ubh_get_usb_first(uspi) \ |
308 | ((struct ufs_super_block_first *)get_usb_offset((uspi), 0)) |
309 | |
310 | #define ubh_get_usb_second(uspi) \ |
311 | ((struct ufs_super_block_second *)get_usb_offset((uspi), UFS_SECTOR_SIZE)) |
312 | |
313 | #define ubh_get_usb_third(uspi) \ |
314 | ((struct ufs_super_block_third *)get_usb_offset((uspi), 2*UFS_SECTOR_SIZE)) |
315 | |
316 | |
317 | #define ubh_get_ucg(ubh) \ |
318 | ((struct ufs_cylinder_group *)((ubh)->bh[0]->b_data)) |
319 | |
320 | |
321 | /* |
322 | * Extract byte from ufs_buffer_head |
323 | * Extract the bits for a block from a map inside ufs_buffer_head |
324 | */ |
325 | #define ubh_get_addr8(ubh,begin) \ |
326 | ((u8*)(ubh)->bh[(begin) >> uspi->s_fshift]->b_data + \ |
327 | ((begin) & ~uspi->s_fmask)) |
328 | |
329 | #define ubh_get_addr16(ubh,begin) \ |
330 | (((__fs16*)((ubh)->bh[(begin) >> (uspi->s_fshift-1)]->b_data)) + \ |
331 | ((begin) & ((uspi->fsize>>1) - 1))) |
332 | |
333 | #define ubh_get_addr32(ubh,begin) \ |
334 | (((__fs32*)((ubh)->bh[(begin) >> (uspi->s_fshift-2)]->b_data)) + \ |
335 | ((begin) & ((uspi->s_fsize>>2) - 1))) |
336 | |
337 | #define ubh_get_addr64(ubh,begin) \ |
338 | (((__fs64*)((ubh)->bh[(begin) >> (uspi->s_fshift-3)]->b_data)) + \ |
339 | ((begin) & ((uspi->s_fsize>>3) - 1))) |
340 | |
341 | #define ubh_get_addr ubh_get_addr8 |
342 | |
343 | static inline void *ubh_get_data_ptr(struct ufs_sb_private_info *uspi, |
344 | struct ufs_buffer_head *ubh, |
345 | u64 blk) |
346 | { |
347 | if (uspi->fs_magic == UFS2_MAGIC) |
348 | return ubh_get_addr64(ubh, blk); |
349 | else |
350 | return ubh_get_addr32(ubh, blk); |
351 | } |
352 | |
353 | #define ubh_blkmap(ubh,begin,bit) \ |
354 | ((*ubh_get_addr(ubh, (begin) + ((bit) >> 3)) >> ((bit) & 7)) & (0xff >> (UFS_MAXFRAG - uspi->s_fpb))) |
355 | |
356 | /* |
357 | * Determine the number of available frags given a |
358 | * percentage to hold in reserve. |
359 | */ |
360 | static inline u64 |
361 | ufs_freespace(struct ufs_sb_private_info *uspi, int percentreserved) |
362 | { |
363 | return ufs_blkstofrags(uspi->cs_total.cs_nbfree) + |
364 | uspi->cs_total.cs_nffree - |
365 | (uspi->s_dsize * (percentreserved) / 100); |
366 | } |
367 | |
368 | /* |
369 | * Macros to access cylinder group array structures |
370 | */ |
371 | #define ubh_cg_blktot(ucpi,cylno) \ |
372 | (*((__fs32*)ubh_get_addr(UCPI_UBH(ucpi), (ucpi)->c_btotoff + ((cylno) << 2)))) |
373 | |
374 | #define ubh_cg_blks(ucpi,cylno,rpos) \ |
375 | (*((__fs16*)ubh_get_addr(UCPI_UBH(ucpi), \ |
376 | (ucpi)->c_boff + (((cylno) * uspi->s_nrpos + (rpos)) << 1 )))) |
377 | |
378 | /* |
379 | * Bitmap operations |
380 | * These functions work like classical bitmap operations. |
381 | * The difference is that we don't have the whole bitmap |
382 | * in one contiguous chunk of memory, but in several buffers. |
383 | * The parameters of each function are super_block, ufs_buffer_head and |
384 | * position of the beginning of the bitmap. |
385 | */ |
386 | #define ubh_setbit(ubh,begin,bit) \ |
387 | (*ubh_get_addr(ubh, (begin) + ((bit) >> 3)) |= (1 << ((bit) & 7))) |
388 | |
389 | #define ubh_clrbit(ubh,begin,bit) \ |
390 | (*ubh_get_addr (ubh, (begin) + ((bit) >> 3)) &= ~(1 << ((bit) & 7))) |
391 | |
392 | #define ubh_isset(ubh,begin,bit) \ |
393 | (*ubh_get_addr (ubh, (begin) + ((bit) >> 3)) & (1 << ((bit) & 7))) |
394 | |
395 | #define ubh_isclr(ubh,begin,bit) (!ubh_isset(ubh,begin,bit)) |
396 | |
397 | #define ubh_find_first_zero_bit(ubh,begin,size) _ubh_find_next_zero_bit_(uspi,ubh,begin,size,0) |
398 | |
399 | #define ubh_find_next_zero_bit(ubh,begin,size,offset) _ubh_find_next_zero_bit_(uspi,ubh,begin,size,offset) |
400 | static inline unsigned _ubh_find_next_zero_bit_( |
401 | struct ufs_sb_private_info * uspi, struct ufs_buffer_head * ubh, |
402 | unsigned begin, unsigned size, unsigned offset) |
403 | { |
404 | unsigned base, count, pos; |
405 | |
406 | size -= offset; |
407 | begin <<= 3; |
408 | offset += begin; |
409 | base = offset >> uspi->s_bpfshift; |
410 | offset &= uspi->s_bpfmask; |
411 | for (;;) { |
412 | count = min_t(unsigned int, size + offset, uspi->s_bpf); |
413 | size -= count - offset; |
414 | pos = ext2_find_next_zero_bit (ubh->bh[base]->b_data, count, offset); |
415 | if (pos < count || !size) |
416 | break; |
417 | base++; |
418 | offset = 0; |
419 | } |
420 | return (base << uspi->s_bpfshift) + pos - begin; |
421 | } |
422 | |
423 | static inline unsigned find_last_zero_bit (unsigned char * bitmap, |
424 | unsigned size, unsigned offset) |
425 | { |
426 | unsigned bit, i; |
427 | unsigned char * mapp; |
428 | unsigned char map; |
429 | |
430 | mapp = bitmap + (size >> 3); |
431 | map = *mapp--; |
432 | bit = 1 << (size & 7); |
433 | for (i = size; i > offset; i--) { |
434 | if ((map & bit) == 0) |
435 | break; |
436 | if ((i & 7) != 0) { |
437 | bit >>= 1; |
438 | } else { |
439 | map = *mapp--; |
440 | bit = 1 << 7; |
441 | } |
442 | } |
443 | return i; |
444 | } |
445 | |
446 | #define ubh_find_last_zero_bit(ubh,begin,size,offset) _ubh_find_last_zero_bit_(uspi,ubh,begin,size,offset) |
447 | static inline unsigned _ubh_find_last_zero_bit_( |
448 | struct ufs_sb_private_info * uspi, struct ufs_buffer_head * ubh, |
449 | unsigned begin, unsigned start, unsigned end) |
450 | { |
451 | unsigned base, count, pos, size; |
452 | |
453 | size = start - end; |
454 | begin <<= 3; |
455 | start += begin; |
456 | base = start >> uspi->s_bpfshift; |
457 | start &= uspi->s_bpfmask; |
458 | for (;;) { |
459 | count = min_t(unsigned int, |
460 | size + (uspi->s_bpf - start), uspi->s_bpf) |
461 | - (uspi->s_bpf - start); |
462 | size -= count; |
463 | pos = find_last_zero_bit (ubh->bh[base]->b_data, |
464 | start, start - count); |
465 | if (pos > start - count || !size) |
466 | break; |
467 | base--; |
468 | start = uspi->s_bpf; |
469 | } |
470 | return (base << uspi->s_bpfshift) + pos - begin; |
471 | } |
472 | |
473 | #define ubh_isblockclear(ubh,begin,block) (!_ubh_isblockset_(uspi,ubh,begin,block)) |
474 | |
475 | #define ubh_isblockset(ubh,begin,block) _ubh_isblockset_(uspi,ubh,begin,block) |
476 | static inline int _ubh_isblockset_(struct ufs_sb_private_info * uspi, |
477 | struct ufs_buffer_head * ubh, unsigned begin, unsigned block) |
478 | { |
479 | switch (uspi->s_fpb) { |
480 | case 8: |
481 | return (*ubh_get_addr (ubh, begin + block) == 0xff); |
482 | case 4: |
483 | return (*ubh_get_addr (ubh, begin + (block >> 1)) == (0x0f << ((block & 0x01) << 2))); |
484 | case 2: |
485 | return (*ubh_get_addr (ubh, begin + (block >> 2)) == (0x03 << ((block & 0x03) << 1))); |
486 | case 1: |
487 | return (*ubh_get_addr (ubh, begin + (block >> 3)) == (0x01 << (block & 0x07))); |
488 | } |
489 | return 0; |
490 | } |
491 | |
492 | #define ubh_clrblock(ubh,begin,block) _ubh_clrblock_(uspi,ubh,begin,block) |
493 | static inline void _ubh_clrblock_(struct ufs_sb_private_info * uspi, |
494 | struct ufs_buffer_head * ubh, unsigned begin, unsigned block) |
495 | { |
496 | switch (uspi->s_fpb) { |
497 | case 8: |
498 | *ubh_get_addr (ubh, begin + block) = 0x00; |
499 | return; |
500 | case 4: |
501 | *ubh_get_addr (ubh, begin + (block >> 1)) &= ~(0x0f << ((block & 0x01) << 2)); |
502 | return; |
503 | case 2: |
504 | *ubh_get_addr (ubh, begin + (block >> 2)) &= ~(0x03 << ((block & 0x03) << 1)); |
505 | return; |
506 | case 1: |
507 | *ubh_get_addr (ubh, begin + (block >> 3)) &= ~(0x01 << ((block & 0x07))); |
508 | return; |
509 | } |
510 | } |
511 | |
512 | #define ubh_setblock(ubh,begin,block) _ubh_setblock_(uspi,ubh,begin,block) |
513 | static inline void _ubh_setblock_(struct ufs_sb_private_info * uspi, |
514 | struct ufs_buffer_head * ubh, unsigned begin, unsigned block) |
515 | { |
516 | switch (uspi->s_fpb) { |
517 | case 8: |
518 | *ubh_get_addr(ubh, begin + block) = 0xff; |
519 | return; |
520 | case 4: |
521 | *ubh_get_addr(ubh, begin + (block >> 1)) |= (0x0f << ((block & 0x01) << 2)); |
522 | return; |
523 | case 2: |
524 | *ubh_get_addr(ubh, begin + (block >> 2)) |= (0x03 << ((block & 0x03) << 1)); |
525 | return; |
526 | case 1: |
527 | *ubh_get_addr(ubh, begin + (block >> 3)) |= (0x01 << ((block & 0x07))); |
528 | return; |
529 | } |
530 | } |
531 | |
532 | static inline void ufs_fragacct (struct super_block * sb, unsigned blockmap, |
533 | __fs32 * fraglist, int cnt) |
534 | { |
535 | struct ufs_sb_private_info * uspi; |
536 | unsigned fragsize, pos; |
537 | |
538 | uspi = UFS_SB(sb)->s_uspi; |
539 | |
540 | fragsize = 0; |
541 | for (pos = 0; pos < uspi->s_fpb; pos++) { |
542 | if (blockmap & (1 << pos)) { |
543 | fragsize++; |
544 | } |
545 | else if (fragsize > 0) { |
546 | fs32_add(sb, &fraglist[fragsize], cnt); |
547 | fragsize = 0; |
548 | } |
549 | } |
550 | if (fragsize > 0 && fragsize < uspi->s_fpb) |
551 | fs32_add(sb, &fraglist[fragsize], cnt); |
552 | } |
553 | |
554 | static inline void *ufs_get_direct_data_ptr(struct ufs_sb_private_info *uspi, |
555 | struct ufs_inode_info *ufsi, |
556 | unsigned blk) |
557 | { |
558 | BUG_ON(blk > UFS_TIND_BLOCK); |
559 | return uspi->fs_magic == UFS2_MAGIC ? |
560 | (void *)&ufsi->i_u1.u2_i_data[blk] : |
561 | (void *)&ufsi->i_u1.i_data[blk]; |
562 | } |
563 | |
564 | static inline u64 ufs_data_ptr_to_cpu(struct super_block *sb, void *p) |
565 | { |
566 | return UFS_SB(sb)->s_uspi->fs_magic == UFS2_MAGIC ? |
567 | fs64_to_cpu(sb, *(__fs64 *)p) : |
568 | fs32_to_cpu(sb, *(__fs32 *)p); |
569 | } |
570 | |
571 | static inline void ufs_cpu_to_data_ptr(struct super_block *sb, void *p, u64 val) |
572 | { |
573 | if (UFS_SB(sb)->s_uspi->fs_magic == UFS2_MAGIC) |
574 | *(__fs64 *)p = cpu_to_fs64(sb, val); |
575 | else |
576 | *(__fs32 *)p = cpu_to_fs32(sb, val); |
577 | } |
578 | |
579 | static inline void ufs_data_ptr_clear(struct ufs_sb_private_info *uspi, |
580 | void *p) |
581 | { |
582 | if (uspi->fs_magic == UFS2_MAGIC) |
583 | *(__fs64 *)p = 0; |
584 | else |
585 | *(__fs32 *)p = 0; |
586 | } |
587 | |
588 | static inline int ufs_is_data_ptr_zero(struct ufs_sb_private_info *uspi, |
589 | void *p) |
590 | { |
591 | if (uspi->fs_magic == UFS2_MAGIC) |
592 | return *(__fs64 *)p == 0; |
593 | else |
594 | return *(__fs32 *)p == 0; |
595 | } |
596 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9