Commit 737db367 authored by Anton Altaparmakov's avatar Anton Altaparmakov

NTFS: Minor bug fix in attribute list attribute handling that fixes the

I/O errors on "ls" of certain fragmented files found by at least two
people running Windows XP.
parent ec004d58
...@@ -272,6 +272,10 @@ ChangeLog ...@@ -272,6 +272,10 @@ ChangeLog
Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
2.1.5:
- Minor bug fix in attribute list attribute handling that fixes the
I/O errors on "ls" of certain fragmented files found by at least two
people running Windows XP.
2.1.4: 2.1.4:
- Minor update allowing compilation with all gcc versions (well, the - Minor update allowing compilation with all gcc versions (well, the
ones the kernel can be compiled with anyway). ones the kernel can be compiled with anyway).
......
...@@ -20,6 +20,14 @@ ToDo: ...@@ -20,6 +20,14 @@ ToDo:
sufficient for synchronisation here. We then just need to make sure sufficient for synchronisation here. We then just need to make sure
ntfs_readpage/writepage/truncate interoperate properly with us. ntfs_readpage/writepage/truncate interoperate properly with us.
2.1.5 - Fix minor bug in attribute list attribute handling.
- Fix bug in attribute list handling. Actually it is not as much a bug
as too much protection in that we were not allowing attribute lists
which waste space on disk while Windows XP clearly allows it and in
fact creates such attribute lists so our driver was failing.
- Update NTFS documentation ready for 2.6 kernel release.
2.1.4 - Reduce compiler requirements. 2.1.4 - Reduce compiler requirements.
- Remove all uses of unnamed structs and unions in the driver to make - Remove all uses of unnamed structs and unions in the driver to make
......
...@@ -5,7 +5,7 @@ obj-$(CONFIG_NTFS_FS) += ntfs.o ...@@ -5,7 +5,7 @@ obj-$(CONFIG_NTFS_FS) += ntfs.o
ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \ ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \
mst.o namei.o super.o sysctl.o time.o unistr.o upcase.o mst.o namei.o super.o sysctl.o time.o unistr.o upcase.o
EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.4\" EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.5\"
ifeq ($(CONFIG_NTFS_DEBUG),y) ifeq ($(CONFIG_NTFS_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG EXTRA_CFLAGS += -DDEBUG
......
...@@ -1215,7 +1215,7 @@ BOOL find_attr(const ATTR_TYPES type, const uchar_t *name, const u32 name_len, ...@@ -1215,7 +1215,7 @@ BOOL find_attr(const ATTR_TYPES type, const uchar_t *name, const u32 name_len,
* load_attribute_list - load an attribute list into memory * load_attribute_list - load an attribute list into memory
* @vol: ntfs volume from which to read * @vol: ntfs volume from which to read
* @run_list: run list of the attribute list * @run_list: run list of the attribute list
* @al: destination buffer * @al_start: destination buffer
* @size: size of the destination buffer in bytes * @size: size of the destination buffer in bytes
* @initialized_size: initialized size of the attribute list * @initialized_size: initialized size of the attribute list
* *
...@@ -1227,10 +1227,11 @@ BOOL find_attr(const ATTR_TYPES type, const uchar_t *name, const u32 name_len, ...@@ -1227,10 +1227,11 @@ BOOL find_attr(const ATTR_TYPES type, const uchar_t *name, const u32 name_len,
* *
* Return 0 on success or -errno on error. * Return 0 on success or -errno on error.
*/ */
int load_attribute_list(ntfs_volume *vol, run_list *run_list, u8 *al, int load_attribute_list(ntfs_volume *vol, run_list *run_list, u8 *al_start,
const s64 size, const s64 initialized_size) const s64 size, const s64 initialized_size)
{ {
LCN lcn; LCN lcn;
u8 *al = al_start;
u8 *al_end = al + initialized_size; u8 *al_end = al + initialized_size;
run_list_element *rl; run_list_element *rl;
struct buffer_head *bh; struct buffer_head *bh;
...@@ -1284,32 +1285,28 @@ int load_attribute_list(ntfs_volume *vol, run_list *run_list, u8 *al, ...@@ -1284,32 +1285,28 @@ int load_attribute_list(ntfs_volume *vol, run_list *run_list, u8 *al,
} }
if (initialized_size < size) { if (initialized_size < size) {
initialize: initialize:
memset(al + initialized_size, 0, size - initialized_size); memset(al_start + initialized_size, 0, size - initialized_size);
} }
done: done:
up_read(&run_list->lock); up_read(&run_list->lock);
return err; return err;
do_final: do_final:
if (al < al_end) { if (al < al_end) {
/* Partial block. */
memcpy(al, bh->b_data, al_end - al);
brelse(bh);
/* /*
* Skip sanity checking if initialized_size < size as it is * Partial block.
* too much trouble. *
* Note: The attribute list can be smaller than its allocation
* by multiple clusters. This has been encountered by at least
* two people running Windows XP, thus we cannot do any
* truncation sanity checking here. (AIA)
*/ */
memcpy(al, bh->b_data, al_end - al);
brelse(bh);
if (initialized_size < size) if (initialized_size < size)
goto initialize; goto initialize;
/* If the final lcn is partial all is fine. */ goto done;
if (((s64)(block - (lcn << vol->cluster_size_bits >> }
block_size_bits)) << block_size_bits >> brelse(bh);
vol->cluster_size_bits) == rl->length - 1) {
if (!rl[1].length || (rl[1].lcn == LCN_RL_NOT_MAPPED
&& !rl[2].length))
goto done;
}
} else
brelse(bh);
/* Real overflow! */ /* Real overflow! */
ntfs_error(sb, "Attribute list buffer overflow. Read attribute list " ntfs_error(sb, "Attribute list buffer overflow. Read attribute list "
"is truncated."); "is truncated.");
......
...@@ -87,7 +87,7 @@ BOOL lookup_attr(const ATTR_TYPES type, const uchar_t *name, const u32 name_len, ...@@ -87,7 +87,7 @@ BOOL lookup_attr(const ATTR_TYPES type, const uchar_t *name, const u32 name_len,
const IGNORE_CASE_BOOL ic, const VCN lowest_vcn, const u8 *val, const IGNORE_CASE_BOOL ic, const VCN lowest_vcn, const u8 *val,
const u32 val_len, attr_search_context *ctx); const u32 val_len, attr_search_context *ctx);
extern int load_attribute_list(ntfs_volume *vol, run_list *rl, u8 *al, extern int load_attribute_list(ntfs_volume *vol, run_list *rl, u8 *al_start,
const s64 size, const s64 initialized_size); const s64 size, const s64 initialized_size);
static inline s64 attribute_value_length(const ATTR_RECORD *a) static inline s64 attribute_value_length(const ATTR_RECORD *a)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment