#define CEPH_SAN_LOG(fmt, ...) \
ceph_san_log(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
-#endif /* CEPH_SAN_LOGGER_H */
\ No newline at end of file
+#endif /* CEPH_SAN_LOGGER_H */
\ No newline at end of file
int cephsan_pagefrag_init(struct cephsan_pagefrag *pf);
int cephsan_pagefrag_init_with_buffer(struct cephsan_pagefrag *pf, void *buffer, size_t size);
u64 cephsan_pagefrag_alloc(struct cephsan_pagefrag *pf, unsigned int n);
+void *cephsan_pagefrag_get_ptr_from_tail(struct cephsan_pagefrag *pf);
void cephsan_pagefrag_free(struct cephsan_pagefrag *pf, unsigned int n);
void cephsan_pagefrag_deinit(struct cephsan_pagefrag *pf);
+void cephsan_pagefrag_reset(struct cephsan_pagefrag *pf);
void *cephsan_pagefrag_get_ptr(struct cephsan_pagefrag *pf, u64 val);
#define CEPHSAN_PAGEFRAG_GET_N(val) ((val) >> 32)
list_add(&ctx->list, &g_logger.contexts);
spin_unlock(&g_logger.lock);
}
-
+ cephsan_pagefrag_reset(&ctx->pf);
/* Set up TLS */
current->tls.state = ctx;
current->tls.release = ceph_san_tls_release;
struct ceph_san_tls_ctx *ctx;
struct ceph_san_log_entry *entry;
va_list args;
+ u64 alloc;
int len;
ctx = ceph_san_get_tls_ctx();
va_end(args);
/* Allocate entry from pagefrag */ //We need a spinlock here to protect printing
- u64 alloc = cephsan_pagefrag_alloc(&ctx->pf, sizeof(*entry) + len + 1);
- if (!alloc)
- return;
+ alloc = cephsan_pagefrag_alloc(&ctx->pf, sizeof(*entry) + len + 1);
+ while (!alloc) {
+ entry = cephsan_pagefrag_get_ptr_from_tail(&ctx->pf);
+ cephsan_pagefrag_free(&ctx->pf, entry->len);
+ alloc = cephsan_pagefrag_alloc(&ctx->pf, sizeof(*entry) + len + 1);
+ }
entry = cephsan_pagefrag_get_ptr(&ctx->pf, alloc);
/* Copy to entry buffer */
{
/* Case 1: tail > head */
if (pf->tail > pf->head) {
- if (pf->tail - pf->head >= n) {
+ if (pf->tail - pf->head > n) {
unsigned int prev_head = pf->head;
pf->head += n;
return ((u64)n << 32) | prev_head;
} else {
- pr_err("Not enough space in pagefrag buffer\n");
return 0;
}
}
return ((u64)n << 32) | prev_head;
} else {
/* Need to wrap around */
- if (n <= pf->tail) {
+ if (n < pf->tail) {
pf->head = n;
n += CEPHSAN_PAGEFRAG_SIZE - pf->head;
return ((u64)n << 32) | 0;
} else {
- pr_err("Not enough space for wrap-around allocation\n");
return 0;
}
}
}
EXPORT_SYMBOL(cephsan_pagefrag_get_ptr);
+/**
+ * cephsan_pagefrag_get_ptr_from_tail - Get buffer pointer from pagefrag tail
+ * @pf: pagefrag allocator
+ * @n: number of bytes to get pointer from
+ *
+ * Returns pointer to the buffer region at the tail pointer minus @n bytes.
+ */
+void *cephsan_pagefrag_get_ptr_from_tail(struct cephsan_pagefrag *pf)
+{
+ return pf->buffer + pf->tail;
+}
+EXPORT_SYMBOL(cephsan_pagefrag_get_ptr_from_tail);
+
/**
* cephsan_pagefrag_free - Free bytes in the pagefrag allocator.
* @n: number of bytes to free.
pf->head = pf->tail = 0;
}
EXPORT_SYMBOL(cephsan_pagefrag_deinit);
+
+/**
+ * cephsan_pagefrag_reset - Reset the pagefrag allocator.
+ *
+ * Resets the head and tail pointers to the beginning of the buffer.
+ */
+void cephsan_pagefrag_reset(struct cephsan_pagefrag *pf)
+{
+ pf->head = 0;
+ pf->tail = 0;
+}
+EXPORT_SYMBOL(cephsan_pagefrag_reset);