aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jfs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jfs/namei.c')
-rw-r--r--fs/jfs/namei.c82
1 files changed, 52 insertions, 30 deletions
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index a9cf8e8675be..eaaf2b511e89 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/fs.h> 20#include <linux/fs.h>
21#include <linux/namei.h>
21#include <linux/ctype.h> 22#include <linux/ctype.h>
22#include <linux/quotaops.h> 23#include <linux/quotaops.h>
23#include <linux/exportfs.h> 24#include <linux/exportfs.h>
@@ -114,7 +115,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
114 if (rc) 115 if (rc)
115 goto out3; 116 goto out3;
116 117
117 rc = jfs_init_security(tid, ip, dip); 118 rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
118 if (rc) { 119 if (rc) {
119 txAbort(tid, 0); 120 txAbort(tid, 0);
120 goto out3; 121 goto out3;
@@ -252,7 +253,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
252 if (rc) 253 if (rc)
253 goto out3; 254 goto out3;
254 255
255 rc = jfs_init_security(tid, ip, dip); 256 rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
256 if (rc) { 257 if (rc) {
257 txAbort(tid, 0); 258 txAbort(tid, 0);
258 goto out3; 259 goto out3;
@@ -808,9 +809,6 @@ static int jfs_link(struct dentry *old_dentry,
808 if (ip->i_nlink == JFS_LINK_MAX) 809 if (ip->i_nlink == JFS_LINK_MAX)
809 return -EMLINK; 810 return -EMLINK;
810 811
811 if (ip->i_nlink == 0)
812 return -ENOENT;
813
814 dquot_initialize(dir); 812 dquot_initialize(dir);
815 813
816 tid = txBegin(ip->i_sb, 0); 814 tid = txBegin(ip->i_sb, 0);
@@ -839,7 +837,7 @@ static int jfs_link(struct dentry *old_dentry,
839 ip->i_ctime = CURRENT_TIME; 837 ip->i_ctime = CURRENT_TIME;
840 dir->i_ctime = dir->i_mtime = CURRENT_TIME; 838 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
841 mark_inode_dirty(dir); 839 mark_inode_dirty(dir);
842 atomic_inc(&ip->i_count); 840 ihold(ip);
843 841
844 iplist[0] = ip; 842 iplist[0] = ip;
845 iplist[1] = dir; 843 iplist[1] = dir;
@@ -931,7 +929,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
931 mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT); 929 mutex_lock_nested(&JFS_IP(dip)->commit_mutex, COMMIT_MUTEX_PARENT);
932 mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD); 930 mutex_lock_nested(&JFS_IP(ip)->commit_mutex, COMMIT_MUTEX_CHILD);
933 931
934 rc = jfs_init_security(tid, ip, dip); 932 rc = jfs_init_security(tid, ip, dip, &dentry->d_name);
935 if (rc) 933 if (rc)
936 goto out3; 934 goto out3;
937 935
@@ -1394,7 +1392,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
1394 if (rc) 1392 if (rc)
1395 goto out3; 1393 goto out3;
1396 1394
1397 rc = jfs_init_security(tid, ip, dir); 1395 rc = jfs_init_security(tid, ip, dir, &dentry->d_name);
1398 if (rc) { 1396 if (rc) {
1399 txAbort(tid, 0); 1397 txAbort(tid, 0);
1400 goto out3; 1398 goto out3;
@@ -1464,9 +1462,6 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struc
1464 1462
1465 jfs_info("jfs_lookup: name = %s", name); 1463 jfs_info("jfs_lookup: name = %s", name);
1466 1464
1467 if (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2)
1468 dentry->d_op = &jfs_ci_dentry_operations;
1469
1470 if ((name[0] == '.') && (len == 1)) 1465 if ((name[0] == '.') && (len == 1))
1471 inum = dip->i_ino; 1466 inum = dip->i_ino;
1472 else if (strcmp(name, "..") == 0) 1467 else if (strcmp(name, "..") == 0)
@@ -1491,12 +1486,7 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struc
1491 return ERR_CAST(ip); 1486 return ERR_CAST(ip);
1492 } 1487 }
1493 1488
1494 dentry = d_splice_alias(ip, dentry); 1489 return d_splice_alias(ip, dentry);
1495
1496 if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2))
1497 dentry->d_op = &jfs_ci_dentry_operations;
1498
1499 return dentry;
1500} 1490}
1501 1491
1502static struct inode *jfs_nfs_get_inode(struct super_block *sb, 1492static struct inode *jfs_nfs_get_inode(struct super_block *sb,
@@ -1573,7 +1563,8 @@ const struct file_operations jfs_dir_operations = {
1573 .llseek = generic_file_llseek, 1563 .llseek = generic_file_llseek,
1574}; 1564};
1575 1565
1576static int jfs_ci_hash(struct dentry *dir, struct qstr *this) 1566static int jfs_ci_hash(const struct dentry *dir, const struct inode *inode,
1567 struct qstr *this)
1577{ 1568{
1578 unsigned long hash; 1569 unsigned long hash;
1579 int i; 1570 int i;
@@ -1586,32 +1577,63 @@ static int jfs_ci_hash(struct dentry *dir, struct qstr *this)
1586 return 0; 1577 return 0;
1587} 1578}
1588 1579
1589static int jfs_ci_compare(struct dentry *dir, struct qstr *a, struct qstr *b) 1580static int jfs_ci_compare(const struct dentry *parent,
1581 const struct inode *pinode,
1582 const struct dentry *dentry, const struct inode *inode,
1583 unsigned int len, const char *str, const struct qstr *name)
1590{ 1584{
1591 int i, result = 1; 1585 int i, result = 1;
1592 1586
1593 if (a->len != b->len) 1587 if (len != name->len)
1594 goto out; 1588 goto out;
1595 for (i=0; i < a->len; i++) { 1589 for (i=0; i < len; i++) {
1596 if (tolower(a->name[i]) != tolower(b->name[i])) 1590 if (tolower(str[i]) != tolower(name->name[i]))
1597 goto out; 1591 goto out;
1598 } 1592 }
1599 result = 0; 1593 result = 0;
1594out:
1595 return result;
1596}
1600 1597
1598static int jfs_ci_revalidate(struct dentry *dentry, struct nameidata *nd)
1599{
1600 if (nd && nd->flags & LOOKUP_RCU)
1601 return -ECHILD;
1601 /* 1602 /*
1602 * We want creates to preserve case. A negative dentry, a, that 1603 * This is not negative dentry. Always valid.
1603 * has a different case than b may cause a new entry to be created 1604 *
1604 * with the wrong case. Since we can't tell if a comes from a negative 1605 * Note, rename() to existing directory entry will have ->d_inode,
1605 * dentry, we blindly replace it with b. This should be harmless if 1606 * and will use existing name which isn't specified name by user.
1606 * a is not a negative dentry. 1607 *
1608 * We may be able to drop this positive dentry here. But dropping
1609 * positive dentry isn't good idea. So it's unsupported like
1610 * rename("filename", "FILENAME") for now.
1607 */ 1611 */
1608 memcpy((unsigned char *)a->name, b->name, a->len); 1612 if (dentry->d_inode)
1609out: 1613 return 1;
1610 return result; 1614
1615 /*
1616 * This may be nfsd (or something), anyway, we can't see the
1617 * intent of this. So, since this can be for creation, drop it.
1618 */
1619 if (!nd)
1620 return 0;
1621
1622 /*
1623 * Drop the negative dentry, in order to make sure to use the
1624 * case sensitive name which is specified by user if this is
1625 * for creation.
1626 */
1627 if (!(nd->flags & (LOOKUP_CONTINUE | LOOKUP_PARENT))) {
1628 if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
1629 return 0;
1630 }
1631 return 1;
1611} 1632}
1612 1633
1613const struct dentry_operations jfs_ci_dentry_operations = 1634const struct dentry_operations jfs_ci_dentry_operations =
1614{ 1635{
1615 .d_hash = jfs_ci_hash, 1636 .d_hash = jfs_ci_hash,
1616 .d_compare = jfs_ci_compare, 1637 .d_compare = jfs_ci_compare,
1638 .d_revalidate = jfs_ci_revalidate,
1617}; 1639};