u32 attr_len;
int err = 0;
char *kattr;
+ struct page *ipage;
if (NInoAttr(ni))
base_ni = ni->ext.base_ntfs_ino;
kattr = (u8 *)ctx->attr + le16_to_cpu(ctx->attr->data.resident.value_offset);
- iomap->inline_data = kmemdup(kattr, attr_len, GFP_KERNEL);
- if (!iomap->inline_data) {
+ ipage = alloc_page(GFP_NOFS | __GFP_ZERO);
+ if (!ipage) {
err = -ENOMEM;
goto out;
}
+ memcpy(page_address(ipage), kattr, attr_len);
iomap->type = IOMAP_INLINE;
+ iomap->inline_data = page_address(ipage);
iomap->offset = 0;
iomap->length = attr_len;
+ iomap->private = ipage;
out:
if (ctx)
static int ntfs_read_iomap_end(struct inode *inode, loff_t pos, loff_t length,
ssize_t written, unsigned int flags, struct iomap *iomap)
{
- if (iomap->type == IOMAP_INLINE)
- kfree(iomap->inline_data);
+ if (iomap->type == IOMAP_INLINE) {
+ struct page *ipage = iomap->private;
+
+ put_page(ipage);
+ }
return written;
}
u32 attr_len;
int err = 0;
char *kattr;
+ struct page *ipage;
ctx = ntfs_attr_get_search_ctx(ni, NULL);
if (!ctx) {
attr_len = le32_to_cpu(a->data.resident.value_length);
kattr = (u8 *)a + le16_to_cpu(a->data.resident.value_offset);
- iomap->inline_data = kmemdup(kattr, attr_len, GFP_KERNEL);
- if (!iomap->inline_data) {
+ ipage = alloc_page(GFP_NOFS | __GFP_ZERO);
+ if (!ipage) {
err = -ENOMEM;
goto out;
}
+ memcpy(page_address(ipage), kattr, attr_len);
iomap->type = IOMAP_INLINE;
+ iomap->inline_data = page_address(ipage);
iomap->offset = 0;
/* iomap requires there is only one INLINE_DATA extent */
iomap->length = attr_len;
+ iomap->private = ipage;
out:
if (ctx)
u32 attr_len;
int err;
char *kattr;
+ struct page *ipage = iomap->private;
mutex_lock(&ni->mrec_lock);
ctx = ntfs_attr_get_search_ctx(ni, NULL);
mark_mft_record_dirty(ctx->ntfs_ino);
err_out:
ntfs_attr_put_search_ctx(ctx);
- kfree(iomap->inline_data);
+ put_page(ipage);
mutex_unlock(&ni->mrec_lock);
return written;