Whamcloud - gitweb
updates to lu_object printing code:
authornikita <nikita>
Fri, 21 Jul 2006 19:25:56 +0000 (19:25 +0000)
committernikita <nikita>
Fri, 21 Jul 2006 19:25:56 +0000 (19:25 +0000)
 - print objects into log (libcfs_debug_msg());

 - LU_OBJECT_DEBUG() macro.

lustre/cmm/cmm_object.c
lustre/cmm/mdc_object.c
lustre/include/lu_object.h
lustre/kernel_patches/patches/ext3-iam-uapi.patch
lustre/mdd/mdd_handler.c
lustre/mdt/mdt_handler.c
lustre/obdclass/lu_object.c

index 0eacde8..02b9b15 100644 (file)
@@ -44,9 +44,9 @@ static int cmm_fld_lookup(struct cmm_device *cm,
         ENTRY;
 
         LASSERT(fid_is_sane(fid));
-        
+
         ls = cm->cmm_md_dev.md_lu_dev.ld_site;
-        
+
         rc = fld_client_lookup(ls->ls_client_fld,
                                fid_seq(fid), mds);
         if (rc) {
@@ -196,10 +196,10 @@ static int cml_object_exists(const struct lu_context *ctx,
         return lu_object_exists(ctx, lu_object_next(lo));
 }
 
-static int cml_object_print(const struct lu_context *ctx,
-                            struct seq_file *f, const struct lu_object *lo)
+static int cml_object_print(const struct lu_context *ctx, void *cookie,
+                            lu_printer_t p, const struct lu_object *lo)
 {
-       return seq_printf(f, LUSTRE_CMM0_NAME"-local@%p", lo);
+       return (*p)(ctx, cookie, LUSTRE_CMM0_NAME"-local@%p", lo);
 }
 
 static struct lu_object_operations cml_obj_ops = {
@@ -314,8 +314,8 @@ static int cml_lookup(const struct lu_context *ctx, struct md_object *mo_p,
 
 }
 
-static int cml_create(const struct lu_context *ctx, struct md_object *mo_p, 
-                      const char *child_name, struct md_object *mo_c, 
+static int cml_create(const struct lu_context *ctx, struct md_object *mo_p,
+                      const char *child_name, struct md_object *mo_c,
                       const char *target_name, struct md_attr *ma)
 {
         int rc;
@@ -479,10 +479,10 @@ static int cmr_object_exists(const struct lu_context *ctx,
         return -1;
 }
 
-static int cmr_object_print(const struct lu_context *ctx,
-                            struct seq_file *f, const struct lu_object *lo)
+static int cmr_object_print(const struct lu_context *ctx, void *cookie,
+                            lu_printer_t p, const struct lu_object *lo)
 {
-       return seq_printf(f, LUSTRE_CMM0_NAME"-remote@%p", lo);
+       return (*p)(ctx, cookie, LUSTRE_CMM0_NAME"-remote@%p", lo);
 }
 
 static struct lu_object_operations cmr_obj_ops = {
@@ -578,7 +578,7 @@ static int cmr_lookup(const struct lu_context *ctx, struct md_object *mo_p,
  *
  */
 static int cmr_create(const struct lu_context *ctx, struct md_object *mo_p,
-                      const char *child_name, struct md_object *mo_c, 
+                      const char *child_name, struct md_object *mo_c,
                       const char *target_name, struct md_attr *ma)
 {
         int rc;
@@ -653,7 +653,7 @@ static int cmr_rename(const struct lu_context *ctx, struct md_object *mo_po,
         RETURN(rc);
 }
 
-/* part of cross-ref rename(). Used to insert new name in new parent 
+/* part of cross-ref rename(). Used to insert new name in new parent
  * and unlink target with same name if it exists */
 static int cmr_rename_tgt(const struct lu_context *ctx,
                           struct md_object *mo_p, struct md_object *mo_t,
index b053e8b..f9fcea0 100644 (file)
@@ -77,10 +77,10 @@ static int mdc_object_init(const struct lu_context *ctx, struct lu_object *lo)
         RETURN(0);
 }
 
-static int mdc_object_print(const struct lu_context *ctx,
-                            struct seq_file *f, const struct lu_object *lo)
+static int mdc_object_print(const struct lu_context *ctx, void *cookie,
+                            lu_printer_t p, const struct lu_object *lo)
 {
-       return seq_printf(f, LUSTRE_MDC0_NAME"-object@%p", lo);
+       return (*p)(ctx, cookie, LUSTRE_MDC0_NAME"-object@%p", lo);
 }
 
 static struct lu_object_operations mdc_obj_ops = {
@@ -101,7 +101,7 @@ static int mdc_object_create(const struct lu_context *ctx,
 
         mci = lu_context_key_get(ctx, &mdc_thread_key);
         LASSERT(mci);
-        
+
         memset(&mci->mci_opdata, 0, sizeof(mci->mci_opdata));
         mci->mci_opdata.fid1 = *lu_object_fid(&mo->mo_lu);
         mci->mci_opdata.mod_time = attr->la_mtime;
index 9cfdc94..5779c8e 100644 (file)
@@ -144,6 +144,16 @@ struct lu_device_operations {
 };
 
 /*
+ * Type of "printer" function used by ->loo_object_print() method.
+ *
+ * Printer function is needed to provide some flexibility in (semi-)debugging
+ * output: possible implementations: printk, CDEBUG, sysfs/seq_file
+ */
+typedef int (*lu_printer_t)(const struct lu_context *ctx,
+                            void *cookie, const char *format, ...)
+        __attribute__ ((format (printf, 3, 4)));
+
+/*
  * Operations specific for particular lu_object.
  */
 struct lu_object_operations {
@@ -187,8 +197,8 @@ struct lu_object_operations {
         /*
          * Debugging helper. Print given object.
          */
-        int (*loo_object_print)(const struct lu_context *ctx,
-                                struct seq_file *f, const struct lu_object *o);
+        int (*loo_object_print)(const struct lu_context *ctx, void *cookie,
+                                lu_printer_t p, const struct lu_object *o);
         /*
          * Optional debugging method. Returns true iff method is internally
          * consistent.
@@ -435,6 +445,7 @@ struct lu_object_header {
 };
 
 struct fld;
+
 /*
  * lu_site is a "compartment" within which objects are unique, and LRU
  * discipline is maintained.
@@ -697,11 +708,41 @@ lu_object_ops(const struct lu_object *o)
 struct lu_object *lu_object_locate(struct lu_object_header *h,
                                    struct lu_device_type *dtype);
 
+struct lu_cdebug_print_info {
+        int         lpi_subsys;
+        int         lpi_mask;
+        const char *lpi_file;
+        const char *lpi_fn;
+        int         lpi_line;
+};
+
+/*
+ * Printer function emitting messages through libcfs_debug_msg().
+ */
+int lu_cdebug_printer(const struct lu_context *ctx,
+                      void *cookie, const char *format, ...);
+
+/*
+ * Print object description followed by user-supplied message.
+ */
+#define LU_OBJECT_DEBUG(mask, ctx, object, format, ...)                 \
+({                                                                      \
+        static struct lu_cdebug_print_info __info = {                   \
+                .lpi_subsys = DEBUG_SUBSYSTEM,                          \
+                .lpi_mask   = (mask),                                   \
+                .lpi_file   = __FILE__,                                 \
+                .lpi_fn     = __FUNCTION__,                             \
+                .lpi_line   = __LINE__                                  \
+        };                                                              \
+        lu_object_print(ctx, &__info, lu_cdebug_printer, object);       \
+        CDEBUG(mask, format , ## __VA_ARGS__);                          \
+})
+
 /*
  * Print human readable representation of the @o to the @f.
  */
-int lu_object_print(const struct lu_context *ctxt,
-                    struct seq_file *f, const struct lu_object *o);
+void lu_object_print(const struct lu_context *ctxt, void *cookie,
+                     lu_printer_t printer, const struct lu_object *o);
 
 /*
  * Check object consistency.
@@ -710,7 +751,7 @@ int lu_object_invariant(const struct lu_object *o);
 
 /*
  * Returns 1 iff object @o exists on the stable storage,
- * returns -1 iif object @o is on remote server.
+ * returns -1 iff object @o is on remote server.
  */
 static inline int lu_object_exists(const struct lu_context *ctx,
                                    const struct lu_object *o)
@@ -719,13 +760,13 @@ static inline int lu_object_exists(const struct lu_context *ctx,
 }
 
 static inline int lu_object_assert_exists(const struct lu_context *ctx,
-                                   const struct lu_object *o)
+                                          const struct lu_object *o)
 {
         return lu_object_exists(ctx, o) != 0;
 }
 
 static inline int lu_object_assert_not_exists(const struct lu_context *ctx,
-                                       const struct lu_object *o)
+                                              const struct lu_object *o)
 {
         return lu_object_exists(ctx, o) <= 0;
 }
@@ -848,4 +889,14 @@ void lu_context_enter(struct lu_context *ctx);
  */
 void lu_context_exit(struct lu_context *ctx);
 
+/*
+ * Initialization of global lu_* data.
+ */
+int lu_global_init(void);
+
+/*
+ * Dual to lu_global_init().
+ */
+void lu_global_fini(void);
+
 #endif /* __LUSTRE_LU_OBJECT_H */
index f97aaa6..20cc4a7 100644 (file)
@@ -1,7 +1,7 @@
 Index: iam/fs/ext3/Makefile
 ===================================================================
---- iam.orig/fs/ext3/Makefile  2006-07-20 18:33:52.000000000 +0400
-+++ iam/fs/ext3/Makefile       2006-07-20 18:33:52.000000000 +0400
+--- iam.orig/fs/ext3/Makefile  2006-07-21 23:12:10.000000000 +0400
++++ iam/fs/ext3/Makefile       2006-07-21 23:12:10.000000000 +0400
 @@ -6,7 +6,7 @@ obj-$(CONFIG_EXT3_FS) += ext3.o
  
  ext3-y        := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
@@ -13,8 +13,8 @@ Index: iam/fs/ext3/Makefile
  ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o
 Index: iam/fs/ext3/dir.c
 ===================================================================
---- iam.orig/fs/ext3/dir.c     2006-07-20 18:33:52.000000000 +0400
-+++ iam/fs/ext3/dir.c  2006-07-20 18:33:52.000000000 +0400
+--- iam.orig/fs/ext3/dir.c     2006-07-21 23:12:10.000000000 +0400
++++ iam/fs/ext3/dir.c  2006-07-21 23:12:10.000000000 +0400
 @@ -28,6 +28,7 @@
  #include <linux/smp_lock.h>
  #include <linux/slab.h>
@@ -112,8 +112,8 @@ Index: iam/fs/ext3/dir.c
                    (filp->f_version != inode->i_version)) {
 Index: iam/fs/ext3/file.c
 ===================================================================
---- iam.orig/fs/ext3/file.c    2006-07-20 18:33:52.000000000 +0400
-+++ iam/fs/ext3/file.c 2006-07-20 18:33:52.000000000 +0400
+--- iam.orig/fs/ext3/file.c    2006-07-21 23:12:10.000000000 +0400
++++ iam/fs/ext3/file.c 2006-07-21 23:12:10.000000000 +0400
 @@ -23,6 +23,7 @@
  #include <linux/jbd.h>
  #include <linux/ext3_fs.h>
@@ -149,7 +149,7 @@ Index: iam/fs/ext3/file.c
 Index: iam/fs/ext3/iam-uapi.c
 ===================================================================
 --- iam.orig/fs/ext3/iam-uapi.c        2004-04-06 17:27:52.000000000 +0400
-+++ iam/fs/ext3/iam-uapi.c     2006-07-20 18:33:52.000000000 +0400
++++ iam/fs/ext3/iam-uapi.c     2006-07-21 23:12:10.000000000 +0400
 @@ -0,0 +1,361 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
@@ -514,8 +514,8 @@ Index: iam/fs/ext3/iam-uapi.c
 +}
 Index: iam/fs/ext3/ioctl.c
 ===================================================================
---- iam.orig/fs/ext3/ioctl.c   2006-07-20 18:33:52.000000000 +0400
-+++ iam/fs/ext3/ioctl.c        2006-07-20 18:33:52.000000000 +0400
+--- iam.orig/fs/ext3/ioctl.c   2006-07-21 23:12:10.000000000 +0400
++++ iam/fs/ext3/ioctl.c        2006-07-21 23:12:10.000000000 +0400
 @@ -250,6 +250,6 @@ flags_err:
  
  
@@ -526,8 +526,8 @@ Index: iam/fs/ext3/ioctl.c
  }
 Index: iam/include/linux/lustre_iam.h
 ===================================================================
---- iam.orig/include/linux/lustre_iam.h        2006-07-20 18:33:52.000000000 +0400
-+++ iam/include/linux/lustre_iam.h     2006-07-20 18:33:52.000000000 +0400
+--- iam.orig/include/linux/lustre_iam.h        2006-07-21 23:12:10.000000000 +0400
++++ iam/include/linux/lustre_iam.h     2006-07-21 23:12:10.000000000 +0400
 @@ -30,9 +30,6 @@
  #ifndef __LINUX_LUSTRE_IAM_H__
  #define __LINUX_LUSTRE_IAM_H__
index aa00a0a..d588915 100644 (file)
@@ -218,10 +218,10 @@ static void mdd_txn_param_build(const struct lu_context *ctx,
         mdd_ctx_info(ctx)->mti_param.tp_credits = opd->mod_credits;
 }
 
-static int mdd_object_print(const struct lu_context *ctxt,
-                            struct seq_file *f, const struct lu_object *o)
+static int mdd_object_print(const struct lu_context *ctxt, void *cookie,
+                            lu_printer_t p, const struct lu_object *o)
 {
-        return seq_printf(f, LUSTRE_MDD0_NAME"-object@%p", o);
+        return (*p)(ctxt, cookie, LUSTRE_MDD0_NAME"-object@%p", o);
 }
 
 static int mdd_object_exists(const struct lu_context *ctx,
index 126a80e..46208ef 100644 (file)
@@ -772,7 +772,7 @@ int fid_lock(struct ldlm_namespace *ns, const struct lu_fid *f,
         return rc == ELDLM_OK ? 0 : -EIO;
 }
 
-/* just call ldlm_lock_decref() if decref, 
+/* just call ldlm_lock_decref() if decref,
  * else we only call ptlrpc_save_lock() to save this lock in req.
  * when transaction committed, req will be released and lock will be released */
 void fid_unlock(struct ptlrpc_request *req, const struct lu_fid *f,
@@ -790,7 +790,7 @@ void fid_unlock(struct ptlrpc_request *req, const struct lu_fid *f,
         }
         if (decref)
                 ldlm_lock_decref(lh, mode);
-        else 
+        else
                 ptlrpc_save_lock(req, lh, mode);
 }
 
@@ -841,7 +841,7 @@ void mdt_object_unlock(struct mdt_thread_info *info, struct mdt_object *o,
         ENTRY;
 
         if (lustre_handle_is_used(&lh->mlh_lh)) {
-                fid_unlock(req, mdt_object_fid(o), 
+                fid_unlock(req, mdt_object_fid(o),
                            &lh->mlh_lh, lh->mlh_mode, decref);
                 lh->mlh_lh.cookie = 0;
         }
@@ -2306,10 +2306,10 @@ static void mdt_object_free(const struct lu_context *ctxt, struct lu_object *o)
         EXIT;
 }
 
-static int mdt_object_print(const struct lu_context *ctxt,
-                            struct seq_file *f, const struct lu_object *o)
+static int mdt_object_print(const struct lu_context *ctxt, void *cookie,
+                            lu_printer_t p, const struct lu_object *o)
 {
-        return seq_printf(f, LUSTRE_MDT0_NAME"-object@%p", o);
+        return (*p)(ctxt, cookie, LUSTRE_MDT0_NAME"-object@%p", o);
 }
 
 int mdt_object_exists(const struct lu_context *ctx,
@@ -2671,18 +2671,24 @@ LPROCFS_INIT_VARS(mdt, lprocfs_mdt_module_vars, lprocfs_mdt_obd_vars);
 
 static int __init mdt_mod_init(void)
 {
+        int result;
         struct lprocfs_static_vars lvars;
 
         mdt_num_threads = MDT_NUM_THREADS;
         lprocfs_init_vars(mdt, &lvars);
-        return class_register_type(&mdt_obd_device_ops, NULL,
-                                   lvars.module_vars, LUSTRE_MDT0_NAME,
-                                   &mdt_device_type);
+        result = lu_global_init();
+        if (result == 0)
+                result = class_register_type(&mdt_obd_device_ops, NULL,
+                                             lvars.module_vars,
+                                             LUSTRE_MDT0_NAME,
+                                             &mdt_device_type);
+        return result;
 }
 
 static void __exit mdt_mod_exit(void)
 {
         class_unregister_type(LUSTRE_MDT0_NAME);
+        lu_global_fini();
 }
 
 
index 670c17a..95be489 100644 (file)
@@ -224,29 +224,136 @@ void lu_site_purge(const struct lu_context *ctx, struct lu_site *s, int nr)
 EXPORT_SYMBOL(lu_site_purge);
 
 /*
- * Print human readable representation of the @o to the @f.
+ * Object printing.
+ *
+ * Code below has to jump through certain loops to output object description
+ * into libcfs_debug_msg-based log. The problem is that lu_object_print()
+ * composes object description from strings that are parts of _lines_ of
+ * output (i.e., strings that are not terminated by newline). This doesn't fit
+ * very well into libcfs_debug_msg() interface that assumes that each message
+ * supplied to it is a self-contained output line.
+ *
+ * To work around this, strings are collected in a temporary buffer
+ * (implemented as a value of lu_cdebug_key key), until terminating newline
+ * character is detected.
+ *
+ */
+
+enum {
+        /*
+         * Maximal line size.
+         *
+         * XXX overflow is not handled correctly.
+         */
+        LU_CDEBUG_LINE = 256
+};
+
+struct lu_cdebug_data {
+        /*
+         * Temporary buffer.
+         */
+        char lck_area[LU_CDEBUG_LINE];
+};
+
+static void *lu_cdebug_key_init(const struct lu_context *ctx,
+                                struct lu_context_key *key)
+{
+        struct lu_cdebug_key *value;
+
+        OBD_ALLOC_PTR(value);
+        if (value == NULL)
+                value = ERR_PTR(-ENOMEM);
+        return value;
+}
+
+static void lu_cdebug_key_fini(const struct lu_context *ctx,
+                               struct lu_context_key *key, void *data)
+{
+        struct lu_cdebug_key *value = data;
+        OBD_FREE_PTR(value);
+}
+
+/*
+ * Key, holding temporary buffer. This key is registered very early by
+ * lu_global_init().
+ */
+static struct lu_context_key lu_cdebug_key = {
+        .lct_tags = LCT_MD_THREAD|LCT_DT_THREAD|LCT_CL_THREAD,
+        .lct_init = lu_cdebug_key_init,
+        .lct_fini = lu_cdebug_key_fini
+};
+
+/*
+ * Printer function emitting messages through libcfs_debug_msg().
+ */
+int lu_cdebug_printer(const struct lu_context *ctx,
+                      void *cookie, const char *format, ...)
+{
+        struct lu_cdebug_print_info *info = cookie;
+        struct lu_cdebug_data       *key;
+        int used;
+        int complete;
+       va_list args;
+
+        va_start(args, format);
+
+        key = lu_context_key_get(ctx, &lu_cdebug_key);
+        LASSERT(key != NULL);
+
+        used = strlen(key->lck_area);
+        complete = format[strlen(format) - 1] == '\n';
+        /*
+         * Append new chunk to the buffer.
+         */
+        vsnprintf(key->lck_area + used,
+                  ARRAY_SIZE(key->lck_area) - used, format, args);
+        if (complete) {
+                libcfs_debug_msg(info->lpi_subsys, info->lpi_mask,
+                                 info->lpi_file, info->lpi_fn,
+                                 info->lpi_line, "%s", key->lck_area);
+                key->lck_area[0] = 0;
+        }
+        va_end(args);
+        return 0;
+}
+EXPORT_SYMBOL(lu_cdebug_printer);
+
+/*
+ * Print object header.
  */
-int lu_object_print(const struct lu_context *ctx,
-                    struct seq_file *f, const struct lu_object *o)
+static void lu_object_header_print(const struct lu_context *ctx,
+                                   void *cookie, lu_printer_t printer,
+                                   const struct lu_object_header *hdr)
 {
-        static char ruler[] = "........................................";
+        (*printer)(ctx, cookie, "header@%p[%#lx, %d, "DFID3"%s%s]",
+                   hdr, hdr->loh_flags, hdr->loh_ref, PFID3(&hdr->loh_fid),
+                   hlist_unhashed(&hdr->loh_hash) ? "" : " hash",
+                   list_empty(&hdr->loh_lru) ? "" : " lru");
+}
+
+/*
+ * Print human readable representation of the @o to the @printer.
+ */
+void lu_object_print(const struct lu_context *ctx, void *cookie,
+                     lu_printer_t printer, const struct lu_object *o)
+{
+        static const char ruler[] = "........................................";
         struct lu_object_header *top;
-        int nob;
         int depth;
 
-        nob = 0;
         top = o->lo_header;
+        lu_object_header_print(ctx, cookie, printer, top);
+        (*printer)(ctx, cookie, "\n");
         list_for_each_entry(o, &top->loh_layers, lo_linkage) {
-                depth = o->lo_depth;
+                depth = o->lo_depth + 4;
                 LASSERT(o->lo_ops->loo_object_print != NULL);
                 /*
                  * print `.' @depth times.
                  */
-                nob += seq_printf(f, "%*.*s", depth, depth, ruler);
-                nob += o->lo_ops->loo_object_print(ctx, f, o);
-                nob += seq_printf(f, "\n");
+                (*printer)(ctx, cookie, "%*.*s", depth, depth, ruler);
+                o->lo_ops->loo_object_print(ctx, cookie, printer, o);
+                (*printer)(ctx, cookie, "\n");
         }
-        return nob;
 }
 EXPORT_SYMBOL(lu_object_print);
 
@@ -714,3 +821,31 @@ void lu_context_exit(struct lu_context *ctx)
 {
 }
 EXPORT_SYMBOL(lu_context_exit);
+
+/*
+ * Initialization of global lu_* data.
+ */
+int lu_global_init(void)
+{
+        static int initialized = 0;
+        int result;
+
+        if (!initialized) {
+                result = lu_context_key_register(&lu_cdebug_key);
+                initialized = 1;
+        } else {
+                CERROR("Double initialization\n");
+                result = 0;
+        }
+        return result;
+}
+EXPORT_SYMBOL(lu_global_init);
+
+/*
+ * Dual to lu_global_init().
+ */
+void lu_global_fini(void)
+{
+        lu_context_key_degister(&lu_cdebug_key);
+}
+EXPORT_SYMBOL(lu_global_fini);