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(dip);
 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(dip);
 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(dip);
 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(ip);
 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(ip);
 842        dir->i_ctime = dir->i_mtime = current_time(dir);
 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(dip);
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                      unsigned int flags)
1083{
1084        struct btstack btstack;
1085        ino_t ino;
1086        struct component_name new_dname;
1087        struct inode *new_ip;
1088        struct component_name old_dname;
1089        struct inode *old_ip;
1090        int rc;
1091        tid_t tid;
1092        struct tlock *tlck;
1093        struct dt_lock *dtlck;
1094        struct lv *lv;
1095        int ipcount;
1096        struct inode *iplist[4];
1097        struct tblock *tblk;
1098        s64 new_size = 0;
1099        int commit_flag;
1100
1101        if (flags & ~RENAME_NOREPLACE)
1102                return -EINVAL;
1103
1104        jfs_info("jfs_rename: %pd %pd", old_dentry, new_dentry);
1105
1106        rc = dquot_initialize(old_dir);
1107        if (rc)
1108                goto out1;
1109        rc = dquot_initialize(new_dir);
1110        if (rc)
1111                goto out1;
1112
1113        old_ip = d_inode(old_dentry);
1114        new_ip = d_inode(new_dentry);
1115
1116        if ((rc = get_UCSname(&old_dname, old_dentry)))
1117                goto out1;
1118
1119        if ((rc = get_UCSname(&new_dname, new_dentry)))
1120                goto out2;
1121
1122        /*
1123         * Make sure source inode number is what we think it is
1124         */
1125        rc = dtSearch(old_dir, &old_dname, &ino, &btstack, JFS_LOOKUP);
1126        if (rc || (ino != old_ip->i_ino)) {
1127                rc = -ENOENT;
1128                goto out3;
1129        }
1130
1131        /*
1132         * Make sure dest inode number (if any) is what we think it is
1133         */
1134        rc = dtSearch(new_dir, &new_dname, &ino, &btstack, JFS_LOOKUP);
1135        if (!rc) {
1136                if ((!new_ip) || (ino != new_ip->i_ino)) {
1137                        rc = -ESTALE;
1138                        goto out3;
1139                }
1140        } else if (rc != -ENOENT)
1141                goto out3;
1142        else if (new_ip) {
1143                /* no entry exists, but one was expected */
1144                rc = -ESTALE;
1145                goto out3;
1146        }
1147
1148        if (S_ISDIR(old_ip->i_mode)) {
1149                if (new_ip) {
1150                        if (!dtEmpty(new_ip)) {
1151                                rc = -ENOTEMPTY;
1152                                goto out3;
1153                        }
1154                }
1155        } else if (new_ip) {
1156                IWRITE_LOCK(new_ip, RDWRLOCK_NORMAL);
1157                /* Init inode for quota operations. */
1158                rc = dquot_initialize(new_ip);
1159                if (rc)
1160                        goto out_unlock;
1161        }
1162
1163        /*
1164         * The real work starts here
1165         */
1166        tid = txBegin(new_dir->i_sb, 0);
1167
1168        /*
1169         * How do we know the locking is safe from deadlocks?
1170         * The vfs does the hard part for us.  Any time we are taking nested
1171         * commit_mutexes, the vfs already has i_mutex held on the parent.
1172         * Here, the vfs has already taken i_mutex on both old_dir and new_dir.
1173         */
1174        mutex_lock_nested(&JFS_IP(new_dir)->commit_mutex, COMMIT_MUTEX_PARENT);
1175        mutex_lock_nested(&JFS_IP(old_ip)->commit_mutex, COMMIT_MUTEX_CHILD);
1176        if (old_dir != new_dir)
1177                mutex_lock_nested(&JFS_IP(old_dir)->commit_mutex,
1178                                  COMMIT_MUTEX_SECOND_PARENT);
1179
1180        if (new_ip) {
1181                mutex_lock_nested(&JFS_IP(new_ip)->commit_mutex,
1182                                  COMMIT_MUTEX_VICTIM);
1183                /*
1184                 * Change existing directory entry to new inode number
1185                 */
1186                ino = new_ip->i_ino;
1187                rc = dtModify(tid, new_dir, &new_dname, &ino,
1188                              old_ip->i_ino, JFS_RENAME);
1189                if (rc)
1190                        goto out_tx;
1191                drop_nlink(new_ip);
1192                if (S_ISDIR(new_ip->i_mode)) {
1193                        drop_nlink(new_ip);
1194                        if (new_ip->i_nlink) {
1195                                mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
1196                                if (old_dir != new_dir)
1197                                        mutex_unlock(&JFS_IP(old_dir)->commit_mutex);
1198                                mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
1199                                mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
1200                                if (!S_ISDIR(old_ip->i_mode) && new_ip)
1201                                        IWRITE_UNLOCK(new_ip);
1202                                jfs_error(new_ip->i_sb,
1203                                          "new_ip->i_nlink != 0\n");
1204                                return -EIO;
1205                        }
1206                        tblk = tid_to_tblock(tid);
1207                        tblk->xflag |= COMMIT_DELETE;
1208                        tblk->u.ip = new_ip;
1209                } else if (new_ip->i_nlink == 0) {
1210                        assert(!test_cflag(COMMIT_Nolink, new_ip));
1211                        /* free block resources */
1212                        if ((new_size = commitZeroLink(tid, new_ip)) < 0) {
1213                                txAbort(tid, 1);        /* Marks FS Dirty */
1214                                rc = new_size;
1215                                goto out_tx;
1216                        }
1217                        tblk = tid_to_tblock(tid);
1218                        tblk->xflag |= COMMIT_DELETE;
1219                        tblk->u.ip = new_ip;
1220                } else {
1221                        new_ip->i_ctime = current_time(new_ip);
1222                        mark_inode_dirty(new_ip);
1223                }
1224        } else {
1225                /*
1226                 * Add new directory entry
1227                 */
1228                rc = dtSearch(new_dir, &new_dname, &ino, &btstack,
1229                              JFS_CREATE);
1230                if (rc) {
1231                        jfs_err("jfs_rename didn't expect dtSearch to fail w/rc = %d",
1232                                rc);
1233                        goto out_tx;
1234                }
1235
1236                ino = old_ip->i_ino;
1237                rc = dtInsert(tid, new_dir, &new_dname, &ino, &btstack);
1238                if (rc) {
1239                        if (rc == -EIO)
1240                                jfs_err("jfs_rename: dtInsert returned -EIO");
1241                        goto out_tx;
1242                }
1243                if (S_ISDIR(old_ip->i_mode))
1244                        inc_nlink(new_dir);
1245        }
1246        /*
1247         * Remove old directory entry
1248         */
1249
1250        ino = old_ip->i_ino;
1251        rc = dtDelete(tid, old_dir, &old_dname, &ino, JFS_REMOVE);
1252        if (rc) {
1253                jfs_err("jfs_rename did not expect dtDelete to return rc = %d",
1254                        rc);
1255                txAbort(tid, 1);        /* Marks Filesystem dirty */
1256                goto out_tx;
1257        }
1258        if (S_ISDIR(old_ip->i_mode)) {
1259                drop_nlink(old_dir);
1260                if (old_dir != new_dir) {
1261                        /*
1262                         * Change inode number of parent for moved directory
1263                         */
1264
1265                        JFS_IP(old_ip)->i_dtroot.header.idotdot =
1266                                cpu_to_le32(new_dir->i_ino);
1267
1268                        /* Linelock header of dtree */
1269                        tlck = txLock(tid, old_ip,
1270                                    (struct metapage *) &JFS_IP(old_ip)->bxflag,
1271                                      tlckDTREE | tlckBTROOT | tlckRELINK);
1272                        dtlck = (struct dt_lock *) & tlck->lock;
1273                        ASSERT(dtlck->index == 0);
1274                        lv = & dtlck->lv[0];
1275                        lv->offset = 0;
1276                        lv->length = 1;
1277                        dtlck->index++;
1278                }
1279        }
1280
1281        /*
1282         * Update ctime on changed/moved inodes & mark dirty
1283         */
1284        old_ip->i_ctime = current_time(old_ip);
1285        mark_inode_dirty(old_ip);
1286
1287        new_dir->i_ctime = new_dir->i_mtime = current_time(new_dir);
1288        mark_inode_dirty(new_dir);
1289
1290        /* Build list of inodes modified by this transaction */
1291        ipcount = 0;
1292        iplist[ipcount++] = old_ip;
1293        if (new_ip)
1294                iplist[ipcount++] = new_ip;
1295        iplist[ipcount++] = old_dir;
1296
1297        if (old_dir != new_dir) {
1298                iplist[ipcount++] = new_dir;
1299                old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
1300                mark_inode_dirty(old_dir);
1301        }
1302
1303        /*
1304         * Incomplete truncate of file data can
1305         * result in timing problems unless we synchronously commit the
1306         * transaction.
1307         */
1308        if (new_size)
1309                commit_flag = COMMIT_SYNC;
1310        else
1311                commit_flag = 0;
1312
1313        rc = txCommit(tid, ipcount, iplist, commit_flag);
1314
1315      out_tx:
1316        txEnd(tid);
1317        if (new_ip)
1318                mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
1319        if (old_dir != new_dir)
1320                mutex_unlock(&JFS_IP(old_dir)->commit_mutex);
1321        mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
1322        mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
1323
1324        while (new_size && (rc == 0)) {
1325                tid = txBegin(new_ip->i_sb, 0);
1326                mutex_lock(&JFS_IP(new_ip)->commit_mutex);
1327                new_size = xtTruncate_pmap(tid, new_ip, new_size);
1328                if (new_size < 0) {
1329                        txAbort(tid, 1);
1330                        rc = new_size;
1331                } else
1332                        rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
1333                txEnd(tid);
1334                mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
1335        }
1336        if (new_ip && (new_ip->i_nlink == 0))
1337                set_cflag(COMMIT_Nolink, new_ip);
1338        /*
1339         * Truncating the directory index table is not guaranteed.  It
1340         * may need to be done iteratively
1341         */
1342        if (test_cflag(COMMIT_Stale, old_dir)) {
1343                if (old_dir->i_size > 1)
1344                        jfs_truncate_nolock(old_dir, 0);
1345
1346                clear_cflag(COMMIT_Stale, old_dir);
1347        }
1348      out_unlock:
1349        if (new_ip && !S_ISDIR(new_ip->i_mode))
1350                IWRITE_UNLOCK(new_ip);
1351      out3:
1352        free_UCSname(&new_dname);
1353      out2:
1354        free_UCSname(&old_dname);
1355      out1:
1356        jfs_info("jfs_rename: returning %d", rc);
1357        return rc;
1358}
1359
1360
1361/*
1362 * NAME:        jfs_mknod
1363 *
1364 * FUNCTION:    Create a special file (device)
1365 */
1366static int jfs_mknod(struct inode *dir, struct dentry *dentry,
1367                umode_t mode, dev_t rdev)
1368{
1369        struct jfs_inode_info *jfs_ip;
1370        struct btstack btstack;
1371        struct component_name dname;
1372        ino_t ino;
1373        struct inode *ip;
1374        struct inode *iplist[2];
1375        int rc;
1376        tid_t tid;
1377        struct tblock *tblk;
1378
1379        jfs_info("jfs_mknod: %pd", dentry);
1380
1381        rc = dquot_initialize(dir);
1382        if (rc)
1383                goto out;
1384
1385        if ((rc = get_UCSname(&dname, dentry)))
1386                goto out;
1387
1388        ip = ialloc(dir, mode);
1389        if (IS_ERR(ip)) {
1390                rc = PTR_ERR(ip);
1391                goto out1;
1392        }
1393        jfs_ip = JFS_IP(ip);
1394
1395        tid = txBegin(dir->i_sb, 0);
1396
1397        mutex_lock_nested(&JFS_IP(dir)->commit_mutex, COMMIT_MUTEX_PARENT);
1398        mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
1399
1400        rc = jfs_init_acl(tid, ip, dir);
1401        if (rc)
1402                goto out3;
1403
1404        rc = jfs_init_security(tid, ip, dir, &dentry->d_name);
1405        if (rc) {
1406                txAbort(tid, 0);
1407                goto out3;
1408        }
1409
1410        if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) {
1411                txAbort(tid, 0);
1412                goto out3;
1413        }
1414
1415        tblk = tid_to_tblock(tid);
1416        tblk->xflag |= COMMIT_CREATE;
1417        tblk->ino = ip->i_ino;
1418        tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
1419
1420        ino = ip->i_ino;
1421        if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) {
1422                txAbort(tid, 0);
1423                goto out3;
1424        }
1425
1426        ip->i_op = &jfs_file_inode_operations;
1427        jfs_ip->dev = new_encode_dev(rdev);
1428        init_special_inode(ip, ip->i_mode, rdev);
1429
1430        mark_inode_dirty(ip);
1431
1432        dir->i_ctime = dir->i_mtime = current_time(dir);
1433
1434        mark_inode_dirty(dir);
1435
1436        iplist[0] = dir;
1437        iplist[1] = ip;
1438        rc = txCommit(tid, 2, iplist, 0);
1439
1440      out3:
1441        txEnd(tid);
1442        mutex_unlock(&JFS_IP(ip)->commit_mutex);
1443        mutex_unlock(&JFS_IP(dir)->commit_mutex);
1444        if (rc) {
1445                free_ea_wmap(ip);
1446                clear_nlink(ip);
1447                unlock_new_inode(ip);
1448                iput(ip);
1449        } else {
1450                unlock_new_inode(ip);
1451                d_instantiate(dentry, ip);
1452        }
1453
1454      out1:
1455        free_UCSname(&dname);
1456
1457      out:
1458        jfs_info("jfs_mknod: returning %d", rc);
1459        return rc;
1460}
1461
1462static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, unsigned int flags)
1463{
1464        struct btstack btstack;
1465        ino_t inum;
1466        struct inode *ip;
1467        struct component_name key;
1468        int rc;
1469
1470        jfs_info("jfs_lookup: name = %pd", dentry);
1471
1472        if ((rc = get_UCSname(&key, dentry)))
1473                return ERR_PTR(rc);
1474        rc = dtSearch(dip, &key, &inum, &btstack, JFS_LOOKUP);
1475        free_UCSname(&key);
1476        if (rc == -ENOENT) {
1477                ip = NULL;
1478        } else if (rc) {
1479                jfs_err("jfs_lookup: dtSearch returned %d", rc);
1480                ip = ERR_PTR(rc);
1481        } else {
1482                ip = jfs_iget(dip->i_sb, inum);
1483                if (IS_ERR(ip))
1484                        jfs_err("jfs_lookup: iget failed on inum %d", (uint)inum);
1485        }
1486
1487        return d_splice_alias(ip, dentry);
1488}
1489
1490static struct inode *jfs_nfs_get_inode(struct super_block *sb,
1491                u64 ino, u32 generation)
1492{
1493        struct inode *inode;
1494
1495        if (ino == 0)
1496                return ERR_PTR(-ESTALE);
1497        inode = jfs_iget(sb, ino);
1498        if (IS_ERR(inode))
1499                return ERR_CAST(inode);
1500
1501        if (generation && inode->i_generation != generation) {
1502                iput(inode);
1503                return ERR_PTR(-ESTALE);
1504        }
1505
1506        return inode;
1507}
1508
1509struct dentry *jfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
1510                int fh_len, int fh_type)
1511{
1512        return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
1513                                    jfs_nfs_get_inode);
1514}
1515
1516struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
1517                int fh_len, int fh_type)
1518{
1519        return generic_fh_to_parent(sb, fid, fh_len, fh_type,
1520                                    jfs_nfs_get_inode);
1521}
1522
1523struct dentry *jfs_get_parent(struct dentry *dentry)
1524{
1525        unsigned long parent_ino;
1526
1527        parent_ino =
1528                le32_to_cpu(JFS_IP(d_inode(dentry))->i_dtroot.header.idotdot);
1529
1530        return d_obtain_alias(jfs_iget(dentry->d_sb, parent_ino));
1531}
1532
1533const struct inode_operations jfs_dir_inode_operations = {
1534        .create         = jfs_create,
1535        .lookup         = jfs_lookup,
1536        .link           = jfs_link,
1537        .unlink         = jfs_unlink,
1538        .symlink        = jfs_symlink,
1539        .mkdir          = jfs_mkdir,
1540        .rmdir          = jfs_rmdir,
1541        .mknod          = jfs_mknod,
1542        .rename         = jfs_rename,
1543        .listxattr      = jfs_listxattr,
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