static gboolean _getxattr_from_chunk(struct attr_handle_s *attr_handle, GError ** error, const char *attrname, char **result){ ssize_t attr_value_size; if (!result || !attr_handle || !attrname) { SETERRCODE(error, EINVAL, "Invalid parameter"); return -1; } attr_value_size = getxattr(attr_handle->chunk_path, attrname, NULL, 0); if (0 > attr_value_size) { SETERRCODE(error, errno, "Failed to get xattr [%s] from file [%s] : %s", attrname, attr_handle->chunk_path, strerror(errno)); *result = NULL; return FALSE; } else if (0 == attr_value_size) { *result = g_try_malloc0(1); if (*result == NULL) { SETERRCODE(error, ENOMEM, "Memory allocation failure"); return FALSE; } } else { *result = g_try_malloc0(attr_value_size + 1); if (*result == NULL) { SETERRCODE(error, ENOMEM, "Memory allocation failure"); return FALSE; } } getxattr(attr_handle->chunk_path, attrname, *result, attr_value_size); return TRUE; }
static gboolean _set_attr_in_handle(struct attr_handle_s *attr_handle, GError ** error, const char *domain, const char *attrname, const char *attrvalue) { char *k, *v; if (!attr_handle || !domain || !attrname || !attrvalue) { SETERRCODE(error, errno, "Invalid argument"); return FALSE; } k = g_strdup_printf("%s.%s", domain, attrname); v = g_strdup(attrvalue); if (k && v) { g_hash_table_insert(attr_handle->attr_hash, k, v); return TRUE; } else { g_free(k); g_free(v); SETERRCODE(error, ENOMEM, "Memory allocation failure"); return FALSE; } }
static gboolean _load_attr_from_file(const char *chunk_path, struct attr_handle_s** attr_handle, GError ** error){ GError *local_error = NULL; if (!(*attr_handle = _alloc_attr_handle(chunk_path))) { SETERRCODE(error, ENOMEM, "Memory allocation failure"); return FALSE; } /* Try to load attributes from the local file and overwrite with xattr */ _load_from_file_attr(*attr_handle, &local_error); if (local_error) g_clear_error(&local_error); _load_from_xattr(*attr_handle, &local_error); if (local_error) g_clear_error(&local_error); *error = NULL; return TRUE; }
static gboolean _commit_v2_attr_handle(int filedes, struct attr_handle_s *attr_handle, GError ** error) { GError *local_error = NULL; if (attr_handle == NULL) { SETERRCODE(error, EINVAL, "Invalid attr_handle argument"); return FALSE; } /* try to write the chunk extended attributes */ if (filedes >= 0) { if (_write_attributes(attr_handle->attr_hash, filedes, _write_to_xattr, &local_error)) return TRUE; else g_clear_error(&local_error); } return TRUE; }
static gboolean _get_attr_from_handle(struct attr_handle_s *attr_handle, GError ** error, const char *domain, const char *attrname, char **result){ char attr_name_buf[ATTR_NAME_MAX_LENGTH], *value; if (!attr_handle || !domain || !attrname || !result) { SETERRCODE(error, EINVAL, "Invalid argument (%p %p %p %p)", attr_handle, domain, attrname, result); return FALSE; } memset(attr_name_buf, '\0', sizeof(attr_name_buf)); snprintf(attr_name_buf, sizeof(attr_name_buf), "%s.%s", domain, attrname); value = g_hash_table_lookup(attr_handle->attr_hash, attr_name_buf); if (value) { *result = g_strdup(value); return TRUE; } TRACE("Attribute [%s] not found for chunk [%s]", attr_name_buf, attr_handle->chunk_path); *result = NULL; return TRUE; }
static gboolean _get_attr_from_handle(struct attr_handle_s *attr_handle, GError ** error, const char *domain, const char *attrname, gchar **result) { char key[ATTR_NAME_MAX_LENGTH], *value; if (!attr_handle || !domain || !attrname || !result) { SETERRCODE(error, EINVAL, "Invalid argument (%p %p %p %p)", attr_handle, domain, attrname, result); return FALSE; } g_snprintf(key, sizeof(key), "%s.%s", domain, attrname); value = g_hash_table_lookup(attr_handle->attr_hash, key); if (value) *result = g_strdup(value); else { GRID_TRACE("Attribute [%s] not found for chunk [%s]", key, attr_handle->chunk_path); *result = NULL; } return TRUE; }
static gboolean _write_attributes(GHashTable * attr_hash, int file, attr_writer_f writer, GError ** error) { GHashTableIter iterator; gpointer key = NULL, value = NULL; GError *local_error = NULL; if (attr_hash == NULL) { SETERRCODE(error, EINVAL, "Invalid parameter attr_hash"); return FALSE; } g_hash_table_iter_init(&iterator, attr_hash); while (g_hash_table_iter_next(&iterator, &key, &value)) { if (!writer(file, (gchar *) key, (gchar *) value, &local_error)) { SETERROR(error, "%s", local_error->message); g_clear_error(&local_error); return FALSE; } } return TRUE; }