Whamcloud - gitweb
LU-1030 clio: reimplement ll_fsync in clio way
[fs/lustre-release.git] / lustre / include / cl_object.h
index 58ef32a..c0f014d 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) 2011, 2012, Whamcloud, Inc.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -1062,10 +1062,10 @@ struct cl_page_operations {
  */
 #define CL_PAGE_DEBUG(mask, env, page, format, ...)                     \
 do {                                                                    \
-        static DECLARE_LU_CDEBUG_PRINT_INFO(__info, mask);              \
+        LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL);                \
                                                                         \
         if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) {                   \
-                cl_page_print(env, &__info, lu_cdebug_printer, page);   \
+                cl_page_print(env, &msgdata, lu_cdebug_printer, page);  \
                 CDEBUG(mask, format , ## __VA_ARGS__);                  \
         }                                                               \
 } while (0)
@@ -1073,14 +1073,14 @@ do {                                                                    \
 /**
  * Helper macro, dumping shorter information about \a page into a log.
  */
-#define CL_PAGE_HEADER(mask, env, page, format, ...)                    \
-do {                                                                    \
-        static DECLARE_LU_CDEBUG_PRINT_INFO(__info, mask);              \
-                                                                        \
-        if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) {                   \
-                cl_page_header_print(env, &__info, lu_cdebug_printer, page); \
-                CDEBUG(mask, format , ## __VA_ARGS__);                  \
-        }                                                               \
+#define CL_PAGE_HEADER(mask, env, page, format, ...)                          \
+do {                                                                          \
+        LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL);                      \
+                                                                              \
+        if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) {                         \
+                cl_page_header_print(env, &msgdata, lu_cdebug_printer, page); \
+                CDEBUG(mask, format , ## __VA_ARGS__);                        \
+        }                                                                     \
 } while (0)
 
 /** @} cl_page */
@@ -1440,7 +1440,9 @@ enum cl_lock_flags {
         /** cancellation is pending for this lock. */
         CLF_CANCELPEND = 1 << 1,
         /** destruction is pending for this lock. */
-        CLF_DOOMED     = 1 << 2
+        CLF_DOOMED     = 1 << 2,
+        /** from enqueue RPC reply upcall. */
+        CLF_FROM_UPCALL= 1 << 3,
 };
 
 /**
@@ -1613,9 +1615,11 @@ struct cl_lock_slice {
  */
 enum cl_lock_transition {
         /** operation cannot be completed immediately. Wait for state change. */
-        CLO_WAIT   = 1,
+        CLO_WAIT        = 1,
         /** operation had to release lock mutex, restart. */
-        CLO_REPEAT = 2
+        CLO_REPEAT      = 2,
+        /** lower layer re-enqueued. */
+        CLO_REENQUEUED  = 3,
 };
 
 /**
@@ -1786,10 +1790,10 @@ struct cl_lock_operations {
 
 #define CL_LOCK_DEBUG(mask, env, lock, format, ...)                     \
 do {                                                                    \
-        static DECLARE_LU_CDEBUG_PRINT_INFO(__info, mask);              \
+        LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL);                \
                                                                         \
         if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) {                   \
-                cl_lock_print(env, &__info, lu_cdebug_printer, lock);   \
+                cl_lock_print(env, &msgdata, lu_cdebug_printer, lock);  \
                 CDEBUG(mask, format , ## __VA_ARGS__);                  \
         }                                                               \
 } while (0)
@@ -1890,13 +1894,18 @@ enum cl_io_type {
         CIT_READ,
         /** write system call */
         CIT_WRITE,
-        /** truncate system call */
-        CIT_TRUNC,
+        /** truncate, utime system calls */
+        CIT_SETATTR,
         /**
          * page fault handling
          */
         CIT_FAULT,
         /**
+        * fsync system call handling
+        * To write out a range of file
+        */
+       CIT_FSYNC,
+       /**
          * Miscellaneous io. This is used for occasional io activity that
          * doesn't fit into other types. Currently this is used for:
          *
@@ -2152,9 +2161,13 @@ enum cl_enq_flags {
          */
         CEF_NEVER        = 0x00000010,
         /**
+         * for async glimpse lock.
+         */
+        CEF_AGL          = 0x00000020,
+        /**
          * mask of enq_flags.
          */
-        CEF_MASK         = 0x0000001f
+        CEF_MASK         = 0x0000003f,
 };
 
 /**
@@ -2219,7 +2232,9 @@ enum cl_io_lock_dmd {
         /** Layers are free to decide between local and global locking. */
         CILR_MAYBE,
         /** Never lock: there is no cache (e.g., liblustre). */
-        CILR_NEVER
+        CILR_NEVER,
+        /** Peek lock: use existing locks, don't queue new ones */
+        CILR_PEEK
 };
 
 struct cl_io_rw_common {
@@ -2270,23 +2285,32 @@ struct cl_io {
                         int                    wr_append;
                 } ci_wr;
                 struct cl_io_rw_common ci_rw;
-                struct cl_truncate_io {
-                        /** new size to which file is truncated */
-                        loff_t           tr_size;
-                        struct obd_capa *tr_capa;
-                } ci_truncate;
+                struct cl_setattr_io {
+                        struct ost_lvb   sa_attr;
+                        unsigned int     sa_valid;
+                        struct obd_capa *sa_capa;
+                } ci_setattr;
                 struct cl_fault_io {
                         /** page index within file. */
                         pgoff_t         ft_index;
                         /** bytes valid byte on a faulted page. */
                         int             ft_nob;
-                        /** writable page? */
+                        /** writable page? for nopage() only */
                         int             ft_writable;
                         /** page of an executable? */
                         int             ft_executable;
+                        /** page_mkwrite() */
+                        int             ft_mkwrite;
                         /** resulting page */
                         struct cl_page *ft_page;
                 } ci_fault;
+               struct cl_fsync_io {
+                       loff_t             fi_start;
+                       loff_t             fi_end;
+                       struct obd_capa   *fi_capa;
+                       /** file system level fid */
+                       struct lu_fid     *fi_fid;
+               } ci_fsync;
         } u;
         struct cl_2queue     ci_queue;
         size_t               ci_nob;
