From: Yehuda Sadeh Date: Mon, 9 Mar 2009 21:31:42 +0000 (-0700) Subject: kclient: sysfs, add mds name and op of current requests X-Git-Tag: v0.7~10 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2c7a38f0279502d95ec94075205d4bc5c8342166;p=ceph.git kclient: sysfs, add mds name and op of current requests --- diff --git a/src/kernel/mds_client.c b/src/kernel/mds_client.c index 6d7a2dbe140..426ecb19748 100644 --- a/src/kernel/mds_client.c +++ b/src/kernel/mds_client.c @@ -889,7 +889,7 @@ static u64 __get_oldest_tid(struct ceph_mds_client *mdsc) * encode hidden .snap dirs as a double /, i.e. * foo/.snap/bar -> foo//bar */ -static char *build_path(struct dentry *dentry, int *plen, u64 *base, int mds) +char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, int mds) { struct dentry *temp; char *path; @@ -987,12 +987,12 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc, if (path1) pathlen1 = strlen(path1); else if (req->r_dentry) - path1 = build_path(req->r_dentry, &pathlen1, &ino1, + path1 = ceph_mdsc_build_path(req->r_dentry, &pathlen1, &ino1, mds); if (path2) pathlen2 = strlen(path2); else if (req->r_old_dentry) - path2 = build_path(req->r_old_dentry, &pathlen2, &ino2, + path2 = ceph_mdsc_build_path(req->r_old_dentry, &pathlen2, &ino2, mds); pathlen = pathlen1 + pathlen2 + 2*(sizeof(u32) + sizeof(u64)); } @@ -1708,7 +1708,7 @@ retry: dentry = d_find_alias(inode); if (dentry) { - path = build_path(dentry, &pathlen, &pathbase, -1); + path = ceph_mdsc_build_path(dentry, &pathlen, &pathbase, -1); if (IS_ERR(path)) { err = PTR_ERR(path); BUG_ON(err); diff --git a/src/kernel/mds_client.h b/src/kernel/mds_client.h index 0d2dc9d57ab..8b4c2740c2d 100644 --- a/src/kernel/mds_client.h +++ b/src/kernel/mds_client.h @@ -141,12 +141,23 @@ struct ceph_mds_client; typedef void (*ceph_mds_request_callback_t) (struct ceph_mds_client *mdsc, struct ceph_mds_request *req); +struct ceph_mds_request_attr { + struct attribute attr; + ssize_t (*show)(struct ceph_mds_request *, struct ceph_mds_request_attr *, + char *); + ssize_t (*store)(struct ceph_mds_request *, struct ceph_mds_request_attr *, + const char *, size_t); +}; + /* * an in-flight mds request */ struct ceph_mds_request { u64 r_tid; /* transaction id */ + struct kobject kobj; + struct ceph_mds_request_attr k_mds, k_op; + int r_op; struct dentry *r_dentry; struct dentry *r_old_dentry; /* rename from or link from */ @@ -192,8 +203,6 @@ struct ceph_mds_request { ceph_mds_request_callback_t r_callback; struct list_head r_unsafe_item; /* per-session unsafe list item */ bool r_got_unsafe, r_got_safe; - - struct kobject kobj; }; /* @@ -300,5 +309,6 @@ extern void ceph_mdsc_flushed_all_caps(struct ceph_mds_client *mdsc, struct ceph_mds_session *session); extern struct ceph_mds_request *ceph_mdsc_get_listener_req(struct inode *inode, u64 tid); +extern char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, int mds); #endif diff --git a/src/kernel/sysfs.c b/src/kernel/sysfs.c index 655587b52c4..a0d8b9dcd32 100644 --- a/src/kernel/sysfs.c +++ b/src/kernel/sysfs.c @@ -7,45 +7,51 @@ static struct kobject ceph_kobj; /* * default kobject attribute operations. duplicated here from - * kobject.c because kobj_sysfs_ops is not exported to modules. + * kobject.c */ -static ssize_t client_attr_show(struct kobject *kobj, struct attribute *attr, - char *buf) -{ - struct ceph_client_attr *a = - container_of(attr, struct ceph_client_attr, attr); - struct ceph_client *c = container_of(kobj, struct ceph_client, kobj); - ssize_t ret = -EIO; - if (a->show) - ret = a->show(c, a, buf); - return ret; -} +#define DEF_ATTR_OP(name) \ +static ssize_t name##_attr_show(struct kobject *kobj, struct attribute *attr, \ + char *buf) \ +{ \ + struct name##_attr *a = \ + container_of(attr, struct name##_attr, attr); \ + struct name *c = container_of(kobj, struct name, kobj); \ + ssize_t ret = -EIO; \ + \ + if (a->show) \ + ret = a->show(c, a, buf); \ + return ret; \ +} \ + \ +static ssize_t name##_attr_store(struct kobject *kobj, struct attribute *attr, \ + const char *buf, size_t count) \ +{ \ + struct name##_attr *a = container_of(attr, struct name##_attr, attr); \ + struct name *c = container_of(kobj, struct name, kobj); \ + ssize_t ret = -EIO; \ + \ + if (a->store) \ + ret = a->store(c, a, buf, count); \ + return ret; \ +} \ + \ +static struct sysfs_ops name##_sysfs_ops = { \ + .show = name##_attr_show, \ + .store = name##_attr_store, \ +}; \ + \ +static struct kobj_type name##_ops = { \ + .sysfs_ops = &name##_sysfs_ops, \ +}; -static ssize_t client_attr_store(struct kobject *kobj, struct attribute *attr, - const char *buf, size_t count) -{ - struct ceph_client_attr *a = container_of(attr, struct ceph_client_attr, attr); - struct ceph_client *c = container_of(kobj, struct ceph_client, kobj); - ssize_t ret = -EIO; - if (a->store) - ret = a->store(c, a, buf, count); - return ret; -} +DEF_ATTR_OP(ceph_client) -static struct sysfs_ops generic_sysfs_ops = { - .show = client_attr_show, - .store = client_attr_store, -}; /* * per-client attributes */ -static struct kobj_type client_type = { - .sysfs_ops = &generic_sysfs_ops, -}; - #define to_client(c) container_of(c, struct ceph_client, kobj) static ssize_t fsid_show(struct ceph_client *client, @@ -141,8 +147,8 @@ static ssize_t osdmap_show(struct ceph_client *client, return pos; } -static struct kobj_type entity_type = { - .sysfs_ops = &generic_sysfs_ops, +static struct kobj_type entity_ops = { + .sysfs_ops = &ceph_client_sysfs_ops, }; @@ -158,12 +164,12 @@ int ceph_sysfs_client_init(struct ceph_client *client) int ret = 0; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) - ret = kobject_init_and_add(&client->kobj, &client_type, + ret = kobject_init_and_add(&client->kobj, &ceph_client_ops, &ceph_kobj, "client%d", client->whoami); if (ret) goto out; - ret = kobject_init_and_add(&client->mdsc.kobj, &entity_type, + ret = kobject_init_and_add(&client->mdsc.kobj, &entity_ops, &client->kobj, "mdsc"); if (ret) goto out; @@ -187,16 +193,68 @@ void ceph_sysfs_client_cleanup(struct ceph_client *client) #endif } +DEF_ATTR_OP(ceph_mds_request) + +#define ADD_MDS_REQ_ATTR(a, n, m, sh, st) \ + req->a.attr.name = n; \ + req->a.attr.mode = m; \ + req->a.show = sh; \ + req->a.store = st; \ + ret = sysfs_create_file(&req->kobj, &req->a.attr); + +static ssize_t req_mds_show(struct ceph_mds_request *req, + struct ceph_mds_request_attr *attr, char *buf) +{ + return sprintf(buf, "%u.%u.%u.%u:%u (%s%d)\n", + IPQUADPORT(req->r_request->hdr.dst.addr.ipaddr), + ENTITY_NAME(req->r_request->hdr.dst.name)); +} + +static ssize_t req_op_show(struct ceph_mds_request *req, + struct ceph_mds_request_attr *attr, char *buf) +{ + int pos = 0, pathlen; + u64 pathbase; + + char *path; + + pos += sprintf(buf, "%s", ceph_mds_op_name(req->r_op)); + + if (req->r_dentry) { + path = ceph_mdsc_build_path(req->r_dentry, &pathlen, &pathbase, -1); + if (path) + pos += sprintf(buf+pos, " %s", path); + } else if (req->r_path1) { + pos += sprintf(buf+pos, " %s", req->r_path1); + } + + if (req->r_old_dentry) { + path = ceph_mdsc_build_path(req->r_old_dentry, &pathlen, &pathbase, -1); + if (path) + pos += sprintf(buf+pos, " %s", path); + } else if (req->r_path2 && + req->r_op != CEPH_MDS_OP_FINDINODE) { + pos += sprintf(buf+pos, " %s", req->r_path2); + } + + pos += sprintf(buf+pos, "\n"); + + return pos; +} + int ceph_sysfs_mds_req_init(struct ceph_mds_client *mdsc, struct ceph_mds_request *req) { int ret = 0; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) - ret = kobject_init_and_add(&req->kobj, &client_type, + ret = kobject_init_and_add(&req->kobj, &ceph_mds_request_ops, &mdsc->kobj, "%d", req->r_tid); if (ret) goto out; + ADD_MDS_REQ_ATTR(k_mds, "mds", 0400, req_mds_show, NULL); + ADD_MDS_REQ_ATTR(k_op, "op", 0400, req_op_show, NULL); + return 0; out: