From 737db3671e78ae4a7016e828b67d67d403b304f3 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Tue, 11 Nov 2003 17:56:57 +0000 Subject: [PATCH] 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. --- Documentation/filesystems/ntfs.txt | 4 ++++ fs/ntfs/ChangeLog | 8 ++++++++ fs/ntfs/Makefile | 2 +- fs/ntfs/attrib.c | 33 ++++++++++++++---------------- fs/ntfs/attrib.h | 2 +- 5 files changed, 29 insertions(+), 20 deletions(-) diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt index 33e3afadad77c..8172fffb1667e 100644 --- a/Documentation/filesystems/ntfs.txt +++ b/Documentation/filesystems/ntfs.txt @@ -272,6 +272,10 @@ 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: - Minor update allowing compilation with all gcc versions (well, the ones the kernel can be compiled with anyway). diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 27a8b478c3569..f6fcaf5cbdfb5 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -20,6 +20,14 @@ ToDo: sufficient for synchronisation here. We then just need to make sure 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. - Remove all uses of unnamed structs and unions in the driver to make diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile index 5e2a43f18188b..b6fa3030ac3e8 100644 --- a/fs/ntfs/Makefile +++ b/fs/ntfs/Makefile @@ -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 \ 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) EXTRA_CFLAGS += -DDEBUG diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index b47366fe9baa3..476bcf512bd9d 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -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 * @vol: ntfs volume from which to read * @run_list: run list of the attribute list - * @al: destination buffer + * @al_start: destination buffer * @size: size of the destination buffer in bytes * @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, * * 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) { LCN lcn; + u8 *al = al_start; u8 *al_end = al + initialized_size; run_list_element *rl; struct buffer_head *bh; @@ -1284,32 +1285,28 @@ int load_attribute_list(ntfs_volume *vol, run_list *run_list, u8 *al, } if (initialized_size < size) { initialize: - memset(al + initialized_size, 0, size - initialized_size); + memset(al_start + initialized_size, 0, size - initialized_size); } done: up_read(&run_list->lock); return err; do_final: 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 - * too much trouble. + * Partial block. + * + * 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) goto initialize; - /* If the final lcn is partial all is fine. */ - if (((s64)(block - (lcn << vol->cluster_size_bits >> - block_size_bits)) << block_size_bits >> - 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); + goto done; + } + brelse(bh); /* Real overflow! */ ntfs_error(sb, "Attribute list buffer overflow. Read attribute list " "is truncated."); diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h index e7009a0703af0..8c36c1a44734a 100644 --- a/fs/ntfs/attrib.h +++ b/fs/ntfs/attrib.h @@ -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 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); static inline s64 attribute_value_length(const ATTR_RECORD *a) -- 2.53.0