Add -p switch to "zpool get"
[zfs.git] / module / zfs / zfs_dir.c
index 47550ec..4a4969f 100644 (file)
@@ -50,6 +50,7 @@
 #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>
@@ -64,11 +65,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 +85,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
@@ -403,28 +416,24 @@ zfs_dirlook(znode_t *dzp, char *name, struct inode **ipp, int flags,
 
                /*
                 * 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;
 
@@ -553,7 +562,7 @@ zfs_unlinked_drain(zfs_sb_t *zsb)
        int             error;
 
        /*
-        * Interate over the contents of the unlinked set.
+        * Iterate over the contents of the unlinked set.
         */
        for (zap_cursor_init(&zc, zsb->z_os, zsb->z_unlinkedobj);
            zap_cursor_retrieve(&zc, &zap) == 0;
@@ -828,8 +837,8 @@ zfs_dropname(zfs_dirlock_t *dl, znode_t *zp, znode_t *dzp, dmu_tx_t *tx,
 }
 
 /*
- * 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.
@@ -856,7 +865,7 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag,
 
                if (zp_is_dir && !zfs_dirempty(zp)) {
                        mutex_exit(&zp->z_lock);
-                       return (EEXIST);
+                       return (ENOTEMPTY);
                }
 
                /*