hammer2 - add HAMMER2IOC_PFS_LOOKUP
authorMatthew Dillon <dillon@apollo.backplane.com>
Tue, 7 Aug 2012 19:37:53 +0000 (12:37 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Tue, 7 Aug 2012 19:37:53 +0000 (12:37 -0700)
* Add the HAMMER2IOC_PFS_LOOKUP ioctl which looks up a specific PFS
  by name.

sys/vfs/hammer2/hammer2_ioctl.c
sys/vfs/hammer2/hammer2_ioctl.h

index 6ed6ca5..7df7e88 100644 (file)
@@ -50,6 +50,7 @@ static int hammer2_ioctl_remote_rep(hammer2_inode_t *ip, void *data);
 static int hammer2_ioctl_socket_get(hammer2_inode_t *ip, void *data);
 static int hammer2_ioctl_socket_set(hammer2_inode_t *ip, void *data);
 static int hammer2_ioctl_pfs_get(hammer2_inode_t *ip, void *data);
+static int hammer2_ioctl_pfs_lookup(hammer2_inode_t *ip, void *data);
 static int hammer2_ioctl_pfs_create(hammer2_inode_t *ip, void *data);
 static int hammer2_ioctl_pfs_delete(hammer2_inode_t *ip, void *data);
 static int hammer2_ioctl_inode_get(hammer2_inode_t *ip, void *data);
@@ -99,6 +100,10 @@ hammer2_ioctl(hammer2_inode_t *ip, u_long com, void *data, int fflag,
                if (error == 0)
                        error = hammer2_ioctl_pfs_get(ip, data);
                break;
+       case HAMMER2IOC_PFS_LOOKUP:
+               if (error == 0)
+                       error = hammer2_ioctl_pfs_lookup(ip, data);
+               break;
        case HAMMER2IOC_PFS_CREATE:
                if (error == 0)
                        error = hammer2_ioctl_pfs_create(ip, data);
@@ -353,6 +358,65 @@ done:
 }
 
 /*
+ * Find a specific PFS by name
+ */
+static int
+hammer2_ioctl_pfs_lookup(hammer2_inode_t *ip, void *data)
+{
+       hammer2_mount_t *hmp = ip->hmp;
+       hammer2_ioc_pfs_t *pfs = data;
+       hammer2_chain_t *parent;
+       hammer2_chain_t *chain;
+       hammer2_inode_t *xip;
+       hammer2_key_t lhc;
+       int error = 0;
+       size_t len;
+
+       parent = hmp->schain;
+       error = hammer2_chain_lock(hmp, parent, HAMMER2_RESOLVE_ALWAYS |
+                                               HAMMER2_RESOLVE_SHARED);
+       if (error)
+               goto done;
+
+       pfs->name[sizeof(pfs->name) - 1] = 0;
+       len = strlen(pfs->name);
+       lhc = hammer2_dirhash(pfs->name, len);
+
+       chain = hammer2_chain_lookup(hmp, &parent,
+                                    lhc, lhc + HAMMER2_DIRHASH_LOMASK,
+                                    HAMMER2_LOOKUP_SHARED);
+       while (chain) {
+               if (chain->bref.type == HAMMER2_BREF_TYPE_INODE &&
+                   chain->u.ip &&
+                   len == chain->data->ipdata.name_len &&
+                   bcmp(pfs->name, chain->data->ipdata.filename, len) == 0) {
+                       break;
+               }
+               chain = hammer2_chain_next(hmp, &parent, chain,
+                                          lhc, lhc + HAMMER2_DIRHASH_LOMASK,
+                                          HAMMER2_LOOKUP_SHARED);
+       }
+
+       /*
+        * Load the data being returned by the ioctl.
+        */
+       if (chain) {
+               xip = chain->u.ip;
+               pfs->name_key = xip->ip_data.name_key;
+               pfs->pfs_type = xip->ip_data.pfs_type;
+               pfs->pfs_clid = xip->ip_data.pfs_clid;
+               pfs->pfs_fsid = xip->ip_data.pfs_fsid;
+
+               hammer2_chain_unlock(hmp, chain);
+       } else {
+               error = ENOENT;
+       }
+done:
+       hammer2_chain_unlock(hmp, parent);
+       return (error);
+}
+
+/*
  * Create a new PFS under the super-root
  */
 static int
index 0dc8f2b..6d96b28 100644 (file)
@@ -126,6 +126,7 @@ typedef struct hammer2_ioc_inode hammer2_ioc_inode_t;
 #define HAMMER2IOC_PFS_GET     _IOWR('h', 80, struct hammer2_ioc_pfs)
 #define HAMMER2IOC_PFS_CREATE  _IOWR('h', 81, struct hammer2_ioc_pfs)
 #define HAMMER2IOC_PFS_DELETE  _IOWR('h', 82, struct hammer2_ioc_pfs)
+#define HAMMER2IOC_PFS_LOOKUP  _IOWR('h', 83, struct hammer2_ioc_pfs)
 
 #define HAMMER2IOC_INODE_GET   _IOWR('h', 86, struct hammer2_ioc_inode)
 #define HAMMER2IOC_INODE_SET   _IOWR('h', 87, struct hammer2_ioc_inode)