From 607e6d979c1d929849eba59a7d28e86786924811 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 18 Mar 2008 16:22:28 -0700 Subject: [PATCH] client: switched over to new encode/decode macros --- src/TODO | 5 -- src/kernel/decode.h | 69 +++++++++++++++++++++ src/kernel/inode.c | 9 ++- src/kernel/mds_client.c | 129 +++++++++++++++++----------------------- src/kernel/messenger.h | 94 ----------------------------- src/kernel/osd_client.c | 46 +++++++------- 6 files changed, 152 insertions(+), 200 deletions(-) diff --git a/src/TODO b/src/TODO index 7657bc0b18752..f6722aefcb0a9 100644 --- a/src/TODO +++ b/src/TODO @@ -7,11 +7,6 @@ code cleanup kernel client - make sure link/unlink results reflected by inode/dentry cache (let fill_trace do it? invalidate? do actual update?) -- finish switching over to new decode macros in decode.h - - mds_client.c - - osd_client.c - - inode.c - - remove old messenger.h ones - procfs/debugfs - adjust granular debug levels too - should we be using debugfs? diff --git a/src/kernel/decode.h b/src/kernel/decode.h index 82ead5e5951da..f981ef42ccbef 100644 --- a/src/kernel/decode.h +++ b/src/kernel/decode.h @@ -60,4 +60,73 @@ ceph_decode_copy(p, pv, n); \ } while (0) +/* + * struct ceph_timeval <-> struct timespec + */ +#define ceph_decode_timespec(ts, tv) \ + do { \ + (ts)->tv_sec = le32_to_cpu((tv)->tv_sec); \ + (ts)->tv_nsec = 1000*le32_to_cpu((tv)->tv_usec); \ + } while (0) +#define ceph_encode_timespec(tv, ts, usec) \ + do { \ + usec = (ts)->tv_nsec; \ + do_div(usec, 1000); \ + (tv)->tv_sec = cpu_to_le32((ts)->tv_sec); \ + (tv)->tv_usec = cpu_to_le32(usec); \ + } while (0) + + +/* + * encoders + */ + +#define ceph_encode_64(p, v) \ + do { \ + *(__u64*)*(p) = cpu_to_le64((v)); \ + *(p) += sizeof(__u64); \ + } while (0) +#define ceph_encode_32(p, v) \ + do { \ + *(__u32*)*(p) = cpu_to_le32((v)); \ + *(p) += sizeof(__u32); \ + } while (0) +#define ceph_encode_16(p, v) \ + do { \ + *(__u16*)*(p) = cpu_to_le16((v)); \ + *(p) += sizeof(__u16); \ + } while (0) +#define ceph_encode_8(p, v) \ + do { \ + *(__u8*)*(p) = v; \ + (*(p))++; \ + } while (0) + +/* + * filepath, string encoders + */ + +static __inline__ void ceph_encode_filepath(void **p, void *end, + ceph_ino_t ino, const char *path) +{ + __u32 len = path ? strlen(path):0; + BUG_ON(*p + sizeof(ino) + sizeof(len) + len > end); + ceph_encode_64(p, ino); + ceph_encode_32(p, len); + if (len) + memcpy(*p, path, len); + *p += len; +} + +static __inline__ void ceph_encode_string(void **p, void *end, + const char *s, __u32 len) +{ + BUG_ON(*p + sizeof(len) + len > end); + ceph_encode_32(p, len); + if (len) + memcpy(*p, s, len); + *p += len; +} + + #endif diff --git a/src/kernel/inode.c b/src/kernel/inode.c index c6526a0616a3f..3458cd187ab5a 100644 --- a/src/kernel/inode.c +++ b/src/kernel/inode.c @@ -12,6 +12,7 @@ int ceph_inode_debug = 50; #define DOUT_VAR ceph_inode_debug #define DOUT_PREFIX "inode: " #include "super.h" +#include "decode.h" const struct inode_operations ceph_symlink_iops; @@ -615,7 +616,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) const unsigned int ia_valid = attr->ia_valid; struct ceph_mds_request *req; struct ceph_mds_request_head *reqh; - int err; + int usectmp, err; /* gratuitous debug output */ if (ia_valid & ATTR_UID) @@ -680,8 +681,10 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) if (IS_ERR(req)) return PTR_ERR(req); reqh = req->r_request->front.iov_base; - ceph_encode_timespec(&reqh->args.utime.mtime, &attr->ia_mtime); - ceph_encode_timespec(&reqh->args.utime.atime, &attr->ia_atime); + ceph_encode_timespec(&reqh->args.utime.mtime, &attr->ia_mtime, + usectmp); + ceph_encode_timespec(&reqh->args.utime.atime, &attr->ia_atime, + usectmp); err = ceph_mdsc_do_request(mdsc, req); ceph_mdsc_put_request(req); dout(10, "utime result %d\n", err); diff --git a/src/kernel/mds_client.c b/src/kernel/mds_client.c index a7df63604f707..9d411e085631a 100644 --- a/src/kernel/mds_client.c +++ b/src/kernel/mds_client.c @@ -10,6 +10,7 @@ int ceph_debug_mdsc = 50; #define DOUT_PREFIX "mds: " #include "super.h" #include "messenger.h" +#include "decode.h" /* * note: this also appears in messages/MClientRequest.h, @@ -55,17 +56,17 @@ static void send_msg_mds(struct ceph_mds_client *mdsc, struct ceph_msg *msg, int parse_reply_info_in(void **p, void *end, struct ceph_mds_reply_info_in *info) { - int err; + int err = -EINVAL; info->in = *p; *p += sizeof(struct ceph_mds_reply_inode) + sizeof(__u32)*le32_to_cpu(info->in->fragtree.nsplits); - if ((err == ceph_decode_32(p, end, &info->symlink_len)) < 0) - return err; + ceph_decode_32_safe(p, end, info->symlink_len, bad); + ceph_decode_need(p, end, info->symlink_len, bad); info->symlink = *p; *p += info->symlink_len; - if (unlikely(*p > end)) - return -EINVAL; return 0; +bad: + return err; } int parse_reply_info_trace(void **p, void *end, @@ -74,9 +75,7 @@ int parse_reply_info_trace(void **p, void *end, __u32 numi; int err = -EINVAL; - err = ceph_decode_32(p, end, &numi); - if (err < 0) - goto bad; + ceph_decode_32_safe(p, end, numi, bad); if (numi == 0) goto done; /* hrm, this shouldn't actually happen, but.. */ @@ -87,8 +86,9 @@ int parse_reply_info_trace(void **p, void *end, sizeof(*info->trace_dname) + sizeof(*info->trace_dname_len)), GFP_KERNEL); - if (info->trace_in == NULL) - return -ENOMEM; + if (info->trace_in == NULL) + goto badmem; + info->trace_dir = (void *)(info->trace_in + numi); info->trace_dname = (void *)(info->trace_dir + numi); info->trace_dname_len = (void *)(info->trace_dname + numi); @@ -101,13 +101,10 @@ int parse_reply_info_trace(void **p, void *end, if (--numi == 0) break; /* dentry */ - err = ceph_decode_32(p, end, &info->trace_dname_len[numi]); - if (err < 0) - goto bad; + ceph_decode_32_safe(p, end, info->trace_dname_len[numi], bad); + ceph_decode_need(p, end, info->trace_dname_len[numi], bad); info->trace_dname[numi] = *p; *p += info->trace_dname_len[numi]; - if (*p > end) - goto bad; /* dir */ info->trace_dir[numi] = *p; *p += sizeof(struct ceph_mds_reply_dirfrag) + @@ -117,10 +114,12 @@ int parse_reply_info_trace(void **p, void *end, } done: - if (*p != end) + if (unlikely(*p != end)) return -EINVAL; return 0; +badmem: + err = -ENOMEM; bad: derr(1, "problem parsing trace %d\n", err); return err; @@ -138,9 +137,7 @@ int parse_reply_info_dir(void **p, void *end, struct ceph_mds_reply_info *info) if (*p > end) goto bad; - err = ceph_decode_32(p, end, &num); - if (err < 0) - goto bad; + ceph_decode_32_safe(p, end, num, bad); if (num == 0) goto done; @@ -151,19 +148,16 @@ int parse_reply_info_dir(void **p, void *end, struct ceph_mds_reply_info *info) sizeof(*info->dir_dname_len)), GFP_KERNEL); if (info->dir_in == NULL) - return -ENOMEM; + goto badmem; info->dir_dname = (void *)(info->dir_in + num); info->dir_dname_len = (void *)(info->dir_dname + num); while (num) { /* dentry, inode */ - err = ceph_decode_32(p, end, &info->dir_dname_len[i]); - if (err < 0) - goto bad; + ceph_decode_32_safe(p, end, info->dir_dname_len[i], bad); + ceph_decode_need(p, end, info->dir_dname_len[i], bad); info->dir_dname[i] = *p; *p += info->dir_dname_len[i]; - if (*p > end) - goto bad; err = parse_reply_info_in(p, end, &info->dir_in[i]); if (err < 0) goto bad; @@ -174,6 +168,8 @@ int parse_reply_info_dir(void **p, void *end, struct ceph_mds_reply_info *info) done: return 0; +badmem: + err = -ENOMEM; bad: derr(1, "problem parsing dir contents %d\n", err); return err; @@ -191,24 +187,16 @@ int parse_reply_info(struct ceph_msg *msg, struct ceph_mds_reply_info *info) /* trace */ p = msg->front.iov_base + sizeof(struct ceph_mds_reply_head); end = p + msg->front.iov_len; - err = ceph_decode_32(&p, end, &len); - if (err < 0) - goto bad; + ceph_decode_32_safe(&p, end, len, bad); if (len > 0) { - if (p + len > end) - goto bad; err = parse_reply_info_trace(&p, p+len, info); if (err < 0) goto bad; } /* dir content */ - err = ceph_decode_32(&p, end, &len); - if (err < 0) - goto bad; + ceph_decode_32_safe(&p, end, len, bad); if (len > 0) { - if (p + len > end) - goto bad; err = parse_reply_info_dir(&p, p+len, info); if (err < 0) goto bad; @@ -914,21 +902,16 @@ void ceph_mdsc_handle_forward(struct ceph_mds_client *mdsc, __u64 tid; __u32 next_mds; __u32 fwd_seq; - int err; + int err = -EINVAL; void *p = msg->front.iov_base; void *end = p + msg->front.iov_len; int frommds = le32_to_cpu(msg->hdr.src.name.num); /* decode */ - err = ceph_decode_64(&p, end, &tid); - if (err != 0) - goto bad; - err = ceph_decode_32(&p, end, &next_mds); - if (err != 0) - goto bad; - err = ceph_decode_32(&p, end, &fwd_seq); - if (err != 0) - goto bad; + ceph_decode_need(&p, end, sizeof(__u64)+2*sizeof(__u32), bad); + ceph_decode_64(&p, tid); + ceph_decode_32(&p, next_mds); + ceph_decode_32(&p, fwd_seq); /* handle */ req = find_request_and_lock(mdsc, tid); @@ -1010,6 +993,7 @@ void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) struct ceph_inode_cap *cap; char *path; int pathlen, err; + int usectmp; struct dentry *dentry; struct ceph_inode_info *ci; struct ceph_mds_cap_reconnect *rec; @@ -1048,57 +1032,45 @@ retry: end = p + len; if (!session) { - ceph_encode_8(&p, end, 1); /* session was closed */ - ceph_encode_32(&p, end, 0); + ceph_encode_8(&p, 1); /* session was closed */ + ceph_encode_32(&p, 0); goto send; } dout(10, "session %p state %d\n", session, session->s_state); /* traverse this session's caps */ spin_lock(&session->s_cap_lock); - ceph_encode_8(&p, end, 0); - ceph_encode_32(&p, end, session->s_nr_caps); + ceph_encode_8(&p, 0); + ceph_encode_32(&p, session->s_nr_caps); count = 0; list_for_each(cp, &session->s_caps) { cap = list_entry(cp, struct ceph_inode_cap, session_caps); ci = cap->ci; - if (p + sizeof(u64) + - sizeof(struct ceph_mds_cap_reconnect) > end) - goto needmore; + ceph_decode_need(&p, end, sizeof(u64) + + sizeof(struct ceph_mds_cap_reconnect), + needmore); dout(10, " adding cap %p on ino %llx inode %p\n", cap, ceph_ino(&ci->vfs_inode), &ci->vfs_inode); - ceph_encode_64(&p, end, ceph_ino(&ci->vfs_inode)); + ceph_encode_64(&p, ceph_ino(&ci->vfs_inode)); rec = p; p += sizeof(*rec); BUG_ON(p > end); rec->wanted = cpu_to_le32(ceph_caps_wanted(ci)); rec->issued = cpu_to_le32(ceph_caps_issued(ci)); rec->size = cpu_to_le64(ci->i_wr_size); - ceph_encode_timespec(&rec->mtime, &ci->vfs_inode.i_mtime); - ceph_encode_timespec(&rec->atime, &ci->vfs_inode.i_atime); + ceph_encode_timespec(&rec->mtime, &ci->vfs_inode.i_mtime, usectmp); + ceph_encode_timespec(&rec->atime, &ci->vfs_inode.i_atime, usectmp); dentry = d_find_alias(&ci->vfs_inode); path = ceph_build_dentry_path(dentry, &pathlen); if (IS_ERR(path)) { err = PTR_ERR(path); BUG_ON(err); } - if (p + pathlen + 4 > end) - goto needmore; + ceph_decode_need(&p, end, pathlen+4, needmore); ceph_encode_string(&p, end, path, pathlen); kfree(path); dput(dentry); count++; - continue; - -needmore: - newlen = len * (session->s_nr_caps+1); - do_div(newlen, (count+1)); - dout(30, "i guessed %d, and did %d of %d, retrying with %d\n", - len, count, session->s_nr_caps, newlen); - len = newlen; - spin_unlock(&session->s_cap_lock); - ceph_msg_put(reply); - goto retry; } spin_unlock(&session->s_cap_lock); @@ -1122,6 +1094,16 @@ send: } return; +needmore: + newlen = len * (session->s_nr_caps+1); + do_div(newlen, (count+1)); + dout(30, "i guessed %d, and did %d of %d, retrying with %d\n", + len, count, session->s_nr_caps, newlen); + len = newlen; + spin_unlock(&session->s_cap_lock); + ceph_msg_put(reply); + goto retry; + bad: spin_lock(&mdsc->lock); derr(0, "error %d generating reconnect. what to do?\n", err); @@ -1454,20 +1436,15 @@ void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, struct ceph_msg *msg) { ceph_epoch_t epoch; __u32 maplen; - int err; void *p = msg->front.iov_base; void *end = p + msg->front.iov_len; struct ceph_mdsmap *newmap, *oldmap; int from = le32_to_cpu(msg->hdr.src.name.num); int newstate; - err = ceph_decode_32(&p, end, &epoch); - if (err != 0) - goto bad; - err = ceph_decode_32(&p, end, &maplen); - if (err != 0) - goto bad; - + ceph_decode_need(&p, end, 2*sizeof(__u32), bad); + ceph_decode_32(&p, epoch); + ceph_decode_32(&p, maplen); dout(2, "handle_map epoch %u len %d\n", epoch, (int)maplen); /* do we need it? */ diff --git a/src/kernel/messenger.h b/src/kernel/messenger.h index 54836f8f0e102..69088971cf414 100644 --- a/src/kernel/messenger.h +++ b/src/kernel/messenger.h @@ -137,98 +137,4 @@ extern void ceph_msg_put(struct ceph_msg *msg); extern int ceph_msg_send(struct ceph_messenger *msgr, struct ceph_msg *msg, unsigned long timeout); - -/* encoding/decoding helpers */ - -static __inline__ int ceph_decode_64(void **p, void *end, __u64 *v) { - if (unlikely(*p + sizeof(*v) > end)) - return -EINVAL; - *v = le64_to_cpu(*(__u64*)*p); - *p += sizeof(*v); - return 0; -} -static __inline__ int ceph_decode_32(void **p, void *end, __u32 *v) { - if (unlikely(*p + sizeof(*v) > end)) - return -EINVAL; - *v = le32_to_cpu(*(__u32*)*p); - *p += sizeof(*v); - return 0; -} -static __inline__ int ceph_decode_16(void **p, void *end, __u16 *v) { - if (unlikely(*p + sizeof(*v) > end)) - return -EINVAL; - *v = le16_to_cpu(*(__u16*)*p); - *p += sizeof(*v); - return 0; -} -static __inline__ int ceph_decode_copy(void **p, void *end, void *v, int len) { - if (unlikely(*p + len > end)) - return -EINVAL; - memcpy(v, *p, len); - *p += len; - return 0; -} - -static __inline__ int ceph_encode_64(void **p, void *end, __u64 v) { - BUG_ON(*p + sizeof(v) > end); - *(__u64*)*p = cpu_to_le64(v); - *p += sizeof(v); - return 0; -} - -static __inline__ int ceph_encode_32(void **p, void *end, __u32 v) { - BUG_ON(*p + sizeof(v) > end); - *(__u32*)*p = cpu_to_le32(v); - *p += sizeof(v); - return 0; -} - -static __inline__ int ceph_encode_16(void **p, void *end, __u16 v) { - BUG_ON(*p + sizeof(v) > end); - *(__u16*)*p = cpu_to_le16(v); - *p += sizeof(v); - return 0; -} - -static __inline__ int ceph_encode_8(void **p, void *end, __u8 v) { - BUG_ON(*p >= end); - *(__u8*)*p = v; - (*p)++; - return 0; -} - -static __inline__ int ceph_encode_filepath(void **p, void *end, ceph_ino_t ino, const char *path) -{ - __u32 len = path ? strlen(path):0; - BUG_ON(*p + sizeof(ino) + sizeof(len) + len > end); - ceph_encode_64(p, end, ino); - ceph_encode_32(p, end, len); - if (len) memcpy(*p, path, len); - *p += len; - return 0; -} - -static __inline__ int ceph_encode_string(void **p, void *end, const char *s, __u32 len) -{ - BUG_ON(*p + sizeof(len) + len > end); - ceph_encode_32(p, end, len); - if (len) memcpy(*p, s, len); - *p += len; - return 0; -} - -static __inline__ void ceph_decode_timespec(struct timespec *ts, struct ceph_timeval *tv) -{ - ts->tv_sec = le32_to_cpu(tv->tv_sec); - ts->tv_nsec = 1000*le32_to_cpu(tv->tv_usec); -} -static __inline__ int ceph_encode_timespec(struct ceph_timeval *tv, struct timespec *ts) -{ - int usec = ts->tv_nsec; - do_div(usec, 1000); - tv->tv_sec = cpu_to_le32(ts->tv_sec); - tv->tv_usec = cpu_to_le32(usec); - return 0; -} - #endif diff --git a/src/kernel/osd_client.c b/src/kernel/osd_client.c index 1ea3f10a3338f..199c503d15462 100644 --- a/src/kernel/osd_client.c +++ b/src/kernel/osd_client.c @@ -13,6 +13,7 @@ int ceph_debug_osdc = 50; #include "osd_client.h" #include "messenger.h" #include "crush/mapper.h" +#include "decode.h" struct ceph_readdesc { struct ceph_osd_client *osdc; @@ -54,18 +55,18 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) end = p + msg->front.iov_len; /* incremental maps */ - if ((err = ceph_decode_32(&p, end, &nr_maps)) < 0) - goto bad; + ceph_decode_32_safe(&p, end, nr_maps, bad); dout(10, " %d inc maps\n", nr_maps); while (nr_maps--) { - if ((err = ceph_decode_32(&p, end, &epoch)) < 0) - goto bad; - if ((err = ceph_decode_32(&p, end, &maplen)) < 0) - goto bad; + ceph_decode_need(&p, end, 2*sizeof(__u32), bad); + ceph_decode_32(&p, epoch); + ceph_decode_32(&p, maplen); + ceph_decode_need(&p, end, maplen, bad); next = p + maplen; if (osdc->osdmap && osdc->osdmap->epoch+1 == epoch) { - dout(10, "applying incremental map %u len %d\n", epoch, maplen); - newmap = apply_incremental(p, min(p+maplen,end), osdc->osdmap); + dout(10, "applying incremental map %u len %d\n", + epoch, maplen); + newmap = apply_incremental(&p, p+maplen, osdc->osdmap); if (IS_ERR(newmap)) { err = PTR_ERR(newmap); goto bad; @@ -83,29 +84,30 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) goto out; /* full maps */ - if ((err = ceph_decode_32(&p, end, &nr_maps)) < 0) - goto bad; + ceph_decode_32_safe(&p, end, nr_maps, bad); dout(30, " %d full maps\n", nr_maps); while (nr_maps > 1) { - if ((err = ceph_decode_32(&p, end, &epoch)) < 0) - goto bad; - if ((err = ceph_decode_32(&p, end, &maplen)) < 0) - goto bad; - dout(5, "skipping non-latest full map %u len %d\n", epoch, maplen); + ceph_decode_need(&p, end, 2*sizeof(__u32), bad); + ceph_decode_32(&p, epoch); + ceph_decode_32(&p, maplen); + ceph_decode_need(&p, end, maplen, bad); + dout(5, "skipping non-latest full map %u len %d\n", + epoch, maplen); p += maplen; } if (nr_maps) { - if ((err = ceph_decode_32(&p, end, &epoch)) < 0) - goto bad; - if ((err = ceph_decode_32(&p, end, &maplen)) < 0) - goto bad; + ceph_decode_need(&p, end, 2*sizeof(__u32), bad); + ceph_decode_32(&p, epoch); + ceph_decode_32(&p, maplen); + ceph_decode_need(&p, end, maplen, bad); if (osdc->osdmap && osdc->osdmap->epoch >= epoch) { - dout(10, "skipping full map %u len %d, older than our %u\n", - epoch, maplen, osdc->osdmap->epoch); + dout(10, "skipping full map %u len %d, " + "older than our %u\n", epoch, maplen, + osdc->osdmap->epoch); p += maplen; } else { dout(10, "taking full map %u len %d\n", epoch, maplen); - newmap = osdmap_decode(&p, min(p+maplen,end)); + newmap = osdmap_decode(&p, p+maplen); if (IS_ERR(newmap)) { err = PTR_ERR(newmap); goto bad; -- 2.39.5