at v2.6.13 257 lines 5.5 kB view raw
1/* 2 * linux/fs/ufs/util.c 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/string.h> 10#include <linux/slab.h> 11#include <linux/ufs_fs.h> 12#include <linux/buffer_head.h> 13 14#include "swab.h" 15#include "util.h" 16 17#undef UFS_UTILS_DEBUG 18 19#ifdef UFS_UTILS_DEBUG 20#define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x; 21#else 22#define UFSD(x) 23#endif 24 25 26struct ufs_buffer_head * _ubh_bread_ (struct ufs_sb_private_info * uspi, 27 struct super_block *sb, u64 fragment, u64 size) 28{ 29 struct ufs_buffer_head * ubh; 30 unsigned i, j ; 31 u64 count = 0; 32 if (size & ~uspi->s_fmask) 33 return NULL; 34 count = size >> uspi->s_fshift; 35 if (count > UFS_MAXFRAG) 36 return NULL; 37 ubh = (struct ufs_buffer_head *) 38 kmalloc (sizeof (struct ufs_buffer_head), GFP_KERNEL); 39 if (!ubh) 40 return NULL; 41 ubh->fragment = fragment; 42 ubh->count = count; 43 for (i = 0; i < count; i++) 44 if (!(ubh->bh[i] = sb_bread(sb, fragment + i))) 45 goto failed; 46 for (; i < UFS_MAXFRAG; i++) 47 ubh->bh[i] = NULL; 48 return ubh; 49failed: 50 for (j = 0; j < i; j++) 51 brelse (ubh->bh[j]); 52 kfree(ubh); 53 return NULL; 54} 55 56struct ufs_buffer_head * ubh_bread_uspi (struct ufs_sb_private_info * uspi, 57 struct super_block *sb, u64 fragment, u64 size) 58{ 59 unsigned i, j; 60 u64 count = 0; 61 if (size & ~uspi->s_fmask) 62 return NULL; 63 count = size >> uspi->s_fshift; 64 if (count <= 0 || count > UFS_MAXFRAG) 65 return NULL; 66 USPI_UBH->fragment = fragment; 67 USPI_UBH->count = count; 68 for (i = 0; i < count; i++) 69 if (!(USPI_UBH->bh[i] = sb_bread(sb, fragment + i))) 70 goto failed; 71 for (; i < UFS_MAXFRAG; i++) 72 USPI_UBH->bh[i] = NULL; 73 return USPI_UBH; 74failed: 75 for (j = 0; j < i; j++) 76 brelse (USPI_UBH->bh[j]); 77 return NULL; 78} 79 80void ubh_brelse (struct ufs_buffer_head * ubh) 81{ 82 unsigned i; 83 if (!ubh) 84 return; 85 for (i = 0; i < ubh->count; i++) 86 brelse (ubh->bh[i]); 87 kfree (ubh); 88} 89 90void ubh_brelse_uspi (struct ufs_sb_private_info * uspi) 91{ 92 unsigned i; 93 if (!USPI_UBH) 94 return; 95 for ( i = 0; i < USPI_UBH->count; i++ ) { 96 brelse (USPI_UBH->bh[i]); 97 USPI_UBH->bh[i] = NULL; 98 } 99} 100 101void ubh_mark_buffer_dirty (struct ufs_buffer_head * ubh) 102{ 103 unsigned i; 104 if (!ubh) 105 return; 106 for ( i = 0; i < ubh->count; i++ ) 107 mark_buffer_dirty (ubh->bh[i]); 108} 109 110void ubh_mark_buffer_uptodate (struct ufs_buffer_head * ubh, int flag) 111{ 112 unsigned i; 113 if (!ubh) 114 return; 115 if (flag) { 116 for ( i = 0; i < ubh->count; i++ ) 117 set_buffer_uptodate (ubh->bh[i]); 118 } else { 119 for ( i = 0; i < ubh->count; i++ ) 120 clear_buffer_uptodate (ubh->bh[i]); 121 } 122} 123 124void ubh_ll_rw_block (int rw, unsigned nr, struct ufs_buffer_head * ubh[]) 125{ 126 unsigned i; 127 if (!ubh) 128 return; 129 for ( i = 0; i < nr; i++ ) 130 ll_rw_block (rw, ubh[i]->count, ubh[i]->bh); 131} 132 133void ubh_wait_on_buffer (struct ufs_buffer_head * ubh) 134{ 135 unsigned i; 136 if (!ubh) 137 return; 138 for ( i = 0; i < ubh->count; i++ ) 139 wait_on_buffer (ubh->bh[i]); 140} 141 142unsigned ubh_max_bcount (struct ufs_buffer_head * ubh) 143{ 144 unsigned i; 145 unsigned max = 0; 146 if (!ubh) 147 return 0; 148 for ( i = 0; i < ubh->count; i++ ) 149 if ( atomic_read(&ubh->bh[i]->b_count) > max ) 150 max = atomic_read(&ubh->bh[i]->b_count); 151 return max; 152} 153 154void ubh_bforget (struct ufs_buffer_head * ubh) 155{ 156 unsigned i; 157 if (!ubh) 158 return; 159 for ( i = 0; i < ubh->count; i++ ) if ( ubh->bh[i] ) 160 bforget (ubh->bh[i]); 161} 162 163int ubh_buffer_dirty (struct ufs_buffer_head * ubh) 164{ 165 unsigned i; 166 unsigned result = 0; 167 if (!ubh) 168 return 0; 169 for ( i = 0; i < ubh->count; i++ ) 170 result |= buffer_dirty(ubh->bh[i]); 171 return result; 172} 173 174void _ubh_ubhcpymem_(struct ufs_sb_private_info * uspi, 175 unsigned char * mem, struct ufs_buffer_head * ubh, unsigned size) 176{ 177 unsigned len, bhno; 178 if (size > (ubh->count << uspi->s_fshift)) 179 size = ubh->count << uspi->s_fshift; 180 bhno = 0; 181 while (size) { 182 len = min_t(unsigned int, size, uspi->s_fsize); 183 memcpy (mem, ubh->bh[bhno]->b_data, len); 184 mem += uspi->s_fsize; 185 size -= len; 186 bhno++; 187 } 188} 189 190void _ubh_memcpyubh_(struct ufs_sb_private_info * uspi, 191 struct ufs_buffer_head * ubh, unsigned char * mem, unsigned size) 192{ 193 unsigned len, bhno; 194 if (size > (ubh->count << uspi->s_fshift)) 195 size = ubh->count << uspi->s_fshift; 196 bhno = 0; 197 while (size) { 198 len = min_t(unsigned int, size, uspi->s_fsize); 199 memcpy (ubh->bh[bhno]->b_data, mem, len); 200 mem += uspi->s_fsize; 201 size -= len; 202 bhno++; 203 } 204} 205 206dev_t 207ufs_get_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi) 208{ 209 __fs32 fs32; 210 dev_t dev; 211 212 if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86) 213 fs32 = ufsi->i_u1.i_data[1]; 214 else 215 fs32 = ufsi->i_u1.i_data[0]; 216 fs32 = fs32_to_cpu(sb, fs32); 217 switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { 218 case UFS_ST_SUNx86: 219 case UFS_ST_SUN: 220 if ((fs32 & 0xffff0000) == 0 || 221 (fs32 & 0xffff0000) == 0xffff0000) 222 dev = old_decode_dev(fs32 & 0x7fff); 223 else 224 dev = MKDEV(sysv_major(fs32), sysv_minor(fs32)); 225 break; 226 227 default: 228 dev = old_decode_dev(fs32); 229 break; 230 } 231 return dev; 232} 233 234void 235ufs_set_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi, dev_t dev) 236{ 237 __fs32 fs32; 238 239 switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { 240 case UFS_ST_SUNx86: 241 case UFS_ST_SUN: 242 fs32 = sysv_encode_dev(dev); 243 if ((fs32 & 0xffff8000) == 0) { 244 fs32 = old_encode_dev(dev); 245 } 246 break; 247 248 default: 249 fs32 = old_encode_dev(dev); 250 break; 251 } 252 fs32 = cpu_to_fs32(sb, fs32); 253 if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86) 254 ufsi->i_u1.i_data[1] = fs32; 255 else 256 ufsi->i_u1.i_data[0] = fs32; 257}