1 /* 2 * namei.c 3 * 4 * PURPOSE 5 * Inode name handling routines for the OSTA-UDF(tm) filesystem. 6 * 7 * CONTACTS 8 * E-mail regarding any portion of the Linux UDF file system should be 9 * directed to the development team mailing list (run by majordomo): 10 * linux_udf@hpesjro.fc.hp.com 11 * 12 * COPYRIGHT 13 * This file is distributed under the terms of the GNU General Public 14 * License (GPL). Copies of the GPL can be obtained from: 15 * ftp://prep.ai.mit.edu/pub/gnu/GPL 16 * Each contributing author retains all rights to their own work. 17 * 18 * (C) 1998-2004 Ben Fennema 19 * (C) 1999-2000 Stelias Computing Inc 20 * 21 * HISTORY 22 * 23 * 12/12/98 blf Created. Split out the lookup code from dir.c 24 * 04/19/99 blf link, mknod, symlink support 25 */ 26 27 #include "udfdecl.h" 28 29 #include "udf_i.h" 30 #include "udf_sb.h" 31 #include <linux/string.h> 32 #include <linux/errno.h> 33 #include <linux/mm.h> 34 #include <linux/slab.h> 35 #include <linux/quotaops.h> 36 #include <linux/smp_lock.h> 37 #include <linux/buffer_head.h> 38 39 static inline int udf_match(int len1, const char *name1, int len2, const char *name2) 40 { 41 if (len1 != len2) 42 return 0; 43 return !memcmp(name1, name2, len1); 44 } 45 46 int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi, 47 struct fileIdentDesc *sfi, struct udf_fileident_bh *fibh, 48 uint8_t *impuse, uint8_t *fileident) 49 { 50 uint16_t crclen = fibh->eoffset - fibh->soffset - sizeof(tag); 51 uint16_t crc; 52 uint8_t checksum = 0; 53 int i; 54 int offset; 55 uint16_t liu = le16_to_cpu(cfi->lengthOfImpUse); 56 uint8_t lfi = cfi->lengthFileIdent; 57 int padlen = fibh->eoffset - fibh->soffset - liu - lfi - 58 sizeof(struct fileIdentDesc); 59 int adinicb = 0; 60 61 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) 62 adinicb = 1; 63 64 offset = fibh->soffset + sizeof(struct fileIdentDesc); 65 66 if (impuse) 67 { 68 if (adinicb || (offset + liu < 0)) 69 memcpy((uint8_t *)sfi->impUse, impuse, liu); 70 else if (offset >= 0) 71 memcpy(fibh->ebh->b_data + offset, impuse, liu); 72 else 73 { 74 memcpy((uint8_t *)sfi->impUse, impuse, -offset); 75 memcpy(fibh->ebh->b_data, impuse - offset, liu + offset); 76 } 77 } 78 79 offset += liu; 80 81 if (fileident) 82 { 83 if (adinicb || (offset + lfi < 0)) 84 memcpy((uint8_t *)sfi->fileIdent + liu, fileident, lfi); 85 else if (offset >= 0) 86 memcpy(fibh->ebh->b_data + offset, fileident, lfi); 87 else 88 { 89 memcpy((uint8_t *)sfi->fileIdent + liu, fileident, -offset); 90 memcpy(fibh->ebh->b_data, fileident - offset, lfi + offset); 91 } 92 } 93 94 offset += lfi; 95 96 if (adinicb || (offset + padlen < 0)) 97 memset((uint8_t *)sfi->padding + liu + lfi, 0x00, padlen); 98 else if (offset >= 0) 99 memset(fibh->ebh->b_data + offset, 0x00, padlen); 100 else 101 { 102 memset((uint8_t *)sfi->padding + liu + lfi, 0x00, -offset); 103 memset(fibh->ebh->b_data, 0x00, padlen + offset); 104 } 105 106 crc = udf_crc((uint8_t *)cfi + sizeof(tag), sizeof(struct fileIdentDesc) - 107 sizeof(tag), 0); 108 109 if (fibh->sbh == fibh->ebh) 110 crc = udf_crc((uint8_t *)sfi->impUse, 111 crclen + sizeof(tag) - sizeof(struct fileIdentDesc), crc); 112 else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) 113 crc = udf_crc(fibh->ebh->b_data + sizeof(struct fileIdentDesc) + fibh->soffset, 114 crclen + sizeof(tag) - sizeof(struct fileIdentDesc), crc); 115 else 116 { 117 crc = udf_crc((uint8_t *)sfi->impUse, 118 -fibh->soffset - sizeof(struct fileIdentDesc), crc); 119 crc = udf_crc(fibh->ebh->b_data, fibh->eoffset, crc); 120 } 121 122 cfi->descTag.descCRC = cpu_to_le16(crc); 123 cfi->descTag.descCRCLength = cpu_to_le16(crclen); 124 125 for (i=0; i<16; i++) 126 if (i != 4) 127 checksum += ((uint8_t *)&cfi->descTag)[i]; 128 129 cfi->descTag.tagChecksum = checksum; 130 if (adinicb || (sizeof(struct fileIdentDesc) <= -fibh->soffset)) 131 memcpy((uint8_t *)sfi, (uint8_t *)cfi, sizeof(struct fileIdentDesc)); 132 else 133 { 134 memcpy((uint8_t *)sfi, (uint8_t *)cfi, -fibh->soffset); 135 memcpy(fibh->ebh->b_data, (uint8_t *)cfi - fibh->soffset, 136 sizeof(struct fileIdentDesc) + fibh->soffset); 137 } 138 139 if (adinicb) 140 mark_inode_dirty(inode); 141 else 142 { 143 if (fibh->sbh != fibh->ebh) 144 mark_buffer_dirty_inode(fibh->ebh, inode); 145 mark_buffer_dirty_inode(fibh->sbh, inode); 146 } 147 return 0; 148 } 149 150 static struct fileIdentDesc * 151 udf_find_entry(struct inode *dir, struct dentry *dentry, 152 struct udf_fileident_bh *fibh, 153 struct fileIdentDesc *cfi) 154 { 155 struct fileIdentDesc *fi=NULL; 156 loff_t f_pos; 157 int block, flen; 158 char fname[UDF_NAME_LEN]; 159 char *nameptr; 160 uint8_t lfi; 161 uint16_t liu; 162 loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; 163 kernel_lb_addr bloc, eloc; 164 uint32_t extoffset, elen, offset; 165 struct buffer_head *bh = NULL; 166 167 if (!dir) 168 return NULL; 169 170 f_pos = (udf_ext0_offset(dir) >> 2); 171 172 fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; 173 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) 174 fibh->sbh = fibh->ebh = NULL; 175 else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 176 &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) 177 { 178 offset >>= dir->i_sb->s_blocksize_bits; 179 block = udf_get_lb_pblock(dir->i_sb, eloc, offset); 180 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) 181 { 182 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) 183 extoffset -= sizeof(short_ad); 184 else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) 185 extoffset -= sizeof(long_ad); 186 } 187 else 188 offset = 0; 189 190 if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) 191 { 192 udf_release_data(bh); 193 return NULL; 194 } 195 } 196 else 197 { 198 udf_release_data(bh); 199 return NULL; 200 } 201 202 while ( (f_pos < size) ) 203 { 204 fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh); 205 206 if (!fi) 207 { 208 if (fibh->sbh != fibh->ebh) 209 udf_release_data(fibh->ebh); 210 udf_release_data(fibh->sbh); 211 udf_release_data(bh); 212 return NULL; 213 } 214 215 liu = le16_to_cpu(cfi->lengthOfImpUse); 216 lfi = cfi->lengthFileIdent; 217 218 if (fibh->sbh == fibh->ebh) 219 { 220 nameptr = fi->fileIdent + liu; 221 } 222 else 223 { 224 int poffset; /* Unpaded ending offset */ 225 226 poffset = fibh->soffset + sizeof(struct fileIdentDesc) + liu + lfi; 227 228 if (poffset >= lfi) 229 nameptr = (uint8_t *)(fibh->ebh->b_data + poffset - lfi); 230 else 231 { 232 nameptr = fname; 233 memcpy(nameptr, fi->fileIdent + liu, lfi - poffset); 234 memcpy(nameptr + lfi - poffset, fibh->ebh->b_data, poffset); 235 } 236 } 237 238 if ( (cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0 ) 239 { 240 if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE) ) 241 continue; 242 } 243 244 if ( (cfi->fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0 ) 245 { 246 if ( !UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE) ) 247 continue; 248 } 249 250 if (!lfi) 251 continue; 252 253 if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi))) 254 { 255 if (udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) 256 { 257 udf_release_data(bh); 258 return fi; 259 } 260 } 261 } 262 if (fibh->sbh != fibh->ebh) 263 udf_release_data(fibh->ebh); 264 udf_release_data(fibh->sbh); 265 udf_release_data(bh); 266 return NULL; 267 } 268 269 /* 270 * udf_lookup 271 * 272 * PURPOSE 273 * Look-up the inode for a given name. 274 * 275 * DESCRIPTION 276 * Required - lookup_dentry() will return -ENOTDIR if this routine is not 277 * available for a directory. The filesystem is useless if this routine is 278 * not available for at least the filesystem's root directory. 279 * 280 * This routine is passed an incomplete dentry - it must be completed by 281 * calling d_add(dentry, inode). If the name does not exist, then the 282 * specified inode must be set to null. An error should only be returned 283 * when the lookup fails for a reason other than the name not existing. 284 * Note that the directory inode semaphore is held during the call. 285 * 286 * Refer to lookup_dentry() in fs/namei.c 287 * lookup_dentry() -> lookup() -> real_lookup() -> . 288 * 289 * PRE-CONDITIONS 290 * dir Pointer to inode of parent directory. 291 * dentry Pointer to dentry to complete. 292 * nd Pointer to lookup nameidata 293 * 294 * POST-CONDITIONS 295 * <return> Zero on success. 296 * 297 * HISTORY 298 * July 1, 1997 - Andrew E. Mileski 299 * Written, tested, and released. 300 */ 301 302 static struct dentry * 303 udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) 304 { 305 struct inode *inode = NULL; 306 struct fileIdentDesc cfi, *fi; 307 struct udf_fileident_bh fibh; 308 309 if (dentry->d_name.len > UDF_NAME_LEN-2) 310 return ERR_PTR(-ENAMETOOLONG); 311 312 lock_kernel(); 313 #ifdef UDF_RECOVERY 314 /* temporary shorthand for specifying files by inode number */ 315 if (!strncmp(dentry->d_name.name, ".B=", 3) ) 316 { 317 kernel_lb_addr lb = { 0, simple_strtoul(dentry->d_name.name+3, NULL, 0) }; 318 inode = udf_iget(dir->i_sb, lb); 319 if (!inode) 320 { 321 unlock_kernel(); 322 return ERR_PTR(-EACCES); 323 } 324 } 325 else 326 #endif /* UDF_RECOVERY */ 327 328 if ((fi = udf_find_entry(dir, dentry, &fibh, &cfi))) 329 { 330 if (fibh.sbh != fibh.ebh) 331 udf_release_data(fibh.ebh); 332 udf_release_data(fibh.sbh); 333 334 inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation)); 335 if ( !inode ) 336 { 337 unlock_kernel(); 338 return ERR_PTR(-EACCES); 339 } 340 } 341 unlock_kernel(); 342 d_add(dentry, inode); 343 return NULL; 344 } 345 346 static struct fileIdentDesc * 347 udf_add_entry(struct inode *dir, struct dentry *dentry, 348 struct udf_fileident_bh *fibh, 349 struct fileIdentDesc *cfi, int *err) 350 { 351 struct super_block *sb; 352 struct fileIdentDesc *fi=NULL; 353 char name[UDF_NAME_LEN], fname[UDF_NAME_LEN]; 354 int namelen; 355 loff_t f_pos; 356 int flen; 357 char *nameptr; 358 loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; 359 int nfidlen; 360 uint8_t lfi; 361 uint16_t liu; 362 int block; 363 kernel_lb_addr bloc, eloc; 364 uint32_t extoffset, elen, offset; 365 struct buffer_head *bh = NULL; 366 367 sb = dir->i_sb; 368 369 if (dentry) 370 { 371 if (!dentry->d_name.len) 372 { 373 *err = -EINVAL; 374 return NULL; 375 } 376 377 if ( !(namelen = udf_put_filename(sb, dentry->d_name.name, name, dentry->d_name.len))) 378 { 379 *err = -ENAMETOOLONG; 380 return NULL; 381 } 382 } 383 else 384 namelen = 0; 385 386 nfidlen = (sizeof(struct fileIdentDesc) + namelen + 3) & ~3; 387 388 f_pos = (udf_ext0_offset(dir) >> 2); 389 390 fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; 391 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) 392 fibh->sbh = fibh->ebh = NULL; 393 else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 394 &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) 395 { 396 offset >>= dir->i_sb->s_blocksize_bits; 397 block = udf_get_lb_pblock(dir->i_sb, eloc, offset); 398 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) 399 { 400 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) 401 extoffset -= sizeof(short_ad); 402 else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) 403 extoffset -= sizeof(long_ad); 404 } 405 else 406 offset = 0; 407 408 if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) 409 { 410 udf_release_data(bh); 411 *err = -EIO; 412 return NULL; 413 } 414 415 block = UDF_I_LOCATION(dir).logicalBlockNum; 416 417 } 418 else 419 { 420 block = udf_get_lb_pblock(dir->i_sb, UDF_I_LOCATION(dir), 0); 421 fibh->sbh = fibh->ebh = NULL; 422 fibh->soffset = fibh->eoffset = sb->s_blocksize; 423 goto add; 424 } 425 426 while ( (f_pos < size) ) 427 { 428 fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh); 429 430 if (!fi) 431 { 432 if (fibh->sbh != fibh->ebh) 433 udf_release_data(fibh->ebh); 434 udf_release_data(fibh->sbh); 435 udf_release_data(bh); 436 *err = -EIO; 437 return NULL; 438 } 439 440 liu = le16_to_cpu(cfi->lengthOfImpUse); 441 lfi = cfi->lengthFileIdent; 442 443 if (fibh->sbh == fibh->ebh) 444 nameptr = fi->fileIdent + liu; 445 else 446 { 447 int poffset; /* Unpaded ending offset */ 448 449 poffset = fibh->soffset + sizeof(struct fileIdentDesc) + liu + lfi; 450 451 if (poffset >= lfi) 452 nameptr = (char *)(fibh->ebh->b_data + poffset - lfi); 453 else 454 { 455 nameptr = fname; 456 memcpy(nameptr, fi->fileIdent + liu, lfi - poffset); 457 memcpy(nameptr + lfi - poffset, fibh->ebh->b_data, poffset); 458 } 459 } 460 461 if ( (cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0 ) 462 { 463 if (((sizeof(struct fileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen) 464 { 465 udf_release_data(bh); 466 cfi->descTag.tagSerialNum = cpu_to_le16(1); 467 cfi->fileVersionNum = cpu_to_le16(1); 468 cfi->fileCharacteristics = 0; 469 cfi->lengthFileIdent = namelen; 470 cfi->lengthOfImpUse = cpu_to_le16(0); 471 if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) 472 return fi; 473 else 474 { 475 *err = -EIO; 476 return NULL; 477 } 478 } 479 } 480 481 if (!lfi || !dentry) 482 continue; 483 484 if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi)) && 485 udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) 486 { 487 if (fibh->sbh != fibh->ebh) 488 udf_release_data(fibh->ebh); 489 udf_release_data(fibh->sbh); 490 udf_release_data(bh); 491 *err = -EEXIST; 492 return NULL; 493 } 494 } 495 496 add: 497 f_pos += nfidlen; 498 499 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB && 500 sb->s_blocksize - fibh->eoffset < nfidlen) 501 { 502 udf_release_data(bh); 503 bh = NULL; 504 fibh->soffset -= udf_ext0_offset(dir); 505 fibh->eoffset -= udf_ext0_offset(dir); 506 f_pos -= (udf_ext0_offset(dir) >> 2); 507 if (fibh->sbh != fibh->ebh) 508 udf_release_data(fibh->ebh); 509 udf_release_data(fibh->sbh); 510 if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err))) 511 return NULL; 512 bloc = UDF_I_LOCATION(dir); 513 eloc.logicalBlockNum = block; 514 eloc.partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum; 515 elen = dir->i_sb->s_blocksize; 516 extoffset = udf_file_entry_alloc_offset(dir); 517 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) 518 extoffset += sizeof(short_ad); 519 else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) 520 extoffset += sizeof(long_ad); 521 } 522 523 if (sb->s_blocksize - fibh->eoffset >= nfidlen) 524 { 525 fibh->soffset = fibh->eoffset; 526 fibh->eoffset += nfidlen; 527 if (fibh->sbh != fibh->ebh) 528 { 529 udf_release_data(fibh->sbh); 530 fibh->sbh = fibh->ebh; 531 } 532 533 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) 534 { 535 block = UDF_I_LOCATION(dir).logicalBlockNum; 536 fi = (struct fileIdentDesc *)(UDF_I_DATA(dir) + fibh->soffset - udf_ext0_offset(dir) + UDF_I_LENEATTR(dir)); 537 } 538 else 539 { 540 block = eloc.logicalBlockNum + ((elen - 1) >> 541 dir->i_sb->s_blocksize_bits); 542 fi = (struct fileIdentDesc *)(fibh->sbh->b_data + fibh->soffset); 543 } 544 } 545 else 546 { 547 fibh->soffset = fibh->eoffset - sb->s_blocksize; 548 fibh->eoffset += nfidlen - sb->s_blocksize; 549 if (fibh->sbh != fibh->ebh) 550 { 551 udf_release_data(fibh->sbh); 552 fibh->sbh = fibh->ebh; 553 } 554 555 block = eloc.logicalBlockNum + ((elen - 1) >> 556 dir->i_sb->s_blocksize_bits); 557 558 if (!(fibh->ebh = udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 1, err))) 559 { 560 udf_release_data(bh); 561 udf_release_data(fibh->sbh); 562 return NULL; 563 } 564 565 if (!(fibh->soffset)) 566 { 567 if (udf_next_aext(dir, &bloc, &extoffset, &eloc, &elen, &bh, 1) == 568 (EXT_RECORDED_ALLOCATED >> 30)) 569 { 570 block = eloc.logicalBlockNum + ((elen - 1) >> 571 dir->i_sb->s_blocksize_bits); 572 } 573 else 574 block ++; 575 576 udf_release_data(fibh->sbh); 577 fibh->sbh = fibh->ebh; 578 fi = (struct fileIdentDesc *)(fibh->sbh->b_data); 579 } 580 else 581 { 582 fi = (struct fileIdentDesc *) 583 (fibh->sbh->b_data + sb->s_blocksize + fibh->soffset); 584 } 585 } 586 587 memset(cfi, 0, sizeof(struct fileIdentDesc)); 588 if (UDF_SB_UDFREV(sb) >= 0x0200) 589 udf_new_tag((char *)cfi, TAG_IDENT_FID, 3, 1, block, sizeof(tag)); 590 else 591 udf_new_tag((char *)cfi, TAG_IDENT_FID, 2, 1, block, sizeof(tag)); 592 cfi->fileVersionNum = cpu_to_le16(1); 593 cfi->lengthFileIdent = namelen; 594 cfi->lengthOfImpUse = cpu_to_le16(0); 595 if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) 596 { 597 udf_release_data(bh); 598 dir->i_size += nfidlen; 599 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) 600 UDF_I_LENALLOC(dir) += nfidlen; 601 mark_inode_dirty(dir); 602 return fi; 603 } 604 else 605 { 606 udf_release_data(bh); 607 if (fibh->sbh != fibh->ebh) 608 udf_release_data(fibh->ebh); 609 udf_release_data(fibh->sbh); 610 *err = -EIO; 611 return NULL; 612 } 613 } 614 615 static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi, 616 struct udf_fileident_bh *fibh, struct fileIdentDesc *cfi) 617 { 618 cfi->fileCharacteristics |= FID_FILE_CHAR_DELETED; 619 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)) 620 memset(&(cfi->icb), 0x00, sizeof(long_ad)); 621 return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL); 622 } 623 624 static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) 625 { 626 struct udf_fileident_bh fibh; 627 struct inode *inode; 628 struct fileIdentDesc cfi, *fi; 629 int err; 630 631 lock_kernel(); 632 inode = udf_new_inode(dir, mode, &err); 633 if (!inode) 634 { 635 unlock_kernel(); 636 return err; 637 } 638 639 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) 640 inode->i_data.a_ops = &udf_adinicb_aops; 641 else 642 inode->i_data.a_ops = &udf_aops; 643 inode->i_op = &udf_file_inode_operations; 644 inode->i_fop = &udf_file_operations; 645 inode->i_mode = mode; 646 mark_inode_dirty(inode); 647 648 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) 649 { 650 inode->i_nlink --; 651 mark_inode_dirty(inode); 652 iput(inode); 653 unlock_kernel(); 654 return err; 655 } 656 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); 657 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode)); 658 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = 659 cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL); 660 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); 661 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) 662 { 663 mark_inode_dirty(dir); 664 } 665 if (fibh.sbh != fibh.ebh) 666 udf_release_data(fibh.ebh); 667 udf_release_data(fibh.sbh); 668 unlock_kernel(); 669 d_instantiate(dentry, inode); 670 return 0; 671 } 672 673 static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t rdev) 674 { 675 struct inode * inode; 676 struct udf_fileident_bh fibh; 677 struct fileIdentDesc cfi, *fi; 678 int err; 679 680 if (!old_valid_dev(rdev)) 681 return -EINVAL; 682 683 lock_kernel(); 684 err = -EIO; 685 inode = udf_new_inode(dir, mode, &err); 686 if (!inode) 687 goto out; 688 689 inode->i_uid = current->fsuid; 690 init_special_inode(inode, mode, rdev); 691 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) 692 { 693 inode->i_nlink --; 694 mark_inode_dirty(inode); 695 iput(inode); 696 unlock_kernel(); 697 return err; 698 } 699 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); 700 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode)); 701 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = 702 cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL); 703 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); 704 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) 705 { 706 mark_inode_dirty(dir); 707 } 708 mark_inode_dirty(inode); 709 710 if (fibh.sbh != fibh.ebh) 711 udf_release_data(fibh.ebh); 712 udf_release_data(fibh.sbh); 713 d_instantiate(dentry, inode); 714 err = 0; 715 out: 716 unlock_kernel(); 717 return err; 718 } 719 720 static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode) 721 { 722 struct inode * inode; 723 struct udf_fileident_bh fibh; 724 struct fileIdentDesc cfi, *fi; 725 int err; 726 727 lock_kernel(); 728 err = -EMLINK; 729 if (dir->i_nlink >= (256<<sizeof(dir->i_nlink))-1) 730 goto out; 731 732 err = -EIO; 733 inode = udf_new_inode(dir, S_IFDIR, &err); 734 if (!inode) 735 goto out; 736 737 inode->i_op = &udf_dir_inode_operations; 738 inode->i_fop = &udf_dir_operations; 739 if (!(fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err))) 740 { 741 inode->i_nlink--; 742 mark_inode_dirty(inode); 743 iput(inode); 744 goto out; 745 } 746 inode->i_nlink = 2; 747 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); 748 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(dir)); 749 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = 750 cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL); 751 cfi.fileCharacteristics = FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT; 752 udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL); 753 udf_release_data(fibh.sbh); 754 inode->i_mode = S_IFDIR | mode; 755 if (dir->i_mode & S_ISGID) 756 inode->i_mode |= S_ISGID; 757 mark_inode_dirty(inode); 758 759 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) 760 { 761 inode->i_nlink = 0; 762 mark_inode_dirty(inode); 763 iput(inode); 764 goto out; 765 } 766 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); 767 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode)); 768 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = 769 cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL); 770 cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY; 771 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); 772 dir->i_nlink++; 773 mark_inode_dirty(dir); 774 d_instantiate(dentry, inode); 775 if (fibh.sbh != fibh.ebh) 776 udf_release_data(fibh.ebh); 777 udf_release_data(fibh.sbh); 778 err = 0; 779 out: 780 unlock_kernel(); 781 return err; 782 } 783 784 static int empty_dir(struct inode *dir) 785 { 786 struct fileIdentDesc *fi, cfi; 787 struct udf_fileident_bh fibh; 788 loff_t f_pos; 789 loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; 790 int block; 791 kernel_lb_addr bloc, eloc; 792 uint32_t extoffset, elen, offset; 793 struct buffer_head *bh = NULL; 794 795 f_pos = (udf_ext0_offset(dir) >> 2); 796 797 fibh.soffset = fibh.eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; 798 799 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) 800 fibh.sbh = fibh.ebh = NULL; 801 else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 802 &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30)) 803 { 804 offset >>= dir->i_sb->s_blocksize_bits; 805 block = udf_get_lb_pblock(dir->i_sb, eloc, offset); 806 if ((++offset << dir->i_sb->s_blocksize_bits) < elen) 807 { 808 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT) 809 extoffset -= sizeof(short_ad); 810 else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG) 811 extoffset -= sizeof(long_ad); 812 } 813 else 814 offset = 0; 815 816 if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) 817 { 818 udf_release_data(bh); 819 return 0; 820 } 821 } 822 else 823 { 824 udf_release_data(bh); 825 return 0; 826 } 827 828 829 while ( (f_pos < size) ) 830 { 831 fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh); 832 833 if (!fi) 834 { 835 if (fibh.sbh != fibh.ebh) 836 udf_release_data(fibh.ebh); 837 udf_release_data(fibh.sbh); 838 udf_release_data(bh); 839 return 0; 840 } 841 842 if (cfi.lengthFileIdent && (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0) 843 { 844 if (fibh.sbh != fibh.ebh) 845 udf_release_data(fibh.ebh); 846 udf_release_data(fibh.sbh); 847 udf_release_data(bh); 848 return 0; 849 } 850 } 851 if (fibh.sbh != fibh.ebh) 852 udf_release_data(fibh.ebh); 853 udf_release_data(fibh.sbh); 854 udf_release_data(bh); 855 return 1; 856 } 857 858 static int udf_rmdir(struct inode * dir, struct dentry * dentry) 859 { 860 int retval; 861 struct inode * inode = dentry->d_inode; 862 struct udf_fileident_bh fibh; 863 struct fileIdentDesc *fi, cfi; 864 kernel_lb_addr tloc; 865 866 retval = -ENOENT; 867 lock_kernel(); 868 fi = udf_find_entry(dir, dentry, &fibh, &cfi); 869 if (!fi) 870 goto out; 871 872 retval = -EIO; 873 tloc = lelb_to_cpu(cfi.icb.extLocation); 874 if (udf_get_lb_pblock(dir->i_sb, tloc, 0) != inode->i_ino) 875 goto end_rmdir; 876 retval = -ENOTEMPTY; 877 if (!empty_dir(inode)) 878 goto end_rmdir; 879 retval = udf_delete_entry(dir, fi, &fibh, &cfi); 880 if (retval) 881 goto end_rmdir; 882 if (inode->i_nlink != 2) 883 udf_warning(inode->i_sb, "udf_rmdir", 884 "empty directory has nlink != 2 (%d)", 885 inode->i_nlink); 886 inode->i_nlink = 0; 887 inode->i_size = 0; 888 mark_inode_dirty(inode); 889 dir->i_nlink --; 890 inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); 891 mark_inode_dirty(dir); 892 893 end_rmdir: 894 if (fibh.sbh != fibh.ebh) 895 udf_release_data(fibh.ebh); 896 udf_release_data(fibh.sbh); 897 out: 898 unlock_kernel(); 899 return retval; 900 } 901 902 static int udf_unlink(struct inode * dir, struct dentry * dentry) 903 { 904 int retval; 905 struct inode * inode = dentry->d_inode; 906 struct udf_fileident_bh fibh; 907 struct fileIdentDesc *fi; 908 struct fileIdentDesc cfi; 909 kernel_lb_addr tloc; 910 911 retval = -ENOENT; 912 lock_kernel(); 913 fi = udf_find_entry(dir, dentry, &fibh, &cfi); 914 if (!fi) 915 goto out; 916 917 retval = -EIO; 918 tloc = lelb_to_cpu(cfi.icb.extLocation); 919 if (udf_get_lb_pblock(dir->i_sb, tloc, 0) != inode->i_ino) 920 goto end_unlink; 921 922 if (!inode->i_nlink) 923 { 924 udf_debug("Deleting nonexistent file (%lu), %d\n", 925 inode->i_ino, inode->i_nlink); 926 inode->i_nlink = 1; 927 } 928 retval = udf_delete_entry(dir, fi, &fibh, &cfi); 929 if (retval) 930 goto end_unlink; 931 dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); 932 mark_inode_dirty(dir); 933 inode->i_nlink--; 934 mark_inode_dirty(inode); 935 inode->i_ctime = dir->i_ctime; 936 retval = 0; 937 938 end_unlink: 939 if (fibh.sbh != fibh.ebh) 940 udf_release_data(fibh.ebh); 941 udf_release_data(fibh.sbh); 942 out: 943 unlock_kernel(); 944 return retval; 945 } 946 947 static int udf_symlink(struct inode * dir, struct dentry * dentry, const char * symname) 948 { 949 struct inode * inode; 950 struct pathComponent *pc; 951 char *compstart; 952 struct udf_fileident_bh fibh; 953 struct buffer_head *bh = NULL; 954 int eoffset, elen = 0; 955 struct fileIdentDesc *fi; 956 struct fileIdentDesc cfi; 957 char *ea; 958 int err; 959 int block; 960 char name[UDF_NAME_LEN]; 961 int namelen; 962 963 lock_kernel(); 964 if (!(inode = udf_new_inode(dir, S_IFLNK, &err))) 965 goto out; 966 967 inode->i_mode = S_IFLNK | S_IRWXUGO; 968 inode->i_data.a_ops = &udf_symlink_aops; 969 inode->i_op = &page_symlink_inode_operations; 970 971 if (UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB) 972 { 973 struct buffer_head *bh = NULL; 974 kernel_lb_addr bloc, eloc; 975 uint32_t elen, extoffset; 976 977 block = udf_new_block(inode->i_sb, inode, 978 UDF_I_LOCATION(inode).partitionReferenceNum, 979 UDF_I_LOCATION(inode).logicalBlockNum, &err); 980 if (!block) 981 goto out_no_entry; 982 bloc = UDF_I_LOCATION(inode); 983 eloc.logicalBlockNum = block; 984 eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum; 985 elen = inode->i_sb->s_blocksize; 986 UDF_I_LENEXTENTS(inode) = elen; 987 extoffset = udf_file_entry_alloc_offset(inode); 988 udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 0); 989 udf_release_data(bh); 990 991 block = udf_get_pblock(inode->i_sb, block, 992 UDF_I_LOCATION(inode).partitionReferenceNum, 0); 993 bh = udf_tread(inode->i_sb, block); 994 lock_buffer(bh); 995 memset(bh->b_data, 0x00, inode->i_sb->s_blocksize); 996 set_buffer_uptodate(bh); 997 unlock_buffer(bh); 998 mark_buffer_dirty_inode(bh, inode); 999 ea = bh->b_data + udf_ext0_offset(inode); 1000 } 1001 else 1002 ea = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode); 1003 1004 eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode); 1005 pc = (struct pathComponent *)ea; 1006 1007 if (*symname == '/') 1008 { 1009 do 1010 { 1011 symname++; 1012 } while (*symname == '/'); 1013 1014 pc->componentType = 1; 1015 pc->lengthComponentIdent = 0; 1016 pc->componentFileVersionNum = 0; 1017 pc += sizeof(struct pathComponent); 1018 elen += sizeof(struct pathComponent); 1019 } 1020 1021 err = -ENAMETOOLONG; 1022 1023 while (*symname) 1024 { 1025 if (elen + sizeof(struct pathComponent) > eoffset) 1026 goto out_no_entry; 1027 1028 pc = (struct pathComponent *)(ea + elen); 1029 1030 compstart = (char *)symname; 1031 1032 do 1033 { 1034 symname++; 1035 } while (*symname && *symname != '/'); 1036 1037 pc->componentType = 5; 1038 pc->lengthComponentIdent = 0; 1039 pc->componentFileVersionNum = 0; 1040 if (compstart[0] == '.') 1041 { 1042 if ((symname-compstart) == 1) 1043 pc->componentType = 4; 1044 else if ((symname-compstart) == 2 && compstart[1] == '.') 1045 pc->componentType = 3; 1046 } 1047 1048 if (pc->componentType == 5) 1049 { 1050 if ( !(namelen = udf_put_filename(inode->i_sb, compstart, name, symname-compstart))) 1051 goto out_no_entry; 1052 1053 if (elen + sizeof(struct pathComponent) + namelen > eoffset) 1054 goto out_no_entry; 1055 else 1056 pc->lengthComponentIdent = namelen; 1057 1058 memcpy(pc->componentIdent, name, namelen); 1059 } 1060 1061 elen += sizeof(struct pathComponent) + pc->lengthComponentIdent; 1062 1063 if (*symname) 1064 { 1065 do 1066 { 1067 symname++; 1068 } while (*symname == '/'); 1069 } 1070 } 1071 1072 udf_release_data(bh); 1073 inode->i_size = elen; 1074 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) 1075 UDF_I_LENALLOC(inode) = inode->i_size; 1076 mark_inode_dirty(inode); 1077 1078 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) 1079 goto out_no_entry; 1080 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); 1081 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode)); 1082 if (UDF_SB_LVIDBH(inode->i_sb)) 1083 { 1084 struct logicalVolHeaderDesc *lvhd; 1085 uint64_t uniqueID; 1086 lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse); 1087 uniqueID = le64_to_cpu(lvhd->uniqueID); 1088 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = 1089 cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL); 1090 if (!(++uniqueID & 0x00000000FFFFFFFFUL)) 1091 uniqueID += 16; 1092 lvhd->uniqueID = cpu_to_le64(uniqueID); 1093 mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb)); 1094 } 1095 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); 1096 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) 1097 { 1098 mark_inode_dirty(dir); 1099 } 1100 if (fibh.sbh != fibh.ebh) 1101 udf_release_data(fibh.ebh); 1102 udf_release_data(fibh.sbh); 1103 d_instantiate(dentry, inode); 1104 err = 0; 1105 1106 out: 1107 unlock_kernel(); 1108 return err; 1109 1110 out_no_entry: 1111 inode->i_nlink--; 1112 mark_inode_dirty(inode); 1113 iput(inode); 1114 goto out; 1115 } 1116 1117 static int udf_link(struct dentry * old_dentry, struct inode * dir, 1118 struct dentry *dentry) 1119 { 1120 struct inode *inode = old_dentry->d_inode; 1121 struct udf_fileident_bh fibh; 1122 struct fileIdentDesc cfi, *fi; 1123 int err; 1124 1125 lock_kernel(); 1126 if (inode->i_nlink >= (256<<sizeof(inode->i_nlink))-1) 1127 { 1128 unlock_kernel(); 1129 return -EMLINK; 1130 } 1131 1132 if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) 1133 { 1134 unlock_kernel(); 1135 return err; 1136 } 1137 cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); 1138 cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode)); 1139 if (UDF_SB_LVIDBH(inode->i_sb)) 1140 { 1141 struct logicalVolHeaderDesc *lvhd; 1142 uint64_t uniqueID; 1143 lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse); 1144 uniqueID = le64_to_cpu(lvhd->uniqueID); 1145 *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = 1146 cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL); 1147 if (!(++uniqueID & 0x00000000FFFFFFFFUL)) 1148 uniqueID += 16; 1149 lvhd->uniqueID = cpu_to_le64(uniqueID); 1150 mark_buffer_dirty(UDF_SB_LVIDBH(inode->i_sb)); 1151 } 1152 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); 1153 if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) 1154 { 1155 mark_inode_dirty(dir); 1156 } 1157 if (fibh.sbh != fibh.ebh) 1158 udf_release_data(fibh.ebh); 1159 udf_release_data(fibh.sbh); 1160 inode->i_nlink ++; 1161 inode->i_ctime = current_fs_time(inode->i_sb); 1162 mark_inode_dirty(inode); 1163 atomic_inc(&inode->i_count); 1164 d_instantiate(dentry, inode); 1165 unlock_kernel(); 1166 return 0; 1167 } 1168 1169 /* Anybody can rename anything with this: the permission checks are left to the 1170 * higher-level routines. 1171 */ 1172 static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, 1173 struct inode * new_dir, struct dentry * new_dentry) 1174 { 1175 struct inode * old_inode = old_dentry->d_inode; 1176 struct inode * new_inode = new_dentry->d_inode; 1177 struct udf_fileident_bh ofibh, nfibh; 1178 struct fileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL, ocfi, ncfi; 1179 struct buffer_head *dir_bh = NULL; 1180 int retval = -ENOENT; 1181 kernel_lb_addr tloc; 1182 1183 lock_kernel(); 1184 if ((ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi))) 1185 { 1186 if (ofibh.sbh != ofibh.ebh) 1187 udf_release_data(ofibh.ebh); 1188 udf_release_data(ofibh.sbh); 1189 } 1190 tloc = lelb_to_cpu(ocfi.icb.extLocation); 1191 if (!ofi || udf_get_lb_pblock(old_dir->i_sb, tloc, 0) 1192 != old_inode->i_ino) 1193 goto end_rename; 1194 1195 nfi = udf_find_entry(new_dir, new_dentry, &nfibh, &ncfi); 1196 if (nfi) 1197 { 1198 if (!new_inode) 1199 { 1200 if (nfibh.sbh != nfibh.ebh) 1201 udf_release_data(nfibh.ebh); 1202 udf_release_data(nfibh.sbh); 1203 nfi = NULL; 1204 } 1205 } 1206 if (S_ISDIR(old_inode->i_mode)) 1207 { 1208 uint32_t offset = udf_ext0_offset(old_inode); 1209 1210 if (new_inode) 1211 { 1212 retval = -ENOTEMPTY; 1213 if (!empty_dir(new_inode)) 1214 goto end_rename; 1215 } 1216 retval = -EIO; 1217 if (UDF_I_ALLOCTYPE(old_inode) == ICBTAG_FLAG_AD_IN_ICB) 1218 { 1219 dir_fi = udf_get_fileident(UDF_I_DATA(old_inode) - 1220 (UDF_I_EFE(old_inode) ? 1221 sizeof(struct extendedFileEntry) : 1222 sizeof(struct fileEntry)), 1223 old_inode->i_sb->s_blocksize, &offset); 1224 } 1225 else 1226 { 1227 dir_bh = udf_bread(old_inode, 0, 0, &retval); 1228 if (!dir_bh) 1229 goto end_rename; 1230 dir_fi = udf_get_fileident(dir_bh->b_data, old_inode->i_sb->s_blocksize, &offset); 1231 } 1232 if (!dir_fi) 1233 goto end_rename; 1234 tloc = lelb_to_cpu(dir_fi->icb.extLocation); 1235 if (udf_get_lb_pblock(old_inode->i_sb, tloc, 0) 1236 != old_dir->i_ino) 1237 goto end_rename; 1238 1239 retval = -EMLINK; 1240 if (!new_inode && new_dir->i_nlink >= (256<<sizeof(new_dir->i_nlink))-1) 1241 goto end_rename; 1242 } 1243 if (!nfi) 1244 { 1245 nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, &retval); 1246 if (!nfi) 1247 goto end_rename; 1248 } 1249 1250 /* 1251 * Like most other Unix systems, set the ctime for inodes on a 1252 * rename. 1253 */ 1254 old_inode->i_ctime = current_fs_time(old_inode->i_sb); 1255 mark_inode_dirty(old_inode); 1256 1257 /* 1258 * ok, that's it 1259 */ 1260 ncfi.fileVersionNum = ocfi.fileVersionNum; 1261 ncfi.fileCharacteristics = ocfi.fileCharacteristics; 1262 memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(long_ad)); 1263 udf_write_fi(new_dir, &ncfi, nfi, &nfibh, NULL, NULL); 1264 1265 /* The old fid may have moved - find it again */ 1266 ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi); 1267 udf_delete_entry(old_dir, ofi, &ofibh, &ocfi); 1268 1269 if (new_inode) 1270 { 1271 new_inode->i_nlink--; 1272 new_inode->i_ctime = current_fs_time(new_inode->i_sb); 1273 mark_inode_dirty(new_inode); 1274 } 1275 old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb); 1276 mark_inode_dirty(old_dir); 1277 1278 if (dir_fi) 1279 { 1280 dir_fi->icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(new_dir)); 1281 udf_update_tag((char *)dir_fi, (sizeof(struct fileIdentDesc) + 1282 le16_to_cpu(dir_fi->lengthOfImpUse) + 3) & ~3); 1283 if (UDF_I_ALLOCTYPE(old_inode) == ICBTAG_FLAG_AD_IN_ICB) 1284 { 1285 mark_inode_dirty(old_inode); 1286 } 1287 else 1288 mark_buffer_dirty_inode(dir_bh, old_inode); 1289 old_dir->i_nlink --; 1290 mark_inode_dirty(old_dir); 1291 if (new_inode) 1292 { 1293 new_inode->i_nlink --; 1294 mark_inode_dirty(new_inode); 1295 } 1296 else 1297 { 1298 new_dir->i_nlink ++; 1299 mark_inode_dirty(new_dir); 1300 } 1301 } 1302 1303 if (ofi) 1304 { 1305 if (ofibh.sbh != ofibh.ebh) 1306 udf_release_data(ofibh.ebh); 1307 udf_release_data(ofibh.sbh); 1308 } 1309 1310 retval = 0; 1311 1312 end_rename: 1313 udf_release_data(dir_bh); 1314 if (nfi) 1315 { 1316 if (nfibh.sbh != nfibh.ebh) 1317 udf_release_data(nfibh.ebh); 1318 udf_release_data(nfibh.sbh); 1319 } 1320 unlock_kernel(); 1321 return retval; 1322 } 1323 1324 struct inode_operations udf_dir_inode_operations = { 1325 .lookup = udf_lookup, 1326 .create = udf_create, 1327 .link = udf_link, 1328 .unlink = udf_unlink, 1329 .symlink = udf_symlink, 1330 .mkdir = udf_mkdir, 1331 .rmdir = udf_rmdir, 1332 .mknod = udf_mknod, 1333 .rename = udf_rename, 1334 }; 1335