* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2012, Whamcloud, Inc.
+ * Copyright (c) 2011, 2013, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#define IOC_MDC_MAX_NR 50
#include <lustre/lustre_idl.h>
+#include <lustre_lib.h>
+#include <libcfs/bitmap.h>
#ifdef HAVE_SERVER_SUPPORT
# include <lu_target.h>
+# include <obd_target.h>
#endif
#include <lu_ref.h>
-#include <lustre_lib.h>
#include <lustre_export.h>
+#include <lustre_fid.h>
#include <lustre_fld.h>
#include <lustre_capa.h>
-#include <libcfs/bitmap.h>
-
-
#define MAX_OBD_DEVICES 8192
struct osc_async_rc {
};
struct lov_oinfo { /* per-stripe data structure */
- struct ost_id loi_oi; /* object ID/Sequence on the target OST */
- int loi_ost_idx; /* OST stripe index in lov_tgt_desc->tgts */
- int loi_ost_gen; /* generation of this loi_ost_idx */
-
- unsigned long loi_kms_valid:1;
- __u64 loi_kms; /* known minimum size */
- struct ost_lvb loi_lvb;
- struct osc_async_rc loi_ar;
+ struct ost_id loi_oi; /* object ID/Sequence on the target OST */
+ int loi_ost_idx; /* OST stripe index in lov_tgt_desc->tgts */
+ int loi_ost_gen; /* generation of this loi_ost_idx */
+
+ unsigned long loi_kms_valid:1;
+ __u64 loi_kms; /* known minimum size */
+ struct ost_lvb loi_lvb;
+ struct osc_async_rc loi_ar;
};
-#define loi_id loi_oi.oi_id
-#define loi_seq loi_oi.oi_seq
static inline void loi_kms_set(struct lov_oinfo *oinfo, __u64 kms)
{
__u64 lsm_maxbytes;
struct {
/* Public members. */
- __u64 lw_object_id; /* lov object id */
- __u64 lw_object_seq; /* lov object seq */
+ struct ost_id lw_object_oi; /* lov object id/seq */
/* LOV-private members start here -- only for use in lov/. */
__u32 lw_magic;
struct lov_oinfo *lsm_oinfo[0];
};
-#define lsm_object_id lsm_wire.lw_object_id
-#define lsm_object_seq lsm_wire.lw_object_seq
+#define lsm_oi lsm_wire.lw_object_oi
#define lsm_magic lsm_wire.lw_magic
#define lsm_layout_gen lsm_wire.lw_layout_gen
#define lsm_stripe_size lsm_wire.lw_stripe_size
#define lsm_stripe_count lsm_wire.lw_stripe_count
#define lsm_pool_name lsm_wire.lw_pool_name
+static inline bool lsm_is_released(struct lov_stripe_md *lsm)
+{
+ return !!(lsm->lsm_pattern & LOV_PATTERN_F_RELEASED);
+}
+
+static inline bool lsm_has_objects(struct lov_stripe_md *lsm)
+{
+ if (lsm == NULL)
+ return false;
+ if (lsm_is_released(lsm))
+ return false;
+ return true;
+}
+
struct obd_info;
typedef int (*obd_enqueue_update_f)(void *cookie, int rc);
}
static inline int lov_lum_swab_if_needed(struct lov_user_md_v3 *lumv3,
- int *lmm_magic,
- struct lov_user_md *lum)
+ int *lmm_magic,
+ struct lov_user_md *lum)
{
- if (lum && cfs_copy_from_user(lumv3, lum,sizeof(struct lov_user_md_v1)))
- return -EFAULT;
-
- *lmm_magic = lumv3->lmm_magic;
-
- if (*lmm_magic == __swab32(LOV_USER_MAGIC_V1)) {
- lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lumv3);
- *lmm_magic = LOV_USER_MAGIC_V1;
- } else if (*lmm_magic == LOV_USER_MAGIC_V3) {
- if (lum && cfs_copy_from_user(lumv3, lum, sizeof(*lumv3)))
- return -EFAULT;
- } else if (*lmm_magic == __swab32(LOV_USER_MAGIC_V3)) {
- if (lum && cfs_copy_from_user(lumv3, lum, sizeof(*lumv3)))
- return -EFAULT;
- lustre_swab_lov_user_md_v3(lumv3);
- *lmm_magic = LOV_USER_MAGIC_V3;
- } else if (*lmm_magic != LOV_USER_MAGIC_V1) {
- CDEBUG(D_IOCTL,
- "bad userland LOV MAGIC: %#08x != %#08x nor %#08x\n",
- *lmm_magic, LOV_USER_MAGIC_V1, LOV_USER_MAGIC_V3);
- return -EINVAL;
- }
- return 0;
+ if (lum && copy_from_user(lumv3, lum, sizeof(struct lov_user_md_v1)))
+ return -EFAULT;
+
+ *lmm_magic = lumv3->lmm_magic;
+
+ if (*lmm_magic == __swab32(LOV_USER_MAGIC_V1)) {
+ lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lumv3);
+ *lmm_magic = LOV_USER_MAGIC_V1;
+ } else if (*lmm_magic == LOV_USER_MAGIC_V3) {
+ if (lum && copy_from_user(lumv3, lum, sizeof(*lumv3)))
+ return -EFAULT;
+ } else if (*lmm_magic == __swab32(LOV_USER_MAGIC_V3)) {
+ if (lum && copy_from_user(lumv3, lum, sizeof(*lumv3)))
+ return -EFAULT;
+ lustre_swab_lov_user_md_v3(lumv3);
+ *lmm_magic = LOV_USER_MAGIC_V3;
+ } else if (*lmm_magic != LOV_USER_MAGIC_V1) {
+ CDEBUG(D_IOCTL,
+ "bad userland LOV MAGIC: %#08x != %#08x nor %#08x\n",
+ *lmm_magic, LOV_USER_MAGIC_V1, LOV_USER_MAGIC_V3);
+ return -EINVAL;
+ }
+ return 0;
}
void lov_stripe_lock(struct lov_stripe_md *md);
};
struct brw_page {
- obd_off off;
- cfs_page_t *pg;
- int count;
- obd_flag flag;
-};
-
-/* Individual type definitions */
-
-struct ost_server_data;
-
-struct osd_properties {
- size_t osd_max_ea_size;
-};
-
-#define OBT_MAGIC 0xBDDECEAE
-/* hold common fields for "target" device */
-struct obd_device_target {
- __u32 obt_magic;
- __u32 obt_instance;
- struct super_block *obt_sb;
- /** last_rcvd file */
- struct file *obt_rcvd_filp;
-#ifdef HAVE_SERVER_SUPPORT
- struct lu_target *obt_lut;
-#endif
- __u64 obt_mount_count;
- struct rw_semaphore obt_rwsem;
- struct vfsmount *obt_vfsmnt;
- struct file *obt_health_check_filp;
- struct osd_properties obt_osd_properties;
- struct obd_job_stats obt_jobstats;
+ obd_off off;
+ struct page *pg;
+ int count;
+ obd_flag flag;
};
/* llog contexts */
LLOG_MAX_CTXTS
};
-#define FILTER_SUBDIR_COUNT 32 /* set to zero for no subdirs */
-
-struct filter_subdirs {
- cfs_dentry_t *dentry[FILTER_SUBDIR_COUNT];
-};
-
-
-struct filter_ext {
- __u64 fe_start;
- __u64 fe_end;
-};
-
-struct filter_obd {
- /* NB this field MUST be first */
- struct obd_device_target fo_obt;
- const char *fo_fstype;
-
- int fo_group_count;
- cfs_dentry_t *fo_dentry_O;
- cfs_dentry_t **fo_dentry_O_groups;
- struct filter_subdirs *fo_dentry_O_sub;
- struct mutex fo_init_lock; /* group initialization lock*/
- int fo_committed_group;
-
- spinlock_t fo_objidlock; /* protect fo_lastobjid */
-
- unsigned long fo_destroys_in_progress;
- struct mutex fo_create_locks[FILTER_SUBDIR_COUNT];
-
- cfs_list_t fo_export_list;
- int fo_subdir_count;
-
- obd_size fo_tot_dirty; /* protected by obd_osfs_lock */
- obd_size fo_tot_granted; /* all values in bytes */
- obd_size fo_tot_pending;
- int fo_tot_granted_clients;
-
- obd_size fo_readcache_max_filesize;
- spinlock_t fo_flags_lock;
- unsigned int fo_read_cache:1, /**< enable read-only cache */
- fo_writethrough_cache:1,/**< read cache writes */
- fo_mds_ost_sync:1, /**< MDS-OST orphan recovery*/
- fo_raid_degraded:1;/**< RAID device degraded */
-
- struct obd_import *fo_mdc_imp;
- struct obd_uuid fo_mdc_uuid;
- struct lustre_handle fo_mdc_conn;
- struct file **fo_last_objid_files;
- __u64 *fo_last_objids; /* last created objid for groups,
- * protected by fo_objidlock */
-
- struct mutex fo_alloc_lock;
-
- cfs_atomic_t fo_r_in_flight;
- cfs_atomic_t fo_w_in_flight;
-
- /*
- * per-filter pool of kiobuf's allocated by filter_common_setup() and
- * torn down by filter_cleanup().
- *
- * This pool contains kiobuf used by
- * filter_{prep,commit}rw_{read,write}() and is shared by all OST
- * threads.
- *
- * Locking: protected by internal lock of cfs_hash, pool can be
- * found from this hash table by t_id of ptlrpc_thread.
- */
- struct cfs_hash *fo_iobuf_hash;
-
- cfs_list_t fo_llog_list;
- spinlock_t fo_llog_list_lock;
-
- struct brw_stats fo_filter_stats;
-
- int fo_fmd_max_num; /* per exp filter_mod_data */
- int fo_fmd_max_age; /* jiffies to fmd expiry */
- unsigned long fo_syncjournal:1, /* sync journal on writes */
- fo_sync_lock_cancel:2;/* sync on lock cancel */
-
-
- /* sptlrpc stuff */
- rwlock_t fo_sptlrpc_lock;
- struct sptlrpc_rule_set fo_sptlrpc_rset;
-
- /* capability related */
- unsigned int fo_fl_oss_capa;
- cfs_list_t fo_capa_keys;
- cfs_hlist_head_t *fo_capa_hash;
- struct llog_commit_master *fo_lcm;
- int fo_sec_level;
-};
-
struct timeout_item {
enum timeout_event ti_event;
cfs_time_t ti_timeout;
enum lustre_sec_part cl_sp_to;
struct sptlrpc_flavor cl_flvr_mgc; /* fixed flavor of mgc->mgs */
- //struct llog_canceld_ctxt *cl_llcd; /* it's included by obd_llog_ctxt */
- void *cl_llcd_offset;
-
/* the grant values are protected by loi_list_lock below */
long cl_dirty; /* all _dirty_ in bytes */
long cl_dirty_max; /* allowed w/o rpc */
int cl_grant_shrink_interval; /* seconds */
/* A chunk is an optimal size used by osc_extent to determine
- * the extent size. A chunk is max(CFS_PAGE_SIZE, OST block size) */
+ * the extent size. A chunk is max(PAGE_CACHE_SIZE, OST block size) */
int cl_chunkbits;
int cl_chunk;
int cl_extent_tax; /* extent overhead, by bytes */
/* just a sum of the loi/lop pending numbers to be exported by /proc */
cfs_atomic_t cl_pending_w_pages;
cfs_atomic_t cl_pending_r_pages;
- int cl_max_pages_per_rpc;
+ __u32 cl_max_pages_per_rpc;
int cl_max_rpcs_in_flight;
struct obd_histogram cl_read_rpc_hist;
struct obd_histogram cl_write_rpc_hist;
obd_id *data;
};
-/* */
-
-struct echo_obd {
- struct obd_device_target eo_obt;
- struct obdo eo_oa;
- spinlock_t eo_lock;
- __u64 eo_lastino;
- struct lustre_handle eo_nl_lock;
- cfs_atomic_t eo_prep;
-};
-
-struct ost_obd {
- struct ptlrpc_service *ost_service;
- struct ptlrpc_service *ost_create_service;
- struct ptlrpc_service *ost_io_service;
- struct mutex ost_health_mutex;
-};
-
struct echo_client_obd {
struct obd_export *ec_exp; /* the local connection to osc/lov */
spinlock_t ec_lock;
/* Cached LRU pages from upper layer */
void *lov_cache;
+
+ struct rw_semaphore lov_notify_lock;
};
struct lmv_tgt_desc {
- struct obd_uuid ltd_uuid;
- struct obd_export *ltd_exp;
- int ltd_active; /* is this target up for requests */
- int ltd_idx;
+ struct obd_uuid ltd_uuid;
+ struct obd_export *ltd_exp;
+ int ltd_idx;
struct mutex ltd_fid_mutex;
+ unsigned long ltd_active:1; /* target up for requests */
};
enum placement_policy {
int refcount;
struct lu_client_fld lmv_fld;
spinlock_t lmv_lock;
- placement_policy_t lmv_placement;
- struct lmv_desc desc;
- struct obd_uuid cluuid;
- struct obd_export *exp;
-
- int connected;
- int max_easize;
- int max_def_easize;
- int max_cookiesize;
- int server_timeout;
- struct mutex init_mutex;
+ placement_policy_t lmv_placement;
+ struct lmv_desc desc;
+ struct obd_uuid cluuid;
+ struct obd_export *exp;
- struct lmv_tgt_desc *tgts;
- int tgts_size;
+ struct mutex init_mutex;
+ int connected;
+ int max_easize;
+ int max_def_easize;
+ int max_cookiesize;
+ int server_timeout;
- struct obd_connect_data *datas;
- int datas_size;
+ int tgts_size; /* size of tgts array */
+ struct lmv_tgt_desc **tgts;
- struct obd_connect_data conn_data;
+ struct obd_connect_data conn_data;
};
struct niobuf_local {
- __u64 lnb_file_offset;
- __u32 lnb_page_offset;
- __u32 len;
- __u32 flags;
- cfs_page_t *page;
- cfs_dentry_t *dentry;
- int lnb_grant_used;
- int rc;
+ __u64 lnb_file_offset;
+ __u32 lnb_page_offset;
+ __u32 len;
+ __u32 flags;
+ struct page *page;
+ struct dentry *dentry;
+ int lnb_grant_used;
+ int rc;
};
#define LUSTRE_FLD_NAME "fld"
#define LUSTRE_SEQ_NAME "seq"
-#define LUSTRE_CMM_NAME "cmm"
#define LUSTRE_MDD_NAME "mdd"
#define LUSTRE_OSD_LDISKFS_NAME "osd-ldiskfs"
#define LUSTRE_OSD_ZFS_NAME "osd-zfs"
#define LUSTRE_VVP_NAME "vvp"
#define LUSTRE_LMV_NAME "lmv"
-#define LUSTRE_CMM_MDC_NAME "cmm-mdc"
#define LUSTRE_SLP_NAME "slp"
#define LUSTRE_LOD_NAME "lod"
#define LUSTRE_OSP_NAME "osp"
+#define LUSTRE_LWP_NAME "lwp"
/* obd device type names */
/* FIXME all the references to LUSTRE_MDS_NAME should be swapped with LUSTRE_MDT_NAME */
#define LUSTRE_MGS_NAME "mgs"
#define LUSTRE_MGC_NAME "mgc"
-#define LUSTRE_CACHEOBD_NAME "cobd"
#define LUSTRE_ECHO_NAME "obdecho"
#define LUSTRE_ECHO_CLIENT_NAME "echo_client"
#define LUSTRE_QMT_NAME "qmt"
#define LUSTRE_MGS_OBDNAME "MGS"
#define LUSTRE_MGC_OBDNAME "MGC"
-/* Don't conflict with on-wire flags OBD_BRW_WRITE, etc */
-#define N_LOCAL_TEMP_PAGE 0x10000000
-
-static inline int is_osp_on_ost(char *name)
+static inline int is_osp_on_mdt(char *name)
{
char *ptr;
return 0;
}
- if (strncmp(ptr + 1, "OST", 3) != 0 && strncmp(ptr + 1, "MDT", 3) != 0)
- return 0;
+ /* 1.8 OSC/OSP name on MDT is fsname-OSTxxxx-osc */
+ if (strncmp(ptr + 1, "osc", 3) == 0)
+ return 1;
- /* match the "-osp" */
- if (ptr - name < strlen(LUSTRE_OSP_NAME) + 1)
+ if (strncmp(ptr + 1, "MDT", 3) != 0)
return 0;
- ptr -= (strlen(LUSTRE_OSP_NAME) + 1);
- if (*ptr != '-')
+ while (*(--ptr) != '-' && ptr != name);
+
+ if (ptr == name)
return 0;
- if (strncmp(ptr + 1, LUSTRE_OSP_NAME, strlen(LUSTRE_OSP_NAME)) != 0)
+ if (strncmp(ptr + 1, LUSTRE_OSP_NAME, strlen(LUSTRE_OSP_NAME)) != 0 &&
+ strncmp(ptr + 1, LUSTRE_OSC_NAME, strlen(LUSTRE_OSC_NAME)) != 0)
return 0;
return 1;
}
+/* Don't conflict with on-wire flags OBD_BRW_WRITE, etc */
+#define N_LOCAL_TEMP_PAGE 0x10000000
+
struct obd_trans_info {
__u64 oti_transno;
__u64 oti_xid;
struct llog_cookie *oti_logcookies;
int oti_numcookies;
/** synchronous write is needed */
- long oti_sync_write:1;
+ unsigned long oti_sync_write:1;
/* initial thread handling transaction */
struct ptlrpc_thread * oti_thread;
struct completion trd_finishing;
};
-/**
- * In HEAD for CMD, the object is created in group number which is 3>=
- * or indexing starts from 3. To test this assertions are added to disallow
- * group 0. But to run 2.0 mds server on 1.8.x disk format (i.e. interop_mode)
- * object in group 0 needs to be allowed.
- * So for interop mode following changes needs to be done:
- * 1. No need to assert on group 0 or allow group 0
- * 2. The group number indexing starts from 0 instead of 3
- */
-
-#define LASSERT_SEQ_IS_MDT(seq) LASSERT(fid_seq_is_mdt(seq))
-
-static inline __u64 objseq_to_mdsno(obd_seq seq)
-{
- LASSERT_SEQ_IS_MDT(seq);
- if (seq == FID_SEQ_OST_MDT0)
- return 0;
- return seq - FID_SEQ_OST_MDT1 + 1;
-}
-
-static inline int mdt_to_obd_objseq(int mdtid)
-{
- /**
- * MDS0 uses seq 0 pre FID-on-OST, other MDSes will use seq from
- * FID_SEQ_OST_MDT1
- */
- if (mdtid)
- return FID_SEQ_OST_MDT1 + mdtid - 1;
- return 0;
-}
-
struct obd_llog_group {
- cfs_list_t olg_list;
int olg_seq;
struct llog_ctxt *olg_ctxts[LLOG_MAX_CTXTS];
cfs_waitq_t olg_waitq;
spinlock_t olg_lock;
- struct obd_export *olg_exp;
- int olg_initializing;
struct mutex olg_cat_processing;
};
cfs_list_t obd_final_req_queue;
int obd_recovery_stage;
- union {
- struct obd_device_target obt;
- struct filter_obd filter;
- struct client_obd cli;
- struct ost_obd ost;
- struct echo_client_obd echo_client;
- struct echo_obd echo;
- struct lov_obd lov;
- struct lmv_obd lmv;
- } u;
- /* Fields used by LProcFS */
- unsigned int obd_cntr_base;
- struct lprocfs_stats *obd_stats;
+ union {
+#ifdef HAVE_SERVER_SUPPORT
+ struct obd_device_target obt;
+ struct filter_obd filter;
+ struct ost_obd ost;
+ struct echo_obd echo;
+#endif
+ struct client_obd cli;
+ struct echo_client_obd echo_client;
+ struct lov_obd lov;
+ struct lmv_obd lmv;
+ } u;
+ /* Fields used by LProcFS */
+ unsigned int obd_cntr_base;
+ struct lprocfs_stats *obd_stats;
unsigned int md_cntr_base;
struct lprocfs_stats *md_stats;
#define KEY_INIT_RECOV "initial_recov"
#define KEY_INTERMDS "inter_mds"
#define KEY_LAST_ID "last_id"
+#define KEY_LAST_FID "last_fid"
#define KEY_LOCK_TO_STRIPE "lock_to_stripe"
#define KEY_LOVDESC "lovdesc"
#define KEY_LOV_IDX "lov_idx"
#define KEY_CACHE_SET "cache_set"
#define KEY_CACHE_LRU_SHRINK "cache_lru_shrink"
+#define KEY_CHANGELOG_INDEX "changelog_index"
struct lu_context;
/* Size-on-MDS epoch and flags. */
__u64 op_ioepoch;
- __u32 op_flags;
+ __u32 op_flags;
/* Capa fields */
struct obd_capa *op_capa1;
struct obd_capa *op_capa2;
/* Various operation flags. */
- __u32 op_bias;
+ __u32 op_bias;
/* Operation type */
- __u32 op_opc;
+ __u32 op_opc;
/* Used by readdir */
- __u32 op_npages;
- __u64 op_offset;
+ __u64 op_offset;
+
+ /* Used by readdir */
+ __u32 op_npages;
+
+ /* used to transfer info between the stacks of MD client
+ * see enum op_cli_flags */
+ __u32 op_cli_flags;
+};
+
+enum op_cli_flags {
+ CLI_SET_MEA = 1 << 0,
+ CLI_RM_ENTRY = 1 << 1,
};
struct md_enqueue_info;
void *localdata);
int (*o_disconnect)(struct obd_export *exp);
- /* Initialize/finalize fids infrastructure. */
- int (*o_fid_init)(struct obd_export *exp);
- int (*o_fid_fini)(struct obd_export *exp);
+ /* Initialize/finalize fids infrastructure. */
+ int (*o_fid_init)(struct obd_device *obd,
+ struct obd_export *exp, enum lu_cli_type type);
+ int (*o_fid_fini)(struct obd_device *obd);
/* Allocate new fid according to passed @hint. */
int (*o_fid_alloc)(struct obd_export *exp, struct lu_fid *fid,
struct md_ops {
int (*m_getstatus)(struct obd_export *, struct lu_fid *,
struct obd_capa **);
- int (*m_change_cbdata)(struct obd_export *, const struct lu_fid *,
- ldlm_iterator_t, void *);
+ int (*m_null_inode)(struct obd_export *, const struct lu_fid *);
int (*m_find_cbdata)(struct obd_export *, const struct lu_fid *,
ldlm_iterator_t, void *);
int (*m_close)(struct obd_export *, struct md_op_data *,
}
}
-int lvfs_check_io_health(struct obd_device *obd, struct file *file);
-
/* Requests for obd_extent_calc() */
#define OBD_CALC_STRIPE_START 1
#define OBD_CALC_STRIPE_END 2
}
#define obd_mod_get(mod) cfs_atomic_inc(&(mod)->mod_refcount)
-#define obd_mod_put(mod) \
-({ \
- if (cfs_atomic_dec_and_test(&(mod)->mod_refcount)) { \
- if ((mod)->mod_open_req) \
- ptlrpc_req_finished((mod)->mod_open_req); \
- OBD_FREE_PTR(mod); \
- } \
+#define obd_mod_put(mod) \
+({ \
+ if (cfs_atomic_dec_and_test(&(mod)->mod_refcount)) { \
+ if ((mod)->mod_open_req) \
+ ptlrpc_req_finished((mod)->mod_open_req); \
+ OBD_FREE_PTR(mod); \
+ } \
})
void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid);
return lu_dev->ld_obd->obd_name;
}
+static inline bool filename_is_volatile(const char *name, int namelen, int *idx)
+{
+ const char *start;
+ char *end;
+
+ if (strncmp(name, LUSTRE_VOLATILE_HDR, LUSTRE_VOLATILE_HDR_LEN) != 0)
+ return false;
+
+ /* caller does not care of idx */
+ if (idx == NULL)
+ return true;
+
+ /* volatile file, the MDT can be set from name */
+ /* name format is LUSTRE_VOLATILE_HDR:[idx]: */
+ /* if no MDT is specified, use std way */
+ if (namelen < LUSTRE_VOLATILE_HDR_LEN + 2)
+ goto bad_format;
+ /* test for no MDT idx case */
+ if ((*(name + LUSTRE_VOLATILE_HDR_LEN) == ':') &&
+ (*(name + LUSTRE_VOLATILE_HDR_LEN + 1) == ':')) {
+ *idx = -1;
+ return true;
+ }
+ /* we have an idx, read it */
+ start = name + LUSTRE_VOLATILE_HDR_LEN + 1;
+ *idx = strtoul(start, &end, 0);
+ /* error cases:
+ * no digit, no trailing :, negative value
+ */
+ if (((*idx == 0) && (end == start)) ||
+ (*end != ':') || (*idx < 0))
+ goto bad_format;
+
+ return true;
+bad_format:
+ /* bad format of mdt idx, we cannot return an error
+ * to caller so we use hash algo */
+ CERROR("Bad volatile file name format: %s\n",
+ name + LUSTRE_VOLATILE_HDR_LEN);
+ return false;
+}
+
+static inline int cli_brw_size(struct obd_device *obd)
+{
+ LASSERT(obd != NULL);
+ return obd->u.cli.cl_max_pages_per_rpc << PAGE_CACHE_SHIFT;
+}
+
#endif /* __OBD_H */