hammer2 - Refactor frontend part 14/many
[dragonfly.git] / sys / vfs / hammer2 / hammer2_chain.c
index cb8ba6c..dcd564a 100644 (file)
@@ -1535,7 +1535,6 @@ hammer2_chain_lookup_done(hammer2_chain_t *parent)
        }
 }
 
-static
 hammer2_chain_t *
 hammer2_chain_getparent(hammer2_chain_t **parentp, int how)
 {
@@ -4033,295 +4032,6 @@ hammer2_chain_testcheck(hammer2_chain_t *chain, void *bdata)
        return r;
 }
 
-#if 0
-/*
- * The chain has been removed from the original directory and replaced
- * with a hardlink pointer.  Move the chain to the specified parent
- * directory, change the filename to "0xINODENUMBER", and adjust the key.
- * The chain becomes our invisible hardlink target.
- *
- * The original chain must be deleted on entry.
- *
- * Caller is responsible for synchronizing ip->meta.name/name_len.  This
- * routine may be called from a XOP, so modifying ip->meta directly is out.
- */
-static
-void
-hammer2_chain_hardlink_shiftup(
-                       hammer2_chain_t *chain,
-                       hammer2_key_t inum,
-                       hammer2_chain_t **dchainp,
-                       int *errorp)
-{
-       hammer2_inode_data_t *nipdata;
-       hammer2_chain_t *xchain;
-       hammer2_key_t key_dummy;
-       hammer2_key_t lhc;
-       hammer2_blockref_t bref;
-
-       lhc = inum;     /* bit 63 not set makes hardlinks invisible */
-       KKASSERT((lhc & HAMMER2_DIRHASH_VISIBLE) == 0);
-
-       /*
-        * Locate the inode or indirect block to create the new
-        * entry in.  lhc represents the inode number so there is
-        * no collision iteration.
-        *
-        * There should be no key collisions with invisible inode keys.
-        */
-       *errorp = 0;
-       xchain = hammer2_chain_lookup(dchainp, &key_dummy, lhc, lhc, 0);
-       if (xchain) {
-               hammer2_chain_unlock(xchain);
-               hammer2_chain_drop(xchain);
-               xchain =NULL;
-               *errorp = ENOSPC;
-#if 0
-               Debugger("X3");
-#endif
-       }
-
-       /*
-        * Handle the error case
-        */
-       if (*errorp) {
-               panic("error2");
-               KKASSERT(xchain == NULL);
-               return;
-       }
-
-       /*
-        * Use xcluster as a placeholder for (lhc).  Duplicate cluster to the
-        * same target bref as xcluster and then delete xcluster.  The
-        * duplication occurs after xcluster in flush order even though
-        * xcluster is deleted after the duplication. XXX
-        *
-        * WARNING! Duplications (to a different parent) can cause indirect
-        *          blocks to be inserted, refactor xcluster.
-        *
-        * WARNING! Only key and keybits is extracted from a passed-in bref.
-        */
-       bref = chain->bref;
-       bref.key = lhc;                 /* invisible dir entry key */
-       bref.keybits = 0;
-       hammer2_chain_rename(&bref, dchainp, chain, 0);
-
-       /*
-        * cluster is now 'live' again.. adjust the filename.
-        *
-        * Directory entries are inodes but this is a hidden hardlink
-        * target.  The name isn't used but to ease debugging give it
-        * a name after its inode number.
-        */
-       hammer2_chain_modify(chain, 0);
-       nipdata = &chain->data->ipdata;
-       ksnprintf(nipdata->filename, sizeof(nipdata->filename),
-                 "0x%016jx", (intmax_t)inum);
-
-       /*
-        * Warning: Caller must adjust ip->meta.name_lne, name_key,
-        *          and nlinks.
-        */
-       nipdata->meta.name_len = strlen(nipdata->filename);
-       nipdata->meta.name_key = lhc;
-       /*ip->meta.nlinks += nlinks;*/
-}
-
-/*
- * Given an exclusively locked inode and cluster we consolidate the cluster
- * for hardlink creation, adding (nlinks) to the file's link count and
- * potentially relocating the inode to (cdip) which is a parent directory
- * common to both the current location of the inode and the intended new
- * hardlink.
- *
- * Replaces (*clusterp) if consolidation occurred, unlocking the old cluster
- * and returning a new locked cluster.
- *
- * NOTE!  This function will also replace ip->cluster.
- */
-int
-hammer2_chain_hardlink_consolidate(
-                       hammer2_inode_t *ip,
-                       hammer2_chain_t **chainp,
-                       hammer2_inode_t *cdip,
-                       hammer2_chain_t *cdchain,
-                       int nlinks)
-{
-       hammer2_chain_t *chain;
-       hammer2_chain_t *parent;
-       int error;
-
-       chain = *chainp;
-       if (nlinks == 0 &&                      /* no hardlink needed */
-           (ip->meta.name_key & HAMMER2_DIRHASH_VISIBLE)) {
-               return (0);
-       }
-
-       if (hammer2_hardlink_enable == 0) {     /* disallow hardlinks */
-               hammer2_chain_unlock(chain);
-               hammer2_chain_drop(chain);
-               *chainp = NULL;
-               return (ENOTSUP);
-       }
-
-       parent = NULL;
-
-       /*
-        * If no change in the hardlink's target directory is required and
-        * this is already a hardlink target, all we need to do is adjust
-        * the link count.
-        */
-       if (cdip == ip->pip &&
-           (ip->meta.name_key & HAMMER2_DIRHASH_VISIBLE) == 0) {
-               if (nlinks) {
-                       hammer2_inode_modify(ip);
-                       ip->meta.nlinks += nlinks;
-#if 0
-                       hammer2_cluster_modify(cluster, 0);
-                       wipdata = &hammer2_cluster_wdata(cluster)->ipdata;
-                       wipdata->meta.nlinks += nlinks;
-                       hammer2_cluster_modsync(cluster);
-                       ripdata = wipdata;
-#endif
-               }
-               error = 0;
-               goto done;
-       }
-
-       /*
-        * Cluster is the real inode.  The originating directory is locked
-        * by the caller so we can manipulate it without worrying about races
-        * against other lookups.
-        *
-        * If cluster is visible we need to delete it from the current
-        * location and create a hardlink pointer in its place.  If it is
-        * not visible we need only delete it.  Then later cluster will be
-        * renamed to a parent directory and converted (if necessary) to
-        * a hidden inode (via shiftup).
-        *
-        * NOTE! We must hold cparent locked through the delete/create/rename
-        *       operation to ensure that other threads block resolving to
-        *       the same hardlink, otherwise the other threads may not see
-        *       the hardlink.
-        */
-       KKASSERT((cluster->focus->flags & HAMMER2_CHAIN_DELETED) == 0);
-       cparent = hammer2_cluster_parent(cluster);
-
-       hammer2_cluster_delete(cparent, cluster, 0);
-
-       KKASSERT(ip->meta.type != HAMMER2_OBJTYPE_HARDLINK);
-       if (ip->meta.name_key & HAMMER2_DIRHASH_VISIBLE) {
-               const hammer2_inode_data_t *ripdata;
-               hammer2_inode_data_t *wipdata;
-               hammer2_cluster_t *ncluster;
-               hammer2_key_t lhc;
-
-               ncluster = NULL;
-               lhc = cluster->focus->bref.key;
-               error = hammer2_cluster_create(cparent, &ncluster,
-                                            lhc, 0,
-                                            HAMMER2_BREF_TYPE_INODE,
-                                            HAMMER2_INODE_BYTES,
-                                            0);
-               hammer2_cluster_modify(ncluster, 0);
-               wipdata = &hammer2_cluster_wdata(ncluster)->ipdata;
-
-               /* wipdata->meta.comp_algo = ip->meta.comp_algo; */
-               wipdata->meta.comp_algo = 0;
-               wipdata->meta.check_algo = 0;
-               wipdata->meta.version = HAMMER2_INODE_VERSION_ONE;
-               wipdata->meta.inum = ip->meta.inum;
-               wipdata->meta.target_type = ip->meta.type;
-               wipdata->meta.type = HAMMER2_OBJTYPE_HARDLINK;
-               wipdata->meta.uflags = 0;
-               wipdata->meta.rmajor = 0;
-               wipdata->meta.rminor = 0;
-               wipdata->meta.ctime = 0;
-               wipdata->meta.mtime = 0;
-               wipdata->meta.atime = 0;
-               wipdata->meta.btime = 0;
-               bzero(&wipdata->meta.uid, sizeof(wipdata->meta.uid));
-               bzero(&wipdata->meta.gid, sizeof(wipdata->meta.gid));
-               wipdata->meta.op_flags = HAMMER2_OPFLAG_DIRECTDATA;
-               wipdata->meta.cap_flags = 0;
-               wipdata->meta.mode = 0;
-               wipdata->meta.size = 0;
-               wipdata->meta.nlinks = 1;
-               wipdata->meta.iparent = 0;      /* XXX */
-               wipdata->meta.pfs_type = 0;
-               wipdata->meta.pfs_inum = 0;
-               bzero(&wipdata->meta.pfs_clid, sizeof(wipdata->meta.pfs_clid));
-               bzero(&wipdata->meta.pfs_fsid, sizeof(wipdata->meta.pfs_fsid));
-               wipdata->meta.data_quota = 0;
-               /* wipdata->data_count = 0; */
-               wipdata->meta.inode_quota = 0;
-               /* wipdata->inode_count = 0; */
-               wipdata->meta.attr_tid = 0;
-               wipdata->meta.dirent_tid = 0;
-               bzero(&wipdata->u, sizeof(wipdata->u));
-               ripdata = &hammer2_cluster_rdata(cluster)->ipdata;
-               KKASSERT(ip->meta.name_len <= sizeof(wipdata->filename));
-               bcopy(ripdata->filename, wipdata->filename,
-                     ip->meta.name_len);
-               wipdata->meta.name_key = ncluster->focus->bref.key;
-               wipdata->meta.name_len = ip->meta.name_len;
-               /* XXX transaction ids */
-               hammer2_cluster_modsync(ncluster);
-               hammer2_cluster_unlock(ncluster);
-               hammer2_cluster_drop(ncluster);
-       }
-
-       /*
-        * cluster represents the hardlink target and is now flagged deleted.
-        * duplicate it to the parent directory and adjust nlinks.
-        *
-        * WARNING! The shiftup() call can cause ncluster to be moved into
-        *          an indirect block, and our ncluster will wind up pointing
-        *          to the older/original version.
-        */
-       KKASSERT(cluster->focus->flags & HAMMER2_CHAIN_DELETED);
-       hammer2_chain_hardlink_shiftup(cluster, ip, cdip, cdcluster,
-                                        nlinks, &error);
-
-       if (error == 0)
-               hammer2_inode_repoint(ip, cdip, cluster);
-
-done:
-       /*
-        * Cleanup, cluster/ncluster already dealt with.
-        *
-        * Return the shifted cluster in *clusterp.
-        */
-       if (cparent) {
-               hammer2_cluster_unlock(cparent);
-               hammer2_cluster_drop(cparent);
-       }
-       *clusterp = cluster;
-
-       return (error);
-}
-
-/*
- * If (*ochainp) is non-NULL it points to the forward OBJTYPE_HARDLINK
- * inode while (*chainp) points to the resolved (hidden hardlink
- * target) inode.  In this situation when nlinks is 1 we wish to
- * deconsolidate the hardlink, moving it back to the directory that now
- * represents the only remaining link.
- */
-int
-hammer2_chain_hardlink_deconsolidate(
-                              hammer2_inode_t *dip,
-                              hammer2_chain_t **chainp,
-                              hammer2_chain_t **ochainp)
-{
-       if (*ochainp == NULL)
-               return (0);
-       /* XXX */
-       return (0);
-}
-
-#endif
-
 /*
  * The caller presents a shared-locked (parent, chain) where the chain
  * is of type HAMMER2_OBJTYPE_HARDLINK.  The caller must hold the ip
@@ -4336,7 +4046,8 @@ hammer2_chain_hardlink_deconsolidate(
 int
 hammer2_chain_hardlink_find(hammer2_inode_t *dip,
                        hammer2_chain_t **parentp,
-                       hammer2_chain_t **chainp)
+                       hammer2_chain_t **chainp,
+                       int flags)
 {
        hammer2_chain_t *parent;
        hammer2_chain_t *rchain;
@@ -4357,8 +4068,7 @@ hammer2_chain_hardlink_find(hammer2_inode_t *dip,
                int nloops;
                rchain = hammer2_chain_lookup(parentp, &key_dummy,
                                              lhc, lhc,
-                                             &cache_index,
-                                             HAMMER2_LOOKUP_SHARED);
+                                             &cache_index, flags);
                if (rchain)
                        break;
 
@@ -4374,13 +4084,15 @@ hammer2_chain_hardlink_find(hammer2_inode_t *dip,
                            parent->bref.type == HAMMER2_BREF_TYPE_INODE) {
                                nloops = 1;
                        }
+                       if (parent->bref.flags & HAMMER2_BREF_FLAG_PFSROOT)
+                               goto done;
+                       if (parent->parent == NULL)
+                               goto done;
                        parent = parent->parent;
-                       if (parent == NULL)
-                               break;
                        hammer2_chain_ref(parent);
                        hammer2_chain_unlock(*parentp);
                        hammer2_chain_lock(parent, HAMMER2_RESOLVE_ALWAYS |
-                                                  HAMMER2_RESOLVE_SHARED);
+                                                  flags);
                        if ((*parentp)->parent == parent) {
                                hammer2_chain_drop(*parentp);
                                *parentp = parent;
@@ -4389,12 +4101,14 @@ hammer2_chain_hardlink_find(hammer2_inode_t *dip,
                                hammer2_chain_drop(parent);
                                hammer2_chain_lock(*parentp,
                                                   HAMMER2_RESOLVE_ALWAYS |
-                                                  HAMMER2_RESOLVE_SHARED);
+                                                  flags);
                                parent = NULL;  /* safety */
+                               /* retry */
                        }
                }
        }
+done:
 
        *chainp = rchain;
-       return (rchain ? EIO : 0);
+       return (rchain ? EINVAL : 0);
 }