1 /* 2 * linux/fs/affs/amigaffs.c 3 * 4 * (c) 1996 Hans-Joachim Widmaier - Rewritten 5 * 6 * (C) 1993 Ray Burr - Amiga FFS filesystem. 7 * 8 * Please send bug reports to: hjw@zvw.de 9 */ 10 11 #include "affs.h" 12 13 extern struct timezone sys_tz; 14 15 static char ErrorBuffer[256]; 16 17 /* 18 * Functions for accessing Amiga-FFS structures. 19 */ 20 21 22 /* Insert a header block bh into the directory dir 23 * caller must hold AFFS_DIR->i_hash_lock! 24 */ 25 26 int 27 affs_insert_hash(struct inode *dir, struct buffer_head *bh) 28 { 29 struct super_block *sb = dir->i_sb; 30 struct buffer_head *dir_bh; 31 u32 ino, hash_ino; 32 int offset; 33 34 ino = bh->b_blocknr; 35 offset = affs_hash_name(sb, AFFS_TAIL(sb, bh)->name + 1, AFFS_TAIL(sb, bh)->name[0]); 36 37 pr_debug("%s(dir=%u, ino=%d)\n", __func__, (u32)dir->i_ino, ino); 38 39 dir_bh = affs_bread(sb, dir->i_ino); 40 if (!dir_bh) 41 return -EIO; 42 43 hash_ino = be32_to_cpu(AFFS_HEAD(dir_bh)->table[offset]); 44 while (hash_ino) { 45 affs_brelse(dir_bh); 46 dir_bh = affs_bread(sb, hash_ino); 47 if (!dir_bh) 48 return -EIO; 49 hash_ino = be32_to_cpu(AFFS_TAIL(sb, dir_bh)->hash_chain); 50 } 51 AFFS_TAIL(sb, bh)->parent = cpu_to_be32(dir->i_ino); 52 AFFS_TAIL(sb, bh)->hash_chain = 0; 53 affs_fix_checksum(sb, bh); 54 55 if (dir->i_ino == dir_bh->b_blocknr) 56 AFFS_HEAD(dir_bh)->table[offset] = cpu_to_be32(ino); 57 else 58 AFFS_TAIL(sb, dir_bh)->hash_chain = cpu_to_be32(ino); 59 60 affs_adjust_checksum(dir_bh, ino); 61 mark_buffer_dirty_inode(dir_bh, dir); 62 affs_brelse(dir_bh); 63 64 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 65 dir->i_version++; 66 mark_inode_dirty(dir); 67 68 return 0; 69 } 70 71 /* Remove a header block from its directory. 72 * caller must hold AFFS_DIR->i_hash_lock! 73 */ 74 75 int 76 affs_remove_hash(struct inode *dir, struct buffer_head *rem_bh) 77 { 78 struct super_block *sb; 79 struct buffer_head *bh; 80 u32 rem_ino, hash_ino; 81 __be32 ino; 82 int offset, retval; 83 84 sb = dir->i_sb; 85 rem_ino = rem_bh->b_blocknr; 86 offset = affs_hash_name(sb, AFFS_TAIL(sb, rem_bh)->name+1, AFFS_TAIL(sb, rem_bh)->name[0]); 87 pr_debug("%s(dir=%d, ino=%d, hashval=%d)\n", 88 __func__, (u32)dir->i_ino, rem_ino, offset); 89 90 bh = affs_bread(sb, dir->i_ino); 91 if (!bh) 92 return -EIO; 93 94 retval = -ENOENT; 95 hash_ino = be32_to_cpu(AFFS_HEAD(bh)->table[offset]); 96 while (hash_ino) { 97 if (hash_ino == rem_ino) { 98 ino = AFFS_TAIL(sb, rem_bh)->hash_chain; 99 if (dir->i_ino == bh->b_blocknr) 100 AFFS_HEAD(bh)->table[offset] = ino; 101 else 102 AFFS_TAIL(sb, bh)->hash_chain = ino; 103 affs_adjust_checksum(bh, be32_to_cpu(ino) - hash_ino); 104 mark_buffer_dirty_inode(bh, dir); 105 AFFS_TAIL(sb, rem_bh)->parent = 0; 106 retval = 0; 107 break; 108 } 109 affs_brelse(bh); 110 bh = affs_bread(sb, hash_ino); 111 if (!bh) 112 return -EIO; 113 hash_ino = be32_to_cpu(AFFS_TAIL(sb, bh)->hash_chain); 114 } 115 116 affs_brelse(bh); 117 118 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 119 dir->i_version++; 120 mark_inode_dirty(dir); 121 122 return retval; 123 } 124 125 static void 126 affs_fix_dcache(struct inode *inode, u32 entry_ino) 127 { 128 struct dentry *dentry; 129 spin_lock(&inode->i_lock); 130 hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { 131 if (entry_ino == (u32)(long)dentry->d_fsdata) { 132 dentry->d_fsdata = (void *)inode->i_ino; 133 break; 134 } 135 } 136 spin_unlock(&inode->i_lock); 137 } 138 139 140 /* Remove header from link chain */ 141 142 static int 143 affs_remove_link(struct dentry *dentry) 144 { 145 struct inode *dir, *inode = dentry->d_inode; 146 struct super_block *sb = inode->i_sb; 147 struct buffer_head *bh = NULL, *link_bh = NULL; 148 u32 link_ino, ino; 149 int retval; 150 151 pr_debug("%s(key=%ld)\n", __func__, inode->i_ino); 152 retval = -EIO; 153 bh = affs_bread(sb, inode->i_ino); 154 if (!bh) 155 goto done; 156 157 link_ino = (u32)(long)dentry->d_fsdata; 158 if (inode->i_ino == link_ino) { 159 /* we can't remove the head of the link, as its blocknr is still used as ino, 160 * so we remove the block of the first link instead. 161 */ 162 link_ino = be32_to_cpu(AFFS_TAIL(sb, bh)->link_chain); 163 link_bh = affs_bread(sb, link_ino); 164 if (!link_bh) 165 goto done; 166 167 dir = affs_iget(sb, be32_to_cpu(AFFS_TAIL(sb, link_bh)->parent)); 168 if (IS_ERR(dir)) { 169 retval = PTR_ERR(dir); 170 goto done; 171 } 172 173 affs_lock_dir(dir); 174 /* 175 * if there's a dentry for that block, make it 176 * refer to inode itself. 177 */ 178 affs_fix_dcache(inode, link_ino); 179 retval = affs_remove_hash(dir, link_bh); 180 if (retval) { 181 affs_unlock_dir(dir); 182 goto done; 183 } 184 mark_buffer_dirty_inode(link_bh, inode); 185 186 memcpy(AFFS_TAIL(sb, bh)->name, AFFS_TAIL(sb, link_bh)->name, 32); 187 retval = affs_insert_hash(dir, bh); 188 if (retval) { 189 affs_unlock_dir(dir); 190 goto done; 191 } 192 mark_buffer_dirty_inode(bh, inode); 193 194 affs_unlock_dir(dir); 195 iput(dir); 196 } else { 197 link_bh = affs_bread(sb, link_ino); 198 if (!link_bh) 199 goto done; 200 } 201 202 while ((ino = be32_to_cpu(AFFS_TAIL(sb, bh)->link_chain)) != 0) { 203 if (ino == link_ino) { 204 __be32 ino2 = AFFS_TAIL(sb, link_bh)->link_chain; 205 AFFS_TAIL(sb, bh)->link_chain = ino2; 206 affs_adjust_checksum(bh, be32_to_cpu(ino2) - link_ino); 207 mark_buffer_dirty_inode(bh, inode); 208 retval = 0; 209 /* Fix the link count, if bh is a normal header block without links */ 210 switch (be32_to_cpu(AFFS_TAIL(sb, bh)->stype)) { 211 case ST_LINKDIR: 212 case ST_LINKFILE: 213 break; 214 default: 215 if (!AFFS_TAIL(sb, bh)->link_chain) 216 set_nlink(inode, 1); 217 } 218 affs_free_block(sb, link_ino); 219 goto done; 220 } 221 affs_brelse(bh); 222 bh = affs_bread(sb, ino); 223 if (!bh) 224 goto done; 225 } 226 retval = -ENOENT; 227 done: 228 affs_brelse(link_bh); 229 affs_brelse(bh); 230 return retval; 231 } 232 233 234 static int 235 affs_empty_dir(struct inode *inode) 236 { 237 struct super_block *sb = inode->i_sb; 238 struct buffer_head *bh; 239 int retval, size; 240 241 retval = -EIO; 242 bh = affs_bread(sb, inode->i_ino); 243 if (!bh) 244 goto done; 245 246 retval = -ENOTEMPTY; 247 for (size = AFFS_SB(sb)->s_hashsize - 1; size >= 0; size--) 248 if (AFFS_HEAD(bh)->table[size]) 249 goto not_empty; 250 retval = 0; 251 not_empty: 252 affs_brelse(bh); 253 done: 254 return retval; 255 } 256 257 258 /* Remove a filesystem object. If the object to be removed has 259 * links to it, one of the links must be changed to inherit 260 * the file or directory. As above, any inode will do. 261 * The buffer will not be freed. If the header is a link, the 262 * block will be marked as free. 263 * This function returns a negative error number in case of 264 * an error, else 0 if the inode is to be deleted or 1 if not. 265 */ 266 267 int 268 affs_remove_header(struct dentry *dentry) 269 { 270 struct super_block *sb; 271 struct inode *inode, *dir; 272 struct buffer_head *bh = NULL; 273 int retval; 274 275 dir = dentry->d_parent->d_inode; 276 sb = dir->i_sb; 277 278 retval = -ENOENT; 279 inode = dentry->d_inode; 280 if (!inode) 281 goto done; 282 283 pr_debug("%s(key=%ld)\n", __func__, inode->i_ino); 284 retval = -EIO; 285 bh = affs_bread(sb, (u32)(long)dentry->d_fsdata); 286 if (!bh) 287 goto done; 288 289 affs_lock_link(inode); 290 affs_lock_dir(dir); 291 switch (be32_to_cpu(AFFS_TAIL(sb, bh)->stype)) { 292 case ST_USERDIR: 293 /* if we ever want to support links to dirs 294 * i_hash_lock of the inode must only be 295 * taken after some checks 296 */ 297 affs_lock_dir(inode); 298 retval = affs_empty_dir(inode); 299 affs_unlock_dir(inode); 300 if (retval) 301 goto done_unlock; 302 break; 303 default: 304 break; 305 } 306 307 retval = affs_remove_hash(dir, bh); 308 if (retval) 309 goto done_unlock; 310 mark_buffer_dirty_inode(bh, inode); 311 312 affs_unlock_dir(dir); 313 314 if (inode->i_nlink > 1) 315 retval = affs_remove_link(dentry); 316 else 317 clear_nlink(inode); 318 affs_unlock_link(inode); 319 inode->i_ctime = CURRENT_TIME_SEC; 320 mark_inode_dirty(inode); 321 322 done: 323 affs_brelse(bh); 324 return retval; 325 326 done_unlock: 327 affs_unlock_dir(dir); 328 affs_unlock_link(inode); 329 goto done; 330 } 331 332 /* Checksum a block, do various consistency checks and optionally return 333 the blocks type number. DATA points to the block. If their pointers 334 are non-null, *PTYPE and *STYPE are set to the primary and secondary 335 block types respectively, *HASHSIZE is set to the size of the hashtable 336 (which lets us calculate the block size). 337 Returns non-zero if the block is not consistent. */ 338 339 u32 340 affs_checksum_block(struct super_block *sb, struct buffer_head *bh) 341 { 342 __be32 *ptr = (__be32 *)bh->b_data; 343 u32 sum; 344 int bsize; 345 346 sum = 0; 347 for (bsize = sb->s_blocksize / sizeof(__be32); bsize > 0; bsize--) 348 sum += be32_to_cpu(*ptr++); 349 return sum; 350 } 351 352 /* 353 * Calculate the checksum of a disk block and store it 354 * at the indicated position. 355 */ 356 357 void 358 affs_fix_checksum(struct super_block *sb, struct buffer_head *bh) 359 { 360 int cnt = sb->s_blocksize / sizeof(__be32); 361 __be32 *ptr = (__be32 *)bh->b_data; 362 u32 checksum; 363 __be32 *checksumptr; 364 365 checksumptr = ptr + 5; 366 *checksumptr = 0; 367 for (checksum = 0; cnt > 0; ptr++, cnt--) 368 checksum += be32_to_cpu(*ptr); 369 *checksumptr = cpu_to_be32(-checksum); 370 } 371 372 void 373 secs_to_datestamp(time_t secs, struct affs_date *ds) 374 { 375 u32 days; 376 u32 minute; 377 378 secs -= sys_tz.tz_minuteswest * 60 + ((8 * 365 + 2) * 24 * 60 * 60); 379 if (secs < 0) 380 secs = 0; 381 days = secs / 86400; 382 secs -= days * 86400; 383 minute = secs / 60; 384 secs -= minute * 60; 385 386 ds->days = cpu_to_be32(days); 387 ds->mins = cpu_to_be32(minute); 388 ds->ticks = cpu_to_be32(secs * 50); 389 } 390 391 umode_t 392 prot_to_mode(u32 prot) 393 { 394 umode_t mode = 0; 395 396 if (!(prot & FIBF_NOWRITE)) 397 mode |= S_IWUSR; 398 if (!(prot & FIBF_NOREAD)) 399 mode |= S_IRUSR; 400 if (!(prot & FIBF_NOEXECUTE)) 401 mode |= S_IXUSR; 402 if (prot & FIBF_GRP_WRITE) 403 mode |= S_IWGRP; 404 if (prot & FIBF_GRP_READ) 405 mode |= S_IRGRP; 406 if (prot & FIBF_GRP_EXECUTE) 407 mode |= S_IXGRP; 408 if (prot & FIBF_OTR_WRITE) 409 mode |= S_IWOTH; 410 if (prot & FIBF_OTR_READ) 411 mode |= S_IROTH; 412 if (prot & FIBF_OTR_EXECUTE) 413 mode |= S_IXOTH; 414 415 return mode; 416 } 417 418 void 419 mode_to_prot(struct inode *inode) 420 { 421 u32 prot = AFFS_I(inode)->i_protect; 422 umode_t mode = inode->i_mode; 423 424 if (!(mode & S_IXUSR)) 425 prot |= FIBF_NOEXECUTE; 426 if (!(mode & S_IRUSR)) 427 prot |= FIBF_NOREAD; 428 if (!(mode & S_IWUSR)) 429 prot |= FIBF_NOWRITE; 430 if (mode & S_IXGRP) 431 prot |= FIBF_GRP_EXECUTE; 432 if (mode & S_IRGRP) 433 prot |= FIBF_GRP_READ; 434 if (mode & S_IWGRP) 435 prot |= FIBF_GRP_WRITE; 436 if (mode & S_IXOTH) 437 prot |= FIBF_OTR_EXECUTE; 438 if (mode & S_IROTH) 439 prot |= FIBF_OTR_READ; 440 if (mode & S_IWOTH) 441 prot |= FIBF_OTR_WRITE; 442 443 AFFS_I(inode)->i_protect = prot; 444 } 445 446 void 447 affs_error(struct super_block *sb, const char *function, const char *fmt, ...) 448 { 449 va_list args; 450 451 va_start(args,fmt); 452 vsnprintf(ErrorBuffer,sizeof(ErrorBuffer),fmt,args); 453 va_end(args); 454 455 pr_crit("error (device %s): %s(): %s\n", sb->s_id, 456 function,ErrorBuffer); 457 if (!(sb->s_flags & MS_RDONLY)) 458 pr_warn("Remounting filesystem read-only\n"); 459 sb->s_flags |= MS_RDONLY; 460 } 461 462 void 463 affs_warning(struct super_block *sb, const char *function, const char *fmt, ...) 464 { 465 va_list args; 466 467 va_start(args,fmt); 468 vsnprintf(ErrorBuffer,sizeof(ErrorBuffer),fmt,args); 469 va_end(args); 470 471 pr_warn("(device %s): %s(): %s\n", sb->s_id, 472 function,ErrorBuffer); 473 } 474 475 bool 476 affs_nofilenametruncate(const struct dentry *dentry) 477 { 478 struct inode *inode = dentry->d_inode; 479 return AFFS_SB(inode->i_sb)->s_flags & SF_NO_TRUNCATE; 480 481 } 482 483 /* Check if the name is valid for a affs object. */ 484 485 int 486 affs_check_name(const unsigned char *name, int len, bool notruncate) 487 { 488 int i; 489 490 if (len > 30) { 491 if (notruncate) 492 return -ENAMETOOLONG; 493 else 494 len = 30; 495 } 496 for (i = 0; i < len; i++) { 497 if (name[i] < ' ' || name[i] == ':' 498 || (name[i] > 0x7e && name[i] < 0xa0)) 499 return -EINVAL; 500 } 501 502 return 0; 503 } 504 505 /* This function copies name to bstr, with at most 30 506 * characters length. The bstr will be prepended by 507 * a length byte. 508 * NOTE: The name will must be already checked by 509 * affs_check_name()! 510 */ 511 512 int 513 affs_copy_name(unsigned char *bstr, struct dentry *dentry) 514 { 515 int len = min(dentry->d_name.len, 30u); 516 517 *bstr++ = len; 518 memcpy(bstr, dentry->d_name.name, len); 519 return len; 520 } 521