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 26 struct 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; 49 failed: 50 for (j = 0; j < i; j++) 51 brelse (ubh->bh[j]); 52 kfree(ubh); 53 return NULL; 54 } 55 56 struct 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; 74 failed: 75 for (j = 0; j < i; j++) 76 brelse (USPI_UBH->bh[j]); 77 return NULL; 78 } 79 80 void 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 90 void 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 101 void 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 110 void 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 124 void 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 133 void 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 142 unsigned 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 154 void 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 163 int 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 174 void _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 190 void _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 206 dev_t 207 ufs_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 234 void 235 ufs_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 } 258