2008-10-28 22:11:41 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2005, 2006
|
2009-06-14 22:23:09 +08:00
|
|
|
* Avishay Traeger (avishay@gmail.com)
|
2008-10-28 22:11:41 +08:00
|
|
|
* Copyright (C) 2008, 2009
|
2014-10-20 00:38:58 +08:00
|
|
|
* Boaz Harrosh <ooo@electrozaur.com>
|
2008-10-28 22:11:41 +08:00
|
|
|
*
|
|
|
|
* Copyrights for code taken from ext2:
|
|
|
|
* Copyright (C) 1992, 1993, 1994, 1995
|
|
|
|
* Remy Card (card@masi.ibp.fr)
|
|
|
|
* Laboratoire MASI - Institut Blaise Pascal
|
|
|
|
* Universite Pierre et Marie Curie (Paris VI)
|
|
|
|
* from
|
|
|
|
* linux/fs/minix/inode.c
|
|
|
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
|
|
|
*
|
|
|
|
* This file is part of exofs.
|
|
|
|
*
|
|
|
|
* exofs 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. Since it is based on ext2, and the only
|
|
|
|
* valid version of GPL for the Linux kernel is version 2, the only valid
|
|
|
|
* version of GPL for exofs is version 2.
|
|
|
|
*
|
|
|
|
* exofs 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 exofs; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/string.h>
|
|
|
|
#include <linux/parser.h>
|
|
|
|
#include <linux/vfs.h>
|
|
|
|
#include <linux/random.h>
|
2011-07-02 02:23:34 +08:00
|
|
|
#include <linux/module.h>
|
2009-03-22 18:47:26 +08:00
|
|
|
#include <linux/exportfs.h>
|
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h
percpu.h is included by sched.h and module.h and thus ends up being
included when building most .c files. percpu.h includes slab.h which
in turn includes gfp.h making everything defined by the two files
universally available and complicating inclusion dependencies.
percpu.h -> slab.h dependency is about to be removed. Prepare for
this change by updating users of gfp and slab facilities include those
headers directly instead of assuming availability. As this conversion
needs to touch large number of source files, the following script is
used as the basis of conversion.
http://userweb.kernel.org/~tj/misc/slabh-sweep.py
The script does the followings.
* Scan files for gfp and slab usages and update includes such that
only the necessary includes are there. ie. if only gfp is used,
gfp.h, if slab is used, slab.h.
* When the script inserts a new include, it looks at the include
blocks and try to put the new include such that its order conforms
to its surrounding. It's put in the include block which contains
core kernel includes, in the same order that the rest are ordered -
alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
doesn't seem to be any matching order.
* If the script can't find a place to put a new include (mostly
because the file doesn't have fitting include block), it prints out
an error message indicating which .h file needs to be added to the
file.
The conversion was done in the following steps.
1. The initial automatic conversion of all .c files updated slightly
over 4000 files, deleting around 700 includes and adding ~480 gfp.h
and ~3000 slab.h inclusions. The script emitted errors for ~400
files.
2. Each error was manually checked. Some didn't need the inclusion,
some needed manual addition while adding it to implementation .h or
embedding .c file was more appropriate for others. This step added
inclusions to around 150 files.
3. The script was run again and the output was compared to the edits
from #2 to make sure no file was left behind.
4. Several build tests were done and a couple of problems were fixed.
e.g. lib/decompress_*.c used malloc/free() wrappers around slab
APIs requiring slab.h to be added manually.
5. The script was run on all .h files but without automatically
editing them as sprinkling gfp.h and slab.h inclusions around .h
files could easily lead to inclusion dependency hell. Most gfp.h
inclusion directives were ignored as stuff from gfp.h was usually
wildly available and often used in preprocessor macros. Each
slab.h inclusion directive was examined and added manually as
necessary.
6. percpu.h was updated not to include slab.h.
7. Build test were done on the following configurations and failures
were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my
distributed build env didn't work with gcov compiles) and a few
more options had to be turned off depending on archs to make things
build (like ipr on powerpc/64 which failed due to missing writeq).
* x86 and x86_64 UP and SMP allmodconfig and a custom test config.
* powerpc and powerpc64 SMP allmodconfig
* sparc and sparc64 SMP allmodconfig
* ia64 SMP allmodconfig
* s390 SMP allmodconfig
* alpha SMP allmodconfig
* um on x86_64 SMP allmodconfig
8. percpu.h modifications were reverted so that it could be applied as
a separate patch and serve as bisection point.
Given the fact that I had only a couple of failures from tests on step
6, I'm fairly confident about the coverage of this conversion patch.
If there is a breakage, it's likely to be something in one of the arch
headers which should be easily discoverable easily on most builds of
the specific arch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
2010-03-24 16:04:11 +08:00
|
|
|
#include <linux/slab.h>
|
2017-12-11 19:35:13 +08:00
|
|
|
#include <linux/iversion.h>
|
2008-10-28 22:11:41 +08:00
|
|
|
|
|
|
|
#include "exofs.h"
|
|
|
|
|
2011-05-16 20:26:47 +08:00
|
|
|
#define EXOFS_DBGMSG2(M...) do {} while (0)
|
|
|
|
|
2008-10-28 22:11:41 +08:00
|
|
|
/******************************************************************************
|
|
|
|
* MOUNT OPTIONS
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* struct to hold what we get from mount options
|
|
|
|
*/
|
|
|
|
struct exofs_mountopt {
|
2011-01-31 20:32:14 +08:00
|
|
|
bool is_osdname;
|
2008-10-28 22:11:41 +08:00
|
|
|
const char *dev_name;
|
|
|
|
uint64_t pid;
|
|
|
|
int timeout;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* exofs-specific mount-time options.
|
|
|
|
*/
|
2011-01-31 20:32:14 +08:00
|
|
|
enum { Opt_name, Opt_pid, Opt_to, Opt_err };
|
2008-10-28 22:11:41 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Our mount-time options. These should ideally be 64-bit unsigned, but the
|
|
|
|
* kernel's parsing functions do not currently support that. 32-bit should be
|
|
|
|
* sufficient for most applications now.
|
|
|
|
*/
|
|
|
|
static match_table_t tokens = {
|
2011-01-31 20:32:14 +08:00
|
|
|
{Opt_name, "osdname=%s"},
|
2008-10-28 22:11:41 +08:00
|
|
|
{Opt_pid, "pid=%u"},
|
|
|
|
{Opt_to, "to=%u"},
|
|
|
|
{Opt_err, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The main option parsing method. Also makes sure that all of the mandatory
|
|
|
|
* mount options were set.
|
|
|
|
*/
|
|
|
|
static int parse_options(char *options, struct exofs_mountopt *opts)
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
substring_t args[MAX_OPT_ARGS];
|
|
|
|
int option;
|
|
|
|
bool s_pid = false;
|
|
|
|
|
|
|
|
EXOFS_DBGMSG("parse_options %s\n", options);
|
|
|
|
/* defaults */
|
|
|
|
memset(opts, 0, sizeof(*opts));
|
|
|
|
opts->timeout = BLK_DEFAULT_SG_TIMEOUT;
|
|
|
|
|
|
|
|
while ((p = strsep(&options, ",")) != NULL) {
|
|
|
|
int token;
|
|
|
|
char str[32];
|
|
|
|
|
|
|
|
if (!*p)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
token = match_token(p, tokens, args);
|
|
|
|
switch (token) {
|
2011-01-31 20:32:14 +08:00
|
|
|
case Opt_name:
|
2018-06-13 12:05:13 +08:00
|
|
|
kfree(opts->dev_name);
|
2011-01-31 20:32:14 +08:00
|
|
|
opts->dev_name = match_strdup(&args[0]);
|
|
|
|
if (unlikely(!opts->dev_name)) {
|
|
|
|
EXOFS_ERR("Error allocating dev_name");
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
opts->is_osdname = true;
|
|
|
|
break;
|
2008-10-28 22:11:41 +08:00
|
|
|
case Opt_pid:
|
|
|
|
if (0 == match_strlcpy(str, &args[0], sizeof(str)))
|
|
|
|
return -EINVAL;
|
|
|
|
opts->pid = simple_strtoull(str, NULL, 0);
|
|
|
|
if (opts->pid < EXOFS_MIN_PID) {
|
|
|
|
EXOFS_ERR("Partition ID must be >= %u",
|
|
|
|
EXOFS_MIN_PID);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
s_pid = 1;
|
|
|
|
break;
|
|
|
|
case Opt_to:
|
|
|
|
if (match_int(&args[0], &option))
|
|
|
|
return -EINVAL;
|
|
|
|
if (option <= 0) {
|
2016-02-08 19:53:12 +08:00
|
|
|
EXOFS_ERR("Timeout must be > 0");
|
2008-10-28 22:11:41 +08:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
opts->timeout = option * HZ;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!s_pid) {
|
|
|
|
EXOFS_ERR("Need to specify the following options:\n");
|
|
|
|
EXOFS_ERR(" -o pid=pid_no_to_use\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* INODE CACHE
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Our inode cache. Isn't it pretty?
|
|
|
|
*/
|
|
|
|
static struct kmem_cache *exofs_inode_cachep;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate an inode in the cache
|
|
|
|
*/
|
|
|
|
static struct inode *exofs_alloc_inode(struct super_block *sb)
|
|
|
|
{
|
|
|
|
struct exofs_i_info *oi;
|
|
|
|
|
|
|
|
oi = kmem_cache_alloc(exofs_inode_cachep, GFP_KERNEL);
|
|
|
|
if (!oi)
|
|
|
|
return NULL;
|
|
|
|
|
2017-12-11 19:35:13 +08:00
|
|
|
inode_set_iversion(&oi->vfs_inode, 1);
|
2008-10-28 22:11:41 +08:00
|
|
|
return &oi->vfs_inode;
|
|
|
|
}
|
|
|
|
|
2011-01-07 14:49:49 +08:00
|
|
|
static void exofs_i_callback(struct rcu_head *head)
|
|
|
|
{
|
|
|
|
struct inode *inode = container_of(head, struct inode, i_rcu);
|
|
|
|
kmem_cache_free(exofs_inode_cachep, exofs_i(inode));
|
|
|
|
}
|
|
|
|
|
2008-10-28 22:11:41 +08:00
|
|
|
/*
|
|
|
|
* Remove an inode from the cache
|
|
|
|
*/
|
|
|
|
static void exofs_destroy_inode(struct inode *inode)
|
|
|
|
{
|
2011-01-07 14:49:49 +08:00
|
|
|
call_rcu(&inode->i_rcu, exofs_i_callback);
|
2008-10-28 22:11:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize the inode
|
|
|
|
*/
|
|
|
|
static void exofs_init_once(void *foo)
|
|
|
|
{
|
|
|
|
struct exofs_i_info *oi = foo;
|
|
|
|
|
|
|
|
inode_init_once(&oi->vfs_inode);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create and initialize the inode cache
|
|
|
|
*/
|
|
|
|
static int init_inodecache(void)
|
|
|
|
{
|
exofs: Define usercopy region in exofs_inode_cache slab cache
The exofs short symlink names, stored in struct exofs_i_info.i_data and
therefore contained in the exofs_inode_cache slab cache, need to be copied
to/from userspace.
cache object allocation:
fs/exofs/super.c:
exofs_alloc_inode(...):
...
oi = kmem_cache_alloc(exofs_inode_cachep, GFP_KERNEL);
...
return &oi->vfs_inode;
fs/exofs/namei.c:
exofs_symlink(...):
...
inode->i_link = (char *)oi->i_data;
example usage trace:
readlink_copy+0x43/0x70
vfs_readlink+0x62/0x110
SyS_readlinkat+0x100/0x130
fs/namei.c:
readlink_copy(..., link):
...
copy_to_user(..., link, len);
(inlined in vfs_readlink)
generic_readlink(dentry, ...):
struct inode *inode = d_inode(dentry);
const char *link = inode->i_link;
...
readlink_copy(..., link);
In support of usercopy hardening, this patch defines a region in the
exofs_inode_cache slab cache in which userspace copy operations are
allowed.
This region is known as the slab cache's usercopy region. Slab caches
can now check that each dynamically sized copy operation involving
cache-managed memory falls entirely within the slab's usercopy region.
This patch is modified from Brad Spengler/PaX Team's PAX_USERCOPY
whitelisting code in the last public patch of grsecurity/PaX based on my
understanding of the code. Changes or omissions from the original code are
mine and don't reflect the original grsecurity/PaX code.
Signed-off-by: David Windsor <dave@nullcore.net>
[kees: adjust commit log, provide usage trace]
Cc: Boaz Harrosh <ooo@electrozaur.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
2017-06-11 10:50:34 +08:00
|
|
|
exofs_inode_cachep = kmem_cache_create_usercopy("exofs_inode_cache",
|
2008-10-28 22:11:41 +08:00
|
|
|
sizeof(struct exofs_i_info), 0,
|
2016-01-15 07:18:21 +08:00
|
|
|
SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD |
|
exofs: Define usercopy region in exofs_inode_cache slab cache
The exofs short symlink names, stored in struct exofs_i_info.i_data and
therefore contained in the exofs_inode_cache slab cache, need to be copied
to/from userspace.
cache object allocation:
fs/exofs/super.c:
exofs_alloc_inode(...):
...
oi = kmem_cache_alloc(exofs_inode_cachep, GFP_KERNEL);
...
return &oi->vfs_inode;
fs/exofs/namei.c:
exofs_symlink(...):
...
inode->i_link = (char *)oi->i_data;
example usage trace:
readlink_copy+0x43/0x70
vfs_readlink+0x62/0x110
SyS_readlinkat+0x100/0x130
fs/namei.c:
readlink_copy(..., link):
...
copy_to_user(..., link, len);
(inlined in vfs_readlink)
generic_readlink(dentry, ...):
struct inode *inode = d_inode(dentry);
const char *link = inode->i_link;
...
readlink_copy(..., link);
In support of usercopy hardening, this patch defines a region in the
exofs_inode_cache slab cache in which userspace copy operations are
allowed.
This region is known as the slab cache's usercopy region. Slab caches
can now check that each dynamically sized copy operation involving
cache-managed memory falls entirely within the slab's usercopy region.
This patch is modified from Brad Spengler/PaX Team's PAX_USERCOPY
whitelisting code in the last public patch of grsecurity/PaX based on my
understanding of the code. Changes or omissions from the original code are
mine and don't reflect the original grsecurity/PaX code.
Signed-off-by: David Windsor <dave@nullcore.net>
[kees: adjust commit log, provide usage trace]
Cc: Boaz Harrosh <ooo@electrozaur.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
2017-06-11 10:50:34 +08:00
|
|
|
SLAB_ACCOUNT,
|
|
|
|
offsetof(struct exofs_i_info, i_data),
|
|
|
|
sizeof_field(struct exofs_i_info, i_data),
|
|
|
|
exofs_init_once);
|
2008-10-28 22:11:41 +08:00
|
|
|
if (exofs_inode_cachep == NULL)
|
|
|
|
return -ENOMEM;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Destroy the inode cache
|
|
|
|
*/
|
|
|
|
static void destroy_inodecache(void)
|
|
|
|
{
|
2012-09-26 09:33:07 +08:00
|
|
|
/*
|
|
|
|
* Make sure all delayed rcu free inodes are flushed before we
|
|
|
|
* destroy cache.
|
|
|
|
*/
|
|
|
|
rcu_barrier();
|
2008-10-28 22:11:41 +08:00
|
|
|
kmem_cache_destroy(exofs_inode_cachep);
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
2011-05-16 20:26:47 +08:00
|
|
|
* Some osd helpers
|
2008-10-28 22:11:41 +08:00
|
|
|
*****************************************************************************/
|
2011-05-16 20:26:47 +08:00
|
|
|
void exofs_make_credential(u8 cred_a[OSD_CAP_LEN], const struct osd_obj_id *obj)
|
|
|
|
{
|
|
|
|
osd_sec_init_nosec_doall_caps(cred_a, obj, false, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int exofs_read_kern(struct osd_dev *od, u8 *cred, struct osd_obj_id *obj,
|
|
|
|
u64 offset, void *p, unsigned length)
|
|
|
|
{
|
2018-05-09 15:54:03 +08:00
|
|
|
struct osd_request *or = osd_start_request(od);
|
2011-05-16 20:26:47 +08:00
|
|
|
/* struct osd_sense_info osi = {.key = 0};*/
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (unlikely(!or)) {
|
|
|
|
EXOFS_DBGMSG("%s: osd_start_request failed.\n", __func__);
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
ret = osd_req_read_kern(or, obj, offset, p, length);
|
|
|
|
if (unlikely(ret)) {
|
|
|
|
EXOFS_DBGMSG("%s: osd_req_read_kern failed.\n", __func__);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = osd_finalize_request(or, 0, cred, NULL);
|
|
|
|
if (unlikely(ret)) {
|
|
|
|
EXOFS_DBGMSG("Failed to osd_finalize_request() => %d\n", ret);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = osd_execute_request(or);
|
|
|
|
if (unlikely(ret))
|
|
|
|
EXOFS_DBGMSG("osd_execute_request() => %d\n", ret);
|
|
|
|
/* osd_req_decode_sense(or, ret); */
|
|
|
|
|
|
|
|
out:
|
|
|
|
osd_end_request(or);
|
|
|
|
EXOFS_DBGMSG2("read_kern(0x%llx) offset=0x%llx "
|
|
|
|
"length=0x%llx dev=%p ret=>%d\n",
|
|
|
|
_LLU(obj->id), _LLU(offset), _LLU(length), od, ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-02-03 23:53:25 +08:00
|
|
|
static const struct osd_attr g_attr_sb_stats = ATTR_DEF(
|
|
|
|
EXOFS_APAGE_SB_DATA,
|
|
|
|
EXOFS_ATTR_SB_STATS,
|
|
|
|
sizeof(struct exofs_sb_stats));
|
|
|
|
|
|
|
|
static int __sbi_read_stats(struct exofs_sb_info *sbi)
|
|
|
|
{
|
|
|
|
struct osd_attr attrs[] = {
|
|
|
|
[0] = g_attr_sb_stats,
|
|
|
|
};
|
2011-08-07 10:26:31 +08:00
|
|
|
struct ore_io_state *ios;
|
2011-02-03 23:53:25 +08:00
|
|
|
int ret;
|
|
|
|
|
2011-09-28 16:39:59 +08:00
|
|
|
ret = ore_get_io_state(&sbi->layout, &sbi->oc, &ios);
|
2011-02-03 23:53:25 +08:00
|
|
|
if (unlikely(ret)) {
|
2011-08-07 10:26:31 +08:00
|
|
|
EXOFS_ERR("%s: ore_get_io_state failed.\n", __func__);
|
2011-02-03 23:53:25 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ios->in_attr = attrs;
|
|
|
|
ios->in_attr_len = ARRAY_SIZE(attrs);
|
|
|
|
|
2011-08-07 10:26:31 +08:00
|
|
|
ret = ore_read(ios);
|
2011-02-03 23:53:25 +08:00
|
|
|
if (unlikely(ret)) {
|
|
|
|
EXOFS_ERR("Error reading super_block stats => %d\n", ret);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = extract_attr_from_ios(ios, &attrs[0]);
|
|
|
|
if (ret) {
|
|
|
|
EXOFS_ERR("%s: extract_attr of sb_stats failed\n", __func__);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
if (attrs[0].len) {
|
|
|
|
struct exofs_sb_stats *ess;
|
|
|
|
|
|
|
|
if (unlikely(attrs[0].len != sizeof(*ess))) {
|
|
|
|
EXOFS_ERR("%s: Wrong version of exofs_sb_stats "
|
|
|
|
"size(%d) != expected(%zd)\n",
|
|
|
|
__func__, attrs[0].len, sizeof(*ess));
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
ess = attrs[0].val_ptr;
|
|
|
|
sbi->s_nextid = le64_to_cpu(ess->s_nextid);
|
|
|
|
sbi->s_numfiles = le32_to_cpu(ess->s_numfiles);
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
2011-08-07 10:26:31 +08:00
|
|
|
ore_put_io_state(ios);
|
2011-02-03 23:53:25 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-08-07 10:26:31 +08:00
|
|
|
static void stats_done(struct ore_io_state *ios, void *p)
|
2011-02-03 23:53:25 +08:00
|
|
|
{
|
2011-08-07 10:26:31 +08:00
|
|
|
ore_put_io_state(ios);
|
2011-02-03 23:53:25 +08:00
|
|
|
/* Good thanks nothing to do anymore */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Asynchronously write the stats attribute */
|
|
|
|
int exofs_sbi_write_stats(struct exofs_sb_info *sbi)
|
|
|
|
{
|
|
|
|
struct osd_attr attrs[] = {
|
|
|
|
[0] = g_attr_sb_stats,
|
|
|
|
};
|
2011-08-07 10:26:31 +08:00
|
|
|
struct ore_io_state *ios;
|
2011-02-03 23:53:25 +08:00
|
|
|
int ret;
|
|
|
|
|
2011-09-28 16:39:59 +08:00
|
|
|
ret = ore_get_io_state(&sbi->layout, &sbi->oc, &ios);
|
2011-02-03 23:53:25 +08:00
|
|
|
if (unlikely(ret)) {
|
2011-08-07 10:26:31 +08:00
|
|
|
EXOFS_ERR("%s: ore_get_io_state failed.\n", __func__);
|
2011-02-03 23:53:25 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
sbi->s_ess.s_nextid = cpu_to_le64(sbi->s_nextid);
|
|
|
|
sbi->s_ess.s_numfiles = cpu_to_le64(sbi->s_numfiles);
|
|
|
|
attrs[0].val_ptr = &sbi->s_ess;
|
|
|
|
|
exofs: ios: Move to a per inode components & device-table
Exofs raid engine was saving on memory space by having a single layout-info,
single pid, and a single device-table, global to the filesystem. Then passing
a credential and object_id info at the io_state level, private for each
inode. It would also devise this contraption of rotating the device table
view for each inode->ino to spread out the device usage.
This is not compatible with the pnfs-objects standard, demanding that
each inode can have it's own layout-info, device-table, and each object
component it's own pid, oid and creds.
So: Bring exofs raid engine to be usable for generic pnfs-objects use by:
* Define an exofs_comp structure that holds obj_id and credential info.
* Break up exofs_layout struct to an exofs_components structure that holds a
possible array of exofs_comp and the array of devices + the size of the
arrays.
* Add a "comps" parameter to get_io_state() that specifies the ids creds
and device array to use for each IO.
This enables to keep the layout global, but the device-table view, creds
and IDs at the inode level. It only adds two 64bit to each inode, since
some of these members already existed in another form.
* ios raid engine now access layout-info and comps-info through the passed
pointers. Everything is pre-prepared by caller for generic access of
these structures and arrays.
At the exofs Level:
* Super block holds an exofs_components struct that holds the device
array, previously in layout. The devices there are in device-table
order. The device-array is twice bigger and repeats the device-table
twice so now each inode's device array can point to a random device
and have a round-robin view of the table, making it compatible to
previous exofs versions.
* Each inode has an exofs_components struct that is initialized at
load time, with it's own view of the device table IDs and creds.
When doing IO this gets passed to the io_state together with the
layout.
While preforming this change. Bugs where found where credentials with the
wrong IDs where used to access the different SB objects (super.c). As well
as some dead code. It was never noticed because the target we use does not
check the credentials.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2011-08-06 06:06:04 +08:00
|
|
|
|
2011-02-03 23:53:25 +08:00
|
|
|
ios->done = stats_done;
|
|
|
|
ios->private = sbi;
|
|
|
|
ios->out_attr = attrs;
|
|
|
|
ios->out_attr_len = ARRAY_SIZE(attrs);
|
|
|
|
|
2011-08-07 10:26:31 +08:00
|
|
|
ret = ore_write(ios);
|
2011-02-03 23:53:25 +08:00
|
|
|
if (unlikely(ret)) {
|
2011-08-07 10:26:31 +08:00
|
|
|
EXOFS_ERR("%s: ore_write failed.\n", __func__);
|
|
|
|
ore_put_io_state(ios);
|
2011-02-03 23:53:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-05-16 20:26:47 +08:00
|
|
|
/******************************************************************************
|
|
|
|
* SUPERBLOCK FUNCTIONS
|
|
|
|
*****************************************************************************/
|
|
|
|
static const struct super_operations exofs_sops;
|
|
|
|
static const struct export_operations exofs_export_ops;
|
|
|
|
|
2008-10-28 22:11:41 +08:00
|
|
|
/*
|
|
|
|
* Write the superblock to the OSD
|
|
|
|
*/
|
2011-09-24 04:46:51 +08:00
|
|
|
static int exofs_sync_fs(struct super_block *sb, int wait)
|
2008-10-28 22:11:41 +08:00
|
|
|
{
|
|
|
|
struct exofs_sb_info *sbi;
|
|
|
|
struct exofs_fscb *fscb;
|
2011-08-07 10:26:31 +08:00
|
|
|
struct ore_comp one_comp;
|
2011-09-28 16:39:59 +08:00
|
|
|
struct ore_components oc;
|
2011-08-07 10:26:31 +08:00
|
|
|
struct ore_io_state *ios;
|
2009-06-08 16:03:58 +08:00
|
|
|
int ret = -ENOMEM;
|
2008-10-28 22:11:41 +08:00
|
|
|
|
2011-02-03 23:53:25 +08:00
|
|
|
fscb = kmalloc(sizeof(*fscb), GFP_KERNEL);
|
|
|
|
if (unlikely(!fscb))
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2008-10-28 22:11:41 +08:00
|
|
|
sbi = sb->s_fs_info;
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
|
2011-02-03 23:53:25 +08:00
|
|
|
/* NOTE: We no longer dirty the super_block anywhere in exofs. The
|
|
|
|
* reason we write the fscb here on unmount is so we can stay backwards
|
|
|
|
* compatible with fscb->s_version == 1. (What we are not compatible
|
|
|
|
* with is if a new version FS crashed and then we try to mount an old
|
|
|
|
* version). Otherwise the exofs_fscb is read-only from mkfs time. All
|
|
|
|
* the writeable info is set in exofs_sbi_write_stats() above.
|
|
|
|
*/
|
exofs: ios: Move to a per inode components & device-table
Exofs raid engine was saving on memory space by having a single layout-info,
single pid, and a single device-table, global to the filesystem. Then passing
a credential and object_id info at the io_state level, private for each
inode. It would also devise this contraption of rotating the device table
view for each inode->ino to spread out the device usage.
This is not compatible with the pnfs-objects standard, demanding that
each inode can have it's own layout-info, device-table, and each object
component it's own pid, oid and creds.
So: Bring exofs raid engine to be usable for generic pnfs-objects use by:
* Define an exofs_comp structure that holds obj_id and credential info.
* Break up exofs_layout struct to an exofs_components structure that holds a
possible array of exofs_comp and the array of devices + the size of the
arrays.
* Add a "comps" parameter to get_io_state() that specifies the ids creds
and device array to use for each IO.
This enables to keep the layout global, but the device-table view, creds
and IDs at the inode level. It only adds two 64bit to each inode, since
some of these members already existed in another form.
* ios raid engine now access layout-info and comps-info through the passed
pointers. Everything is pre-prepared by caller for generic access of
these structures and arrays.
At the exofs Level:
* Super block holds an exofs_components struct that holds the device
array, previously in layout. The devices there are in device-table
order. The device-array is twice bigger and repeats the device-table
twice so now each inode's device array can point to a random device
and have a round-robin view of the table, making it compatible to
previous exofs versions.
* Each inode has an exofs_components struct that is initialized at
load time, with it's own view of the device table IDs and creds.
When doing IO this gets passed to the io_state together with the
layout.
While preforming this change. Bugs where found where credentials with the
wrong IDs where used to access the different SB objects (super.c). As well
as some dead code. It was never noticed because the target we use does not
check the credentials.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2011-08-06 06:06:04 +08:00
|
|
|
|
2011-09-28 16:39:59 +08:00
|
|
|
exofs_init_comps(&oc, &one_comp, sbi, EXOFS_SUPER_ID);
|
exofs: ios: Move to a per inode components & device-table
Exofs raid engine was saving on memory space by having a single layout-info,
single pid, and a single device-table, global to the filesystem. Then passing
a credential and object_id info at the io_state level, private for each
inode. It would also devise this contraption of rotating the device table
view for each inode->ino to spread out the device usage.
This is not compatible with the pnfs-objects standard, demanding that
each inode can have it's own layout-info, device-table, and each object
component it's own pid, oid and creds.
So: Bring exofs raid engine to be usable for generic pnfs-objects use by:
* Define an exofs_comp structure that holds obj_id and credential info.
* Break up exofs_layout struct to an exofs_components structure that holds a
possible array of exofs_comp and the array of devices + the size of the
arrays.
* Add a "comps" parameter to get_io_state() that specifies the ids creds
and device array to use for each IO.
This enables to keep the layout global, but the device-table view, creds
and IDs at the inode level. It only adds two 64bit to each inode, since
some of these members already existed in another form.
* ios raid engine now access layout-info and comps-info through the passed
pointers. Everything is pre-prepared by caller for generic access of
these structures and arrays.
At the exofs Level:
* Super block holds an exofs_components struct that holds the device
array, previously in layout. The devices there are in device-table
order. The device-array is twice bigger and repeats the device-table
twice so now each inode's device array can point to a random device
and have a round-robin view of the table, making it compatible to
previous exofs versions.
* Each inode has an exofs_components struct that is initialized at
load time, with it's own view of the device table IDs and creds.
When doing IO this gets passed to the io_state together with the
layout.
While preforming this change. Bugs where found where credentials with the
wrong IDs where used to access the different SB objects (super.c). As well
as some dead code. It was never noticed because the target we use does not
check the credentials.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2011-08-06 06:06:04 +08:00
|
|
|
|
2011-09-28 16:39:59 +08:00
|
|
|
ret = ore_get_io_state(&sbi->layout, &oc, &ios);
|
2011-02-03 23:53:25 +08:00
|
|
|
if (unlikely(ret))
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
goto out;
|
|
|
|
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
ios->length = offsetof(struct exofs_fscb, s_dev_table_oid);
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
memset(fscb, 0, ios->length);
|
2008-10-28 22:11:41 +08:00
|
|
|
fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
|
2011-11-21 22:43:11 +08:00
|
|
|
fscb->s_numfiles = cpu_to_le64(sbi->s_numfiles);
|
2008-10-28 22:11:41 +08:00
|
|
|
fscb->s_magic = cpu_to_le16(sb->s_magic);
|
|
|
|
fscb->s_newfs = 0;
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
fscb->s_version = EXOFS_FSCB_VER;
|
2008-10-28 22:11:41 +08:00
|
|
|
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
ios->offset = 0;
|
|
|
|
ios->kern_buff = fscb;
|
2008-10-28 22:11:41 +08:00
|
|
|
|
2011-08-07 10:26:31 +08:00
|
|
|
ret = ore_write(ios);
|
2011-02-03 23:53:25 +08:00
|
|
|
if (unlikely(ret))
|
2011-08-07 10:26:31 +08:00
|
|
|
EXOFS_ERR("%s: ore_write failed.\n", __func__);
|
2011-02-03 23:53:25 +08:00
|
|
|
|
2008-10-28 22:11:41 +08:00
|
|
|
out:
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
EXOFS_DBGMSG("s_nextid=0x%llx ret=%d\n", _LLU(sbi->s_nextid), ret);
|
2011-08-07 10:26:31 +08:00
|
|
|
ore_put_io_state(ios);
|
2011-02-03 23:53:25 +08:00
|
|
|
kfree(fscb);
|
2009-06-08 16:03:58 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-09-04 01:38:02 +08:00
|
|
|
static void _exofs_print_device(const char *msg, const char *dev_path,
|
|
|
|
struct osd_dev *od, u64 pid)
|
|
|
|
{
|
|
|
|
const struct osd_dev_info *odi = osduld_device_info(od);
|
|
|
|
|
|
|
|
printk(KERN_NOTICE "exofs: %s %s osd_name-%s pid-0x%llx\n",
|
|
|
|
msg, dev_path ?: "", odi->osdname, _LLU(pid));
|
|
|
|
}
|
|
|
|
|
2011-09-24 04:46:51 +08:00
|
|
|
static void exofs_free_sbi(struct exofs_sb_info *sbi)
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
{
|
2011-09-28 19:43:09 +08:00
|
|
|
unsigned numdevs = sbi->oc.numdevs;
|
|
|
|
|
|
|
|
while (numdevs) {
|
|
|
|
unsigned i = --numdevs;
|
|
|
|
struct osd_dev *od = ore_comp_dev(&sbi->oc, i);
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
|
|
|
|
if (od) {
|
2011-09-28 19:43:09 +08:00
|
|
|
ore_comp_set_dev(&sbi->oc, i, NULL);
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
osduld_put_device(od);
|
|
|
|
}
|
|
|
|
}
|
2011-09-28 19:43:09 +08:00
|
|
|
kfree(sbi->oc.ods);
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
kfree(sbi);
|
|
|
|
}
|
|
|
|
|
2008-10-28 22:11:41 +08:00
|
|
|
/*
|
|
|
|
* This function is called when the vfs is freeing the superblock. We just
|
|
|
|
* need to free our own part.
|
|
|
|
*/
|
|
|
|
static void exofs_put_super(struct super_block *sb)
|
|
|
|
{
|
|
|
|
int num_pend;
|
|
|
|
struct exofs_sb_info *sbi = sb->s_fs_info;
|
|
|
|
|
|
|
|
/* make sure there are no pending commands */
|
|
|
|
for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0;
|
|
|
|
num_pend = atomic_read(&sbi->s_curr_pending)) {
|
|
|
|
wait_queue_head_t wq;
|
2011-02-08 00:12:15 +08:00
|
|
|
|
|
|
|
printk(KERN_NOTICE "%s: !!Pending operations in flight. "
|
|
|
|
"This is a BUG. please report to osd-dev@open-osd.org\n",
|
|
|
|
__func__);
|
2008-10-28 22:11:41 +08:00
|
|
|
init_waitqueue_head(&wq);
|
|
|
|
wait_event_timeout(wq,
|
|
|
|
(atomic_read(&sbi->s_curr_pending) == 0),
|
|
|
|
msecs_to_jiffies(100));
|
|
|
|
}
|
|
|
|
|
2011-09-28 19:43:09 +08:00
|
|
|
_exofs_print_device("Unmounting", NULL, ore_comp_dev(&sbi->oc, 0),
|
exofs: ios: Move to a per inode components & device-table
Exofs raid engine was saving on memory space by having a single layout-info,
single pid, and a single device-table, global to the filesystem. Then passing
a credential and object_id info at the io_state level, private for each
inode. It would also devise this contraption of rotating the device table
view for each inode->ino to spread out the device usage.
This is not compatible with the pnfs-objects standard, demanding that
each inode can have it's own layout-info, device-table, and each object
component it's own pid, oid and creds.
So: Bring exofs raid engine to be usable for generic pnfs-objects use by:
* Define an exofs_comp structure that holds obj_id and credential info.
* Break up exofs_layout struct to an exofs_components structure that holds a
possible array of exofs_comp and the array of devices + the size of the
arrays.
* Add a "comps" parameter to get_io_state() that specifies the ids creds
and device array to use for each IO.
This enables to keep the layout global, but the device-table view, creds
and IDs at the inode level. It only adds two 64bit to each inode, since
some of these members already existed in another form.
* ios raid engine now access layout-info and comps-info through the passed
pointers. Everything is pre-prepared by caller for generic access of
these structures and arrays.
At the exofs Level:
* Super block holds an exofs_components struct that holds the device
array, previously in layout. The devices there are in device-table
order. The device-array is twice bigger and repeats the device-table
twice so now each inode's device array can point to a random device
and have a round-robin view of the table, making it compatible to
previous exofs versions.
* Each inode has an exofs_components struct that is initialized at
load time, with it's own view of the device table IDs and creds.
When doing IO this gets passed to the io_state together with the
layout.
While preforming this change. Bugs where found where credentials with the
wrong IDs where used to access the different SB objects (super.c). As well
as some dead code. It was never noticed because the target we use does not
check the credentials.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2011-08-06 06:06:04 +08:00
|
|
|
sbi->one_comp.obj.partition);
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
|
2012-03-15 09:01:45 +08:00
|
|
|
exofs_sysfs_sb_del(sbi);
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
exofs_free_sbi(sbi);
|
2008-10-28 22:11:41 +08:00
|
|
|
sb->s_fs_info = NULL;
|
|
|
|
}
|
|
|
|
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs,
|
|
|
|
struct exofs_device_table *dt)
|
|
|
|
{
|
2011-09-28 18:18:45 +08:00
|
|
|
int ret;
|
exofs: RAID0 support
We now support striping over mirror devices. Including variable sized
stripe_unit.
Some limits:
* stripe_unit must be a multiple of PAGE_SIZE
* stripe_unit * stripe_count is maximum upto 32-bit (4Gb)
Tested RAID0 over mirrors, RAID0 only, mirrors only. All check.
Design notes:
* I'm not using a vectored raid-engine mechanism yet. Following the
pnfs-objects-layout data-map structure, "Mirror" is just a private
case of "group_width" == 1, and RAID0 is a private case of
"Mirrors" == 1. The performance lose of the general case over the
particular special case optimization is totally negligible, also
considering the extra code size.
* In general I added a prepare_stripes() stage that divides the
to-be-io pages to the participating devices, the previous
exofs_ios_write/read, now becomes _write/read_mirrors and a new
write/read upper layer loops on all devices calling
_write/read_mirrors. Effectively the prepare_stripes stage is the all
secret.
Also truncate need fixing to accommodate for striping.
* In a RAID0 arrangement, in a regular usage scenario, if all inode
layouts will start at the same device, the small files fill up the
first device and the later devices stay empty, the farther the device
the emptier it is.
To fix that, each inode will start at a different stripe_unit,
according to it's obj_id modulus number-of-stripe-units. And
will then span all stripe-units in the same incrementing order
wrapping back to the beginning of the device table. We call it
a stripe-units moving window.
Special consideration was taken to keep all devices in a mirror
arrangement identical. So a broken osd-device could just be cloned
from one of the mirrors and no FS scrubbing is needed. (We do that
by rotating stripe-unit at a time and not a single device at a time.)
TODO:
We no longer verify object_length == inode->i_size in exofs_iget.
(since i_size is stripped on multiple objects now).
I should introduce a multiple-device attribute reading, and use
it in exofs_iget.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2010-02-01 19:35:51 +08:00
|
|
|
|
2011-08-11 05:15:02 +08:00
|
|
|
sbi->layout.stripe_unit =
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
le64_to_cpu(dt->dt_data_map.cb_stripe_unit);
|
2011-08-11 05:15:02 +08:00
|
|
|
sbi->layout.group_width =
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
le32_to_cpu(dt->dt_data_map.cb_group_width);
|
2011-08-11 05:15:02 +08:00
|
|
|
sbi->layout.group_depth =
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
le32_to_cpu(dt->dt_data_map.cb_group_depth);
|
2011-08-11 05:15:02 +08:00
|
|
|
sbi->layout.mirrors_p1 =
|
|
|
|
le32_to_cpu(dt->dt_data_map.cb_mirror_cnt) + 1;
|
|
|
|
sbi->layout.raid_algorithm =
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
le32_to_cpu(dt->dt_data_map.cb_raid_algorithm);
|
|
|
|
|
2011-09-28 18:18:45 +08:00
|
|
|
ret = ore_verify_layout(numdevs, &sbi->layout);
|
exofs: RAID0 support
We now support striping over mirror devices. Including variable sized
stripe_unit.
Some limits:
* stripe_unit must be a multiple of PAGE_SIZE
* stripe_unit * stripe_count is maximum upto 32-bit (4Gb)
Tested RAID0 over mirrors, RAID0 only, mirrors only. All check.
Design notes:
* I'm not using a vectored raid-engine mechanism yet. Following the
pnfs-objects-layout data-map structure, "Mirror" is just a private
case of "group_width" == 1, and RAID0 is a private case of
"Mirrors" == 1. The performance lose of the general case over the
particular special case optimization is totally negligible, also
considering the extra code size.
* In general I added a prepare_stripes() stage that divides the
to-be-io pages to the participating devices, the previous
exofs_ios_write/read, now becomes _write/read_mirrors and a new
write/read upper layer loops on all devices calling
_write/read_mirrors. Effectively the prepare_stripes stage is the all
secret.
Also truncate need fixing to accommodate for striping.
* In a RAID0 arrangement, in a regular usage scenario, if all inode
layouts will start at the same device, the small files fill up the
first device and the later devices stay empty, the farther the device
the emptier it is.
To fix that, each inode will start at a different stripe_unit,
according to it's obj_id modulus number-of-stripe-units. And
will then span all stripe-units in the same incrementing order
wrapping back to the beginning of the device table. We call it
a stripe-units moving window.
Special consideration was taken to keep all devices in a mirror
arrangement identical. So a broken osd-device could just be cloned
from one of the mirrors and no FS scrubbing is needed. (We do that
by rotating stripe-unit at a time and not a single device at a time.)
TODO:
We no longer verify object_length == inode->i_size in exofs_iget.
(since i_size is stripped on multiple objects now).
I should introduce a multiple-device attribute reading, and use
it in exofs_iget.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2010-02-01 19:35:51 +08:00
|
|
|
|
2011-07-28 08:51:53 +08:00
|
|
|
EXOFS_DBGMSG("exofs: layout: "
|
|
|
|
"num_comps=%u stripe_unit=0x%x group_width=%u "
|
|
|
|
"group_depth=0x%llx mirrors_p1=%u raid_algorithm=%u\n",
|
|
|
|
numdevs,
|
|
|
|
sbi->layout.stripe_unit,
|
|
|
|
sbi->layout.group_width,
|
|
|
|
_LLU(sbi->layout.group_depth),
|
|
|
|
sbi->layout.mirrors_p1,
|
2011-08-11 05:15:02 +08:00
|
|
|
sbi->layout.raid_algorithm);
|
2011-09-28 18:18:45 +08:00
|
|
|
return ret;
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
}
|
|
|
|
|
2011-08-07 10:26:31 +08:00
|
|
|
static unsigned __ra_pages(struct ore_layout *layout)
|
2010-10-08 02:28:18 +08:00
|
|
|
{
|
|
|
|
const unsigned _MIN_RA = 32; /* min 128K read-ahead */
|
|
|
|
unsigned ra_pages = layout->group_width * layout->stripe_unit /
|
|
|
|
PAGE_SIZE;
|
|
|
|
unsigned max_io_pages = exofs_max_io_pages(layout, ~0);
|
|
|
|
|
|
|
|
ra_pages *= 2; /* two stripes */
|
|
|
|
if (ra_pages < _MIN_RA)
|
|
|
|
ra_pages = roundup(_MIN_RA, ra_pages / 2);
|
|
|
|
|
|
|
|
if (ra_pages > max_io_pages)
|
|
|
|
ra_pages = max_io_pages;
|
|
|
|
|
|
|
|
return ra_pages;
|
|
|
|
}
|
|
|
|
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
/* @odi is valid only as long as @fscb_dev is valid */
|
|
|
|
static int exofs_devs_2_odi(struct exofs_dt_device_info *dt_dev,
|
|
|
|
struct osd_dev_info *odi)
|
|
|
|
{
|
|
|
|
odi->systemid_len = le32_to_cpu(dt_dev->systemid_len);
|
2012-01-30 15:59:49 +08:00
|
|
|
if (likely(odi->systemid_len))
|
|
|
|
memcpy(odi->systemid, dt_dev->systemid, OSD_SYSTEMID_LEN);
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
|
|
|
|
odi->osdname_len = le32_to_cpu(dt_dev->osdname_len);
|
|
|
|
odi->osdname = dt_dev->osdname;
|
|
|
|
|
|
|
|
/* FIXME support long names. Will need a _put function */
|
|
|
|
if (dt_dev->long_name_offset)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
/* Make sure osdname is printable!
|
|
|
|
* mkexofs should give us space for a null-terminator else the
|
|
|
|
* device-table is invalid.
|
|
|
|
*/
|
|
|
|
if (unlikely(odi->osdname_len >= sizeof(dt_dev->osdname)))
|
|
|
|
odi->osdname_len = sizeof(dt_dev->osdname) - 1;
|
|
|
|
dt_dev->osdname[odi->osdname_len] = 0;
|
|
|
|
|
|
|
|
/* If it's all zeros something is bad we read past end-of-obj */
|
|
|
|
return !(odi->systemid_len || odi->osdname_len);
|
|
|
|
}
|
|
|
|
|
2014-04-02 22:23:29 +08:00
|
|
|
static int __alloc_dev_table(struct exofs_sb_info *sbi, unsigned numdevs,
|
2011-09-28 19:43:09 +08:00
|
|
|
struct exofs_dev **peds)
|
|
|
|
{
|
2018-06-15 06:27:27 +08:00
|
|
|
/* Twice bigger table: See exofs_init_comps() and comment at
|
|
|
|
* exofs_read_lookup_dev_table()
|
|
|
|
*/
|
|
|
|
const size_t numores = numdevs * 2 - 1;
|
2011-09-28 19:43:09 +08:00
|
|
|
struct exofs_dev *eds;
|
|
|
|
unsigned i;
|
|
|
|
|
2018-06-15 06:27:27 +08:00
|
|
|
sbi->oc.ods = kzalloc(numores * sizeof(struct ore_dev *) +
|
|
|
|
numdevs * sizeof(struct exofs_dev), GFP_KERNEL);
|
|
|
|
if (unlikely(!sbi->oc.ods)) {
|
2012-02-01 22:53:46 +08:00
|
|
|
EXOFS_ERR("ERROR: failed allocating Device array[%d]\n",
|
2011-09-28 19:43:09 +08:00
|
|
|
numdevs);
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
2018-06-15 06:27:27 +08:00
|
|
|
/* Start of allocated struct exofs_dev entries */
|
|
|
|
*peds = eds = (void *)sbi->oc.ods[numores];
|
|
|
|
/* Initialize pointers into struct exofs_dev */
|
2011-09-28 19:43:09 +08:00
|
|
|
for (i = 0; i < numdevs; ++i)
|
2018-06-15 06:27:27 +08:00
|
|
|
sbi->oc.ods[i] = &eds[i].ored;
|
2011-09-28 19:43:09 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-07-28 08:51:53 +08:00
|
|
|
static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi,
|
|
|
|
struct osd_dev *fscb_od,
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
unsigned table_count)
|
|
|
|
{
|
2011-08-07 10:26:31 +08:00
|
|
|
struct ore_comp comp;
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
struct exofs_device_table *dt;
|
2011-09-28 19:43:09 +08:00
|
|
|
struct exofs_dev *eds;
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
unsigned table_bytes = table_count * sizeof(dt->dt_dev_table[0]) +
|
|
|
|
sizeof(*dt);
|
|
|
|
unsigned numdevs, i;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
dt = kmalloc(table_bytes, GFP_KERNEL);
|
|
|
|
if (unlikely(!dt)) {
|
|
|
|
EXOFS_ERR("ERROR: allocating %x bytes for device table\n",
|
|
|
|
table_bytes);
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
2011-09-28 16:39:59 +08:00
|
|
|
sbi->oc.numdevs = 0;
|
exofs: ios: Move to a per inode components & device-table
Exofs raid engine was saving on memory space by having a single layout-info,
single pid, and a single device-table, global to the filesystem. Then passing
a credential and object_id info at the io_state level, private for each
inode. It would also devise this contraption of rotating the device table
view for each inode->ino to spread out the device usage.
This is not compatible with the pnfs-objects standard, demanding that
each inode can have it's own layout-info, device-table, and each object
component it's own pid, oid and creds.
So: Bring exofs raid engine to be usable for generic pnfs-objects use by:
* Define an exofs_comp structure that holds obj_id and credential info.
* Break up exofs_layout struct to an exofs_components structure that holds a
possible array of exofs_comp and the array of devices + the size of the
arrays.
* Add a "comps" parameter to get_io_state() that specifies the ids creds
and device array to use for each IO.
This enables to keep the layout global, but the device-table view, creds
and IDs at the inode level. It only adds two 64bit to each inode, since
some of these members already existed in another form.
* ios raid engine now access layout-info and comps-info through the passed
pointers. Everything is pre-prepared by caller for generic access of
these structures and arrays.
At the exofs Level:
* Super block holds an exofs_components struct that holds the device
array, previously in layout. The devices there are in device-table
order. The device-array is twice bigger and repeats the device-table
twice so now each inode's device array can point to a random device
and have a round-robin view of the table, making it compatible to
previous exofs versions.
* Each inode has an exofs_components struct that is initialized at
load time, with it's own view of the device table IDs and creds.
When doing IO this gets passed to the io_state together with the
layout.
While preforming this change. Bugs where found where credentials with the
wrong IDs where used to access the different SB objects (super.c). As well
as some dead code. It was never noticed because the target we use does not
check the credentials.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2011-08-06 06:06:04 +08:00
|
|
|
|
|
|
|
comp.obj.partition = sbi->one_comp.obj.partition;
|
|
|
|
comp.obj.id = EXOFS_DEVTABLE_ID;
|
|
|
|
exofs_make_credential(comp.cred, &comp.obj);
|
|
|
|
|
|
|
|
ret = exofs_read_kern(fscb_od, comp.cred, &comp.obj, 0, dt,
|
|
|
|
table_bytes);
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
if (unlikely(ret)) {
|
|
|
|
EXOFS_ERR("ERROR: reading device table\n");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
numdevs = le64_to_cpu(dt->dt_num_devices);
|
|
|
|
if (unlikely(!numdevs)) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
WARN_ON(table_count != numdevs);
|
|
|
|
|
|
|
|
ret = _read_and_match_data_map(sbi, numdevs, dt);
|
|
|
|
if (unlikely(ret))
|
|
|
|
goto out;
|
|
|
|
|
2011-09-28 19:43:09 +08:00
|
|
|
ret = __alloc_dev_table(sbi, numdevs, &eds);
|
|
|
|
if (unlikely(ret))
|
|
|
|
goto out;
|
|
|
|
/* exofs round-robins the device table view according to inode
|
|
|
|
* number. We hold a: twice bigger table hence inodes can point
|
|
|
|
* to any device and have a sequential view of the table
|
|
|
|
* starting at this device. See exofs_init_comps()
|
|
|
|
*/
|
|
|
|
memcpy(&sbi->oc.ods[numdevs], &sbi->oc.ods[0],
|
|
|
|
(numdevs - 1) * sizeof(sbi->oc.ods[0]));
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
|
2012-03-15 09:01:45 +08:00
|
|
|
/* create sysfs subdir under which we put the device table
|
|
|
|
* And cluster layout. A Superblock is identified by the string:
|
|
|
|
* "dev[0].osdname"_"pid"
|
|
|
|
*/
|
|
|
|
exofs_sysfs_sb_add(sbi, &dt->dt_dev_table[0]);
|
|
|
|
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
for (i = 0; i < numdevs; i++) {
|
|
|
|
struct exofs_fscb fscb;
|
|
|
|
struct osd_dev_info odi;
|
|
|
|
struct osd_dev *od;
|
|
|
|
|
|
|
|
if (exofs_devs_2_odi(&dt->dt_dev_table[i], &odi)) {
|
|
|
|
EXOFS_ERR("ERROR: Read all-zeros device entry\n");
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
printk(KERN_NOTICE "Add device[%d]: osd_name-%s\n",
|
|
|
|
i, odi.osdname);
|
|
|
|
|
2011-09-28 19:43:09 +08:00
|
|
|
/* the exofs id is currently the table index */
|
|
|
|
eds[i].did = i;
|
|
|
|
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
/* On all devices the device table is identical. The user can
|
|
|
|
* specify any one of the participating devices on the command
|
|
|
|
* line. We always keep them in device-table order.
|
|
|
|
*/
|
|
|
|
if (fscb_od && osduld_device_same(fscb_od, &odi)) {
|
2011-09-28 19:43:09 +08:00
|
|
|
eds[i].ored.od = fscb_od;
|
2011-09-28 16:39:59 +08:00
|
|
|
++sbi->oc.numdevs;
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
fscb_od = NULL;
|
2012-03-15 09:01:45 +08:00
|
|
|
exofs_sysfs_odev_add(&eds[i], sbi);
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
od = osduld_info_lookup(&odi);
|
2010-12-09 22:55:21 +08:00
|
|
|
if (IS_ERR(od)) {
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
ret = PTR_ERR(od);
|
|
|
|
EXOFS_ERR("ERROR: device requested is not found "
|
|
|
|
"osd_name-%s =>%d\n", odi.osdname, ret);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2011-09-28 19:43:09 +08:00
|
|
|
eds[i].ored.od = od;
|
2011-09-28 16:39:59 +08:00
|
|
|
++sbi->oc.numdevs;
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
|
|
|
|
/* Read the fscb of the other devices to make sure the FS
|
|
|
|
* partition is there.
|
|
|
|
*/
|
exofs: ios: Move to a per inode components & device-table
Exofs raid engine was saving on memory space by having a single layout-info,
single pid, and a single device-table, global to the filesystem. Then passing
a credential and object_id info at the io_state level, private for each
inode. It would also devise this contraption of rotating the device table
view for each inode->ino to spread out the device usage.
This is not compatible with the pnfs-objects standard, demanding that
each inode can have it's own layout-info, device-table, and each object
component it's own pid, oid and creds.
So: Bring exofs raid engine to be usable for generic pnfs-objects use by:
* Define an exofs_comp structure that holds obj_id and credential info.
* Break up exofs_layout struct to an exofs_components structure that holds a
possible array of exofs_comp and the array of devices + the size of the
arrays.
* Add a "comps" parameter to get_io_state() that specifies the ids creds
and device array to use for each IO.
This enables to keep the layout global, but the device-table view, creds
and IDs at the inode level. It only adds two 64bit to each inode, since
some of these members already existed in another form.
* ios raid engine now access layout-info and comps-info through the passed
pointers. Everything is pre-prepared by caller for generic access of
these structures and arrays.
At the exofs Level:
* Super block holds an exofs_components struct that holds the device
array, previously in layout. The devices there are in device-table
order. The device-array is twice bigger and repeats the device-table
twice so now each inode's device array can point to a random device
and have a round-robin view of the table, making it compatible to
previous exofs versions.
* Each inode has an exofs_components struct that is initialized at
load time, with it's own view of the device table IDs and creds.
When doing IO this gets passed to the io_state together with the
layout.
While preforming this change. Bugs where found where credentials with the
wrong IDs where used to access the different SB objects (super.c). As well
as some dead code. It was never noticed because the target we use does not
check the credentials.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2011-08-06 06:06:04 +08:00
|
|
|
ret = exofs_read_kern(od, comp.cred, &comp.obj, 0, &fscb,
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
sizeof(fscb));
|
|
|
|
if (unlikely(ret)) {
|
|
|
|
EXOFS_ERR("ERROR: Malformed participating device "
|
|
|
|
"error reading fscb osd_name-%s\n",
|
|
|
|
odi.osdname);
|
|
|
|
goto out;
|
|
|
|
}
|
2012-03-15 09:01:45 +08:00
|
|
|
exofs_sysfs_odev_add(&eds[i], sbi);
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
|
|
|
|
/* TODO: verify other information is correct and FS-uuid
|
|
|
|
* matches. Benny what did you say about device table
|
|
|
|
* generation and old devices?
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
kfree(dt);
|
2011-09-28 19:43:09 +08:00
|
|
|
if (unlikely(fscb_od && !ret)) {
|
exofs: ios: Move to a per inode components & device-table
Exofs raid engine was saving on memory space by having a single layout-info,
single pid, and a single device-table, global to the filesystem. Then passing
a credential and object_id info at the io_state level, private for each
inode. It would also devise this contraption of rotating the device table
view for each inode->ino to spread out the device usage.
This is not compatible with the pnfs-objects standard, demanding that
each inode can have it's own layout-info, device-table, and each object
component it's own pid, oid and creds.
So: Bring exofs raid engine to be usable for generic pnfs-objects use by:
* Define an exofs_comp structure that holds obj_id and credential info.
* Break up exofs_layout struct to an exofs_components structure that holds a
possible array of exofs_comp and the array of devices + the size of the
arrays.
* Add a "comps" parameter to get_io_state() that specifies the ids creds
and device array to use for each IO.
This enables to keep the layout global, but the device-table view, creds
and IDs at the inode level. It only adds two 64bit to each inode, since
some of these members already existed in another form.
* ios raid engine now access layout-info and comps-info through the passed
pointers. Everything is pre-prepared by caller for generic access of
these structures and arrays.
At the exofs Level:
* Super block holds an exofs_components struct that holds the device
array, previously in layout. The devices there are in device-table
order. The device-array is twice bigger and repeats the device-table
twice so now each inode's device array can point to a random device
and have a round-robin view of the table, making it compatible to
previous exofs versions.
* Each inode has an exofs_components struct that is initialized at
load time, with it's own view of the device table IDs and creds.
When doing IO this gets passed to the io_state together with the
layout.
While preforming this change. Bugs where found where credentials with the
wrong IDs where used to access the different SB objects (super.c). As well
as some dead code. It was never noticed because the target we use does not
check the credentials.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2011-08-06 06:06:04 +08:00
|
|
|
EXOFS_ERR("ERROR: Bad device-table container device not present\n");
|
|
|
|
osduld_put_device(fscb_od);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-10-28 22:11:41 +08:00
|
|
|
/*
|
|
|
|
* Read the superblock from the OSD and fill in the fields
|
|
|
|
*/
|
|
|
|
static int exofs_fill_super(struct super_block *sb, void *data, int silent)
|
|
|
|
{
|
|
|
|
struct inode *root;
|
|
|
|
struct exofs_mountopt *opts = data;
|
|
|
|
struct exofs_sb_info *sbi; /*extended info */
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
struct osd_dev *od; /* Master device */
|
2008-10-28 22:11:41 +08:00
|
|
|
struct exofs_fscb fscb; /*on-disk superblock info */
|
2011-08-07 10:26:31 +08:00
|
|
|
struct ore_comp comp;
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
unsigned table_count;
|
2008-10-28 22:11:41 +08:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
|
|
|
|
if (!sbi)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
/* use mount options to fill superblock */
|
2011-01-31 20:32:14 +08:00
|
|
|
if (opts->is_osdname) {
|
|
|
|
struct osd_dev_info odi = {.systemid_len = 0};
|
|
|
|
|
|
|
|
odi.osdname_len = strlen(opts->dev_name);
|
|
|
|
odi.osdname = (u8 *)opts->dev_name;
|
|
|
|
od = osduld_info_lookup(&odi);
|
2011-08-04 11:18:01 +08:00
|
|
|
kfree(opts->dev_name);
|
|
|
|
opts->dev_name = NULL;
|
2011-01-31 20:32:14 +08:00
|
|
|
} else {
|
|
|
|
od = osduld_path_lookup(opts->dev_name);
|
|
|
|
}
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
if (IS_ERR(od)) {
|
2011-01-31 20:32:14 +08:00
|
|
|
ret = -EINVAL;
|
2008-10-28 22:11:41 +08:00
|
|
|
goto free_sbi;
|
|
|
|
}
|
|
|
|
|
2010-01-28 17:46:16 +08:00
|
|
|
/* Default layout in case we do not have a device-table */
|
exofs: RAID0 support
We now support striping over mirror devices. Including variable sized
stripe_unit.
Some limits:
* stripe_unit must be a multiple of PAGE_SIZE
* stripe_unit * stripe_count is maximum upto 32-bit (4Gb)
Tested RAID0 over mirrors, RAID0 only, mirrors only. All check.
Design notes:
* I'm not using a vectored raid-engine mechanism yet. Following the
pnfs-objects-layout data-map structure, "Mirror" is just a private
case of "group_width" == 1, and RAID0 is a private case of
"Mirrors" == 1. The performance lose of the general case over the
particular special case optimization is totally negligible, also
considering the extra code size.
* In general I added a prepare_stripes() stage that divides the
to-be-io pages to the participating devices, the previous
exofs_ios_write/read, now becomes _write/read_mirrors and a new
write/read upper layer loops on all devices calling
_write/read_mirrors. Effectively the prepare_stripes stage is the all
secret.
Also truncate need fixing to accommodate for striping.
* In a RAID0 arrangement, in a regular usage scenario, if all inode
layouts will start at the same device, the small files fill up the
first device and the later devices stay empty, the farther the device
the emptier it is.
To fix that, each inode will start at a different stripe_unit,
according to it's obj_id modulus number-of-stripe-units. And
will then span all stripe-units in the same incrementing order
wrapping back to the beginning of the device table. We call it
a stripe-units moving window.
Special consideration was taken to keep all devices in a mirror
arrangement identical. So a broken osd-device could just be cloned
from one of the mirrors and no FS scrubbing is needed. (We do that
by rotating stripe-unit at a time and not a single device at a time.)
TODO:
We no longer verify object_length == inode->i_size in exofs_iget.
(since i_size is stripped on multiple objects now).
I should introduce a multiple-device attribute reading, and use
it in exofs_iget.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2010-02-01 19:35:51 +08:00
|
|
|
sbi->layout.stripe_unit = PAGE_SIZE;
|
|
|
|
sbi->layout.mirrors_p1 = 1;
|
|
|
|
sbi->layout.group_width = 1;
|
2010-02-11 19:01:39 +08:00
|
|
|
sbi->layout.group_depth = -1;
|
|
|
|
sbi->layout.group_count = 1;
|
2008-10-28 22:11:41 +08:00
|
|
|
sbi->s_timeout = opts->timeout;
|
|
|
|
|
exofs: ios: Move to a per inode components & device-table
Exofs raid engine was saving on memory space by having a single layout-info,
single pid, and a single device-table, global to the filesystem. Then passing
a credential and object_id info at the io_state level, private for each
inode. It would also devise this contraption of rotating the device table
view for each inode->ino to spread out the device usage.
This is not compatible with the pnfs-objects standard, demanding that
each inode can have it's own layout-info, device-table, and each object
component it's own pid, oid and creds.
So: Bring exofs raid engine to be usable for generic pnfs-objects use by:
* Define an exofs_comp structure that holds obj_id and credential info.
* Break up exofs_layout struct to an exofs_components structure that holds a
possible array of exofs_comp and the array of devices + the size of the
arrays.
* Add a "comps" parameter to get_io_state() that specifies the ids creds
and device array to use for each IO.
This enables to keep the layout global, but the device-table view, creds
and IDs at the inode level. It only adds two 64bit to each inode, since
some of these members already existed in another form.
* ios raid engine now access layout-info and comps-info through the passed
pointers. Everything is pre-prepared by caller for generic access of
these structures and arrays.
At the exofs Level:
* Super block holds an exofs_components struct that holds the device
array, previously in layout. The devices there are in device-table
order. The device-array is twice bigger and repeats the device-table
twice so now each inode's device array can point to a random device
and have a round-robin view of the table, making it compatible to
previous exofs versions.
* Each inode has an exofs_components struct that is initialized at
load time, with it's own view of the device table IDs and creds.
When doing IO this gets passed to the io_state together with the
layout.
While preforming this change. Bugs where found where credentials with the
wrong IDs where used to access the different SB objects (super.c). As well
as some dead code. It was never noticed because the target we use does not
check the credentials.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2011-08-06 06:06:04 +08:00
|
|
|
sbi->one_comp.obj.partition = opts->pid;
|
|
|
|
sbi->one_comp.obj.id = 0;
|
|
|
|
exofs_make_credential(sbi->one_comp.cred, &sbi->one_comp.obj);
|
2011-09-28 16:39:59 +08:00
|
|
|
sbi->oc.single_comp = EC_SINGLE_COMP;
|
|
|
|
sbi->oc.comps = &sbi->one_comp;
|
exofs: ios: Move to a per inode components & device-table
Exofs raid engine was saving on memory space by having a single layout-info,
single pid, and a single device-table, global to the filesystem. Then passing
a credential and object_id info at the io_state level, private for each
inode. It would also devise this contraption of rotating the device table
view for each inode->ino to spread out the device usage.
This is not compatible with the pnfs-objects standard, demanding that
each inode can have it's own layout-info, device-table, and each object
component it's own pid, oid and creds.
So: Bring exofs raid engine to be usable for generic pnfs-objects use by:
* Define an exofs_comp structure that holds obj_id and credential info.
* Break up exofs_layout struct to an exofs_components structure that holds a
possible array of exofs_comp and the array of devices + the size of the
arrays.
* Add a "comps" parameter to get_io_state() that specifies the ids creds
and device array to use for each IO.
This enables to keep the layout global, but the device-table view, creds
and IDs at the inode level. It only adds two 64bit to each inode, since
some of these members already existed in another form.
* ios raid engine now access layout-info and comps-info through the passed
pointers. Everything is pre-prepared by caller for generic access of
these structures and arrays.
At the exofs Level:
* Super block holds an exofs_components struct that holds the device
array, previously in layout. The devices there are in device-table
order. The device-array is twice bigger and repeats the device-table
twice so now each inode's device array can point to a random device
and have a round-robin view of the table, making it compatible to
previous exofs versions.
* Each inode has an exofs_components struct that is initialized at
load time, with it's own view of the device table IDs and creds.
When doing IO this gets passed to the io_state together with the
layout.
While preforming this change. Bugs where found where credentials with the
wrong IDs where used to access the different SB objects (super.c). As well
as some dead code. It was never noticed because the target we use does not
check the credentials.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2011-08-06 06:06:04 +08:00
|
|
|
|
2008-10-28 22:11:41 +08:00
|
|
|
/* fill in some other data by hand */
|
|
|
|
memset(sb->s_id, 0, sizeof(sb->s_id));
|
|
|
|
strcpy(sb->s_id, "exofs");
|
|
|
|
sb->s_blocksize = EXOFS_BLKSIZE;
|
|
|
|
sb->s_blocksize_bits = EXOFS_BLKSHIFT;
|
|
|
|
sb->s_maxbytes = MAX_LFS_FILESIZE;
|
2012-02-07 01:45:27 +08:00
|
|
|
sb->s_max_links = EXOFS_LINK_MAX;
|
2008-10-28 22:11:41 +08:00
|
|
|
atomic_set(&sbi->s_curr_pending, 0);
|
|
|
|
sb->s_bdev = NULL;
|
|
|
|
sb->s_dev = 0;
|
|
|
|
|
exofs: ios: Move to a per inode components & device-table
Exofs raid engine was saving on memory space by having a single layout-info,
single pid, and a single device-table, global to the filesystem. Then passing
a credential and object_id info at the io_state level, private for each
inode. It would also devise this contraption of rotating the device table
view for each inode->ino to spread out the device usage.
This is not compatible with the pnfs-objects standard, demanding that
each inode can have it's own layout-info, device-table, and each object
component it's own pid, oid and creds.
So: Bring exofs raid engine to be usable for generic pnfs-objects use by:
* Define an exofs_comp structure that holds obj_id and credential info.
* Break up exofs_layout struct to an exofs_components structure that holds a
possible array of exofs_comp and the array of devices + the size of the
arrays.
* Add a "comps" parameter to get_io_state() that specifies the ids creds
and device array to use for each IO.
This enables to keep the layout global, but the device-table view, creds
and IDs at the inode level. It only adds two 64bit to each inode, since
some of these members already existed in another form.
* ios raid engine now access layout-info and comps-info through the passed
pointers. Everything is pre-prepared by caller for generic access of
these structures and arrays.
At the exofs Level:
* Super block holds an exofs_components struct that holds the device
array, previously in layout. The devices there are in device-table
order. The device-array is twice bigger and repeats the device-table
twice so now each inode's device array can point to a random device
and have a round-robin view of the table, making it compatible to
previous exofs versions.
* Each inode has an exofs_components struct that is initialized at
load time, with it's own view of the device table IDs and creds.
When doing IO this gets passed to the io_state together with the
layout.
While preforming this change. Bugs where found where credentials with the
wrong IDs where used to access the different SB objects (super.c). As well
as some dead code. It was never noticed because the target we use does not
check the credentials.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2011-08-06 06:06:04 +08:00
|
|
|
comp.obj.partition = sbi->one_comp.obj.partition;
|
|
|
|
comp.obj.id = EXOFS_SUPER_ID;
|
|
|
|
exofs_make_credential(comp.cred, &comp.obj);
|
2008-10-28 22:11:41 +08:00
|
|
|
|
exofs: ios: Move to a per inode components & device-table
Exofs raid engine was saving on memory space by having a single layout-info,
single pid, and a single device-table, global to the filesystem. Then passing
a credential and object_id info at the io_state level, private for each
inode. It would also devise this contraption of rotating the device table
view for each inode->ino to spread out the device usage.
This is not compatible with the pnfs-objects standard, demanding that
each inode can have it's own layout-info, device-table, and each object
component it's own pid, oid and creds.
So: Bring exofs raid engine to be usable for generic pnfs-objects use by:
* Define an exofs_comp structure that holds obj_id and credential info.
* Break up exofs_layout struct to an exofs_components structure that holds a
possible array of exofs_comp and the array of devices + the size of the
arrays.
* Add a "comps" parameter to get_io_state() that specifies the ids creds
and device array to use for each IO.
This enables to keep the layout global, but the device-table view, creds
and IDs at the inode level. It only adds two 64bit to each inode, since
some of these members already existed in another form.
* ios raid engine now access layout-info and comps-info through the passed
pointers. Everything is pre-prepared by caller for generic access of
these structures and arrays.
At the exofs Level:
* Super block holds an exofs_components struct that holds the device
array, previously in layout. The devices there are in device-table
order. The device-array is twice bigger and repeats the device-table
twice so now each inode's device array can point to a random device
and have a round-robin view of the table, making it compatible to
previous exofs versions.
* Each inode has an exofs_components struct that is initialized at
load time, with it's own view of the device table IDs and creds.
When doing IO this gets passed to the io_state together with the
layout.
While preforming this change. Bugs where found where credentials with the
wrong IDs where used to access the different SB objects (super.c). As well
as some dead code. It was never noticed because the target we use does not
check the credentials.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2011-08-06 06:06:04 +08:00
|
|
|
ret = exofs_read_kern(od, comp.cred, &comp.obj, 0, &fscb, sizeof(fscb));
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
if (unlikely(ret))
|
2008-10-28 22:11:41 +08:00
|
|
|
goto free_sbi;
|
|
|
|
|
|
|
|
sb->s_magic = le16_to_cpu(fscb.s_magic);
|
2011-02-03 23:53:25 +08:00
|
|
|
/* NOTE: we read below to be backward compatible with old versions */
|
2008-10-28 22:11:41 +08:00
|
|
|
sbi->s_nextid = le64_to_cpu(fscb.s_nextid);
|
|
|
|
sbi->s_numfiles = le32_to_cpu(fscb.s_numfiles);
|
|
|
|
|
|
|
|
/* make sure what we read from the object store is correct */
|
|
|
|
if (sb->s_magic != EXOFS_SUPER_MAGIC) {
|
|
|
|
if (!silent)
|
|
|
|
EXOFS_ERR("ERROR: Bad magic value\n");
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto free_sbi;
|
|
|
|
}
|
2011-02-03 23:53:25 +08:00
|
|
|
if (le32_to_cpu(fscb.s_version) > EXOFS_FSCB_VER) {
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
EXOFS_ERR("ERROR: Bad FSCB version expected-%d got-%d\n",
|
|
|
|
EXOFS_FSCB_VER, le32_to_cpu(fscb.s_version));
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto free_sbi;
|
|
|
|
}
|
2008-10-28 22:11:41 +08:00
|
|
|
|
|
|
|
/* start generation numbers from a random point */
|
|
|
|
get_random_bytes(&sbi->s_next_generation, sizeof(u32));
|
|
|
|
spin_lock_init(&sbi->s_next_gen_lock);
|
|
|
|
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
table_count = le64_to_cpu(fscb.s_dev_table_count);
|
|
|
|
if (table_count) {
|
2011-07-28 08:51:53 +08:00
|
|
|
ret = exofs_read_lookup_dev_table(sbi, od, table_count);
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
if (unlikely(ret))
|
|
|
|
goto free_sbi;
|
2011-07-28 08:51:53 +08:00
|
|
|
} else {
|
2011-09-28 19:43:09 +08:00
|
|
|
struct exofs_dev *eds;
|
|
|
|
|
|
|
|
ret = __alloc_dev_table(sbi, 1, &eds);
|
|
|
|
if (unlikely(ret))
|
|
|
|
goto free_sbi;
|
|
|
|
|
|
|
|
ore_comp_set_dev(&sbi->oc, 0, od);
|
2012-05-16 19:22:21 +08:00
|
|
|
sbi->oc.numdevs = 1;
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
}
|
|
|
|
|
2011-02-03 23:53:25 +08:00
|
|
|
__sbi_read_stats(sbi);
|
|
|
|
|
2008-10-28 22:11:41 +08:00
|
|
|
/* set up operation vectors */
|
2017-04-12 18:24:39 +08:00
|
|
|
ret = super_setup_bdi(sb);
|
|
|
|
if (ret) {
|
|
|
|
EXOFS_DBGMSG("Failed to super_setup_bdi\n");
|
|
|
|
goto free_sbi;
|
|
|
|
}
|
|
|
|
sb->s_bdi->ra_pages = __ra_pages(&sbi->layout);
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
sb->s_fs_info = sbi;
|
2008-10-28 22:11:41 +08:00
|
|
|
sb->s_op = &exofs_sops;
|
2009-03-22 18:47:26 +08:00
|
|
|
sb->s_export_op = &exofs_export_ops;
|
2008-10-28 22:11:41 +08:00
|
|
|
root = exofs_iget(sb, EXOFS_ROOT_ID - EXOFS_OBJ_OFF);
|
|
|
|
if (IS_ERR(root)) {
|
|
|
|
EXOFS_ERR("ERROR: exofs_iget failed\n");
|
|
|
|
ret = PTR_ERR(root);
|
|
|
|
goto free_sbi;
|
|
|
|
}
|
2012-01-09 11:15:13 +08:00
|
|
|
sb->s_root = d_make_root(root);
|
2008-10-28 22:11:41 +08:00
|
|
|
if (!sb->s_root) {
|
|
|
|
EXOFS_ERR("ERROR: get root inode failed\n");
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto free_sbi;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!S_ISDIR(root->i_mode)) {
|
|
|
|
dput(sb->s_root);
|
|
|
|
sb->s_root = NULL;
|
|
|
|
EXOFS_ERR("ERROR: corrupt root inode (mode = %hd)\n",
|
|
|
|
root->i_mode);
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto free_sbi;
|
|
|
|
}
|
|
|
|
|
2012-03-15 09:01:45 +08:00
|
|
|
exofs_sysfs_dbg_print();
|
2011-09-28 19:43:09 +08:00
|
|
|
_exofs_print_device("Mounting", opts->dev_name,
|
|
|
|
ore_comp_dev(&sbi->oc, 0),
|
exofs: ios: Move to a per inode components & device-table
Exofs raid engine was saving on memory space by having a single layout-info,
single pid, and a single device-table, global to the filesystem. Then passing
a credential and object_id info at the io_state level, private for each
inode. It would also devise this contraption of rotating the device table
view for each inode->ino to spread out the device usage.
This is not compatible with the pnfs-objects standard, demanding that
each inode can have it's own layout-info, device-table, and each object
component it's own pid, oid and creds.
So: Bring exofs raid engine to be usable for generic pnfs-objects use by:
* Define an exofs_comp structure that holds obj_id and credential info.
* Break up exofs_layout struct to an exofs_components structure that holds a
possible array of exofs_comp and the array of devices + the size of the
arrays.
* Add a "comps" parameter to get_io_state() that specifies the ids creds
and device array to use for each IO.
This enables to keep the layout global, but the device-table view, creds
and IDs at the inode level. It only adds two 64bit to each inode, since
some of these members already existed in another form.
* ios raid engine now access layout-info and comps-info through the passed
pointers. Everything is pre-prepared by caller for generic access of
these structures and arrays.
At the exofs Level:
* Super block holds an exofs_components struct that holds the device
array, previously in layout. The devices there are in device-table
order. The device-array is twice bigger and repeats the device-table
twice so now each inode's device array can point to a random device
and have a round-robin view of the table, making it compatible to
previous exofs versions.
* Each inode has an exofs_components struct that is initialized at
load time, with it's own view of the device table IDs and creds.
When doing IO this gets passed to the io_state together with the
layout.
While preforming this change. Bugs where found where credentials with the
wrong IDs where used to access the different SB objects (super.c). As well
as some dead code. It was never noticed because the target we use does not
check the credentials.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2011-08-06 06:06:04 +08:00
|
|
|
sbi->one_comp.obj.partition);
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
return 0;
|
2008-10-28 22:11:41 +08:00
|
|
|
|
|
|
|
free_sbi:
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n",
|
exofs: ios: Move to a per inode components & device-table
Exofs raid engine was saving on memory space by having a single layout-info,
single pid, and a single device-table, global to the filesystem. Then passing
a credential and object_id info at the io_state level, private for each
inode. It would also devise this contraption of rotating the device table
view for each inode->ino to spread out the device usage.
This is not compatible with the pnfs-objects standard, demanding that
each inode can have it's own layout-info, device-table, and each object
component it's own pid, oid and creds.
So: Bring exofs raid engine to be usable for generic pnfs-objects use by:
* Define an exofs_comp structure that holds obj_id and credential info.
* Break up exofs_layout struct to an exofs_components structure that holds a
possible array of exofs_comp and the array of devices + the size of the
arrays.
* Add a "comps" parameter to get_io_state() that specifies the ids creds
and device array to use for each IO.
This enables to keep the layout global, but the device-table view, creds
and IDs at the inode level. It only adds two 64bit to each inode, since
some of these members already existed in another form.
* ios raid engine now access layout-info and comps-info through the passed
pointers. Everything is pre-prepared by caller for generic access of
these structures and arrays.
At the exofs Level:
* Super block holds an exofs_components struct that holds the device
array, previously in layout. The devices there are in device-table
order. The device-array is twice bigger and repeats the device-table
twice so now each inode's device array can point to a random device
and have a round-robin view of the table, making it compatible to
previous exofs versions.
* Each inode has an exofs_components struct that is initialized at
load time, with it's own view of the device table IDs and creds.
When doing IO this gets passed to the io_state together with the
layout.
While preforming this change. Bugs where found where credentials with the
wrong IDs where used to access the different SB objects (super.c). As well
as some dead code. It was never noticed because the target we use does not
check the credentials.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2011-08-06 06:06:04 +08:00
|
|
|
opts->dev_name, sbi->one_comp.obj.partition, ret);
|
exofs: Multi-device mirror support
This patch changes on-disk format, it is accompanied with a parallel
patch to mkfs.exofs that enables multi-device capabilities.
After this patch, old exofs will refuse to mount a new formatted FS and
new exofs will refuse an old format. This is done by moving the magic
field offset inside the FSCB. A new FSCB *version* field was added. In
the future, exofs will refuse to mount unmatched FSCB version. To
up-grade or down-grade an exofs one must use mkfs.exofs --upgrade option
before mounting.
Introduced, a new object that contains a *device-table*. This object
contains the default *data-map* and a linear array of devices
information, which identifies the devices used in the filesystem. This
object is only written to offline by mkfs.exofs. This is why it is kept
separate from the FSCB, since the later is written to while mounted.
Same partition number, same object number is used on all devices only
the device varies.
* define the new format, then load the device table on mount time make
sure every thing is supported.
* Change I/O engine to now support Mirror IO, .i.e write same data
to multiple devices, read from a random device to spread the
read-load from multiple clients (TODO: stripe read)
Implementation notes:
A few points introduced in previous patch should be mentioned here:
* Special care was made so absolutlly all operation that have any chance
of failing are done before any osd-request is executed. This is to
minimize the need for a data consistency recovery, to only real IO
errors.
* Each IO state has a kref. It starts at 1, any osd-request executed
will increment the kref, finally when all are executed the first ref
is dropped. At IO-done, each request completion decrements the kref,
the last one to return executes the internal _last_io() routine.
_last_io() will call the registered io_state_done. On sync mode a
caller does not supply a done method, indicating a synchronous
request, the caller is put to sleep and a special io_state_done is
registered that will awaken the caller. Though also in sync mode all
operations are executed in parallel.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-16 22:03:05 +08:00
|
|
|
exofs_free_sbi(sbi);
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
return ret;
|
2008-10-28 22:11:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set up the superblock (calls exofs_fill_super eventually)
|
|
|
|
*/
|
2010-07-25 15:46:36 +08:00
|
|
|
static struct dentry *exofs_mount(struct file_system_type *type,
|
2008-10-28 22:11:41 +08:00
|
|
|
int flags, const char *dev_name,
|
2010-07-25 15:46:36 +08:00
|
|
|
void *data)
|
2008-10-28 22:11:41 +08:00
|
|
|
{
|
|
|
|
struct exofs_mountopt opts;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = parse_options(data, &opts);
|
2018-06-13 12:05:13 +08:00
|
|
|
if (ret) {
|
|
|
|
kfree(opts.dev_name);
|
2010-07-25 15:46:36 +08:00
|
|
|
return ERR_PTR(ret);
|
2018-06-13 12:05:13 +08:00
|
|
|
}
|
2008-10-28 22:11:41 +08:00
|
|
|
|
2011-01-31 20:32:14 +08:00
|
|
|
if (!opts.dev_name)
|
|
|
|
opts.dev_name = dev_name;
|
2010-07-25 15:46:36 +08:00
|
|
|
return mount_nodev(type, flags, &opts, exofs_fill_super);
|
2008-10-28 22:11:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return information about the file system state in the buffer. This is used
|
|
|
|
* by the 'df' command, for example.
|
|
|
|
*/
|
|
|
|
static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
|
|
|
{
|
|
|
|
struct super_block *sb = dentry->d_sb;
|
|
|
|
struct exofs_sb_info *sbi = sb->s_fs_info;
|
2011-08-07 10:26:31 +08:00
|
|
|
struct ore_io_state *ios;
|
2008-10-28 22:11:41 +08:00
|
|
|
struct osd_attr attrs[] = {
|
|
|
|
ATTR_DEF(OSD_APAGE_PARTITION_QUOTAS,
|
|
|
|
OSD_ATTR_PQ_CAPACITY_QUOTA, sizeof(__be64)),
|
|
|
|
ATTR_DEF(OSD_APAGE_PARTITION_INFORMATION,
|
|
|
|
OSD_ATTR_PI_USED_CAPACITY, sizeof(__be64)),
|
|
|
|
};
|
|
|
|
uint64_t capacity = ULLONG_MAX;
|
|
|
|
uint64_t used = ULLONG_MAX;
|
|
|
|
int ret;
|
|
|
|
|
2011-09-28 16:39:59 +08:00
|
|
|
ret = ore_get_io_state(&sbi->layout, &sbi->oc, &ios);
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
if (ret) {
|
2011-08-07 10:26:31 +08:00
|
|
|
EXOFS_DBGMSG("ore_get_io_state failed.\n");
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
return ret;
|
2008-10-28 22:11:41 +08:00
|
|
|
}
|
|
|
|
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
ios->in_attr = attrs;
|
|
|
|
ios->in_attr_len = ARRAY_SIZE(attrs);
|
|
|
|
|
2011-08-07 10:26:31 +08:00
|
|
|
ret = ore_read(ios);
|
2008-10-28 22:11:41 +08:00
|
|
|
if (unlikely(ret))
|
|
|
|
goto out;
|
|
|
|
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
ret = extract_attr_from_ios(ios, &attrs[0]);
|
2009-11-03 00:19:24 +08:00
|
|
|
if (likely(!ret)) {
|
2008-10-28 22:11:41 +08:00
|
|
|
capacity = get_unaligned_be64(attrs[0].val_ptr);
|
2009-11-03 00:19:24 +08:00
|
|
|
if (unlikely(!capacity))
|
|
|
|
capacity = ULLONG_MAX;
|
|
|
|
} else
|
2008-10-28 22:11:41 +08:00
|
|
|
EXOFS_DBGMSG("exofs_statfs: get capacity failed.\n");
|
|
|
|
|
exofs: Move all operations to an io_engine
In anticipation for multi-device operations, we separate osd operations
into an abstract I/O API. Currently only one device is used but later
when adding more devices, we will drive all devices in parallel according
to a "data_map" that describes how data is arranged on multiple devices.
The file system level operates, like before, as if there is one object
(inode-number) and an i_size. The io engine will split this to the same
object-number but on multiple device.
At first we introduce Mirror (raid 1) layout. But at the final outcome
we intend to fully implement the pNFS-Objects data-map, including
raid 0,4,5,6 over mirrored devices, over multiple device-groups. And
more. See: http://tools.ietf.org/html/draft-ietf-nfsv4-pnfs-obj-12
* Define an io_state based API for accessing osd storage devices
in an abstract way.
Usage:
First a caller allocates an io state with:
exofs_get_io_state(struct exofs_sb_info *sbi,
struct exofs_io_state** ios);
Then calles one of:
exofs_sbi_create(struct exofs_io_state *ios);
exofs_sbi_remove(struct exofs_io_state *ios);
exofs_sbi_write(struct exofs_io_state *ios);
exofs_sbi_read(struct exofs_io_state *ios);
exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len);
And when done
exofs_put_io_state(struct exofs_io_state *ios);
* Convert all source files to use this new API
* Convert from bio_alloc to bio_kmalloc
* In io engine we make use of the now fixed osd_req_decode_sense
There are no functional changes or on disk additions after this patch.
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
2009-11-08 20:54:08 +08:00
|
|
|
ret = extract_attr_from_ios(ios, &attrs[1]);
|
2008-10-28 22:11:41 +08:00
|
|
|
if (likely(!ret))
|
|
|
|
used = get_unaligned_be64(attrs[1].val_ptr);
|
|
|
|
else
|
|
|
|
EXOFS_DBGMSG("exofs_statfs: get used-space failed.\n");
|
|
|
|
|
|
|
|
/* fill in the stats buffer */
|
|
|
|
buf->f_type = EXOFS_SUPER_MAGIC;
|
|
|
|
buf->f_bsize = EXOFS_BLKSIZE;
|
2009-11-03 00:19:24 +08:00
|
|
|
buf->f_blocks = capacity >> 9;
|
|
|
|
buf->f_bfree = (capacity - used) >> 9;
|
2008-10-28 22:11:41 +08:00
|
|
|
buf->f_bavail = buf->f_bfree;
|
|
|
|
buf->f_files = sbi->s_numfiles;
|
|
|
|
buf->f_ffree = EXOFS_MAX_ID - sbi->s_numfiles;
|
|
|
|
buf->f_namelen = EXOFS_NAME_LEN;
|
|
|
|
|
|
|
|
out:
|
2011-08-07 10:26:31 +08:00
|
|
|
ore_put_io_state(ios);
|
2008-10-28 22:11:41 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct super_operations exofs_sops = {
|
|
|
|
.alloc_inode = exofs_alloc_inode,
|
|
|
|
.destroy_inode = exofs_destroy_inode,
|
|
|
|
.write_inode = exofs_write_inode,
|
2010-06-07 23:42:26 +08:00
|
|
|
.evict_inode = exofs_evict_inode,
|
2008-10-28 22:11:41 +08:00
|
|
|
.put_super = exofs_put_super,
|
2009-06-08 16:03:58 +08:00
|
|
|
.sync_fs = exofs_sync_fs,
|
2008-10-28 22:11:41 +08:00
|
|
|
.statfs = exofs_statfs,
|
|
|
|
};
|
|
|
|
|
2009-03-22 18:47:26 +08:00
|
|
|
/******************************************************************************
|
|
|
|
* EXPORT OPERATIONS
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2011-09-24 04:46:51 +08:00
|
|
|
static struct dentry *exofs_get_parent(struct dentry *child)
|
2009-03-22 18:47:26 +08:00
|
|
|
{
|
|
|
|
unsigned long ino = exofs_parent_ino(child);
|
|
|
|
|
|
|
|
if (!ino)
|
2011-07-09 08:56:55 +08:00
|
|
|
return ERR_PTR(-ESTALE);
|
2009-03-22 18:47:26 +08:00
|
|
|
|
2016-04-10 13:33:30 +08:00
|
|
|
return d_obtain_alias(exofs_iget(child->d_sb, ino));
|
2009-03-22 18:47:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct inode *exofs_nfs_get_inode(struct super_block *sb,
|
|
|
|
u64 ino, u32 generation)
|
|
|
|
{
|
|
|
|
struct inode *inode;
|
|
|
|
|
|
|
|
inode = exofs_iget(sb, ino);
|
|
|
|
if (IS_ERR(inode))
|
|
|
|
return ERR_CAST(inode);
|
|
|
|
if (generation && inode->i_generation != generation) {
|
|
|
|
/* we didn't find the right inode.. */
|
|
|
|
iput(inode);
|
|
|
|
return ERR_PTR(-ESTALE);
|
|
|
|
}
|
|
|
|
return inode;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct dentry *exofs_fh_to_dentry(struct super_block *sb,
|
|
|
|
struct fid *fid, int fh_len, int fh_type)
|
|
|
|
{
|
|
|
|
return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
|
|
|
|
exofs_nfs_get_inode);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct dentry *exofs_fh_to_parent(struct super_block *sb,
|
|
|
|
struct fid *fid, int fh_len, int fh_type)
|
|
|
|
{
|
|
|
|
return generic_fh_to_parent(sb, fid, fh_len, fh_type,
|
|
|
|
exofs_nfs_get_inode);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct export_operations exofs_export_ops = {
|
|
|
|
.fh_to_dentry = exofs_fh_to_dentry,
|
|
|
|
.fh_to_parent = exofs_fh_to_parent,
|
|
|
|
.get_parent = exofs_get_parent,
|
|
|
|
};
|
|
|
|
|
2008-10-28 22:11:41 +08:00
|
|
|
/******************************************************************************
|
|
|
|
* INSMOD/RMMOD
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* struct that describes this file system
|
|
|
|
*/
|
|
|
|
static struct file_system_type exofs_type = {
|
|
|
|
.owner = THIS_MODULE,
|
|
|
|
.name = "exofs",
|
2010-07-25 15:46:36 +08:00
|
|
|
.mount = exofs_mount,
|
2008-10-28 22:11:41 +08:00
|
|
|
.kill_sb = generic_shutdown_super,
|
|
|
|
};
|
2013-03-03 11:39:14 +08:00
|
|
|
MODULE_ALIAS_FS("exofs");
|
2008-10-28 22:11:41 +08:00
|
|
|
|
|
|
|
static int __init init_exofs(void)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = init_inodecache();
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
err = register_filesystem(&exofs_type);
|
|
|
|
if (err)
|
|
|
|
goto out_d;
|
|
|
|
|
2012-03-15 09:01:45 +08:00
|
|
|
/* We don't fail if sysfs creation failed */
|
|
|
|
exofs_sysfs_init();
|
|
|
|
|
2008-10-28 22:11:41 +08:00
|
|
|
return 0;
|
|
|
|
out_d:
|
|
|
|
destroy_inodecache();
|
|
|
|
out:
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __exit exit_exofs(void)
|
|
|
|
{
|
2012-03-15 09:01:45 +08:00
|
|
|
exofs_sysfs_uninit();
|
2008-10-28 22:11:41 +08:00
|
|
|
unregister_filesystem(&exofs_type);
|
|
|
|
destroy_inodecache();
|
|
|
|
}
|
|
|
|
|
|
|
|
MODULE_AUTHOR("Avishay Traeger <avishay@gmail.com>");
|
|
|
|
MODULE_DESCRIPTION("exofs");
|
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
|
|
|
|
module_init(init_exofs)
|
|
|
|
module_exit(exit_exofs)
|