X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Finclude%2Fcl_object.h;h=20b14d20e464c43bc518e461a5ce14aa76f00595;hb=314614462e473ccea9557368d1b3fdec13b429c3;hp=734d0f9be68ba9365e58e053c3a9fc3a1caeb491;hpb=c5607338d96aa222319bebe58aa16785f463315e;p=fs%2Flustre-release.git diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index 734d0f9..20b14d2 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -862,7 +862,7 @@ struct cl_page_operations { const struct cl_page_slice *slice, struct cl_io *io); /** - * Announces whether the page contains valid data or not by @uptodate. + * Announces whether the page contains valid data or not by \a uptodate. * * \see cl_page_export() * \see vvp_page_export() @@ -1337,15 +1337,15 @@ const char *cl_lock_mode_name(const enum cl_lock_mode mode); * | | V * | | HELD<---------+ * | | | | - * | | | | + * | | | | cl_use_try() * | | cl_unuse_try() | | * | | | | - * | | V | cached - * | +------------>UNLOCKING (*) | lock found - * | | | - * | cl_unuse_try() | | + * | | V ---+ + * | +------------>INTRANSIT (D) <--+ * | | | + * | cl_unuse_try() | | cached lock found * | | | cl_use_try() + * | | | * | V | * +------------------CACHED---------+ * | @@ -1364,6 +1364,8 @@ const char *cl_lock_mode_name(const enum cl_lock_mode mode); * * (C) is the point where Cancellation call-back is invoked. * + * (D) is the transit state which means the lock is changing. + * * Transition to FREEING state is possible from any other state in the * diagram in case of unrecoverable error. * @@ -1382,9 +1384,6 @@ const char *cl_lock_mode_name(const enum cl_lock_mode mode); * handled, and is in ENQUEUED state after enqueue to S2 has been sent (note * that in this case, sub-locks move from state to state, and top-lock remains * in the same state). - * - * Separate UNLOCKING state is needed to maintain an invariant that in HELD - * state lock is immediately ready for use. */ enum cl_lock_state { /** @@ -1406,10 +1405,16 @@ enum cl_lock_state { */ CLS_HELD, /** - * Lock is in the transition from CLS_HELD to CLS_CACHED. Lock is in - * this state only while cl_unuse() is executing against it. + * This state is used to mark the lock is being used, or unused. + * We need this state because the lock may have several sublocks, + * so it's impossible to have an atomic way to bring all sublocks + * into CLS_HELD state at use case, or all sublocks to CLS_CACHED + * at unuse case. + * If a thread is referring to a lock, and it sees the lock is in this + * state, it must wait for the lock. + * See state diagram for details. */ - CLS_UNLOCKING, + CLS_INTRANSIT, /** * Lock granted, not used. */ @@ -1430,9 +1435,7 @@ enum cl_lock_flags { /** cancellation is pending for this lock. */ CLF_CANCELPEND = 1 << 1, /** destruction is pending for this lock. */ - CLF_DOOMED = 1 << 2, - /** State update is pending. */ - CLF_STATE = 1 << 3 + CLF_DOOMED = 1 << 2 }; /** @@ -1530,6 +1533,10 @@ struct cl_lock { cfs_task_t *cll_guarder; int cll_depth; + /** + * the owner for INTRANSIT state + */ + cfs_task_t *cll_intransit_owner; int cll_error; /** * Number of holds on a lock. A hold prevents a lock from being @@ -1732,7 +1739,7 @@ struct cl_lock_operations { const struct cl_lock_slice *slice, struct cl_lock_closure *closure); /** - * Executed top-to-bottom when lock description changes (e.g., as a + * Executed bottom-to-top when lock description changes (e.g., as a * result of server granting more generous lock than was requested). * * \see lovsub_lock_modify() @@ -1804,7 +1811,7 @@ struct cl_page_list { cfs_task_t *pl_owner; }; -/** \addtogroup cl_page_list cl_page_list +/** * A 2-queue of pages. A convenience data-type for common use case, 2-queue * contains an incoming page list and an outgoing page list. */ @@ -2216,6 +2223,7 @@ struct cl_io_rw_common { int crw_nonblock; }; + /** * State for io. * @@ -2251,7 +2259,6 @@ struct cl_io { union { struct cl_rd_io { struct cl_io_rw_common rd; - int rd_is_sendfile; } ci_rd; struct cl_wr_io { struct cl_io_rw_common wr; @@ -2628,6 +2635,7 @@ int cl_conf_set (const struct lu_env *env, struct cl_object *obj, const struct cl_object_conf *conf); void cl_object_prune (const struct lu_env *env, struct cl_object *obj); void cl_object_kill (const struct lu_env *env, struct cl_object *obj); +int cl_object_has_locks (struct cl_object *obj); /** * Returns true, iff \a o0 and \a o1 are slices of the same object. @@ -2778,6 +2786,14 @@ int cl_lock_user_del (const struct lu_env *env, struct cl_lock *lock); int cl_lock_compatible(const struct cl_lock *lock1, const struct cl_lock *lock2); +enum cl_lock_state cl_lock_intransit(const struct lu_env *env, + struct cl_lock *lock); + +void cl_lock_extransit(const struct lu_env *env, struct cl_lock *lock, + enum cl_lock_state state); + +int cl_lock_is_intransit(struct cl_lock *lock); + /** \name statemachine statemachine * Interface to lock state machine consists of 3 parts: * @@ -2818,7 +2834,7 @@ int cl_enqueue_try(const struct lu_env *env, struct cl_lock *lock, struct cl_io *io, __u32 flags); int cl_unuse_try (const struct lu_env *env, struct cl_lock *lock); int cl_wait_try (const struct lu_env *env, struct cl_lock *lock); -int cl_use_try (const struct lu_env *env, struct cl_lock *lock); +int cl_use_try (const struct lu_env *env, struct cl_lock *lock, int atomic); /** @} statemachine */ void cl_lock_signal (const struct lu_env *env, struct cl_lock *lock); @@ -2912,8 +2928,6 @@ static inline int cl_io_is_append(const struct cl_io *io) return io->ci_type == CIT_WRITE && io->u.ci_wr.wr_append; } -int cl_io_is_sendfile(const struct cl_io *io); - struct cl_io *cl_io_top(struct cl_io *io); void cl_io_print(const struct lu_env *env, void *cookie,