};
static
-const chunk_command close_command_get_post_release_func(
+chunk_command close_command_get_post_release_func(
lttng_trace_chunk_command_type type) {
switch (type) {
case LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED:
}
static
-void fs_handle_untracked_put_fd(struct fs_handle *_handle)
+void fs_handle_untracked_put_fd(struct fs_handle *_handle __attribute__((unused)))
{
/* no-op. */
}
enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK;
const struct chunk_credentials credentials = {
.use_current_user = true,
+ .user = {},
};
pthread_mutex_lock(&chunk->lock);
}
static
-int lttng_trace_chunk_no_operation(struct lttng_trace_chunk *trace_chunk)
+int lttng_trace_chunk_no_operation(struct lttng_trace_chunk *trace_chunk __attribute__((unused)))
{
return 0;
}
struct lttng_trace_chunk_registry_element *element =
container_of(node, typeof(*element), rcu_node);
- lttng_trace_chunk_fini(&element->chunk);
free(element);
}
if (chunk->in_registry_element) {
struct lttng_trace_chunk_registry_element *element;
+ /*
+ * Release internal chunk attributes immediately and
+ * only use the deferred `call_rcu` work to reclaim the
+ * storage.
+ *
+ * This ensures that file handles are released as soon as
+ * possible which works around a problem we encounter with PRAM fs
+ * mounts (and possibly other non-POSIX compliant file systems):
+ * directories that contain files which are open can't be
+ * rmdir().
+ *
+ * This means that the recording of a snapshot could be
+ * completed, but that it would be impossible for the user to
+ * delete it until the deferred clean-up released the file
+ * handles to its contents.
+ */
+ lttng_trace_chunk_fini(chunk);
+
element = container_of(chunk, typeof(*element), chunk);
if (element->registry) {
rcu_read_lock();
struct lttng_trace_chunk *
lttng_trace_chunk_registry_publish_chunk(
struct lttng_trace_chunk_registry *registry,
- uint64_t session_id, struct lttng_trace_chunk *chunk)
+ uint64_t session_id,
+ struct lttng_trace_chunk *chunk)
+{
+ bool unused;
+
+ return lttng_trace_chunk_registry_publish_chunk(
+ registry, session_id, chunk, &unused);
+}
+
+struct lttng_trace_chunk *
+lttng_trace_chunk_registry_publish_chunk(
+ struct lttng_trace_chunk_registry *registry,
+ uint64_t session_id, struct lttng_trace_chunk *chunk,
+ bool *previously_published)
{
struct lttng_trace_chunk_registry_element *element;
unsigned long element_hash;
element->registry = registry;
/* Acquire a reference for the caller. */
if (lttng_trace_chunk_get(&element->chunk)) {
+ *previously_published = false;
break;
} else {
/*
if (lttng_trace_chunk_get(published_chunk)) {
lttng_trace_chunk_put(&element->chunk);
element = published_element;
+ *previously_published = true;
break;
}
/*