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 iter->namebuf = kmalloc(UDF_NAME_LEN_CS0, GFP_KERNEL); 255 if (!iter->namebuf) 256 return -ENOMEM; 257 258 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 259 err = udf_copy_fi(iter); 260 goto out; 261 } 262 263 if (inode_bmap(dir, iter->pos >> dir->i_blkbits, &iter->epos, 264 &iter->eloc, &iter->elen, &iter->loffset) != 265 (EXT_RECORDED_ALLOCATED >> 30)) { 266 if (pos == dir->i_size) 267 return 0; 268 udf_err(dir->i_sb, 269 "position %llu not allocated in directory (ino %lu)\n", 270 (unsigned long long)pos, dir->i_ino); 271 err = -EFSCORRUPTED; 272 goto out; 273 } 274 err = udf_fiiter_load_bhs(iter); 275 if (err < 0) 276 goto out; 277 err = udf_copy_fi(iter); 278 out: 279 if (err < 0) 280 udf_fiiter_release(iter); 281 return err; 282 } 283 284 int udf_fiiter_advance(struct udf_fileident_iter *iter) 285 { 286 unsigned int oldoff, len; 287 int blksize = 1 << iter->dir->i_blkbits; 288 int err; 289 290 oldoff = iter->pos & (blksize - 1); 291 len = udf_dir_entry_len(&iter->fi); 292 iter->pos += len; 293 if (UDF_I(iter->dir)->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { 294 if (oldoff + len >= blksize) { 295 brelse(iter->bh[0]); 296 iter->bh[0] = NULL; 297 /* Next block already loaded? */ 298 if (iter->bh[1]) { 299 iter->bh[0] = iter->bh[1]; 300 iter->bh[1] = NULL; 301 } else { 302 err = udf_fiiter_advance_blk(iter); 303 if (err < 0) 304 return err; 305 } 306 } 307 err = udf_fiiter_load_bhs(iter); 308 if (err < 0) 309 return err; 310 } 311 return udf_copy_fi(iter); 312 } 313 314 void udf_fiiter_release(struct udf_fileident_iter *iter) 315 { 316 iter->dir = NULL; 317 brelse(iter->bh[0]); 318 brelse(iter->bh[1]); 319 iter->bh[0] = iter->bh[1] = NULL; 320 kfree(iter->namebuf); 321 iter->namebuf = NULL; 322 } 323 324 static void udf_copy_to_bufs(void *buf1, int len1, void *buf2, int len2, 325 int off, void *src, int len) 326 { 327 int copy; 328 329 if (off >= len1) { 330 off -= len1; 331 } else { 332 copy = min(off + len, len1) - off; 333 memcpy(buf1 + off, src, copy); 334 src += copy; 335 len -= copy; 336 off = 0; 337 } 338 if (len > 0) { 339 if (WARN_ON_ONCE(off + len > len2 || !buf2)) 340 return; 341 memcpy(buf2 + off, src, len); 342 } 343 } 344 345 static uint16_t udf_crc_fi_bufs(void *buf1, int len1, void *buf2, int len2, 346 int off, int len) 347 { 348 int copy; 349 uint16_t crc = 0; 350 351 if (off >= len1) { 352 off -= len1; 353 } else { 354 copy = min(off + len, len1) - off; 355 crc = crc_itu_t(crc, buf1 + off, copy); 356 len -= copy; 357 off = 0; 358 } 359 if (len > 0) { 360 if (WARN_ON_ONCE(off + len > len2 || !buf2)) 361 return 0; 362 crc = crc_itu_t(crc, buf2 + off, len); 363 } 364 return crc; 365 } 366 367 static void udf_copy_fi_to_bufs(char *buf1, int len1, char *buf2, int len2, 368 int off, struct fileIdentDesc *fi, 369 uint8_t *impuse, uint8_t *name) 370 { 371 uint16_t crc; 372 int fioff = off; 373 int crcoff = off + sizeof(struct tag); 374 unsigned int crclen = udf_dir_entry_len(fi) - sizeof(struct tag); 375 char zeros[UDF_NAME_PAD] = {}; 376 int endoff = off + udf_dir_entry_len(fi); 377 378 udf_copy_to_bufs(buf1, len1, buf2, len2, off, fi, 379 sizeof(struct fileIdentDesc)); 380 off += sizeof(struct fileIdentDesc); 381 if (impuse) 382 udf_copy_to_bufs(buf1, len1, buf2, len2, off, impuse, 383 le16_to_cpu(fi->lengthOfImpUse)); 384 off += le16_to_cpu(fi->lengthOfImpUse); 385 if (name) { 386 udf_copy_to_bufs(buf1, len1, buf2, len2, off, name, 387 fi->lengthFileIdent); 388 off += fi->lengthFileIdent; 389 udf_copy_to_bufs(buf1, len1, buf2, len2, off, zeros, 390 endoff - off); 391 } 392 393 crc = udf_crc_fi_bufs(buf1, len1, buf2, len2, crcoff, crclen); 394 fi->descTag.descCRC = cpu_to_le16(crc); 395 fi->descTag.descCRCLength = cpu_to_le16(crclen); 396 fi->descTag.tagChecksum = udf_tag_checksum(&fi->descTag); 397 398 udf_copy_to_bufs(buf1, len1, buf2, len2, fioff, fi, sizeof(struct tag)); 399 } 400 401 void udf_fiiter_write_fi(struct udf_fileident_iter *iter, uint8_t *impuse) 402 { 403 struct udf_inode_info *iinfo = UDF_I(iter->dir); 404 void *buf1, *buf2 = NULL; 405 int len1, len2 = 0, off; 406 int blksize = 1 << iter->dir->i_blkbits; 407 408 off = iter->pos & (blksize - 1); 409 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 410 buf1 = iinfo->i_data + iinfo->i_lenEAttr; 411 len1 = iter->dir->i_size; 412 } else { 413 buf1 = iter->bh[0]->b_data; 414 len1 = blksize; 415 if (iter->bh[1]) { 416 buf2 = iter->bh[1]->b_data; 417 len2 = blksize; 418 } 419 } 420 421 udf_copy_fi_to_bufs(buf1, len1, buf2, len2, off, &iter->fi, impuse, 422 iter->name == iter->namebuf ? iter->name : NULL); 423 424 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { 425 mark_inode_dirty(iter->dir); 426 } else { 427 mark_buffer_dirty_inode(iter->bh[0], iter->dir); 428 if (iter->bh[1]) 429 mark_buffer_dirty_inode(iter->bh[1], iter->dir); 430 } 431 inode_inc_iversion(iter->dir); 432 } 433 434 void udf_fiiter_update_elen(struct udf_fileident_iter *iter, uint32_t new_elen) 435 { 436 struct udf_inode_info *iinfo = UDF_I(iter->dir); 437 int diff = new_elen - iter->elen; 438 439 /* Skip update when we already went past the last extent */ 440 if (!iter->elen) 441 return; 442 iter->elen = new_elen; 443 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) 444 iter->epos.offset -= sizeof(struct short_ad); 445 else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) 446 iter->epos.offset -= sizeof(struct long_ad); 447 udf_write_aext(iter->dir, &iter->epos, &iter->eloc, iter->elen, 1); 448 iinfo->i_lenExtents += diff; 449 mark_inode_dirty(iter->dir); 450 } 451 452 /* Append new block to directory. @iter is expected to point at EOF */ 453 int udf_fiiter_append_blk(struct udf_fileident_iter *iter) 454 { 455 struct udf_inode_info *iinfo = UDF_I(iter->dir); 456 int blksize = 1 << iter->dir->i_blkbits; 457 struct buffer_head *bh; 458 sector_t block; 459 uint32_t old_elen = iter->elen; 460 int err; 461 462 if (WARN_ON_ONCE(iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)) 463 return -EINVAL; 464 465 /* Round up last extent in the file */ 466 udf_fiiter_update_elen(iter, ALIGN(iter->elen, blksize)); 467 468 /* Allocate new block and refresh mapping information */ 469 block = iinfo->i_lenExtents >> iter->dir->i_blkbits; 470 bh = udf_bread(iter->dir, block, 1, &err); 471 if (!bh) { 472 udf_fiiter_update_elen(iter, old_elen); 473 return err; 474 } 475 if (inode_bmap(iter->dir, block, &iter->epos, &iter->eloc, &iter->elen, 476 &iter->loffset) != (EXT_RECORDED_ALLOCATED >> 30)) { 477 udf_err(iter->dir->i_sb, 478 "block %llu not allocated in directory (ino %lu)\n", 479 (unsigned long long)block, iter->dir->i_ino); 480 return -EFSCORRUPTED; 481 } 482 if (!(iter->pos & (blksize - 1))) { 483 brelse(iter->bh[0]); 484 iter->bh[0] = bh; 485 } else { 486 iter->bh[1] = bh; 487 } 488 return 0; 489 } 490 491 struct short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset, 492 int inc) 493 { 494 struct short_ad *sa; 495 496 if ((!ptr) || (!offset)) { 497 pr_err("%s: invalidparms\n", __func__); 498 return NULL; 499 } 500 501 if ((*offset + sizeof(struct short_ad)) > maxoffset) 502 return NULL; 503 else { 504 sa = (struct short_ad *)ptr; 505 if (sa->extLength == 0) 506 return NULL; 507 } 508 509 if (inc) 510 *offset += sizeof(struct short_ad); 511 return sa; 512 } 513 514 struct long_ad *udf_get_filelongad(uint8_t *ptr, int maxoffset, uint32_t *offset, int inc) 515 { 516 struct long_ad *la; 517 518 if ((!ptr) || (!offset)) { 519 pr_err("%s: invalidparms\n", __func__); 520 return NULL; 521 } 522 523 if ((*offset + sizeof(struct long_ad)) > maxoffset) 524 return NULL; 525 else { 526 la = (struct long_ad *)ptr; 527 if (la->extLength == 0) 528 return NULL; 529 } 530 531 if (inc) 532 *offset += sizeof(struct long_ad); 533 return la; 534 } 535