-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* GPL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
/*
#include <cl_object.h>
#include "lov_internal.h"
-/** \addtogroup lov lov @{ */
-
/** \defgroup lov lov
* Logical object volume layer. This layer implements data striping (raid0).
*
* cl_lock::cll_guard, and will be automatically cleared by the sub-lock
* when the latter is destroyed. When a sub-lock is canceled, a
* reference to it is removed from the top-lock array, and top-lock is
- * moved into CLS_NEW state. It is guaranteed that all sub-locks exits
+ * moved into CLS_NEW state. It is guaranteed that all sub-locks exist
* while their top-lock is in CLS_HELD or CLS_CACHED states.
*
* - IO's are not reference counted.
*
* To implement a connection between top and sub entities, lov layer is split
* into two pieces: lov ("upper half"), and lovsub ("bottom half"), both
- * implementing full set of cl-interfaces. For example, top-object has clu and
+ * implementing full set of cl-interfaces. For example, top-object has vvp and
* lov layers, and it's sub-object has lovsub and osc layers. lovsub layer is
* used to track child-parent relationship.
*
* Serializes access to lov_device::ld_emrg in low-memory
* conditions.
*/
- struct mutex ld_mutex;
+ cfs_mutex_t ld_mutex;
};
/**
LLT_EMPTY,
/** striped file */
LLT_RAID0,
- /** join file */
- LLT_JOIN,
LLT_NR
};
*
* \see lov_object::lo_type
*/
- struct rw_semaphore lo_type_guard;
+ cfs_rw_semaphore_t lo_type_guard;
/**
* Type of an object. Protected by lov_object::lo_type_guard.
*/
enum lov_layout_type lo_type;
+ /**
+ * True if layout is valid. This bit is cleared when layout lock
+ * is lost.
+ */
+ unsigned lo_lsm_invalid:1;
+ /**
+ * Layout metadata.
+ */
+ struct lov_stripe_md *lo_lsm;
+ /**
+ * Waitq - wait for no one else is using lo_lsm
+ */
+ cfs_waitq_t lo_waitq;
union lov_layout_state {
struct lov_layout_raid0 {
unsigned lo_nr;
- struct lov_stripe_md *lo_lsm;
+ /**
+ * When this is true, lov_object::lo_attr contains
+ * valid up to date attributes for a top-level
+ * object. This field is reset to 0 when attributes of
+ * any sub-object change.
+ */
+ int lo_attr_valid;
+ /**
+ * Array of sub-objects. Allocated when top-object is
+ * created (lov_init_raid0()).
+ *
+ * Top-object is a strict master of its sub-objects:
+ * it is created before them, and outlives its
+ * children (this later is necessary so that basic
+ * functions like cl_object_top() always
+ * work). Top-object keeps a reference on every
+ * sub-object.
+ *
+ * When top-object is destroyed (lov_delete_raid0())
+ * it releases its reference to a sub-object and waits
+ * until the latter is finally destroyed.
+ */
struct lovsub_object **lo_sub;
/**
- * When this is true, lov_object::lo_attr contains
- * valid up to date attributes for a top-level
- * object. This field is reset to 0 when attributes of
- * any sub-object change.
+ * protect lo_sub
*/
- int lo_attr_valid;
+ cfs_spinlock_t lo_sub_lock;
/**
* Cached object attribute, built from sub-object
* attributes.
} raid0;
struct lov_layout_state_empty {
} empty;
- struct lov_layout_state_join {
- } join;
} u;
/**
* Thread that acquired lov_object::lo_type_guard in an exclusive
unsigned lls_nr_filled;
/**
* Set when sub-lock was canceled, while top-lock was being
- * unlocked.
+ * used, or unused.
*/
- int lls_unuse_race;
+ int lls_cancel_race:1;
/**
* An array of sub-locks
*
* A linkage into per sub-lock list of all corresponding top-locks,
* hanging off lovsub_lock::lss_parents.
*/
- struct list_head lll_list;
+ cfs_list_t lll_list;
};
/**
* List of top-locks that have given sub-lock as their part. Protected
* by cl_lock::cll_guard mutex.
*/
- struct list_head lss_parents;
+ cfs_list_t lss_parents;
/**
* Top-lock that initiated current operation on this sub-lock. This is
* only set during top-to-bottom lock operations like enqueue, and is
struct cl_lock *lss_active;
};
+/**
+ * Describe the environment settings for sublocks.
+ */
+struct lov_sublock_env {
+ const struct lu_env *lse_env;
+ struct cl_io *lse_io;
+ struct lov_io_sub *lse_sub;
+};
+
struct lovsub_page {
struct cl_page_slice lsb_cl;
};
struct cl_lock_descr lti_ldescr;
struct ost_lvb lti_lvb;
struct cl_2queue lti_cl2q;
- union lov_layout_state lti_state;
struct cl_lock_closure lti_closure;
+ cfs_waitlink_t lti_waiter;
};
/**
* Linkage into a list (hanging off lov_io::lis_active) of all
* sub-io's active for the current IO iteration.
*/
- struct list_head sub_linkage;
+ cfs_list_t sub_linkage;
/**
* true, iff cl_io_init() was successfully executed against
* lov_io_sub::sub_io.
* lov_io::lis_cl::cis_object.
*/
struct lov_object *lis_object;
+ /**
+ * Lov stripe - this determines how this io fans out.
+ * Hold a refcount to the lsm so it can't go away during IO.
+ */
+ struct lov_stripe_md *lis_lsm;
/**
* Original end-of-io position for this IO, set by the upper layer as
* cl_io::u::ci_rw::pos + cl_io::u::ci_rw::count. lov remembers this,
/**
* List of active sub-io's.
*/
- struct list_head lis_active;
+ cfs_list_t lis_active;
};
struct lov_session {
- struct lov_io ls_io;
+ struct lov_io ls_io;
+ struct lov_sublock_env ls_subenv;
};
/**
void lov_lock_unlink (const struct lu_env *env, struct lov_lock_link *link,
struct lovsub_lock *sub);
-void lov_sub_put (struct lov_io_sub *sub);
+struct lov_io_sub *lov_sub_get(const struct lu_env *env, struct lov_io *lio,
+ int stripe);
+void lov_sub_put (struct lov_io_sub *sub);
int lov_sublock_modify (const struct lu_env *env, struct lov_lock *lov,
struct lovsub_lock *sublock,
const struct cl_lock_descr *d, int idx);
struct lov_io *lio,
const struct cl_page_slice *slice);
+void lov_lsm_decref(struct lov_object *lov, struct lov_stripe_md *lsm);
+struct lov_stripe_md *lov_lsm_addref(struct lov_object *lov);
#define lov_foreach_target(lov, var) \
for (var = 0; var < lov_targets_nr(lov); ++var)
static inline struct lov_layout_raid0 *lov_r0(struct lov_object *lov)
{
- struct lov_layout_raid0 *raid0;
-
- LASSERT(lov->lo_type == LLT_RAID0);
- raid0 = &lov->u.raid0;
- LASSERT(raid0->lo_lsm->lsm_wire.lw_magic == LOV_MAGIC);
- return raid0;
+ LASSERT(lov->lo_type == LLT_RAID0);
+ LASSERT(lov->lo_lsm->lsm_wire.lw_magic == LOV_MAGIC ||
+ lov->lo_lsm->lsm_wire.lw_magic == LOV_MAGIC_V3);
+ return &lov->u.raid0;
}
/** @} lov */