SOURCES (LINUX_2_6): ocfs2-2005.06.17.patch (NEW) - ocfs2 [beta] f...

cieciwa cieciwa at pld-linux.org
Thu Jun 30 11:59:08 CEST 2005


Author: cieciwa                      Date: Thu Jun 30 09:59:08 2005 GMT
Module: SOURCES                       Tag: LINUX_2_6
---- Log message:
- ocfs2 [beta] from Oracle.

---- Files affected:
SOURCES:
   ocfs2-2005.06.17.patch (NONE -> 1.1.2.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/ocfs2-2005.06.17.patch
diff -u /dev/null SOURCES/ocfs2-2005.06.17.patch:1.1.2.1
--- /dev/null	Thu Jun 30 11:59:08 2005
+++ SOURCES/ocfs2-2005.06.17.patch	Thu Jun 30 11:59:03 2005
@@ -0,0 +1,45262 @@
+diff -Nur --exclude '*.orig' linux-2.6.12.1.org/Documentation/filesystems/00-INDEX linux-2.6.12.1/Documentation/filesystems/00-INDEX
+--- linux-2.6.12.1.org/Documentation/filesystems/00-INDEX	2005-06-22 21:33:05.000000000 +0200
++++ linux-2.6.12.1/Documentation/filesystems/00-INDEX	2005-06-30 11:53:12.613534856 +0200
+@@ -12,10 +12,14 @@
+ 	- description of the CIFS filesystem
+ coda.txt
+ 	- description of the CODA filesystem.
++configfs/
++	- directory containing configfs documentation and example code.
+ cramfs.txt
+ 	- info on the cram filesystem for small storage (ROMs etc)
+ devfs/
+ 	- directory containing devfs documentation.
++dlmfs.txt
++	- info on the userspace interface to the OCFS2 DLM.
+ ext2.txt
+ 	- info, mount options and specifications for the Ext2 filesystem.
+ fat_cvf.txt
+@@ -32,6 +36,8 @@
+ 	- info and mount options for the NTFS filesystem (Windows NT).
+ proc.txt
+ 	- info on Linux's /proc filesystem.
++ocfs2.txt
++	- info and mount options for the OCFS2 clustered filesystem.
+ romfs.txt
+ 	- Description of the ROMFS filesystem.
+ smbfs.txt
+diff -Nur --exclude '*.orig' linux-2.6.12.1.org/Documentation/filesystems/configfs/configfs.txt linux-2.6.12.1/Documentation/filesystems/configfs/configfs.txt
+--- linux-2.6.12.1.org/Documentation/filesystems/configfs/configfs.txt	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.12.1/Documentation/filesystems/configfs/configfs.txt	2005-06-30 11:52:37.784829624 +0200
+@@ -0,0 +1,434 @@
++
++configfs - Userspace-driven kernel object configuation.
++
++Joel Becker <joel.becker at oracle.com>
++
++Updated: 31 March 2005
++
++Copyright (c) 2005 Oracle Corporation,
++	Joel Becker <joel.becker at oracle.com>
++
++
++[What is configfs?]
++
++configfs is a ram-based filesystem that provides the converse of
++sysfs's functionality.  Where sysfs is a filesystem-based view of
++kernel objects, configfs is a filesystem-based manager of kernel
++objects, or config_items.
++
++With sysfs, an object is created in kernel (for example, when a device
++is discovered) and it is registered with sysfs.  Its attributes then
++appear in sysfs, allowing userspace to read the attributes via
++readdir(3)/read(2).  It may allow some attributes to be modified via
++write(2).  The important point is that the object is created and
++destroyed in kernel, the kernel controls the lifecycle of the sysfs
++representation, and sysfs is merely a window on all this.
++
++A configfs config_item is created via an explicit userspace operation:
++mkdir(2).  It is destroyed via rmdir(2).  The attributes appear at
++mkdir(2) time, and can be read or modified via read(2) and write(2).
++As with sysfs, readdir(3) queries the list of items and/or attributes.
++symlink(2) can be used to group items together.  Unlike sysfs, the
++lifetime of the representation is completely driven by userspace.  The
++kernel modules backing the items must respond to this.
++
++Both sysfs and configfs can and should exist together on the same
++system.  One is not a replacement for the other.
++
++[Using configfs]
++
++configfs can be compiled as a module or into the kernel.  You can access
++it by doing
++
++	mount -t configfs none /config
++
++The configfs tree will be empty unless client modules are also loaded.
++These are modules that register their item types with configfs as
++subsystems.  Once a client subsystem is loaded, it will appear as a
++subdirectory (or more than one) under /config.  Like sysfs, the
++configfs tree is always there, whether mounted on /config or not.
++
++An item is created via mkdir(2).  The item's attributes will also
++appear at this time.  readdir(3) can determine what the attributes are,
++read(2) can query their default values, and write(2) can store new
++values.  Like sysfs, attributes should be ASCII text files, preferably
++with only one value per file.  The same efficiency caveats from sysfs
++apply.  Don't mix more than one attribute in one attribute file.
++
++Like sysfs, configfs expects write(2) to store the entire buffer at
++once.  When writing to configfs attributes, userspace processes should
++first read the entire file, modify the portions they wish to change, and
++then write the entire buffer back.  Attribute files have a maximum size
++of one page (PAGE_SIZE, 4096 on i386).
++
++When an item needs to be destroyed, remove it with rmdir(2).  An
++item cannot be destroyed if any other item has a link to it (via
++symlink(2)).  Links can be removed via unlink(2).
++
++[Configuring FakeNBD: an Example]
++
++Imagine there's a Network Block Device (NBD) driver that allows you to
++access remote block devices.  Call it FakeNBD.  FakeNBD uses configfs
++for its configuration.  Obviously, there will be a nice program that
++sysadmins use to configure FakeNBD, but somehow that program has to tell
++the driver about it.  Here's where configfs comes in.
++
++When the FakeNBD driver is loaded, it registers itself with configfs.
++readdir(3) sees this just fine:
++
++	# ls /config
++	fakenbd
++
++A fakenbd connection can be created with mkdir(2).  The name is
++arbitrary, but likely the tool will make some use of the name.  Perhaps
++it is a uuid or a disk name:
++
++	# mkdir /config/fakenbd/disk1
++	# ls /config/fakenbd/disk1
++	target device rw
++
++The target attribute contains the IP address of the server FakeNBD will
++connect to.  The device attribute is the device on the server.
++Predictably, the rw attribute determines whether the connection is
++read-only or read-write.
++
++	# echo 10.0.0.1 > /config/fakenbd/disk1/target
++	# echo /dev/sda1 > /config/fakenbd/disk1/device
++	# echo 1 > /config/fakenbd/disk1/rw
++
++That's it.  That's all there is.  Now the device is configured, via the
++shell no less.
++
++[Coding With configfs]
++
++Every object in configfs is a config_item.  A config_item reflects an
++object in the subsystem.  It has attributes that match values on that
++object.  configfs handles the filesystem representation of that object
++and its attributes, allowing the subsystem to ignore all but the
++basic show/store interaction.
++
++Items are created and destroyed inside a config_group.  A group is a
++collection of items that share the same attributes and operations.
++Items are created by mkdir(2) and removed by rmdir(2), but configfs
++handles that.  The group has a set of operations to perform these tasks
++
++A subsystem is the top level of a client module.  During initialization,
++the client module registers the subsystem with configfs, the subsystem
++appears as a directory at the top of the configfs filesystem.  A
++subsystem is also a config_group, and can do everything a config_group
++can.
++
++[struct config_item]
++
++	struct config_item {
++		char                    *ci_name;
++		char                    ci_namebuf[UOBJ_NAME_LEN];
++		struct kref             ci_kref;
++		struct list_head        ci_entry;
++		struct config_item      *ci_parent;
++		struct config_group     *ci_group;
++		struct config_item_type *ci_type;
++		struct dentry           *ci_dentry;
++	};
++
++	void config_item_init(struct config_item *);
++	void config_item_init_type_name(struct config_item *,
++					const char *name,
++					struct config_item_type *type);
++	struct config_item *config_item_get(struct config_item *);
++	void config_item_put(struct config_item *);
++
++Generally, struct config_item is embedded in a container structure, a
++structure that actually represents what the subsystem is doing.  The
++config_item portion of that structure is how the object interacts with
++configfs.
++
++Whether statically defined in a source file or created by a parent
++config_group, a config_item must have one of the _init() functions
++called on it.  This initializes the reference count and sets up the
++appropriate fields.
++
++All users of a config_item should have a reference on it via
++config_item_get(), and drop the reference when they are done via
++config_item_put().
++
++By itself, a config_item cannot do much more than appear in configfs.
++Usually a subsystem wants the item to display and/or store attributes,
++among other things.  For that, it needs a type.
++
++[struct config_item_type]
++
++	struct configfs_item_operations {
++		void (*release)(struct config_item *);
++		ssize_t (*show_attribute)(struct config_item *,
++					  struct configfs_attribute *,
++					  char *);
++		ssize_t (*store_attribute)(struct config_item *,
++					   struct configfs_attribute *,
++					   const char *, size_t);
++		int (*allow_link)(struct config_item *src,
++				  struct config_item *target);
++		int (*drop_link)(struct config_item *src,
++				 struct config_item *target);
++	};
++
++	struct config_item_type {
++		struct module                           *ct_owner;
++		struct configfs_item_operations         *ct_item_ops;
++		struct configfs_group_operations        *ct_group_ops;
++		struct configfs_attribute               **ct_attrs;
++	};
++
++The most basic function of a config_item_type is to define what
++operations can be performed on a config_item.  All items that have been
++allocated dynamically will need to provide the ct_item_ops->release()
++method.  This method is called when the config_item's reference count
++reaches zero.  Items that wish to display an attribute need to provide
++the ct_item_ops->show_attribute() method.  Similarly, storing a new
++attribute value uses the store_attribute() method.
++
++[struct configfs_attribute]
++
++	struct configfs_attribute {
++		char                    *ca_name;
++		struct module           *ca_owner;
++		mode_t                  ca_mode;
++	};
++
++When a config_item wants an attribute to appear as a file in the item's
++configfs directory, it must define a configfs_attribute describing it.
++It then adds the attribute to the NULL-terminated array
++config_item_type->ct_attrs.  When the item appears in configfs, the
++attribute file will appear with the configfs_attribute->ca_name
++filename.  configfs_attribute->ca_mode specifies the file permissions.
++
++If an attribute is readable and the config_item provides a
++ct_item_ops->show_attribute() method, that method will be called
++whenever userspace asks for a read(2) on the attribute.  The converse
++will happen for write(2).
++
++[struct config_group]
++
++A config_item cannot live in a vaccum.  The only way one can be created
++is via mkdir(2) on a config_group.  This will trigger creation of a
++child item.
++
++	struct config_group {
++		struct config_item		cg_item;
++		struct list_head		cg_children;
++		struct configfs_subsystem 	*cg_subsys;
++		struct config_group		**default_groups;
++	};
++
++	void config_group_init(struct config_group *group);
++	void config_group_init_type_name(struct config_group *group,
++					 const char *name,
++					 struct config_item_type *type);
++
++
++The config_group structure contains a config_item.  Properly configuring
++that item means that a group can behave as an item in its own right.
++However, it can do more: it can create child items or groups.  This is
++accomplished via the group operations specified on the group's
++config_item_type.
++
++	struct configfs_group_operations {
++		struct config_item *(*make_item)(struct config_group *group,
++						 const char *name);
++		struct config_group *(*make_group)(struct config_group *group,
++						   const char *name);
++		int (*commit_item)(struct config_item *item);
++		void (*drop_item)(struct config_group *group,
++				  struct config_item *item);
++	};
++
++A group creates child items by providing the
++ct_group_ops->make_item() method.  If provided, this method is called from mkdir(2) in the group's directory.  The subsystem allocates a new
++config_item (or more likely, its container structure), initializes it,
++and returns it to configfs.  Configfs will then populate the filesystem
++tree to reflect the new item.
++
++If the subsystem wants the child to be a group itself, the subsystem
++provides ct_group_ops->make_group().  Everything else behaves the same,
++using the group _init() functions on the group.
++
++Finally, when userspace calls rmdir(2) on the item or group,
++ct_group_ops->drop_item() is called.  As a config_group is also a
++config_item, it is not necessary for a seperate drop_group() method.
++The subsystem must config_item_put() the reference that was initialized
++upon item allocation.  If a subsystem has no work to do, it may omit
++the ct_group_ops->drop_item() method, and configfs will call
++config_item_put() on the item on behalf of the subsystem.
++
++IMPORTANT: drop_item() is void, and as such cannot fail.  When rmdir(2)
++is called, configfs WILL remove the item from the filesystem tree
++(assuming that it has no children to keep it busy).  The subsystem is
++responsible for responding to this.  If the subsystem has references to
++the item in other threads, the memory is safe.  It may take some time
++for the item to actually disappear from the subsystem's usage.  But it
++is gone from configfs.
++
++A config_group cannot be removed while it still has child items.  This
++is implemented in the configfs rmdir(2) code.  ->drop_item() will not be
++called, as the item has not been dropped.  rmdir(2) will fail, as the
++directory is not empty.
++
++[struct configfs_subsystem]
++
++A subsystem must register itself, ususally at module_init time.  This
++tells configfs to make the subsystem appear in the file tree.
++
++	struct configfs_subsystem {
++		struct config_group	su_group;
++		struct semaphore	su_sem;
++	};
++
++	int configfs_register_subsystem(struct configfs_subsystem *subsys);
++	void configfs_unregister_subsystem(struct configfs_subsystem *subsys);
++
++	A subsystem consists of a toplevel config_group and a semaphore.
++The group is where child config_items are created.  For a subsystem,
++this group is usually defined statically.  Before calling
++configfs_register_subsystem(), the subsystem must have initialized the
++group via the usual group _init() functions, and it must also have
++initialized the semaphore.
++	When the register call returns, the subsystem is live, and it
++will be visible via configfs.  At that point, mkdir(2) can be called and
++the subsystem must be ready for it.
++
++[An Example]
++
++The best example of these basic concepts is the simple_children
++subsystem/group and the simple_child item in configfs_example.c  It
++shows a trivial object displaying and storing an attribute, and a simple
++group creating and destroying these children.
++
++[Hierarchy Navigation and the Subsystem Semaphore]
++
++There is an extra bonus that configfs provides.  The config_groups and
++config_items are arranged in a hierarchy due to the fact that they
++appear in a filesystem.  A subsystem is NEVER to touch the filesystem
++parts, but the subsystem might be interested in this hierarchy.  For
++this reason, the hierarchy is mirrored via the config_group->cg_children
++and config_item->ci_parent structure members.
++
++A subsystem can navigate the cg_children list and the ci_parent pointer
++to see the tree created by the subsystem.  This can race with configfs'
++management of the hierarchy, so configfs uses the subsystem semaphore to
++protect modifications.  Whenever a subsystem wants to navigate the
++hierarchy, it must do so under the protection of the subsystem
++semaphore.
++
++A subsystem will be prevented from acquiring the semaphore while a newly
++allocated item has not been linked into this hierarchy.   Similarly, it
++will not be able to acquire the semaphore while a dropping item has not
++yet been unlinked.  This means that an item's ci_parent pointer will
++never be NULL while the item is in configfs, and that an item will only
++be in its parent's cg_children list for the same duration.  This allows
++a subsystem to trust ci_parent and cg_children while they hold the
++semaphore.
++
++[Item Aggregation Via symlink(2)]
++
++configfs provides a simple group via the group->item parent/child
++relationship.  Often, however, a larger environment requires aggregation
++outside of the parent/child connection.  This is implemented via
++symlink(2).
++
++A config_item may provide the ct_item_ops->allow_link() and
++ct_item_ops->drop_link() methods.  If the ->allow_link() method exists,
++symlink(2) may be called with the config_item as the source of the link.
++These links are only allowed between configfs config_items.  Any
++symlink(2) attempt outside the configfs filesystem will be denied.
++
++When symlink(2) is called, the source config_item's ->allow_link()
++method is called with itself and a target item.  If the source item
++allows linking to target item, it returns 0.  A source item may wish to
++reject a link if it only wants links to a certain type of object (say,
++in its own subsystem).
++
++When unlink(2) is called on the symbolic link, the source item is
++notified via the ->drop_link() method.  Like the ->drop_item() method,
++this is a void function and cannot return failure.  The subsystem is
++responsible for responding to the change.
++
++A config_item cannot be removed while it links to any other item, nor
++can it be removed while an item links to it.  Dangling symlinks are not
++allowed in configfs.
++
++[Automatically Created Subgroups]
++
++A new config_group may want to have two types of child config_items.
++While this could be codified by magic names in ->make_item(), it is much
++more explicit to have a method whereby userspace sees this divergence.
++
++Rather than have a group where some items behave differently than
++others, configfs provides a method whereby one or many subgroups are
++automatically created inside the parent at its creation.  Thus,
++mkdir("parent) results in "parent", "parent/subgroup1", up through
++"parent/subgroupN".  Items of type 1 can now be created in
++"parent/subgroup1", and items of type N can be created in
++"parent/subgroupN".
++
++These automatic subgroups, or default groups, do not preclude other
++children of the parent group.  If ct_group_ops->make_group() exists,
++other child groups can be created on the parent group directly.
++
++A configfs subsystem specifies default groups by filling in the
++NULL-terminated array default_groups on the config_group structure.
++Each group in that array is populated in the configfs tree at the same
++time as the parent group.  Similarly, they are removed at the same time
++as the parent.  No extra notification is provided.  When a ->drop_item()
++method call notifies the subsystem the parent group is going away, it
++also means every default group child associated with that parent group.
++
++As a consequence of this, default_groups cannot be removed directly via
++rmdir(2).  They also are not considered when rmdir(2) on the parent
++group is checking for children.
++
++[Committable Items]
++
++NOTE: Committable items are currently unimplemented.
++
++Some config_items cannot have a valid initial state.  That is, no
++default values can be specified for the item's attributes such that the
++item can do its work.  Userspace must configure one or more attributes,
++after which the subsystem can start whatever entity this item
++represents.
++
++Consider the FakeNBD device from above.  Without a target address *and*
++a target device, the subsystem has no idea what block device to import.
++The simple example assumes that the subsystem merely waits until all the
++appropriate attributes are configured, and then connects.  This will,
++indeed, work, but now every attribute store must check if the attributes
++are initialized.  Every attribute store must fire off the connection if
++that condition is met.
++
++Far better would be an explicit action notifying the subsystem that the
++config_item is ready to go.  More importantly, an explicit action allows
++the subsystem to provide feedback as to whether the attibutes are
++initialized in a way that makes sense.  configfs provides this as
++committable items.
++
++configfs still uses only normal filesystem operations.  An item is
++committed via rename(2).  The item is moved from a directory where it
++can be modified to a directory where it cannot.
++
++Any group that provides the ct_group_ops->commit_item() method has
++committable items.  When this group appears in configfs, mkdir(2) will
++not work directly in the group.  Instead, the group will have two
++subdirectories: "live" and "pending".  The "live" directory does not
++support mkdir(2) or rmdir(2) either.  It only allows rename(2).  The
++"pending" directory does allow mkdir(2) and rmdir(2).  An item is
++created in the "pending" directory.  Its attributes can be modified at
++will.  Userspace commits the item by renaming it into the "live"
++directory.  At this point, the subsystem recieves the ->commit_item()
++callback.  If all required attributes are filled to satisfaction, the
++method returns zero and the item is moved to the "live" directory.
++
++As rmdir(2) does not work in the "live" directory, an item must be
++shutdown, or "uncommitted".  Again, this is done via rename(2), this
++time from the "live" directory back to the "pending" one.  The subsystem
++is notified by the ct_group_ops->uncommit_object() method.
++
++
+diff -Nur --exclude '*.orig' linux-2.6.12.1.org/Documentation/filesystems/configfs/configfs_example.c linux-2.6.12.1/Documentation/filesystems/configfs/configfs_example.c
+--- linux-2.6.12.1.org/Documentation/filesystems/configfs/configfs_example.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.12.1/Documentation/filesystems/configfs/configfs_example.c	2005-06-30 11:52:37.786829320 +0200
+@@ -0,0 +1,474 @@
++/*
++ * vim: noexpandtab ts=8 sts=0 sw=8:
++ *
++ * configfs_example.c - This file is a demonstration module containing
++ *      a number of configfs subsystems.
++ *
++ * 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 021110-1307, USA.
++ *
++ * Based on sysfs:
++ * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
++ *
++ * configfs Copyright (C) 2005 Oracle.  All rights reserved.
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++
++#include <linux/configfs.h>
++
++
++
++/*
++ * 01-childless
++ *
++ * This first example is a childless subsystem.  It cannot create
++ * any config_items.  It just has attributes.  
++ *
++ * Note that we are enclosing the configfs_subsystem inside a container.
++ * This is not necessary if a subsystem has no attributes directly
++ * on the subsystem.  See the next example, 02-simple-children, for
++ * such a subsystem.
++ */
++
++struct childless {
++	struct configfs_subsystem subsys;
++	int showme;
++	int storeme;
++};
++
++struct childless_attribute {
++	struct configfs_attribute attr;
++	ssize_t (*show)(struct childless *, char *);
++	ssize_t (*store)(struct childless *, const char *, size_t);
++};
++
++static inline struct childless *to_childless(struct config_item *item)
++{
++	return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
++}
++
++static ssize_t childless_showme_read(struct childless *childless,
++				     char *page)
++{
++	ssize_t pos;
++
++	pos = sprintf(page, "%d\n", childless->showme);
++	childless->showme++;
++
++	return pos;
++}
++
++static ssize_t childless_storeme_read(struct childless *childless,
++				      char *page)
++{
++	return sprintf(page, "%d\n", childless->storeme);
++}
++
++static ssize_t childless_storeme_write(struct childless *childless,
++				       const char *page,
++				       size_t count)
++{
++	unsigned long tmp;
++	char *p = (char *) page;
++
++	tmp = simple_strtoul(p, &p, 10);
++	if (!p || (*p && (*p != '\n')))
++		return -EINVAL;
++
++	if (tmp > INT_MAX)
++		return -ERANGE;
++
++	childless->storeme = tmp;
++
++	return count;
++}
++
++static ssize_t childless_description_read(struct childless *childless,
++					  char *page)
++{
++	return sprintf(page,
++"[01-childless]\n"
++"\n"
++"The childless subsystem is the simplest possible subsystem in\n"
++"configfs.  It does not support the creation of child config_items.\n"
++"It only has a few attributes.  In fact, it isn't much different\n"
++"than a directory in /proc.\n");
++}
++
++static struct childless_attribute childless_attr_showme = {
++	.attr	= { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO },
++	.show	= childless_showme_read,
++};
++static struct childless_attribute childless_attr_storeme = {
++	.attr	= { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR },
++	.show	= childless_storeme_read,
++	.store	= childless_storeme_write,
++};
++static struct childless_attribute childless_attr_description = {
<<Diff was trimmed, longer than 597 lines>>



More information about the pld-cvs-commit mailing list