aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/zpl_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'module/zfs/zpl_inode.c')
-rw-r--r--module/zfs/zpl_inode.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c
index c4233959b..cbdab7d30 100644
--- a/module/zfs/zpl_inode.c
+++ b/module/zfs/zpl_inode.c
@@ -31,6 +31,7 @@
#include <sys/dmu_objset.h>
#include <sys/vfs.h>
#include <sys/zpl.h>
+#include <sys/file.h>
static struct dentry *
@@ -46,6 +47,7 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
fstrans_cookie_t cookie;
pathname_t *ppn = NULL;
pathname_t pn;
+ int zfs_flags = 0;
zfs_sb_t *zsb = dentry->d_sb->s_fs_info;
if (dlen(dentry) > ZFS_MAXNAMELEN)
@@ -56,12 +58,13 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
/* If we are a case insensitive fs, we need the real name */
if (zsb->z_case == ZFS_CASE_INSENSITIVE) {
+ zfs_flags = FIGNORECASE;
pn.pn_bufsize = ZFS_MAXNAMELEN;
pn.pn_buf = kmem_zalloc(ZFS_MAXNAMELEN, KM_SLEEP);
ppn = &pn;
}
- error = -zfs_lookup(dir, dname(dentry), &ip, 0, cr, NULL, ppn);
+ error = -zfs_lookup(dir, dname(dentry), &ip, zfs_flags, cr, NULL, ppn);
spl_fstrans_unmark(cookie);
ASSERT3S(error, <=, 0);
crfree(cr);
@@ -74,8 +77,17 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
spin_unlock(&dentry->d_lock);
if (error) {
- if (ppn)
+ /*
+ * If we have a case sensitive fs, we do not want to
+ * insert negative entries, so return NULL for ENOENT.
+ * Fall through if the error is not ENOENT. Also free memory.
+ */
+ if (ppn) {
kmem_free(pn.pn_buf, ZFS_MAXNAMELEN);
+ if (error == -ENOENT)
+ return (NULL);
+ }
+
if (error == -ENOENT)
return (d_splice_alias(NULL, dentry));
else
@@ -205,10 +217,19 @@ zpl_unlink(struct inode *dir, struct dentry *dentry)
cred_t *cr = CRED();
int error;
fstrans_cookie_t cookie;
+ zfs_sb_t *zsb = dentry->d_sb->s_fs_info;
crhold(cr);
cookie = spl_fstrans_mark();
error = -zfs_remove(dir, dname(dentry), cr);
+
+ /*
+ * For a CI FS we must invalidate the dentry to prevent the
+ * creation of negative entries.
+ */
+ if (error == 0 && zsb->z_case == ZFS_CASE_INSENSITIVE)
+ d_invalidate(dentry);
+
spl_fstrans_unmark(cookie);
crfree(cr);
ASSERT3S(error, <=, 0);
@@ -256,10 +277,19 @@ zpl_rmdir(struct inode * dir, struct dentry *dentry)
cred_t *cr = CRED();
int error;
fstrans_cookie_t cookie;
+ zfs_sb_t *zsb = dentry->d_sb->s_fs_info;
crhold(cr);
cookie = spl_fstrans_mark();
error = -zfs_rmdir(dir, dname(dentry), NULL, cr, 0);
+
+ /*
+ * For a CI FS we must invalidate the dentry to prevent the
+ * creation of negative entries.
+ */
+ if (error == 0 && zsb->z_case == ZFS_CASE_INSENSITIVE)
+ d_invalidate(dentry);
+
spl_fstrans_unmark(cookie);
crfree(cr);
ASSERT3S(error, <=, 0);