All of lore.kernel.org
 help / color / mirror / Atom feed
From: kupcevic@sourceware.org <kupcevic@sourceware.org>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] conga ricci/modules/storage/Makefile luci/site ...
Date: 26 Sep 2006 03:17:43 -0000	[thread overview]
Message-ID: <20060926031743.2219.qmail@sourceware.org> (raw)

CVSROOT:	/cvs/cluster
Module name:	conga
Changes by:	kupcevic at sourceware.org	2006-09-26 03:17:41

Modified files:
	ricci/modules/storage: Makefile 
	luci/site/luci/Extensions: conga_storage_constants.py 
	                           StorageReport.py 
Added files:
	ricci/modules/storage: GFS1.cpp GFS1.h GFS2.cpp GFS2.h 
	                       UnsupportedFS.cpp UnsupportedFS.h 
	                       gfs2_ondisk.h gfs_ondisk.h 

Log message:
	storage module: add full GFS1/2 support, and detection of multiple other filesystems (so they don't get overwriten)

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/GFS1.cpp.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/GFS1.h.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/GFS2.cpp.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/GFS2.h.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/UnsupportedFS.cpp.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/UnsupportedFS.h.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/gfs2_ondisk.h.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/gfs_ondisk.h.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/Makefile.diff?cvsroot=cluster&r1=1.11&r2=1.12
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/conga_storage_constants.py.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/StorageReport.py.diff?cvsroot=cluster&r1=1.6&r2=1.7

/cvs/cluster/conga/ricci/modules/storage/GFS1.cpp,v  -->  standard output
revision 1.1
--- conga/ricci/modules/storage/GFS1.cpp
+++ -	2006-09-26 03:17:42.080799000 +0000
@@ -0,0 +1,331 @@
+/*
+  Copyright Red Hat, Inc. 2006
+
+  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, 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; see the file COPYING.  If not, write to the
+  Free Software Foundation, Inc.,  675 Mass Ave, Cambridge, 
+  MA 02139, USA.
+*/
+/*
+ * Author: Stanko Kupcevic <kupcevic@redhat.com>
+ */
+
+
+#include "GFS1.h"
+#include "utils.h"
+#include "defines.h"
+
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <unistd.h>
+
+
+#include <iostream>
+using namespace std;
+
+
+#include "gfs_ondisk.h"
+
+
+const String GFS1::PRETTY_NAME("GFS1 - Global FS v.1");
+const static String gfs1_module("gfs");
+
+const static String MKFS_GFS1_path("/sbin/mkfs.gfs");
+const static long long DEF_JSIZE = 128 * 1024 * 1024;
+
+static void 
+detect_gfs1(const String& filename,
+	    long long &block_size,
+	    String& locking_protocol,
+	    String& locking_table);
+
+
+
+
+GFS1::GFS1(const String& path) :
+  ContentFS(path, PRETTY_NAME, gfs1_module)
+{
+  long long bs;
+  String proto, table;
+  detect_gfs1(path, bs, proto, table);
+  
+  _props.set(Variable("block_size", bs));
+  
+  // cluster
+  String cluster = table.substr(0, table.find(":"));
+  String name = table.substr(table.find(":") + 1);
+  _props.set(Variable("clustered", proto != "lock_nolock"));
+  Variable proto_var("locking_protocol", 
+		     proto.substr(proto.find("_") + 1));
+  proto_var.set_conditional_bool_if("clustered");
+  _props.set(proto_var);
+  Variable cluster_var("cluster_name", cluster);
+  cluster_var.set_conditional_bool_if("clustered");
+  _props.set(cluster_var);
+  Variable name_var("gfs_fsname", name);
+  name_var.set_conditional_bool_if("clustered");
+  _props.set(name_var);
+  
+  // mountpoints
+  mount_props_probe(path, 
+		    _module, 
+		    _props);
+}
+
+GFS1::~GFS1()
+{}
+
+
+bool 
+GFS1::expandable(long long& max_size) const
+{
+  return false;
+}
+
+void 
+GFS1::expand(const String& path,
+	     unsigned long long new_size, 
+	     const Props& new_props)
+{}
+
+bool 
+GFS1::shrinkable(long long& min_size) const
+{
+  return false;
+}
+
+void 
+GFS1::shrink(const String& path,
+	     unsigned long long new_size, 
+	     const Props& new_props)
+{}
+
+void 
+GFS1::apply_props_before_resize(const String& path,
+				unsigned long long old_size, 
+				unsigned long long new_size, 
+				const Props& new_props)
+{}
+
+void 
+GFS1::apply_props_after_resize(const String& path,
+			       unsigned long long old_size, 
+			       unsigned long long new_size, 
+			       const Props& new_props)
+{
+  // mountpoints
+  mount_props_apply(path, _module, _props, new_props);
+}
+
+bool 
+GFS1::removable() const
+{
+  return true;
+}
+
+
+
+
+
+void 
+create_GFS1(const String& path,
+	    const counting_auto_ptr<ContentTemplate>& templ)
+{
+  String bs = utils::to_string(templ->_props.get("block_size").get_int());
+  String jnum = utils::to_string(templ->_props.get("journals_num").get_int());
+  long long jsize_bytes = templ->_props.get("journal_size").get_int();
+  String jsize = utils::to_string(jsize_bytes / 1024 / 1024);
+  
+  bool clustered = templ->_props.get("clustered").get_bool();
+  String proto("nolock");
+  String table;
+  if (clustered) {
+    proto = templ->_props.get("locking_protocol").get_string();
+    table = templ->_props.get("cluster_name").get_string() +
+      ":" +
+      templ->_props.get("gfs_fsname").get_string();
+  }
+  proto = String("lock_") + proto;
+  
+  
+  vector<String> args;
+  args.push_back("-b");
+  args.push_back(bs);
+  
+  args.push_back("-J");
+  args.push_back(jsize);
+  
+  args.push_back("-j");
+  args.push_back(jnum);
+  
+  args.push_back("-O"); // no prompt
+  
+  args.push_back("-p");
+  args.push_back(proto);
+  
+  if (!table.empty()) {
+    args.push_back("-t");
+    args.push_back(table);
+  }
+  
+  args.push_back(path);
+  
+  String out, err;
+  int status;
+  if (utils::execute(MKFS_GFS1_path, args, out, err, status))
+    throw String("execute failed");
+  if (status)
+    throw MKFS_GFS1_path + " " + path + " failed";
+  
+  // mountpoints
+  ContentFSTemplate::mount_props_create(path, gfs1_module, templ->_props);
+}
+
+GFS1Template::GFS1Template() :
+  ContentFSTemplate(GFS1::PRETTY_NAME)
+{
+  if (access(MKFS_GFS1_path.c_str(), X_OK|R_OK))
+    throw String("no mkfs.gfs exists");
+  
+  // ## general options ##
+  
+  // mountpoints
+  mount_props_template(gfs1_module, _props);
+  
+  // block_size
+  list<long long> b_sizes;
+  b_sizes.push_back(512);
+  b_sizes.push_back(1024);
+  b_sizes.push_back(2048);
+  b_sizes.push_back(4096);
+  _props.set(Variable("block_size", 4096, b_sizes));
+  
+  // journals
+  _props.set(Variable("journals_num", 1, 1, 128, 1));
+  list<long long> jsizes;
+  long long jsize = 32 * 1024 * 1024; 
+  for (int i = 1; i<11; i++) {
+    jsizes.push_back(jsize);
+    jsize *= 2;
+  }
+  _props.set(Variable("journal_size", DEF_JSIZE, jsizes));
+  
+  
+  // ## cluster options ##
+  
+  bool cluster_exists = false;
+  XMLObject cluster_conf;
+  try {
+    cluster_conf = readXML("/etc/cluster/cluster.conf");
+    if (cluster_conf.tag() != "cluster" ||
+	cluster_conf.get_attr("name").empty() ||
+	cluster_conf.get_attr("config_version").empty())
+      throw String("invalid cluster.conf");
+    cluster_exists = true;
+  } catch ( ... ) {}
+  String cluster = cluster_conf.get_attr("name");
+  String name    = "unique_gfs_name";
+  String proto   = "dlm";
+  
+  long long jnum = 1;
+  if (cluster_exists) {
+    for (list<XMLObject>::const_iterator iter = cluster_conf.children().begin();
+	 iter != cluster_conf.children().end();
+	 iter++) {
+      if (iter->tag() == "clusternodes")
+	jnum = iter->children().size();
+      if (iter->tag() == "gulm")
+	proto = "gulm";
+    }
+    _props.set(Variable("journals_num", jnum, 1, 128, 1));
+  }
+  
+  _props.set(Variable("clustered", cluster_exists, cluster_exists));
+  
+  Variable proto_var("locking_protocol", proto);
+  proto_var.set_conditional_bool_if("clustered");
+  _props.set(proto_var);
+  Variable cluster_var("cluster_name", cluster);
+  cluster_var.set_conditional_bool_if("clustered");
+  _props.set(cluster_var);
+  Variable name_var("gfs_fsname", 
+		    name,
+		    1,
+		    16,
+		    String(" ;!@#$%^& *()+=/\\|?><,.\"':;"),
+		    list<String>());
+  name_var.set_conditional_bool_if("clustered");
+  _props.set(name_var);
+}
+
+GFS1Template::~GFS1Template()
+{}
+
+
+
+
+
+
+
+void
+detect_gfs1(const String& filename,
+	    long long &block_size,
+	    String& locking_protocol,
+	    String& locking_table)
+{
+  // IMPORTANT: gfs saves metadata as BigEndian
+  
+  int fd = open(filename.c_str(), O_RDONLY);
+  if (fd < 0)
+    throw String("GFS1_detect: cannot open ") + filename;
+  
+  try {
+    struct gfs_sb sb;
+    
+    int ret;
+    do {
+      const static int sb_offset = GFS_SB_ADDR * GFS_BASIC_BLOCK;
+      if (lseek(fd, sb_offset, SEEK_SET) != sb_offset)
+	throw String("lseek failed for ") + filename;
+      ret = read(fd, &sb, sizeof(sb));
+    } while (ret == -1 && 
+	     errno == EINTR);
+    if (ret != (int) sizeof(sb))
+      throw String("read of gfs superblock failed for ") + filename;
+    
+    if (ntohl(sb.sb_header.mh_magic) != GFS_MAGIC ||
+	ntohl(sb.sb_header.mh_type) != GFS_METATYPE_SB ||
+	ntohl(sb.sb_fs_format) != GFS_FORMAT_FS ||
+	ntohl(sb.sb_multihost_format) != GFS_FORMAT_MULTI)
+      throw filename + " does not contain gfs";
+    
+    block_size = ntohl(sb.sb_bsize);
+    
+    sb.sb_lockproto[sizeof(sb.sb_lockproto) - 1] = '\0';
+    locking_protocol = String(sb.sb_lockproto);
+    
+    sb.sb_locktable[sizeof(sb.sb_locktable) - 1] = '\0';
+    locking_table = String(sb.sb_locktable);
+    
+    while (close(fd))
+      if (errno != EINTR)
+	break;
+  } catch ( ... ) {
+    while (close(fd))
+      if (errno != EINTR)
+	break;
+    throw;
+  }
+}
/cvs/cluster/conga/ricci/modules/storage/GFS1.h,v  -->  standard output
revision 1.1
--- conga/ricci/modules/storage/GFS1.h
+++ -	2006-09-26 03:17:42.213209000 +0000
@@ -0,0 +1,80 @@
+/*
+  Copyright Red Hat, Inc. 2006
+
+  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, 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; see the file COPYING.  If not, write to the
+  Free Software Foundation, Inc.,  675 Mass Ave, Cambridge, 
+  MA 02139, USA.
+*/
+/*
+ * Author: Stanko Kupcevic <kupcevic@redhat.com>
+ */
+
+
+#ifndef GFS1_h
+#define GFS1_h
+
+#include "ContentFS.h"
+#include "String.h"
+
+
+void create_GFS1(const String& path,
+		 const counting_auto_ptr<ContentTemplate>& templ);
+
+
+class GFS1 : public ContentFS
+{
+ public:
+  GFS1(const String& path);
+  virtual ~GFS1();
+  
+  const static String PRETTY_NAME;
+  
+  virtual bool expandable(long long& max_size) const;
+  virtual bool shrinkable(long long& min_size) const;
+  virtual void shrink(const String& path,
+		      unsigned long long new_size, 
+		      const Props& new_props);
+  virtual void expand(const String& path,
+		      unsigned long long new_size, 
+		      const Props& new_props);
+  
+  virtual void apply_props_before_resize(const String& path,
+					 unsigned long long old_size, 
+					 unsigned long long new_size, 
+					 const Props& new_props);
+  virtual void apply_props_after_resize(const String& path,
+					unsigned long long old_size, 
+					unsigned long long new_size, 
+					const Props& new_props);
+  
+  virtual bool removable() const;
+  
+ private:
+  
+};
+
+
+class GFS1Template : public ContentFSTemplate
+{
+ public:
+  GFS1Template();
+  virtual ~GFS1Template();
+  
+ private:
+  
+  
+};
+
+
+#endif // GFS1_h
/cvs/cluster/conga/ricci/modules/storage/GFS2.cpp,v  -->  standard output
revision 1.1
--- conga/ricci/modules/storage/GFS2.cpp
+++ -	2006-09-26 03:17:42.298832000 +0000
@@ -0,0 +1,331 @@
+/*
+  Copyright Red Hat, Inc. 2006
+
+  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, 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; see the file COPYING.  If not, write to the
+  Free Software Foundation, Inc.,  675 Mass Ave, Cambridge, 
+  MA 02139, USA.
+*/
+/*
+ * Author: Stanko Kupcevic <kupcevic@redhat.com>
+ */
+
+
+#include "GFS2.h"
+#include "utils.h"
+#include "defines.h"
+
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <unistd.h>
+
+
+#include <iostream>
+using namespace std;
+
+
+#define __be64 uint64_t
+#define __be32 uint32_t
+#define __be16 uint16_t
+#define __u32  uint32_t
+#define __u16  uint16_t
+#define __u8   uint8_t
+#include "gfs2_ondisk.h"
+
+
+const String GFS2::PRETTY_NAME("GFS2 - Global FS v.2");
+const static String gfs2_module("gfs2");
+
+const static String MKFS_GFS2_path("/sbin/mkfs.gfs2");
+const static long long DEF_JSIZE = 32 * 1024 * 1024;
+
+static void 
+detect_gfs2(const String& filename,
+	    long long &block_size,
+	    String& locking_protocol,
+	    String& locking_table);
+
+
+
+
+GFS2::GFS2(const String& path) :
+  ContentFS(path, PRETTY_NAME, gfs2_module)
+{
+  long long bs;
+  String proto, table;
+  detect_gfs2(path, bs, proto, table);
+  
+  _props.set(Variable("block_size", bs));
+  
+  // cluster
+  String cluster = table.substr(0, table.find(":"));
+  String name = table.substr(table.find(":") + 1);
+  _props.set(Variable("clustered", proto != "lock_nolock"));
+  Variable proto_var("locking_protocol", 
+		     proto.substr(proto.find("_") + 1));
+  proto_var.set_conditional_bool_if("clustered");
+  _props.set(proto_var);
+  Variable cluster_var("cluster_name", cluster);
+  cluster_var.set_conditional_bool_if("clustered");
+  _props.set(cluster_var);
+  Variable name_var("gfs_fsname", name);
+  name_var.set_conditional_bool_if("clustered");
+  _props.set(name_var);
+  
+  // mountpoints
+  mount_props_probe(path, _module, _props);
+}
+
+GFS2::~GFS2()
+{}
+
+
+bool 
+GFS2::expandable(long long& max_size) const
+{
+  return false;
+}
+
+void 
+GFS2::expand(const String& path,
+	     unsigned long long new_size, 
+	     const Props& new_props)
+{}
+
+bool 
+GFS2::shrinkable(long long& min_size) const
+{
+  return false;
+}
+
+void 
+GFS2::shrink(const String& path,
+	     unsigned long long new_size, 
+	     const Props& new_props)
+{}
+
+void 
+GFS2::apply_props_before_resize(const String& path,
+				unsigned long long old_size, 
+				unsigned long long new_size, 
+				const Props& new_props)
+{}
+
+void 
+GFS2::apply_props_after_resize(const String& path,
+			       unsigned long long old_size, 
+			       unsigned long long new_size, 
+			       const Props& new_props)
+{
+  // mountpoints
+  mount_props_apply(path, _module, _props, new_props);
+}
+
+bool 
+GFS2::removable() const
+{
+  return true;
+}
+
+
+
+
+
+void 
+create_GFS2(const String& path,
+	    const counting_auto_ptr<ContentTemplate>& templ)
+{
+  String bs = utils::to_string(templ->_props.get("block_size").get_int());
+  String jnum = utils::to_string(templ->_props.get("journals_num").get_int());
+  long long jsize_bytes = templ->_props.get("journal_size").get_int();
+  String jsize = utils::to_string(jsize_bytes / 1024 / 1024);
+  
+  bool clustered = templ->_props.get("clustered").get_bool();
+  String proto("nolock");
+  String table;
+  if (clustered) {
+    proto = templ->_props.get("locking_protocol").get_string();
+    table = templ->_props.get("cluster_name").get_string() +
+      ":" +
+      templ->_props.get("gfs_fsname").get_string();
+  }
+  proto = String("lock_") + proto;
+  
+  
+  vector<String> args;
+  args.push_back("-b");
+  args.push_back(bs);
+  
+  args.push_back("-J");
+  args.push_back(jsize);
+  
+  args.push_back("-j");
+  args.push_back(jnum);
+  
+  args.push_back("-O"); // no prompt
+  
+  args.push_back("-p");
+  args.push_back(proto);
+  
+  if (!table.empty()) {
+    args.push_back("-t");
+    args.push_back(table);
+  }
+  
+  args.push_back(path);
+  
+  String out, err;
+  int status;
+  if (utils::execute(MKFS_GFS2_path, args, out, err, status))
+    throw String("execute failed");
+  if (status)
+    throw MKFS_GFS2_path + " " + path + " failed";
+  
+  // mountpoints
+  ContentFSTemplate::mount_props_create(path, gfs2_module, templ->_props);
+}
+
+GFS2Template::GFS2Template() :
+  ContentFSTemplate(GFS2::PRETTY_NAME)
+{
+  if (access(MKFS_GFS2_path.c_str(), X_OK|R_OK))
+    throw String("no mkfs.gfs2 exists");
+  
+  // ## general options ##
+  
+  // mountpoints
+  mount_props_template(gfs2_module, _props);
+  
+  // block_size
+  list<long long> b_sizes;
+  b_sizes.push_back(512);
+  b_sizes.push_back(1024);
+  b_sizes.push_back(2048);
+  b_sizes.push_back(4096);
+  _props.set(Variable("block_size", 4096, b_sizes));
+  
+  // journals
+  _props.set(Variable("journals_num", 1, 1, 128, 1));
+  list<long long> jsizes;
+  long long jsize = 8*1024*1024; 
+  for (int i = 1; i<11; i++) {
+    jsizes.push_back(jsize);
+    jsize *= 2;
+  }
+  _props.set(Variable("journal_size", DEF_JSIZE, jsizes));
+  
+  
+  // ## cluster options ##
+  
+  bool cluster_exists = false;
+  XMLObject cluster_conf;
+  try {
+    cluster_conf = readXML("/etc/cluster/cluster.conf");
+    if (cluster_conf.tag() != "cluster" ||
+	cluster_conf.get_attr("name").empty() ||
+	cluster_conf.get_attr("config_version").empty())
+      throw String("invalid cluster.conf");
+    cluster_exists = true;
+  } catch ( ... ) {}
+  String cluster = cluster_conf.get_attr("name");
+  String name = "unique_gfs_name";
+  
+  long long jnum = 1;
+  if (cluster_exists) {
+    for (list<XMLObject>::const_iterator iter = cluster_conf.children().begin();
+	 iter != cluster_conf.children().end();
+	 iter++)
+      if (iter->tag() == "clusternodes")
+	jnum = iter->children().size();
+    _props.set(Variable("journals_num", jnum, 1, 128, 1));
+  }
+  
+  _props.set(Variable("clustered", cluster_exists, cluster_exists));
+  
+  Variable proto_var("locking_protocol", String("dlm"));
+  proto_var.set_conditional_bool_if("clustered");
+  _props.set(proto_var);
+  Variable cluster_var("cluster_name", cluster);
+  cluster_var.set_conditional_bool_if("clustered");
+  _props.set(cluster_var);
+  Variable name_var("gfs_fsname", 
+		    name,
+		    1,
+		    16,
+		    String(" ;!@#$%^&*()+=/\\|?><,.\"':;"),
+		    list<String>());
+  name_var.set_conditional_bool_if("clustered");
+  _props.set(name_var);
+}
+
+GFS2Template::~GFS2Template()
+{}
+
+
+
+
+
+
+
+void
+detect_gfs2(const String& filename,
+	    long long &block_size,
+	    String& locking_protocol,
+	    String& locking_table)
+{
+  // IMPORTANT: gfs2 saves metadata as BigEndian
+  
+  int fd = open(filename.c_str(), O_RDONLY);
+  if (fd < 0)
+    throw String("GFS2_detect: cannot open ") + filename;
+  
+  try {
+    struct gfs2_sb sb;
+    
+    int ret;
+    do {
+      const static int sb_offset = GFS2_SB_ADDR * GFS2_BASIC_BLOCK;
+      if (lseek(fd, sb_offset, SEEK_SET) != sb_offset)
+	throw String("lseek failed for ") + filename;
+      ret = read(fd, &sb, sizeof(sb));
+    } while (ret == -1 && 
+	     errno == EINTR);
+    if (ret != (int) sizeof(sb))
+      throw String("read of gfs2 superblock failed for ") + filename;
+    
+    if (ntohl(sb.sb_header.mh_magic) != GFS2_MAGIC ||
+	ntohl(sb.sb_header.mh_type) != GFS2_METATYPE_SB ||
+	ntohl(sb.sb_fs_format) != GFS2_FORMAT_FS ||
+	ntohl(sb.sb_multihost_format) != GFS2_FORMAT_MULTI)
+      throw filename + " does not contain gfs2";
+    
+    block_size = ntohl(sb.sb_bsize);
+    
+    sb.sb_lockproto[sizeof(sb.sb_lockproto) - 1] = '\0';
+    locking_protocol = String(sb.sb_lockproto);
+    
+    sb.sb_locktable[sizeof(sb.sb_locktable) - 1] = '\0';
+    locking_table = String(sb.sb_locktable);
+    
+    while (close(fd))
+      if (errno != EINTR)
+	break;
+  } catch ( ... ) {
+    while (close(fd))
+      if (errno != EINTR)
+	break;
+    throw;
+  }
+}
/cvs/cluster/conga/ricci/modules/storage/GFS2.h,v  -->  standard output
revision 1.1
--- conga/ricci/modules/storage/GFS2.h
+++ -	2006-09-26 03:17:42.388214000 +0000
@@ -0,0 +1,80 @@
+/*
+  Copyright Red Hat, Inc. 2006
+
+  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, 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; see the file COPYING.  If not, write to the
+  Free Software Foundation, Inc.,  675 Mass Ave, Cambridge, 
+  MA 02139, USA.
+*/
+/*
+ * Author: Stanko Kupcevic <kupcevic@redhat.com>
+ */
+
+
+#ifndef GFS2_h
+#define GFS2_h
+
+#include "ContentFS.h"
+#include "String.h"
+
+
+void create_GFS2(const String& path,
+		 const counting_auto_ptr<ContentTemplate>& templ);
+
+
+class GFS2 : public ContentFS
+{
+ public:
+  GFS2(const String& path);
+  virtual ~GFS2();
+  
+  const static String PRETTY_NAME;
+  
+  virtual bool expandable(long long& max_size) const;
+  virtual bool shrinkable(long long& min_size) const;
+  virtual void shrink(const String& path,
+		      unsigned long long new_size, 
+		      const Props& new_props);
+  virtual void expand(const String& path,
+		      unsigned long long new_size, 
+		      const Props& new_props);
+  
+  virtual void apply_props_before_resize(const String& path,
+					 unsigned long long old_size, 
+					 unsigned long long new_size, 
+					 const Props& new_props);
+  virtual void apply_props_after_resize(const String& path,
+					unsigned long long old_size, 
+					unsigned long long new_size, 
+					const Props& new_props);
+  
+  virtual bool removable() const;
+  
+ private:
+  
+};
+
+
+class GFS2Template : public ContentFSTemplate
+{
+ public:
+  GFS2Template();
+  virtual ~GFS2Template();
+  
+ private:
+  
+  
+};
+
+
+#endif // GFS2_h
/cvs/cluster/conga/ricci/modules/storage/UnsupportedFS.cpp,v  -->  standard output
revision 1.1
--- conga/ricci/modules/storage/UnsupportedFS.cpp
+++ -	2006-09-26 03:17:42.485944000 +0000
@@ -0,0 +1,165 @@
+/*
+  Copyright Red Hat, Inc. 2006
+
+  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, 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; see the file COPYING.  If not, write to the
+  Free Software Foundation, Inc.,  675 Mass Ave, Cambridge, 
+  MA 02139, USA.
+*/
+/*
+ * Author: Stanko Kupcevic <kupcevic@redhat.com>
+ */
+
+
+#include "UnsupportedFS.h"
+#include "FileMagic.h"
+#include "utils.h"
+
+
+UnsupportedFS::UnsupportedFS(const String& path) :
+  ContentFS(path, "bug", "bug")
+{
+  String magic(FileMagic::get_description(path));
+  magic = utils::to_lower(magic);
+  if (magic.find("minix filesystem") != magic.npos) {
+    _name   = "Minix FS";
+    _module = "minix";
+  } else if (magic.find("unix fast file") != magic.npos) {
+    _name   = "Unix Fast FS";
+    _module = "ufs";
+  } else if (magic.find("sgi xfs") != magic.npos) {
+    _name   = "SGI XFS";
+    _module = "xfs";
+  } else if (magic.find("iso 9660 cd-rom") != magic.npos) {
+    _name   = "ISO 9660 CD-ROM FS";
+    _module = "isofs";
+  } else if (magic.find("linux compressed rom file system") != magic.npos) {
+    _name   = "CramFS";
+    _module = "cramfs";
+  } else if (magic.find("reiserfs") != magic.npos) {
+    _name   = "Reiser FS";
+    _module = "reiserfs";
+  } else if (magic.find("linux journalled flash file system") != magic.npos) {
+    _name   = "Journalled Flash FS v.1";
+    _module = "jffs";
+  } else if (magic.find("jffs2") != magic.npos) {
+    _name   = "Journalled Flash FS v.1";
+    _module = "jffs2";
+  } else if (magic.find("squashfs") != magic.npos) {
+    _name   = "SquashFS";
+    _module = "squashfs";
+  } else if (magic.find("fat (12 bit)") != magic.npos ||
+	     magic.find("fat (16 bit)") != magic.npos ||
+	     magic.find("fat (32 bit)") != magic.npos) {
+    _name   = "MS vfat FS";
+    _module = "vfat";
+  } else if (magic.find("msdos") != magic.npos ||
+	     magic.find("ms-dos") != magic.npos) {
+    _name   = "MS-DOS FS";
+    _module = "msdos";
+  } else if (magic.find("affs") != magic.npos) {
+    _name   = "Amiga FS";
+    _module = "affs";
+  } else if (magic.find("befs") != magic.npos) {
+    _name   = "BeOS FS";
+    _module = "befs";
+  } else if (magic.find("bfs") != magic.npos) {
+    _name   = "SCO UnixWare BFS";
+    _module = "bfs";
+  } else if (magic.find("jfs") != magic.npos) {
+    _name   = "Journaled Filesystem (JFS)";
+    _module = "jfs";
+  } else if (magic.find("efs") != magic.npos) {
+    _name   = "efs";
+    _module = "efs";
+  } else if (magic.find("vxfs") != magic.npos) {
+    _name   = "Veritas Filesystem (VxFS)";
+    _module = "freevxfs";
+  } else if (magic.find("hfsplus") != magic.npos) {
+    _name   = "Macintosh FS (extended)";
+    _module = "hfsplus";
+  } else if (magic.find("hfs") != magic.npos) {
+    _name   = "Macintosh FS";
+    _module = "hfs";
+  } else if (magic.find("ncpfs") != magic.npos) {
+    _name   = "ncpfs";
+    _module = "ncpfs";
+  } else if (magic.find("ocfs2") != magic.npos) {
+    _name   = "Oracle Clustered FS v.2";
+    _module = "ocfs2";
+  } else if (magic.find("relayfs") != magic.npos) {
+    _name   = "Relay FS";
+    _module = "relayfs";
+  } else if (magic.find("udf") != magic.npos) {
+    _name   = "Universal Disk Format";
+    _module = "udf";
+    
+    
+    
+  } else
+    throw String("not even an unsupported FS");
+  
+  // mountpoints
+  mount_props_probe(path, _module, _props);
+}
+
+UnsupportedFS::~UnsupportedFS()
+{}
+
+
+bool 
+UnsupportedFS::expandable(long long& max_size) const
+{
+  return false;
+}
+
+void 
+UnsupportedFS::expand(const String& path,
+	     unsigned long long new_size, 
+	     const Props& new_props)
+{}
+
+bool 
+UnsupportedFS::shrinkable(long long& min_size) const
+{
+  return false;
+}
+
+void 
+UnsupportedFS::shrink(const String& path,
+	     unsigned long long new_size, 
+	     const Props& new_props)
+{}
+
+void 
+UnsupportedFS::apply_props_before_resize(const String& path,
+				unsigned long long old_size, 
+				unsigned long long new_size, 
+				const Props& new_props)
+{}
+
+void 
+UnsupportedFS::apply_props_after_resize(const String& path,
+			       unsigned long long old_size, 
+			       unsigned long long new_size, 
+			       const Props& new_props)
+{
+  // mountpoints
+  mount_props_apply(path, _module, _props, new_props);
+}
+
+bool 
+UnsupportedFS::removable() const
+{
+  return true;
+}
/cvs/cluster/conga/ricci/modules/storage/UnsupportedFS.h,v  -->  standard output
revision 1.1
--- conga/ricci/modules/storage/UnsupportedFS.h
+++ -	2006-09-26 03:17:42.573138000 +0000
@@ -0,0 +1,64 @@
+/*
+  Copyright Red Hat, Inc. 2006
+
+  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, 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; see the file COPYING.  If not, write to the
+  Free Software Foundation, Inc.,  675 Mass Ave, Cambridge, 
+  MA 02139, USA.
+*/
+/*
+ * Author: Stanko Kupcevic <kupcevic@redhat.com>
+ */
+
+
+#ifndef UnsupportedFS_h
+#define UnsupportedFS_h
+
+#include "ContentFS.h"
+#include "String.h"
+
+
+
+class UnsupportedFS : public ContentFS
+{
+ public:
+  UnsupportedFS(const String& path);
+  virtual ~UnsupportedFS();
+  
+  
+  virtual bool expandable(long long& max_size) const;
+  virtual bool shrinkable(long long& min_size) const;
+  virtual void shrink(const String& path,
+		      unsigned long long new_size, 
+		      const Props& new_props);
+  virtual void expand(const String& path,
+		      unsigned long long new_size, 
+		      const Props& new_props);
+  
+  virtual void apply_props_before_resize(const String& path,
+					 unsigned long long old_size, 
+					 unsigned long long new_size, 
+					 const Props& new_props);
+  virtual void apply_props_after_resize(const String& path,
+					unsigned long long old_size, 
+					unsigned long long new_size, 
+					const Props& new_props);
+  
+  virtual bool removable() const;
+  
+ private:
+  
+};
+
+
+#endif // UnsupportedFS_h
/cvs/cluster/conga/ricci/modules/storage/gfs2_ondisk.h,v  -->  standard output
revision 1.1
--- conga/ricci/modules/storage/gfs2_ondisk.h
+++ -	2006-09-26 03:17:42.661009000 +0000
@@ -0,0 +1,454 @@
+/*
+ * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
+ * Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ */
+
+#ifndef __GFS2_ONDISK_DOT_H__
+#define __GFS2_ONDISK_DOT_H__
+
+#define GFS2_MAGIC		0x01161970
+#define GFS2_BASIC_BLOCK	512
+#define GFS2_BASIC_BLOCK_SHIFT	9
+
+/* Lock numbers of the LM_TYPE_NONDISK type */
+
+#define GFS2_MOUNT_LOCK		0
+#define GFS2_LIVE_LOCK		1
+#define GFS2_TRANS_LOCK		2
+#define GFS2_RENAME_LOCK	3
+
+/* Format numbers for various metadata types */
+
+#define GFS2_FORMAT_NONE	0
+#define GFS2_FORMAT_SB		100
+#define GFS2_FORMAT_RG		200
+#define GFS2_FORMAT_RB		300
+#define GFS2_FORMAT_DI		400
+#define GFS2_FORMAT_IN		500
+#define GFS2_FORMAT_LF		600
+#define GFS2_FORMAT_JD		700
+#define GFS2_FORMAT_LH		800
+#define GFS2_FORMAT_LD		900
+#define GFS2_FORMAT_LB		1000
+#define GFS2_FORMAT_EA		1100
+#define GFS2_FORMAT_ED		1200
+#define GFS2_FORMAT_UT		1300
+#define GFS2_FORMAT_QC		1400
+/* These are format numbers for entities contained in files */
+#define GFS2_FORMAT_RI		1500
+#define GFS2_FORMAT_DE		1600
+#define GFS2_FORMAT_QU		1700
+/* These are part of the superblock */
+#define GFS2_FORMAT_FS		1801
+#define GFS2_FORMAT_MULTI	1900
+
+/*
+ * An on-disk inode number
+ */
+
+#define gfs2_inum_equal(ino1, ino2) \
+	(((ino1)->no_formal_ino == (ino2)->no_formal_ino) && \
+	((ino1)->no_addr == (ino2)->no_addr))
+
+struct gfs2_inum {
+	__be64 no_formal_ino;
+	__be64 no_addr;
+};
+
+/*
+ * Generic metadata head structure
+ * Every inplace buffer logged in the journal must start with this.
+ */
+
+#define GFS2_METATYPE_NONE	0
+#define GFS2_METATYPE_SB	1
+#define GFS2_METATYPE_RG	2
+#define GFS2_METATYPE_RB	3
+#define GFS2_METATYPE_DI	4
+#define GFS2_METATYPE_IN	5
+#define GFS2_METATYPE_LF	6
+#define GFS2_METATYPE_JD	7
+#define GFS2_METATYPE_LH	8
+#define GFS2_METATYPE_LD	9
+#define GFS2_METATYPE_LB	10
+#define GFS2_METATYPE_EA	11
+#define GFS2_METATYPE_ED	12
+#define GFS2_METATYPE_UT	13
+#define GFS2_METATYPE_QC	14
+
+struct gfs2_meta_header {
+	__be32 mh_magic;
+	__be32 mh_type;
+	__be64 __pad0;		/* Was generation number in gfs1 */
+	__be32 mh_format;
+	__be32 __pad1;		/* Was incarnation number in gfs1 */
+};
+
+/*
+ * super-block structure
+ *
+ * It's probably good if SIZEOF_SB <= GFS2_BASIC_BLOCK (512 bytes)
+ *
+ * Order is important, need to be able to read old superblocks to do on-disk
+ * version upgrades.
+ */
+
+/* Address of superblock in GFS2 basic blocks */
+#define GFS2_SB_ADDR		128
+
+/* The lock number for the superblock (must be zero) */
+#define GFS2_SB_LOCK		0
+
+/* Requirement:  GFS2_LOCKNAME_LEN % 8 == 0
+   Includes: the fencing zero@the end */
+#define GFS2_LOCKNAME_LEN	64
+
+struct gfs2_sb {
+	struct gfs2_meta_header sb_header;
+
+	__be32 sb_fs_format;
+	__be32 sb_multihost_format;
+	__u32  __pad0;	/* Was superblock flags in gfs1 */
+
+	__be32 sb_bsize;
+	__be32 sb_bsize_shift;
+	__u32 __pad1;	/* Was journal segment size in gfs1 */
+
+	struct gfs2_inum sb_master_dir; /* Was jindex dinode in gfs1 */
+	struct gfs2_inum __pad2; /* Was rindex dinode in gfs1 */
+	struct gfs2_inum sb_root_dir;
+
+	char sb_lockproto[GFS2_LOCKNAME_LEN];
+	char sb_locktable[GFS2_LOCKNAME_LEN];
+	/* In gfs1, quota and license dinodes followed */
+};
+
+/*
+ * resource index structure
+ */
+
+struct gfs2_rindex {
+	__be64 ri_addr;	/* grp block disk address */
+	__be32 ri_length;	/* length of rgrp header in fs blocks */
+	__u32 __pad;
+
+	__be64 ri_data0;	/* first data location */
+	__be32 ri_data;	/* num of data blocks in rgrp */
+
+	__be32 ri_bitbytes;	/* number of bytes in data bitmaps */
+
+	__u8 ri_reserved[64];
+};
+
+/*
+ * resource group header structure
+ */
+
+/* Number of blocks per byte in rgrp */
+#define GFS2_NBBY		4
+#define GFS2_BIT_SIZE		2
+#define GFS2_BIT_MASK		0x00000003
+
+#define GFS2_BLKST_FREE		0
+#define GFS2_BLKST_USED		1
+#define GFS2_BLKST_INVALID	2
+#define GFS2_BLKST_DINODE	3
+
+#define GFS2_RGF_JOURNAL	0x00000001
+#define GFS2_RGF_METAONLY	0x00000002
+#define GFS2_RGF_DATAONLY	0x00000004
+#define GFS2_RGF_NOALLOC	0x00000008
+
+struct gfs2_rgrp {
+	struct gfs2_meta_header rg_header;
+
+	__be32 rg_flags;
+	__be32 rg_free;
+	__be32 rg_dinodes;
+
+	__u8 rg_reserved[92]; /* Several fields from gfs1 now reserved */
+};
+
+/*
+ * quota structure
+ */
+
+struct gfs2_quota {
+	__be64 qu_limit;
+	__be64 qu_warn;
+	__be64 qu_value;
+};
+
+/*
+ * dinode structure
+ */
+
+#define GFS2_MAX_META_HEIGHT	10
+#define GFS2_DIR_MAX_DEPTH	17
+
+#define DT2IF(dt) (((dt) << 12) & S_IFMT)
+#define IF2DT(sif) (((sif) & S_IFMT) >> 12)
+
+/* Dinode flags */
+#define GFS2_DIF_JDATA			0x00000001
+#define GFS2_DIF_EXHASH			0x00000002
+#define GFS2_DIF_UNUSED			0x00000004  /* only in gfs1 */
+#define GFS2_DIF_EA_INDIRECT		0x00000008
+#define GFS2_DIF_DIRECTIO		0x00000010
+#define GFS2_DIF_IMMUTABLE		0x00000020
+#define GFS2_DIF_APPENDONLY		0x00000040
+#define GFS2_DIF_NOATIME		0x00000080
+#define GFS2_DIF_SYNC			0x00000100
+#define GFS2_DIF_SYSTEM			0x00000200 /* New in gfs2 */
+#define GFS2_DIF_TRUNC_IN_PROG		0x20000000 /* New in gfs2 */
+#define GFS2_DIF_INHERIT_DIRECTIO	0x40000000
+#define GFS2_DIF_INHERIT_JDATA		0x80000000
+
+struct gfs2_dinode {
+	struct gfs2_meta_header di_header;
+
+	struct gfs2_inum di_num;
+
+	__be32 di_mode;	/* mode of file */
+	__be32 di_uid;	/* owner's user id */
+	__be32 di_gid;	/* owner's group id */
+	__be32 di_nlink;	/* number of links to this file */
+	__be64 di_size;	/* number of bytes in file */
+	__be64 di_blocks;	/* number of blocks in file */
+	__be64 di_atime;	/* time last accessed */
+	__be64 di_mtime;	/* time last modified */
+	__be64 di_ctime;	/* time last changed */
+	__be32 di_major;	/* device major number */
+	__be32 di_minor;	/* device minor number */
+
+	/* This section varies from gfs1. Padding added to align with
+         * remainder of dinode
+	 */
+	__be64 di_goal_meta;	/* rgrp to alloc from next */
+	__be64 di_goal_data;	/* data block goal */
+	__u32 __pad[2];
+
+	__be32 di_flags;	/* GFS2_DIF_... */
+	__be32 di_payload_format;  /* GFS2_FORMAT_... */
+	__u16 __pad1;	/* Was ditype in gfs1 */
+	__be16 di_height;	/* height of metadata */
+	__u32 __pad2;	/* Unused incarnation number from gfs1 */
+
+	/* These only apply to directories  */
+	__u16 __pad3;	/* Padding */
+	__be16 di_depth;	/* Number of bits in the table */
+	__be32 di_entries;	/* The number of entries in the directory */
+
+	struct gfs2_inum __pad4; /* Unused even in current gfs1 */
+
+	__be64 di_eattr;	/* extended attribute block number */
+
+	__u8 di_reserved[56];
+};
+
+/*
+ * directory structure - many of these per directory file
+ */
+
+#define GFS2_FNAMESIZE		255
+#define GFS2_DIRENT_SIZE(name_len) ((sizeof(struct gfs2_dirent) + (name_len) + 7) & ~7)
+
+struct gfs2_dirent {
+	struct gfs2_inum de_inum;
+	__be32 de_hash;
+	__be32 de_rec_len;
+	__u8 de_name_len;
+	__u8 de_type;
+	__u16 __pad1;
+	__u32 __pad2;
+};
+
+/*
+ * Header of leaf directory nodes
+ */
+
+struct gfs2_leaf {
+	struct gfs2_meta_header lf_header;
+
+	__be16 lf_depth;		/* Depth of leaf */
+	__be16 lf_entries;		/* Number of dirents in leaf */
+	__be32 lf_dirent_format;	/* Format of the dirents */
+	__be64 lf_next;			/* Next leaf, if overflow */
+
+	__u8 lf_reserved[32];
+};
+
+/*
+ * Extended attribute header format
+ */
+
+#define GFS2_EA_MAX_NAME_LEN	255
+#define GFS2_EA_MAX_DATA_LEN	65536
+
+#define GFS2_EATYPE_UNUSED	0
+#define GFS2_EATYPE_USR		1
+#define GFS2_EATYPE_SYS		2
+
+#define GFS2_EATYPE_LAST	2
+#define GFS2_EATYPE_VALID(x)	((x) <= GFS2_EATYPE_LAST)
+
+#define GFS2_EAFLAG_LAST	0x01	/* last ea in block */
+
+struct gfs2_ea_header {
+	__be32 ea_rec_len;
+	__be32 ea_data_len;
+	__u8 ea_name_len;	/* no NULL pointer after the string */
+	__u8 ea_type;		/* GFS2_EATYPE_... */
+	__u8 ea_flags;		/* GFS2_EAFLAG_... */
+	__u8 ea_num_ptrs;
+	__u32 __pad;
+};
+
+/*
+ * Log header structure
+ */
+
+#define GFS2_LOG_HEAD_UNMOUNT	0x00000001	/* log is clean */
+
+struct gfs2_log_header {
+	struct gfs2_meta_header lh_header;
+
+	__be64 lh_sequence;	/* Sequence number of this transaction */
+	__be32 lh_flags;	/* GFS2_LOG_HEAD_... */
+	__be32 lh_tail;		/* Block number of log tail */
+	__be32 lh_blkno;
+	__be32 lh_hash;
+};
+
+/*
+ * Log type descriptor
+ */
+
+#define GFS2_LOG_DESC_METADATA	300
+/* ld_data1 is the number of metadata blocks in the descriptor.
+   ld_data2 is unused. */
+
+#define GFS2_LOG_DESC_REVOKE	301
+/* ld_data1 is the number of revoke blocks in the descriptor.
+   ld_data2 is unused. */
+
+struct gfs2_log_descriptor {
+	struct gfs2_meta_header ld_header;
+
+	__be32 ld_type;		/* GFS2_LOG_DESC_... */
+	__be32 ld_length;	/* Number of buffers in this chunk */
+	__be32 ld_data1;	/* descriptor-specific field */
+	__be32 ld_data2;	/* descriptor-specific field */
+
+	__u8 ld_reserved[32];
+};
+
+/*
+ * Inum Range
+ * Describe a range of formal inode numbers allocated to
+ * one machine to assign to inodes.
+ */
+
+#define GFS2_INUM_QUANTUM	1048576
+
+struct gfs2_inum_range {
+	__be64 ir_start;
+	__be64 ir_length;
+};
+
+/*
+ * Statfs change
+ * Describes an change to the pool of free and allocated
+ * blocks.
+ */
+
+struct gfs2_statfs_change {
+	__be64 sc_total;
+	__be64 sc_free;
+	__be64 sc_dinodes;
+};
+
+/*
+ * Unlinked Tag
+ * Describes an allocated inode that isn't linked into
+ * the directory tree and might need to be deallocated.
+ */
+
+#define GFS2_UTF_UNINIT		0x00000001
+
+struct gfs2_unlinked_tag {
+	struct gfs2_inum ut_inum;
+	__be32 ut_flags;	/* GFS2_UTF_... */
+	__u32 __pad;
+};
+
+/*
+ * Quota change
+ * Describes an allocation change for a particular
+ * user or group.
+ */
+
+#define GFS2_QCF_USER		0x00000001
+
+struct gfs2_quota_change {
+	__be64 qc_change;
+	__be32 qc_flags;	/* GFS2_QCF_... */
+	__be32 qc_id;
+};
+
+/* Translation functions */
+
+extern void gfs2_inum_in(struct gfs2_inum *no, char *buf);
+extern void gfs2_inum_out(struct gfs2_inum *no, char *buf);
+extern void gfs2_meta_header_in(struct gfs2_meta_header *mh, char *buf);
+extern void gfs2_meta_header_out(struct gfs2_meta_header *mh, char *buf);
+extern void gfs2_sb_in(struct gfs2_sb *sb, char *buf);
+extern void gfs2_sb_out(struct gfs2_sb *sb, char *buf);
+extern void gfs2_rindex_in(struct gfs2_rindex *ri, char *buf);
+extern void gfs2_rindex_out(struct gfs2_rindex *ri, char *buf);
+extern void gfs2_rgrp_in(struct gfs2_rgrp *rg, char *buf);
+extern void gfs2_rgrp_out(struct gfs2_rgrp *rg, char *buf);
+extern void gfs2_quota_in(struct gfs2_quota *qu, char *buf);
+extern void gfs2_quota_out(struct gfs2_quota *qu, char *buf);
+extern void gfs2_dinode_in(struct gfs2_dinode *di, char *buf);
+extern void gfs2_dinode_out(struct gfs2_dinode *di, char *buf);
+extern void gfs2_dirent_in(struct gfs2_dirent *de, char *buf);
+extern void gfs2_dirent_out(struct gfs2_dirent *de, char *buf);
+extern void gfs2_leaf_in(struct gfs2_leaf *lf, char *buf);
+extern void gfs2_leaf_out(struct gfs2_leaf *lf, char *buf);
+extern void gfs2_ea_header_in(struct gfs2_ea_header *ea, char *buf);
+extern void gfs2_ea_header_out(struct gfs2_ea_header *ea, char *buf);
+extern void gfs2_log_header_in(struct gfs2_log_header *lh, char *buf);
+extern void gfs2_inum_range_in(struct gfs2_inum_range *ir, char *buf);
+extern void gfs2_inum_range_out(struct gfs2_inum_range *ir, char *buf);
+extern void gfs2_statfs_change_in(struct gfs2_statfs_change *sc, char *buf);
+extern void gfs2_statfs_change_out(struct gfs2_statfs_change *sc, char *buf);
+extern void gfs2_unlinked_tag_in(struct gfs2_unlinked_tag *ut, char *buf);
+extern void gfs2_unlinked_tag_out(struct gfs2_unlinked_tag *ut, char *buf);
+extern void gfs2_quota_change_in(struct gfs2_quota_change *qc, char *buf);
+extern void gfs2_quota_change_out(struct gfs2_quota_change *qc, char *buf);
+
+/* Printing functions */
+
+extern void gfs2_inum_print(struct gfs2_inum *no);
+extern void gfs2_meta_header_print(struct gfs2_meta_header *mh);
+extern void gfs2_sb_print(struct gfs2_sb *sb);
+extern void gfs2_rindex_print(struct gfs2_rindex *ri);
+extern void gfs2_rgrp_print(struct gfs2_rgrp *rg);
+extern void gfs2_quota_print(struct gfs2_quota *qu);
+extern void gfs2_dinode_print(struct gfs2_dinode *di);
+extern void gfs2_dirent_print(struct gfs2_dirent *de, char *name);
+extern void gfs2_leaf_print(struct gfs2_leaf *lf);
+extern void gfs2_ea_header_print(struct gfs2_ea_header *ea, char *name);
+extern void gfs2_log_header_print(struct gfs2_log_header *lh);
+extern void gfs2_log_descriptor_print(struct gfs2_log_descriptor *ld);
+extern void gfs2_inum_range_print(struct gfs2_inum_range *ir);
+extern void gfs2_statfs_change_print(struct gfs2_statfs_change *sc);
+extern void gfs2_unlinked_tag_print(struct gfs2_unlinked_tag *ut);
+extern void gfs2_quota_change_print(struct gfs2_quota_change *qc);
+
+#endif /* __GFS2_ONDISK_DOT_H__ */
/cvs/cluster/conga/ricci/modules/storage/gfs_ondisk.h,v  -->  standard output
revision 1.1
--- conga/ricci/modules/storage/gfs_ondisk.h
+++ -	2006-09-26 03:17:42.764233000 +0000
@@ -0,0 +1,1899 @@
+/******************************************************************************
+*******************************************************************************
+**
+**  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
+**  Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
+**
+**  This copyrighted material is made available to anyone wishing to use,
+**  modify, copy, or redistribute it subject to the terms and conditions
+**  of the GNU General Public License v.2.
+**
+*******************************************************************************
+******************************************************************************/
+
+/*
+ * On-disk structures.
+ *
+ * THE BIG PICTURE of on-disk layout:
+ *
+ * GFS filesystem code views the entire filesystem, including journals, as
+ * one contiguous group of blocks on one (perhaps virtual) storage device.
+ * The filesystem space is shared, not distributed; each node in the cluster
+ * must see the entire filesystem space.
+ *
+ * If the filesystem is spread across multiple physical storage devices,
+ * volume management (device mapping) must be used to present the fileystem
+ * space to GFS as one (virtual) device, with contiguous blocks.
+ *
+ * The superblock contains basic information about the filesytem, and appears
+ * at a location 64 KBytes into the filesystem.  The first 64 KBytes of the
+ * filesystem are empty, providing a safety buffer against wayward volume
+ * management software (that sometimes write data into the first few bytes of
+ * a device) or administrators.
+ *
+ * After the superblock, the rest of the filesystem is divided into multiple
+ * Resource Groups and several journals.
+ *
+ * The Resource Groups (RGs or rgrps) contain the allocatable blocks that are
+ * used for storing files, directories, etc., and all of the associated
+ * metadata.  Each RG has its own set of block allocation statistics (within
+ * the RG header), a number of blocks containing the block allocation bitmap,
+ * and a large number of allocatable blocks for file data and metadata.
+ * Multiple RGs allow multiple nodes to simultaneously allocate blocks from the 
+ * filesystem (using different RGs), enhancing parallel access.  RG size and
+ * number of RGs are determined by gfs_mkfs when creating the filesystem.
+ * An administrator can specify RG size (see man gfs_mkfs).
+ *
+ * The journals contain temporary copies of metadata blocks, along with
+ * other data, that allow GFS to recover the filesystem to a consistent state
+ * (at least as far as metadata is concerned) if a node fails in the midst
+ * of performing a write transaction.  There must be one journal for each node
+ * in the cluster.  Since access to the entire filesystem space is shared,
+ * if a node crashes, another node will be able to read the crashed node's
+ * journal, and perform recovery.
+ *
+ * Currently, gfs_mkfs places the journals right in the middle of a freshly
+ * created filesystem space, between 2 large groups of RGs.  From a filesystem
+ * layout perspective, this placement is not a requirement; the journals
+ * could be placed anywhere within the filesystem space.
+ *
+ * New Resource Groups and Journals may be added to the filesystem after the
+ * filesystem has been created, if the filesystem's (virtual) device is made
+ * larger.  See man gfs_grow and gfs_jadd.
+ *
+ * A few special hidden inodes are contained in a GFS filesystem.  They do
+ * not appear in any directories; instead, the superblock points to them
+ * using block numbers for their location.  The special inodes are:
+ *
+ *   Root inode:  Root directory of the filesystem
+ *   Resource Group Index:  A file containing block numbers and sizes of all RGs
+ *   Journal Index:  A file containing block numbers and sizes of all journals
+ *   Quota:  A file containing all quota information for the filesystem
+ *   License:  A file containing license information
+ *
+ * Note that there is NOTHING RELATED TO INTER-NODE LOCK MANAGEMENT ON-DISK.
+ * Locking is handled completely off-disk, typically via LAN.
+ *
+ * NOTE:
+ * If you add 8 byte fields to these structures, they must be 8 byte
+ * aligned.  4 byte field must be 4 byte aligned, etc...
+ *
+ * All structures must be a multiple of 8 bytes long.
+ *
+ * GRIPES:
+ * We should have forgetten about supporting 512B FS block sizes 
+ * and made the di_reserved field in the struct gfs_dinode structure
+ * much bigger.
+ *
+ * de_rec_len in struct gfs_dirent should really have been a 32-bit value
+ * as it now limits us to a 64k FS block size (with the current code
+ * in dir.c).
+ */
+
+#ifndef __GFS_ONDISK_DOT_H__
+#define __GFS_ONDISK_DOT_H__
+
+#define GFS_MAGIC               (0x01161970) /* for all on-disk headers */
+#define GFS_BASIC_BLOCK         (512)  /* "basic block" = "sector" = 512B */
+#define GFS_BASIC_BLOCK_SHIFT   (9)
+
+/*  Controls how much data can be logged in-core before dumping log to disk */
+
+#define GFS_DUMPS_PER_LOG       (4)    /* 1/4 of on-disk journal size*/
+
+/*  Lock numbers of the LM_TYPE_NONDISK type.  These protect certain
+ *  cluster-wide operations (rather than on-disk entities).
+ *  Currently, the LIVE lock is not used for any real purpose.  */
+
+#define GFS_MOUNT_LOCK          (0)    /* only one node can Mount at a time */
+#define GFS_LIVE_LOCK           (1)    /* shared by all mounted nodes */
+#define GFS_TRANS_LOCK          (2)    /* Transaction, protects jrnl recovery */
+#define GFS_RENAME_LOCK         (3)    /* only one node can Rename at a time */
+
+/*  On-disk format (version) numbers for various metadata types,
+ *  used in gfs_meta_header  */
+
+#define GFS_FORMAT_SB           (100)  /* Super-Block */
+#define GFS_FORMAT_RG           (200)  /* Resource Group Header */
+#define GFS_FORMAT_RB           (300)  /* Resource Group Block Alloc BitBlock */
+#define GFS_FORMAT_DI           (400)  /* "Disk" inode (dinode) */
+#define GFS_FORMAT_IN           (500)  /* Indirect dinode block list */
+#define GFS_FORMAT_LF           (600)  /* Leaf dinode block list */
+#define GFS_FORMAT_JD           (700)  /* Journal Data */
+#define GFS_FORMAT_LH           (800)  /* Log Header */
+#define GFS_FORMAT_LD           (900)  /* Log Descriptor */
+/*  These don't have actual struct gfs_meta_header structures to go with them */
+#define GFS_FORMAT_JI           (1000) /* Journal Index */
+#define GFS_FORMAT_RI           (1100) /* Resource Group Index */
+#define GFS_FORMAT_DE           (1200) /* Directory Entry */
+#define GFS_FORMAT_QU           (1500) /* Quota */
+#define GFS_FORMAT_EA           (1600) /* Extended Attribute */
+#define GFS_FORMAT_ED           (1700) /* Extended Attribute data */
+/*  These version #s are embedded in the superblock  */
+#define GFS_FORMAT_FS           (1309) /* Filesystem (all-encompassing) */
+#define GFS_FORMAT_MULTI        (1401) /* Multi-Host */
+
+/*
+ *  An on-disk inode number
+ *  Initially, the on-disk block address of the inode block is assigned as the
+ *  formal (permanent) ID as well.  Block address can change (to move inode
+ *  on-disk), but formal ID must stay unchanged once assigned.
+ */
+
+#define gfs_inum_equal(ino1, ino2) \
+(((ino1)->no_formal_ino == (ino2)->no_formal_ino) && \
+ ((ino1)->no_addr == (ino2)->no_addr))
+
+struct gfs_inum {
+	uint64_t no_formal_ino;        /* inode identifier */
+	uint64_t no_addr;              /* block # of dinode block */
+};
+
+/*
+ *  Generic metadata head structure
+ *
+ *  Every inplace buffer logged in the journal must start
+ *  with a struct gfs_meta_header.
+ *
+ *  In addition to telling what kind of metadata is in the block,
+ *  the metaheader contains the important generation and incarnation
+ *  numbers.
+ *
+ *  The generation number is used during journal recovery to determine
+ *  whether an in-place block on-disk is older than an on-disk journaled copy
+ *  of the block.  If so, GFS overwrites the in-place block with the journaled
+ *  version of the block.
+ *
+ *  A meta block's generation number must increment monotonically across the
+ *  cluster, each time new contents are committed to the block.  This means
+ *  that whenever GFS allocates a pre-existing metadata block, GFS must read
+ *  that block from disk (in case another node has incremented it).  It also
+ *  means that GFS must sync the block (with incremented generation number)
+ *  to disk (both log and in-place blocks), not only after changing contents
+ *  of the block, but also after de-allocating the block (GFS can't just throw
+ *  away incore metadata for a file that it's just erased).
+ *
+ *  The incarnation number is used only for on-disk (d)inodes.  GFS increments
+ *  it each time it de-allocates a dinode block (i.e. each time the dinode
+ *  loses its identity with a particular file, directory, etc.).  When the
+ *  dinode is later allocated (i.e. to be identified with a new file, etc.),
+ *  GFS copies the incarnation number into the VFS inode's i_generation member.
+ *  If GFS is used as the backing store for an NFS server, GFS uses this
+ *  i_generation number as part of the NFS filehandle, which differentiates
+ *  it from the previous identity of the dinode, and helps protect against
+ *  filesystem corruption that could happen with the use of outdated,
+ *  invalid, or malicious filehandles.  See ops_export.c.
+ *
+ *  GFS caches de-allocated meta-headers, to minimize disk reads.
+ *  See struct gfs_meta_header_cache.
+ */
+
+#define GFS_METATYPE_NONE       (0)
+#define GFS_METATYPE_SB         (1)    /* Super-Block */
+#define GFS_METATYPE_RG         (2)    /* Resource Group Header */
+#define GFS_METATYPE_RB         (3)    /* Resource Group Block Alloc BitBlock */
+#define GFS_METATYPE_DI         (4)    /* "Disk" inode (dinode) */
+#define GFS_METATYPE_IN         (5)    /* Indirect dinode block list */
+#define GFS_METATYPE_LF         (6)    /* Leaf dinode block list */
+#define GFS_METATYPE_JD         (7)    /* Journal Data */
+#define GFS_METATYPE_LH         (8)    /* Log Header (gfs_log_header) */
+#define GFS_METATYPE_LD         (9)    /* Log Descriptor (gfs_log_descriptor) */
+#define GFS_METATYPE_EA         (10)   /* Extended Attribute */
+#define GFS_METATYPE_ED         (11)   /* Extended Attribute data */
+
+#define GFS_META_CLUMP          (64)   /* # blocks to convert fm data to meta */
+
+struct gfs_meta_header {
+	uint32_t mh_magic;      /* GFS_MAGIC sanity check magic number */
+	uint32_t mh_type;       /* GFS_METATYPE_XX type of metadata block */
+	uint64_t mh_generation; /* increment before writing to journal */
+	uint32_t mh_format;     /* GFS_FORMAT_XX (version # for this type) */
+	uint32_t mh_incarn;     /* increment when marking dinode "unused" */
+};
+
+/*
+ *  super-block structure
+ *
+ *  One of these is at beginning of filesystem.
+ *  It's probably good if SIZEOF_SB <= GFS_BASIC_BLOCK (512 bytes)
+ */
+
+/*  Address of SuperBlock in GFS basic blocks.  1st 64K of filesystem is empty
+    for safety against getting clobbered by wayward volume managers, etc.
+    64k was chosen because it's the largest GFS-supported fs block size.  */
+#define GFS_SB_ADDR             (128)
+
+/*  The lock number for the superblock (must be zero)  */
+#define GFS_SB_LOCK             (0)
+#define GFS_CRAP_LOCK           (1)
+
+/*  Requirement:  GFS_LOCKNAME_LEN % 8 == 0
+    Includes: the fencing zero at the end  */
+#define GFS_LOCKNAME_LEN        (64)
+
+struct gfs_sb {
+	/*  Order is important; need to be able to read old superblocks
+	    in order to support on-disk version upgrades */
+	struct gfs_meta_header sb_header;
+
+	uint32_t sb_fs_format;         /* GFS_FORMAT_FS (on-disk version) */
+	uint32_t sb_multihost_format;  /* GFS_FORMAT_MULTI */
+	uint32_t sb_flags;             /* ?? */
+
+	uint32_t sb_bsize;             /* fundamental FS block size in bytes */
+	uint32_t sb_bsize_shift;       /* log2(sb_bsize) */
+	uint32_t sb_seg_size;          /* Journal segment size in FS blocks */
+
+	/* These special inodes do not appear in any on-disk directory. */
+	struct gfs_inum sb_jindex_di;  /* journal index inode */
+	struct gfs_inum sb_rindex_di;  /* resource group index inode */
+	struct gfs_inum sb_root_di;    /* root directory inode */
+
+	/* Default inter-node locking protocol (lock module) and namespace */
+	char sb_lockproto[GFS_LOCKNAME_LEN]; /* lock protocol name */
+	char sb_locktable[GFS_LOCKNAME_LEN]; /* unique name for this FS */
+
+	/* More special inodes */
+	struct gfs_inum sb_quota_di;   /* quota inode */
+	struct gfs_inum sb_license_di; /* license inode */
+
+	char sb_reserved[96];
+};
+
+/*
+ *  journal index structure 
+ *
+ *  One for each journal used by the filesystem.
+ *  These descriptors are packed contiguously within the jindex inode (file).
+ */
+
+struct gfs_jindex {
+	uint64_t ji_addr;       /* starting block of the journal */
+	uint32_t ji_nsegment;   /* number (quantity) of segments in journal */
+	uint32_t ji_pad;
+
+	char ji_reserved[64];
+};
+
+/*
+ *  resource index structure 
+ *
+ *  One of these for each resource group in the filesystem.
+ *  These descriptors are packed contiguously within the rindex inode (file).
+ *  Also see struct gfs_rgrp.
+ */
+
+struct gfs_rindex {
+	uint64_t ri_addr;     /* block # of 1st block (header) in rgrp */
+	uint32_t ri_length;   /* # fs blocks containing rgrp header & bitmap */
+	uint32_t ri_pad;
+
+	uint64_t ri_data1;    /* block # of first data/meta block in rgrp */
+	uint32_t ri_data;     /* number (qty) of data/meta blocks in rgrp */
+
+	uint32_t ri_bitbytes; /* total # bytes used by block alloc bitmap */
+
+	char ri_reserved[64];
+};
+
+/*
+ *  resource group header structure
+ *
+ *  One of these at beginning of the first block of an rgrp,
+ *     followed by block alloc bitmap data in remainder of first block.
+ *  Each resource group contains:
+ *    Header block, including block allocation statistics (struct gfs_rgrp)
+ *       and first part of block alloc bitmap.
+ *    Bitmap block(s), continuing block alloc bitmap started in header block.
+ *    Data/meta blocks, allocatable blocks containing file data and metadata.
+ *  
+ *  In older versions, now-unused (but previously allocated) dinodes were
+ *  saved for re-use in an on-disk linked list (chain).  This is no longer
+ *  done, but support still exists for reclaiming dinodes from this list,
+ *  to support upgrades from older on-disk formats.
+ */
+
+/* Each data block within rgrp is represented by 2 bits in the alloc bitmap */
+#define GFS_NBBY                (4)  /* # blocks represented by 1 bitmap byte */
+#define GFS_BIT_SIZE            (2)
+#define GFS_BIT_MASK            (0x00000003)
+
+/*
+ * 4 possible block allocation states:
+ *   bit 0 = alloc(1)/free(0)
+ *   bit 1 = metadata(1)/data(0)
+ */
+#define GFS_BLKST_FREE          (0)
+#define GFS_BLKST_USED          (1)
+#define GFS_BLKST_FREEMETA      (2)
+#define GFS_BLKST_USEDMETA      (3)
+
+struct gfs_rgrp {
+	struct gfs_meta_header rg_header;
+
+	uint32_t rg_flags;      /* ?? */
+
+	uint32_t rg_free;       /* Number (qty) of free data blocks */
+
+	/* Dinodes are USEDMETA, but are handled separately from other METAs */
+	uint32_t rg_useddi;     /* Number (qty) of dinodes (used or free) */
+	uint32_t rg_freedi;     /* Number (qty) of unused (free) dinodes */
+	struct gfs_inum rg_freedi_list; /* 1st block in chain of free dinodes */
+
+	/* These META statistics do not include dinodes (used or free) */
+	uint32_t rg_usedmeta;   /* Number (qty) of used metadata blocks */
+	uint32_t rg_freemeta;   /* Number (qty) of unused metadata blocks */
+
+	char rg_reserved[64];
+};
+
+/*
+ *  quota structure
+ */
+
+struct gfs_quota {
+	uint64_t qu_limit;
+	uint64_t qu_warn;
+	int64_t qu_value;
+
+	char qu_reserved[64];
+};
+
+/*
+ *  dinode (disk inode) structure
+ *  The ondisk representation of inodes
+ *  One for each file, directory, etc.
+ *  GFS does not put more than one inode in a single block.
+ *  The inode may be "stuffed", carrying file data along with metadata,
+ *    if the file data is small enough.
+ *  Otherwise, the inode block contains pointers to other blocks that contain
+ *    either file data or other pointers to other blocks (indirect addressing
+ *    via a metadata tree).
+ */
+
+#define GFS_MAX_META_HEIGHT     (10)
+#define GFS_DIR_MAX_DEPTH       (17)
+
+/*  Dinode types  */
+#define GFS_FILE_NON            (0)
+#define GFS_FILE_REG            (1)    /* regular file */
+#define GFS_FILE_DIR            (2)    /* directory */
+#define GFS_FILE_LNK            (5)    /* link */
+#define GFS_FILE_BLK            (7)    /* block device node */
+#define GFS_FILE_CHR            (8)    /* character device node */
+#define GFS_FILE_FIFO           (101)  /* fifo/pipe */
+#define GFS_FILE_SOCK           (102)  /* socket */
+
+/*  Dinode flags  */
+#define GFS_DIF_JDATA             (0x00000001) /* jrnl all data for this file */
+#define GFS_DIF_EXHASH            (0x00000002) /* hashed directory (leaves) */
+#define GFS_DIF_UNUSED            (0x00000004) /* unused dinode */
+#define GFS_DIF_EA_INDIRECT       (0x00000008) /* extended attribute, indirect*/
+#define GFS_DIF_DIRECTIO          (0x00000010)
+#define GFS_DIF_IMMUTABLE         (0x00000020) /* Can't change file */
+#define GFS_DIF_APPENDONLY        (0x00000040) /* Can only add to end of file */
+#define GFS_DIF_NOATIME           (0x00000080) /* Don't update access time
+						  (currently unused/ignored) */
+#define GFS_DIF_SYNC              (0x00000100) /* Flush to disk, don't cache
+						  (currently unused/ignored) */
+#define GFS_DIF_INHERIT_DIRECTIO  (0x40000000) /* new files get DIRECTIO flag */
+#define GFS_DIF_INHERIT_JDATA     (0x80000000) /* new files get JDATA flag */
+
+struct gfs_dinode {
+	struct gfs_meta_header di_header;
+
+	struct gfs_inum di_num; /* formal inode # and block address */
+
+	uint32_t di_mode;	/* mode of file */
+	uint32_t di_uid;	/* owner's user id */
+	uint32_t di_gid;	/* owner's group id */
+	uint32_t di_nlink;	/* number (qty) of links to this file */
+	uint64_t di_size;	/* number (qty) of bytes in file */
+	uint64_t di_blocks;	/* number (qty) of blocks in file */
+	int64_t di_atime;	/* time last accessed */
+	int64_t di_mtime;	/* time last modified */
+	int64_t di_ctime;	/* time last changed */
+
+	/*  Non-zero only for character or block device nodes  */
+	uint32_t di_major;	/* device major number */
+	uint32_t di_minor;	/* device minor number */
+
+	/*  Block allocation strategy  */
+	uint64_t di_rgrp;	/* dinode rgrp block number */
+	uint64_t di_goal_rgrp;	/* rgrp to alloc from next */
+	uint32_t di_goal_dblk;	/* data block goal */
+	uint32_t di_goal_mblk;	/* metadata block goal */
+
+	uint32_t di_flags;	/* GFS_DIF_... */
+
+	/*  struct gfs_rindex, struct gfs_jindex, or struct gfs_dirent */
+	uint32_t di_payload_format;  /* GFS_FORMAT_... */
+	uint16_t di_type;	/* GFS_FILE_... type of file */
+	uint16_t di_height;	/* height of metadata (0 == stuffed) */
+	uint32_t di_incarn;	/* incarnation (unused, see gfs_meta_header) */
+	uint16_t di_pad;
+
+	/*  These only apply to directories  */
+	uint16_t di_depth;	/* Number of bits in the table */
+	uint32_t di_entries;	/* The # (qty) of entries in the directory */
+
+	/*  This formed an on-disk chain of unused dinodes  */
+	struct gfs_inum di_next_unused;  /* used in old versions only */
+
+	uint64_t di_eattr;	/* extended attribute block number */
+
+	char di_reserved[56];
+};
+
+/*
+ *  indirect block header
+ *
+ *  A component of a dinode's indirect addressing metadata tree.
+ *  These are pointed to by pointers in dinodes or other indirect blocks.
+ */
+
+struct gfs_indirect {
+	struct gfs_meta_header in_header;
+
+	char in_reserved[64];
+};
+
+/*
+ *  directory structure - many of these per directory file
+ *
+ * See comments at beginning of dir.c
+ */
+
+#define GFS_FNAMESIZE               (255)
+#define GFS_DIRENT_SIZE(name_len) ((sizeof(struct gfs_dirent) + (name_len) + 7) & ~7)
+#define IS_LEAF     (1) /* Hashed (leaf) directory */
+#define IS_DINODE   (2) /* Linear (stuffed dinode block) directory */
+
+struct gfs_dirent {
+	struct gfs_inum de_inum;    /* formal inode number and block address */
+	uint32_t de_hash;           /* hash of the filename */
+	uint16_t de_rec_len;        /* the length of the dirent */
+	uint16_t de_name_len;       /* the length of the name */
+	uint16_t de_type;           /* GFS_FILE_... type of dinode this points to */
+
+	char de_reserved[14];
+};
+
+/*
+ *  Header of leaf directory nodes
+ *
+ * See comments at beginning of dir.c
+ */
+
+struct gfs_leaf {
+	struct gfs_meta_header lf_header;
+
+	uint16_t lf_depth;          /* Depth of leaf */
+	uint16_t lf_entries;        /* Number of dirents in leaf */
+	uint32_t lf_dirent_format;  /* GFS_FORMAT_DE (version #) */
+	uint64_t lf_next;           /* Next leaf, if overflow */
+
+	char lf_reserved[64];
+};
+
+/*
+ *  Log header structure
+ *
+ *  Two of these are in the first block of a transaction log:
+ *    1)  at beginning of block
+ *    2) @end of first 512-byte sector within block
+ */
+
+#define GFS_LOG_HEAD_UNMOUNT    (0x00000001)  /* log is clean, can unmount fs */
+
+struct gfs_log_header {
+	struct gfs_meta_header lh_header;
+
+	uint32_t lh_flags;	/* GFS_LOG_HEAD_... */
+	uint32_t lh_pad;
+
+	uint64_t lh_first;	/* Block number of first header in this trans */
+	uint64_t lh_sequence;	/* Sequence number of this transaction */
+
+	uint64_t lh_tail;	/* Block number of log tail */
+	uint64_t lh_last_dump;	/* Block number of last dump */
+
+	char lh_reserved[64];
+};
+
+/*
+ *  Log type descriptor
+ *
+ *  One of these for each chunk in a transaction
+ */
+
+#define GFS_LOG_DESC_METADATA   (300)    /* metadata */
+/*  ld_data1 is the number (quantity) of metadata blocks in the descriptor.
+    ld_data2 is unused.
+    */
+
+#define GFS_LOG_DESC_IUL        (400)    /* unlinked inode */
+/*  ld_data1 is TRUE if this is a dump.
+    ld_data2 is unused.
+    FixMe!!!  ld_data1 should be the number (quantity) of entries.
+              ld_data2 should be "TRUE if this is a dump".
+    */
+
+#define GFS_LOG_DESC_IDA        (401)    /* de-allocated inode */
+/*  ld_data1 is unused.
+    ld_data2 is unused.
+    FixMe!!!  ld_data1 should be the number (quantity) of entries.
+    */
+
+#define GFS_LOG_DESC_Q          (402)    /* quota */
+/*  ld_data1 is the number of quota changes in the descriptor.
+    ld_data2 is TRUE if this is a dump.
+    */
+
+#define GFS_LOG_DESC_LAST       (500)    /* final in a logged transaction */
+/*  ld_data1 is unused.
+    ld_data2 is unused.
+    */
+
+struct gfs_log_descriptor {
+	struct gfs_meta_header ld_header;
+
+	uint32_t ld_type;	/* GFS_LOG_DESC_... Type of this log chunk */
+	uint32_t ld_length;	/* Number of buffers in this chunk */
+	uint32_t ld_data1;	/* descriptor-specific field */
+	uint32_t ld_data2;	/* descriptor-specific field */
+
+	char ld_reserved[64];
+};
+
+/*
+ *  Metadata block tags
+ *
+ *  One for each logged block.  Tells where block really belongs on-disk.
+ *  These descriptor tags are packed contiguously after a gfs_log_descriptor.
+ */
+
+struct gfs_block_tag {
+	uint64_t bt_blkno;	/* inplace block number */
+	uint32_t bt_flags;	/* ?? */
+	uint32_t bt_pad;
+};
+
+/*
+ *  Quota Journal Tag
+ */
+
+#define GFS_QTF_USER            (0x00000001)
+
+struct gfs_quota_tag {
+	int64_t qt_change;
+	uint32_t qt_flags;      /* GFS_QTF_... */
+	uint32_t qt_id;
+};
+
+/*
+ *  Extended attribute header format
+ */
+
+#define GFS_EA_MAX_NAME_LEN     (255)
+#define GFS_EA_MAX_DATA_LEN     (65536)
+
+#define GFS_EATYPE_UNUSED       (0)
+#define GFS_EATYPE_USR          (1)     /* user attribute */
+#define GFS_EATYPE_SYS          (2)     /* system attribute */
+#define GFS_EATYPE_SECURITY	(3)	/* security attribute */
+
+#define GFS_EATYPE_LAST         (3)
+#define GFS_EATYPE_VALID(x)     ((x) <= GFS_EATYPE_LAST)
+
+#define GFS_EAFLAG_LAST         (0x01)	/* last ea in block */
+
+struct gfs_ea_header {
+	uint32_t ea_rec_len;    /* total record length: hdr + name + data */
+	uint32_t ea_data_len;   /* data length, in bytes */
+	uint8_t ea_name_len;    /* no NULL pointer after the string */
+	uint8_t ea_type;        /* GFS_EATYPE_... */
+	uint8_t ea_flags;       /* GFS_EAFLAG_... */
+	uint8_t ea_num_ptrs;    /* # fs blocks needed for EA */
+	uint32_t ea_pad;
+};
+
+/*  Endian functions  */
+
+#define GFS_ENDIAN_BIG
+
+#ifdef GFS_ENDIAN_BIG
+
+#define gfs16_to_cpu be16_to_cpu
+#define gfs32_to_cpu be32_to_cpu
+#define gfs64_to_cpu be64_to_cpu
+
+#define cpu_to_gfs16 cpu_to_be16
+#define cpu_to_gfs32 cpu_to_be32
+#define cpu_to_gfs64 cpu_to_be64
+
+#else				/*  GFS_ENDIAN_BIG  */
+
+#define gfs16_to_cpu le16_to_cpu
+#define gfs32_to_cpu le32_to_cpu
+#define gfs64_to_cpu le64_to_cpu
+
+#define cpu_to_gfs16 cpu_to_le16
+#define cpu_to_gfs32 cpu_to_le32
+#define cpu_to_gfs64 cpu_to_le64
+
+#endif				/*  GFS_ENDIAN_BIG  */
+
+/*  Translation functions  */
+
+void gfs_inum_in(struct gfs_inum *no, char *buf);
+void gfs_inum_out(struct gfs_inum *no, char *buf);
+void gfs_meta_header_in(struct gfs_meta_header *mh, char *buf);
+void gfs_meta_header_out(struct gfs_meta_header *mh, char *buf);
+void gfs_sb_in(struct gfs_sb *sb, char *buf);
+void gfs_sb_out(struct gfs_sb *sb, char *buf);
+void gfs_jindex_in(struct gfs_jindex *jindex, char *buf);
+void gfs_jindex_out(struct gfs_jindex *jindex, char *buf);
+void gfs_rindex_in(struct gfs_rindex *rindex, char *buf);
+void gfs_rindex_out(struct gfs_rindex *rindex, char *buf);
+void gfs_rgrp_in(struct gfs_rgrp *rgrp, char *buf);
+void gfs_rgrp_out(struct gfs_rgrp *rgrp, char *buf);
+void gfs_quota_in(struct gfs_quota *quota, char *buf);
+void gfs_quota_out(struct gfs_quota *quota, char *buf);
+void gfs_dinode_in(struct gfs_dinode *dinode, char *buf);
+void gfs_dinode_out(struct gfs_dinode *dinode, char *buf);
+void gfs_indirect_in(struct gfs_indirect *indirect, char *buf);
+void gfs_indirect_out(struct gfs_indirect *indirect, char *buf);
+void gfs_dirent_in(struct gfs_dirent *dirent, char *buf);
+void gfs_dirent_out(struct gfs_dirent *dirent, char *buf);
+void gfs_leaf_in(struct gfs_leaf *leaf, char *buf);
+void gfs_leaf_out(struct gfs_leaf *leaf, char *buf);
+void gfs_log_header_in(struct gfs_log_header *head, char *buf);
+void gfs_log_header_out(struct gfs_log_header *head, char *buf);
+void gfs_desc_in(struct gfs_log_descriptor *desc, char *buf);
+void gfs_desc_out(struct gfs_log_descriptor *desc, char *buf);
+void gfs_block_tag_in(struct gfs_block_tag *btag, char *buf);
+void gfs_block_tag_out(struct gfs_block_tag *btag, char *buf);
+void gfs_quota_tag_in(struct gfs_quota_tag *qtag, char *buf);
+void gfs_quota_tag_out(struct gfs_quota_tag *qtag, char *buf);
+void gfs_ea_header_in(struct gfs_ea_header *qtag, char *buf);
+void gfs_ea_header_out(struct gfs_ea_header *qtag, char *buf);
+
+/*  Printing functions  */
+
+void gfs_inum_print(struct gfs_inum *no);
+void gfs_meta_header_print(struct gfs_meta_header *mh);
+void gfs_sb_print(struct gfs_sb *sb);
+void gfs_jindex_print(struct gfs_jindex *jindex);
+void gfs_rindex_print(struct gfs_rindex *rindex);
+void gfs_rgrp_print(struct gfs_rgrp *rgrp);
+void gfs_quota_print(struct gfs_quota *quota);
+void gfs_dinode_print(struct gfs_dinode *dinode);
+void gfs_indirect_print(struct gfs_indirect *indirect);
+void gfs_dirent_print(struct gfs_dirent *dirent, char *name);
+void gfs_leaf_print(struct gfs_leaf *leaf);
+void gfs_log_header_print(struct gfs_log_header *head);
+void gfs_desc_print(struct gfs_log_descriptor *desc);
+void gfs_block_tag_print(struct gfs_block_tag *tag);
+void gfs_quota_tag_print(struct gfs_quota_tag *tag);
+void gfs_ea_header_print(struct gfs_ea_header *ea, char *name);
+
+/*  The hash function for ExHash directories  */
+
+uint32_t gfs_dir_hash(const char *data, int len);
+
+#endif /* __GFS_ONDISK_DOT_H__ */
+
+
+
+#ifdef WANT_GFS_CONVERSION_FUNCTIONS
+
+#define CPIN_08(s1, s2, member, count) {memcpy((s1->member), (s2->member), (count));}
+#define CPOUT_08(s1, s2, member, count) {memcpy((s2->member), (s1->member), (count));}
+#define CPIN_16(s1, s2, member) {(s1->member) = gfs16_to_cpu((s2->member));}
+#define CPOUT_16(s1, s2, member) {(s2->member) = cpu_to_gfs16((s1->member));}
+#define CPIN_32(s1, s2, member) {(s1->member) = gfs32_to_cpu((s2->member));}
+#define CPOUT_32(s1, s2, member) {(s2->member) = cpu_to_gfs32((s1->member));}
+#define CPIN_64(s1, s2, member) {(s1->member) = gfs64_to_cpu((s2->member));}
+#define CPOUT_64(s1, s2, member) {(s2->member) = cpu_to_gfs64((s1->member));}
+
+#define pa(struct, member, count) print_array(#member, struct->member, count);
+
+/**
+ * print_array - Print out an array of bytes
+ * @title: what to print before the array
+ * @buf: the array
+ * @count: the number of bytes
+ *
+ */
+
+static void
+print_array(char *title, char *buf, int count)
+{
+	int x;
+
+	printk("  %s =\n", title);
+	for (x = 0; x < count; x++) {
+		printk("%.2X ", (unsigned char)buf[x]);
+		if (x % 16 == 15)
+			printk("\n");
+	}
+	if (x % 16)
+		printk("\n");
+}
+
+/**
+ * gfs_inum_in - Read in an inode number
+ * @no: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_inum_in(struct gfs_inum *no, char *buf)
+{
+	struct gfs_inum *str = (struct gfs_inum *)buf;
+
+	CPIN_64(no, str, no_formal_ino);
+	CPIN_64(no, str, no_addr);
+}
+
+/**
+ * gfs_inum_out - Write out an inode number
+ * @no: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_inum_out(struct gfs_inum *no, char *buf)
+{
+	struct gfs_inum *str = (struct gfs_inum *)buf;
+
+	CPOUT_64(no, str, no_formal_ino);
+	CPOUT_64(no, str, no_addr);
+}
+
+/**
+ * gfs_inum_print - Print out a inode number
+ * @no: the cpu-order buffer
+ *
+ */
+
+void
+gfs_inum_print(struct gfs_inum *no)
+{
+	pv(no, no_formal_ino, "%"PRIu64);
+	pv(no, no_addr, "%"PRIu64);
+}
+
+/**
+ * gfs_meta_header_in - Read in a metadata header
+ * @mh: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_meta_header_in(struct gfs_meta_header *mh, char *buf)
+{
+	struct gfs_meta_header *str = (struct gfs_meta_header *)buf;
+
+	CPIN_32(mh, str, mh_magic);
+	CPIN_32(mh, str, mh_type);
+	CPIN_64(mh, str, mh_generation);
+	CPIN_32(mh, str, mh_format);
+	CPIN_32(mh, str, mh_incarn);
+}
+
+/**
+ * gfs_meta_header_in - Write out a metadata header
+ * @mh: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ * Don't ever change the generation number in this routine.
+ * It's done manually in increment_generation().
+ */
+
+void
+gfs_meta_header_out(struct gfs_meta_header *mh, char *buf)
+{
+	struct gfs_meta_header *str = (struct gfs_meta_header *)buf;
+
+	CPOUT_32(mh, str, mh_magic);
+	CPOUT_32(mh, str, mh_type);
+#if 0
+	/* Don't do this!
+	   Mh_generation should only be change manually. */
+	CPOUT_64(mh, str, mh_generation);
+#endif
+	CPOUT_32(mh, str, mh_format);
+	CPOUT_32(mh, str, mh_incarn);
+}
+
+/**
+ * gfs_meta_header_print - Print out a metadata header
+ * @mh: the cpu-order buffer
+ *
+ */
+
+void
+gfs_meta_header_print(struct gfs_meta_header *mh)
+{
+	pv(mh, mh_magic, "0x%.8X");
+	pv(mh, mh_type, "%u");
+	pv(mh, mh_generation, "%"PRIu64);
+	pv(mh, mh_format, "%u");
+	pv(mh, mh_incarn, "%u");
+}
+
+/**
+ * gfs_sb_in - Read in a superblock
+ * @sb: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_sb_in(struct gfs_sb *sb, char *buf)
+{
+	struct gfs_sb *str = (struct gfs_sb *)buf;
+
+	gfs_meta_header_in(&sb->sb_header, buf);
+
+	CPIN_32(sb, str, sb_fs_format);
+	CPIN_32(sb, str, sb_multihost_format);
+	CPIN_32(sb, str, sb_flags);
+
+	CPIN_32(sb, str, sb_bsize);
+	CPIN_32(sb, str, sb_bsize_shift);
+	CPIN_32(sb, str, sb_seg_size);
+
+	gfs_inum_in(&sb->sb_jindex_di, (char *)&str->sb_jindex_di);
+	gfs_inum_in(&sb->sb_rindex_di, (char *)&str->sb_rindex_di);
+	gfs_inum_in(&sb->sb_root_di, (char *)&str->sb_root_di);
+
+	CPIN_08(sb, str, sb_lockproto, GFS_LOCKNAME_LEN);
+	CPIN_08(sb, str, sb_locktable, GFS_LOCKNAME_LEN);
+
+	gfs_inum_in(&sb->sb_quota_di, (char *)&str->sb_quota_di);
+	gfs_inum_in(&sb->sb_license_di, (char *)&str->sb_license_di);
+
+	CPIN_08(sb, str, sb_reserved, 96);
+}
+
+/**
+ * gfs_sb_out - Write out a superblock
+ * @sb: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_sb_out(struct gfs_sb *sb, char *buf)
+{
+	struct gfs_sb *str = (struct gfs_sb *)buf;
+
+	gfs_meta_header_out(&sb->sb_header, buf);
+
+	CPOUT_32(sb, str, sb_fs_format);
+	CPOUT_32(sb, str, sb_multihost_format);
+	CPOUT_32(sb, str, sb_flags);
+
+	CPOUT_32(sb, str, sb_bsize);
+	CPOUT_32(sb, str, sb_bsize_shift);
+	CPOUT_32(sb, str, sb_seg_size);
+
+	gfs_inum_out(&sb->sb_jindex_di, (char *)&str->sb_jindex_di);
+	gfs_inum_out(&sb->sb_rindex_di, (char *)&str->sb_rindex_di);
+	gfs_inum_out(&sb->sb_root_di, (char *)&str->sb_root_di);
+
+	CPOUT_08(sb, str, sb_lockproto, GFS_LOCKNAME_LEN);
+	CPOUT_08(sb, str, sb_locktable, GFS_LOCKNAME_LEN);
+
+	gfs_inum_out(&sb->sb_quota_di, (char *)&str->sb_quota_di);
+	gfs_inum_out(&sb->sb_license_di, (char *)&str->sb_license_di);
+
+	CPOUT_08(sb, str, sb_reserved, 96);
+}
+
+/**
+ * gfs_sb_print - Print out a superblock
+ * @sb: the cpu-order buffer
+ *
+ */
+
+void
+gfs_sb_print(struct gfs_sb *sb)
+{
+	gfs_meta_header_print(&sb->sb_header);
+
+	pv(sb, sb_fs_format, "%u");
+	pv(sb, sb_multihost_format, "%u");
+	pv(sb, sb_flags, "%u");
+
+	pv(sb, sb_bsize, "%u");
+	pv(sb, sb_bsize_shift, "%u");
+	pv(sb, sb_seg_size, "%u");
+
+	gfs_inum_print(&sb->sb_jindex_di);
+	gfs_inum_print(&sb->sb_rindex_di);
+	gfs_inum_print(&sb->sb_root_di);
+
+	pv(sb, sb_lockproto, "%s");
+	pv(sb, sb_locktable, "%s");
+
+	gfs_inum_print(&sb->sb_quota_di);
+	gfs_inum_print(&sb->sb_license_di);
+
+	pa(sb, sb_reserved, 96);
+}
+
+/**
+ * gfs_jindex_in - Read in a journal index structure
+ * @jindex: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_jindex_in(struct gfs_jindex *jindex, char *buf)
+{
+	struct gfs_jindex *str = (struct gfs_jindex *)buf;
+
+	CPIN_64(jindex, str, ji_addr);
+	CPIN_32(jindex, str, ji_nsegment);
+	CPIN_32(jindex, str, ji_pad);
+
+	CPIN_08(jindex, str, ji_reserved, 64);
+}
+
+/**
+ * gfs_jindex_out - Write out a journal index structure
+ * @jindex: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_jindex_out(struct gfs_jindex *jindex, char *buf)
+{
+	struct gfs_jindex *str = (struct gfs_jindex *)buf;
+
+	CPOUT_64(jindex, str, ji_addr);
+	CPOUT_32(jindex, str, ji_nsegment);
+	CPOUT_32(jindex, str, ji_pad);
+
+	CPOUT_08(jindex, str, ji_reserved, 64);
+}
+
+/**
+ * gfs_jindex_print - Print out a journal index structure
+ * @ji: the cpu-order buffer
+ *
+ */
+
+void
+gfs_jindex_print(struct gfs_jindex *ji)
+{
+	pv(ji, ji_addr, "%"PRIu64);
+	pv(ji, ji_nsegment, "%u");
+	pv(ji, ji_pad, "%u");
+
+	pa(ji, ji_reserved, 64);
+}
+
+/**
+ * gfs_rindex_in - Read in a resource index structure
+ * @rindex: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_rindex_in(struct gfs_rindex *rindex, char *buf)
+{
+	struct gfs_rindex *str = (struct gfs_rindex *)buf;
+
+	CPIN_64(rindex, str, ri_addr);
+	CPIN_32(rindex, str, ri_length);
+	CPIN_32(rindex, str, ri_pad);
+
+	CPIN_64(rindex, str, ri_data1);
+	CPIN_32(rindex, str, ri_data);
+
+	CPIN_32(rindex, str, ri_bitbytes);
+
+	CPIN_08(rindex, str, ri_reserved, 64);
+}
+
+/**
+ * gfs_rindex_out - Write out a resource index structure
+ * @rindex: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_rindex_out(struct gfs_rindex *rindex, char *buf)
+{
+	struct gfs_rindex *str = (struct gfs_rindex *)buf;
+
+	CPOUT_64(rindex, str, ri_addr);
+	CPOUT_32(rindex, str, ri_length);
+	CPOUT_32(rindex, str, ri_pad);
+
+	CPOUT_64(rindex, str, ri_data1);
+	CPOUT_32(rindex, str, ri_data);
+
+	CPOUT_32(rindex, str, ri_bitbytes);
+
+	CPOUT_08(rindex, str, ri_reserved, 64);
+}
+
+/**
+ * gfs_rindex_print - Print out a resource index structure
+ * @ri: the cpu-order buffer
+ *
+ */
+
+void
+gfs_rindex_print(struct gfs_rindex *ri)
+{
+	pv(ri, ri_addr, "%"PRIu64);
+	pv(ri, ri_length, "%u");
+	pv(ri, ri_pad, "%u");
+
+	pv(ri, ri_data1, "%"PRIu64);
+	pv(ri, ri_data, "%u");
+
+	pv(ri, ri_bitbytes, "%u");
+
+	pa(ri, ri_reserved, 64);
+}
+
+/**
+ * gfs_rgrp_in - Read in a resource group header
+ * @rgrp: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_rgrp_in(struct gfs_rgrp *rgrp, char *buf)
+{
+	struct gfs_rgrp *str = (struct gfs_rgrp *)buf;
+
+	gfs_meta_header_in(&rgrp->rg_header, buf);
+
+	CPIN_32(rgrp, str, rg_flags);
+
+	CPIN_32(rgrp, str, rg_free);
+
+	CPIN_32(rgrp, str, rg_useddi);
+	CPIN_32(rgrp, str, rg_freedi);
+	gfs_inum_in(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list);
+
+	CPIN_32(rgrp, str, rg_usedmeta);
+	CPIN_32(rgrp, str, rg_freemeta);
+
+	CPIN_08(rgrp, str, rg_reserved, 64);
+}
+
+/**
+ * gfs_rgrp_out - Write out a resource group header
+ * @rgrp: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_rgrp_out(struct gfs_rgrp *rgrp, char *buf)
+{
+	struct gfs_rgrp *str = (struct gfs_rgrp *)buf;
+
+	gfs_meta_header_out(&rgrp->rg_header, buf);
+
+	CPOUT_32(rgrp, str, rg_flags);
+
+	CPOUT_32(rgrp, str, rg_free);
+
+	CPOUT_32(rgrp, str, rg_useddi);
+	CPOUT_32(rgrp, str, rg_freedi);
+	gfs_inum_out(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list);
+
+	CPOUT_32(rgrp, str, rg_usedmeta);
+	CPOUT_32(rgrp, str, rg_freemeta);
+
+	CPOUT_08(rgrp, str, rg_reserved, 64);
+}
+
+/**
+ * gfs_rgrp_print - Print out a resource group header
+ * @rg: the cpu-order buffer
+ *
+ */
+
+void
+gfs_rgrp_print(struct gfs_rgrp *rg)
+{
+	gfs_meta_header_print(&rg->rg_header);
+
+	pv(rg, rg_flags, "%u");
+
+	pv(rg, rg_free, "%u");
+
+	pv(rg, rg_useddi, "%u");
+	pv(rg, rg_freedi, "%u");
+	gfs_inum_print(&rg->rg_freedi_list);
+
+	pv(rg, rg_usedmeta, "%u");
+	pv(rg, rg_freemeta, "%u");
+
+	pa(rg, rg_reserved, 64);
+}
+
+/**
+ * gfs_quota_in - Read in a quota structures
+ * @quota: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_quota_in(struct gfs_quota *quota, char *buf)
+{
+	struct gfs_quota *str = (struct gfs_quota *)buf;
+
+	CPIN_64(quota, str, qu_limit);
+	CPIN_64(quota, str, qu_warn);
+	CPIN_64(quota, str, qu_value);
+
+	CPIN_08(quota, str, qu_reserved, 64);
+}
+
+/**
+ * gfs_quota_out - Write out a quota structure
+ * @quota: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_quota_out(struct gfs_quota *quota, char *buf)
+{
+	struct gfs_quota *str = (struct gfs_quota *)buf;
+
+	CPOUT_64(quota, str, qu_limit);
+	CPOUT_64(quota, str, qu_warn);
+	CPOUT_64(quota, str, qu_value);
+
+	CPOUT_08(quota, str, qu_reserved, 64);
+}
+
+/**
+ * gfs_quota_print - Print out a quota structure
+ * @quota: the cpu-order buffer
+ *
+ */
+
+void
+gfs_quota_print(struct gfs_quota *quota)
+{
+	pv(quota, qu_limit, "%"PRIu64);
+	pv(quota, qu_warn, "%"PRIu64);
+	pv(quota, qu_value, "%"PRId64);
+
+	pa(quota, qu_reserved, 64);
+}
+
+/**
+ * gfs_dinode_in - Read in a dinode
+ * @dinode: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_dinode_in(struct gfs_dinode *dinode, char *buf)
+{
+	struct gfs_dinode *str = (struct gfs_dinode *)buf;
+
+	gfs_meta_header_in(&dinode->di_header, buf);
+
+	gfs_inum_in(&dinode->di_num, (char *)&str->di_num);
+
+	CPIN_32(dinode, str, di_mode);
+	CPIN_32(dinode, str, di_uid);
+	CPIN_32(dinode, str, di_gid);
+	CPIN_32(dinode, str, di_nlink);
+	CPIN_64(dinode, str, di_size);
+	CPIN_64(dinode, str, di_blocks);
+	CPIN_64(dinode, str, di_atime);
+	CPIN_64(dinode, str, di_mtime);
+	CPIN_64(dinode, str, di_ctime);
+	CPIN_32(dinode, str, di_major);
+	CPIN_32(dinode, str, di_minor);
+
+	CPIN_64(dinode, str, di_rgrp);
+	CPIN_64(dinode, str, di_goal_rgrp);
+	CPIN_32(dinode, str, di_goal_dblk);
+	CPIN_32(dinode, str, di_goal_mblk);
+	CPIN_32(dinode, str, di_flags);
+	CPIN_32(dinode, str, di_payload_format);
+	CPIN_16(dinode, str, di_type);
+	CPIN_16(dinode, str, di_height);
+	CPIN_32(dinode, str, di_incarn);
+	CPIN_16(dinode, str, di_pad);
+
+	CPIN_16(dinode, str, di_depth);
+	CPIN_32(dinode, str, di_entries);
+
+	gfs_inum_in(&dinode->di_next_unused, (char *)&str->di_next_unused);
+
+	CPIN_64(dinode, str, di_eattr);
+
+	CPIN_08(dinode, str, di_reserved, 56);
+}
+
+/**
+ * gfs_dinode_out - Write out a dinode
+ * @dinode: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_dinode_out(struct gfs_dinode *dinode, char *buf)
+{
+	struct gfs_dinode *str = (struct gfs_dinode *)buf;
+
+	gfs_meta_header_out(&dinode->di_header, buf);
+
+	gfs_inum_out(&dinode->di_num, (char *)&str->di_num);
+
+	CPOUT_32(dinode, str, di_mode);
+	CPOUT_32(dinode, str, di_uid);
+	CPOUT_32(dinode, str, di_gid);
+	CPOUT_32(dinode, str, di_nlink);
+	CPOUT_64(dinode, str, di_size);
+	CPOUT_64(dinode, str, di_blocks);
+	CPOUT_64(dinode, str, di_atime);
+	CPOUT_64(dinode, str, di_mtime);
+	CPOUT_64(dinode, str, di_ctime);
+	CPOUT_32(dinode, str, di_major);
+	CPOUT_32(dinode, str, di_minor);
+
+	CPOUT_64(dinode, str, di_rgrp);
+	CPOUT_64(dinode, str, di_goal_rgrp);
+	CPOUT_32(dinode, str, di_goal_dblk);
+	CPOUT_32(dinode, str, di_goal_mblk);
+	CPOUT_32(dinode, str, di_flags);
+	CPOUT_32(dinode, str, di_payload_format);
+	CPOUT_16(dinode, str, di_type);
+	CPOUT_16(dinode, str, di_height);
+	CPOUT_32(dinode, str, di_incarn);
+	CPOUT_16(dinode, str, di_pad);
+
+	CPOUT_16(dinode, str, di_depth);
+	CPOUT_32(dinode, str, di_entries);
+
+	gfs_inum_out(&dinode->di_next_unused, (char *)&str->di_next_unused);
+
+	CPOUT_64(dinode, str, di_eattr);
+
+	CPOUT_08(dinode, str, di_reserved, 56);
+}
+
+/**
+ * gfs_dinode_print - Print out a dinode
+ * @di: the cpu-order buffer
+ *
+ */
+
+void
+gfs_dinode_print(struct gfs_dinode *di)
+{
+	gfs_meta_header_print(&di->di_header);
+
+	gfs_inum_print(&di->di_num);
+
+	pv(di, di_mode, "0%o");
+	pv(di, di_uid, "%u");
+	pv(di, di_gid, "%u");
+	pv(di, di_nlink, "%u");
+	pv(di, di_size, "%"PRIu64);
+	pv(di, di_blocks, "%"PRIu64);
+	pv(di, di_atime, "%"PRId64);
+	pv(di, di_mtime, "%"PRId64);
+	pv(di, di_ctime, "%"PRId64);
+	pv(di, di_major, "%u");
+	pv(di, di_minor, "%u");
+
+	pv(di, di_rgrp, "%"PRIu64);
+	pv(di, di_goal_rgrp, "%"PRIu64);
+	pv(di, di_goal_dblk, "%u");
+	pv(di, di_goal_mblk, "%u");
+	pv(di, di_flags, "0x%.8X");
+	pv(di, di_payload_format, "%u");
+	pv(di, di_type, "%u");
+	pv(di, di_height, "%u");
+	pv(di, di_incarn, "%u");
+	pv(di, di_pad, "%u");
+
+	pv(di, di_depth, "%u");
+	pv(di, di_entries, "%u");
+
+	gfs_inum_print(&di->di_next_unused);
+
+	pv(di, di_eattr, "%"PRIu64);
+
+	pa(di, di_reserved, 56);
+}
+
+/**
+ * gfs_indirect_in - copy in the header of an indirect block
+ * @indirect: the in memory copy
+ * @buf: the buffer copy
+ *
+ */
+
+void
+gfs_indirect_in(struct gfs_indirect *indirect, char *buf)
+{
+	struct gfs_indirect *str = (struct gfs_indirect *)buf;
+
+	gfs_meta_header_in(&indirect->in_header, buf);
+
+	CPIN_08(indirect, str, in_reserved, 64);
+}
+
+/**
+ * gfs_indirect_out - copy out the header of an indirect block
+ * @indirect: the in memory copy
+ * @buf: the buffer copy
+ *
+ */
+
+void
+gfs_indirect_out(struct gfs_indirect *indirect, char *buf)
+{
+	struct gfs_indirect *str = (struct gfs_indirect *)buf;
+
+	gfs_meta_header_out(&indirect->in_header, buf);
+
+	CPOUT_08(indirect, str, in_reserved, 64);
+}
+
+/**
+ * gfs_indirect_print - Print out a indirect block header
+ * @indirect: the cpu-order buffer
+ *
+ */
+
+void
+gfs_indirect_print(struct gfs_indirect *indirect)
+{
+	gfs_meta_header_print(&indirect->in_header);
+
+	pa(indirect, in_reserved, 64);
+}
+
+/**
+ * gfs_dirent_in - Read in a directory entry
+ * @dirent: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_dirent_in(struct gfs_dirent *dirent, char *buf)
+{
+	struct gfs_dirent *str = (struct gfs_dirent *)buf;
+
+	gfs_inum_in(&dirent->de_inum, (char *)&str->de_inum);
+	CPIN_32(dirent, str, de_hash);
+	CPIN_16(dirent, str, de_rec_len);
+	CPIN_16(dirent, str, de_name_len);
+	CPIN_16(dirent, str, de_type);
+
+	CPIN_08(dirent, str, de_reserved, 14);
+}
+
+/**
+ * gfs_dirent_out - Write out a directory entry
+ * @dirent: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_dirent_out(struct gfs_dirent *dirent, char *buf)
+{
+	struct gfs_dirent *str = (struct gfs_dirent *)buf;
+
+	gfs_inum_out(&dirent->de_inum, (char *)&str->de_inum);
+	CPOUT_32(dirent, str, de_hash);
+	CPOUT_16(dirent, str, de_rec_len);
+	CPOUT_16(dirent, str, de_name_len);
+	CPOUT_16(dirent, str, de_type);
+
+	CPOUT_08(dirent, str, de_reserved, 14);
+}
+
+/**
+ * gfs_dirent_print - Print out a directory entry
+ * @de: the cpu-order buffer
+ * @name: the filename
+ *
+ */
+
+void
+gfs_dirent_print(struct gfs_dirent *de, char *name)
+{
+	char buf[GFS_FNAMESIZE + 1];
+
+	gfs_inum_print(&de->de_inum);
+	pv(de, de_hash, "0x%.8X");
+	pv(de, de_rec_len, "%u");
+	pv(de, de_name_len, "%u");
+	pv(de, de_type, "%u");
+
+	pa(de, de_reserved, 14);
+
+	memset(buf, 0, GFS_FNAMESIZE + 1);
+	memcpy(buf, name, de->de_name_len);
+	printk("  name = %s\n", buf);
+}
+
+/**
+ * gfs_leaf_in - Read in a directory leaf header
+ * @leaf: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_leaf_in(struct gfs_leaf *leaf, char *buf)
+{
+	struct gfs_leaf *str = (struct gfs_leaf *)buf;
+
+	gfs_meta_header_in(&leaf->lf_header, buf);
+
+	CPIN_16(leaf, str, lf_depth);
+	CPIN_16(leaf, str, lf_entries);
+	CPIN_32(leaf, str, lf_dirent_format);
+	CPIN_64(leaf, str, lf_next);
+
+	CPIN_08(leaf, str, lf_reserved, 64);
+}
+
+/**
+ * gfs_leaf_out - Write out a directory leaf header
+ * @leaf: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_leaf_out(struct gfs_leaf *leaf, char *buf)
+{
+	struct gfs_leaf *str = (struct gfs_leaf *)buf;
+
+	gfs_meta_header_out(&leaf->lf_header, buf);
+
+	CPOUT_16(leaf, str, lf_depth);
+	CPOUT_16(leaf, str, lf_entries);
+	CPOUT_32(leaf, str, lf_dirent_format);
+	CPOUT_64(leaf, str, lf_next);
+
+	CPOUT_08(leaf, str, lf_reserved, 64);
+}
+
+/**
+ * gfs_leaf_print - Print out a directory leaf header
+ * @lf: the cpu-order buffer
+ *
+ */
+
+void
+gfs_leaf_print(struct gfs_leaf *lf)
+{
+	gfs_meta_header_print(&lf->lf_header);
+
+	pv(lf, lf_depth, "%u");
+	pv(lf, lf_entries, "%u");
+	pv(lf, lf_dirent_format, "%u");
+	pv(lf, lf_next, "%"PRIu64);
+
+	pa(lf, lf_reserved, 64);
+}
+
+/**
+ * gfs_log_header_in - Read in a log header
+ * @head: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_log_header_in(struct gfs_log_header *head, char *buf)
+{
+	struct gfs_log_header *str = (struct gfs_log_header *)buf;
+
+	gfs_meta_header_in(&head->lh_header, buf);
+
+	CPIN_32(head, str, lh_flags);
+	CPIN_32(head, str, lh_pad);
+
+	CPIN_64(head, str, lh_first);
+	CPIN_64(head, str, lh_sequence);
+
+	CPIN_64(head, str, lh_tail);
+	CPIN_64(head, str, lh_last_dump);
+
+	CPIN_08(head, str, lh_reserved, 64);
+}
+
+/**
+ * gfs_log_header_out - Write out a log header
+ * @head: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_log_header_out(struct gfs_log_header *head, char *buf)
+{
+	struct gfs_log_header *str = (struct gfs_log_header *)buf;
+
+	gfs_meta_header_out(&head->lh_header, buf);
+
+	CPOUT_32(head, str, lh_flags);
+	CPOUT_32(head, str, lh_pad);
+
+	CPOUT_64(head, str, lh_first);
+	CPOUT_64(head, str, lh_sequence);
+
+	CPOUT_64(head, str, lh_tail);
+	CPOUT_64(head, str, lh_last_dump);
+
+	CPOUT_08(head, str, lh_reserved, 64);
+}
+
+/**
+ * gfs_log_header_print - Print out a log header
+ * @head: the cpu-order buffer
+ *
+ */
+
+void
+gfs_log_header_print(struct gfs_log_header *lh)
+{
+	gfs_meta_header_print(&lh->lh_header);
+
+	pv(lh, lh_flags, "0x%.8X");
+	pv(lh, lh_pad, "%u");
+
+	pv(lh, lh_first, "%"PRIu64);
+	pv(lh, lh_sequence, "%"PRIu64);
+
+	pv(lh, lh_tail, "%"PRIu64);
+	pv(lh, lh_last_dump, "%"PRIu64);
+
+	pa(lh, lh_reserved, 64);
+}
+
+/**
+ * gfs_desc_in - Read in a log descriptor
+ * @desc: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_desc_in(struct gfs_log_descriptor *desc, char *buf)
+{
+	struct gfs_log_descriptor *str = (struct gfs_log_descriptor *)buf;
+
+	gfs_meta_header_in(&desc->ld_header, buf);
+
+	CPIN_32(desc, str, ld_type);
+	CPIN_32(desc, str, ld_length);
+	CPIN_32(desc, str, ld_data1);
+	CPIN_32(desc, str, ld_data2);
+
+	CPIN_08(desc, str, ld_reserved, 64);
+}
+
+/**
+ * gfs_desc_out - Write out a log descriptor
+ * @desc: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_desc_out(struct gfs_log_descriptor *desc, char *buf)
+{
+	struct gfs_log_descriptor *str = (struct gfs_log_descriptor *)buf;
+
+	gfs_meta_header_out(&desc->ld_header, buf);
+
+	CPOUT_32(desc, str, ld_type);
+	CPOUT_32(desc, str, ld_length);
+	CPOUT_32(desc, str, ld_data1);
+	CPOUT_32(desc, str, ld_data2);
+
+	CPOUT_08(desc, str, ld_reserved, 64);
+}
+
+/**
+ * gfs_desc_print - Print out a log descriptor
+ * @ld: the cpu-order buffer
+ *
+ */
+
+void
+gfs_desc_print(struct gfs_log_descriptor *ld)
+{
+	gfs_meta_header_print(&ld->ld_header);
+
+	pv(ld, ld_type, "%u");
+	pv(ld, ld_length, "%u");
+	pv(ld, ld_data1, "%u");
+	pv(ld, ld_data2, "%u");
+
+	pa(ld, ld_reserved, 64);
+}
+
+/**
+ * gfs_block_tag_in - Read in a block tag
+ * @tag: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_block_tag_in(struct gfs_block_tag *tag, char *buf)
+{
+	struct gfs_block_tag *str = (struct gfs_block_tag *)buf;
+
+	CPIN_64(tag, str, bt_blkno);
+	CPIN_32(tag, str, bt_flags);
+	CPIN_32(tag, str, bt_pad);
+}
+
+/**
+ * gfs_block_tag_out - Write out a block tag
+ * @tag: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_block_tag_out(struct gfs_block_tag *tag, char *buf)
+{
+	struct gfs_block_tag *str = (struct gfs_block_tag *)buf;
+
+	CPOUT_64(tag, str, bt_blkno);
+	CPOUT_32(tag, str, bt_flags);
+	CPOUT_32(tag, str, bt_pad);
+}
+
+/**
+ * gfs_block_tag_print - Print out a block tag
+ * @tag: the cpu-order buffer
+ *
+ */
+
+void
+gfs_block_tag_print(struct gfs_block_tag *tag)
+{
+	pv(tag, bt_blkno, "%"PRIu64);
+	pv(tag, bt_flags, "%u");
+	pv(tag, bt_pad, "%u");
+}
+
+/**
+ * gfs_quota_tag_in - Read in a quota tag
+ * @tag: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_quota_tag_in(struct gfs_quota_tag *tag, char *buf)
+{
+	struct gfs_quota_tag *str = (struct gfs_quota_tag *)buf;
+
+	CPIN_64(tag, str, qt_change);
+	CPIN_32(tag, str, qt_flags);
+	CPIN_32(tag, str, qt_id);
+}
+
+/**
+ * gfs_quota_tag_out - Write out a quota tag
+ * @tag: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_quota_tag_out(struct gfs_quota_tag *tag, char *buf)
+{
+	struct gfs_quota_tag *str = (struct gfs_quota_tag *)buf;
+
+	CPOUT_64(tag, str, qt_change);
+	CPOUT_32(tag, str, qt_flags);
+	CPOUT_32(tag, str, qt_id);
+}
+
+/**
+ * gfs_quota_tag_print - Print out a quota tag
+ * @tag: the cpu-order buffer
+ *
+ */
+
+void
+gfs_quota_tag_print(struct gfs_quota_tag *tag)
+{
+	pv(tag, qt_change, "%"PRId64);
+	pv(tag, qt_flags, "0x%.8X");
+	pv(tag, qt_id, "%u");
+}
+
+/**
+ * gfs_ea_header_in - Read in a Extended Attribute header
+ * @tag: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_ea_header_in(struct gfs_ea_header *ea, char *buf)
+{
+	struct gfs_ea_header *str = (struct gfs_ea_header *)buf;
+
+	CPIN_32(ea, str, ea_rec_len);
+	CPIN_32(ea, str, ea_data_len);
+	ea->ea_name_len = str->ea_name_len;
+	ea->ea_type = str->ea_type;
+	ea->ea_flags = str->ea_flags;
+	ea->ea_num_ptrs = str->ea_num_ptrs;
+	CPIN_32(ea, str, ea_pad);
+}
+
+/**
+ * gfs_ea_header_out - Write out a Extended Attribute header
+ * @ea: the cpu-order structure
+ * @buf: the disk-order buffer
+ *
+ */
+
+void
+gfs_ea_header_out(struct gfs_ea_header *ea, char *buf)
+{
+	struct gfs_ea_header *str = (struct gfs_ea_header *)buf;
+
+	CPOUT_32(ea, str, ea_rec_len);
+	CPOUT_32(ea, str, ea_data_len);
+	str->ea_name_len = ea->ea_name_len;
+	str->ea_type = ea->ea_type;
+	str->ea_flags = ea->ea_flags;
+	str->ea_num_ptrs = ea->ea_num_ptrs;
+	CPOUT_32(ea, str, ea_pad);
+}
+
+/**
+ * gfs_ea_header_printt - Print out a Extended Attribute header
+ * @ea: the cpu-order buffer
+ *
+ */
+
+void
+gfs_ea_header_print(struct gfs_ea_header *ea, char *name)
+{
+	char buf[GFS_EA_MAX_NAME_LEN + 1];
+
+	pv(ea, ea_rec_len, "%u");
+	pv(ea, ea_data_len, "%u");
+	pv(ea, ea_name_len, "%u");
+	pv(ea, ea_type, "%u");
+	pv(ea, ea_flags, "%u");
+	pv(ea, ea_num_ptrs, "%u");
+	pv(ea, ea_pad, "%u");
+
+	memset(buf, 0, GFS_EA_MAX_NAME_LEN + 1);
+	memcpy(buf, name, ea->ea_name_len);
+	printk("  name = %s\n", buf);
+}
+
+static const uint32_t crc_32_tab[] =
+{
+  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+  0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+  0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+  0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+  0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+  0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+  0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+  0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+  0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+  0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+  0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+  0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+  0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+  0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+  0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+  0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+  0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+  0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+  0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+  0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+  0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+  0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+  0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+  0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+  0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+  0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+  0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+  0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+  0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+  0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+/**
+ * gfs_dir_hash - hash an array of data
+ * @data: the data to be hashed
+ * @len: the length of data to be hashed
+ *
+ * Take some data and convert it to a 32-bit hash.
+ *
+ * The hash function is a 32-bit CRC of the data.  The algorithm uses
+ * the crc_32_tab table above.
+ *
+ * This may not be the fastest hash function, but it does a fair bit better
+ * at providing uniform results than the others I've looked at.  That's
+ * really important for efficient directories.
+ *
+ * Returns: the hash
+ */
+
+uint32_t
+gfs_dir_hash(const char *data, int len)
+{
+	uint32_t hash = 0xFFFFFFFF;
+
+	for (; len--; data++)
+		hash = crc_32_tab[(hash ^ *data) & 0xFF] ^ (hash >> 8);
+
+	hash = ~hash;
+
+	return hash;
+}
+
+#endif  /* WANT_GFS_CONVERSION_FUNCTIONS */
+
--- conga/ricci/modules/storage/Makefile	2006/09/14 17:52:04	1.11
+++ conga/ricci/modules/storage/Makefile	2006/09/26 03:17:41	1.12
@@ -37,6 +37,9 @@
 	FSController.o \
 	ContentFS.o \
 	ExtendedFS.o \
+	GFS1.o \
+	GFS2.o \
+	UnsupportedFS.o \
 	System.o \
 	parted_wrapper.o \
 	PartitionTable.o \
--- conga/luci/site/luci/Extensions/conga_storage_constants.py	2006/08/03 18:56:10	1.3
+++ conga/luci/site/luci/Extensions/conga_storage_constants.py	2006/09/26 03:17:41	1.4
@@ -91,6 +91,7 @@
                          'block_count'             : "Number of Blocks",
                          'block_size'              : "Block Size",
                          'bootable'                : "Bootable",
+                         'cluster_name'            : "Cluster Name",
                          'clustered'               : "Clustered",
                          'dir_index'               : "Use Hashed Binary Trees",
                          'disklabel'               : "Partition Table Type",
@@ -102,9 +103,13 @@
                          'format'                  : "Format",
                          'fstab'                   : "List in /etc/fstab", 
                          'fstabpoint'              : "/etc/fstab Mountpoint", 
+                         'gfs_fsname'              : "Unique GFS Name", 
                          'has_journal'             : "Journaling Enabled",
+                         'journals_num'            : "Number Of Journals", 
+                         'journal_size'            : "Journal Size", 
                          'label'                   : "Label",
                          'level'                   : "Level",
+                         'locking_protocol'        : "Locking Protocol",
                          'lvname'                  : "Logical Volume Name",
                          'max_lvs'                 : "Maximum Logical Volumes",
                          'max_pvs'                 : "Maximum Physical Volumes",
@@ -113,6 +118,7 @@
                          'mirrored'                : "Mirrored",
                          'model'                   : "Model",
                          'mount'                   : "Mount",
+                         'mountable'               : "Mountable",
                          'mountpoint'              : "Mountpoint", 
                          'num_devices'             : "Number of Devices",
                          'num_spares'              : "Number of Spares",
--- conga/luci/site/luci/Extensions/StorageReport.py	2006/08/03 18:56:10	1.6
+++ conga/luci/site/luci/Extensions/StorageReport.py	2006/09/26 03:17:41	1.7
@@ -887,7 +887,7 @@
                             req_name = 'content_variable_' + selected_content_id + '_' + var_name
                             if req_name in request:
                                 if selected_content_data['props'][req_name]['type'] == 'int':
-                                    val = int(request[var_name])
+                                    val = int(request[req_name])
                                     step = int(selected_content_data['props'][req_name]['validation']['step'])
                                     val = (val / step) * step
                                     node.setAttribute('value', str(val))
@@ -1030,7 +1030,7 @@
                                 req_name = 'content_variable_' + selected_content_id + '_' + var_name
                                 if req_name in request:
                                     if selected_content_data['props'][req_name]['type'] == 'int':
-                                        val = int(request[var_name])
+                                        val = int(request[req_name])
                                         step = int(selected_content_data['props'][req_name]['validation']['step'])
                                         val = (val / step) * step
                                         node.setAttribute('value', str(val))



                 reply	other threads:[~2006-09-26  3:17 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20060926031743.2219.qmail@sourceware.org \
    --to=kupcevic@sourceware.org \
    /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.