#include <sys/zap.h>
#include <sys/dmu.h>
#include <sys/atomic.h>
+#include <sys/zfs_ctldir.h>
#include <sys/zfs_fuid.h>
#include <sys/sa.h>
#include <sys/zfs_sa.h>
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;
*/
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
/*
* If we are a snapshot mounted under .zfs, return
- * the vp for the snapshot directory.
+ * the inode pointer for the snapshot directory.
*/
if ((error = sa_lookup(dzp->z_sa_hdl,
SA_ZPL_PARENT(zsb), &parent, sizeof (parent))) != 0)
return (error);
-#ifdef HAVE_SNAPSHOT
+
if (parent == dzp->z_id && zsb->z_parent != zsb) {
error = zfsctl_root_lookup(zsb->z_parent->z_ctldir,
- "snapshot", ipp, NULL, 0, NULL, kcred,
- NULL, NULL, NULL);
+ "snapshot", ipp, 0, kcred, NULL, NULL);
return (error);
}
-#endif /* HAVE_SNAPSHOT */
rw_enter(&dzp->z_parent_lock, RW_READER);
error = zfs_zget(zsb, parent, &zp);
if (error == 0)
*ipp = ZTOI(zp);
rw_exit(&dzp->z_parent_lock);
-#ifdef HAVE_SNAPSHOT
} else if (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) {
*ipp = zfsctl_root(dzp);
-#endif /* HAVE_SNAPSHOT */
} else {
int zf;
* Leave it in the unlinked set.
*/
zfs_znode_dmu_fini(zp);
- zfs_inode_destroy(ZTOI(zp));
return;
}
* Not enough space. Leave the file in the unlinked set.
*/
zfs_znode_dmu_fini(zp);
- zfs_inode_destroy(ZTOI(zp));
return;
}
*/
dmu_tx_abort(tx);
zfs_znode_dmu_fini(zp);
- zfs_inode_destroy(ZTOI(zp));
goto out;
}
}
/*
- * Unlink zp from dl, and mark zp for deletion if this was the last link.
- * Can fail if zp is a mount point (EBUSY) or a non-empty directory (EEXIST).
+ * Unlink zp from dl, and mark zp for deletion if this was the last link. Can
+ * fail if zp is a mount point (EBUSY) or a non-empty directory (ENOTEMPTY).
* If 'unlinkedp' is NULL, we put unlinked znodes on the unlinked list.
* If it's non-NULL, we use it to indicate whether the znode needs deletion,
* and it's the caller's job to do it.
if (zp_is_dir && !zfs_dirempty(zp)) {
mutex_exit(&zp->z_lock);
- return (EEXIST);
+ return (ENOTEMPTY);
}
/*
return (ENOENT);
}
- if (zsb->z_vfs->mnt_flags & MNT_READONLY) {
+ if (zfs_is_readonly(zsb)) {
zfs_dirent_unlock(dl);
return (EROFS);
}
va.va_mode = S_IFDIR | S_ISVTX | 0777;
zfs_fuid_map_ids(zp, cr, &va.va_uid, &va.va_gid);
+ va.va_dentry = NULL;
error = zfs_make_xattrdir(zp, &va, xipp, cr);
zfs_dirent_unlock(dl);