Whamcloud - gitweb
LU-1030 clio: reimplement ll_fsync in clio way
[fs/lustre-release.git] / lustre / osc / osc_cl_internal.h
index 6085101..3094ca2 100644 (file)
@@ -1,6 +1,4 @@
-/* -*- 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.
+ *
+ * Copyright (c) 2012, Whamcloud, Inc.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -57,7 +57,9 @@
 #include <cl_object.h>
 #include "osc_internal.h"
 
-/** \addtogroup osc osc @{ */
+/** \defgroup osc osc
+ *  @{
+ */
 
 /**
  * State maintained by osc layer for each IO context.
@@ -68,11 +70,12 @@ struct osc_io {
         /** true if this io is lockless. */
         int                oi_lockless;
 
-        struct obdo        oi_oa;
-        struct osc_punch_cbargs {
-                int               opc_rc;
-                struct completion opc_sync;
-        } oi_punch_cbarg;
+       struct obd_info    oi_info;
+       struct obdo        oi_oa;
+       struct osc_async_cbargs {
+               int               opc_rc;
+               cfs_completion_t  opc_sync;
+       } oi_cbarg;
 };
 
 /**
@@ -95,10 +98,25 @@ struct osc_thread_info {
         struct cl_lock_descr    oti_descr;
         struct cl_attr          oti_attr;
         struct lustre_handle    oti_handle;
-        struct cl_lock_closure  oti_closure;
         struct cl_page_list     oti_plist;
 };
 
+/**
+ * Manage osc_async_page
+ */
+struct osc_oap_pages {
+       cfs_list_t      oop_pending;
+       cfs_list_t      oop_urgent;
+       int             oop_num_pending;
+};
+
+static inline void osc_oap_pages_init(struct osc_oap_pages *list)
+{
+       CFS_INIT_LIST_HEAD(&list->oop_pending);
+       CFS_INIT_LIST_HEAD(&list->oop_urgent);
+       list->oop_num_pending = 0;
+}
+
 struct osc_object {
         struct cl_object   oo_cl;
         struct lov_oinfo  *oo_oinfo;
@@ -113,17 +131,27 @@ struct osc_object {
          */
         struct cl_io       oo_debug_io;
         /** Serialization object for osc_object::oo_debug_io. */
-        struct mutex       oo_debug_mutex;
+        cfs_mutex_t        oo_debug_mutex;
 #endif
         /**
          * List of pages in transfer.
          */
-        struct list_head   oo_inflight[CRT_NR];
+        cfs_list_t         oo_inflight[CRT_NR];
         /**
          * Lock, protecting ccc_object::cob_inflight, because a seat-belt is
          * locked during take-off and landing.
          */
-        spinlock_t         oo_seatbelt;
+        cfs_spinlock_t     oo_seatbelt;
+
+       /**
+        * used by the osc to keep track of what objects to build into rpcs
+        */
+       struct osc_oap_pages oo_read_pages;
+       struct osc_oap_pages oo_write_pages;
+       cfs_list_t           oo_ready_item;
+       cfs_list_t           oo_hp_ready_item;
+       cfs_list_t           oo_write_item;
+       cfs_list_t           oo_read_item;
 };
 
 /*
@@ -195,6 +223,17 @@ struct osc_lock {
         struct lustre_handle     ols_handle;
         struct ldlm_enqueue_info ols_einfo;
         enum osc_lock_state      ols_state;
+
+        /**
+         * How many pages are using this lock for io, currently only used by
+         * read-ahead. If non-zero, the underlying dlm lock won't be cancelled
+         * during recovery to avoid deadlock. see bz16774.
+         *
+         * \see osc_page::ops_lock
+         * \see osc_page_addref_lock(), osc_page_putref_lock()
+         */
+        cfs_atomic_t             ols_pageref;
+
         /**
          * true, if ldlm_lock_addref() was called against
          * osc_lock::ols_lock. This is used for sanity checking.
@@ -241,12 +280,18 @@ struct osc_lock {
          * granted.
          * Glimpse lock should be destroyed immediately after use.
          */
-                                 ols_glimpse:1;
+                                 ols_glimpse:1,
+        /**
+         * For async glimpse lock.
+         */
+                                 ols_agl:1;
         /**
          * IO that owns this lock. This field is used for a dead-lock
-         * avoidance by osc_lock_enqueue().
+         * avoidance by osc_lock_enqueue_wait().
          *
-         * \see osc_deadlock_is_possible()
+         * XXX: unfortunately, the owner of a osc_lock is not unique, 
+         * the lock may have multiple users, if the lock is granted and
+         * then matched.
          */
         struct osc_io           *ols_owner;
 };
