Showing error 1138

User: Jiri Slaby
Error type: Double Lock
Error type description: Some lock is locked twice unintentionally in a sequence
File location: fs/jfs/namei.c
Line in file: 1299
Project: Linux Kernel
Project version: 2.6.28
Tools: Stanse (1.2)
Entered: 2012-04-29 14:49:11 UTC


Source:

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