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