aboutsummaryrefslogtreecommitdiff
path: root/fs/ceph/decode.h
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/decode.h')
-rw-r--r--fs/ceph/decode.h136
1 files changed, 136 insertions, 0 deletions
diff --git a/fs/ceph/decode.h b/fs/ceph/decode.h
new file mode 100644
index 00000000000..fc2769df062
--- /dev/null
+++ b/fs/ceph/decode.h
@@ -0,0 +1,136 @@
+#ifndef __CEPH_DECODE_H
+#define __CEPH_DECODE_H
+
+#include <asm/unaligned.h>
+
+/*
+ * in all cases,
+ * void **p pointer to position pointer
+ * void *end pointer to end of buffer (last byte + 1)
+ */
+
+/*
+ * bounds check input.
+ */
+#define ceph_decode_need(p, end, n, bad) \
+ do { \
+ if (unlikely(*(p) + (n) > (end))) \
+ goto bad; \
+ } while (0)
+
+#define ceph_decode_64(p, v) \
+ do { \
+ v = get_unaligned_le64(*(p)); \
+ *(p) += sizeof(u64); \
+ } while (0)
+#define ceph_decode_32(p, v) \
+ do { \
+ v = get_unaligned_le32(*(p)); \
+ *(p) += sizeof(u32); \
+ } while (0)
+#define ceph_decode_16(p, v) \
+ do { \
+ v = get_unaligned_le16(*(p)); \
+ *(p) += sizeof(u16); \
+ } while (0)
+#define ceph_decode_8(p, v) \
+ do { \
+ v = *(u8 *)*(p); \
+ (*p)++; \
+ } while (0)
+
+#define ceph_decode_copy(p, pv, n) \
+ do { \
+ memcpy(pv, *(p), n); \
+ *(p) += n; \
+ } while (0)
+
+/* bounds check too */
+#define ceph_decode_64_safe(p, end, v, bad) \
+ do { \
+ ceph_decode_need(p, end, sizeof(u64), bad); \
+ ceph_decode_64(p, v); \
+ } while (0)
+#define ceph_decode_32_safe(p, end, v, bad) \
+ do { \
+ ceph_decode_need(p, end, sizeof(u32), bad); \
+ ceph_decode_32(p, v); \
+ } while (0)
+#define ceph_decode_16_safe(p, end, v, bad) \
+ do { \
+ ceph_decode_need(p, end, sizeof(u16), bad); \
+ ceph_decode_16(p, v); \
+ } while (0)
+
+#define ceph_decode_copy_safe(p, end, pv, n, bad) \
+ do { \
+ ceph_decode_need(p, end, n, bad); \
+ ceph_decode_copy(p, pv, n); \
+ } while (0)
+
+/*
+ * struct ceph_timespec <-> struct timespec
+ */
+#define ceph_decode_timespec(ts, tv) \
+ do { \
+ (ts)->tv_sec = le32_to_cpu((tv)->tv_sec); \
+ (ts)->tv_nsec = le32_to_cpu((tv)->tv_nsec); \
+ } while (0)
+#define ceph_encode_timespec(tv, ts) \
+ do { \
+ (tv)->tv_sec = cpu_to_le32((ts)->tv_sec); \
+ (tv)->tv_nsec = cpu_to_le32((ts)->tv_nsec); \
+ } while (0)
+
+
+/*
+ * encoders
+ */
+#define ceph_encode_64(p, v) \
+ do { \
+ put_unaligned_le64(v, (__le64 *)*(p)); \
+ *(p) += sizeof(u64); \
+ } while (0)
+#define ceph_encode_32(p, v) \
+ do { \
+ put_unaligned_le32(v, (__le32 *)*(p)); \
+ *(p) += sizeof(u32); \
+ } while (0)
+#define ceph_encode_16(p, v) \
+ do { \
+ put_unaligned_le16(v), (__le16 *)*(p)); \
+ *(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,
+ u64 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