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