mdd->mdd_txn_cb.dtc_txn_commit = mdd_txn_commit_cb;
mdd->mdd_txn_cb.dtc_cookie = mdd;
INIT_LIST_HEAD(&mdd->mdd_txn_cb.dtc_linkage);
+ mdd->mdd_atime_diff = MAX_ATIME_DIFF;
+
rc = mdd_procfs_init(mdd, name);
RETURN(rc);
}
/* context key: mdd_thread_key */
LU_CONTEXT_KEY_DEFINE(mdd, LCT_MD_THREAD);
-struct lprocfs_vars lprocfs_mdd_obd_vars[] = {
- { 0 }
-};
-
-struct lprocfs_vars lprocfs_mdd_module_vars[] = {
- { 0 }
-};
-
-static void lprocfs_mdd_init_vars(struct lprocfs_static_vars *lvars)
-{
- lvars->module_vars = lprocfs_mdd_module_vars;
- lvars->obd_vars = lprocfs_mdd_obd_vars;
-}
-
static int __init mdd_mod_init(void)
{
struct lprocfs_static_vars lvars;
cfs_proc_dir_entry_t *mdd_proc_entry;
struct lprocfs_stats *mdd_stats;
struct mdd_txn_op_descr mdd_tod[MDD_TXN_LAST_OP];
+ unsigned long mdd_atime_diff;
};
enum mod_flags {
void orph_index_fini(const struct lu_env *env, struct mdd_device *mdd);
int mdd_txn_init_credits(const struct lu_env *env, struct mdd_device *mdd);
+/* mdd_lproc.c */
+void lprocfs_mdd_init_vars(struct lprocfs_static_vars *lvars);
int mdd_procfs_init(struct mdd_device *mdd, const char *name);
int mdd_procfs_fini(struct mdd_device *mdd);
void mdd_lprocfs_time_start(const struct lu_env *env);
struct mdd_object *mdd_object_find(const struct lu_env *env,
struct mdd_device *d,
const struct lu_fid *f);
+
/* mdd_permission.c */
#define mdd_cap_t(x) (x)
ci->mc_capa[offset] = capa;
}
+#define MAX_ATIME_DIFF 60
+
enum {
LPROC_MDD_NR
};
int mdd_procfs_init(struct mdd_device *mdd, const char *name)
{
+ struct lprocfs_static_vars lvars;
struct lu_device *ld = &mdd->mdd_md_dev.md_lu_dev;
struct obd_type *type;
int rc;
LASSERT(type != NULL);
/* Find the type procroot and add the proc entry for this device */
+ lprocfs_mdd_init_vars(&lvars);
mdd->mdd_proc_entry = lprocfs_register(name, type->typ_procroot,
- NULL, NULL);
+ lvars.obd_vars, mdd);
if (IS_ERR(mdd->mdd_proc_entry)) {
rc = PTR_ERR(mdd->mdd_proc_entry);
CERROR("Error %d setting up lprocfs for %s\n",
{
lu_lprocfs_time_end(env, mdd->mdd_stats, idx);
}
+
+static int lprocfs_wr_atime_diff(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ struct mdd_device *mdd = data;
+ char kernbuf[20], *end;
+ unsigned long diff = 0;
+
+ if (count > (sizeof(kernbuf) - 1))
+ return -EINVAL;
+
+ if (copy_from_user(kernbuf, buffer, count))
+ return -EFAULT;
+
+ kernbuf[count] = '\0';
+
+ diff = simple_strtoul(kernbuf, &end, 0);
+ if (kernbuf == end)
+ return -EINVAL;
+
+ mdd->mdd_atime_diff = diff;
+ return count;
+}
+
+static int lprocfs_rd_atime_diff(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ struct mdd_device *mdd = data;
+
+ *eof = 1;
+ return snprintf(page, count, "%lu\n", mdd->mdd_atime_diff);
+}
+
+static struct lprocfs_vars lprocfs_mdd_obd_vars[] = {
+ { "atime_diff", lprocfs_rd_atime_diff, lprocfs_wr_atime_diff, 0 },
+ { 0 }
+};
+
+static struct lprocfs_vars lprocfs_mdd_module_vars[] = {
+ { "num_refs", lprocfs_rd_numrefs, 0, 0 },
+ { 0 }
+};
+
+void lprocfs_mdd_init_vars(struct lprocfs_static_vars *lvars)
+{
+ lvars->module_vars = lprocfs_mdd_module_vars;
+ lvars->obd_vars = lprocfs_mdd_obd_vars;
+}
if (la->la_valid == LA_ATIME) {
/* This is atime only set for read atime update on close. */
- if (la->la_atime <= tmp_la->la_atime + 0/*XXX:mds_atime_diff*/)
+ if (la->la_atime <= tmp_la->la_atime +
+ mdd_obj2mdd_dev(obj)->mdd_atime_diff)
la->la_valid &= ~LA_ATIME;
RETURN(0);
}
{
struct txn_param *p = &mdd_env_info(env)->mti_param;
struct thandle *th;
-
+
th = mdd_child_ops(mdd)->dt_trans_start(env, mdd->mdd_child, p);
return th;
}
MODULES := osd
-osd-objs := osd_handler.o osd_oi.o osd_igif.o
+osd-objs := osd_handler.o osd_oi.o osd_igif.o osd_lproc.o
EXTRA_PRE_CFLAGS := -I@LINUX@/fs -I@LDISKFS_DIR@ -I@LDISKFS_DIR@/ldiskfs
#include <obd_support.h>
/* struct ptlrpc_thread */
#include <lustre_net.h>
-/* LUSTRE_OSD_NAME */
-#include <obd.h>
-/* class_register_type(), class_unregister_type(), class_get_type() */
-#include <obd_class.h>
-#include <lustre_disk.h>
/* fid_is_local() */
#include <lustre_fid.h>
#endif
};
-/*
- * osd device.
- */
-struct osd_device {
- /* super-class */
- struct dt_device od_dt_dev;
- /* information about underlying file system */
- struct lustre_mount_info *od_mount;
- /* object index */
- struct osd_oi od_oi;
- /*
- * XXX temporary stuff for object index: directory where every object
- * is named by its fid.
- */
- struct dentry *od_obj_area;
-
- /* Environment for transaction commit callback.
- * Currently, OSD is based on ext3/JBD. Transaction commit in ext3/JBD
- * is serialized, that is there is no more than one transaction commit
- * at a time (JBD journal_commit_transaction() is serialized).
- * This means that it's enough to have _one_ lu_context.
- */
- struct lu_env od_env_for_commit;
-
- /*
- * Fid Capability
- */
- unsigned int od_fl_capa:1;
- unsigned long od_capa_timeout;
- __u32 od_capa_alg;
- struct lustre_capa_key *od_capa_keys;
- struct hlist_head *od_capa_hash;
-
- /*
- * statfs optimization: we cache a bit.
- */
- cfs_time_t od_osfs_age;
- struct kstatfs od_kstatfs;
- spinlock_t od_osfs_lock;
-};
-
static int osd_root_get (const struct lu_env *env,
struct dt_device *dev, struct lu_fid *f);
-static int osd_statfs (const struct lu_env *env,
- struct dt_device *dev, struct kstatfs *sfs);
static int lu_device_is_osd (const struct lu_device *d);
static void osd_mod_exit (void) __exit;
static struct lu_device_type osd_device_type;
static struct lu_object_operations osd_lu_obj_ops;
static struct obd_ops osd_obd_device_ops;
-static struct lprocfs_vars lprocfs_osd_module_vars[];
-static struct lprocfs_vars lprocfs_osd_obd_vars[];
static struct lu_device_operations osd_lu_ops;
static struct lu_context_key osd_key;
static struct dt_object_operations osd_obj_ops;
/*
* Concurrency: shouldn't matter.
*/
-static int osd_statfs(const struct lu_env *env,
- struct dt_device *d, struct kstatfs *sfs)
+int osd_statfs(const struct lu_env *env, struct dt_device *d,
+ struct kstatfs *sfs)
{
struct osd_device *osd = osd_dt_dev(d);
struct super_block *sb = osd_sb(osd);
static int osd_device_init(const struct lu_env *env, struct lu_device *d,
const char *name, struct lu_device *next)
{
- return lu_context_init(&osd_dev(d)->od_env_for_commit.le_ctx,
- LCT_MD_THREAD);
+ int rc;
+ /* context for commit hooks */
+ rc = lu_context_init(&osd_dev(d)->od_env_for_commit.le_ctx,
+ LCT_MD_THREAD);
+ if (rc == 0)
+ rc = osd_procfs_init(osd_dev(d), name);
+ return rc;
}
static int osd_shutdown(const struct lu_env *env, struct osd_device *o)
static struct lu_device *osd_device_fini(const struct lu_env *env,
struct lu_device *d)
{
+ int rc;
ENTRY;
shrink_dcache_sb(osd_sb(osd_dev(d)));
osd_sync(env, lu2dt_dev(d));
+ rc = osd_procfs_fini(osd_dev(d));
+ if (rc) {
+ CERROR("proc fini error %d \n", rc);
+ RETURN (ERR_PTR(rc));
+ }
+
if (osd_dev(d)->od_mount)
server_put_mount(osd_dev(d)->od_mount->lmi_name,
osd_dev(d)->od_mount->lmi_mnt);
/*
* lprocfs legacy support.
*/
-static struct lprocfs_vars lprocfs_osd_obd_vars[] = {
- { 0 }
-};
-
-static struct lprocfs_vars lprocfs_osd_module_vars[] = {
- { 0 }
-};
-
static struct obd_ops osd_obd_device_ops = {
.o_owner = THIS_MODULE
};
-static void lprocfs_osd_init_vars(struct lprocfs_static_vars *lvars)
-{
- lvars->module_vars = lprocfs_osd_module_vars;
- lvars->obd_vars = lprocfs_osd_obd_vars;
-}
-
-
static int __init osd_mod_init(void)
{
struct lprocfs_static_vars lvars;
#include <linux/dcache.h>
#include <linux/lustre_iam.h>
+/* LUSTRE_OSD_NAME */
+#include <obd.h>
+/* class_register_type(), class_unregister_type(), class_get_type() */
+#include <obd_class.h>
+#include <lustre_disk.h>
+
#include <dt_object.h>
#include "osd_oi.h"
#define OSD_COUNTERS (0)
+/*
+ * osd device.
+ */
+struct osd_device {
+ /* super-class */
+ struct dt_device od_dt_dev;
+ /* information about underlying file system */
+ struct lustre_mount_info *od_mount;
+ /* object index */
+ struct osd_oi od_oi;
+ /*
+ * XXX temporary stuff for object index: directory where every object
+ * is named by its fid.
+ */
+ struct dentry *od_obj_area;
+
+ /* Environment for transaction commit callback.
+ * Currently, OSD is based on ext3/JBD. Transaction commit in ext3/JBD
+ * is serialized, that is there is no more than one transaction commit
+ * at a time (JBD journal_commit_transaction() is serialized).
+ * This means that it's enough to have _one_ lu_context.
+ */
+ struct lu_env od_env_for_commit;
+
+ /*
+ * Fid Capability
+ */
+ unsigned int od_fl_capa:1;
+ unsigned long od_capa_timeout;
+ __u32 od_capa_alg;
+ struct lustre_capa_key *od_capa_keys;
+ struct hlist_head *od_capa_hash;
+
+ cfs_proc_dir_entry_t *od_proc_entry;
+ struct lprocfs_stats *od_stats;
+ /*
+ * statfs optimization: we cache a bit.
+ */
+ cfs_time_t od_osfs_age;
+ struct kstatfs od_kstatfs;
+ spinlock_t od_osfs_lock;
+};
+
+
struct osd_thread_info {
const struct lu_env *oti_env;
#endif
};
+#ifdef LPROCFS
+/* osd_lproc.c */
+void lprocfs_osd_init_vars(struct lprocfs_static_vars *lvars);
+int osd_procfs_init(struct osd_device *osd, const char *name);
+int osd_procfs_fini(struct osd_device *osd);
+void osd_lprocfs_time_start(const struct lu_env *env);
+void osd_lprocfs_time_end(const struct lu_env *env,
+ struct osd_device *osd, int op);
+#endif
+int osd_statfs(const struct lu_env *env, struct dt_device *dev,
+ struct kstatfs *sfs);
+
#endif /* __KERNEL__ */
#endif /* _OSD_INTERNAL_H */
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2008 Sun Microsystems, Inc. All rights reserved.
+ * Author: Mikhail Pershin <tappro@sun.com>
+ *
+ * This file is part of the Lustre file system, http://www.lustre.org
+ * Lustre is a trademark of Cluster File Systems, Inc.
+ *
+ * You may have signed or agreed to another license before downloading
+ * this software. If so, you are bound by the terms and conditions
+ * of that agreement, and the following does not apply to you. See the
+ * LICENSE file included with this distribution for more information.
+ *
+ * If you did not agree to a different license, then this copy of Lustre
+ * is open source software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In either case, Lustre is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * license text for more details.
+ *
+ */
+#define DEBUG_SUBSYSTEM S_CLASS
+
+#include <lprocfs_status.h>
+#include <lu_time.h>
+
+#include <lustre/lustre_idl.h>
+
+#include "osd_internal.h"
+
+#ifdef LPROCFS
+enum {
+ LPROC_OSD_NR
+};
+
+static const char *osd_counter_names[LPROC_OSD_NR] = {
+};
+
+int osd_procfs_init(struct osd_device *osd, const char *name)
+{
+ struct lprocfs_static_vars lvars;
+ struct lu_device *ld = &osd->od_dt_dev.dd_lu_dev;
+ struct obd_type *type;
+ int rc;
+ ENTRY;
+
+ type = ld->ld_type->ldt_obd_type;
+
+ LASSERT(name != NULL);
+ LASSERT(type != NULL);
+
+ /* Find the type procroot and add the proc entry for this device */
+ lprocfs_osd_init_vars(&lvars);
+ osd->od_proc_entry = lprocfs_register(name, type->typ_procroot,
+ lvars.obd_vars, osd);
+ if (IS_ERR(osd->od_proc_entry)) {
+ rc = PTR_ERR(osd->od_proc_entry);
+ CERROR("Error %d setting up lprocfs for %s\n",
+ rc, name);
+ osd->od_proc_entry = NULL;
+ GOTO(out, rc);
+ }
+
+ rc = lu_time_init(&osd->od_stats,
+ osd->od_proc_entry,
+ osd_counter_names, ARRAY_SIZE(osd_counter_names));
+ EXIT;
+out:
+ if (rc)
+ osd_procfs_fini(osd);
+ return rc;
+}
+
+int osd_procfs_fini(struct osd_device *osd)
+{
+ if (osd->od_stats)
+ lu_time_fini(&osd->od_stats);
+
+ if (osd->od_proc_entry) {
+ lprocfs_remove(&osd->od_proc_entry);
+ osd->od_proc_entry = NULL;
+ }
+ RETURN(0);
+}
+
+void osd_lprocfs_time_start(const struct lu_env *env)
+{
+ lu_lprocfs_time_start(env);
+}
+
+void osd_lprocfs_time_end(const struct lu_env *env, struct osd_device *osd,
+ int idx)
+{
+ lu_lprocfs_time_end(env, osd->od_stats, idx);
+}
+
+
+
+int lprocfs_osd_rd_blksize(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ struct osd_device *osd = data;
+ int rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
+ if (!rc) {
+ *eof = 1;
+ rc = snprintf(page, count, "%ld\n", osd->od_kstatfs.f_bsize);
+ }
+ return rc;
+}
+
+int lprocfs_osd_rd_kbytestotal(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ struct osd_device *osd = data;
+ int rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
+ if (!rc) {
+ __u32 blk_size = osd->od_kstatfs.f_bsize >> 10;
+ __u64 result = osd->od_kstatfs.f_blocks;
+
+ while (blk_size >>= 1)
+ result <<= 1;
+
+ *eof = 1;
+ rc = snprintf(page, count, LPU64"\n", result);
+ }
+ return rc;
+}
+
+int lprocfs_osd_rd_kbytesfree(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ struct osd_device *osd = data;
+ int rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
+ if (!rc) {
+ __u32 blk_size = osd->od_kstatfs.f_bsize >> 10;
+ __u64 result = osd->od_kstatfs.f_bfree;
+
+ while (blk_size >>= 1)
+ result <<= 1;
+
+ *eof = 1;
+ rc = snprintf(page, count, LPU64"\n", result);
+ }
+ return rc;
+}
+
+int lprocfs_osd_rd_kbytesavail(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ struct osd_device *osd = data;
+ int rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
+ if (!rc) {
+ __u32 blk_size = osd->od_kstatfs.f_bsize >> 10;
+ __u64 result = osd->od_kstatfs.f_bavail;
+
+ while (blk_size >>= 1)
+ result <<= 1;
+
+ *eof = 1;
+ rc = snprintf(page, count, LPU64"\n", result);
+ }
+ return rc;
+}
+
+int lprocfs_osd_rd_filestotal(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ struct osd_device *osd = data;
+ int rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
+ if (!rc) {
+ *eof = 1;
+ rc = snprintf(page, count, LPU64"\n", osd->od_kstatfs.f_files);
+ }
+
+ return rc;
+}
+
+int lprocfs_osd_rd_filesfree(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ struct osd_device *osd = data;
+ int rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
+ if (!rc) {
+ *eof = 1;
+ rc = snprintf(page, count, LPU64"\n", osd->od_kstatfs.f_ffree);
+ }
+ return rc;
+}
+
+int lprocfs_osd_rd_fstype(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ struct obd_device *osd = data;
+
+ LASSERT(osd != NULL);
+ return snprintf(page, count, "ldiskfs\n");
+}
+
+static int lprocfs_osd_rd_mntdev(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ struct osd_device *osd = data;
+
+ LASSERT(osd != NULL);
+ LASSERT(osd->od_mount->lmi_mnt->mnt_devname);
+ *eof = 1;
+
+ return snprintf(page, count, "%s\n",
+ osd->od_mount->lmi_mnt->mnt_devname);
+}
+
+struct lprocfs_vars lprocfs_osd_obd_vars[] = {
+ { "blocksize", lprocfs_osd_rd_blksize, 0, 0 },
+ { "kbytestotal", lprocfs_osd_rd_kbytestotal, 0, 0 },
+ { "kbytesfree", lprocfs_osd_rd_kbytesfree, 0, 0 },
+ { "kbytesavail", lprocfs_osd_rd_kbytesavail, 0, 0 },
+ { "filestotal", lprocfs_osd_rd_filestotal, 0, 0 },
+ { "filesfree", lprocfs_osd_rd_filesfree, 0, 0 },
+ { "fstype", lprocfs_osd_rd_fstype, 0, 0 },
+ { "mntdev", lprocfs_osd_rd_mntdev, 0, 0 },
+ { 0 }
+};
+
+struct lprocfs_vars lprocfs_osd_module_vars[] = {
+ { "num_refs", lprocfs_rd_numrefs, 0, 0 },
+ { 0 }
+};
+
+void lprocfs_osd_init_vars(struct lprocfs_static_vars *lvars)
+{
+ lvars->module_vars = lprocfs_osd_module_vars;
+ lvars->obd_vars = lprocfs_osd_obd_vars;
+}
+#endif