fedora-ize | 2
pkg/cloudfs.spec | 13 +
pkg/cloudfs.spec.in | 13 +
scripts/cloudfs | 206 ++++++++++++++++++++++++++++
scripts/volfilter.py | 16 +-
xlators/cluster/cloud/src/cloud-mem-types.h | 2
xlators/cluster/cloud/src/cloud.c | 10 -
xlators/cluster/login/src/login.c | 6
xlators/encryption/crypt/src/crypt.c | 8 -
xlators/encryption/crypt/src/crypt.h | 2
xlators/features/oplock/src/oplock.c | 8 -
xlators/features/oplock/src/oplock.h | 2
12 files changed, 260 insertions(+), 28 deletions(-)
New commits:
commit a187af3d67739c5fd7701740bd1a715519ab64b7
Author: Jeff Darcy <jdarcy(a)redhat.com>
Date: Wed Jan 26 15:39:23 2011 -0500
Update build stuff to include cloudfs/volfilter
diff --git a/fedora-ize b/fedora-ize
index 604259b..c5bca93 100755
--- a/fedora-ize
+++ b/fedora-ize
@@ -30,6 +30,8 @@ cd -
# Create and populate the SOURCES directory.
mkdir -p SOURCES
(cd $mytmp; tar cvfz ../SOURCES/cloudfs-0.5.tgz cloudfs-0.5)
+cp scripts/volfilter.py SOURCES/
+cp scripts/cloudfs SOURCES/
# Create and populate the SPECS directory.
mkdir -p SPECS
diff --git a/pkg/cloudfs.spec b/pkg/cloudfs.spec
index 6a2c957..1a03fcc 100644
--- a/pkg/cloudfs.spec
+++ b/pkg/cloudfs.spec
@@ -1,3 +1,5 @@
+%{!?python_sitelib: %global python_sitelib %(%{__python} -c "from
distutils.sysconfig import get_python_lib; print(get_python_lib())")}
+
# if you make changes, the it is advised to increment this number, and provide
# a descriptive suffix to identify who owns or what the change represents
# e.g. release_version 2.MSW
@@ -13,12 +15,17 @@ Vendor: Red Hat
Packager: cloudfs-
URL:
http://cloudfs.org
Source0: cloudfs-0.5.tgz
+Source1: volfilter.py
+Source2: cloudfs
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
Requires: glusterfs >= 3.1.1
+Requires: openssl
+Requires: python
BuildRequires: glusterfs-devel >= 3.1.1
BuildRequires: bison flex
BuildRequires: gcc make
+BuildRequires: openssl-devel
%description
CloudFS is a cloud-capable filesystem based on GlusterFS (
http://gluster.org)
@@ -41,6 +48,10 @@ Provides: cloudfs = %{version}-%{release}
%install
%{__rm} -rf %{buildroot}
%{__make} install DESTDIR=%{buildroot}
+%{__install} -D -p -m 0644 %{SOURCE1} \
+ %{buildroot}%{python_sitelib}/volfilter.py
+%{__install} -D -p -m 0755 %{SOURCE2} \
+ %{buildroot}%{_bindir}/cloudfs
# Remove unwanted files from all the shared libraries
find %{buildroot}%{_libdir} -name '*.a' -delete
@@ -55,6 +66,8 @@ find %{buildroot}%{_libdir} -name '*.la' -delete
%{_libdir}/glusterfs/3.1.1/xlator/cluster/*.so*
%{_libdir}/glusterfs/3.1.1/xlator/encryption/*.so*
%{_libdir}/glusterfs/3.1.1/xlator/features/*.so*
+%{python_sitelib}/volfilter.py
+%{_bindir}/cloudfs
%changelog
* Fri Jan 21 2011 Jeff Darcy <jdarcy(a)redhat.com> - 0.5
diff --git a/pkg/cloudfs.spec.in b/pkg/cloudfs.spec.in
index 01e8196..3e0a705 100644
--- a/pkg/cloudfs.spec.in
+++ b/pkg/cloudfs.spec.in
@@ -1,3 +1,5 @@
+%{!?python_sitelib: %global python_sitelib %(%{__python} -c "from
distutils.sysconfig import get_python_lib; print(get_python_lib())")}
+
# if you make changes, the it is advised to increment this number, and provide
# a descriptive suffix to identify who owns or what the change represents
# e.g. release_version 2.MSW
@@ -13,12 +15,17 @@ Vendor: Red Hat
Packager: @PACKAGE_BUGREPORT@
URL:
http://cloudfs.org
Source0: cloudfs-0.5.tgz
+Source1: volfilter.py
+Source2: cloudfs
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
Requires: glusterfs >= 3.1.1
+Requires: openssl
+Requires: python
BuildRequires: glusterfs-devel >= 3.1.1
BuildRequires: bison flex
BuildRequires: gcc make
+BuildRequires: openssl-devel
%description
CloudFS is a cloud-capable filesystem based on GlusterFS (
http://gluster.org)
@@ -41,6 +48,10 @@ Provides: cloudfs = %{version}-%{release}
%install
%{__rm} -rf %{buildroot}
%{__make} install DESTDIR=%{buildroot}
+%{__install} -D -p -m 0644 %{SOURCE1} \
+ %{buildroot}%{python_sitelib}/volfilter.py
+%{__install} -D -p -m 0755 %{SOURCE2} \
+ %{buildroot}%{_bindir}/cloudfs
# Remove unwanted files from all the shared libraries
find %{buildroot}%{_libdir} -name '*.a' -delete
@@ -55,6 +66,8 @@ find %{buildroot}%{_libdir} -name '*.la' -delete
%{_libdir}/glusterfs/@GLUSTER_VERSION(a)/xlator/cluster/*.so*
%{_libdir}/glusterfs/@GLUSTER_VERSION(a)/xlator/encryption/*.so*
%{_libdir}/glusterfs/@GLUSTER_VERSION(a)/xlator/features/*.so*
+%{python_sitelib}/volfilter.py
+%{_bindir}/cloudfs
%changelog
* Fri Jan 21 2011 Jeff Darcy <jdarcy(a)redhat.com> - 0.5
commit 5d0407a720a90ba786b567d552bdbd89e158cf4f
Author: Jeff Darcy <jdarcy(a)redhat.com>
Date: Wed Jan 26 15:37:24 2011 -0500
Fix bugs in cloudfs script.
added user-* options representing tenants in cloud xlator
added code to delete quick-read when using encryption
diff --git a/scripts/cloudfs b/scripts/cloudfs
index 4c68755..30d73bd 100755
--- a/scripts/cloudfs
+++ b/scripts/cloudfs
@@ -97,6 +97,9 @@ def cloudify_server (volfile, users):
# One cloud to bring them all...
my_xl = volfilter.Translator(last.subvols[0].name)
my_xl.type = "cluster/cloud"
+ my_xl.opts = {}
+ for user, pw in users:
+ my_xl.opts["user-"+user] = pw
my_xl.subvols = subvols
# ...and splice it in.
@@ -176,6 +179,10 @@ def do_init_crypt ():
graph, last = volfilter.load(vfname+".save")
opts = { "key": sys.argv[3] }
to_do = [xl for xl in graph.itervalues()
+ if xl.type == "performance/quick-read"]
+ for td in to_do:
+ volfilter.delete(graph,td)
+ to_do = [xl for xl in graph.itervalues()
if xl.type == "protocol/client"]
for td in to_do:
volfilter.push_filter(graph,td,"encryption/crypt",opts)
commit 1e17b56f8e187d54ffb7a9ad93a7de3b98dcb447
Author: Jeff Darcy <jdarcy(a)redhat.com>
Date: Wed Jan 26 14:36:13 2011 -0500
Add cloudfs script to bring everything together.
diff --git a/scripts/cloudfs b/scripts/cloudfs
new file mode 100755
index 0000000..4c68755
--- /dev/null
+++ b/scripts/cloudfs
@@ -0,0 +1,199 @@
+#!/usr/bin/python
+
+# Copyright (c) 2010 Red Hat, Inc.
+#
+# This file is part of CloudFS.
+#
+# CloudFS is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option)
+# any later version.
+#
+# CloudFS 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 Affero General Public License *
+# along with CloudFS. If not, see <
http://www.gnu.org/licenses/>.
+
+import copy
+import glob
+import os
+import sys
+import volfilter
+
+help = {}
+help["_main"] = """\
+Usage: %s command args...
+
+Commands available:
+ help COMMAND show detailed help for COMMAND
+ init VOL USERS modify volfiles for VOL"""
+
+help["init"] = """\
+%s init VOL USERS
+
+Adds CloudFS-specific modifications to *all* client and server volfiles for
+VOL, as specified for the "gluster" command. The USERS argument should be a
+path for a file where each line contains a tenant username and password,
+separated by a space."""
+
+help["initc"] = """\
+%s initc VOLFILE KEY
+
+Adds client-side encryption to *one* volfile."""
+
+glusterd_dirs = [
+ "/tmp/glusterd", # debug
+ "/var/lib/glusterd", # Fedora
+ "/etc/glusterd" # Gluster
+]
+
+def copy_stack (old_xl,suffix,recursive=False):
+ if recursive:
+ new_name = old_xl.name + "-" + suffix
+ else:
+ new_name = suffix
+ new_xl = volfilter.Translator(new_name)
+ new_xl.type = old_xl.type
+ # The results with normal assignment here are . . . amusing.
+ new_xl.opts = copy.deepcopy(old_xl.opts)
+ for sv in old_xl.subvols:
+ new_xl.subvols.append(copy_stack(sv,suffix,True))
+ # Patch up the path at the bottom.
+ if new_xl.type == "storage/posix":
+ new_xl.opts["directory"] += ("/" + suffix)
+ return new_xl
+
+def cloudify_client (volfile, users):
+ print "# Cloudifying client %s" % volfile
+ for user, pw in users:
+ ptvf = "%s.%s" % (volfile, user) # Per Tenant Vol File
+ graph, last = volfilter.load(volfile+".save")
+ opts = { "username": user, "password": pw }
+ to_do = [xl for xl in graph.itervalues()
+ if xl.type == "protocol/client"]
+ for td in to_do:
+ volfilter.push_filter(graph,td,"cluster/login",opts)
+ volfilter.generate(graph,last,file(ptvf,"w"))
+
+def cloudify_server (volfile, users):
+ print "# Cloudifying server %s" % volfile
+ graph, last = volfilter.load(volfile+".save")
+
+ # Add the pre-authentication subvolume.
+ junk_sv = last.subvols[0]
+ while junk_sv.type != "storage/posix":
+ junk_sv = junk_sv.subvols[0]
+ subvols = [copy_stack(junk_sv,"junk")]
+
+ # Add the per-tenant subvolumes.
+ for user, pw in users:
+ new_stack = copy_stack(last.subvols[0],user)
+ volfilter.push_filter(graph,new_stack,"features/oplock")
+ subvols.append(new_stack)
+
+ # One cloud to bring them all...
+ my_xl = volfilter.Translator(last.subvols[0].name)
+ my_xl.type = "cluster/cloud"
+ my_xl.subvols = subvols
+
+ # ...and splice it in.
+ last.subvols = [my_xl]
+
+ volfilter.generate(graph,last,file(volfile,"w"))
+
+def do_help ():
+ prog = sys.argv[0]
+ cmd = sys.argv[2]
+ try:
+ print >> sys.stderr, help[cmd] % prog
+ except KeyError:
+ print >> sys.stderr, "No help available for '%s'" % cmd
+ return 1
+ return 0
+
+def do_init ():
+ prog = sys.argv[0]
+ if len(sys.argv) != 4:
+ print >> sys.stderr, help["init"] % prog
+ return 1
+
+ volname = sys.argv[2]
+ voldir = ""
+ for gdir in glusterd_dirs:
+ probe = "%s/vols/%s" % (gdir, volname)
+ print "trying %s" % probe
+ if os.access(probe,os.X_OK):
+ voldir = probe
+ break
+ if voldir == "":
+ print >> sys.stderr, "Could not find volfiles for %s" % volname
+ return 1
+ client_volfile = "%s/%s-fuse.vol" % (voldir, volname)
+
+ try:
+ userfile = file(sys.argv[3],"r")
+ except IOError:
+ print >> sys.stderr, "Could not load users from %s" % userfile
+ return 1
+ users = []
+ for line in userfile.readlines():
+ space = line.find(" ")
+ if space == -1:
+ print >> sys.stderr, "Bad line in userfile: %s" % line
+ users.append([line[:space],line[space+1:-1]])
+
+ volfiles = glob.glob('%s/*.vol'%voldir)
+ for v in volfiles:
+ if os.access(v+".save",os.F_OK):
+ print "%s.save already exists - aborting" % v
+ return 1
+ for v in volfiles:
+ os.rename(v,v+".save")
+
+ for v in volfiles:
+ if v == client_volfile:
+ cloudify_client(v,users)
+ else:
+ cloudify_server(v,users)
+
+def do_init_crypt ():
+ prog = sys.argv[0]
+ if len(sys.argv) != 4:
+ print >> sys.stderr, help["initc"] % prog
+ return 1
+
+ vfname = sys.argv[2]
+ print "# Adding encryption to %s" % vfname
+
+ if os.access(vfname+".save",os.F_OK):
+ print "%s.save already exists - aborting" % vfname
+ return 1
+ os.rename(vfname,vfname+".save")
+
+ graph, last = volfilter.load(vfname+".save")
+ opts = { "key": sys.argv[3] }
+ to_do = [xl for xl in graph.itervalues()
+ if xl.type == "protocol/client"]
+ for td in to_do:
+ volfilter.push_filter(graph,td,"encryption/crypt",opts)
+ volfilter.generate(graph,last,file(vfname,"w"))
+
+if len(sys.argv) < 3:
+ print >> sys.stderr, help["_main"] % sys.argv[0]
+ sys.exit(1)
+
+if sys.argv[1] == "help":
+ sys.exit(do_help())
+
+if sys.argv[1] == "init":
+ sys.exit(do_init())
+
+if sys.argv[1] == "initc":
+ sys.exit(do_init_crypt())
+
+# Unrecognized command.
+print >> sys.stderr, help["_main"] % sys.argv[0]
+sys.exit(1)
diff --git a/scripts/volfilter.py b/scripts/volfilter.py
index 3fd6250..7453c32 100755
--- a/scripts/volfilter.py
+++ b/scripts/volfilter.py
@@ -69,20 +69,20 @@ def load (path):
raise RuntimeError, "unclosed volume definition"
return all_xlators, last_xlator
-def generate (graph, last):
+def generate (graph, last, stream=sys.stdout):
for sv in last.subvols:
if not sv.dumped:
- generate(graph,sv)
- print ""
+ generate(graph,sv,stream)
+ print >> stream, ""
sv.dumped = True
- print "volume %s" % last.name
- print " type %s" % last.type
+ print >> stream, "volume %s" % last.name
+ print >> stream, " type %s" % last.type
for k, v in last.opts.iteritems():
- print " option %s %s" % (k, v)
+ print >> stream, " option %s %s" % (k, v)
if last.subvols:
- print " subvolumes %s" % string.join(
+ print >> stream, " subvolumes %s" % string.join(
[ sv.name for sv in last.subvols ])
- print "end-volume"
+ print >> stream, "end-volume"
def push_filter (graph, old_xl, filt_type, opts={}):
suffix = string.split(old_xl.type,"/")[1]
commit 4fd457e2d5f91274c5db31816eabfa443e730d80
Author: Jeff Darcy <jdarcy(a)redhat.com>
Date: Wed Jan 26 11:41:31 2011 -0500
Fix log levels.
diff --git a/xlators/cluster/cloud/src/cloud.c b/xlators/cluster/cloud/src/cloud.c
index bdd0336..5cdbd3f 100644
--- a/xlators/cluster/cloud/src/cloud.c
+++ b/xlators/cluster/cloud/src/cloud.c
@@ -49,8 +49,6 @@
* openssl or Kerberos or some other stronger authentication method.
*/
-#define CLOUD_LEVEL GF_LOG_DEBUG
-
typedef struct {
dict_t *users;
} cloud_priv;
@@ -283,7 +281,7 @@ cloud_setxattr (call_frame_t *frame, xlator_t *this,
op_errno = EPERM;
goto barf;
}
- gf_log(this->name,GF_LOG_ERROR,
+ gf_log(this->name,GF_LOG_INFO,
"re-binding to subvolume %s", sv->xlator->name);
if (!sv->xlator->itable) {
sv->xlator->itable = inode_table_new(0,sv->xlator);
@@ -382,7 +380,7 @@ collect_users (dict_t *this, char *key, data_t *value, void *ctx)
return;
}
- gf_log(xlator->name,CLOUD_LEVEL, "added user %s", user);
+ gf_log(xlator->name,GF_LOG_INFO, "added user %s", user);
}
int
@@ -449,7 +447,7 @@ fini (xlator_t *this)
dict_unref(((cloud_priv *)(this->private))->users);
GF_FREE(this->private);
- gf_log (this->name, GF_LOG_NORMAL,
+ gf_log (this->name, GF_LOG_INFO,
"cloud translator unloaded");
return;
}
diff --git a/xlators/cluster/login/src/login.c b/xlators/cluster/login/src/login.c
index 713dd94..344640e 100644
--- a/xlators/cluster/login/src/login.c
+++ b/xlators/cluster/login/src/login.c
@@ -56,7 +56,7 @@ login_do_login (xlator_t *this, xlator_t *client)
call_frame_t *frame = NULL;
dict_t *dict = NULL;
- gf_log(this->name,GF_LOG_DEBUG,"found client %s",client->name);
+ gf_log(this->name,GF_LOG_INFO,"found client %s",client->name);
frame = create_frame(client,&priv->pool);
if (!frame) {
@@ -203,7 +203,7 @@ init (xlator_t *this)
priv->password = password;
this->private = priv;
- gf_log ("login", GF_LOG_DEBUG, "login xlator loaded");
+ gf_log ("login", GF_LOG_INFO, "login xlator loaded");
return 0;
err_no_frames:
diff --git a/xlators/encryption/crypt/src/crypt.c b/xlators/encryption/crypt/src/crypt.c
index 0c39a1d..6110816 100644
--- a/xlators/encryption/crypt/src/crypt.c
+++ b/xlators/encryption/crypt/src/crypt.c
@@ -330,7 +330,7 @@ crypt_readv (call_frame_t *frame,
local->my_size = size;
local->my_offset = offset;
- gf_log(this->name,GF_LOG_TRACE,"reading %lu at %ld",size,offset);
+ gf_log(this->name,GF_LOG_DEBUG,"reading %lu at %ld",size,offset);
STACK_WIND (frame,
crypt_readv_cbk,
FIRST_CHILD (this),
@@ -654,7 +654,7 @@ crypt_writev (call_frame_t *frame,
}
local->orig_offset = offset;
- gf_log(this->name,GF_LOG_TRACE,"WRITEV: size %lu, offset %ld",
+ gf_log(this->name,GF_LOG_DEBUG,"WRITEV: size %lu, offset %ld",
local->orig_size, local->orig_offset);
head_resid = offset % priv->block_size;
@@ -802,7 +802,7 @@ init (xlator_t *this)
return EINVAL;
}
- gf_log ("crypt", GF_LOG_DEBUG, "crypt xlator loaded");
+ gf_log ("crypt", GF_LOG_INFO, "crypt xlator loaded");
return 0;
}
diff --git a/xlators/features/oplock/src/oplock.c b/xlators/features/oplock/src/oplock.c
index cd6ae0b..940398e 100644
--- a/xlators/features/oplock/src/oplock.c
+++ b/xlators/features/oplock/src/oplock.c
@@ -100,7 +100,7 @@ oplock_fsetxattr (call_frame_t *frame, xlator_t *this,
dict_foreach(state->dict,oplock_check_for_lock,&lock_str);
if (lock_str) {
inode = fd->inode;
- gf_log(this->name,GF_LOG_WARNING,
+ gf_log(this->name,GF_LOG_DEBUG,
"got lock request for %d from %p",
inode->ino, state->conn);
ret = store_op_lock(&priv->locks,inode,state->conn,inode->gen);
@@ -149,7 +149,7 @@ oplock_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct
iovec *vect
entry = fetch_op_lock(&priv->locks,inode,state->conn);
if (entry) {
if (entry->value != inode->gen) {
- gf_log(this->name,GF_LOG_WARNING,
+ gf_log(this->name,GF_LOG_DEBUG,
"would reject write for %d from %p",
inode->ino, state->conn);
op_errno = EBUSY;
@@ -193,7 +193,7 @@ init (xlator_t *this)
LIST_INIT(&priv->locks);
this->private = priv;
- gf_log ("oplock", GF_LOG_DEBUG, "oplock xlator loaded");
+ gf_log ("oplock", GF_LOG_INFO, "oplock xlator loaded");
return 0;
}
commit 232a9436a5cf7ff2d8c7de9e874a0964b34bc56a
Author: Jeff Darcy <jdarcy(a)redhat.com>
Date: Wed Jan 26 11:29:25 2011 -0500
Updated copyright dates.
diff --git a/xlators/cluster/cloud/src/cloud-mem-types.h
b/xlators/cluster/cloud/src/cloud-mem-types.h
index 5727cb8..21971c8 100644
--- a/xlators/cluster/cloud/src/cloud-mem-types.h
+++ b/xlators/cluster/cloud/src/cloud-mem-types.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Red Hat, Inc.
+ * Copyright (c) 2010,2011 Red Hat, Inc.
*
* This file is part of CloudFS.
*
diff --git a/xlators/cluster/cloud/src/cloud.c b/xlators/cluster/cloud/src/cloud.c
index 7c8a650..bdd0336 100644
--- a/xlators/cluster/cloud/src/cloud.c
+++ b/xlators/cluster/cloud/src/cloud.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Red Hat, Inc.
+ * Copyright (c) 2010,2011 Red Hat, Inc.
*
* This file is part of CloudFS.
*
diff --git a/xlators/cluster/login/src/login.c b/xlators/cluster/login/src/login.c
index c537d12..713dd94 100644
--- a/xlators/cluster/login/src/login.c
+++ b/xlators/cluster/login/src/login.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Red Hat, Inc.
+ * Copyright (c) 2011 Red Hat, Inc.
*
* This file is part of CloudFS.
*
diff --git a/xlators/encryption/crypt/src/crypt.c b/xlators/encryption/crypt/src/crypt.c
index 35cc31b..0c39a1d 100644
--- a/xlators/encryption/crypt/src/crypt.c
+++ b/xlators/encryption/crypt/src/crypt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Red Hat, Inc.
+ * Copyright (c) 2010,2011 Red Hat, Inc.
*
* This file is part of CloudFS.
*
diff --git a/xlators/encryption/crypt/src/crypt.h b/xlators/encryption/crypt/src/crypt.h
index f62708e..0c6548c 100644
--- a/xlators/encryption/crypt/src/crypt.h
+++ b/xlators/encryption/crypt/src/crypt.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Red Hat, Inc.
+ * Copyright (c) 2010,2011 Red Hat, Inc.
*
* This file is part of CloudFS.
*
diff --git a/xlators/features/oplock/src/oplock.c b/xlators/features/oplock/src/oplock.c
index 1a9e5b5..cd6ae0b 100644
--- a/xlators/features/oplock/src/oplock.c
+++ b/xlators/features/oplock/src/oplock.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Red Hat, Inc.
+ * Copyright (c) 2011 Red Hat, Inc.
*
* This file is part of CloudFS.
*
diff --git a/xlators/features/oplock/src/oplock.h b/xlators/features/oplock/src/oplock.h
index 7aec177..dc5daf3 100644
--- a/xlators/features/oplock/src/oplock.h
+++ b/xlators/features/oplock/src/oplock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Red Hat, Inc.
+ * Copyright (c) 2011 Red Hat, Inc.
*
* This file is part of CloudFS.
*