All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Corry <corryk@us.ibm.com>
To: torvalds@transmeta.com
Cc: linux-kernel@vger.kernel.org, evms-devel@lists.sourceforge.net
Subject: [PATCH] EVMS core (4/9) passthru.c
Date: Thu, 10 Oct 2002 14:37:14 -0500	[thread overview]
Message-ID: <02101014371406.17770@boiler> (raw)
In-Reply-To: <02101014305502.17770@boiler>

Greetings,

Part 4 of the EVMS core driver.

This file provides the Passthru pseudo-plugin, which simply recognizes
EVMS volume labels. It is always bound to the core driver instead of
being a full, separate plugin.

Kevin Corry
corryk@us.ibm.com
http://evms.sourceforge.net/



diff -Naur linux-2.5.41/drivers/evms/core/passthru.c linux-2.5.41-evms/drivers/evms/core/passthru.c
--- linux-2.5.41/drivers/evms/core/passthru.c	Wed Dec 31 18:00:00 1969
+++ linux-2.5.41-evms/drivers/evms/core/passthru.c	Thu Oct 10 11:16:58 2002
@@ -0,0 +1,373 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/*
+ * EVMS Volume Passthru Manager
+ *
+ * Passthru is a "special" EVMS plugin. It provides all of the services that
+ * a regular plugin provides (volume discovery/delete, I/O and ioctl handling)
+ * but it must always be loaded with the core. Thus, this plugin is not built
+ * as a separate kernel module (like the regular plugins). Instead, it is bound
+ * to the EVMS core module. It also does not have a module_init() or
+ * module_exit(). Instead, the EVMS core will call Passthru's init/exit
+ * functions manually when the core is loaded/unloaded. Also, since it is not a
+ * separate module, it will not do increments/decrements on the module reference
+ * count.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/bio.h>
+#include <linux/evms.h>
+
+#define LOG_PREFIX "passthru: "
+#define EVMS_PASSTHRU_ID 0
+
+static int passthru_discover(struct list_head *);
+static int passthru_delete(struct evms_logical_node *);
+static void passthru_submit_io(struct evms_logical_node *, struct bio *);
+static int passthru_ioctl(struct evms_logical_node *, struct inode *, 
+			  struct file *, unsigned int, unsigned long);
+static int passthru_init_io(struct evms_logical_node *, int, u64, u64, 
+			    void *);
+static int passthru_open(struct evms_logical_node *, struct inode *, 
+			 struct file *);
+static int passthru_release(struct evms_logical_node *, struct inode *, 
+			    struct file *);
+static int passthru_check_media_change(struct evms_logical_node *, kdev_t);
+static int passthru_revalidate(struct evms_logical_node *, kdev_t);
+static int passthru_quiesce(struct evms_logical_node *, int);
+static int passthru_get_geo(struct evms_logical_node *, u64 *, uint *, 
+			    uint *, u64 *);
+static int passthru_device_list(struct evms_logical_node *, 
+				struct list_head *);
+static int passthru_device_status(struct evms_logical_node *, int *);
+
+static struct evms_plugin_fops fops = {
+	.discover	= passthru_discover,
+	.delete		= passthru_delete,
+	.submit_io	= passthru_submit_io,
+	.sync_io	= passthru_init_io,
+	.ioctl		= passthru_ioctl,
+	.open		= passthru_open,
+	.release	= passthru_release,
+	.check_media_change = passthru_check_media_change,
+	.revalidate	= passthru_revalidate,
+	.quiesce	= passthru_quiesce,
+	.get_geo	= passthru_get_geo,
+	.device_list	= passthru_device_list,
+	.device_status	= passthru_device_status
+};
+
+static struct evms_plugin_header plugin_header = {
+	.id = SetPluginID(IBM_OEM_ID,
+			  EVMS_FEATURE,
+			  EVMS_PASSTHRU_ID),
+	.version = {
+		.major		= 1,
+		.minor		= 1,
+		.patchlevel	= 1
+	},
+	.fops = &fops
+};
+
+/*******************************/
+/* Discovery support functions */
+/*******************************/
+
+static int
+process_passthru_data(struct evms_logical_node **pp)
+{
+	int rc, size_in_sectors;
+	struct evms_logical_node *node, *new_node;
+
+	node = *pp;
+
+	size_in_sectors =
+	    evms_cs_size_in_vsectors(sizeof (struct evms_feature_header));
+
+	/* allocate "parent" node */
+	rc = evms_cs_allocate_logical_node(&new_node);
+	if (rc) {
+		/* on any fatal error, delete the node */
+		int rc2 = DELETE(node);
+		if (rc2) {
+			LOG_DEFAULT("error(%d) attempting to delete node(%s)\n",
+				    rc2, node->name);
+		}
+		return rc;
+	}
+	/* initialize "parent" node */
+	new_node->private = node;
+	new_node->flags = node->flags;
+	new_node->plugin = &plugin_header;
+	new_node->system_id = node->system_id;
+	new_node->block_size = node->block_size;
+	new_node->hardsector_size = node->hardsector_size;
+	new_node->total_vsectors = node->total_vsectors;
+	new_node->total_vsectors -= (size_in_sectors << 1) +
+				     node->feature_header->alignment_padding;
+	new_node->volume_info = node->volume_info;
+	strcpy(new_node->name, node->name);
+	if (strlen(node->feature_header->object_name))
+		strcat(new_node->name,
+		       node->feature_header->object_name);
+	else
+		strcat(new_node->name, "_Passthru");
+        /* return "parent" node to caller */
+	*pp = new_node;
+
+	LOG_DETAILS("feature header found on '%s', created '%s'.\n",
+		    node->name, new_node->name);
+	/* we're done with the passthru feature headers
+	 * so lets delete them now.
+	 */
+	kfree(node->feature_header);
+	node->feature_header = NULL;
+	return 0;
+}
+
+/********** Required Plugin Functions **********/
+
+/**
+ * passthru_discover
+ **/
+static int
+passthru_discover(struct list_head *discover_list)
+{
+	struct evms_logical_node *node, *next_node;
+	struct list_head tmp_list_head;
+
+	INIT_LIST_HEAD(&tmp_list_head);
+	list_splice_init(discover_list, &tmp_list_head);
+	list_for_each_entry_safe(node, next_node, &tmp_list_head, discover) {
+		list_del_init(&node->discover);
+		if (!process_passthru_data(&node)) {
+			if (node) {
+				list_add_tail(&node->discover, discover_list);
+			}
+		}
+	}
+	return 0;
+}
+
+/**
+ * passthru_delete
+ **/
+static int
+passthru_delete(struct evms_logical_node *node)
+{
+	int rc;
+	struct evms_logical_node *p;
+
+	LOG_DETAILS("deleting '%s'.\n", node->name);
+
+	p = node->private;
+	rc = DELETE(p);
+	if (!rc) {
+		evms_cs_deallocate_logical_node(node);
+	} else {
+		LOG_DEFAULT("error(%d) attempting to delete node(%s).\n",
+			    rc, node->name);
+	}
+	return rc;
+}
+
+/**
+ * passthru_submit_io
+ **/
+static void
+passthru_submit_io(struct evms_logical_node *node, struct bio *bio)
+{
+	if (bio->bi_sector + bio_sectors(bio) <= node->total_vsectors) {
+		SUBMIT_IO((struct evms_logical_node *) (node->private), bio);
+	} else {
+		LOG_SERIOUS("I/O request on (%s) at rsector ("PFU64") "
+			    "beyond boundary ("PFU64").\n",
+			    node->name, node->total_vsectors - 1,
+			    (u64) bio->bi_sector);
+		bio_io_error(bio, bio->bi_size);
+	}
+}
+
+/**
+ * passthru_ioctl
+ **/
+static int
+passthru_ioctl(struct evms_logical_node *node, struct inode *inode,
+		   struct file *file, unsigned int cmd, unsigned long arg)
+{
+	return IOCTL(((struct evms_logical_node *) (node->private)),
+		     inode, file, cmd, arg);
+}
+
+/**
+ * passthru_init_io
+ **/
+static int
+passthru_init_io(struct evms_logical_node *node, int rw,
+		     u64 sect_nr, u64 num_sects, void *buf_addr)
+{
+	if (sect_nr + num_sects > node->total_vsectors) {
+		return -EINVAL;
+	}
+
+	return INIT_IO(((struct evms_logical_node *) (node->private)),
+			rw, sect_nr, num_sects, buf_addr);
+}
+
+/**
+ * passthru_open - route operation to node
+ * @node:	target node
+ * @inode:     	VFS required parameter
+ * @file:     	VFS required parameter
+ *
+ * returns:
+ *	0 on success
+ *	error code otherwise
+ */
+static int
+passthru_open(struct evms_logical_node *node,
+	       struct inode *inode, struct file *file)
+{
+	return OPEN((struct evms_logical_node *)node->private, inode, file);
+}
+
+/**
+ * passthru_release - route operation to node
+ * @node:	target node
+ * @inode:     	VFS required parameter
+ * @file:     	VFS required parameter
+ *
+ * returns:
+ *	0 on success
+ *	error code otherwise
+ */
+static int
+passthru_release(struct evms_logical_node *node,
+	       struct inode *inode, struct file *file)
+{
+	return CLOSE((struct evms_logical_node *)node->private, inode, file);
+}
+
+/**
+ * passthru_check_media_change - route operation to node
+ * @node:	target node
+ * @dev:       	VFS required parameter
+ *
+ * returns:
+ *	0 on no change detected,
+ *	1 on change detected,
+ *	error code otherwise
+ */
+static int
+passthru_check_media_change(struct evms_logical_node *node, kdev_t dev)
+{
+	return CHECK_MEDIA_CHANGE((struct evms_logical_node *)node->private, dev);
+}
+
+/**
+ * passthru_revalidate - route operation to node
+ * @node:	target node
+ * @dev:       	VFS required parameter
+ *
+ * returns:
+ *	0 on success
+ *	error code otherwise
+ */
+static int
+passthru_revalidate(struct evms_logical_node *node, kdev_t dev)
+{
+	return REVALIDATE((struct evms_logical_node *)node->private, dev);
+}
+
+/**
+ * passthru_quiesce - route operation to node
+ * @node:	target node
+ * @dev:       	VFS required parameter
+ *
+ * returns:
+ *	0 on success
+ *	error code otherwise
+ */
+static int
+passthru_quiesce(struct evms_logical_node *node, int command)
+{
+	return QUIESCE((struct evms_logical_node *)node->private, command);
+}
+
+/**
+ * passthru_get_geo - route operation to node
+ * @node:	target node
+ * @dev:       	VFS required parameter
+ *
+ * returns:
+ *	0 on success
+ *	error code otherwise
+ */
+static int
+passthru_get_geo(struct evms_logical_node *node, u64 *cylinders,
+		    uint *heads, uint *sects, u64 *start)
+{
+	return GET_GEO((struct evms_logical_node *)node->private, 
+			cylinders, heads, sects, start);
+}
+
+/**
+ * passthru_device_list - route operation to node
+ * @node:	target node
+ * @dev:       	VFS required parameter
+ *
+ * returns:
+ *	0 on success
+ *	error code otherwise
+ */
+static int
+passthru_device_list(struct evms_logical_node *node, struct list_head *list)
+{
+	return DEVICE_LIST((struct evms_logical_node *)node->private, list);
+}
+
+/**
+ * passthru_device_status - route operation to node
+ * @node:	target node
+ * @dev:       	VFS required parameter
+ *
+ * returns:
+ *	0 on success
+ *	error code otherwise
+ */
+static int
+passthru_device_status(struct evms_logical_node *node, int *status)
+{
+	return DEVICE_STATUS((struct evms_logical_node *)node->private, 
+			     status);
+}
+
+int
+evms_passthru_init(void)
+{
+	return evms_cs_register_plugin(&plugin_header);
+}
+
+void
+evms_passthru_exit(void)
+{
+	evms_cs_unregister_plugin(&plugin_header);
+}
+

  parent reply	other threads:[~2002-10-10 20:17 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-10-10 19:30 [PATCH] EVMS core (0/9) Kevin Corry
2002-10-10 19:35 ` [PATCH] EVMS core (1/9) evms.c Kevin Corry
2002-10-10 19:35 ` [PATCH] EVMS core (2/9) services.c Kevin Corry
2002-10-10 19:35 ` [PATCH] EVMS core (3/9) discover.c Kevin Corry
2002-10-10 19:37 ` Kevin Corry [this message]
2002-10-10 19:37 ` [PATCH] EVMS core (5/9) evms_core.h Kevin Corry
2002-10-10 19:37 ` [PATCH] EVMS core (6/9) evms.h Kevin Corry
2002-10-10 19:39 ` [PATCH] EVMS core (7/9) evms_ioctl.h Kevin Corry
2002-10-10 19:39 ` [PATCH] EVMS core (8/9) evms_biosplit.h Kevin Corry
2002-10-10 19:39 ` [PATCH] EVMS core (9/9) misc Kevin Corry

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=02101014371406.17770@boiler \
    --to=corryk@us.ibm.com \
    --cc=evms-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.