Commit 522c6443 authored by Anton Altaparmakov's avatar Anton Altaparmakov

NTFS: 2.1.4 release - Reduce compiler requirements.

- Remove all uses of unnamed structs and unions in the driver to make
  old and newer gcc versions happy. Makes it a bit uglier IMO but at
  least people will stop hassling me
parent 0f9ee687
......@@ -247,6 +247,9 @@ ChangeLog
Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
2.1.4:
- Minor update allowing compilation with all gcc versions (well, the
ones the kernel can be compiled with anyway).
2.1.3:
- Major bug fixes for reading files and volumes in corner cases which
were being hit by Windows 2k/XP users.
......
......@@ -20,6 +20,12 @@ ToDo:
sufficient for synchronisation here. We then just need to make sure
ntfs_readpage/writepage/truncate interoperate properly with us.
2.1.4 - Reduce compiler requirements.
- Remove all uses of unnamed structs and unions in the driver to make
old and newer gcc versions happy. Makes it a bit uglier IMO but at
least people will stop hassling me about it.
2.1.3 - Important bug fixes in corner cases.
- super.c::parse_ntfs_boot_sector(): Correct the check for 64-bit
......
......@@ -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.3\"
EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.4\"
ifeq ($(CONFIG_NTFS_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
......
......@@ -2,8 +2,8 @@
* aops.c - NTFS kernel address space operations and page cache handling.
* Part of the Linux-NTFS project.
*
* Copyright (c) 2001,2002 Anton Altaparmakov.
* Copyright (c) 2002 Richard Russon.
* Copyright (c) 2001-2003 Anton Altaparmakov
* Copyright (c) 2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
......@@ -111,7 +111,7 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
unsigned int i, recs, nr_err;
u32 rec_size;
rec_size = ni->_IDM(index_block_size);
rec_size = ni->itype.index.block_size;
recs = PAGE_CACHE_SIZE / rec_size;
addr = kmap_atomic(page, KM_BIO_SRC_IRQ);
for (i = nr_err = 0; i < recs; i++) {
......@@ -124,7 +124,7 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
ni->mft_no ? "index" : "mft",
(long long)(((s64)page->index <<
PAGE_CACHE_SHIFT >>
ni->_IDM(index_block_size_bits)) + i));
ni->itype.index.block_size_bits) + i));
}
flush_dcache_page(page);
kunmap_atomic(addr, KM_BIO_SRC_IRQ);
......@@ -383,7 +383,7 @@ int ntfs_readpage(struct file *file, struct page *page)
if (!NInoAttr(ni))
base_ni = ni;
else
base_ni = ni->_INE(base_ntfs_ino);
base_ni = ni->ext.base_ntfs_ino;
/* Map, pin, and lock the mft record. */
mrec = map_mft_record(base_ni);
......@@ -406,7 +406,7 @@ int ntfs_readpage(struct file *file, struct page *page)
attr_pos = page->index << PAGE_CACHE_SHIFT;
/* The total length of the attribute value. */
attr_len = le32_to_cpu(ctx->attr->_ARA(value_length));
attr_len = le32_to_cpu(ctx->attr->data.resident.value_length);
addr = kmap(page);
/* Copy over in bounds data, zeroing the remainder of the page. */
......@@ -418,8 +418,8 @@ int ntfs_readpage(struct file *file, struct page *page)
memset(addr + bytes, 0, PAGE_CACHE_SIZE - bytes);
/* Copy the data to the page. */
memcpy(addr, attr_pos + (char*)ctx->attr +
le16_to_cpu(ctx->attr->_ARA(value_offset)),
bytes);
le16_to_cpu(
ctx->attr->data.resident.value_offset), bytes);
} else
memset(addr, 0, PAGE_CACHE_SIZE);
flush_dcache_page(page);
......@@ -892,7 +892,7 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
if (!NInoAttr(ni))
base_ni = ni;
else
base_ni = ni->_INE(base_ntfs_ino);
base_ni = ni->ext.base_ntfs_ino;
/* Map, pin, and lock the mft record. */
m = map_mft_record(base_ni);
......@@ -917,7 +917,7 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
attr_pos = page->index << PAGE_CACHE_SHIFT;
/* The total length of the attribute value. */
attr_len = le32_to_cpu(ctx->attr->_ARA(value_length));
attr_len = le32_to_cpu(ctx->attr->data.resident.value_length);
if (unlikely(vi->i_size != attr_len)) {
ntfs_error(vi->i_sb, "BUG()! i_size (0x%Lx) doesn't match "
......@@ -956,8 +956,9 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
kaddr = kmap_atomic(page, KM_USER0);
/* Copy the data from the page to the mft record. */
memcpy((u8*)ctx->attr + le16_to_cpu(ctx->attr->_ARA(value_offset)) +
attr_pos, kaddr, bytes);
memcpy((u8*)ctx->attr + le16_to_cpu(
ctx->attr->data.resident.value_offset) + attr_pos,
kaddr, bytes);
flush_dcache_mft_record_page(ctx->ntfs_ino);
#if 0
/* Zero out of bounds area. */
......@@ -1656,7 +1657,7 @@ static int ntfs_commit_write(struct file *file, struct page *page,
if (!NInoAttr(ni))
base_ni = ni;
else
base_ni = ni->_INE(base_ntfs_ino);
base_ni = ni->ext.base_ntfs_ino;
/* Map, pin, and lock the mft record. */
m = map_mft_record(base_ni);
......@@ -1681,7 +1682,7 @@ static int ntfs_commit_write(struct file *file, struct page *page,
attr_pos = page->index << PAGE_CACHE_SHIFT;
/* The total length of the attribute value. */
attr_len = le32_to_cpu(ctx->attr->_ARA(value_length));
attr_len = le32_to_cpu(ctx->attr->data.resident.value_length);
if (unlikely(vi->i_size != attr_len)) {
ntfs_error(vi->i_sb, "BUG()! i_size (0x%Lx) doesn't match "
......@@ -1705,8 +1706,8 @@ static int ntfs_commit_write(struct file *file, struct page *page,
* Calculate the address of the attribute value corresponding to the
* beginning of the current data @page.
*/
kattr = (u8*)ctx->attr + le16_to_cpu(ctx->attr->_ARA(value_offset)) +
attr_pos;
kattr = (u8*)ctx->attr + le16_to_cpu(
ctx->attr->data.resident.value_offset) + attr_pos;
kaddr = kmap_atomic(page, KM_USER0);
......
......@@ -731,17 +731,18 @@ run_list_element *decompress_mapping_pairs(const ntfs_volume *vol,
#ifdef DEBUG
/* Make sure attr exists and is non-resident. */
if (!attr || !attr->non_resident ||
sle64_to_cpu(attr->_ANR(lowest_vcn)) < (VCN)0) {
if (!attr || !attr->non_resident || sle64_to_cpu(
attr->data.non_resident.lowest_vcn) < (VCN)0) {
ntfs_error(vol->sb, "Invalid arguments.");
return ERR_PTR(-EINVAL);
}
#endif
/* Start at vcn = lowest_vcn and lcn 0. */
vcn = sle64_to_cpu(attr->_ANR(lowest_vcn));
vcn = sle64_to_cpu(attr->data.non_resident.lowest_vcn);
lcn = 0;
/* Get start of the mapping pairs array. */
buf = (u8*)attr + le16_to_cpu(attr->_ANR(mapping_pairs_offset));
buf = (u8*)attr + le16_to_cpu(
attr->data.non_resident.mapping_pairs_offset);
attr_end = (u8*)attr + le32_to_cpu(attr->length);
if (unlikely(buf < (u8*)attr || buf > attr_end)) {
ntfs_error(vol->sb, "Corrupt attribute.");
......@@ -867,7 +868,7 @@ run_list_element *decompress_mapping_pairs(const ntfs_volume *vol,
* If there is a highest_vcn specified, it must be equal to the final
* vcn in the run list - 1, or something has gone badly wrong.
*/
deltaxcn = sle64_to_cpu(attr->_ANR(highest_vcn));
deltaxcn = sle64_to_cpu(attr->data.non_resident.highest_vcn);
if (unlikely(deltaxcn && vcn - 1 != deltaxcn)) {
mpa_err:
ntfs_error(vol->sb, "Corrupt mapping pairs array in "
......@@ -875,10 +876,11 @@ run_list_element *decompress_mapping_pairs(const ntfs_volume *vol,
goto err_out;
}
/* Setup not mapped run list element if this is the base extent. */
if (!attr->_ANR(lowest_vcn)) {
if (!attr->data.non_resident.lowest_vcn) {
VCN max_cluster;
max_cluster = (sle64_to_cpu(attr->_ANR(allocated_size)) +
max_cluster = (sle64_to_cpu(
attr->data.non_resident.allocated_size) +
vol->cluster_size - 1) >>
vol->cluster_size_bits;
/*
......@@ -951,7 +953,7 @@ int map_run_list(ntfs_inode *ni, VCN vcn)
if (!NInoAttr(ni))
base_ni = ni;
else
base_ni = ni->_INE(base_ntfs_ino);
base_ni = ni->ext.base_ntfs_ino;
mrec = map_mft_record(base_ni);
if (IS_ERR(mrec))
......@@ -1183,19 +1185,20 @@ BOOL find_attr(const ATTR_TYPES type, const uchar_t *name, const u32 name_len,
u32 vl;
register int rc;
vl = le32_to_cpu(a->_ARA(value_length));
vl = le32_to_cpu(a->data.resident.value_length);
if (vl > val_len)
vl = val_len;
rc = memcmp(val, (u8*)a + le16_to_cpu(
a->_ARA(value_offset)), vl);
a->data.resident.value_offset), vl);
/*
* If @val collates before the current attribute's
* value, there is no matching attribute.
*/
if (!rc) {
register u32 avl;
avl = le32_to_cpu(a->_ARA(value_length));
avl = le32_to_cpu(
a->data.resident.value_length);
if (val_len == avl)
return TRUE;
if (val_len < avl)
......@@ -1547,9 +1550,11 @@ static BOOL find_external_attr(const ATTR_TYPES type, const uchar_t *name,
* If no @val specified or @val specified and it matches, we
* have found it!
*/
if (!val || (!a->non_resident && le32_to_cpu(a->_ARA(value_length))
== val_len && !memcmp((u8*)a +
le16_to_cpu(a->_ARA(value_offset)), val, val_len))) {
if (!val || (!a->non_resident && le32_to_cpu(
a->data.resident.value_length) == val_len &&
!memcmp((u8*)a +
le16_to_cpu(a->data.resident.value_offset),
val, val_len))) {
ntfs_debug("Done, found.");
return TRUE;
}
......
......@@ -2,8 +2,8 @@
* attrib.h - Defines for attribute handling in NTFS Linux kernel driver.
* Part of the Linux-NTFS project.
*
* Copyright (c) 2001,2002 Anton Altaparmakov.
* Copyright (C) 2002 Richard Russon.
* Copyright (c) 2001-2003 Anton Altaparmakov
* Copyright (c) 2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
......@@ -93,8 +93,8 @@ extern int load_attribute_list(ntfs_volume *vol, run_list *rl, u8 *al,
static inline s64 attribute_value_length(const ATTR_RECORD *a)
{
if (!a->non_resident)
return (s64)le32_to_cpu(a->_ARA(value_length));
return sle64_to_cpu(a->_ANR(data_size));
return (s64)le32_to_cpu(a->data.resident.value_length);
return sle64_to_cpu(a->data.non_resident.data_size);
}
extern void reinit_attr_search_ctx(attr_search_context *ctx);
......
......@@ -477,7 +477,7 @@ int ntfs_read_compressed_block(struct page *page)
u8 *cb, *cb_pos, *cb_end;
struct buffer_head **bhs;
unsigned long offset, index = page->index;
u32 cb_size = ni->_ICF(compression_block_size);
u32 cb_size = ni->itype.compressed.block_size;
u64 cb_size_mask = cb_size - 1UL;
VCN vcn;
LCN lcn;
......@@ -492,7 +492,7 @@ int ntfs_read_compressed_block(struct page *page)
& ~cb_size_mask) >> vol->cluster_size_bits;
/* Number of compression blocks (cbs) in the wanted vcn range. */
unsigned int nr_cbs = (end_vcn - start_vcn) << vol->cluster_size_bits
>> ni->_ICF(compression_block_size_bits);
>> ni->itype.compressed.block_size_bits;
/*
* Number of pages required to store the uncompressed data from all
* compression blocks (cbs) overlapping @page. Due to alignment
......@@ -573,7 +573,7 @@ int ntfs_read_compressed_block(struct page *page)
*/
cur_page = 0;
cur_ofs = 0;
cb_clusters = ni->_ICF(compression_block_clusters);
cb_clusters = ni->itype.compressed.block_clusters;
do_next_cb:
nr_cbs--;
nr_bhs = 0;
......
This diff is collapsed.
This diff is collapsed.
......@@ -2,8 +2,8 @@
* inode.h - Defines for inode structures NTFS Linux kernel driver. Part of
* the Linux-NTFS project.
*
* Copyright (c) 2001,2002 Anton Altaparmakov.
* Copyright (c) 2002 Richard Russon.
* Copyright (c) 2001-2003 Anton Altaparmakov
* Copyright (c) 2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
......@@ -93,23 +93,21 @@ struct _ntfs_inode {
struct { /* It is a directory or $MFT. */
struct inode *bmp_ino; /* Attribute inode for the
directory index $BITMAP. */
u32 index_block_size; /* Size of an index block. */
u32 index_vcn_size; /* Size of a vcn in this
u32 block_size; /* Size of an index block. */
u32 vcn_size; /* Size of a vcn in this
directory index. */
u8 index_block_size_bits; /* Log2 of the above. */
u8 index_vcn_size_bits; /* Log2 of the above. */
} SN(idm);
u8 block_size_bits; /* Log2 of the above. */
u8 vcn_size_bits; /* Log2 of the above. */
} index;
struct { /* It is a compressed file or fake inode. */
s64 compressed_size; /* Copy from $DATA. */
u32 compression_block_size; /* Size of a compression
block (cb). */
u8 compression_block_size_bits; /* Log2 of the size of
a cb. */
u8 compression_block_clusters; /* Number of clusters
per compression
block. */
} SN(icf);
} SN(idc);
s64 size; /* Copy of compressed_size from
$DATA. */
u32 block_size; /* Size of a compression block
(cb). */
u8 block_size_bits; /* Log2 of the size of a cb. */
u8 block_clusters; /* Number of clusters per cb. */
} compressed;
} itype;
struct semaphore extent_lock; /* Lock for accessing/modifying the
below . */
s32 nr_extents; /* For a base mft record, the number of attached extent
......@@ -126,13 +124,9 @@ struct _ntfs_inode {
record. For fake inodes, the
real (base) inode to which
the attribute belongs. */
} SN(ine);
} ext;
};
#define _IDM(X) SC(idc.idm,X)
#define _ICF(X) SC(idc.icf,X)
#define _INE(X) SC(ine,X)
/*
* Defined bits for the state field in the ntfs_inode structure.
* (f) = files only, (d) = directories only, (a) = attributes/fake inodes only
......
This diff is collapsed.
/**
* mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project.
*
* Copyright (c) 2001,2002 Anton Altaparmakov.
* Copyright (c) 2002 Richard Russon.
* Copyright (c) 2001-2003 Anton Altaparmakov
* Copyright (c) 2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
......@@ -39,18 +39,18 @@ static void __format_mft_record(MFT_RECORD *m, const int size,
ATTR_RECORD *a;
memset(m, 0, size);
m->_MNR(magic) = magic_FILE;
m->magic = magic_FILE;
/* Aligned to 2-byte boundary. */
m->_MNR(usa_ofs) = cpu_to_le16((sizeof(MFT_RECORD) + 1) & ~1);
m->_MNR(usa_count) = cpu_to_le16(size / NTFS_BLOCK_SIZE + 1);
m->usa_ofs = cpu_to_le16((sizeof(MFT_RECORD) + 1) & ~1);
m->usa_count = cpu_to_le16(size / NTFS_BLOCK_SIZE + 1);
/* Set the update sequence number to 1. */
*(u16*)((char*)m + ((sizeof(MFT_RECORD) + 1) & ~1)) = cpu_to_le16(1);
m->lsn = cpu_to_le64(0LL);
m->sequence_number = cpu_to_le16(1);
m->link_count = cpu_to_le16(0);
/* Aligned to 8-byte boundary. */
m->attrs_offset = cpu_to_le16((le16_to_cpu(m->_MNR(usa_ofs)) +
(le16_to_cpu(m->_MNR(usa_count)) << 1) + 7) & ~7);
m->attrs_offset = cpu_to_le16((le16_to_cpu(m->usa_ofs) +
(le16_to_cpu(m->usa_count) << 1) + 7) & ~7);
m->flags = cpu_to_le16(0);
/*
* Using attrs_offset plus eight bytes (for the termination attribute),
......@@ -329,7 +329,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
*/
down(&base_ni->extent_lock);
if (base_ni->nr_extents > 0) {
extent_nis = base_ni->_INE(extent_ntfs_inos);
extent_nis = base_ni->ext.extent_ntfs_inos;
for (i = 0; i < base_ni->nr_extents; i++) {
if (mft_no != extent_nis[i]->mft_no)
continue;
......@@ -374,7 +374,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
ni->vol = base_ni->vol;
ni->seq_no = seq_no;
ni->nr_extents = -1;
ni->_INE(base_ntfs_ino) = base_ni;
ni->ext.base_ntfs_ino = base_ni;
/* Now map the record. */
m = map_mft_record(ni);
if (unlikely(IS_ERR(m))) {
......@@ -404,14 +404,14 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
m = ERR_PTR(-ENOMEM);
goto unm_err_out;
}
if (base_ni->_INE(extent_ntfs_inos)) {
memcpy(tmp, base_ni->_INE(extent_ntfs_inos), new_size -
if (base_ni->ext.extent_ntfs_inos) {
memcpy(tmp, base_ni->ext.extent_ntfs_inos, new_size -
4 * sizeof(ntfs_inode *));
kfree(base_ni->_INE(extent_ntfs_inos));
kfree(base_ni->ext.extent_ntfs_inos);
}
base_ni->_INE(extent_ntfs_inos) = tmp;
base_ni->ext.extent_ntfs_inos = tmp;
}
base_ni->_INE(extent_ntfs_inos)[base_ni->nr_extents++] = ni;
base_ni->ext.extent_ntfs_inos[base_ni->nr_extents++] = ni;
up(&base_ni->extent_lock);
atomic_dec(&base_ni->count);
ntfs_debug("Done 2.");
......
......@@ -2,7 +2,7 @@
* namei.c - NTFS kernel directory inode operations. Part of the Linux-NTFS
* project.
*
* Copyright (c) 2001,2002 Anton Altaparmakov.
* Copyright (c) 2001-2003 Anton Altaparmakov
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
......@@ -210,12 +210,12 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent)
a = ctx->attr;
if (a->non_resident || a->flags)
goto eio_err_out;
val_len = le32_to_cpu(a->_ARA(value_length));
if (le16_to_cpu(a->_ARA(value_offset)) + val_len >
le32_to_cpu(a->length))
val_len = le32_to_cpu(a->data.resident.value_length);
if (le16_to_cpu(a->data.resident.value_offset) +
val_len > le32_to_cpu(a->length))
goto eio_err_out;
fn = (FILE_NAME_ATTR*)((u8*)ctx->attr + le16_to_cpu(
ctx->attr->_ARA(value_offset)));
ctx->attr->data.resident.value_offset));
if ((u32)(fn->file_name_length * sizeof(uchar_t) +
sizeof(FILE_NAME_ATTR)) > val_len)
goto eio_err_out;
......
......@@ -883,10 +883,10 @@ static BOOL load_system_files(ntfs_volume *vol)
goto iput_volume_failed;
}
vi = (VOLUME_INFORMATION*)((char*)ctx->attr +
le16_to_cpu(ctx->attr->_ARA(value_offset)));
le16_to_cpu(ctx->attr->data.resident.value_offset));
/* Some bounds checks. */
if ((u8*)vi < (u8*)ctx->attr || (u8*)vi +
le32_to_cpu(ctx->attr->_ARA(value_length)) >
le32_to_cpu(ctx->attr->data.resident.value_length) >
(u8*)ctx->attr + le32_to_cpu(ctx->attr->length))
goto err_put_vol;
/* Setup volume flags and version. */
......
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