return NULL;
inode->security_id = -1;
inode->link_count = 1;
+#ifdef WITH_FUSE
+ inode->next_stream_id = 1;
+#endif
INIT_LIST_HEAD(&inode->dentry_list);
return inode;
}
struct ads_entry *ads_entries;
struct ads_entry *new_entry;
- DEBUG("Add alternate data stream `%s'", stream_name);
+ DEBUG("Add alternate data stream \"%s\"", stream_name);
if (inode->num_ads >= 0xfffe) {
ERROR("Too many alternate data streams in one inode!");
struct ads_entry *ads_entry;
struct lookup_table_entry *lte;
+ wimlib_assert(idx < inode->num_ads);
+ wimlib_assert(inode->resolved);
+
ads_entry = &inode->ads_entries[idx];
- wimlib_assert(ads_entry);
- wimlib_assert(inode->resolved);
+ DEBUG("Remove alternate data stream \"%s\"", ads_entry->stream_name_utf8);
lte = ads_entry->lte;
-
if (lte)
lte_decrement_refcnt(lte, lookup_table);
destroy_ads_entry(ads_entry);
- wimlib_assert(inode->num_ads);
memcpy(&inode->ads_entries[idx],
&inode->ads_entries[idx + 1],
(inode->num_ads - idx - 1) * sizeof(inode->ads_entries[0]));
* reference count reaches 0, it is unlinked from the lookup table. If,
* furthermore, the entry has no opened file descriptors associated with it, the
* entry is freed. */
-struct lookup_table_entry *
-lte_decrement_refcnt(struct lookup_table_entry *lte, struct lookup_table *table)
+void lte_decrement_refcnt(struct lookup_table_entry *lte,
+ struct lookup_table *table)
{
wimlib_assert(lte);
wimlib_assert(lte->refcnt);
#ifdef WITH_FUSE
if (lte->num_opened_fds == 0)
#endif
- {
finalize_lte(lte);
- lte = NULL;
- }
}
- return lte;
}
#ifdef WITH_FUSE
-struct lookup_table_entry *
-lte_decrement_num_opened_fds(struct lookup_table_entry *lte,
- struct lookup_table *table)
+void lte_decrement_num_opened_fds(struct lookup_table_entry *lte,
+ struct lookup_table *table)
{
- if (lte) {
- wimlib_assert(lte->num_opened_fds);
- if (--lte->num_opened_fds == 0 && lte->refcnt == 0) {
- lookup_table_unlink(table, lte);
- finalize_lte(lte);
- lte = NULL;
- }
- }
- return lte;
+ wimlib_assert(lte);
+ wimlib_assert(lte->num_opened_fds);
+ if (--lte->num_opened_fds == 0 && lte->refcnt == 0)
+ finalize_lte(lte);
}
#endif
table->num_entries--;
}
-
-extern struct lookup_table_entry *
-lookup_table_decrement_refcnt(struct lookup_table* table, const u8 hash[]);
-
-#ifdef WITH_FUSE
-extern struct lookup_table_entry *
-lte_decrement_num_opened_fds(struct lookup_table_entry *lte,
- struct lookup_table *table);
-#endif
-
-extern struct lookup_table_entry *
-lte_decrement_refcnt(struct lookup_table_entry *lte,
- struct lookup_table *table);
-
-
extern struct lookup_table_entry *new_lookup_table_entry();
extern int for_lookup_table_entry(struct lookup_table *table,
struct lookup_table_entry **lte_ret,
u16 *stream_idx_ret);
+extern void lte_decrement_refcnt(struct lookup_table_entry *lte,
+ struct lookup_table *table);
+extern void lte_decrement_num_opened_fds(struct lookup_table_entry *lte,
+ struct lookup_table *table);
+
extern int lte_zero_out_refcnt(struct lookup_table_entry *entry, void *ignore);
extern int lte_zero_real_refcnt(struct lookup_table_entry *entry, void *ignore);
extern int lte_free_extracted_file(struct lookup_table_entry *lte, void *ignone);
return 0;
/* Close staging file descriptor if needed. */
- wimlib_assert(lte->num_opened_fds);
if (lte->resource_location == RESOURCE_IN_STAGING_FILE
&& fd->staging_fd != -1)
int fd;
struct lookup_table_entry *old_lte, *new_lte;
+ DEBUG("Extracting resource to staging dir: inode %"PRIu64", "
+ "stream id %"PRIu32, inode->ino, stream_id);
+
old_lte = *lte;
fd = create_staging_file(&staging_file_name, O_WRONLY);
if (fd == -1)
size_t size)
{
int ret;
- struct dentry *dentry;
+ struct inode *inode;
struct ads_entry *ads_entry;
size_t res_size;
struct lookup_table_entry *lte;
return -ENOATTR;
name += 5;
- dentry = get_dentry(w, path);
- if (!dentry)
+ inode = wim_pathname_to_inode(w, path);
+ if (!inode)
return -ENOENT;
- ads_entry = inode_get_ads_entry(dentry->d_inode, name, NULL);
+
+ ads_entry = inode_get_ads_entry(inode, name, NULL);
if (!ads_entry)
return -ENOATTR;
if (size == 0)
return res_size;
+
if (res_size > size)
return -ERANGE;
+
ret = read_full_wim_resource(lte, (u8*)value);
if (ret != 0)
return -EIO;
+
return res_size;
}
#endif
#ifdef ENABLE_XATTR
static int wimfs_listxattr(const char *path, char *list, size_t size)
{
- struct dentry *dentry;
int ret;
- char *p = list;
size_t needed_size;
unsigned i;
struct inode *inode;
+
if (!(mount_flags & WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_XATTR))
return -ENOTSUP;
/* List alternate data streams, or get the list size */
- ret = lookup_resource(w, path, get_lookup_flags(), &dentry, NULL, NULL);
- if (ret != 0)
- return ret;
- inode = dentry->d_inode;
+ inode = wim_pathname_to_inode(w, path);
+ if (!inode)
+ return -ENOENT;
if (size == 0) {
needed_size = 0;
needed_size += inode->ads_entries[i].stream_name_utf8_len + 6;
return needed_size;
} else {
+ char *p = list;
for (i = 0; i < inode->num_ads; i++) {
needed_size = inode->ads_entries[i].stream_name_utf8_len + 6;
if (needed_size > size)
&& (stream_name = path_stream_name(path))) {
/* Make an alternate data stream */
struct ads_entry *new_entry;
- struct dentry *dentry;
+ struct inode *inode;
char *p = (char*)stream_name - 1;
wimlib_assert(*p == ':');
*p = '\0';
- dentry = get_dentry(w, path);
- if (!dentry || !dentry_is_regular_file(dentry))
+ inode = wim_pathname_to_inode(w, path);
+ if (!inode)
+ return -ENOENT;
+ if (!inode_is_regular_file(inode))
return -ENOENT;
- if (inode_get_ads_entry(dentry->d_inode, stream_name, NULL))
+ if (inode_get_ads_entry(inode, stream_name, NULL))
return -EEXIST;
- new_entry = inode_add_ads(dentry->d_inode, stream_name);
+ new_entry = inode_add_ads(inode, stream_name);
if (!new_entry)
- return -ENOENT;
+ return -ENOMEM;
} else {
struct dentry *dentry, *parent;
const char *basename;
/* Remove an alternate data stream through the XATTR interface */
static int wimfs_removexattr(const char *path, const char *name)
{
- struct dentry *dentry;
+ struct inode *inode;
struct ads_entry *ads_entry;
u16 ads_idx;
if (!(mount_flags & WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_XATTR))
return -ENOATTR;
name += 5;
- dentry = get_dentry(w, path);
- if (!dentry)
+ inode = wim_pathname_to_inode(w, path);
+ if (!inode)
return -ENOENT;
- ads_entry = inode_get_ads_entry(dentry->d_inode, name, &ads_idx);
+ ads_entry = inode_get_ads_entry(inode, name, &ads_idx);
if (!ads_entry)
return -ENOATTR;
- inode_remove_ads(dentry->d_inode, ads_idx, w->lookup_table);
+ inode_remove_ads(inode, ads_idx, w->lookup_table);
return 0;
}
#endif
lte->attached_buffer = symlink_buf;
lte->resource_entry.original_size = symlink_buf_len;
lte->resource_entry.size = symlink_buf_len;
- lte->resource_entry.flags = 0;
copy_hash(lte->hash, symlink_buf_hash);
}