|
@@ -32,16 +32,51 @@
|
|
|
|
|
|
#define NFSDBG_FACILITY NFSDBG_PNFS
|
|
|
|
|
|
-/* STUB that returns the equivalent of "no module found" */
|
|
|
+/* Locking:
|
|
|
+ *
|
|
|
+ * pnfs_spinlock:
|
|
|
+ * protects pnfs_modules_tbl.
|
|
|
+ */
|
|
|
+static DEFINE_SPINLOCK(pnfs_spinlock);
|
|
|
+
|
|
|
+/*
|
|
|
+ * pnfs_modules_tbl holds all pnfs modules
|
|
|
+ */
|
|
|
+static LIST_HEAD(pnfs_modules_tbl);
|
|
|
+
|
|
|
+/* Return the registered pnfs layout driver module matching given id */
|
|
|
+static struct pnfs_layoutdriver_type *
|
|
|
+find_pnfs_driver_locked(u32 id)
|
|
|
+{
|
|
|
+ struct pnfs_layoutdriver_type *local;
|
|
|
+
|
|
|
+ list_for_each_entry(local, &pnfs_modules_tbl, pnfs_tblid)
|
|
|
+ if (local->id == id)
|
|
|
+ goto out;
|
|
|
+ local = NULL;
|
|
|
+out:
|
|
|
+ dprintk("%s: Searching for id %u, found %p\n", __func__, id, local);
|
|
|
+ return local;
|
|
|
+}
|
|
|
+
|
|
|
static struct pnfs_layoutdriver_type *
|
|
|
find_pnfs_driver(u32 id)
|
|
|
{
|
|
|
- return NULL;
|
|
|
+ struct pnfs_layoutdriver_type *local;
|
|
|
+
|
|
|
+ spin_lock(&pnfs_spinlock);
|
|
|
+ local = find_pnfs_driver_locked(id);
|
|
|
+ spin_unlock(&pnfs_spinlock);
|
|
|
+ return local;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
unset_pnfs_layoutdriver(struct nfs_server *nfss)
|
|
|
{
|
|
|
+ if (nfss->pnfs_curr_ld) {
|
|
|
+ nfss->pnfs_curr_ld->uninitialize_mountpoint(nfss);
|
|
|
+ module_put(nfss->pnfs_curr_ld->owner);
|
|
|
+ }
|
|
|
nfss->pnfs_curr_ld = NULL;
|
|
|
}
|
|
|
|
|
@@ -74,7 +109,18 @@ set_pnfs_layoutdriver(struct nfs_server *server, u32 id)
|
|
|
goto out_no_driver;
|
|
|
}
|
|
|
}
|
|
|
+ if (!try_module_get(ld_type->owner)) {
|
|
|
+ dprintk("%s: Could not grab reference on module\n", __func__);
|
|
|
+ goto out_no_driver;
|
|
|
+ }
|
|
|
server->pnfs_curr_ld = ld_type;
|
|
|
+ if (ld_type->initialize_mountpoint(server)) {
|
|
|
+ printk(KERN_ERR
|
|
|
+ "%s: Error initializing mount point for layout driver %u.\n",
|
|
|
+ __func__, id);
|
|
|
+ module_put(ld_type->owner);
|
|
|
+ goto out_no_driver;
|
|
|
+ }
|
|
|
dprintk("%s: pNFS module for %u set\n", __func__, id);
|
|
|
return;
|
|
|
|
|
@@ -82,3 +128,41 @@ out_no_driver:
|
|
|
dprintk("%s: Using NFSv4 I/O\n", __func__);
|
|
|
server->pnfs_curr_ld = NULL;
|
|
|
}
|
|
|
+
|
|
|
+int
|
|
|
+pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *ld_type)
|
|
|
+{
|
|
|
+ int status = -EINVAL;
|
|
|
+ struct pnfs_layoutdriver_type *tmp;
|
|
|
+
|
|
|
+ if (ld_type->id == 0) {
|
|
|
+ printk(KERN_ERR "%s id 0 is reserved\n", __func__);
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+
|
|
|
+ spin_lock(&pnfs_spinlock);
|
|
|
+ tmp = find_pnfs_driver_locked(ld_type->id);
|
|
|
+ if (!tmp) {
|
|
|
+ list_add(&ld_type->pnfs_tblid, &pnfs_modules_tbl);
|
|
|
+ status = 0;
|
|
|
+ dprintk("%s Registering id:%u name:%s\n", __func__, ld_type->id,
|
|
|
+ ld_type->name);
|
|
|
+ } else {
|
|
|
+ printk(KERN_ERR "%s Module with id %d already loaded!\n",
|
|
|
+ __func__, ld_type->id);
|
|
|
+ }
|
|
|
+ spin_unlock(&pnfs_spinlock);
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(pnfs_register_layoutdriver);
|
|
|
+
|
|
|
+void
|
|
|
+pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *ld_type)
|
|
|
+{
|
|
|
+ dprintk("%s Deregistering id:%u\n", __func__, ld_type->id);
|
|
|
+ spin_lock(&pnfs_spinlock);
|
|
|
+ list_del(&ld_type->pnfs_tblid);
|
|
|
+ spin_unlock(&pnfs_spinlock);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(pnfs_unregister_layoutdriver);
|