Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *   Copyright (C) International Business Machines Corp., 2000-2004
0004  *   Portions Copyright (C) Christoph Hellwig, 2001-2002
0005  */
0006 
0007 #include <linux/fs.h>
0008 #include <linux/namei.h>
0009 #include <linux/ctype.h>
0010 #include <linux/quotaops.h>
0011 #include <linux/exportfs.h>
0012 #include "jfs_incore.h"
0013 #include "jfs_superblock.h"
0014 #include "jfs_inode.h"
0015 #include "jfs_dinode.h"
0016 #include "jfs_dmap.h"
0017 #include "jfs_unicode.h"
0018 #include "jfs_metapage.h"
0019 #include "jfs_xattr.h"
0020 #include "jfs_acl.h"
0021 #include "jfs_debug.h"
0022 
0023 /*
0024  * forward references
0025  */
0026 const struct dentry_operations jfs_ci_dentry_operations;
0027 
0028 static s64 commitZeroLink(tid_t, struct inode *);
0029 
0030 /*
0031  * NAME:    free_ea_wmap(inode)
0032  *
0033  * FUNCTION:    free uncommitted extended attributes from working map
0034  *
0035  */
0036 static inline void free_ea_wmap(struct inode *inode)
0037 {
0038     dxd_t *ea = &JFS_IP(inode)->ea;
0039 
0040     if (ea->flag & DXD_EXTENT) {
0041         /* free EA pages from cache */
0042         invalidate_dxd_metapages(inode, *ea);
0043         dbFree(inode, addressDXD(ea), lengthDXD(ea));
0044     }
0045     ea->flag = 0;
0046 }
0047 
0048 /*
0049  * NAME:    jfs_create(dip, dentry, mode)
0050  *
0051  * FUNCTION:    create a regular file in the parent directory <dip>
0052  *      with name = <from dentry> and mode = <mode>
0053  *
0054  * PARAMETER:   dip - parent directory vnode
0055  *      dentry  - dentry of new file
0056  *      mode    - create mode (rwxrwxrwx).
0057  *      nd- nd struct
0058  *
0059  * RETURN:  Errors from subroutines
0060  *
0061  */
0062 static int jfs_create(struct user_namespace *mnt_userns, struct inode *dip,
0063               struct dentry *dentry, umode_t mode, bool excl)
0064 {
0065     int rc = 0;
0066     tid_t tid;      /* transaction id */
0067     struct inode *ip = NULL;    /* child directory inode */
0068     ino_t ino;
0069     struct component_name dname;    /* child directory name */
0070     struct btstack btstack;
0071     struct inode *iplist[2];
0072     struct tblock *tblk;
0073 
0074     jfs_info("jfs_create: dip:0x%p name:%pd", dip, dentry);
0075 
0076     rc = dquot_initialize(dip);
0077     if (rc)
0078         goto out1;
0079 
0080     /*
0081      * search parent directory for entry/freespace
0082      * (dtSearch() returns parent directory page pinned)
0083      */
0084     if ((rc = get_UCSname(&dname, dentry)))
0085         goto out1;
0086 
0087     /*
0088      * Either iAlloc() or txBegin() may block.  Deadlock can occur if we
0089      * block there while holding dtree page, so we allocate the inode &
0090      * begin the transaction before we search the directory.
0091      */
0092     ip = ialloc(dip, mode);
0093     if (IS_ERR(ip)) {
0094         rc = PTR_ERR(ip);
0095         goto out2;
0096     }
0097 
0098     tid = txBegin(dip->i_sb, 0);
0099 
0100     mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
0101     mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
0102 
0103     rc = jfs_init_acl(tid, ip, dip);
0104     if (rc)
0105         goto out3;
0106 
0107     rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
0108     if (rc) {
0109         txAbort(tid, 0);
0110         goto out3;
0111     }
0112 
0113     if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
0114         jfs_err("jfs_create: dtSearch returned %d", rc);
0115         txAbort(tid, 0);
0116         goto out3;
0117     }
0118 
0119     tblk = tid_to_tblock(tid);
0120     tblk->xflag |= COMMIT_CREATE;
0121     tblk->ino = ip->i_ino;
0122     tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
0123 
0124     iplist[0] = dip;
0125     iplist[1] = ip;
0126 
0127     /*
0128      * initialize the child XAD tree root in-line in inode
0129      */
0130     xtInitRoot(tid, ip);
0131 
0132     /*
0133      * create entry in parent directory for child directory
0134      * (dtInsert() releases parent directory page)
0135      */
0136     ino = ip->i_ino;
0137     if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
0138         if (rc == -EIO) {
0139             jfs_err("jfs_create: dtInsert returned -EIO");
0140             txAbort(tid, 1);    /* Marks Filesystem dirty */
0141         } else
0142             txAbort(tid, 0);    /* Filesystem full */
0143         goto out3;
0144     }
0145 
0146     ip->i_op = &jfs_file_inode_operations;
0147     ip->i_fop = &jfs_file_operations;
0148     ip->i_mapping->a_ops = &jfs_aops;
0149 
0150     mark_inode_dirty(ip);
0151 
0152     dip->i_ctime = dip->i_mtime = current_time(dip);
0153 
0154     mark_inode_dirty(dip);
0155 
0156     rc = txCommit(tid, 2, &iplist[0], 0);
0157 
0158       out3:
0159     txEnd(tid);
0160     mutex_unlock(&JFS_IP(ip)->commit_mutex);
0161     mutex_unlock(&JFS_IP(dip)->commit_mutex);
0162     if (rc) {
0163         free_ea_wmap(ip);
0164         clear_nlink(ip);
0165         discard_new_inode(ip);
0166     } else {
0167         d_instantiate_new(dentry, ip);
0168     }
0169 
0170       out2:
0171     free_UCSname(&dname);
0172 
0173       out1:
0174 
0175     jfs_info("jfs_create: rc:%d", rc);
0176     return rc;
0177 }
0178 
0179 
0180 /*
0181  * NAME:    jfs_mkdir(dip, dentry, mode)
0182  *
0183  * FUNCTION:    create a child directory in the parent directory <dip>
0184  *      with name = <from dentry> and mode = <mode>
0185  *
0186  * PARAMETER:   dip - parent directory vnode
0187  *      dentry  - dentry of child directory
0188  *      mode    - create mode (rwxrwxrwx).
0189  *
0190  * RETURN:  Errors from subroutines
0191  *
0192  * note:
0193  * EACCES: user needs search+write permission on the parent directory
0194  */
0195 static int jfs_mkdir(struct user_namespace *mnt_userns, struct inode *dip,
0196              struct dentry *dentry, umode_t mode)
0197 {
0198     int rc = 0;
0199     tid_t tid;      /* transaction id */
0200     struct inode *ip = NULL;    /* child directory inode */
0201     ino_t ino;
0202     struct component_name dname;    /* child directory name */
0203     struct btstack btstack;
0204     struct inode *iplist[2];
0205     struct tblock *tblk;
0206 
0207     jfs_info("jfs_mkdir: dip:0x%p name:%pd", dip, dentry);
0208 
0209     rc = dquot_initialize(dip);
0210     if (rc)
0211         goto out1;
0212 
0213     /*
0214      * search parent directory for entry/freespace
0215      * (dtSearch() returns parent directory page pinned)
0216      */
0217     if ((rc = get_UCSname(&dname, dentry)))
0218         goto out1;
0219 
0220     /*
0221      * Either iAlloc() or txBegin() may block.  Deadlock can occur if we
0222      * block there while holding dtree page, so we allocate the inode &
0223      * begin the transaction before we search the directory.
0224      */
0225     ip = ialloc(dip, S_IFDIR | mode);
0226     if (IS_ERR(ip)) {
0227         rc = PTR_ERR(ip);
0228         goto out2;
0229     }
0230 
0231     tid = txBegin(dip->i_sb, 0);
0232 
0233     mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
0234     mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
0235 
0236     rc = jfs_init_acl(tid, ip, dip);
0237     if (rc)
0238         goto out3;
0239 
0240     rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
0241     if (rc) {
0242         txAbort(tid, 0);
0243         goto out3;
0244     }
0245 
0246     if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
0247         jfs_err("jfs_mkdir: dtSearch returned %d", rc);
0248         txAbort(tid, 0);
0249         goto out3;
0250     }
0251 
0252     tblk = tid_to_tblock(tid);
0253     tblk->xflag |= COMMIT_CREATE;
0254     tblk->ino = ip->i_ino;
0255     tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
0256 
0257     iplist[0] = dip;
0258     iplist[1] = ip;
0259 
0260     /*
0261      * initialize the child directory in-line in inode
0262      */
0263     dtInitRoot(tid, ip, dip->i_ino);
0264 
0265     /*
0266      * create entry in parent directory for child directory
0267      * (dtInsert() releases parent directory page)
0268      */
0269     ino = ip->i_ino;
0270     if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
0271         if (rc == -EIO) {
0272             jfs_err("jfs_mkdir: dtInsert returned -EIO");
0273             txAbort(tid, 1);    /* Marks Filesystem dirty */
0274         } else
0275             txAbort(tid, 0);    /* Filesystem full */
0276         goto out3;
0277     }
0278 
0279     set_nlink(ip, 2);   /* for '.' */
0280     ip->i_op = &jfs_dir_inode_operations;
0281     ip->i_fop = &jfs_dir_operations;
0282 
0283     mark_inode_dirty(ip);
0284 
0285     /* update parent directory inode */
0286     inc_nlink(dip);     /* for '..' from child directory */
0287     dip->i_ctime = dip->i_mtime = current_time(dip);
0288     mark_inode_dirty(dip);
0289 
0290     rc = txCommit(tid, 2, &iplist[0], 0);
0291 
0292       out3:
0293     txEnd(tid);
0294     mutex_unlock(&JFS_IP(ip)->commit_mutex);
0295     mutex_unlock(&JFS_IP(dip)->commit_mutex);
0296     if (rc) {
0297         free_ea_wmap(ip);
0298         clear_nlink(ip);
0299         discard_new_inode(ip);
0300     } else {
0301         d_instantiate_new(dentry, ip);
0302     }
0303 
0304       out2:
0305     free_UCSname(&dname);
0306 
0307 
0308       out1:
0309 
0310     jfs_info("jfs_mkdir: rc:%d", rc);
0311     return rc;
0312 }
0313 
0314 /*
0315  * NAME:    jfs_rmdir(dip, dentry)
0316  *
0317  * FUNCTION:    remove a link to child directory
0318  *
0319  * PARAMETER:   dip - parent inode
0320  *      dentry  - child directory dentry
0321  *
0322  * RETURN:  -EINVAL - if name is . or ..
0323  *      -EINVAL - if . or .. exist but are invalid.
0324  *      errors from subroutines
0325  *
0326  * note:
0327  * if other threads have the directory open when the last link
0328  * is removed, the "." and ".." entries, if present, are removed before
0329  * rmdir() returns and no new entries may be created in the directory,
0330  * but the directory is not removed until the last reference to
0331  * the directory is released (cf.unlink() of regular file).
0332  */
0333 static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
0334 {
0335     int rc;
0336     tid_t tid;      /* transaction id */
0337     struct inode *ip = d_inode(dentry);
0338     ino_t ino;
0339     struct component_name dname;
0340     struct inode *iplist[2];
0341     struct tblock *tblk;
0342 
0343     jfs_info("jfs_rmdir: dip:0x%p name:%pd", dip, dentry);
0344 
0345     /* Init inode for quota operations. */
0346     rc = dquot_initialize(dip);
0347     if (rc)
0348         goto out;
0349     rc = dquot_initialize(ip);
0350     if (rc)
0351         goto out;
0352 
0353     /* directory must be empty to be removed */
0354     if (!dtEmpty(ip)) {
0355         rc = -ENOTEMPTY;
0356         goto out;
0357     }
0358 
0359     if ((rc = get_UCSname(&dname, dentry))) {
0360         goto out;
0361     }
0362 
0363     tid = txBegin(dip->i_sb, 0);
0364 
0365     mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
0366     mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
0367 
0368     iplist[0] = dip;
0369     iplist[1] = ip;
0370 
0371     tblk = tid_to_tblock(tid);
0372     tblk->xflag |= COMMIT_DELETE;
0373     tblk->u.ip = ip;
0374 
0375     /*
0376      * delete the entry of target directory from parent directory
0377      */
0378     ino = ip->i_ino;
0379     if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) {
0380         jfs_err("jfs_rmdir: dtDelete returned %d", rc);
0381         if (rc == -EIO)
0382             txAbort(tid, 1);
0383         txEnd(tid);
0384         mutex_unlock(&JFS_IP(ip)->commit_mutex);
0385         mutex_unlock(&JFS_IP(dip)->commit_mutex);
0386 
0387         goto out2;
0388     }
0389 
0390     /* update parent directory's link count corresponding
0391      * to ".." entry of the target directory deleted
0392      */
0393     dip->i_ctime = dip->i_mtime = current_time(dip);
0394     inode_dec_link_count(dip);
0395 
0396     /*
0397      * OS/2 could have created EA and/or ACL
0398      */
0399     /* free EA from both persistent and working map */
0400     if (JFS_IP(ip)->ea.flag & DXD_EXTENT) {
0401         /* free EA pages */
0402         txEA(tid, ip, &JFS_IP(ip)->ea, NULL);
0403     }
0404     JFS_IP(ip)->ea.flag = 0;
0405 
0406     /* free ACL from both persistent and working map */
0407     if (JFS_IP(ip)->acl.flag & DXD_EXTENT) {
0408         /* free ACL pages */
0409         txEA(tid, ip, &JFS_IP(ip)->acl, NULL);
0410     }
0411     JFS_IP(ip)->acl.flag = 0;
0412 
0413     /* mark the target directory as deleted */
0414     clear_nlink(ip);
0415     mark_inode_dirty(ip);
0416 
0417     rc = txCommit(tid, 2, &iplist[0], 0);
0418 
0419     txEnd(tid);
0420 
0421     mutex_unlock(&JFS_IP(ip)->commit_mutex);
0422     mutex_unlock(&JFS_IP(dip)->commit_mutex);
0423 
0424     /*
0425      * Truncating the directory index table is not guaranteed.  It
0426      * may need to be done iteratively
0427      */
0428     if (test_cflag(COMMIT_Stale, dip)) {
0429         if (dip->i_size > 1)
0430             jfs_truncate_nolock(dip, 0);
0431 
0432         clear_cflag(COMMIT_Stale, dip);
0433     }
0434 
0435       out2:
0436     free_UCSname(&dname);
0437 
0438       out:
0439     jfs_info("jfs_rmdir: rc:%d", rc);
0440     return rc;
0441 }
0442 
0443 /*
0444  * NAME:    jfs_unlink(dip, dentry)
0445  *
0446  * FUNCTION:    remove a link to object <vp> named by <name>
0447  *      from parent directory <dvp>
0448  *
0449  * PARAMETER:   dip - inode of parent directory
0450  *      dentry  - dentry of object to be removed
0451  *
0452  * RETURN:  errors from subroutines
0453  *
0454  * note:
0455  * temporary file: if one or more processes have the file open
0456  * when the last link is removed, the link will be removed before
0457  * unlink() returns, but the removal of the file contents will be
0458  * postponed until all references to the files are closed.
0459  *
0460  * JFS does NOT support unlink() on directories.
0461  *
0462  */
0463 static int jfs_unlink(struct inode *dip, struct dentry *dentry)
0464 {
0465     int rc;
0466     tid_t tid;      /* transaction id */
0467     struct inode *ip = d_inode(dentry);
0468     ino_t ino;
0469     struct component_name dname;    /* object name */
0470     struct inode *iplist[2];
0471     struct tblock *tblk;
0472     s64 new_size = 0;
0473     int commit_flag;
0474 
0475     jfs_info("jfs_unlink: dip:0x%p name:%pd", dip, dentry);
0476 
0477     /* Init inode for quota operations. */
0478     rc = dquot_initialize(dip);
0479     if (rc)
0480         goto out;
0481     rc = dquot_initialize(ip);
0482     if (rc)
0483         goto out;
0484 
0485     if ((rc = get_UCSname(&dname, dentry)))
0486         goto out;
0487 
0488     IWRITE_LOCK(ip, RDWRLOCK_NORMAL);
0489 
0490     tid = txBegin(dip->i_sb, 0);
0491 
0492     mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
0493     mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
0494 
0495     iplist[0] = dip;
0496     iplist[1] = ip;
0497 
0498     /*
0499      * delete the entry of target file from parent directory
0500      */
0501     ino = ip->i_ino;
0502     if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) {
0503         jfs_err("jfs_unlink: dtDelete returned %d", rc);
0504         if (rc == -EIO)
0505             txAbort(tid, 1);    /* Marks FS Dirty */
0506         txEnd(tid);
0507         mutex_unlock(&JFS_IP(ip)->commit_mutex);
0508         mutex_unlock(&JFS_IP(dip)->commit_mutex);
0509         IWRITE_UNLOCK(ip);
0510         goto out1;
0511     }
0512 
0513     ASSERT(ip->i_nlink);
0514 
0515     ip->i_ctime = dip->i_ctime = dip->i_mtime = current_time(ip);
0516     mark_inode_dirty(dip);
0517 
0518     /* update target's inode */
0519     inode_dec_link_count(ip);
0520 
0521     /*
0522      *  commit zero link count object
0523      */
0524     if (ip->i_nlink == 0) {
0525         assert(!test_cflag(COMMIT_Nolink, ip));
0526         /* free block resources */
0527         if ((new_size = commitZeroLink(tid, ip)) < 0) {
0528             txAbort(tid, 1);    /* Marks FS Dirty */
0529             txEnd(tid);
0530             mutex_unlock(&JFS_IP(ip)->commit_mutex);
0531             mutex_unlock(&JFS_IP(dip)->commit_mutex);
0532             IWRITE_UNLOCK(ip);
0533             rc = new_size;
0534             goto out1;
0535         }
0536         tblk = tid_to_tblock(tid);
0537         tblk->xflag |= COMMIT_DELETE;
0538         tblk->u.ip = ip;
0539     }
0540 
0541     /*
0542      * Incomplete truncate of file data can
0543      * result in timing problems unless we synchronously commit the
0544      * transaction.
0545      */
0546     if (new_size)
0547         commit_flag = COMMIT_SYNC;
0548     else
0549         commit_flag = 0;
0550 
0551     /*
0552      * If xtTruncate was incomplete, commit synchronously to avoid
0553      * timing complications
0554      */
0555     rc = txCommit(tid, 2, &iplist[0], commit_flag);
0556 
0557     txEnd(tid);
0558 
0559     mutex_unlock(&JFS_IP(ip)->commit_mutex);
0560     mutex_unlock(&JFS_IP(dip)->commit_mutex);
0561 
0562     while (new_size && (rc == 0)) {
0563         tid = txBegin(dip->i_sb, 0);
0564         mutex_lock(&JFS_IP(ip)->commit_mutex);
0565         new_size = xtTruncate_pmap(tid, ip, new_size);
0566         if (new_size < 0) {
0567             txAbort(tid, 1);    /* Marks FS Dirty */
0568             rc = new_size;
0569         } else
0570             rc = txCommit(tid, 2, &iplist[0], COMMIT_SYNC);
0571         txEnd(tid);
0572         mutex_unlock(&JFS_IP(ip)->commit_mutex);
0573     }
0574 
0575     if (ip->i_nlink == 0)
0576         set_cflag(COMMIT_Nolink, ip);
0577 
0578     IWRITE_UNLOCK(ip);
0579 
0580     /*
0581      * Truncating the directory index table is not guaranteed.  It
0582      * may need to be done iteratively
0583      */
0584     if (test_cflag(COMMIT_Stale, dip)) {
0585         if (dip->i_size > 1)
0586             jfs_truncate_nolock(dip, 0);
0587 
0588         clear_cflag(COMMIT_Stale, dip);
0589     }
0590 
0591       out1:
0592     free_UCSname(&dname);
0593       out:
0594     jfs_info("jfs_unlink: rc:%d", rc);
0595     return rc;
0596 }
0597 
0598 /*
0599  * NAME:    commitZeroLink()
0600  *
0601  * FUNCTION:    for non-directory, called by jfs_remove(),
0602  *      truncate a regular file, directory or symbolic
0603  *      link to zero length. return 0 if type is not
0604  *      one of these.
0605  *
0606  *      if the file is currently associated with a VM segment
0607  *      only permanent disk and inode map resources are freed,
0608  *      and neither the inode nor indirect blocks are modified
0609  *      so that the resources can be later freed in the work
0610  *      map by ctrunc1.
0611  *      if there is no VM segment on entry, the resources are
0612  *      freed in both work and permanent map.
0613  *      (? for temporary file - memory object is cached even
0614  *      after no reference:
0615  *      reference count > 0 -   )
0616  *
0617  * PARAMETERS:  cd  - pointer to commit data structure.
0618  *            current inode is the one to truncate.
0619  *
0620  * RETURN:  Errors from subroutines
0621  */
0622 static s64 commitZeroLink(tid_t tid, struct inode *ip)
0623 {
0624     int filetype;
0625     struct tblock *tblk;
0626 
0627     jfs_info("commitZeroLink: tid = %d, ip = 0x%p", tid, ip);
0628 
0629     filetype = ip->i_mode & S_IFMT;
0630     switch (filetype) {
0631     case S_IFREG:
0632         break;
0633     case S_IFLNK:
0634         /* fast symbolic link */
0635         if (ip->i_size < IDATASIZE) {
0636             ip->i_size = 0;
0637             return 0;
0638         }
0639         break;
0640     default:
0641         assert(filetype != S_IFDIR);
0642         return 0;
0643     }
0644 
0645     set_cflag(COMMIT_Freewmap, ip);
0646 
0647     /* mark transaction of block map update type */
0648     tblk = tid_to_tblock(tid);
0649     tblk->xflag |= COMMIT_PMAP;
0650 
0651     /*
0652      * free EA
0653      */
0654     if (JFS_IP(ip)->ea.flag & DXD_EXTENT)
0655         /* acquire maplock on EA to be freed from block map */
0656         txEA(tid, ip, &JFS_IP(ip)->ea, NULL);
0657 
0658     /*
0659      * free ACL
0660      */
0661     if (JFS_IP(ip)->acl.flag & DXD_EXTENT)
0662         /* acquire maplock on EA to be freed from block map */
0663         txEA(tid, ip, &JFS_IP(ip)->acl, NULL);
0664 
0665     /*
0666      * free xtree/data (truncate to zero length):
0667      * free xtree/data pages from cache if COMMIT_PWMAP,
0668      * free xtree/data blocks from persistent block map, and
0669      * free xtree/data blocks from working block map if COMMIT_PWMAP;
0670      */
0671     if (ip->i_size)
0672         return xtTruncate_pmap(tid, ip, 0);
0673 
0674     return 0;
0675 }
0676 
0677 
0678 /*
0679  * NAME:    jfs_free_zero_link()
0680  *
0681  * FUNCTION:    for non-directory, called by iClose(),
0682  *      free resources of a file from cache and WORKING map
0683  *      for a file previously committed with zero link count
0684  *      while associated with a pager object,
0685  *
0686  * PARAMETER:   ip  - pointer to inode of file.
0687  */
0688 void jfs_free_zero_link(struct inode *ip)
0689 {
0690     int type;
0691 
0692     jfs_info("jfs_free_zero_link: ip = 0x%p", ip);
0693 
0694     /* return if not reg or symbolic link or if size is
0695      * already ok.
0696      */
0697     type = ip->i_mode & S_IFMT;
0698 
0699     switch (type) {
0700     case S_IFREG:
0701         break;
0702     case S_IFLNK:
0703         /* if its contained in inode nothing to do */
0704         if (ip->i_size < IDATASIZE)
0705             return;
0706         break;
0707     default:
0708         return;
0709     }
0710 
0711     /*
0712      * free EA
0713      */
0714     if (JFS_IP(ip)->ea.flag & DXD_EXTENT) {
0715         s64 xaddr = addressDXD(&JFS_IP(ip)->ea);
0716         int xlen = lengthDXD(&JFS_IP(ip)->ea);
0717         struct maplock maplock; /* maplock for COMMIT_WMAP */
0718         struct pxd_lock *pxdlock;   /* maplock for COMMIT_WMAP */
0719 
0720         /* free EA pages from cache */
0721         invalidate_dxd_metapages(ip, JFS_IP(ip)->ea);
0722 
0723         /* free EA extent from working block map */
0724         maplock.index = 1;
0725         pxdlock = (struct pxd_lock *) & maplock;
0726         pxdlock->flag = mlckFREEPXD;
0727         PXDaddress(&pxdlock->pxd, xaddr);
0728         PXDlength(&pxdlock->pxd, xlen);
0729         txFreeMap(ip, pxdlock, NULL, COMMIT_WMAP);
0730     }
0731 
0732     /*
0733      * free ACL
0734      */
0735     if (JFS_IP(ip)->acl.flag & DXD_EXTENT) {
0736         s64 xaddr = addressDXD(&JFS_IP(ip)->acl);
0737         int xlen = lengthDXD(&JFS_IP(ip)->acl);
0738         struct maplock maplock; /* maplock for COMMIT_WMAP */
0739         struct pxd_lock *pxdlock;   /* maplock for COMMIT_WMAP */
0740 
0741         invalidate_dxd_metapages(ip, JFS_IP(ip)->acl);
0742 
0743         /* free ACL extent from working block map */
0744         maplock.index = 1;
0745         pxdlock = (struct pxd_lock *) & maplock;
0746         pxdlock->flag = mlckFREEPXD;
0747         PXDaddress(&pxdlock->pxd, xaddr);
0748         PXDlength(&pxdlock->pxd, xlen);
0749         txFreeMap(ip, pxdlock, NULL, COMMIT_WMAP);
0750     }
0751 
0752     /*
0753      * free xtree/data (truncate to zero length):
0754      * free xtree/data pages from cache, and
0755      * free xtree/data blocks from working block map;
0756      */
0757     if (ip->i_size)
0758         xtTruncate(0, ip, 0, COMMIT_WMAP);
0759 }
0760 
0761 /*
0762  * NAME:    jfs_link(vp, dvp, name, crp)
0763  *
0764  * FUNCTION:    create a link to <vp> by the name = <name>
0765  *      in the parent directory <dvp>
0766  *
0767  * PARAMETER:   vp  - target object
0768  *      dvp - parent directory of new link
0769  *      name    - name of new link to target object
0770  *      crp - credential
0771  *
0772  * RETURN:  Errors from subroutines
0773  *
0774  * note:
0775  * JFS does NOT support link() on directories (to prevent circular
0776  * path in the directory hierarchy);
0777  * EPERM: the target object is a directory, and either the caller
0778  * does not have appropriate privileges or the implementation prohibits
0779  * using link() on directories [XPG4.2].
0780  *
0781  * JFS does NOT support links between file systems:
0782  * EXDEV: target object and new link are on different file systems and
0783  * implementation does not support links between file systems [XPG4.2].
0784  */
0785 static int jfs_link(struct dentry *old_dentry,
0786          struct inode *dir, struct dentry *dentry)
0787 {
0788     int rc;
0789     tid_t tid;
0790     struct inode *ip = d_inode(old_dentry);
0791     ino_t ino;
0792     struct component_name dname;
0793     struct btstack btstack;
0794     struct inode *iplist[2];
0795 
0796     jfs_info("jfs_link: %pd %pd", old_dentry, dentry);
0797 
0798     rc = dquot_initialize(dir);
0799     if (rc)
0800         goto out;
0801 
0802     tid = txBegin(ip->i_sb, 0);
0803 
0804     mutex_lock_nested(&JFS_IP(dir)->commit_mutex, COMMIT_MUTEX_PARENT);
0805     mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
0806 
0807     /*
0808      * scan parent directory for entry/freespace
0809      */
0810     if ((rc = get_UCSname(&dname, dentry)))
0811         goto out_tx;
0812 
0813     if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE)))
0814         goto free_dname;
0815 
0816     /*
0817      * create entry for new link in parent directory
0818      */
0819     ino = ip->i_ino;
0820     if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack)))
0821         goto free_dname;
0822 
0823     /* update object inode */
0824     inc_nlink(ip);      /* for new link */
0825     ip->i_ctime = current_time(ip);
0826     dir->i_ctime = dir->i_mtime = current_time(dir);
0827     mark_inode_dirty(dir);
0828     ihold(ip);
0829 
0830     iplist[0] = ip;
0831     iplist[1] = dir;
0832     rc = txCommit(tid, 2, &iplist[0], 0);
0833 
0834     if (rc) {
0835         drop_nlink(ip); /* never instantiated */
0836         iput(ip);
0837     } else
0838         d_instantiate(dentry, ip);
0839 
0840       free_dname:
0841     free_UCSname(&dname);
0842 
0843       out_tx:
0844     txEnd(tid);
0845 
0846     mutex_unlock(&JFS_IP(ip)->commit_mutex);
0847     mutex_unlock(&JFS_IP(dir)->commit_mutex);
0848 
0849       out:
0850     jfs_info("jfs_link: rc:%d", rc);
0851     return rc;
0852 }
0853 
0854 /*
0855  * NAME:    jfs_symlink(dip, dentry, name)
0856  *
0857  * FUNCTION:    creates a symbolic link to <symlink> by name <name>
0858  *          in directory <dip>
0859  *
0860  * PARAMETER:   dip - parent directory vnode
0861  *      dentry  - dentry of symbolic link
0862  *      name    - the path name of the existing object
0863  *            that will be the source of the link
0864  *
0865  * RETURN:  errors from subroutines
0866  *
0867  * note:
0868  * ENAMETOOLONG: pathname resolution of a symbolic link produced
0869  * an intermediate result whose length exceeds PATH_MAX [XPG4.2]
0870 */
0871 
0872 static int jfs_symlink(struct user_namespace *mnt_userns, struct inode *dip,
0873                struct dentry *dentry, const char *name)
0874 {
0875     int rc;
0876     tid_t tid;
0877     ino_t ino = 0;
0878     struct component_name dname;
0879     int ssize;      /* source pathname size */
0880     struct btstack btstack;
0881     struct inode *ip = d_inode(dentry);
0882     s64 xlen = 0;
0883     int bmask = 0, xsize;
0884     s64 xaddr;
0885     struct metapage *mp;
0886     struct super_block *sb;
0887     struct tblock *tblk;
0888 
0889     struct inode *iplist[2];
0890 
0891     jfs_info("jfs_symlink: dip:0x%p name:%s", dip, name);
0892 
0893     rc = dquot_initialize(dip);
0894     if (rc)
0895         goto out1;
0896 
0897     ssize = strlen(name) + 1;
0898 
0899     /*
0900      * search parent directory for entry/freespace
0901      * (dtSearch() returns parent directory page pinned)
0902      */
0903 
0904     if ((rc = get_UCSname(&dname, dentry)))
0905         goto out1;
0906 
0907     /*
0908      * allocate on-disk/in-memory inode for symbolic link:
0909      * (iAlloc() returns new, locked inode)
0910      */
0911     ip = ialloc(dip, S_IFLNK | 0777);
0912     if (IS_ERR(ip)) {
0913         rc = PTR_ERR(ip);
0914         goto out2;
0915     }
0916 
0917     tid = txBegin(dip->i_sb, 0);
0918 
0919     mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
0920     mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
0921 
0922     rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
0923     if (rc)
0924         goto out3;
0925 
0926     tblk = tid_to_tblock(tid);
0927     tblk->xflag |= COMMIT_CREATE;
0928     tblk->ino = ip->i_ino;
0929     tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
0930 
0931     /* fix symlink access permission
0932      * (dir_create() ANDs in the u.u_cmask,
0933      * but symlinks really need to be 777 access)
0934      */
0935     ip->i_mode |= 0777;
0936 
0937     /*
0938      * write symbolic link target path name
0939      */
0940     xtInitRoot(tid, ip);
0941 
0942     /*
0943      * write source path name inline in on-disk inode (fast symbolic link)
0944      */
0945 
0946     if (ssize <= IDATASIZE) {
0947         ip->i_op = &jfs_fast_symlink_inode_operations;
0948 
0949         ip->i_link = JFS_IP(ip)->i_inline;
0950         memcpy(ip->i_link, name, ssize);
0951         ip->i_size = ssize - 1;
0952 
0953         /*
0954          * if symlink is > 128 bytes, we don't have the space to
0955          * store inline extended attributes
0956          */
0957         if (ssize > sizeof (JFS_IP(ip)->i_inline))
0958             JFS_IP(ip)->mode2 &= ~INLINEEA;
0959 
0960         jfs_info("jfs_symlink: fast symlink added  ssize:%d name:%s ",
0961              ssize, name);
0962     }
0963     /*
0964      * write source path name in a single extent
0965      */
0966     else {
0967         jfs_info("jfs_symlink: allocate extent ip:0x%p", ip);
0968 
0969         ip->i_op = &jfs_symlink_inode_operations;
0970         inode_nohighmem(ip);
0971         ip->i_mapping->a_ops = &jfs_aops;
0972 
0973         /*
0974          * even though the data of symlink object (source
0975          * path name) is treated as non-journaled user data,
0976          * it is read/written thru buffer cache for performance.
0977          */
0978         sb = ip->i_sb;
0979         bmask = JFS_SBI(sb)->bsize - 1;
0980         xsize = (ssize + bmask) & ~bmask;
0981         xaddr = 0;
0982         xlen = xsize >> JFS_SBI(sb)->l2bsize;
0983         if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0))) {
0984             txAbort(tid, 0);
0985             goto out3;
0986         }
0987         ip->i_size = ssize - 1;
0988         while (ssize) {
0989             /* This is kind of silly since PATH_MAX == 4K */
0990             int copy_size = min(ssize, PSIZE);
0991 
0992             mp = get_metapage(ip, xaddr, PSIZE, 1);
0993 
0994             if (mp == NULL) {
0995                 xtTruncate(tid, ip, 0, COMMIT_PWMAP);
0996                 rc = -EIO;
0997                 txAbort(tid, 0);
0998                 goto out3;
0999             }
1000             memcpy(mp->data, name, copy_size);
1001             flush_metapage(mp);
1002             ssize -= copy_size;
1003             name += copy_size;
1004             xaddr += JFS_SBI(sb)->nbperpage;
1005         }
1006     }
1007 
1008     /*
1009      * create entry for symbolic link in parent directory
1010      */
1011     rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE);
1012     if (rc == 0) {
1013         ino = ip->i_ino;
1014         rc = dtInsert(tid, dip, &dname, &ino, &btstack);
1015     }
1016     if (rc) {
1017         if (xlen)
1018             xtTruncate(tid, ip, 0, COMMIT_PWMAP);
1019         txAbort(tid, 0);
1020         /* discard new inode */
1021         goto out3;
1022     }
1023 
1024     mark_inode_dirty(ip);
1025 
1026     dip->i_ctime = dip->i_mtime = current_time(dip);
1027     mark_inode_dirty(dip);
1028     /*
1029      * commit update of parent directory and link object
1030      */
1031 
1032     iplist[0] = dip;
1033     iplist[1] = ip;
1034     rc = txCommit(tid, 2, &iplist[0], 0);
1035 
1036       out3:
1037     txEnd(tid);
1038     mutex_unlock(&JFS_IP(ip)->commit_mutex);
1039     mutex_unlock(&JFS_IP(dip)->commit_mutex);
1040     if (rc) {
1041         free_ea_wmap(ip);
1042         clear_nlink(ip);
1043         discard_new_inode(ip);
1044     } else {
1045         d_instantiate_new(dentry, ip);
1046     }
1047 
1048       out2:
1049     free_UCSname(&dname);
1050 
1051       out1:
1052     jfs_info("jfs_symlink: rc:%d", rc);
1053     return rc;
1054 }
1055 
1056 
1057 /*
1058  * NAME:    jfs_rename
1059  *
1060  * FUNCTION:    rename a file or directory
1061  */
1062 static int jfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
1063               struct dentry *old_dentry, struct inode *new_dir,
1064               struct dentry *new_dentry, unsigned int flags)
1065 {
1066     struct btstack btstack;
1067     ino_t ino;
1068     struct component_name new_dname;
1069     struct inode *new_ip;
1070     struct component_name old_dname;
1071     struct inode *old_ip;
1072     int rc;
1073     tid_t tid;
1074     struct tlock *tlck;
1075     struct dt_lock *dtlck;
1076     struct lv *lv;
1077     int ipcount;
1078     struct inode *iplist[4];
1079     struct tblock *tblk;
1080     s64 new_size = 0;
1081     int commit_flag;
1082 
1083     if (flags & ~RENAME_NOREPLACE)
1084         return -EINVAL;
1085 
1086     jfs_info("jfs_rename: %pd %pd", old_dentry, new_dentry);
1087 
1088     rc = dquot_initialize(old_dir);
1089     if (rc)
1090         goto out1;
1091     rc = dquot_initialize(new_dir);
1092     if (rc)
1093         goto out1;
1094 
1095     old_ip = d_inode(old_dentry);
1096     new_ip = d_inode(new_dentry);
1097 
1098     if ((rc = get_UCSname(&old_dname, old_dentry)))
1099         goto out1;
1100 
1101     if ((rc = get_UCSname(&new_dname, new_dentry)))
1102         goto out2;
1103 
1104     /*
1105      * Make sure source inode number is what we think it is
1106      */
1107     rc = dtSearch(old_dir, &old_dname, &ino, &btstack, JFS_LOOKUP);
1108     if (rc || (ino != old_ip->i_ino)) {
1109         rc = -ENOENT;
1110         goto out3;
1111     }
1112 
1113     /*
1114      * Make sure dest inode number (if any) is what we think it is
1115      */
1116     rc = dtSearch(new_dir, &new_dname, &ino, &btstack, JFS_LOOKUP);
1117     if (!rc) {
1118         if ((!new_ip) || (ino != new_ip->i_ino)) {
1119             rc = -ESTALE;
1120             goto out3;
1121         }
1122     } else if (rc != -ENOENT)
1123         goto out3;
1124     else if (new_ip) {
1125         /* no entry exists, but one was expected */
1126         rc = -ESTALE;
1127         goto out3;
1128     }
1129 
1130     if (S_ISDIR(old_ip->i_mode)) {
1131         if (new_ip) {
1132             if (!dtEmpty(new_ip)) {
1133                 rc = -ENOTEMPTY;
1134                 goto out3;
1135             }
1136         }
1137     } else if (new_ip) {
1138         IWRITE_LOCK(new_ip, RDWRLOCK_NORMAL);
1139         /* Init inode for quota operations. */
1140         rc = dquot_initialize(new_ip);
1141         if (rc)
1142             goto out_unlock;
1143     }
1144 
1145     /*
1146      * The real work starts here
1147      */
1148     tid = txBegin(new_dir->i_sb, 0);
1149 
1150     /*
1151      * How do we know the locking is safe from deadlocks?
1152      * The vfs does the hard part for us.  Any time we are taking nested
1153      * commit_mutexes, the vfs already has i_mutex held on the parent.
1154      * Here, the vfs has already taken i_mutex on both old_dir and new_dir.
1155      */
1156     mutex_lock_nested(&JFS_IP(new_dir)->commit_mutex, COMMIT_MUTEX_PARENT);
1157     mutex_lock_nested(&JFS_IP(old_ip)->commit_mutex, COMMIT_MUTEX_CHILD);
1158     if (old_dir != new_dir)
1159         mutex_lock_nested(&JFS_IP(old_dir)->commit_mutex,
1160                   COMMIT_MUTEX_SECOND_PARENT);
1161 
1162     if (new_ip) {
1163         mutex_lock_nested(&JFS_IP(new_ip)->commit_mutex,
1164                   COMMIT_MUTEX_VICTIM);
1165         /*
1166          * Change existing directory entry to new inode number
1167          */
1168         ino = new_ip->i_ino;
1169         rc = dtModify(tid, new_dir, &new_dname, &ino,
1170                   old_ip->i_ino, JFS_RENAME);
1171         if (rc)
1172             goto out_tx;
1173         drop_nlink(new_ip);
1174         if (S_ISDIR(new_ip->i_mode)) {
1175             drop_nlink(new_ip);
1176             if (new_ip->i_nlink) {
1177                 mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
1178                 if (old_dir != new_dir)
1179                     mutex_unlock(&JFS_IP(old_dir)->commit_mutex);
1180                 mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
1181                 mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
1182                 if (!S_ISDIR(old_ip->i_mode) && new_ip)
1183                     IWRITE_UNLOCK(new_ip);
1184                 jfs_error(new_ip->i_sb,
1185                       "new_ip->i_nlink != 0\n");
1186                 return -EIO;
1187             }
1188             tblk = tid_to_tblock(tid);
1189             tblk->xflag |= COMMIT_DELETE;
1190             tblk->u.ip = new_ip;
1191         } else if (new_ip->i_nlink == 0) {
1192             assert(!test_cflag(COMMIT_Nolink, new_ip));
1193             /* free block resources */
1194             if ((new_size = commitZeroLink(tid, new_ip)) < 0) {
1195                 txAbort(tid, 1);    /* Marks FS Dirty */
1196                 rc = new_size;
1197                 goto out_tx;
1198             }
1199             tblk = tid_to_tblock(tid);
1200             tblk->xflag |= COMMIT_DELETE;
1201             tblk->u.ip = new_ip;
1202         } else {
1203             new_ip->i_ctime = current_time(new_ip);
1204             mark_inode_dirty(new_ip);
1205         }
1206     } else {
1207         /*
1208          * Add new directory entry
1209          */
1210         rc = dtSearch(new_dir, &new_dname, &ino, &btstack,
1211                   JFS_CREATE);
1212         if (rc) {
1213             jfs_err("jfs_rename didn't expect dtSearch to fail w/rc = %d",
1214                 rc);
1215             goto out_tx;
1216         }
1217 
1218         ino = old_ip->i_ino;
1219         rc = dtInsert(tid, new_dir, &new_dname, &ino, &btstack);
1220         if (rc) {
1221             if (rc == -EIO)
1222                 jfs_err("jfs_rename: dtInsert returned -EIO");
1223             goto out_tx;
1224         }
1225         if (S_ISDIR(old_ip->i_mode))
1226             inc_nlink(new_dir);
1227     }
1228     /*
1229      * Remove old directory entry
1230      */
1231 
1232     ino = old_ip->i_ino;
1233     rc = dtDelete(tid, old_dir, &old_dname, &ino, JFS_REMOVE);
1234     if (rc) {
1235         jfs_err("jfs_rename did not expect dtDelete to return rc = %d",
1236             rc);
1237         txAbort(tid, 1);    /* Marks Filesystem dirty */
1238         goto out_tx;
1239     }
1240     if (S_ISDIR(old_ip->i_mode)) {
1241         drop_nlink(old_dir);
1242         if (old_dir != new_dir) {
1243             /*
1244              * Change inode number of parent for moved directory
1245              */
1246 
1247             JFS_IP(old_ip)->i_dtroot.header.idotdot =
1248                 cpu_to_le32(new_dir->i_ino);
1249 
1250             /* Linelock header of dtree */
1251             tlck = txLock(tid, old_ip,
1252                     (struct metapage *) &JFS_IP(old_ip)->bxflag,
1253                       tlckDTREE | tlckBTROOT | tlckRELINK);
1254             dtlck = (struct dt_lock *) & tlck->lock;
1255             ASSERT(dtlck->index == 0);
1256             lv = & dtlck->lv[0];
1257             lv->offset = 0;
1258             lv->length = 1;
1259             dtlck->index++;
1260         }
1261     }
1262 
1263     /*
1264      * Update ctime on changed/moved inodes & mark dirty
1265      */
1266     old_ip->i_ctime = current_time(old_ip);
1267     mark_inode_dirty(old_ip);
1268 
1269     new_dir->i_ctime = new_dir->i_mtime = current_time(new_dir);
1270     mark_inode_dirty(new_dir);
1271 
1272     /* Build list of inodes modified by this transaction */
1273     ipcount = 0;
1274     iplist[ipcount++] = old_ip;
1275     if (new_ip)
1276         iplist[ipcount++] = new_ip;
1277     iplist[ipcount++] = old_dir;
1278 
1279     if (old_dir != new_dir) {
1280         iplist[ipcount++] = new_dir;
1281         old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
1282         mark_inode_dirty(old_dir);
1283     }
1284 
1285     /*
1286      * Incomplete truncate of file data can
1287      * result in timing problems unless we synchronously commit the
1288      * transaction.
1289      */
1290     if (new_size)
1291         commit_flag = COMMIT_SYNC;
1292     else
1293         commit_flag = 0;
1294 
1295     rc = txCommit(tid, ipcount, iplist, commit_flag);
1296 
1297       out_tx:
1298     txEnd(tid);
1299     if (new_ip)
1300         mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
1301     if (old_dir != new_dir)
1302         mutex_unlock(&JFS_IP(old_dir)->commit_mutex);
1303     mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
1304     mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
1305 
1306     while (new_size && (rc == 0)) {
1307         tid = txBegin(new_ip->i_sb, 0);
1308         mutex_lock(&JFS_IP(new_ip)->commit_mutex);
1309         new_size = xtTruncate_pmap(tid, new_ip, new_size);
1310         if (new_size < 0) {
1311             txAbort(tid, 1);
1312             rc = new_size;
1313         } else
1314             rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
1315         txEnd(tid);
1316         mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
1317     }
1318     if (new_ip && (new_ip->i_nlink == 0))
1319         set_cflag(COMMIT_Nolink, new_ip);
1320     /*
1321      * Truncating the directory index table is not guaranteed.  It
1322      * may need to be done iteratively
1323      */
1324     if (test_cflag(COMMIT_Stale, old_dir)) {
1325         if (old_dir->i_size > 1)
1326             jfs_truncate_nolock(old_dir, 0);
1327 
1328         clear_cflag(COMMIT_Stale, old_dir);
1329     }
1330       out_unlock:
1331     if (new_ip && !S_ISDIR(new_ip->i_mode))
1332         IWRITE_UNLOCK(new_ip);
1333       out3:
1334     free_UCSname(&new_dname);
1335       out2:
1336     free_UCSname(&old_dname);
1337       out1:
1338     jfs_info("jfs_rename: returning %d", rc);
1339     return rc;
1340 }
1341 
1342 
1343 /*
1344  * NAME:    jfs_mknod
1345  *
1346  * FUNCTION:    Create a special file (device)
1347  */
1348 static int jfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
1349              struct dentry *dentry, umode_t mode, dev_t rdev)
1350 {
1351     struct jfs_inode_info *jfs_ip;
1352     struct btstack btstack;
1353     struct component_name dname;
1354     ino_t ino;
1355     struct inode *ip;
1356     struct inode *iplist[2];
1357     int rc;
1358     tid_t tid;
1359     struct tblock *tblk;
1360 
1361     jfs_info("jfs_mknod: %pd", dentry);
1362 
1363     rc = dquot_initialize(dir);
1364     if (rc)
1365         goto out;
1366 
1367     if ((rc = get_UCSname(&dname, dentry)))
1368         goto out;
1369 
1370     ip = ialloc(dir, mode);
1371     if (IS_ERR(ip)) {
1372         rc = PTR_ERR(ip);
1373         goto out1;
1374     }
1375     jfs_ip = JFS_IP(ip);
1376 
1377     tid = txBegin(dir->i_sb, 0);
1378 
1379     mutex_lock_nested(&JFS_IP(dir)->commit_mutex, COMMIT_MUTEX_PARENT);
1380     mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
1381 
1382     rc = jfs_init_acl(tid, ip, dir);
1383     if (rc)
1384         goto out3;
1385 
1386     rc = jfs_init_security(tid, ip, dir, &dentry->d_name);
1387     if (rc) {
1388         txAbort(tid, 0);
1389         goto out3;
1390     }
1391 
1392     if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) {
1393         txAbort(tid, 0);
1394         goto out3;
1395     }
1396 
1397     tblk = tid_to_tblock(tid);
1398     tblk->xflag |= COMMIT_CREATE;
1399     tblk->ino = ip->i_ino;
1400     tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
1401 
1402     ino = ip->i_ino;
1403     if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) {
1404         txAbort(tid, 0);
1405         goto out3;
1406     }
1407 
1408     ip->i_op = &jfs_file_inode_operations;
1409     jfs_ip->dev = new_encode_dev(rdev);
1410     init_special_inode(ip, ip->i_mode, rdev);
1411 
1412     mark_inode_dirty(ip);
1413 
1414     dir->i_ctime = dir->i_mtime = current_time(dir);
1415 
1416     mark_inode_dirty(dir);
1417 
1418     iplist[0] = dir;
1419     iplist[1] = ip;
1420     rc = txCommit(tid, 2, iplist, 0);
1421 
1422       out3:
1423     txEnd(tid);
1424     mutex_unlock(&JFS_IP(ip)->commit_mutex);
1425     mutex_unlock(&JFS_IP(dir)->commit_mutex);
1426     if (rc) {
1427         free_ea_wmap(ip);
1428         clear_nlink(ip);
1429         discard_new_inode(ip);
1430     } else {
1431         d_instantiate_new(dentry, ip);
1432     }
1433 
1434       out1:
1435     free_UCSname(&dname);
1436 
1437       out:
1438     jfs_info("jfs_mknod: returning %d", rc);
1439     return rc;
1440 }
1441 
1442 static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, unsigned int flags)
1443 {
1444     struct btstack btstack;
1445     ino_t inum;
1446     struct inode *ip;
1447     struct component_name key;
1448     int rc;
1449 
1450     jfs_info("jfs_lookup: name = %pd", dentry);
1451 
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         ip = NULL;
1458     } else if (rc) {
1459         jfs_err("jfs_lookup: dtSearch returned %d", rc);
1460         ip = ERR_PTR(rc);
1461     } else {
1462         ip = jfs_iget(dip->i_sb, inum);
1463         if (IS_ERR(ip))
1464             jfs_err("jfs_lookup: iget failed on inum %d", (uint)inum);
1465     }
1466 
1467     return d_splice_alias(ip, dentry);
1468 }
1469 
1470 static struct inode *jfs_nfs_get_inode(struct super_block *sb,
1471         u64 ino, u32 generation)
1472 {
1473     struct inode *inode;
1474 
1475     if (ino == 0)
1476         return ERR_PTR(-ESTALE);
1477     inode = jfs_iget(sb, ino);
1478     if (IS_ERR(inode))
1479         return ERR_CAST(inode);
1480 
1481     if (generation && inode->i_generation != generation) {
1482         iput(inode);
1483         return ERR_PTR(-ESTALE);
1484     }
1485 
1486     return inode;
1487 }
1488 
1489 struct dentry *jfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
1490         int fh_len, int fh_type)
1491 {
1492     return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
1493                     jfs_nfs_get_inode);
1494 }
1495 
1496 struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
1497         int fh_len, int fh_type)
1498 {
1499     return generic_fh_to_parent(sb, fid, fh_len, fh_type,
1500                     jfs_nfs_get_inode);
1501 }
1502 
1503 struct dentry *jfs_get_parent(struct dentry *dentry)
1504 {
1505     unsigned long parent_ino;
1506 
1507     parent_ino =
1508         le32_to_cpu(JFS_IP(d_inode(dentry))->i_dtroot.header.idotdot);
1509 
1510     return d_obtain_alias(jfs_iget(dentry->d_sb, parent_ino));
1511 }
1512 
1513 const struct inode_operations jfs_dir_inode_operations = {
1514     .create     = jfs_create,
1515     .lookup     = jfs_lookup,
1516     .link       = jfs_link,
1517     .unlink     = jfs_unlink,
1518     .symlink    = jfs_symlink,
1519     .mkdir      = jfs_mkdir,
1520     .rmdir      = jfs_rmdir,
1521     .mknod      = jfs_mknod,
1522     .rename     = jfs_rename,
1523     .listxattr  = jfs_listxattr,
1524     .setattr    = jfs_setattr,
1525     .fileattr_get   = jfs_fileattr_get,
1526     .fileattr_set   = jfs_fileattr_set,
1527 #ifdef CONFIG_JFS_POSIX_ACL
1528     .get_acl    = jfs_get_acl,
1529     .set_acl    = jfs_set_acl,
1530 #endif
1531 };
1532 
1533 const struct file_operations jfs_dir_operations = {
1534     .read       = generic_read_dir,
1535     .iterate    = jfs_readdir,
1536     .fsync      = jfs_fsync,
1537     .unlocked_ioctl = jfs_ioctl,
1538     .compat_ioctl   = compat_ptr_ioctl,
1539     .llseek     = generic_file_llseek,
1540 };
1541 
1542 static int jfs_ci_hash(const struct dentry *dir, struct qstr *this)
1543 {
1544     unsigned long hash;
1545     int i;
1546 
1547     hash = init_name_hash(dir);
1548     for (i=0; i < this->len; i++)
1549         hash = partial_name_hash(tolower(this->name[i]), hash);
1550     this->hash = end_name_hash(hash);
1551 
1552     return 0;
1553 }
1554 
1555 static int jfs_ci_compare(const struct dentry *dentry,
1556         unsigned int len, const char *str, const struct qstr *name)
1557 {
1558     int i, result = 1;
1559 
1560     if (len != name->len)
1561         goto out;
1562     for (i=0; i < len; i++) {
1563         if (tolower(str[i]) != tolower(name->name[i]))
1564             goto out;
1565     }
1566     result = 0;
1567 out:
1568     return result;
1569 }
1570 
1571 static int jfs_ci_revalidate(struct dentry *dentry, unsigned int flags)
1572 {
1573     /*
1574      * This is not negative dentry. Always valid.
1575      *
1576      * Note, rename() to existing directory entry will have ->d_inode,
1577      * and will use existing name which isn't specified name by user.
1578      *
1579      * We may be able to drop this positive dentry here. But dropping
1580      * positive dentry isn't good idea. So it's unsupported like
1581      * rename("filename", "FILENAME") for now.
1582      */
1583     if (d_really_is_positive(dentry))
1584         return 1;
1585 
1586     /*
1587      * This may be nfsd (or something), anyway, we can't see the
1588      * intent of this. So, since this can be for creation, drop it.
1589      */
1590     if (!flags)
1591         return 0;
1592 
1593     /*
1594      * Drop the negative dentry, in order to make sure to use the
1595      * case sensitive name which is specified by user if this is
1596      * for creation.
1597      */
1598     if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
1599         return 0;
1600     return 1;
1601 }
1602 
1603 const struct dentry_operations jfs_ci_dentry_operations =
1604 {
1605     .d_hash = jfs_ci_hash,
1606     .d_compare = jfs_ci_compare,
1607     .d_revalidate = jfs_ci_revalidate,
1608 };