*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
*
* GPL HEADER END
*/
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2015, Intel Corporation.
+ * Copyright (c) 2011, 2017, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#ifndef __OBD_H
#define __OBD_H
+#include <linux/kobject.h>
#include <linux/spinlock.h>
+#include <linux/sysfs.h>
-#include <lustre/lustre_idl.h>
+#include <uapi/linux/lustre/lustre_idl.h>
#include <lustre_lib.h>
#include <libcfs/bitmap.h>
#ifdef HAVE_SERVER_SUPPORT
oinfo->loi_kms_valid = 1;
}
-static inline void loi_init(struct lov_oinfo *loi)
-{
-}
-
struct lov_stripe_md;
struct obd_info;
struct md_ops *typ_md_ops;
struct proc_dir_entry *typ_procroot;
struct proc_dir_entry *typ_procsym;
- __u32 typ_sym_filter;
+ struct dentry *typ_debugfs_entry;
+#ifdef HAVE_SERVER_SUPPORT
+ bool typ_sym_filter;
+#endif
char *typ_name;
int typ_refcnt;
struct lu_device_type *typ_lu;
spinlock_t obd_type_lock;
+ struct kobject *typ_kobj;
};
struct brw_page {
struct timeout_item {
enum timeout_event ti_event;
- cfs_time_t ti_timeout;
+ time64_t ti_timeout;
timeout_cb_t ti_cb;
void *ti_cb_data;
struct list_head ti_obd_list;
#define OBD_MAX_RIF_DEFAULT 8
#define OBD_MAX_RIF_MAX 512
#define OSC_MAX_RIF_MAX 256
-#define OSC_MAX_DIRTY_DEFAULT (OBD_MAX_RIF_DEFAULT * 4)
+#define OSC_MAX_DIRTY_DEFAULT 2000 /* Arbitrary large value */
#define OSC_MAX_DIRTY_MB_MAX 2048 /* arbitrary, but < MAX_LONG bytes */
#define OSC_DEFAULT_RESENDS 10
* run-time if a larger observed size is advertised by the MDT. */
__u32 cl_max_mds_easize;
+ /* Data-on-MDT specific value to set larger reply buffer for possible
+ * data read along with open/stat requests. By default it tries to use
+ * unused space in reply buffer.
+ * This value is used to ensure that reply buffer has at least as
+ * much free space as value indicates. That free space is gained from
+ * LOV EA buffer which is small for DoM files and on big systems can
+ * provide up to 32KB of extra space in reply buffer.
+ * Default value is 8K now.
+ */
+ __u32 cl_dom_min_inline_repsize;
+
enum lustre_sec_part cl_sp_me;
enum lustre_sec_part cl_sp_to;
struct sptlrpc_flavor cl_flvr_mgc; /* fixed flavor of mgc->mgs */
* See osc_{reserve|unreserve}_grant for details. */
long cl_reserved_grant;
struct list_head cl_cache_waiters; /* waiting for cache/grant */
- cfs_time_t cl_next_shrink_grant; /* jiffies */
- struct list_head cl_grant_shrink_list; /* Timeout event list */
- int cl_grant_shrink_interval; /* seconds */
+ time64_t cl_next_shrink_grant; /* seconds */
+ struct list_head cl_grant_chain;
+ time64_t cl_grant_shrink_interval; /* seconds */
/* A chunk is an optimal size used by osc_extent to determine
- * the extent size. A chunk is max(PAGE_CACHE_SIZE, OST block size) */
+ * the extent size. A chunk is max(PAGE_SIZE, OST block size) */
int cl_chunkbits;
/* extent insertion metadata overhead to be accounted in grant,
* in bytes */
atomic_t cl_pending_r_pages;
__u32 cl_max_pages_per_rpc;
__u32 cl_max_rpcs_in_flight;
+ __u32 cl_short_io_bytes;
struct obd_histogram cl_read_rpc_hist;
struct obd_histogram cl_write_rpc_hist;
struct obd_histogram cl_read_page_hist;
* allowed to have multiple threads shrinking LRU cache. */
atomic_t cl_lru_shrinkers;
/** The time when this LRU cache was last used. */
- time_t cl_lru_last_used;
+ time64_t cl_lru_last_used;
/** stats: how many reclaims have happened for this client_obd.
* reclaim and shrink - shrink is async, voluntarily rebalancing;
* reclaim is sync, initiated by IO thread when the LRU slots are
struct mutex cl_mgc_mutex;
struct local_oid_storage *cl_mgc_los;
struct dt_object *cl_mgc_configs_dir;
- atomic_t cl_mgc_refcount;
struct obd_export *cl_mgc_mgsexp;
+ atomic_t cl_mgc_refcount;
+ /* in-flight control list and total RPCs counter */
+ struct list_head cl_flight_waiters;
+ __u32 cl_rpcs_in_flight;
/* checksumming for data sent over the network */
- unsigned int cl_checksum:1; /* 0 = disabled, 1 = enabled */
+ unsigned int cl_checksum:1, /* 0 = disabled, 1 = enabled */
+ cl_checksum_dump:1; /* same */
/* supported checksum types that are worked out at connect time */
__u32 cl_supp_cksum_types;
/* checksum algorithm to be used */
- cksum_type_t cl_cksum_type;
+ enum cksum_types cl_cksum_type;
/* also protected by the poorly named _loi_list_lock lock above */
struct osc_async_rc cl_ar;
/* sequence manager */
struct lu_client_seq *cl_seq;
+ struct rw_semaphore cl_seq_rwsem;
- atomic_t cl_resends; /* resend count */
+ atomic_t cl_resends; /* resend count */
/* ptlrpc work for writeback in ptlrpcd context */
void *cl_writeback_work;
void *cl_lru_work;
/* hash tables for osc_quota_info */
struct cfs_hash *cl_quota_hash[LL_MAXQUOTAS];
+ /* Links to the global list of registered changelog devices */
+ struct list_head cl_chg_dev_linkage;
};
#define obd2cli_tgt(obd) ((char *)(obd)->u.cli.cl_target_uuid.uuid)
ltd_reap:1; /* should this target be deleted */
};
+struct lov_md_tgt_desc {
+ struct obd_device *lmtd_mdc;
+ __u32 lmtd_index;
+};
+
struct lov_obd {
struct lov_desc desc;
struct lov_tgt_desc **lov_tgts; /* sparse array */
struct cl_client_cache *lov_cache;
struct rw_semaphore lov_notify_lock;
+ /* Data-on-MDT: MDC array */
+ struct lov_md_tgt_desc *lov_mdc_tgts;
+
+ struct kobject *lov_tgts_kobj;
};
struct lmv_tgt_desc {
struct obd_uuid ltd_uuid;
+ struct obd_device *ltd_obd;
struct obd_export *ltd_exp;
__u32 ltd_idx;
struct mutex ltd_fid_mutex;
unsigned long ltd_active:1; /* target up for requests */
};
-enum placement_policy {
- PLACEMENT_CHAR_POLICY = 0,
- PLACEMENT_NID_POLICY = 1,
- PLACEMENT_INVAL_POLICY = 2,
- PLACEMENT_MAX_POLICY
-};
-
-typedef enum placement_policy placement_policy_t;
-
struct lmv_obd {
- 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;
- struct proc_dir_entry *targets_proc_entry;
struct mutex lmv_init_mutex;
int connected;
struct lmv_tgt_desc **tgts;
struct obd_connect_data conn_data;
+ struct kobject *lmv_tgts_kobj;
};
struct niobuf_local {
void *lnb_data;
};
+struct tgt_thread_big_cache {
+ struct niobuf_local local[PTLRPC_MAX_BRW_PAGES];
+};
+
#define LUSTRE_FLD_NAME "fld"
#define LUSTRE_SEQ_NAME "seq"
* Events signalled through obd_notify() upcall-chain.
*/
enum obd_notify_event {
- /* target added */
- OBD_NOTIFY_CREATE,
/* Device connect start */
OBD_NOTIFY_CONNECT,
/* Device activated */
OBD_NOTIFY_ACTIVE,
/* Device deactivated */
OBD_NOTIFY_INACTIVE,
- /* Device disconnected */
- OBD_NOTIFY_DISCON,
/* Connect data for import were changed */
OBD_NOTIFY_OCD,
- /* Sync request */
- OBD_NOTIFY_SYNC_NONBLOCK,
- OBD_NOTIFY_SYNC,
- /* Configuration event */
- OBD_NOTIFY_CONFIG,
/* Administratively deactivate/activate event */
OBD_NOTIFY_DEACTIVATE,
OBD_NOTIFY_ACTIVATE
};
-/* bit-mask flags for config events */
-enum config_flags {
- CONFIG_LOG = 0x1, /* finished processing config log */
- CONFIG_SYNC = 0x2, /* mdt synced 1 ost */
- CONFIG_TARGET = 0x4 /* one target is added */
-};
-
/*
* Data structure used to pass obd_notify()-event to non-obd listeners (llite
- * and liblustre being main examples).
+ * being main example).
*/
struct obd_notify_upcall {
- int (*onu_upcall)(struct obd_device *host, struct obd_device *watched,
- enum obd_notify_event ev, void *owner, void *data);
+ int (*onu_upcall)(struct obd_device *host, struct obd_device *watched,
+ enum obd_notify_event ev, void *owner);
/* Opaque datum supplied by upper layer listener */
void *onu_owner;
};
* (for /proc/status only!!) */
obd_no_ir:1, /* no imperative recovery. */
obd_process_conf:1, /* device is processing mgs config */
- obd_uses_nid_stats:1; /* maintain per-client OBD stats */
+ obd_checksum_dump:1; /* dump pages upon cksum error */
/* use separate field as it is set in interrupt to don't mess with
* protection of other bits using _bh lock */
spinlock_t obd_dev_lock; /* protect OBD bitfield above */
spinlock_t obd_osfs_lock;
struct obd_statfs obd_osfs; /* locked by obd_osfs_lock */
- __u64 obd_osfs_age;
+ time64_t obd_osfs_age;
__u64 obd_last_committed;
struct mutex obd_dev_mutex;
struct lvfs_run_ctxt obd_lvfs_ctxt;
struct obd_export *obd_lwp_export;
/* list of exports in LRU order, for ping evictor, with obd_dev_lock */
struct list_head obd_exports_timed;
- time_t obd_eviction_timer; /* for ping evictor */
+ time64_t obd_eviction_timer; /* for ping evictor */
int obd_max_recoverable_clients;
atomic_t obd_connected_clients;
/* protected by obd_recovery_task_lock */
struct timer_list obd_recovery_timer;
/* seconds */
- time_t obd_recovery_start;
+ time64_t obd_recovery_start;
/* seconds, for lprocfs_status */
- time_t obd_recovery_end;
- int obd_recovery_time_hard;
- int obd_recovery_timeout;
+ time64_t obd_recovery_end;
+ time64_t obd_recovery_time_hard;
+ time64_t obd_recovery_timeout;
int obd_recovery_ir_factor;
/* new recovery stuff from CMD2 */
/* Fields used by LProcFS */
struct lprocfs_stats *obd_stats;
- unsigned int obd_cntr_base;
unsigned int obd_md_cntr_base;
struct lprocfs_stats *obd_md_stats;
+ struct dentry *obd_debugfs_entry;
struct proc_dir_entry *obd_proc_entry;
struct proc_dir_entry *obd_proc_exports_entry;
- struct proc_dir_entry *obd_svc_procroot;
+ struct dentry *obd_svc_debugfs_entry;
struct lprocfs_stats *obd_svc_stats;
+ const struct attribute **obd_attrs;
struct lprocfs_vars *obd_vars;
atomic_t obd_evict_inprogress;
wait_queue_head_t obd_evict_inprogress_waitq;
/**
* List of outstanding class_incref()'s fo this OBD. For debugging. */
struct lu_ref obd_reference;
+
+ struct kset obd_kset; /* sysfs object collection */
+ struct kobj_type obd_ktype;
+ struct completion obd_kobj_unregister;
};
/* get/set_info keys */
/* CREAT needs to be tested before open (both could be set) */
if (it->it_op & IT_CREAT)
return LCK_CW;
- else if (it->it_op & (IT_GETATTR | IT_OPEN | IT_LOOKUP |
- IT_LAYOUT))
+ else if (it->it_op & (IT_GETATTR | IT_OPEN | IT_LOOKUP))
return LCK_CR;
+ else if (it->it_op & IT_LAYOUT)
+ return (it->it_flags & FMODE_WRITE) ? LCK_EX : LCK_CR;
else if (it->it_op & IT_READDIR)
return LCK_PR;
else if (it->it_op & IT_GETXATTR)
return LCK_PR;
- else if (it->it_op & IT_SETXATTR)
- return LCK_PW;
LASSERTF(0, "Invalid it_op: %d\n", it->it_op);
return -EINVAL;
CLI_MIGRATE = 1 << 4,
};
+/**
+ * GETXATTR is not included as only a couple of fields in the reply body
+ * is filled, but not FID which is needed for common intent handling in
+ * mdc_finish_intent_lock()
+ */
+static inline bool it_has_reply_body(const struct lookup_intent *it)
+{
+ return it->it_op & (IT_OPEN | IT_LOOKUP | IT_GETATTR);
+}
+
struct md_op_data {
- struct lu_fid op_fid1; /* operation fid1 (usualy parent) */
- struct lu_fid op_fid2; /* operation fid2 (usualy child) */
- struct lu_fid op_fid3; /* 2 extra fids to find conflicting */
- struct lu_fid op_fid4; /* to the operation locks. */
+ struct lu_fid op_fid1; /* operation fid1 (usualy parent) */
+ struct lu_fid op_fid2; /* operation fid2 (usualy child) */
+ struct lu_fid op_fid3; /* 2 extra fids to find conflicting */
+ struct lu_fid op_fid4; /* to the operation locks. */
u32 op_mds; /* what mds server open will go to */
- struct lustre_handle op_handle;
+ __u32 op_mode;
+ struct lustre_handle op_handle;
s64 op_mod_time;
- const char *op_name;
+ const char *op_name;
size_t op_namelen;
- __u32 op_mode;
- struct lmv_stripe_md *op_mea1;
- struct lmv_stripe_md *op_mea2;
- __u32 op_suppgids[2];
- __u32 op_fsuid;
- __u32 op_fsgid;
- cfs_cap_t op_cap;
- void *op_data;
+ struct lmv_stripe_md *op_mea1;
+ struct lmv_stripe_md *op_mea2;
+ __u32 op_suppgids[2];
+ __u32 op_fsuid;
+ __u32 op_fsgid;
+ cfs_cap_t op_cap;
+ void *op_data;
size_t op_data_size;
- /* iattr fields and blocks. */
+ /* iattr fields and blocks. */
struct iattr op_attr;
loff_t op_attr_blocks;
- unsigned int op_attr_flags; /* LUSTRE_{SYNC,..}_FL */
__u64 op_valid; /* OBD_MD_* */
+ unsigned int op_attr_flags; /* LUSTRE_{SYNC,..}_FL */
enum md_op_flags op_flags;
/* Various operation flags. */
enum mds_op_bias op_bias;
- /* Used by readdir */
- unsigned int op_max_pages;
-
/* used to transfer info between the stacks of MD client
* see enum op_cli_flags */
enum md_cli_flags op_cli_flags;
__u64 op_data_version;
struct lustre_handle op_lease_handle;
+ /* File security context, for creates. */
+ const char *op_file_secctx_name;
+ void *op_file_secctx;
+ __u32 op_file_secctx_size;
+
/* default stripe offset */
__u32 op_default_stripe_offset;
+
+ __u32 op_projid;
+
+ /* Used by readdir */
+ unsigned int op_max_pages;
+
+ __u16 op_mirror_id;
};
struct md_callback {
* about this.
*/
int (*o_statfs)(const struct lu_env *, struct obd_export *exp,
- struct obd_statfs *osfs, __u64 max_age, __u32 flags);
+ struct obd_statfs *osfs, time64_t max_age, __u32 flags);
int (*o_statfs_async)(struct obd_export *exp, struct obd_info *oinfo,
- __u64 max_age, struct ptlrpc_request_set *set);
+ time64_t max_age, struct ptlrpc_request_set *set);
int (*o_create)(const struct lu_env *env, struct obd_export *exp,
struct obdo *oa);
int (*o_destroy)(const struct lu_env *env, struct obd_export *exp,
enum obd_import_event);
int (*o_notify)(struct obd_device *obd, struct obd_device *watched,
- enum obd_notify_event ev, void *data);
+ enum obd_notify_event ev);
int (*o_health_check)(const struct lu_env *env, struct obd_device *);
struct obd_uuid *(*o_get_uuid) (struct obd_export *exp);
char *ostname);
int (*o_pool_rem)(struct obd_device *obd, char *poolname,
char *ostname);
- void (*o_getref)(struct obd_device *obd);
- void (*o_putref)(struct obd_device *obd);
- /*
- * NOTE: If adding ops, add another LPROCFS_OBD_OP_INIT() line
- * to lprocfs_alloc_obd_stats() in obdclass/lprocfs_status.c.
- * Also, add a wrapper function in include/linux/obd_class.h. */
};
/* lmv structures */
cfs_cap_t, __u64, struct ptlrpc_request **);
int (*m_enqueue)(struct obd_export *, struct ldlm_enqueue_info *,
- const union ldlm_policy_data *,
- struct lookup_intent *, struct md_op_data *,
+ const union ldlm_policy_data *, struct md_op_data *,
struct lustre_handle *, __u64);
int (*m_getattr)(struct obd_export *, struct md_op_data *,
struct ptlrpc_request **);
int (*m_setxattr)(struct obd_export *, const struct lu_fid *,
- u64, const char *, const char *, int, int, int, u32,
- struct ptlrpc_request **);
+ u64, const char *, const void *, size_t, unsigned int,
+ u32, struct ptlrpc_request **);
int (*m_getxattr)(struct obd_export *, const struct lu_fid *,
- u64, const char *, const char *, int, int, int,
- struct ptlrpc_request **);
+ u64, const char *, size_t, struct ptlrpc_request **);
int (*m_intent_getattr_async)(struct obd_export *,
struct md_enqueue_info *);
#define MD_STATS_LAST_OP m_revalidate_lock
+ int (*m_file_resync)(struct obd_export *, struct md_op_data *);
+
int (*m_get_root)(struct obd_export *, const char *, struct lu_fid *);
int (*m_null_inode)(struct obd_export *, const struct lu_fid *);
void obdo_from_inode(struct obdo *dst, struct inode *src, u64 valid);
void obdo_set_parent_fid(struct obdo *dst, const struct lu_fid *parent);
+void obdo_set_o_projid(struct obdo *dst, u32 projid);
/* return 1 if client should be resend request */
static inline int client_should_resend(int resend, struct client_obd *cli)
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;
+ return obd->u.cli.cl_max_pages_per_rpc << PAGE_SHIFT;
}
-/* when RPC size or the max RPCs in flight is increased, the max dirty pages
+/*
+ * When RPC size or the max RPCs in flight is increased, the max dirty pages
* of the client should be increased accordingly to avoid sending fragmented
* RPCs over the network when the client runs out of the maximum dirty space
* when so many RPCs are being generated.
static inline void client_adjust_max_dirty(struct client_obd *cli)
{
/* initializing */
- if (cli->cl_dirty_max_pages <= 0)
- cli->cl_dirty_max_pages = (OSC_MAX_DIRTY_DEFAULT * 1024 * 1024)
- >> PAGE_CACHE_SHIFT;
- else {
+ if (cli->cl_dirty_max_pages <= 0) {
+ cli->cl_dirty_max_pages =
+ (OSC_MAX_DIRTY_DEFAULT * 1024 * 1024) >> PAGE_SHIFT;
+ } else {
unsigned long dirty_max = cli->cl_max_rpcs_in_flight *
cli->cl_max_pages_per_rpc;
if (cli->cl_dirty_max_pages > totalram_pages / 8)
cli->cl_dirty_max_pages = totalram_pages / 8;
+
+ /* This value is exported to userspace through the max_dirty_mb
+ * parameter. So we round up the number of pages to make it a round
+ * number of MBs. */
+ cli->cl_dirty_max_pages = round_up(cli->cl_dirty_max_pages,
+ 1 << (20 - PAGE_SHIFT));
}
#endif /* __OBD_H */