Unverified Commit 220cf049 authored by Konstantin Komarov's avatar Konstantin Komarov
Browse files

fs/ntfs3: Simplify initialization of $AttrDef and $UpCase



Replaced the two loops reading $AttrDef and $UpCase with
the inode_read_data() function.

Signed-off-by: default avatarKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
parent 487f8d48
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -1097,6 +1097,34 @@ int ntfs_flush_inodes(struct super_block *sb, struct inode *i1,
	return ret;
}

/*
 * Helper function to read file.
 */
int inode_read_data(struct inode *inode, void *data, size_t bytes)
{
	pgoff_t idx;
	struct address_space *mapping = inode->i_mapping;

	for (idx = 0; bytes; idx++) {
		size_t op = bytes > PAGE_SIZE ? PAGE_SIZE : bytes;
		struct page *page = read_mapping_page(mapping, idx, NULL);
		void *kaddr;

		if (IS_ERR(page))
			return PTR_ERR(page);

		kaddr = kmap_atomic(page);
		memcpy(data, kaddr, op);
		kunmap_atomic(kaddr);

		put_page(page);

		bytes -= op;
		data = Add2Ptr(data, PAGE_SIZE);
	}
	return 0;
}

/*
 * ntfs_reparse_bytes
 *
+1 −16
Original line number Diff line number Diff line
@@ -716,6 +716,7 @@ int ntfs3_write_inode(struct inode *inode, struct writeback_control *wbc);
int ntfs_sync_inode(struct inode *inode);
int ntfs_flush_inodes(struct super_block *sb, struct inode *i1,
		      struct inode *i2);
int inode_read_data(struct inode *inode, void *data, size_t bytes);
int ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir,
		      struct dentry *dentry, const struct cpu_str *uni,
		      umode_t mode, dev_t dev, const char *symname, u32 size,
@@ -909,22 +910,6 @@ static inline bool ntfs_is_meta_file(struct ntfs_sb_info *sbi, CLST rno)
	       rno == sbi->usn_jrnl_no;
}

static inline void ntfs_unmap_page(struct page *page)
{
	kunmap(page);
	put_page(page);
}

static inline struct page *ntfs_map_page(struct address_space *mapping,
					 unsigned long index)
{
	struct page *page = read_mapping_page(mapping, index, NULL);

	if (!IS_ERR(page))
		kmap(page);
	return page;
}

static inline size_t wnd_zone_bit(const struct wnd_bitmap *wnd)
{
	return wnd->zone_bit;
+23 −37
Original line number Diff line number Diff line
@@ -1163,7 +1163,7 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
	CLST vcn, lcn, len;
	struct ATTRIB *attr;
	const struct VOLUME_INFO *info;
	u32 idx, done, bytes;
	u32 done, bytes;
	struct ATTR_DEF_ENTRY *t;
	u16 *shared;
	struct MFT_REF ref;
@@ -1435,31 +1435,22 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
		goto put_inode_out;
	}

	for (done = idx = 0; done < bytes; done += PAGE_SIZE, idx++) {
		unsigned long tail = bytes - done;
		struct page *page = ntfs_map_page(inode->i_mapping, idx);

		if (IS_ERR(page)) {
			err = PTR_ERR(page);
	/* Read the entire file. */
	err = inode_read_data(inode, sbi->def_table, bytes);
	if (err) {
		ntfs_err(sb, "Failed to read $AttrDef (%d).", err);
		goto put_inode_out;
	}
		memcpy(Add2Ptr(t, done), page_address(page),
		       min(PAGE_SIZE, tail));
		ntfs_unmap_page(page);

		if (!idx && ATTR_STD != t->type) {
	if (ATTR_STD != t->type) {
		ntfs_err(sb, "$AttrDef is corrupted.");
		err = -EINVAL;
		goto put_inode_out;
	}
	}

	t += 1;
	sbi->def_entries = 1;
	done = sizeof(struct ATTR_DEF_ENTRY);
	sbi->reparse.max_size = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
	sbi->ea_max_size = 0x10000; /* default formatter value */

	while (done + sizeof(struct ATTR_DEF_ENTRY) <= bytes) {
		u32 t32 = le32_to_cpu(t->type);
@@ -1495,27 +1486,22 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
		goto put_inode_out;
	}

	for (idx = 0; idx < (0x10000 * sizeof(short) >> PAGE_SHIFT); idx++) {
		const __le16 *src;
		u16 *dst = Add2Ptr(sbi->upcase, idx << PAGE_SHIFT);
		struct page *page = ntfs_map_page(inode->i_mapping, idx);

		if (IS_ERR(page)) {
			err = PTR_ERR(page);
	/* Read the entire file. */
	err = inode_read_data(inode, sbi->upcase, 0x10000 * sizeof(short));
	if (err) {
		ntfs_err(sb, "Failed to read $UpCase (%d).", err);
		goto put_inode_out;
	}

		src = page_address(page);

#ifdef __BIG_ENDIAN
		for (i = 0; i < PAGE_SIZE / sizeof(u16); i++)
	{
		const __le16 *src = sbi->upcase;
		u16 *dst = sbi->upcase;

		for (i = 0; i < 0x10000; i++)
			*dst++ = le16_to_cpu(*src++);
#else
		memcpy(dst, src, PAGE_SIZE);
#endif
		ntfs_unmap_page(page);
	}
#endif

	shared = ntfs_set_shared(sbi->upcase, 0x10000 * sizeof(short));
	if (shared && sbi->upcase != shared) {