#include <sys/sid.h>
#include <sys/mode.h>
#include "fs/fs_subr.h"
+#include <sys/zfs_ctldir.h>
#include <sys/zfs_fuid.h>
#include <sys/zfs_sa.h>
#include <sys/zfs_vnops.h>
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;
}
dmu_prefetch(os, objnum, 0, 0);
}
- if (*pos >= 2) {
+ if (*pos > 2 || (*pos == 2 && !zfs_show_ctldir(zp))) {
zap_cursor_advance(&zc);
*pos = zap_cursor_serialize(&zc);
} else {
zfs_sb_t *zsb = ITOZSB(ip);
int error;
-#ifdef HAVE_SNAPSHOT
- /* Early return for snapshot inode? */
-#endif /* HAVE_SNAPSHOT */
+ if (zfsctl_is_node(ip)) {
+ zfsctl_inode_inactive(ip);
+ return;
+ }
rw_enter(&zsb->z_teardown_inactive_lock, RW_READER);
if (zp->z_sa_hdl == NULL) {
return (EINVAL);
}
+ /*
+ * Permissions aren't checked on Solaris because on this OS
+ * zfs_space() can only be called with an opened file handle.
+ * On Linux we can get here through truncate_range() which
+ * operates directly on inodes, so we need to check access rights.
+ */
+ if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr))) {
+ ZFS_EXIT(zsb);
+ return (error);
+ }
+
off = bfp->l_start;
len = bfp->l_len; /* 0 means from off to end of file */