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