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