aboutsummaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
Diffstat (limited to 'module')
-rw-r--r--module/zfs/zfs_dir.c18
-rw-r--r--module/zfs/zfs_vnops.c16
2 files changed, 28 insertions, 6 deletions
diff --git a/module/zfs/zfs_dir.c b/module/zfs/zfs_dir.c
index 47550ec63..8f1a0c2cc 100644
--- a/module/zfs/zfs_dir.c
+++ b/module/zfs/zfs_dir.c
@@ -64,11 +64,11 @@ static int
zfs_match_find(zfs_sb_t *zsb, znode_t *dzp, char *name, boolean_t exact,
boolean_t update, int *deflags, pathname_t *rpnp, uint64_t *zoid)
{
+ boolean_t conflict = B_FALSE;
int error;
if (zsb->z_norm) {
matchtype_t mt = MT_FIRST;
- boolean_t conflict = B_FALSE;
size_t bufsz = 0;
char *buf = NULL;
@@ -84,11 +84,23 @@ zfs_match_find(zfs_sb_t *zsb, znode_t *dzp, char *name, boolean_t exact,
*/
error = zap_lookup_norm(zsb->z_os, dzp->z_id, name, 8, 1,
zoid, mt, buf, bufsz, &conflict);
- if (!error && deflags)
- *deflags = conflict ? ED_CASE_CONFLICT : 0;
} else {
error = zap_lookup(zsb->z_os, dzp->z_id, name, 8, 1, zoid);
}
+
+ /*
+ * Allow multiple entries provided the first entry is
+ * the object id. Non-zpl consumers may safely make
+ * use of the additional space.
+ *
+ * XXX: This should be a feature flag for compatibility
+ */
+ if (error == EOVERFLOW)
+ error = 0;
+
+ if (zsb->z_norm && !error && deflags)
+ *deflags = conflict ? ED_CASE_CONFLICT : 0;
+
*zoid = ZFS_DIRENT_OBJ(*zoid);
#ifdef HAVE_DNLC
diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c
index b7f5daaaf..c1391984a 100644
--- a/module/zfs/zfs_vnops.c
+++ b/module/zfs/zfs_vnops.c
@@ -2012,12 +2012,22 @@ zfs_readdir(struct inode *ip, void *dirent, filldir_t filldir,
goto update;
}
+ /*
+ * Allow multiple entries provided the first entry is
+ * the object id. Non-zpl consumers may safely make
+ * use of the additional space.
+ *
+ * XXX: This should be a feature flag for compatibility
+ */
if (zap.za_integer_length != 8 ||
- zap.za_num_integers != 1) {
+ zap.za_num_integers == 0) {
cmn_err(CE_WARN, "zap_readdir: bad directory "
- "entry, obj = %lld, offset = %lld\n",
+ "entry, obj = %lld, offset = %lld, "
+ "length = %d, num = %lld\n",
(u_longlong_t)zp->z_id,
- (u_longlong_t)*pos);
+ (u_longlong_t)*pos,
+ zap.za_integer_length,
+ (u_longlong_t)zap.za_num_integers);
error = ENXIO;
goto update;
}