[PATCH 1/9] exofs: osd Swiss army knife

Boaz Harrosh
2008-12-16T15:16:33Z

In this patch are all the osd infrastructure that will be used later
by the file system.

Also the declarations of constants, on disk structures, and prototypes.

And the Kbuild+Kconfig files needed to build the exofs module.

Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
---
fs/exofs/Kbuild | 30 +++++
fs/exofs/Kconfig | 13 ++
fs/exofs/common.h | 154 ++++++++++++++++++++++++
fs/exofs/exofs.h | 183 +++++++++++++++++++++++++++++
fs/exofs/osd.c | 334 +++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 714 insertions(+), 0 deletions(-)
create mode 100644 fs/exofs/Kbuild
create mode 100644 fs/exofs/Kconfig
create mode 100644 fs/exofs/common.h
create mode 100644 fs/exofs/exofs.h
create mode 100644 fs/exofs/osd.c

diff --git a/fs/exofs/Kbuild b/fs/exofs/Kbuild
new file mode 100644
index 0000000..fd3351e
--- /dev/null
+++ b/fs/exofs/Kbuild
@@ -0,0 +1,30 @@
+#
+# Kbuild for the EXOFS module
+#
+# Copyright (C) 2008 Panasas Inc. All rights reserved.
+#
+# Authors:
+# Boaz Harrosh <bharrosh@panasas.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2
+#
+# Kbuild - Gets included from the Kernels Makefile and build system
+#
+
+ifneq ($(OSD_INC),)
+# we are built out-of-tree Kconfigure everything as on
+
+CONFIG_EXOFS_FS=m
+ccflags += -DCONFIG_EXOFS_FS -DCONFIG_EXOFS_FS_MODULE
+# ccflags += -DCONFIG_EXOFS_DEBUG
+
+# if we are built out-of-tree and the hosting kernel has OSD headers
+# then "ccflags-y +=" will not pick the out-off-tree headers. Only by doing
+# this it will work. This might break in future kernels
+KBUILD_CPPFLAGS := -I$(OSD_INC) $(KBUILD_CPPFLAGS)
+
+endif
+
+exofs-objs := osd.o
+obj-$(CONFIG_EXOFS_FS) += exofs.o
diff --git a/fs/exofs/Kconfig b/fs/exofs/Kconfig
new file mode 100644
index 0000000..86194b2
--- /dev/null
+++ b/fs/exofs/Kconfig
@@ -0,0 +1,13 @@
+config EXOFS_FS
+ tristate "exofs: OSD based file system support"
+ depends on SCSI_OSD_ULD
+ help
+ EXOFS is a file system that uses an OSD storage device,
+ as its backing storage.
+
+# Debugging-related stuff
+config EXOFS_DEBUG
+ bool "Enable debugging"
+ depends on EXOFS_FS
+ help
+ This option enables EXOFS debug prints.
diff --git a/fs/exofs/common.h b/fs/exofs/common.h
new file mode 100644
index 0000000..9a165b3
--- /dev/null
+++ b/fs/exofs/common.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ *
+ * 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
+ */
+
+#ifndef __EXOFS_COM_H__
+#define __EXOFS_COM_H__
+
+#include <linux/types.h>
+#include <linux/timex.h>
+
+#include <scsi/osd_attributes.h>
+#include <scsi/osd_initiator.h>
+#include <scsi/osd_sec.h>
+
+/****************************************************************************
+ * Object ID related defines
+ * NOTE: inode# = object ID - EXOFS_OBJ_OFF
+ ****************************************************************************/
+#define EXOFS_OBJ_OFF 0x10000 /* offset for objects */
+#define EXOFS_SUPER_ID 0x10000 /* object ID for on-disk superblock */
+#define EXOFS_BM_ID 0x10001 /* object ID for ID bitmap */
+#define EXOFS_ROOT_ID 0x10002 /* object ID for root directory */
+#define EXOFS_TEST_ID 0x10003 /* object ID for test object */
+
+/* exofs Application specific page/attribute */
+#ifndef OSD_PAGE_NUM_IBM_UOBJ_FS_DATA
+# define OSD_PAGE_NUM_IBM_UOBJ_FS_DATA (OSD_APAGE_APP_DEFINED_FIRST + 3)
+# define OSD_ATTR_NUM_IBM_UOBJ_FS_DATA_INODE 1
+#endif
+
+/*
+ * The maximum number of files we can have is limited by the size of the
+ * inode number. This is the largest object ID that the file system supports.
+ * Object IDs 0, 1, and 2 are always in use (see above defines).
+ */
+enum {
+ EXOFS_UINT64_MAX = (~0LL),
+ EXOFS_MAX_INO_ID = (sizeof(ino_t) * 8 == 64) ? EXOFS_UINT64_MAX :
+ (1LL << (sizeof(ino_t) * 8 - 1)),
+ EXOFS_MAX_ID = (EXOFS_MAX_INO_ID - 1 - EXOFS_OBJ_OFF),
+};
+
+/****************************************************************************
+ * Misc.
+ ****************************************************************************/
+#define EXOFS_BLKSHIFT 12
+#define EXOFS_BLKSIZE (1UL << EXOFS_BLKSHIFT)
+
+/****************************************************************************
+ * superblock-related things
+ ****************************************************************************/
+#define EXOFS_SUPER_MAGIC 0x5DF5
+
+/*
+ * The file system control block - stored in an object's data (mainly, the one
+ * with ID EXOFS_SUPER_ID). This is where the in-memory superblock is stored
+ * on disk. Right now it just has a magic value, which is basically a sanity
+ * check on our ability to communicate with the object store.
+ */
+struct exofs_fscb {
+ uint32_t s_nextid; /* Highest object ID used */
+ uint32_t s_numfiles; /* Number of files on fs */
+ uint16_t s_magic; /* Magic signature */
+ uint16_t s_newfs; /* Non-zero if this is a new fs */
+};
+
+/****************************************************************************
+ * inode-related things
+ ****************************************************************************/
+#define EXOFS_IDATA 5
+
+/*
+ * The file control block - stored in an object's attributes. This is where
+ * the in-memory inode is stored on disk.
+ */
+struct exofs_fcb {
+ uint64_t i_size; /* Size of the file */
+ uint16_t i_mode; /* File mode */
+ uint16_t i_links_count; /* Links count */
+ uint32_t i_uid; /* Owner Uid */
+ uint32_t i_gid; /* Group Id */
+ uint32_t i_atime; /* Access time */
+ uint32_t i_ctime; /* Creation time */
+ uint32_t i_mtime; /* Modification time */
+ uint32_t i_flags; /* File flags */
+ uint32_t i_version; /* File version */
+ uint32_t i_generation; /* File version (for NFS) */
+ uint32_t i_data[EXOFS_IDATA]; /* Short symlink names and device #s */
+};
+
+#define EXOFS_INO_ATTR_SIZE sizeof(struct exofs_fcb)
+
+/****************************************************************************
+ * dentry-related things
+ ****************************************************************************/
+#define EXOFS_NAME_LEN 255
+
+/*
+ * The on-disk directory entry
+ */
+struct exofs_dir_entry {
+ uint32_t inode; /* inode number */
+ uint16_t rec_len; /* directory entry length */
+ uint8_t name_len; /* name length */
+ uint8_t file_type; /* umm...file type */
+ char name[EXOFS_NAME_LEN]; /* file name */
+};
+
+enum {
+ EXOFS_FT_UNKNOWN,
+ EXOFS_FT_REG_FILE,
+ EXOFS_FT_DIR,
+ EXOFS_FT_CHRDEV,
+ EXOFS_FT_BLKDEV,
+ EXOFS_FT_FIFO,
+ EXOFS_FT_SOCK,
+ EXOFS_FT_SYMLINK,
+ EXOFS_FT_MAX
+};
+
+#define EXOFS_DIR_PAD 4
+#define EXOFS_DIR_ROUND (EXOFS_DIR_PAD - 1)
+#define EXOFS_DIR_REC_LEN(name_len) (((name_len) + 8 + EXOFS_DIR_ROUND) & \
+ ~EXOFS_DIR_ROUND)
+#endif
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h
new file mode 100644
index 0000000..8534450
--- /dev/null
+++ b/fs/exofs/exofs.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ *
+ * 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/fs.h>
+#include <linux/time.h>
+#include "common.h"
+
+#ifndef __EXOFS_H__
+#define __EXOFS_H__
+
+#define EXOFS_ERR(fmt, a...) printk(KERN_ERR "exofs: " fmt, ##a)
+
+#ifdef CONFIG_EXOFS_DEBUG
+#define EXOFS_DBGMSG(fmt, a...) \
+ printk(KERN_NOTICE "exofs @%s:%d: " fmt, __func__, __LINE__, ##a)
+#else
+#define EXOFS_DBGMSG(fmt, a...) \
+ do {} while (0)
+#endif
+
+/* u64 has problems with printk this will cast it to unsigned long long */
+#define _LLU(x) (unsigned long long)(x)
+
+/*
+ * our extension to the in-memory superblock
+ */
+struct exofs_sb_info {
+ struct osd_dev *s_dev; /* returned by get_osd_dev */
+ uint64_t s_pid; /* partition ID of file system*/
+ int s_timeout; /* timeout for OSD operations */
+ uint32_t s_nextid; /* highest object ID used */
+ uint32_t s_numfiles; /* number of files on fs */
+ spinlock_t s_next_gen_lock; /* spinlock for gen # update */
+ u32 s_next_generation; /* next gen # to use */
+ atomic_t s_curr_pending; /* number of pending commands */
+ uint8_t s_cred[OSD_CAP_LEN]; /* all-powerful credential */
+};
+
+/*
+ * our inode flags
+ */
+#ifdef ARCH_HAS_ATOMIC_UNSIGNED
+typedef unsigned exofs_iflags_t;
+#else
+typedef unsigned long exofs_iflags_t;
+#endif
+
+#define OBJ_2BCREATED 0 /* object will be created soon*/
+#define OBJ_CREATED 1 /* object has been created on the osd*/
+
+#define Obj2BCreated(oi) \
+ test_bit(OBJ_2BCREATED, &(oi->i_flags))
+#define SetObj2BCreated(oi) \
+ set_bit(OBJ_2BCREATED, &(oi->i_flags))
+
+#define ObjCreated(oi) \
+ test_bit(OBJ_CREATED, &(oi->i_flags))
+#define SetObjCreated(oi) \
+ set_bit(OBJ_CREATED, &(oi->i_flags))
+
+/*
+ * our extension to the in-memory inode
+ */
+struct exofs_i_info {
+ exofs_iflags_t i_flags; /* various atomic flags */
+ __le32 i_data[EXOFS_IDATA];/*short symlink names and device #s*/
+ uint32_t i_dir_start_lookup; /* which page to start lookup */
+ wait_queue_head_t i_wq; /* wait queue for inode */
+ uint64_t i_commit_size; /* the object's written length */
+ uint8_t i_cred[OSD_CAP_LEN];/* all-powerful credential */
+ struct inode vfs_inode; /* normal in-memory inode */
+};
+
+/*
+ * get to our inode from the vfs inode
+ */
+static inline struct exofs_i_info *EXOFS_I(struct inode *inode)
+{
+ return container_of(inode, struct exofs_i_info, vfs_inode);
+}
+
+/*************************
+ * function declarations *
+ *************************/
+/* osd.c */
+void make_credential(uint8_t[], uint64_t, uint64_t);
+int check_ok(struct osd_request *);
+int exofs_sync_op(struct osd_request *, int, uint8_t *);
+int exofs_async_op(struct osd_request *, osd_req_done_fn *, void *, char *);
+
+int prepare_get_attr_list_add_entry(struct osd_request *req,
+ uint32_t page_num,
+ uint32_t attr_num,
+ uint32_t attr_len);
+int prepare_set_attr_list_add_entry(struct osd_request *req,
+ uint32_t page_num,
+ uint32_t attr_num,
+ uint16_t attr_len,
+ const unsigned char *attr_val);
+int extract_next_attr_from_req(struct osd_request *req,
+ uint32_t *page_num, uint32_t *attr_num,
+ uint16_t *attr_len, uint8_t **attr_val);
+struct osd_request *prepare_osd_format_lun(struct osd_dev *dev,
+ uint64_t formatted_capacity);
+struct osd_request *prepare_osd_create_partition(struct osd_dev *dev,
+ uint64_t requested_id);
+struct osd_request *prepare_osd_remove_partition(struct osd_dev *dev,
+ uint64_t requested_id);
+struct osd_request *prepare_osd_create(struct osd_dev *dev,
+ uint64_t part_id,
+ uint64_t requested_id);
+struct osd_request *prepare_osd_remove(struct osd_dev *dev,
+ uint64_t part_id,
+ uint64_t obj_id);
+struct osd_request *prepare_osd_set_attr(struct osd_dev *dev,
+ uint64_t part_id,
+ uint64_t obj_id);
+struct osd_request *prepare_osd_get_attr(struct osd_dev *dev,
+ uint64_t part_id,
+ uint64_t obj_id);
+struct osd_request *prepare_osd_read(struct osd_dev *dev,
+ uint64_t part_id,
+ uint64_t obj_id,
+ uint64_t length,
+ uint64_t offset,
+ int cmd_data_use_sg,
+ unsigned char *cmd_data);
+struct osd_request *prepare_osd_write(struct osd_dev *dev,
+ uint64_t part_id,
+ uint64_t obj_id,
+ uint64_t length,
+ uint64_t offset,
+ int cmd_data_use_sg,
+ const unsigned char *cmd_data);
+struct osd_request *prepare_osd_list(struct osd_dev *dev,
+ uint64_t part_id,
+ uint32_t list_id,
+ uint64_t alloc_len,
+ uint64_t initial_obj_id,
+ int use_sg,
+ void *data);
+int extract_list_from_req(struct osd_request *req,
+ uint64_t *total_matches_p,
+ uint64_t *num_ids_retrieved_p,
+ uint64_t *list_of_ids_p[],
+ int *is_list_of_partitions_p,
+ int *list_isnt_up_to_date_p,
+ uint64_t *continuation_tag_p,
+ uint32_t *list_id_for_more_p);
+
+void free_osd_req(struct osd_request *req);
+
+#endif
diff --git a/fs/exofs/osd.c b/fs/exofs/osd.c
new file mode 100644
index 0000000..3859d3e
--- /dev/null
+++ b/fs/exofs/osd.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ *
+ * 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 <scsi/scsi_device.h>
+#include <scsi/osd_sense.h>
+
+#include "exofs.h"
+
+int check_ok(struct osd_request *req)
+{
+ struct osd_sense_info osi;
+ int ret = osd_req_decode_sense(req, &osi);
+
+ if (ret) { /* translate to Linux codes */
+ if (osi.additional_code == scsi_invalid_field_in_cdb) {
+ if (osi.cdb_field_offset == OSD_CFO_STARTING_BYTE)
+ ret = -EFAULT;
+ if (osi.cdb_field_offset == OSD_CFO_OBJECT_ID)
+ ret = -ENOENT;
+ else
+ ret = -EINVAL;
+ } else if (osi.additional_code == osd_quota_error)
+ ret = -ENOSPC;
+ else
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
+void make_credential(uint8_t cred_a[OSD_CAP_LEN], uint64_t pid, uint64_t oid)
+{
+ struct osd_obj_id obj = {
+ .partition = pid,
+ .id = oid
+ };
+
+ osd_sec_init_nosec_doall_caps(cred_a, &obj, false, true);
+}
+
+/*
+ * Perform a synchronous OSD operation.
+ */
+int exofs_sync_op(struct osd_request *req, int timeout, uint8_t *credential)
+{
+ int ret;
+
+ req->timeout = timeout;
+ ret = osd_finalize_request(req, 0, credential, NULL);
+ if (ret) {
+ EXOFS_DBGMSG("Faild to osd_finalize_request() => %d\n", ret);
+ return ret;
+ }
+
+ ret = osd_execute_request(req);
+
+ if (ret)
+ EXOFS_DBGMSG("osd_execute_request() => %d\n", ret);
+ /* osd_req_decode_sense(or, ret); */
+ return ret;
+}
+
+/*
+ * Perform an asynchronous OSD operation.
+ */
+int exofs_async_op(struct osd_request *req, osd_req_done_fn *async_done,
+ void *caller_context, char *credential)
+{
+ int ret;
+
+ ret = osd_finalize_request(req, 0, credential, NULL);
+ if (ret) {
+ EXOFS_DBGMSG("Faild to osd_finalize_request() => %d\n", ret);
+ return ret;
+ }
+
+ ret = osd_execute_request_async(req, async_done, caller_context);
+
+ if (ret)
+ EXOFS_DBGMSG("osd_execute_request_async() => %d\n", ret);
+ return ret;
+}
+
+int prepare_get_attr_list_add_entry(struct osd_request *req,
+ uint32_t page_num,
+ uint32_t attr_num,
+ uint32_t attr_len)
+{
+ struct osd_attr attr = {
+ .page = page_num,
+ .attr_id = attr_num,
+ .len = attr_len,
+ };
+
+ return osd_req_add_get_attr_list(req, &attr, 1);
+}
+
+int prepare_set_attr_list_add_entry(struct osd_request *req,
+ uint32_t page_num,
+ uint32_t attr_num,
+ uint16_t attr_len,
+ const unsigned char *attr_val)
+{
+ struct osd_attr attr = {
+ .page = page_num,
+ .attr_id = attr_num,
+ .len = attr_len,
+ .val_ptr = (u8 *)attr_val,
+ };
+
+ return osd_req_add_set_attr_list(req, &attr, 1);
+}
+
+int extract_next_attr_from_req(struct osd_request *req,
+ uint32_t *page_num, uint32_t *attr_num,
+ uint16_t *attr_len, uint8_t **attr_val)
+{
+ struct osd_attr attr = {.page = 0}; /* start with zeros */
+ void *iter = NULL;
+ int nelem;
+
+ do {
+ nelem = 1;
+ osd_req_decode_get_attr_list(req, &attr, &nelem, &iter);
+ if ((attr.page == *page_num) && (attr.attr_id == *attr_num)) {
+ *attr_len = attr.len;
+ *attr_val = attr.val_ptr;
+ return 0;
+ }
+ } while (iter);
+
+ return -EIO;
+}
+
+struct osd_request *prepare_osd_format_lun(struct osd_dev *dev,
+ uint64_t formatted_capacity)
+{
+ struct osd_request *or = osd_start_request(dev, GFP_KERNEL);
+
+ if (!or)
+ return NULL;
+
+ osd_req_format(or, formatted_capacity);
+
+ return or;
+}
+
+struct osd_request *prepare_osd_create_partition(struct osd_dev *dev,
+ uint64_t requested_id)
+{
+ struct osd_request *or = osd_start_request(dev, GFP_KERNEL);
+
+ if (!or)
+ return NULL;
+
+ osd_req_create_partition(or, requested_id);
+
+ return or;
+}
+
+struct osd_request *prepare_osd_remove_partition(struct osd_dev *dev,
+ uint64_t requested_id)
+{
+ struct osd_request *or = osd_start_request(dev, GFP_KERNEL);
+
+ if (!or)
+ return NULL;
+
+ osd_req_remove_partition(or, requested_id);
+
+ return or;
+}
+
+struct osd_request *prepare_osd_create(struct osd_dev *dev,
+ uint64_t part_id,
+ uint64_t requested_id)
+{
+ struct osd_obj_id obj = {
+ .partition = part_id,
+ .id = requested_id
+ };
+ struct osd_request *or = osd_start_request(dev, GFP_KERNEL);
+
+ if (!or)
+ return NULL;
+
+ osd_req_create_object(or, &obj);
+
+ return or;
+}
+
+struct osd_request *prepare_osd_remove(struct osd_dev *dev,
+ uint64_t part_id,
+ uint64_t obj_id)
+{
+ struct osd_obj_id obj = {
+ .partition = part_id,
+ .id = obj_id
+ };
+ struct osd_request *or = osd_start_request(dev, GFP_KERNEL);
+
+ if (!or)
+ return NULL;
+
+ osd_req_remove_object(or, &obj);
+
+ return or;
+}
+
+struct osd_request *prepare_osd_set_attr(struct osd_dev *dev,
+ uint64_t part_id,
+ uint64_t obj_id)
+{
+ struct osd_obj_id obj = {
+ .partition = part_id,
+ .id = obj_id
+ };
+ struct osd_request *or = osd_start_request(dev, GFP_KERNEL);
+
+ if (!or)
+ return NULL;
+
+ osd_req_set_attributes(or, &obj);
+
+ return or;
+}
+
+struct osd_request *prepare_osd_get_attr(struct osd_dev *dev,
+ uint64_t part_id,
+ uint64_t obj_id)
+{
+ struct osd_obj_id obj = {
+ .partition = part_id,
+ .id = obj_id
+ };
+ struct osd_request *or = osd_start_request(dev, GFP_KERNEL);
+
+ if (!or)
+ return NULL;
+
+ osd_req_get_attributes(or, &obj);
+
+ return or;
+}
+
+struct osd_request *prepare_osd_read(struct osd_dev *dev,
+ uint64_t part_id,
+ uint64_t obj_id,
+ uint64_t length,
+ uint64_t offset,
+ int cmd_data_use_sg,
+ unsigned char *cmd_data)
+{
+ struct osd_obj_id obj = {
+ .partition = part_id,
+ .id = obj_id
+ };
+ struct osd_request *or = osd_start_request(dev, GFP_KERNEL);
+ struct request_queue *req_q = dev->scsi_device->request_queue;
+ struct bio *bio;
+
+ if (!or)
+ return NULL;
+
+ BUG_ON(cmd_data_use_sg);
+ bio = bio_map_kern(req_q, cmd_data, length, or->alloc_flags);
+ if (!bio) {
+ osd_end_request(or);
+ return NULL;
+ }
+
+ osd_req_read(or, &obj, bio, offset);
+ EXOFS_DBGMSG("osd_req_read(p=%llX, ob=%llX, l=%llu, of=%llu)\n",
+ _LLU(part_id), _LLU(obj_id), _LLU(length), _LLU(offset));
+ return or;
+}
+
+struct osd_request *prepare_osd_write(struct osd_dev *dev,
+ uint64_t part_id,
+ uint64_t obj_id,
+ uint64_t length,
+ uint64_t offset,
+ int cmd_data_use_sg,
+ const unsigned char *cmd_data)
+{
+ struct osd_obj_id obj = {
+ .partition = part_id,
+ .id = obj_id
+ };
+ struct osd_request *or = osd_start_request(dev, GFP_KERNEL);
+ struct request_queue *req_q = dev->scsi_device->request_queue;
+ struct bio *bio;
+
+ if (!or)
+ return NULL;
+
+ BUG_ON(cmd_data_use_sg);
+ bio = bio_map_kern(req_q, (u8 *)cmd_data, length, or->alloc_flags);
+ if (!bio) {
+ osd_end_request(or);
+ return NULL;
+ }
+
+ osd_req_write(or, &obj, bio, offset);
+ EXOFS_DBGMSG("osd_req_write(p=%llX, ob=%llX, l=%llu, of=%llu)\n",
+ _LLU(part_id), _LLU(obj_id), _LLU(length), _LLU(offset));
+ return or;
+}
+
+void free_osd_req(struct osd_request *req)
+{
+ osd_end_request(req);
+}
--
1.6.0.1