1 /* 2 * directory.c 3 * 4 * PURPOSE 5 * Directory related functions 6 * 7 * COPYRIGHT 8 * This file is distributed under the terms of the GNU General Public 9 * License (GPL). Copies of the GPL can be obtained from: 10 * ftp://prep.ai.mit.edu/pub/gnu/GPL 11 * Each contributing author retains all rights to their own work. 12 */ 13 14 #include "udfdecl.h" 15 #include "udf_i.h" 16 17 #include <linux/fs.h> 18 #include <linux/string.h> 19 #include <linux/bio.h> 20 #include <linux/crc-itu-t.h> 21 #include <linux/iversion.h> 22 23 static int udf_verify_fi(struct udf_fileident_iter *iter) 24 { 25 unsigned int len; 26 27 if (iter->fi.descTag.tagIdent != cpu_to_le16(TAG_IDENT_FID)) { 28 udf_err(iter->dir->i_sb, 29 "directory (ino %lu) has entry at pos %llu with incorrect tag %x\n", 30 iter->dir->i_ino, (unsigned long long)iter->pos, 31 le16_to_cpu(iter->fi.descTag.tagIdent)); 32 return -EFSCORRUPTED; 33 } 34 len = udf_dir_entry_len(&iter->fi); 35 if (le16_to_cpu(iter->fi.lengthOfImpUse) & 3) { 36 udf_err(iter->dir->i_sb, 37 "directory (ino %lu) has entry at pos %llu with unaligned length of impUse field\n", 38 iter->dir->i_ino, (unsigned long long)iter->pos); 39 return -EFSCORRUPTED; 40 } 41 /* 42 * This is in fact allowed by the spec due to long impUse field but 43 * we don't support it. If there is real media with this large impUse 44 * field, support can be added. 45 */ 46 if (len > 1 << iter->dir->i_blkbits) { 47 udf_err(iter->dir->i_sb, 48 "directory (ino %lu) has too big (%u) entry at pos %llu\n", 49 iter->dir->i_ino, len, (unsigned long long)iter->pos); 50 return -EFSCORRUPTED; 51 } 52 if (iter->pos + len > iter->dir->i_size) { 53 udf_err(iter->dir->i_sb, 54 "directory (ino %lu) has entry past directory size at pos %llu\n", 55 iter->dir->i_ino, (unsigned long long)iter->pos); 56 return -EFSCORRUPTED; 57 } 58 if (udf_dir_entry_len(&iter->fi) != 59 sizeof(struct tag) + le16_to_cpu(iter->fi.descTag.descCRCLength)) { 60 udf_err(iter->dir->i_sb, 61 "directory (ino %lu) has entry where CRC length (%u) does not match entry length (%u)\n", 62 iter->dir->i_ino, 63 (unsigned)le16_to_cpu(iter->fi.descTag.descCRCLength), 64 (unsigned)(udf_dir_entry_len(&iter->fi) - 65 sizeof(struct tag))); 66 return -EFSCORRUPTED; 67 } 68 return 0; 69 } 70 71 static int udf_copy_fi(struct udf_fileident_iter *iter) 72 { 73 struct udf_inode_info *iinfo = UDF_I(iter->dir); 74 u32 blksize = 1 << iter->dir->i_blkbits; 75 u32 off, len, nameoff; 76 int err; 77 78 /* Skip copying when we are at EOF */ 79 if (iter->pos >= iter->dir->i_size) { 80 iter->name = NULL; 81 return 0; 82 } 83 if (iter->dir->i_size < iter->pos + sizeof(struct fileIdentDesc)) { 84 udf_err(iter->dir->i_sb, 85 "directory (ino %lu) has entry straddling EOF\n", 86 iter->dir->i_ino); 87 return -EFSCORRUPTED; 88 } 89 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 90 memcpy(&iter->fi, iinfo->i_data + iinfo->i_lenEAttr + iter->pos, 91 sizeof(struct fileIdentDesc)); 92 err = udf_verify_fi(iter); 93 if (err < 0) 94 return err; 95 iter->name = iinfo->i_data + iinfo->i_lenEAttr + iter->pos + 96 sizeof(struct fileIdentDesc) + 97 le16_to_cpu(iter->fi.lengthOfImpUse); 98 return 0; 99 } 100 101 off = iter->pos & (blksize - 1); 102 len = min_t(int, sizeof(struct fileIdentDesc), blksize - off); 103 memcpy(&iter->fi, iter->bh[0]->b_data + off, len); 104 if (len < sizeof(struct fileIdentDesc)) 105 memcpy((char *)(&iter->fi) + len, iter->bh[1]->b_data, 106 sizeof(struct fileIdentDesc) - len); 107 err = udf_verify_fi(iter); 108 if (err < 0) 109 return err; 110 111 /* Handle directory entry name */ 112 nameoff = off + sizeof(struct fileIdentDesc) + 113 le16_to_cpu(iter->fi.lengthOfImpUse); 114 if (off + udf_dir_entry_len(&iter->fi) <= blksize) { 115 iter->name = iter->bh[0]->b_data + nameoff; 116 } else if (nameoff >= blksize) { 117 iter->name = iter->bh[1]->b_data + (nameoff - blksize); 118 } else { 119 iter->name = iter->namebuf; 120 len = blksize - nameoff; 121 memcpy(iter->name, iter->bh[0]->b_data + nameoff, len); 122 memcpy(iter->name + len, iter->bh[1]->b_data, 123 iter->fi.lengthFileIdent - len); 124 } 125 return 0; 126 } 127 128 /* Readahead 8k once we are at 8k boundary */ 129 static void udf_readahead_dir(struct udf_fileident_iter *iter) 130 { 131 unsigned int ralen = 16 >> (iter->dir->i_blkbits - 9); 132 struct buffer_head *tmp, *bha[16]; 133 int i, num; 134 udf_pblk_t blk; 135 136 if (iter->loffset & (ralen - 1)) 137 return; 138 139 if (iter->loffset + ralen > (iter->elen >> iter->dir->i_blkbits)) 140 ralen = (iter->elen >> iter->dir->i_blkbits) - iter->loffset; 141 num = 0; 142 for (i = 0; i < ralen; i++) { 143 blk = udf_get_lb_pblock(iter->dir->i_sb, &iter->eloc, 144 iter->loffset + i); 145 tmp = sb_getblk(iter->dir->i_sb, blk); 146 if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp)) 147 bha[num++] = tmp; 148 else 149 brelse(tmp); 150 } 151 if (num) { 152 bh_readahead_batch(num, bha, REQ_RAHEAD); 153 for (i = 0; i < num; i++) 154 brelse(bha[i]); 155 } 156 } 157 158 static struct buffer_head *udf_fiiter_bread_blk(struct udf_fileident_iter *iter) 159 { 160 udf_pblk_t blk; 161 162 udf_readahead_dir(iter); 163 blk = udf_get_lb_pblock(iter->dir->i_sb, &iter->eloc, iter->loffset); 164 return sb_bread(iter->dir->i_sb, blk); 165 } 166 167 /* 168 * Updates loffset to point to next directory block; eloc, elen & epos are 169 * updated if we need to traverse to the next extent as well. 170 */ 171 static int udf_fiiter_advance_blk(struct udf_fileident_iter *iter) 172 { 173 iter->loffset++; 174 if (iter->loffset < DIV_ROUND_UP(iter->elen, 1<<iter->dir->i_blkbits)) 175 return 0; 176 177 iter->loffset = 0; 178 if (udf_next_aext(iter->dir, &iter->epos, &iter->eloc, &iter->elen, 1) 179 != (EXT_RECORDED_ALLOCATED >> 30)) { 180 if (iter->pos == iter->dir->i_size) { 181 iter->elen = 0; 182 return 0; 183 } 184 udf_err(iter->dir->i_sb, 185 "extent after position %llu not allocated in directory (ino %lu)\n", 186 (unsigned long long)iter->pos, iter->dir->i_ino); 187 return -EFSCORRUPTED; 188 } 189 return 0; 190 } 191 192 static int udf_fiiter_load_bhs(struct udf_fileident_iter *iter) 193 { 194 int blksize = 1 << iter->dir->i_blkbits; 195 int off = iter->pos & (blksize - 1); 196 int err; 197 struct fileIdentDesc *fi; 198 199 /* Is there any further extent we can map from? */ 200 if (!iter->bh[0] && iter->elen) { 201 iter->bh[0] = udf_fiiter_bread_blk(iter); 202 if (!iter->bh[0]) { 203 err = -ENOMEM; 204 goto out_brelse; 205 } 206 if (!buffer_uptodate(iter->bh[0])) { 207 err = -EIO; 208 goto out_brelse; 209 } 210 } 211 /* There's no next block so we are done */ 212 if (iter->pos >= iter->dir->i_size) 213 return 0; 214 /* Need to fetch next block as well? */ 215 if (off + sizeof(struct fileIdentDesc) > blksize) 216 goto fetch_next; 217 fi = (struct fileIdentDesc *)(iter->bh[0]->b_data + off); 218 /* Need to fetch next block to get name? */ 219 if (off + udf_dir_entry_len(fi) > blksize) { 220 fetch_next: 221 err = udf_fiiter_advance_blk(iter); 222 if (err) 223 goto out_brelse; 224 iter->bh[1] = udf_fiiter_bread_blk(iter); 225 if (!iter->bh[1]) { 226 err = -ENOMEM; 227 goto out_brelse; 228 } 229 if (!buffer_uptodate(iter->bh[1])) { 230 err = -EIO; 231 goto out_brelse; 232 } 233 } 234 return 0; 235 out_brelse: 236 brelse(iter->bh[0]); 237 brelse(iter->bh[1]); 238 iter->bh[0] = iter->bh[1] = NULL; 239 return err; 240 } 241 242 int udf_fiiter_init(struct udf_fileident_iter *iter, struct inode *dir, 243 loff_t pos) 244 { 245 struct udf_inode_info *iinfo = UDF_I(dir); 246 int err = 0; 247 248 iter->dir = dir; 249 iter->bh[0] = iter->bh[1] = NULL; 250 iter->pos = pos; 251 iter->elen = 0; 252 iter->epos.bh = NULL; 253 iter->name = NULL; 254 /* 255 * When directory is verified, we don't expect directory iteration to 256 * fail and it can be difficult to undo without corrupting filesystem. 257 * So just do not allow memory allocation failures here. 258 */ 259 iter->namebuf = kmalloc(UDF_NAME_LEN_CS0, GFP_KERNEL | __GFP_NOFAIL); 260 261 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 262 err = udf_copy_fi(iter); 263 goto out; 264 } 265 266 if (inode_bmap(dir, iter->pos >> dir->i_blkbits, &iter->epos, 267 &iter->eloc, &iter->elen, &iter->loffset) != 268 (EXT_RECORDED_ALLOCATED >> 30)) { 269 if (pos == dir->i_size) 270 return 0; 271 udf_err(dir->i_sb, 272 "position %llu not allocated in directory (ino %lu)\n", 273 (unsigned long long)pos, dir->i_ino); 274 err = -EFSCORRUPTED; 275 goto out; 276 } 277 err = udf_fiiter_load_bhs(iter); 278 if (err < 0) 279 goto out; 280 err = udf_copy_fi(iter); 281 out: 282 if (err < 0) 283 udf_fiiter_release(iter); 284 return err; 285 } 286 287 int udf_fiiter_advance(struct udf_fileident_iter *iter) 288 { 289 unsigned int oldoff, len; 290 int blksize = 1 << iter->dir->i_blkbits; 291 int err; 292 293 oldoff = iter->pos & (blksize - 1); 294 len = udf_dir_entry_len(&iter->fi); 295 iter->pos += len; 296 if (UDF_I(iter->dir)->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { 297 if (oldoff + len >= blksize) { 298 brelse(iter->bh[0]); 299 iter->bh[0] = NULL; 300 /* Next block already loaded? */ 301 if (iter->bh[1]) { 302 iter->bh[0] = iter->bh[1]; 303 iter->bh[1] = NULL; 304 } else { 305 err = udf_fiiter_advance_blk(iter); 306 if (err < 0) 307 return err; 308 } 309 } 310 err = udf_fiiter_load_bhs(iter); 311 if (err < 0) 312 return err; 313 } 314 return udf_copy_fi(iter); 315 } 316 317 void udf_fiiter_release(struct udf_fileident_iter *iter) 318 { 319 iter->dir = NULL; 320 brelse(iter->bh[0]); 321 brelse(iter->bh[1]); 322 iter->bh[0] = iter->bh[1] = NULL; 323 kfree(iter->namebuf); 324 iter->namebuf = NULL; 325 } 326 327 static void udf_copy_to_bufs(void *buf1, int len1, void *buf2, int len2, 328 int off, void *src, int len) 329 { 330 int copy; 331 332 if (off >= len1) { 333 off -= len1; 334 } else { 335 copy = min(off + len, len1) - off; 336 memcpy(buf1 + off, src, copy); 337 src += copy; 338 len -= copy; 339 off = 0; 340 } 341 if (len > 0) { 342 if (WARN_ON_ONCE(off + len > len2 || !buf2)) 343 return; 344 memcpy(buf2 + off, src, len); 345 } 346 } 347 348 static uint16_t udf_crc_fi_bufs(void *buf1, int len1, void *buf2, int len2, 349 int off, int len) 350 { 351 int copy; 352 uint16_t crc = 0; 353 354 if (off >= len1) { 355 off -= len1; 356 } else { 357 copy = min(off + len, len1) - off; 358 crc = crc_itu_t(crc, buf1 + off, copy); 359 len -= copy; 360 off = 0; 361 } 362 if (len > 0) { 363 if (WARN_ON_ONCE(off + len > len2 || !buf2)) 364 return 0; 365 crc = crc_itu_t(crc, buf2 + off, len); 366 } 367 return crc; 368 } 369 370 static void udf_copy_fi_to_bufs(char *buf1, int len1, char *buf2, int len2, 371 int off, struct fileIdentDesc *fi, 372 uint8_t *impuse, uint8_t *name) 373 { 374 uint16_t crc; 375 int fioff = off; 376 int crcoff = off + sizeof(struct tag); 377 unsigned int crclen = udf_dir_entry_len(fi) - sizeof(struct tag); 378 char zeros[UDF_NAME_PAD] = {}; 379 int endoff = off + udf_dir_entry_len(fi); 380 381 udf_copy_to_bufs(buf1, len1, buf2, len2, off, fi, 382 sizeof(struct fileIdentDesc)); 383 off += sizeof(struct fileIdentDesc); 384 if (impuse) 385 udf_copy_to_bufs(buf1, len1, buf2, len2, off, impuse, 386 le16_to_cpu(fi->lengthOfImpUse)); 387 off += le16_to_cpu(fi->lengthOfImpUse); 388 if (name) { 389 udf_copy_to_bufs(buf1, len1, buf2, len2, off, name, 390 fi->lengthFileIdent); 391 off += fi->lengthFileIdent; 392 udf_copy_to_bufs(buf1, len1, buf2, len2, off, zeros, 393 endoff - off); 394 } 395 396 crc = udf_crc_fi_bufs(buf1, len1, buf2, len2, crcoff, crclen); 397 fi->descTag.descCRC = cpu_to_le16(crc); 398 fi->descTag.descCRCLength = cpu_to_le16(crclen); 399 fi->descTag.tagChecksum = udf_tag_checksum(&fi->descTag); 400 401 udf_copy_to_bufs(buf1, len1, buf2, len2, fioff, fi, sizeof(struct tag)); 402 } 403 404 void udf_fiiter_write_fi(struct udf_fileident_iter *iter, uint8_t *impuse) 405 { 406 struct udf_inode_info *iinfo = UDF_I(iter->dir); 407 void *buf1, *buf2 = NULL; 408 int len1, len2 = 0, off; 409 int blksize = 1 << iter->dir->i_blkbits; 410 411 off = iter->pos & (blksize - 1); 412 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 413 buf1 = iinfo->i_data + iinfo->i_lenEAttr; 414 len1 = iter->dir->i_size; 415 } else { 416 buf1 = iter->bh[0]->b_data; 417 len1 = blksize; 418 if (iter->bh[1]) { 419 buf2 = iter->bh[1]->b_data; 420 len2 = blksize; 421 } 422 } 423 424 udf_copy_fi_to_bufs(buf1, len1, buf2, len2, off, &iter->fi, impuse, 425 iter->name == iter->namebuf ? iter->name : NULL); 426 427 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 428 mark_inode_dirty(iter->dir); 429 } else { 430 mark_buffer_dirty_inode(iter->bh[0], iter->dir); 431 if (iter->bh[1]) 432 mark_buffer_dirty_inode(iter->bh[1], iter->dir); 433 } 434 inode_inc_iversion(iter->dir); 435 } 436 437 void udf_fiiter_update_elen(struct udf_fileident_iter *iter, uint32_t new_elen) 438 { 439 struct udf_inode_info *iinfo = UDF_I(iter->dir); 440 int diff = new_elen - iter->elen; 441 442 /* Skip update when we already went past the last extent */ 443 if (!iter->elen) 444 return; 445 iter->elen = new_elen; 446 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) 447 iter->epos.offset -= sizeof(struct short_ad); 448 else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) 449 iter->epos.offset -= sizeof(struct long_ad); 450 udf_write_aext(iter->dir, &iter->epos, &iter->eloc, iter->elen, 1); 451 iinfo->i_lenExtents += diff; 452 mark_inode_dirty(iter->dir); 453 } 454 455 /* Append new block to directory. @iter is expected to point at EOF */ 456 int udf_fiiter_append_blk(struct udf_fileident_iter *iter) 457 { 458 struct udf_inode_info *iinfo = UDF_I(iter->dir); 459 int blksize = 1 << iter->dir->i_blkbits; 460 struct buffer_head *bh; 461 sector_t block; 462 uint32_t old_elen = iter->elen; 463 int err; 464 465 if (WARN_ON_ONCE(iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)) 466 return -EINVAL; 467 468 /* Round up last extent in the file */ 469 udf_fiiter_update_elen(iter, ALIGN(iter->elen, blksize)); 470 471 /* Allocate new block and refresh mapping information */ 472 block = iinfo->i_lenExtents >> iter->dir->i_blkbits; 473 bh = udf_bread(iter->dir, block, 1, &err); 474 if (!bh) { 475 udf_fiiter_update_elen(iter, old_elen); 476 return err; 477 } 478 if (inode_bmap(iter->dir, block, &iter->epos, &iter->eloc, &iter->elen, 479 &iter->loffset) != (EXT_RECORDED_ALLOCATED >> 30)) { 480 udf_err(iter->dir->i_sb, 481 "block %llu not allocated in directory (ino %lu)\n", 482 (unsigned long long)block, iter->dir->i_ino); 483 return -EFSCORRUPTED; 484 } 485 if (!(iter->pos & (blksize - 1))) { 486 brelse(iter->bh[0]); 487 iter->bh[0] = bh; 488 } else { 489 iter->bh[1] = bh; 490 } 491 return 0; 492 } 493 494 struct short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset, 495 int inc) 496 { 497 struct short_ad *sa; 498 499 if ((!ptr) || (!offset)) { 500 pr_err("%s: invalidparms\n", __func__); 501 return NULL; 502 } 503 504 if ((*offset + sizeof(struct short_ad)) > maxoffset) 505 return NULL; 506 else { 507 sa = (struct short_ad *)ptr; 508 if (sa->extLength == 0) 509 return NULL; 510 } 511 512 if (inc) 513 *offset += sizeof(struct short_ad); 514 return sa; 515 } 516 517 struct long_ad *udf_get_filelongad(uint8_t *ptr, int maxoffset, uint32_t *offset, int inc) 518 { 519 struct long_ad *la; 520 521 if ((!ptr) || (!offset)) { 522 pr_err("%s: invalidparms\n", __func__); 523 return NULL; 524 } 525 526 if ((*offset + sizeof(struct long_ad)) > maxoffset) 527 return NULL; 528 else { 529 la = (struct long_ad *)ptr; 530 if (la->extLength == 0) 531 return NULL; 532 } 533 534 if (inc) 535 *offset += sizeof(struct long_ad); 536 return la; 537 } 538