diff options
author | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:49:25 -0500 |
---|---|---|
committer | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:50:18 -0500 |
commit | 2bc334dcc7c77be3700dd443d92a78603f76976b (patch) | |
tree | 51c666a438263f09efdea8a55a6220411ff7f8ab | |
parent | 79eb4dde742fe2e9c9e301432b894a7410261ce7 (diff) |
jfs: dont overwrite dentry name in d_revalidate
Use vfat's method for dealing with negative dentries to preserve case,
rather than overwrite dentry name in d_revalidate, which is a bit ugly
and also gets in the way of doing lock-free path walking.
Signed-off-by: Nick Piggin <npiggin@kernel.dk>
-rw-r--r-- | fs/jfs/namei.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 231ca4af9bce..2da1546161fa 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> |
@@ -1597,21 +1598,47 @@ static int jfs_ci_compare(struct dentry *dir, struct qstr *a, struct qstr *b) | |||
1597 | goto out; | 1598 | goto out; |
1598 | } | 1599 | } |
1599 | result = 0; | 1600 | result = 0; |
1601 | out: | ||
1602 | return result; | ||
1603 | } | ||
1600 | 1604 | ||
1605 | static int jfs_ci_revalidate(struct dentry *dentry, struct nameidata *nd) | ||
1606 | { | ||
1601 | /* | 1607 | /* |
1602 | * We want creates to preserve case. A negative dentry, a, that | 1608 | * This is not negative dentry. Always valid. |
1603 | * has a different case than b may cause a new entry to be created | 1609 | * |
1604 | * with the wrong case. Since we can't tell if a comes from a negative | 1610 | * Note, rename() to existing directory entry will have ->d_inode, |
1605 | * dentry, we blindly replace it with b. This should be harmless if | 1611 | * and will use existing name which isn't specified name by user. |
1606 | * a is not a negative dentry. | 1612 | * |
1613 | * We may be able to drop this positive dentry here. But dropping | ||
1614 | * positive dentry isn't good idea. So it's unsupported like | ||
1615 | * rename("filename", "FILENAME") for now. | ||
1607 | */ | 1616 | */ |
1608 | memcpy((unsigned char *)a->name, b->name, a->len); | 1617 | if (dentry->d_inode) |
1609 | out: | 1618 | return 1; |
1610 | return result; | 1619 | |
1620 | /* | ||
1621 | * This may be nfsd (or something), anyway, we can't see the | ||
1622 | * intent of this. So, since this can be for creation, drop it. | ||
1623 | */ | ||
1624 | if (!nd) | ||
1625 | return 0; | ||
1626 | |||
1627 | /* | ||
1628 | * Drop the negative dentry, in order to make sure to use the | ||
1629 | * case sensitive name which is specified by user if this is | ||
1630 | * for creation. | ||
1631 | */ | ||
1632 | if (!(nd->flags & (LOOKUP_CONTINUE | LOOKUP_PARENT))) { | ||
1633 | if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) | ||
1634 | return 0; | ||
1635 | } | ||
1636 | return 1; | ||
1611 | } | 1637 | } |
1612 | 1638 | ||
1613 | const struct dentry_operations jfs_ci_dentry_operations = | 1639 | const struct dentry_operations jfs_ci_dentry_operations = |
1614 | { | 1640 | { |
1615 | .d_hash = jfs_ci_hash, | 1641 | .d_hash = jfs_ci_hash, |
1616 | .d_compare = jfs_ci_compare, | 1642 | .d_compare = jfs_ci_compare, |
1643 | .d_revalidate = jfs_ci_revalidate, | ||
1617 | }; | 1644 | }; |