@@ -280,16 +325,34 @@ struct osc_page {
          * True for a `temporary page' created by read-ahead code, probably
          * outside of any DLM lock.
          */
-                              ops_temp:1;
+                              ops_temp:1,
+        /**
+         * Set if the page must be transferred with OBD_BRW_SRVLOCK.
+         */
+                              ops_srvlock:1;
         /**
          * Linkage into a per-osc_object list of pages in flight. For
          * debugging.
          */
-        struct list_head      ops_inflight;
+        cfs_list_t            ops_inflight;
         /**
          * Thread that submitted this page for transfer. For debugging.
          */
         cfs_task_t           *ops_submitter;
+        /**
+         * Submit time - the time when the page is starting RPC. For debugging.
+         */
+        cfs_time_t            ops_submit_time;
+
+        /**
+         * A lock of which we hold a reference covers this page. Only used by
+         * read-ahead: for a readahead page, we hold it's covering lock to
+         * prevent it from being canceled during recovery.
+         *
+         * \see osc_lock::ols_pageref
+         * \see osc_page_addref_lock(), osc_page_putref_lock().
+         */
+        struct cl_lock       *ops_lock;
 };
 
 extern cfs_mem_cache_t *osc_page_kmem;
@@ -325,9 +388,25 @@ void osc_index2policy  (ldlm_policy_data_t *policy, const struct cl_object *obj,
                         pgoff_t start, pgoff_t end);
 int  osc_lvb_print     (const struct lu_env *env, void *cookie,
                         lu_printer_t p, const struct ost_lvb *lvb);
+
 void osc_io_submit_page(const struct lu_env *env,
                         struct osc_io *oio, struct osc_page *opg,
                         enum cl_req_type crt);
+void osc_ap_completion(const struct lu_env *env, struct client_obd *cli,
+                      struct obdo *oa, struct osc_async_page *oap,
+                      int sent, int rc);
+int osc_cancel_async_page(const struct lu_env *env, struct osc_page *ops);
+int osc_set_async_flags(struct osc_object *obj, struct osc_page *opg,
+                       obd_flag async_flags);
+int osc_prep_async_page(struct osc_object *osc, struct osc_page *ops,
+                       cfs_page_t *page, loff_t offset);
+int osc_queue_async_io(const struct lu_env *env, struct osc_page *ops);
+int osc_teardown_async_page(struct osc_object *obj,
+                           struct osc_page *ops);
+int osc_queue_sync_page(const struct lu_env *env, struct osc_page *ops,
+                       int cmd, int brw_flags);
+void osc_io_unplug(const struct lu_env *env, struct client_obd *cli,
+                  struct osc_object *osc, pdl_policy_t pol);
 
 void osc_object_set_contended  (struct osc_object *obj);
 void osc_object_clear_contended(struct osc_object *obj);
@@ -388,14 +467,24 @@ static inline struct osc_object *cl2osc(const struct cl_object *obj)
 
 static inline ldlm_mode_t osc_cl_lock2ldlm(enum cl_lock_mode mode)
 {
-        LASSERT(mode == CLM_READ || mode == CLM_WRITE);
-        return mode == CLM_READ ? LCK_PR : LCK_PW;
+        LASSERT(mode == CLM_READ || mode == CLM_WRITE || mode == CLM_GROUP);
+        if (mode == CLM_READ)
+                return LCK_PR;
+        else if (mode == CLM_WRITE)
+                return LCK_PW;
+        else
+                return LCK_GROUP;
 }
 
 static inline enum cl_lock_mode osc_ldlm2cl_lock(ldlm_mode_t mode)
 {
-        LASSERT(mode == LCK_PR || mode == LCK_PW);
-        return mode == LCK_PR ? CLM_READ : CLM_WRITE;
+        LASSERT(mode == LCK_PR || mode == LCK_PW || mode == LCK_GROUP);
+        if (mode == LCK_PR)
+                return CLM_READ;
+        else if (mode == LCK_PW)
+                return CLM_WRITE;
+        else
+                return CLM_GROUP;
 }
 
 static inline struct osc_page *cl2osc_page(const struct cl_page_slice *slice)
@@ -415,6 +504,11 @@ static inline struct osc_lock *osc_lock_at(const struct cl_lock *lock)
         return cl2osc_lock(cl_lock_at(lock, &osc_device_type));
 }
 
+static inline int osc_io_srvlock(struct osc_io *oio)
+{
+        return (oio->oi_lockless && !oio->oi_cl.cis_io->ci_no_srvlock);
+}
+
 /** @} osc */
 
 #endif /* OSC_CL_INTERNAL_H */