* Returns 0 or a -errno code.
*/
static int
-create_dentry(struct fuse_context *fuse_ctx, const char *path,
- mode_t mode, dev_t rdev, u32 attributes,
- struct wim_dentry **dentry_ret)
+create_file(struct fuse_context *fuse_ctx, const char *path,
+ mode_t mode, dev_t rdev, u32 attributes,
+ struct wim_dentry **dentry_ret)
{
struct wimfs_context *wimfs_ctx = WIMFS_CTX(fuse_ctx);
struct wim_dentry *parent;
filedes_init(&fd->f_staging_fd, raw_fd);
}
- /* Remove the appropriate count of file descriptors and stream
- * references from the old blob. */
- if (old_blob) {
+ if (old_blob)
old_blob->num_opened_fds -= new_blob->num_opened_fds;
- for (u32 i = 0; i < inode->i_nlink; i++)
- blob_decrement_refcnt(old_blob, ctx->wim->blob_table);
- }
- new_blob->refcnt = inode->i_nlink;
new_blob->blob_location = BLOB_IN_STAGING_FILE;
new_blob->staging_file_name = staging_file_name;
new_blob->staging_dir_fd = ctx->staging_dir_fd;
prepare_unhashed_blob(new_blob, inode, strm->stream_id,
&wim_get_current_image_metadata(ctx->wim)->unhashed_blobs);
- stream_set_blob(strm, new_blob);
+ inode_replace_stream_blob(inode, strm, new_blob, ctx->wim->blob_table);
return 0;
out_revert_fd_changes:
struct blob_table *blob_table = ctx->wim->blob_table;
struct blob_descriptor *blob, *tmp;
- list_for_each_entry_safe(blob, tmp, list, orig_blob_list) {
- u32 n = blob->out_refcnt;
- while (n--)
- blob_decrement_refcnt(blob, blob_table);
- }
+ list_for_each_entry_safe(blob, tmp, list, orig_blob_list)
+ blob_subtract_refcnt(blob, blob_table, blob->out_refcnt);
}
/* Delete the 'struct blob_descriptor' for any stream that was modified
new_blob = new_blob_descriptor();
if (!new_blob)
goto err_put_replace_imd;
- new_blob->flags = WIM_RESHDR_FLAG_METADATA;
+
+ new_blob->refcnt = 1;
new_blob->unhashed = 1;
+ new_blob->is_metadata = 1;
/* Make the image being moved available at a new index. Increments the
* WIM's image count, but does not increment the reference count of the
int ret;
/* Note: according to fuse.h, mode may not include S_IFDIR */
- ret = create_dentry(fuse_get_context(), path, mode | S_IFDIR, 0,
- FILE_ATTRIBUTE_DIRECTORY, &dentry);
+ ret = create_file(fuse_get_context(), path, mode | S_IFDIR, 0,
+ FILE_ATTRIBUTE_DIRECTORY, &dentry);
if (ret)
return ret;
touch_parent(dentry);
/* Note: we still use FILE_ATTRIBUTE_NORMAL for device nodes,
* named pipes, and sockets. The real mode is in the UNIX
* metadata. */
- ret = create_dentry(fuse_ctx, path, mode, rdev,
- FILE_ATTRIBUTE_NORMAL, &dentry);
+ ret = create_file(fuse_ctx, path, mode, rdev,
+ FILE_ATTRIBUTE_NORMAL, &dentry);
if (ret)
return ret;
touch_parent(dentry);
{
struct wimfs_context *ctx = wimfs_get_context();
struct wim_inode *inode;
- struct wim_inode_stream *existing_strm;
+ struct wim_inode_stream *strm;
const utf16lechar *uname;
int ret;
if (ret)
return -errno;
- existing_strm = inode_get_stream(inode, STREAM_TYPE_DATA, uname);
- if (existing_strm) {
+ strm = inode_get_stream(inode, STREAM_TYPE_DATA, uname);
+ if (strm) {
ret = -EEXIST;
if (flags & XATTR_CREATE)
goto out_put_uname;
goto out_put_uname;
}
- if (!inode_add_stream_with_data(inode, STREAM_TYPE_DATA, uname,
- value, size, ctx->wim->blob_table))
- {
- ret = -errno;
- goto out_put_uname;
+ if (strm) {
+ if (!inode_replace_stream_data(inode, strm, value, size,
+ ctx->wim->blob_table))
+ {
+ ret = -errno;
+ goto out_put_uname;
+ }
+ } else {
+ if (!inode_add_stream_with_data(inode, STREAM_TYPE_DATA, uname,
+ value, size, ctx->wim->blob_table))
+ {
+ ret = -errno;
+ goto out_put_uname;
+ }
}
- if (existing_strm)
- inode_remove_stream(inode, existing_strm, ctx->wim->blob_table);
+
ret = 0;
out_put_uname:
tstr_put_utf16le(uname);
struct wim_dentry *dentry;
int ret;
- ret = create_dentry(fuse_ctx, from, S_IFLNK | 0777, 0,
- FILE_ATTRIBUTE_REPARSE_POINT, &dentry);
+ ret = create_file(fuse_ctx, from, S_IFLNK | 0777, 0,
+ FILE_ATTRIBUTE_REPARSE_POINT, &dentry);
if (ret)
return ret;
dentry->d_inode->i_reparse_tag = WIM_IO_REPARSE_TAG_SYMLINK;