+ struct dentry *dentry;
+ struct ads_entry *existing_ads_entry;
+ struct ads_entry *new_ads_entry;
+ struct lookup_table_entry *existing_lte;
+ struct lookup_table_entry *lte;
+ u8 value_hash[SHA1_HASH_SIZE];
+ int ret;
+ int fd;
+
+ if (!(mount_flags & WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_XATTR))
+ return -ENOTSUP;
+
+ dentry = get_dentry(w, path);
+ if (!dentry)
+ return -ENOENT;
+ existing_ads_entry = dentry_get_ads_entry(dentry, name);
+ if (existing_ads_entry) {
+ if (flags & XATTR_CREATE)
+ return -EEXIST;
+ remove_ads(dentry, existing_ads_entry, w->lookup_table);
+ } else {
+ if (flags & XATTR_REPLACE)
+ return -ENOATTR;
+ }
+ new_ads_entry = dentry_add_ads(dentry, name);
+ if (!new_ads_entry)
+ return -ENOMEM;
+
+ sha1_buffer(value, size, value_hash);
+
+ existing_lte = __lookup_resource(w->lookup_table, value_hash);
+
+ if (existing_lte) {
+ lte = existing_lte;
+ lte->refcnt++;
+ } else {
+ char *value_copy;
+ lte = new_lookup_table_entry();
+ if (!lte)
+ return -ENOMEM;
+ value_copy = MALLOC(size);
+ if (!value_copy) {
+ FREE(lte);
+ return -ENOMEM;
+ }
+ lte->resource_location = RESOURCE_IN_ATTACHED_BUFFER;
+ lte->attached_buffer = value_copy;
+ lte->resource_entry.original_size = size;
+ lte->resource_entry.size = size;
+ lte->resource_entry.flags = 0;
+ copy_hash(lte->hash, value_hash);
+ lookup_table_insert(w->lookup_table, lte);
+ }
+ new_ads_entry->lte = lte;
+ return 0;