exofs: Define on-disk per-inode optional layout attribute

* Layouts describe the way a file is spread on multiple devices.
  The layout information is stored in the objects attribute introduced
  in this patch.

* There can be multiple generating function for the layout.
  Currently defined:
    - No attribute present - use below moving-window on global
      device table, all devices.
      (This is the only one currently used in exofs)
    - an obj_id generated moving window - the obj_id is a randomizing
      factor in the otherwise global map layout.
    - An explicit layout stored, including a data_map and a device
      index list.
    - More might be defined in future ...

* There are two attributes defined of the same structure:
  A-data-files-layout - This layout is used by data-files. If present
                        at a directory, all files of that directory will
                        be created with this layout.
  A-meta-data-layout - This layout is used by a directory and other
                       meta-data information. Also inherited at creation
                       of subdirectories.

* At creation time inodes are created with the layout specified above.
  A usermode utility may change the creation layout on a give directory
  or file. Which in the case of directories, will also apply to newly
  created files/subdirectories, children of that directory.
  In the simple unaltered case of a newly created exofs, no layout
  attributes are present, and all layouts adhere to the layout specified
  at the device-table.

* In case of a future file system loaded in an old exofs-driver.
  At iget(), the generating_function is inspected and if not supported
  will return an IO error to the application and the inode will not
  be loaded. So not to damage any data.
  Note: After this patch we do not yet support any type of layout
        only the RAID0 patch that enables striping at the super-block
        level will add support for RAID0 layouts above. This way we
        are past and future compatible and fully bisectable.

* Access to the device table is done by an accessor since
  it will change according to above information.

Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
This commit is contained in:
Boaz Harrosh
2010-01-28 11:58:08 +02:00
parent 46f4d973f6
commit d9c740d225
4 changed files with 114 additions and 10 deletions

View File

@ -859,6 +859,15 @@ int exofs_setattr(struct dentry *dentry, struct iattr *iattr)
return error;
}
static const struct osd_attr g_attr_inode_file_layout = ATTR_DEF(
EXOFS_APAGE_FS_DATA,
EXOFS_ATTR_INODE_FILE_LAYOUT,
0);
static const struct osd_attr g_attr_inode_dir_layout = ATTR_DEF(
EXOFS_APAGE_FS_DATA,
EXOFS_ATTR_INODE_DIR_LAYOUT,
0);
/*
* Read an inode from the OSD, and return it as is. We also return the size
* attribute in the 'obj_size' argument.
@ -867,11 +876,16 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
struct exofs_fcb *inode, uint64_t *obj_size)
{
struct exofs_sb_info *sbi = sb->s_fs_info;
struct osd_attr attrs[2];
struct osd_attr attrs[] = {
[0] = g_attr_inode_data,
[1] = g_attr_inode_file_layout,
[2] = g_attr_inode_dir_layout,
[3] = g_attr_logical_length,
};
struct exofs_io_state *ios;
struct exofs_on_disk_inode_layout *layout;
int ret;
*obj_size = ~0;
ret = exofs_get_io_state(&sbi->layout, &ios);
if (unlikely(ret)) {
EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__);
@ -882,8 +896,9 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
exofs_make_credential(oi->i_cred, &ios->obj);
ios->cred = oi->i_cred;
attrs[0] = g_attr_inode_data;
attrs[1] = g_attr_logical_length;
attrs[1].len = exofs_on_disk_inode_layout_size(sbi->layout.s_numdevs);
attrs[2].len = exofs_on_disk_inode_layout_size(sbi->layout.s_numdevs);
ios->in_attr = attrs;
ios->in_attr_len = ARRAY_SIZE(attrs);
@ -900,12 +915,43 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
memcpy(inode, attrs[0].val_ptr, EXOFS_INO_ATTR_SIZE);
ret = extract_attr_from_ios(ios, &attrs[1]);
if (ret) {
EXOFS_ERR("%s: extract_attr of inode_data failed\n", __func__);
goto out;
}
if (attrs[1].len) {
layout = attrs[1].val_ptr;
if (layout->gen_func != cpu_to_le16(LAYOUT_MOVING_WINDOW)) {
EXOFS_ERR("%s: unsupported files layout %d\n",
__func__, layout->gen_func);
ret = -ENOTSUPP;
goto out;
}
}
ret = extract_attr_from_ios(ios, &attrs[2]);
if (ret) {
EXOFS_ERR("%s: extract_attr of inode_data failed\n", __func__);
goto out;
}
if (attrs[2].len) {
layout = attrs[2].val_ptr;
if (layout->gen_func != cpu_to_le16(LAYOUT_MOVING_WINDOW)) {
EXOFS_ERR("%s: unsupported meta-data layout %d\n",
__func__, layout->gen_func);
ret = -ENOTSUPP;
goto out;
}
}
*obj_size = ~0;
ret = extract_attr_from_ios(ios, &attrs[3]);
if (ret) {
EXOFS_ERR("%s: extract_attr of logical_length failed\n",
__func__);
goto out;
}
*obj_size = get_unaligned_be64(attrs[1].val_ptr);
*obj_size = get_unaligned_be64(attrs[3].val_ptr);
out:
exofs_put_io_state(ios);