linux/fs/jfs/namei.c
<<
>>
Prefs
   1/*
   2 *   Copyright (C) International Business Machines Corp., 2000-2004
   3 *   Portions Copyright (C) Christoph Hellwig, 2001-2002
   4 *
   5 *   This program is free software;  you can redistribute it and/or modify
   6 *   it under the terms of the GNU General Public License as published by
   7 *   the Free Software Foundation; either version 2 of the License, or
   8 *   (at your option) any later version.
   9 *
  10 *   This program is distributed in the hope that it will be useful,
  11 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
  12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  13 *   the GNU General Public License for more details.
  14 *
  15 *   You should have received a copy of the GNU General Public License
  16 *   along with this program;  if not, write to the Free Software
  17 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18 */
  19
  20#include <linux/fs.h>
  21#include <linux/namei.h>
  22#include <linux/ctype.h>
  23#include <linux/quotaops.h>
  24#include <linux/exportfs.h>
  25#include "jfs_incore.h"
  26#include "jfs_superblock.h"
  27#include "jfs_inode.h"
  28#include "jfs_dinode.h"
  29#include "jfs_dmap.h"
  30#include "jfs_unicode.h"
  31#include "jfs_metapage.h"
  32#include "jfs_xattr.h"
  33#include "jfs_acl.h"
  34#include "jfs_debug.h"
  35
  36/*
  37 * forward references
  38 */
  39const struct dentry_operations jfs_ci_dentry_operations;
  40
  41static s64 commitZeroLink(tid_t, struct inode *);
  42
  43/*
  44 * NAME:        free_ea_wmap(inode)
  45 *
  46 * FUNCTION:    free uncommitted extended attributes from working map
  47 *
  48 */
  49static inline void free_ea_wmap(struct inode *inode)
  50{
  51        dxd_t *ea = &JFS_IP(inode)->ea;
  52
  53        if (ea->flag & DXD_EXTENT) {
  54                /* free EA pages from cache */
  55                invalidate_dxd_metapages(inode, *ea);
  56                dbFree(inode, addressDXD(ea), lengthDXD(ea));
  57        }
  58        ea->flag = 0;
  59}
  60
  61/*
  62 * NAME:        jfs_create(dip, dentry, mode)
  63 *
  64 * FUNCTION:    create a regular file in the parent directory <dip>
  65 *              with name = <from dentry> and mode = <mode>
  66 *
  67 * PARAMETER:   dip     - parent directory vnode
  68 *              dentry  - dentry of new file
  69 *              mode    - create mode (rwxrwxrwx).
  70 *              nd- nd struct
  71 *
  72 * RETURN:      Errors from subroutines
  73 *
  74 */
  75static int jfs_create(struct inode *dip, struct dentry *dentry, umode_t mode,
  76                bool excl)
  77{
  78        int rc = 0;
  79        tid_t tid;              /* transaction id */
  80        struct inode *ip = NULL;        /* child directory inode */
  81        ino_t ino;
  82        struct component_name dname;    /* child directory name */
  83        struct btstack btstack;
  84        struct inode *iplist[2];
  85        struct tblock *tblk;
  86
  87        jfs_info("jfs_create: dip:0x%p name:%pd", dip, dentry);
  88
  89        rc = dquot_initialize(dip);
  90        if (rc)
  91                goto out1;
  92
  93        /*
  94         * search parent directory for entry/freespace
  95         * (dtSearch() returns parent directory page pinned)
  96         */
  97        if ((rc = get_UCSname(&dname, dentry)))
  98                goto out1;
  99
 100        /*
 101         * Either iAlloc() or txBegin() may block.  Deadlock can occur if we
 102         * block there while holding dtree page, so we allocate the inode &
 103         * begin the transaction before we search the directory.
 104         */
 105        ip = ialloc(dip, mode);
 106        if (IS_ERR(ip)) {
 107                rc = PTR_ERR(ip);
 108                goto out2;
 109        }
 110
 111        tid = txBegin(dip->i_sb, 0);
 112
 113        mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
 114        mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
 115
 116        rc = jfs_init_acl(tid, ip, dip);
 117        if (rc)
 118                goto out3;
 119
 120        rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
 121        if (rc) {
 122                txAbort(tid, 0);
 123                goto out3;
 124        }
 125
 126        if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
 127                jfs_err("jfs_create: dtSearch returned %d", rc);
 128                txAbort(tid, 0);
 129                goto out3;
 130        }
 131
 132        tblk = tid_to_tblock(tid);
 133        tblk->xflag |= COMMIT_CREATE;
 134        tblk->ino = ip->i_ino;
 135        tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
 136
 137        iplist[0] = dip;
 138        iplist[1] = ip;
 139
 140        /*
 141         * initialize the child XAD tree root in-line in inode
 142         */
 143        xtInitRoot(tid, ip);
 144
 145        /*
 146         * create entry in parent directory for child directory
 147         * (dtInsert() releases parent directory page)
 148         */
 149        ino = ip->i_ino;
 150        if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
 151                if (rc == -EIO) {
 152                        jfs_err("jfs_create: dtInsert returned -EIO");
 153                        txAbort(tid, 1);        /* Marks Filesystem dirty */
 154                } else
 155                        txAbort(tid, 0);        /* Filesystem full */
 156                goto out3;
 157        }
 158
 159        ip->i_op = &jfs_file_inode_operations;
 160        ip->i_fop = &jfs_file_operations;
 161        ip->i_mapping->a_ops = &jfs_aops;
 162
 163        mark_inode_dirty(ip);
 164
 165        dip->i_ctime = dip->i_mtime = CURRENT_TIME;
 166
 167        mark_inode_dirty(dip);
 168
 169        rc = txCommit(tid, 2, &iplist[0], 0);
 170
 171      out3:
 172        txEnd(tid);
 173        mutex_unlock(&JFS_IP(ip)->commit_mutex);
 174        mutex_unlock(&JFS_IP(dip)->commit_mutex);
 175        if (rc) {
 176                free_ea_wmap(ip);
 177                clear_nlink(ip);
 178                unlock_new_inode(ip);
 179                iput(ip);
 180        } else {
 181                unlock_new_inode(ip);
 182                d_instantiate(dentry, ip);
 183        }
 184
 185      out2:
 186        free_UCSname(&dname);
 187
 188      out1:
 189
 190        jfs_info("jfs_create: rc:%d", rc);
 191        return rc;
 192}
 193
 194
 195/*
 196 * NAME:        jfs_mkdir(dip, dentry, mode)
 197 *
 198 * FUNCTION:    create a child directory in the parent directory <dip>
 199 *              with name = <from dentry> and mode = <mode>
 200 *
 201 * PARAMETER:   dip     - parent directory vnode
 202 *              dentry  - dentry of child directory
 203 *              mode    - create mode (rwxrwxrwx).
 204 *
 205 * RETURN:      Errors from subroutines
 206 *
 207 * note:
 208 * EACCESS: user needs search+write permission on the parent directory
 209 */
 210static int jfs_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
 211{
 212        int rc = 0;
 213        tid_t tid;              /* transaction id */
 214        struct inode *ip = NULL;        /* child directory inode */
 215        ino_t ino;
 216        struct component_name dname;    /* child directory name */
 217        struct btstack btstack;
 218        struct inode *iplist[2];
 219        struct tblock *tblk;
 220
 221        jfs_info("jfs_mkdir: dip:0x%p name:%pd", dip, dentry);
 222
 223        rc = dquot_initialize(dip);
 224        if (rc)
 225                goto out1;
 226
 227        /*
 228         * search parent directory for entry/freespace
 229         * (dtSearch() returns parent directory page pinned)
 230         */
 231        if ((rc = get_UCSname(&dname, dentry)))
 232                goto out1;
 233
 234        /*
 235         * Either iAlloc() or txBegin() may block.  Deadlock can occur if we
 236         * block there while holding dtree page, so we allocate the inode &
 237         * begin the transaction before we search the directory.
 238         */
 239        ip = ialloc(dip, S_IFDIR | mode);
 240        if (IS_ERR(ip)) {
 241                rc = PTR_ERR(ip);
 242                goto out2;
 243        }
 244
 245        tid = txBegin(dip->i_sb, 0);
 246
 247        mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
 248        mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
 249
 250        rc = jfs_init_acl(tid, ip, dip);
 251        if (rc)
 252                goto out3;
 253
 254        rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
 255        if (rc) {
 256                txAbort(tid, 0);
 257                goto out3;
 258        }
 259
 260        if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
 261                jfs_err("jfs_mkdir: dtSearch returned %d", rc);
 262                txAbort(tid, 0);
 263                goto out3;
 264        }
 265
 266        tblk = tid_to_tblock(tid);
 267        tblk->xflag |= COMMIT_CREATE;
 268        tblk->ino = ip->i_ino;
 269        tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
 270
 271        iplist[0] = dip;
 272        iplist[1] = ip;
 273
 274        /*
 275         * initialize the child directory in-line in inode
 276         */
 277        dtInitRoot(tid, ip, dip->i_ino);
 278
 279        /*
 280         * create entry in parent directory for child directory
 281         * (dtInsert() releases parent directory page)
 282         */
 283        ino = ip->i_ino;
 284        if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
 285                if (rc == -EIO) {
 286                        jfs_err("jfs_mkdir: dtInsert returned -EIO");
 287                        txAbort(tid, 1);        /* Marks Filesystem dirty */
 288                } else
 289                        txAbort(tid, 0);        /* Filesystem full */
 290                goto out3;
 291        }
 292
 293        set_nlink(ip, 2);       /* for '.' */
 294        ip->i_op = &jfs_dir_inode_operations;
 295        ip->i_fop = &jfs_dir_operations;
 296
 297        mark_inode_dirty(ip);
 298
 299        /* update parent directory inode */
 300        inc_nlink(dip);         /* for '..' from child directory */
 301        dip->i_ctime = dip->i_mtime = CURRENT_TIME;
 302        mark_inode_dirty(dip);
 303
 304        rc = txCommit(tid, 2, &iplist[0], 0);
 305
 306      out3:
 307        txEnd(tid);
 308        mutex_unlock(&JFS_IP(ip)->commit_mutex);
 309        mutex_unlock(&JFS_IP(dip)->commit_mutex);
 310        if (rc) {
 311                free_ea_wmap(ip);
 312                clear_nlink(ip);
 313                unlock_new_inode(ip);
 314                iput(ip);
 315        } else {
 316                unlock_new_inode(ip);
 317                d_instantiate(dentry, ip);
 318        }
 319
 320      out2:
 321        free_UCSname(&dname);
 322
 323
 324      out1:
 325
 326        jfs_info("jfs_mkdir: rc:%d", rc);
 327        return rc;
 328}
 329
 330/*
 331 * NAME:        jfs_rmdir(dip, dentry)
 332 *
 333 * FUNCTION:    remove a link to child directory
 334 *
 335 * PARAMETER:   dip     - parent inode
 336 *              dentry  - child directory dentry
 337 *
 338 * RETURN:      -EINVAL - if name is . or ..
 339 *              -EINVAL - if . or .. exist but are invalid.
 340 *              errors from subroutines
 341 *
 342 * note:
 343 * if other threads have the directory open when the last link
 344 * is removed, the "." and ".." entries, if present, are removed before
 345 * rmdir() returns and no new entries may be created in the directory,
 346 * but the directory is not removed until the last reference to
 347 * the directory is released (cf.unlink() of regular file).
 348 */
 349static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
 350{
 351        int rc;
 352        tid_t tid;              /* transaction id */
 353        struct inode *ip = d_inode(dentry);
 354        ino_t ino;
 355        struct component_name dname;
 356        struct inode *iplist[2];
 357        struct tblock *tblk;
 358
 359        jfs_info("jfs_rmdir: dip:0x%p name:%pd", dip, dentry);
 360
 361        /* Init inode for quota operations. */
 362        rc = dquot_initialize(dip);
 363        if (rc)
 364                goto out;
 365        rc = dquot_initialize(ip);
 366        if (rc)
 367                goto out;
 368
 369        /* directory must be empty to be removed */
 370        if (!dtEmpty(ip)) {
 371                rc = -ENOTEMPTY;
 372                goto out;
 373        }
 374
 375        if ((rc = get_UCSname(&dname, dentry))) {
 376                goto out;
 377        }
 378
 379        tid = txBegin(dip->i_sb, 0);
 380
 381        mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
 382        mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
 383
 384        iplist[0] = dip;
 385        iplist[1] = ip;
 386
 387        tblk = tid_to_tblock(tid);
 388        tblk->xflag |= COMMIT_DELETE;
 389        tblk->u.ip = ip;
 390
 391        /*
 392         * delete the entry of target directory from parent directory
 393         */
 394        ino = ip->i_ino;
 395        if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) {
 396                jfs_err("jfs_rmdir: dtDelete returned %d", rc);
 397                if (rc == -EIO)
 398                        txAbort(tid, 1);
 399                txEnd(tid);
 400                mutex_unlock(&JFS_IP(ip)->commit_mutex);
 401                mutex_unlock(&JFS_IP(dip)->commit_mutex);
 402
 403                goto out2;
 404        }
 405
 406        /* update parent directory's link count corresponding
 407         * to ".." entry of the target directory deleted
 408         */
 409        dip->i_ctime = dip->i_mtime = CURRENT_TIME;
 410        inode_dec_link_count(dip);
 411
 412        /*
 413         * OS/2 could have created EA and/or ACL
 414         */
 415        /* free EA from both persistent and working map */
 416        if (JFS_IP(ip)->ea.flag & DXD_EXTENT) {
 417                /* free EA pages */
 418                txEA(tid, ip, &JFS_IP(ip)->ea, NULL);
 419        }
 420        JFS_IP(ip)->ea.flag = 0;
 421
 422        /* free ACL from both persistent and working map */
 423        if (JFS_IP(ip)->acl.flag & DXD_EXTENT) {
 424                /* free ACL pages */
 425                txEA(tid, ip, &JFS_IP(ip)->acl, NULL);
 426        }
 427        JFS_IP(ip)->acl.flag = 0;
 428
 429        /* mark the target directory as deleted */
 430        clear_nlink(ip);
 431        mark_inode_dirty(ip);
 432
 433        rc = txCommit(tid, 2, &iplist[0], 0);
 434
 435        txEnd(tid);
 436
 437        mutex_unlock(&JFS_IP(ip)->commit_mutex);
 438        mutex_unlock(&JFS_IP(dip)->commit_mutex);
 439
 440        /*
 441         * Truncating the directory index table is not guaranteed.  It
 442         * may need to be done iteratively
 443         */
 444        if (test_cflag(COMMIT_Stale, dip)) {
 445                if (dip->i_size > 1)
 446                        jfs_truncate_nolock(dip, 0);
 447
 448                clear_cflag(COMMIT_Stale, dip);
 449        }
 450
 451      out2:
 452        free_UCSname(&dname);
 453
 454      out:
 455        jfs_info("jfs_rmdir: rc:%d", rc);
 456        return rc;
 457}
 458
 459/*
 460 * NAME:        jfs_unlink(dip, dentry)
 461 *
 462 * FUNCTION:    remove a link to object <vp> named by <name>
 463 *              from parent directory <dvp>
 464 *
 465 * PARAMETER:   dip     - inode of parent directory
 466 *              dentry  - dentry of object to be removed
 467 *
 468 * RETURN:      errors from subroutines
 469 *
 470 * note:
 471 * temporary file: if one or more processes have the file open
 472 * when the last link is removed, the link will be removed before
 473 * unlink() returns, but the removal of the file contents will be
 474 * postponed until all references to the files are closed.
 475 *
 476 * JFS does NOT support unlink() on directories.
 477 *
 478 */
 479static int jfs_unlink(struct inode *dip, struct dentry *dentry)
 480{
 481        int rc;
 482        tid_t tid;              /* transaction id */
 483        struct inode *ip = d_inode(dentry);
 484        ino_t ino;
 485        struct component_name dname;    /* object name */
 486        struct inode *iplist[2];
 487        struct tblock *tblk;
 488        s64 new_size = 0;
 489        int commit_flag;
 490
 491        jfs_info("jfs_unlink: dip:0x%p name:%pd", dip, dentry);
 492
 493        /* Init inode for quota operations. */
 494        rc = dquot_initialize(dip);
 495        if (rc)
 496                goto out;
 497        rc = dquot_initialize(ip);
 498        if (rc)
 499                goto out;
 500
 501        if ((rc = get_UCSname(&dname, dentry)))
 502                goto out;
 503
 504        IWRITE_LOCK(ip, RDWRLOCK_NORMAL);
 505
 506        tid = txBegin(dip->i_sb, 0);
 507
 508        mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
 509        mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
 510
 511        iplist[0] = dip;
 512        iplist[1] = ip;
 513
 514        /*
 515         * delete the entry of target file from parent directory
 516         */
 517        ino = ip->i_ino;
 518        if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) {
 519                jfs_err("jfs_unlink: dtDelete returned %d", rc);
 520                if (rc == -EIO)
 521                        txAbort(tid, 1);        /* Marks FS Dirty */
 522                txEnd(tid);
 523                mutex_unlock(&JFS_IP(ip)->commit_mutex);
 524                mutex_unlock(&JFS_IP(dip)->commit_mutex);
 525                IWRITE_UNLOCK(ip);
 526                goto out1;
 527        }
 528
 529        ASSERT(ip->i_nlink);
 530
 531        ip->i_ctime = dip->i_ctime = dip->i_mtime = CURRENT_TIME;
 532        mark_inode_dirty(dip);
 533
 534        /* update target's inode */
 535        inode_dec_link_count(ip);
 536
 537        /*
 538         *      commit zero link count object
 539         */
 540        if (ip->i_nlink == 0) {
 541                assert(!test_cflag(COMMIT_Nolink, ip));
 542                /* free block resources */
 543                if ((new_size = commitZeroLink(tid, ip)) < 0) {
 544                        txAbort(tid, 1);        /* Marks FS Dirty */
 545                        txEnd(tid);
 546                        mutex_unlock(&JFS_IP(ip)->commit_mutex);
 547                        mutex_unlock(&JFS_IP(dip)->commit_mutex);
 548                        IWRITE_UNLOCK(ip);
 549                        rc = new_size;
 550                        goto out1;
 551                }
 552                tblk = tid_to_tblock(tid);
 553                tblk->xflag |= COMMIT_DELETE;
 554                tblk->u.ip = ip;
 555        }
 556
 557        /*
 558         * Incomplete truncate of file data can
 559         * result in timing problems unless we synchronously commit the
 560         * transaction.
 561         */
 562        if (new_size)
 563                commit_flag = COMMIT_SYNC;
 564        else
 565                commit_flag = 0;
 566
 567        /*
 568         * If xtTruncate was incomplete, commit synchronously to avoid
 569         * timing complications
 570         */
 571        rc = txCommit(tid, 2, &iplist[0], commit_flag);
 572
 573        txEnd(tid);
 574
 575        mutex_unlock(&JFS_IP(ip)->commit_mutex);
 576        mutex_unlock(&JFS_IP(dip)->commit_mutex);
 577
 578        while (new_size && (rc == 0)) {
 579                tid = txBegin(dip->i_sb, 0);
 580                mutex_lock(&JFS_IP(ip)->commit_mutex);
 581                new_size = xtTruncate_pmap(tid, ip, new_size);
 582                if (new_size < 0) {
 583                        txAbort(tid, 1);        /* Marks FS Dirty */
 584                        rc = new_size;
 585                } else
 586                        rc = txCommit(tid, 2, &iplist[0], COMMIT_SYNC);
 587                txEnd(tid);
 588                mutex_unlock(&JFS_IP(ip)->commit_mutex);
 589        }
 590
 591        if (ip->i_nlink == 0)
 592                set_cflag(COMMIT_Nolink, ip);
 593
 594        IWRITE_UNLOCK(ip);
 595
 596        /*
 597         * Truncating the directory index table is not guaranteed.  It
 598         * may need to be done iteratively
 599         */
 600        if (test_cflag(COMMIT_Stale, dip)) {
 601                if (dip->i_size > 1)
 602                        jfs_truncate_nolock(dip, 0);
 603
 604                clear_cflag(COMMIT_Stale, dip);
 605        }
 606
 607      out1:
 608        free_UCSname(&dname);
 609      out:
 610        jfs_info("jfs_unlink: rc:%d", rc);
 611        return rc;
 612}
 613
 614/*
 615 * NAME:        commitZeroLink()
 616 *
 617 * FUNCTION:    for non-directory, called by jfs_remove(),
 618 *              truncate a regular file, directory or symbolic
 619 *              link to zero length. return 0 if type is not
 620 *              one of these.
 621 *
 622 *              if the file is currently associated with a VM segment
 623 *              only permanent disk and inode map resources are freed,
 624 *              and neither the inode nor indirect blocks are modified
 625 *              so that the resources can be later freed in the work
 626 *              map by ctrunc1.
 627 *              if there is no VM segment on entry, the resources are
 628 *              freed in both work and permanent map.
 629 *              (? for temporary file - memory object is cached even
 630 *              after no reference:
 631 *              reference count > 0 -   )
 632 *
 633 * PARAMETERS:  cd      - pointer to commit data structure.
 634 *                        current inode is the one to truncate.
 635 *
 636 * RETURN:      Errors from subroutines
 637 */
 638static s64 commitZeroLink(tid_t tid, struct inode *ip)
 639{
 640        int filetype;
 641        struct tblock *tblk;
 642
 643        jfs_info("commitZeroLink: tid = %d, ip = 0x%p", tid, ip);
 644
 645        filetype = ip->i_mode & S_IFMT;
 646        switch (filetype) {
 647        case S_IFREG:
 648                break;
 649        case S_IFLNK:
 650                /* fast symbolic link */
 651                if (ip->i_size < IDATASIZE) {
 652                        ip->i_size = 0;
 653                        return 0;
 654                }
 655                break;
 656        default:
 657                assert(filetype != S_IFDIR);
 658                return 0;
 659        }
 660
 661        set_cflag(COMMIT_Freewmap, ip);
 662
 663        /* mark transaction of block map update type */
 664        tblk = tid_to_tblock(tid);
 665        tblk->xflag |= COMMIT_PMAP;
 666
 667        /*
 668         * free EA
 669         */
 670        if (JFS_IP(ip)->ea.flag & DXD_EXTENT)
 671                /* acquire maplock on EA to be freed from block map */
 672                txEA(tid, ip, &JFS_IP(ip)->ea, NULL);
 673
 674        /*
 675         * free ACL
 676         */
 677        if (JFS_IP(ip)->acl.flag & DXD_EXTENT)
 678                /* acquire maplock on EA to be freed from block map */
 679                txEA(tid, ip, &JFS_IP(ip)->acl, NULL);
 680
 681        /*
 682         * free xtree/data (truncate to zero length):
 683         * free xtree/data pages from cache if COMMIT_PWMAP,
 684         * free xtree/data blocks from persistent block map, and
 685         * free xtree/data blocks from working block map if COMMIT_PWMAP;
 686         */
 687        if (ip->i_size)
 688                return xtTruncate_pmap(tid, ip, 0);
 689
 690        return 0;
 691}
 692
 693
 694/*
 695 * NAME:        jfs_free_zero_link()
 696 *
 697 * FUNCTION:    for non-directory, called by iClose(),
 698 *              free resources of a file from cache and WORKING map
 699 *              for a file previously committed with zero link count
 700 *              while associated with a pager object,
 701 *
 702 * PARAMETER:   ip      - pointer to inode of file.
 703 */
 704void jfs_free_zero_link(struct inode *ip)
 705{
 706        int type;
 707
 708        jfs_info("jfs_free_zero_link: ip = 0x%p", ip);
 709
 710        /* return if not reg or symbolic link or if size is
 711         * already ok.
 712         */
 713        type = ip->i_mode & S_IFMT;
 714
 715        switch (type) {
 716        case S_IFREG:
 717                break;
 718        case S_IFLNK:
 719                /* if its contained in inode nothing to do */
 720                if (ip->i_size < IDATASIZE)
 721                        return;
 722                break;
 723        default:
 724                return;
 725        }
 726
 727        /*
 728         * free EA
 729         */
 730        if (JFS_IP(ip)->ea.flag & DXD_EXTENT) {
 731                s64 xaddr = addressDXD(&JFS_IP(ip)->ea);
 732                int xlen = lengthDXD(&JFS_IP(ip)->ea);
 733                struct maplock maplock; /* maplock for COMMIT_WMAP */
 734                struct pxd_lock *pxdlock;       /* maplock for COMMIT_WMAP */
 735
 736                /* free EA pages from cache */
 737                invalidate_dxd_metapages(ip, JFS_IP(ip)->ea);
 738
 739                /* free EA extent from working block map */
 740                maplock.index = 1;
 741                pxdlock = (struct pxd_lock *) & maplock;
 742                pxdlock->flag = mlckFREEPXD;
 743                PXDaddress(&pxdlock->pxd, xaddr);
 744                PXDlength(&pxdlock->pxd, xlen);
 745                txFreeMap(ip, pxdlock, NULL, COMMIT_WMAP);
 746        }
 747
 748        /*
 749         * free ACL
 750         */
 751        if (JFS_IP(ip)->acl.flag & DXD_EXTENT) {
 752                s64 xaddr = addressDXD(&JFS_IP(ip)->acl);
 753                int xlen = lengthDXD(&JFS_IP(ip)->acl);
 754                struct maplock maplock; /* maplock for COMMIT_WMAP */
 755                struct pxd_lock *pxdlock;       /* maplock for COMMIT_WMAP */
 756
 757                invalidate_dxd_metapages(ip, JFS_IP(ip)->acl);
 758
 759                /* free ACL extent from working block map */
 760                maplock.index = 1;
 761                pxdlock = (struct pxd_lock *) & maplock;
 762                pxdlock->flag = mlckFREEPXD;
 763                PXDaddress(&pxdlock->pxd, xaddr);
 764                PXDlength(&pxdlock->pxd, xlen);
 765                txFreeMap(ip, pxdlock, NULL, COMMIT_WMAP);
 766        }
 767
 768        /*
 769         * free xtree/data (truncate to zero length):
 770         * free xtree/data pages from cache, and
 771         * free xtree/data blocks from working block map;
 772         */
 773        if (ip->i_size)
 774                xtTruncate(0, ip, 0, COMMIT_WMAP);
 775}
 776
 777/*
 778 * NAME:        jfs_link(vp, dvp, name, crp)
 779 *
 780 * FUNCTION:    create a link to <vp> by the name = <name>
 781 *              in the parent directory <dvp>
 782 *
 783 * PARAMETER:   vp      - target object
 784 *              dvp     - parent directory of new link
 785 *              name    - name of new link to target object
 786 *              crp     - credential
 787 *
 788 * RETURN:      Errors from subroutines
 789 *
 790 * note:
 791 * JFS does NOT support link() on directories (to prevent circular
 792 * path in the directory hierarchy);
 793 * EPERM: the target object is a directory, and either the caller
 794 * does not have appropriate privileges or the implementation prohibits
 795 * using link() on directories [XPG4.2].
 796 *
 797 * JFS does NOT support links between file systems:
 798 * EXDEV: target object and new link are on different file systems and
 799 * implementation does not support links between file systems [XPG4.2].
 800 */
 801static int jfs_link(struct dentry *old_dentry,
 802             struct inode *dir, struct dentry *dentry)
 803{
 804        int rc;
 805        tid_t tid;
 806        struct inode *ip = d_inode(old_dentry);
 807        ino_t ino;
 808        struct component_name dname;
 809        struct btstack btstack;
 810        struct inode *iplist[2];
 811
 812        jfs_info("jfs_link: %pd %pd", old_dentry, dentry);
 813
 814        rc = dquot_initialize(dir);
 815        if (rc)
 816                goto out;
 817
 818        tid = txBegin(ip->i_sb, 0);
 819
 820        mutex_lock_nested(&JFS_IP(dir)->commit_mutex, COMMIT_MUTEX_PARENT);
 821        mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
 822
 823        /*
 824         * scan parent directory for entry/freespace
 825         */
 826        if ((rc = get_UCSname(&dname, dentry)))
 827                goto out_tx;
 828
 829        if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE)))
 830                goto free_dname;
 831
 832        /*
 833         * create entry for new link in parent directory
 834         */
 835        ino = ip->i_ino;
 836        if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack)))
 837                goto free_dname;
 838
 839        /* update object inode */
 840        inc_nlink(ip);          /* for new link */
 841        ip->i_ctime = CURRENT_TIME;
 842        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 843        mark_inode_dirty(dir);
 844        ihold(ip);
 845
 846        iplist[0] = ip;
 847        iplist[1] = dir;
 848        rc = txCommit(tid, 2, &iplist[0], 0);
 849
 850        if (rc) {
 851                drop_nlink(ip); /* never instantiated */
 852                iput(ip);
 853        } else
 854                d_instantiate(dentry, ip);
 855
 856      free_dname:
 857        free_UCSname(&dname);
 858
 859      out_tx:
 860        txEnd(tid);
 861
 862        mutex_unlock(&JFS_IP(ip)->commit_mutex);
 863        mutex_unlock(&JFS_IP(dir)->commit_mutex);
 864
 865      out:
 866        jfs_info("jfs_link: rc:%d", rc);
 867        return rc;
 868}
 869
 870/*
 871 * NAME:        jfs_symlink(dip, dentry, name)
 872 *
 873 * FUNCTION:    creates a symbolic link to <symlink> by name <name>
 874 *                      in directory <dip>
 875 *
 876 * PARAMETER:   dip     - parent directory vnode
 877 *              dentry  - dentry of symbolic link
 878 *              name    - the path name of the existing object
 879 *                        that will be the source of the link
 880 *
 881 * RETURN:      errors from subroutines
 882 *
 883 * note:
 884 * ENAMETOOLONG: pathname resolution of a symbolic link produced
 885 * an intermediate result whose length exceeds PATH_MAX [XPG4.2]
 886*/
 887
 888static int jfs_symlink(struct inode *dip, struct dentry *dentry,
 889                const char *name)
 890{
 891        int rc;
 892        tid_t tid;
 893        ino_t ino = 0;
 894        struct component_name dname;
 895        int ssize;              /* source pathname size */
 896        struct btstack btstack;
 897        struct inode *ip = d_inode(dentry);
 898        s64 xlen = 0;
 899        int bmask = 0, xsize;
 900        s64 xaddr;
 901        struct metapage *mp;
 902        struct super_block *sb;
 903        struct tblock *tblk;
 904
 905        struct inode *iplist[2];
 906
 907        jfs_info("jfs_symlink: dip:0x%p name:%s", dip, name);
 908
 909        rc = dquot_initialize(dip);
 910        if (rc)
 911                goto out1;
 912
 913        ssize = strlen(name) + 1;
 914
 915        /*
 916         * search parent directory for entry/freespace
 917         * (dtSearch() returns parent directory page pinned)
 918         */
 919
 920        if ((rc = get_UCSname(&dname, dentry)))
 921                goto out1;
 922
 923        /*
 924         * allocate on-disk/in-memory inode for symbolic link:
 925         * (iAlloc() returns new, locked inode)
 926         */
 927        ip = ialloc(dip, S_IFLNK | 0777);
 928        if (IS_ERR(ip)) {
 929                rc = PTR_ERR(ip);
 930                goto out2;
 931        }
 932
 933        tid = txBegin(dip->i_sb, 0);
 934
 935        mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
 936        mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
 937
 938        rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
 939        if (rc)
 940                goto out3;
 941
 942        tblk = tid_to_tblock(tid);
 943        tblk->xflag |= COMMIT_CREATE;
 944        tblk->ino = ip->i_ino;
 945        tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
 946
 947        /* fix symlink access permission
 948         * (dir_create() ANDs in the u.u_cmask,
 949         * but symlinks really need to be 777 access)
 950         */
 951        ip->i_mode |= 0777;
 952
 953        /*
 954         * write symbolic link target path name
 955         */
 956        xtInitRoot(tid, ip);
 957
 958        /*
 959         * write source path name inline in on-disk inode (fast symbolic link)
 960         */
 961
 962        if (ssize <= IDATASIZE) {
 963                ip->i_op = &jfs_fast_symlink_inode_operations;
 964
 965                ip->i_link = JFS_IP(ip)->i_inline;
 966                memcpy(ip->i_link, name, ssize);
 967                ip->i_size = ssize - 1;
 968
 969                /*
 970                 * if symlink is > 128 bytes, we don't have the space to
 971                 * store inline extended attributes
 972                 */
 973                if (ssize > sizeof (JFS_IP(ip)->i_inline))
 974                        JFS_IP(ip)->mode2 &= ~INLINEEA;
 975
 976                jfs_info("jfs_symlink: fast symlink added  ssize:%d name:%s ",
 977                         ssize, name);
 978        }
 979        /*
 980         * write source path name in a single extent
 981         */
 982        else {
 983                jfs_info("jfs_symlink: allocate extent ip:0x%p", ip);
 984
 985                ip->i_op = &jfs_symlink_inode_operations;
 986                inode_nohighmem(ip);
 987                ip->i_mapping->a_ops = &jfs_aops;
 988
 989                /*
 990                 * even though the data of symlink object (source
 991                 * path name) is treated as non-journaled user data,
 992                 * it is read/written thru buffer cache for performance.
 993                 */
 994                sb = ip->i_sb;
 995                bmask = JFS_SBI(sb)->bsize - 1;
 996                xsize = (ssize + bmask) & ~bmask;
 997                xaddr = 0;
 998                xlen = xsize >> JFS_SBI(sb)->l2bsize;
 999                if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0))) {
1000                        txAbort(tid, 0);
1001                        goto out3;
1002                }
1003                ip->i_size = ssize - 1;
1004                while (ssize) {
1005                        /* This is kind of silly since PATH_MAX == 4K */
1006                        int copy_size = min(ssize, PSIZE);
1007
1008                        mp = get_metapage(ip, xaddr, PSIZE, 1);
1009
1010                        if (mp == NULL) {
1011                                xtTruncate(tid, ip, 0, COMMIT_PWMAP);
1012                                rc = -EIO;
1013                                txAbort(tid, 0);
1014                                goto out3;
1015                        }
1016                        memcpy(mp->data, name, copy_size);
1017                        flush_metapage(mp);
1018                        ssize -= copy_size;
1019                        name += copy_size;
1020                        xaddr += JFS_SBI(sb)->nbperpage;
1021                }
1022        }
1023
1024        /*
1025         * create entry for symbolic link in parent directory
1026         */
1027        rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE);
1028        if (rc == 0) {
1029                ino = ip->i_ino;
1030                rc = dtInsert(tid, dip, &dname, &ino, &btstack);
1031        }
1032        if (rc) {
1033                if (xlen)
1034                        xtTruncate(tid, ip, 0, COMMIT_PWMAP);
1035                txAbort(tid, 0);
1036                /* discard new inode */
1037                goto out3;
1038        }
1039
1040        mark_inode_dirty(ip);
1041
1042        dip->i_ctime = dip->i_mtime = CURRENT_TIME;
1043        mark_inode_dirty(dip);
1044        /*
1045         * commit update of parent directory and link object
1046         */
1047
1048        iplist[0] = dip;
1049        iplist[1] = ip;
1050        rc = txCommit(tid, 2, &iplist[0], 0);
1051
1052      out3:
1053        txEnd(tid);
1054        mutex_unlock(&JFS_IP(ip)->commit_mutex);
1055        mutex_unlock(&JFS_IP(dip)->commit_mutex);
1056        if (rc) {
1057                free_ea_wmap(ip);
1058                clear_nlink(ip);
1059                unlock_new_inode(ip);
1060                iput(ip);
1061        } else {
1062                unlock_new_inode(ip);
1063                d_instantiate(dentry, ip);
1064        }
1065
1066      out2:
1067        free_UCSname(&dname);
1068
1069      out1:
1070        jfs_info("jfs_symlink: rc:%d", rc);
1071        return rc;
1072}
1073
1074
1075/*
1076 * NAME:        jfs_rename
1077 *
1078 * FUNCTION:    rename a file or directory
1079 */
1080static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1081               struct inode *new_dir, struct dentry *new_dentry)
1082{
1083        struct btstack btstack;
1084        ino_t ino;
1085        struct component_name new_dname;
1086        struct inode *new_ip;
1087        struct component_name old_dname;
1088        struct inode *old_ip;
1089        int rc;
1090        tid_t tid;
1091        struct tlock *tlck;
1092        struct dt_lock *dtlck;
1093        struct lv *lv;
1094        int ipcount;
1095        struct inode *iplist[4];
1096        struct tblock *tblk;
1097        s64 new_size = 0;
1098        int commit_flag;
1099
1100
1101        jfs_info("jfs_rename: %pd %pd", old_dentry, new_dentry);
1102
1103        rc = dquot_initialize(old_dir);
1104        if (rc)
1105                goto out1;
1106        rc = dquot_initialize(new_dir);
1107        if (rc)
1108                goto out1;
1109
1110        old_ip = d_inode(old_dentry);
1111        new_ip = d_inode(new_dentry);
1112
1113        if ((rc = get_UCSname(&old_dname, old_dentry)))
1114                goto out1;
1115
1116        if ((rc = get_UCSname(&new_dname, new_dentry)))
1117                goto out2;
1118
1119        /*
1120         * Make sure source inode number is what we think it is
1121         */
1122        rc = dtSearch(old_dir, &old_dname, &ino, &btstack, JFS_LOOKUP);
1123        if (rc || (ino != old_ip->i_ino)) {
1124                rc = -ENOENT;
1125                goto out3;
1126        }
1127
1128        /*
1129         * Make sure dest inode number (if any) is what we think it is
1130         */
1131        rc = dtSearch(new_dir, &new_dname, &ino, &btstack, JFS_LOOKUP);
1132        if (!rc) {
1133                if ((!new_ip) || (ino != new_ip->i_ino)) {
1134                        rc = -ESTALE;
1135                        goto out3;
1136                }
1137        } else if (rc != -ENOENT)
1138                goto out3;
1139        else if (new_ip) {
1140                /* no entry exists, but one was expected */
1141                rc = -ESTALE;
1142                goto out3;
1143        }
1144
1145        if (S_ISDIR(old_ip->i_mode)) {
1146                if (new_ip) {
1147                        if (!dtEmpty(new_ip)) {
1148                                rc = -ENOTEMPTY;
1149                                goto out3;
1150                        }
1151                }
1152        } else if (new_ip) {
1153                IWRITE_LOCK(new_ip, RDWRLOCK_NORMAL);
1154                /* Init inode for quota operations. */
1155                rc = dquot_initialize(new_ip);
1156                if (rc)
1157                        goto out_unlock;
1158        }
1159
1160        /*
1161         * The real work starts here
1162         */
1163        tid = txBegin(new_dir->i_sb, 0);
1164
1165        /*
1166         * How do we know the locking is safe from deadlocks?
1167         * The vfs does the hard part for us.  Any time we are taking nested
1168         * commit_mutexes, the vfs already has i_mutex held on the parent.
1169         * Here, the vfs has already taken i_mutex on both old_dir and new_dir.
1170         */
1171        mutex_lock_nested(&JFS_IP(new_dir)->commit_mutex, COMMIT_MUTEX_PARENT);
1172        mutex_lock_nested(&JFS_IP(old_ip)->commit_mutex, COMMIT_MUTEX_CHILD);
1173        if (old_dir != new_dir)
1174                mutex_lock_nested(&JFS_IP(old_dir)->commit_mutex,
1175                                  COMMIT_MUTEX_SECOND_PARENT);
1176
1177        if (new_ip) {
1178                mutex_lock_nested(&JFS_IP(new_ip)->commit_mutex,
1179                                  COMMIT_MUTEX_VICTIM);
1180                /*
1181                 * Change existing directory entry to new inode number
1182                 */
1183                ino = new_ip->i_ino;
1184                rc = dtModify(tid, new_dir, &new_dname, &ino,
1185                              old_ip->i_ino, JFS_RENAME);
1186                if (rc)
1187                        goto out_tx;
1188                drop_nlink(new_ip);
1189                if (S_ISDIR(new_ip->i_mode)) {
1190                        drop_nlink(new_ip);
1191                        if (new_ip->i_nlink) {
1192                                mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
1193                                if (old_dir != new_dir)
1194                                        mutex_unlock(&JFS_IP(old_dir)->commit_mutex);
1195                                mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
1196                                mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
1197                                if (!S_ISDIR(old_ip->i_mode) && new_ip)
1198                                        IWRITE_UNLOCK(new_ip);
1199                                jfs_error(new_ip->i_sb,
1200                                          "new_ip->i_nlink != 0\n");
1201                                return -EIO;
1202                        }
1203                        tblk = tid_to_tblock(tid);
1204                        tblk->xflag |= COMMIT_DELETE;
1205                        tblk->u.ip = new_ip;
1206                } else if (new_ip->i_nlink == 0) {
1207                        assert(!test_cflag(COMMIT_Nolink, new_ip));
1208                        /* free block resources */
1209                        if ((new_size = commitZeroLink(tid, new_ip)) < 0) {
1210                                txAbort(tid, 1);        /* Marks FS Dirty */
1211                                rc = new_size;
1212                                goto out_tx;
1213                        }
1214                        tblk = tid_to_tblock(tid);
1215                        tblk->xflag |= COMMIT_DELETE;
1216                        tblk->u.ip = new_ip;
1217                } else {
1218                        new_ip->i_ctime = CURRENT_TIME;
1219                        mark_inode_dirty(new_ip);
1220                }
1221        } else {
1222                /*
1223                 * Add new directory entry
1224                 */
1225                rc = dtSearch(new_dir, &new_dname, &ino, &btstack,
1226                              JFS_CREATE);
1227                if (rc) {
1228                        jfs_err("jfs_rename didn't expect dtSearch to fail w/rc = %d",
1229                                rc);
1230                        goto out_tx;
1231                }
1232
1233                ino = old_ip->i_ino;
1234                rc = dtInsert(tid, new_dir, &new_dname, &ino, &btstack);
1235                if (rc) {
1236                        if (rc == -EIO)
1237                                jfs_err("jfs_rename: dtInsert returned -EIO");
1238                        goto out_tx;
1239                }
1240                if (S_ISDIR(old_ip->i_mode))
1241                        inc_nlink(new_dir);
1242        }
1243        /*
1244         * Remove old directory entry
1245         */
1246
1247        ino = old_ip->i_ino;
1248        rc = dtDelete(tid, old_dir, &old_dname, &ino, JFS_REMOVE);
1249        if (rc) {
1250                jfs_err("jfs_rename did not expect dtDelete to return rc = %d",
1251                        rc);
1252                txAbort(tid, 1);        /* Marks Filesystem dirty */
1253                goto out_tx;
1254        }
1255        if (S_ISDIR(old_ip->i_mode)) {
1256                drop_nlink(old_dir);
1257                if (old_dir != new_dir) {
1258                        /*
1259                         * Change inode number of parent for moved directory
1260                         */
1261
1262                        JFS_IP(old_ip)->i_dtroot.header.idotdot =
1263                                cpu_to_le32(new_dir->i_ino);
1264
1265                        /* Linelock header of dtree */
1266                        tlck = txLock(tid, old_ip,
1267                                    (struct metapage *) &JFS_IP(old_ip)->bxflag,
1268                                      tlckDTREE | tlckBTROOT | tlckRELINK);
1269                        dtlck = (struct dt_lock *) & tlck->lock;
1270                        ASSERT(dtlck->index == 0);
1271                        lv = & dtlck->lv[0];
1272                        lv->offset = 0;
1273                        lv->length = 1;
1274                        dtlck->index++;
1275                }
1276        }
1277
1278        /*
1279         * Update ctime on changed/moved inodes & mark dirty
1280         */
1281        old_ip->i_ctime = CURRENT_TIME;
1282        mark_inode_dirty(old_ip);
1283
1284        new_dir->i_ctime = new_dir->i_mtime = current_fs_time(new_dir->i_sb);
1285        mark_inode_dirty(new_dir);
1286
1287        /* Build list of inodes modified by this transaction */
1288        ipcount = 0;
1289        iplist[ipcount++] = old_ip;
1290        if (new_ip)
1291                iplist[ipcount++] = new_ip;
1292        iplist[ipcount++] = old_dir;
1293
1294        if (old_dir != new_dir) {
1295                iplist[ipcount++] = new_dir;
1296                old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
1297                mark_inode_dirty(old_dir);
1298        }
1299
1300        /*
1301         * Incomplete truncate of file data can
1302         * result in timing problems unless we synchronously commit the
1303         * transaction.
1304         */
1305        if (new_size)
1306                commit_flag = COMMIT_SYNC;
1307        else
1308                commit_flag = 0;
1309
1310        rc = txCommit(tid, ipcount, iplist, commit_flag);
1311
1312      out_tx:
1313        txEnd(tid);
1314        if (new_ip)
1315                mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
1316        if (old_dir != new_dir)
1317                mutex_unlock(&JFS_IP(old_dir)->commit_mutex);
1318        mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
1319        mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
1320
1321        while (new_size && (rc == 0)) {
1322                tid = txBegin(new_ip->i_sb, 0);
1323                mutex_lock(&JFS_IP(new_ip)->commit_mutex);
1324                new_size = xtTruncate_pmap(tid, new_ip, new_size);
1325                if (new_size < 0) {
1326                        txAbort(tid, 1);
1327                        rc = new_size;
1328                } else
1329                        rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
1330                txEnd(tid);
1331                mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
1332        }
1333        if (new_ip && (new_ip->i_nlink == 0))
1334                set_cflag(COMMIT_Nolink, new_ip);
1335        /*
1336         * Truncating the directory index table is not guaranteed.  It
1337         * may need to be done iteratively
1338         */
1339        if (test_cflag(COMMIT_Stale, old_dir)) {
1340                if (old_dir->i_size > 1)
1341                        jfs_truncate_nolock(old_dir, 0);
1342
1343                clear_cflag(COMMIT_Stale, old_dir);
1344        }
1345      out_unlock:
1346        if (new_ip && !S_ISDIR(new_ip->i_mode))
1347                IWRITE_UNLOCK(new_ip);
1348      out3:
1349        free_UCSname(&new_dname);
1350      out2:
1351        free_UCSname(&old_dname);
1352      out1:
1353        jfs_info("jfs_rename: returning %d", rc);
1354        return rc;
1355}
1356
1357
1358/*
1359 * NAME:        jfs_mknod
1360 *
1361 * FUNCTION:    Create a special file (device)
1362 */
1363static int jfs_mknod(struct inode *dir, struct dentry *dentry,
1364                umode_t mode, dev_t rdev)
1365{
1366        struct jfs_inode_info *jfs_ip;
1367        struct btstack btstack;
1368        struct component_name dname;
1369        ino_t ino;
1370        struct inode *ip;
1371        struct inode *iplist[2];
1372        int rc;
1373        tid_t tid;
1374        struct tblock *tblk;
1375
1376        jfs_info("jfs_mknod: %pd", dentry);
1377
1378        rc = dquot_initialize(dir);
1379        if (rc)
1380                goto out;
1381
1382        if ((rc = get_UCSname(&dname, dentry)))
1383                goto out;
1384
1385        ip = ialloc(dir, mode);
1386        if (IS_ERR(ip)) {
1387                rc = PTR_ERR(ip);
1388                goto out1;
1389        }
1390        jfs_ip = JFS_IP(ip);
1391
1392        tid = txBegin(dir->i_sb, 0);
1393
1394        mutex_lock_nested(&JFS_IP(dir)->commit_mutex, COMMIT_MUTEX_PARENT);
1395        mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
1396
1397        rc = jfs_init_acl(tid, ip, dir);
1398        if (rc)
1399                goto out3;
1400
1401        rc = jfs_init_security(tid, ip, dir, &dentry->d_name);
1402        if (rc) {
1403                txAbort(tid, 0);
1404                goto out3;
1405        }
1406
1407        if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) {
1408                txAbort(tid, 0);
1409                goto out3;
1410        }
1411
1412        tblk = tid_to_tblock(tid);
1413        tblk->xflag |= COMMIT_CREATE;
1414        tblk->ino = ip->i_ino;
1415        tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
1416
1417        ino = ip->i_ino;
1418        if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) {
1419                txAbort(tid, 0);
1420                goto out3;
1421        }
1422
1423        ip->i_op = &jfs_file_inode_operations;
1424        jfs_ip->dev = new_encode_dev(rdev);
1425        init_special_inode(ip, ip->i_mode, rdev);
1426
1427        mark_inode_dirty(ip);
1428
1429        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
1430
1431        mark_inode_dirty(dir);
1432
1433        iplist[0] = dir;
1434        iplist[1] = ip;
1435        rc = txCommit(tid, 2, iplist, 0);
1436
1437      out3:
1438        txEnd(tid);
1439        mutex_unlock(&JFS_IP(ip)->commit_mutex);
1440        mutex_unlock(&JFS_IP(dir)->commit_mutex);
1441        if (rc) {
1442                free_ea_wmap(ip);
1443                clear_nlink(ip);
1444                unlock_new_inode(ip);
1445                iput(ip);
1446        } else {
1447                unlock_new_inode(ip);
1448                d_instantiate(dentry, ip);
1449        }
1450
1451      out1:
1452        free_UCSname(&dname);
1453
1454      out:
1455        jfs_info("jfs_mknod: returning %d", rc);
1456        return rc;
1457}
1458
1459static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, unsigned int flags)
1460{
1461        struct btstack btstack;
1462        ino_t inum;
1463        struct inode *ip;
1464        struct component_name key;
1465        int rc;
1466
1467        jfs_info("jfs_lookup: name = %pd", dentry);
1468
1469        if ((rc = get_UCSname(&key, dentry)))
1470                return ERR_PTR(rc);
1471        rc = dtSearch(dip, &key, &inum, &btstack, JFS_LOOKUP);
1472        free_UCSname(&key);
1473        if (rc == -ENOENT) {
1474                ip = NULL;
1475        } else if (rc) {
1476                jfs_err("jfs_lookup: dtSearch returned %d", rc);
1477                ip = ERR_PTR(rc);
1478        } else {
1479                ip = jfs_iget(dip->i_sb, inum);
1480                if (IS_ERR(ip))
1481                        jfs_err("jfs_lookup: iget failed on inum %d", (uint)inum);
1482        }
1483
1484        return d_splice_alias(ip, dentry);
1485}
1486
1487static struct inode *jfs_nfs_get_inode(struct super_block *sb,
1488                u64 ino, u32 generation)
1489{
1490        struct inode *inode;
1491
1492        if (ino == 0)
1493                return ERR_PTR(-ESTALE);
1494        inode = jfs_iget(sb, ino);
1495        if (IS_ERR(inode))
1496                return ERR_CAST(inode);
1497
1498        if (generation && inode->i_generation != generation) {
1499                iput(inode);
1500                return ERR_PTR(-ESTALE);
1501        }
1502
1503        return inode;
1504}
1505
1506struct dentry *jfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
1507                int fh_len, int fh_type)
1508{
1509        return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
1510                                    jfs_nfs_get_inode);
1511}
1512
1513struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
1514                int fh_len, int fh_type)
1515{
1516        return generic_fh_to_parent(sb, fid, fh_len, fh_type,
1517                                    jfs_nfs_get_inode);
1518}
1519
1520struct dentry *jfs_get_parent(struct dentry *dentry)
1521{
1522        unsigned long parent_ino;
1523
1524        parent_ino =
1525                le32_to_cpu(JFS_IP(d_inode(dentry))->i_dtroot.header.idotdot);
1526
1527        return d_obtain_alias(jfs_iget(dentry->d_sb, parent_ino));
1528}
1529
1530const struct inode_operations jfs_dir_inode_operations = {
1531        .create         = jfs_create,
1532        .lookup         = jfs_lookup,
1533        .link           = jfs_link,
1534        .unlink         = jfs_unlink,
1535        .symlink        = jfs_symlink,
1536        .mkdir          = jfs_mkdir,
1537        .rmdir          = jfs_rmdir,
1538        .mknod          = jfs_mknod,
1539        .rename         = jfs_rename,
1540        .setxattr       = generic_setxattr,
1541        .getxattr       = generic_getxattr,
1542        .listxattr      = jfs_listxattr,
1543        .removexattr    = generic_removexattr,
1544        .setattr        = jfs_setattr,
1545#ifdef CONFIG_JFS_POSIX_ACL
1546        .get_acl        = jfs_get_acl,
1547        .set_acl        = jfs_set_acl,
1548#endif
1549};
1550
1551const struct file_operations jfs_dir_operations = {
1552        .read           = generic_read_dir,
1553        .iterate        = jfs_readdir,
1554        .fsync          = jfs_fsync,
1555        .unlocked_ioctl = jfs_ioctl,
1556#ifdef CONFIG_COMPAT
1557        .compat_ioctl   = jfs_compat_ioctl,
1558#endif
1559        .llseek         = generic_file_llseek,
1560};
1561
1562static int jfs_ci_hash(const struct dentry *dir, struct qstr *this)
1563{
1564        unsigned long hash;
1565        int i;
1566
1567        hash = init_name_hash(dir);
1568        for (i=0; i < this->len; i++)
1569                hash = partial_name_hash(tolower(this->name[i]), hash);
1570        this->hash = end_name_hash(hash);
1571
1572        return 0;
1573}
1574
1575static int jfs_ci_compare(const struct dentry *dentry,
1576                unsigned int len, const char *str, const struct qstr *name)
1577{
1578        int i, result = 1;
1579
1580        if (len != name->len)
1581                goto out;
1582        for (i=0; i < len; i++) {
1583                if (tolower(str[i]) != tolower(name->name[i]))
1584                        goto out;
1585        }
1586        result = 0;
1587out:
1588        return result;
1589}
1590
1591static int jfs_ci_revalidate(struct dentry *dentry, unsigned int flags)
1592{
1593        /*
1594         * This is not negative dentry. Always valid.
1595         *
1596         * Note, rename() to existing directory entry will have ->d_inode,
1597         * and will use existing name which isn't specified name by user.
1598         *
1599         * We may be able to drop this positive dentry here. But dropping
1600         * positive dentry isn't good idea. So it's unsupported like
1601         * rename("filename", "FILENAME") for now.
1602         */
1603        if (d_really_is_positive(dentry))
1604                return 1;
1605
1606        /*
1607         * This may be nfsd (or something), anyway, we can't see the
1608         * intent of this. So, since this can be for creation, drop it.
1609         */
1610        if (!flags)
1611                return 0;
1612
1613        /*
1614         * Drop the negative dentry, in order to make sure to use the
1615         * case sensitive name which is specified by user if this is
1616         * for creation.
1617         */
1618        if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
1619                return 0;
1620        return 1;
1621}
1622
1623const struct dentry_operations jfs_ci_dentry_operations =
1624{
1625        .d_hash = jfs_ci_hash,
1626        .d_compare = jfs_ci_compare,
1627        .d_revalidate = jfs_ci_revalidate,
1628};
1629