@@ -2366,10 +2390,12 @@ struct cl_io {
  * Per-transfer attributes.
  */
 struct cl_req_attr {
-        /** Generic attributes for the server consumption. */
-        struct obdo     *cra_oa;
-        /** Capability. */
-        struct obd_capa *cra_capa;
+       /** Generic attributes for the server consumption. */
+       struct obdo     *cra_oa;
+       /** Capability. */
+       struct obd_capa *cra_capa;
+       /** Jobid */
+       char             cra_jobid[JOBSTATS_JOBID_SIZE];
 };
 
 /**
@@ -2654,15 +2680,23 @@ static inline int cl_object_same(struct cl_object *o0, struct cl_object *o1)
 
 /** \defgroup cl_page cl_page
  * @{ */
-struct cl_page       *cl_page_lookup(struct cl_object_header *hdr,
+enum {
+        CLP_GANG_OKAY = 0,
+        CLP_GANG_RESCHED,
+        CLP_GANG_AGAIN,
+        CLP_GANG_ABORT
+};
+
+/* callback of cl_page_gang_lookup() */
+typedef int   (*cl_page_gang_cb_t)  (const struct lu_env *, struct cl_io *,
+                                     struct cl_page *, void *);
+int             cl_page_gang_lookup (const struct lu_env *env,
+                                     struct cl_object *obj,
+                                     struct cl_io *io,
+                                     pgoff_t start, pgoff_t end,
+                                     cl_page_gang_cb_t cb, void *cbdata);
+struct cl_page *cl_page_lookup      (struct cl_object_header *hdr,
                                      pgoff_t index);
-void                  cl_page_gang_lookup(const struct lu_env *env,
-                                          struct cl_object *obj,
-                                          struct cl_io *io,
-                                          pgoff_t start, pgoff_t end,
-                                          struct cl_page_list *plist,
-                                          int nonblock,
-                                          int *resched);
 struct cl_page *cl_page_find        (const struct lu_env *env,
                                      struct cl_object *obj,
                                      pgoff_t idx, struct page *vmpage,
@@ -2684,7 +2718,6 @@ cfs_page_t     *cl_page_vmpage      (const struct lu_env *env,
                                      struct cl_page *page);
 struct cl_page *cl_vmpage_page      (cfs_page_t *vmpage, struct cl_object *obj);
 struct cl_page *cl_page_top         (struct cl_page *page);
-int             cl_is_page          (const void *addr);
 
 const struct cl_page_slice *cl_page_at(const struct cl_page *page,
                                        const struct lu_device_type *dtype);
@@ -2791,16 +2824,17 @@ void  cl_lock_unhold    (const struct lu_env *env, struct cl_lock *lock,
 void  cl_lock_release   (const struct lu_env *env, struct cl_lock *lock,
                          const char *scope, const void *source);
 void  cl_lock_user_add  (const struct lu_env *env, struct cl_lock *lock);
-int   cl_lock_user_del  (const struct lu_env *env, struct cl_lock *lock);
+void  cl_lock_user_del  (const struct lu_env *env, struct cl_lock *lock);
 
 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);
 
+int cl_lock_enqueue_wait(const struct lu_env *env, struct cl_lock *lock,
+                         int keep_mutex);
+
 /** \name statemachine statemachine
  * Interface to lock state machine consists of 3 parts:
  *
@@ -2842,6 +2876,7 @@ int   cl_enqueue_try(const struct lu_env *env, struct cl_lock *lock,
 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 atomic);
+
 /** @} statemachine */
 
 void cl_lock_signal      (const struct lu_env *env, struct cl_lock *lock);
@@ -2881,7 +2916,6 @@ void cl_lock_cancel(const struct lu_env *env, struct cl_lock *lock);
 void cl_lock_delete(const struct lu_env *env, struct cl_lock *lock);
 void cl_lock_error (const struct lu_env *env, struct cl_lock *lock, int error);
 void cl_locks_prune(const struct lu_env *env, struct cl_object *obj, int wait);
-int  cl_is_lock    (const void *addr);
 
 unsigned long cl_lock_weigh(const struct lu_env *env, struct cl_lock *lock);
 
@@ -2935,6 +2969,15 @@ static inline int cl_io_is_append(const struct cl_io *io)
         return io->ci_type == CIT_WRITE && io->u.ci_wr.wr_append;
 }
 
+/**
+ * True, iff \a io is a truncate(2).
+ */
+static inline int cl_io_is_trunc(const struct cl_io *io)
+{
+        return io->ci_type == CIT_SETATTR &&
+                (io->u.ci_setattr.sa_valid & ATTR_SIZE);
+}
+
 struct cl_io *cl_io_top(struct cl_io *io);
 
 void cl_io_print(const struct lu_env *env, void *cookie,
@@ -2955,6 +2998,15 @@ do {                                                                    \
  * @{ */
 
 /**
+ * Last page in the page list.
+ */
+static inline struct cl_page *cl_page_list_last(struct cl_page_list *plist)
+{
+        LASSERT(plist->pl_nr > 0);
+        return cfs_list_entry(plist->pl_pages.prev, struct cl_page, cp_batch);
+}
+
+/**
  * Iterate over pages in a page list.
  */
 #define cl_page_list_for_each(page, list)                               \