Commit dfeb4845 authored by Anton Altaparmakov's avatar Anton Altaparmakov

NTFS: 2.0.4 - Cleanups and updates for kernel 2.5.11.

- Add documentation on how to use the MD driver to be able to use NTFS
stripe and volume sets in Linux and generally cleanup documentation
a bit.

Remove all uses of kdev_t in favour of struct block_device *:
- Change compress.c::ntfs_file_read_compressed_block() to use sb_getblk()
instead of getblk().
- Change super.c::ntfs_fill_suoer() to use bdev_hardsect_size() instead
of get_hardsect_size().
- No need to get old blocksize in super.c::ntfs_fill_super() as
fs/super.c::get_sb_bdev() already does this.
- Set bh->b_bdev instead of bh->b_dev throughout aops.c.
parent 923b6fa8
NTFS Overview The Linux NTFS filesystem driver
============= ================================
Table of contents
=================
- Overview
- Supported mount options
- Features
- Known bugs and (mis-)features
- Using Software RAID with NTFS
- Limitiations when using the MD driver
- ChangeLog
Overview
========
To mount an NTFS 1.2/3.x (Windows NT4/2000/XP) volume, use the filesystem To mount an NTFS 1.2/3.x (Windows NT4/2000/XP) volume, use the filesystem
type 'ntfs'. The driver currently works only in read-only mode, with no type 'ntfs'. The driver currently works only in read-only mode, with no
fault-tolerance supported. fault-tolerance or journalling supported.
For fault tolerance and raid support (i.e. volume and stripe sets), you can use
the kernel's Software RAID / MD driver. See section "Using Software RAID with
NTFS" for details.
For ftdisk support, limited success was reported with volume sets on top of
the md driver, although mirror and stripe sets should work as well - if the
md driver can be talked into using the same layout as Windows NT. However,
using the md driver will fail if any of your NTFS partitions have an odd
number of sectors.
Supported mount options Supported mount options
======================= =======================
In addition to the generic mount options described by the manual page for the
mount command (man 8 mount, also see man 5 fstab), the NTFS driver supports the
following mount options:
iocharset=name Deprecated option. Still supported but please use iocharset=name Deprecated option. Still supported but please use
nls=name in the future. See description for nls=name. nls=name in the future. See description for nls=name.
...@@ -137,6 +156,7 @@ mft_zone_multiplier= Set the MFT zone multiplier for the volume (this ...@@ -137,6 +156,7 @@ mft_zone_multiplier= Set the MFT zone multiplier for the volume (this
4 50% 4 50%
Note this option is irrelevant for read-only mounts. Note this option is irrelevant for read-only mounts.
Features Features
======== ========
...@@ -155,6 +175,7 @@ Features ...@@ -155,6 +175,7 @@ Features
was unchanged but the time spent in the kernel was decreased by a factor of was unchanged but the time spent in the kernel was decreased by a factor of
2.5 (from 85 CPU seconds down to 33). 2.5 (from 85 CPU seconds down to 33).
Known bugs and (mis-)features Known bugs and (mis-)features
============================= =============================
...@@ -163,11 +184,86 @@ Known bugs and (mis-)features ...@@ -163,11 +184,86 @@ Known bugs and (mis-)features
Please send bug reports/comments/feedback/abuse to the Linux-NTFS development Please send bug reports/comments/feedback/abuse to the Linux-NTFS development
list at sourceforge: linux-ntfs-dev@lists.sourceforge.net list at sourceforge: linux-ntfs-dev@lists.sourceforge.net
Using Software RAID with NTFS
=============================
For support of volume and stripe sets, use the kernel's Software RAID / MD
driver and set up your /etc/raidtab appropriately (see man 5 raidtab).
Linear volume sets, i.e. linear raid, as well as stripe sets, i.e. raid level 0,
have been tested and work fine (though see section "Limitiations when using the
MD driver with NTFS volumes" especially if you want to use linear raid). Even
though untested, there is no reason why mirrors, i.e. raid level 1, and stripes
with parity, i.e. raid level 5, should not work, too.
You have to use the "persistent-superblock 0" option for each raid-disk in the
NTFS volume/stripe you are configuring in /etc/raidtab as the persistent
superblock used by the MD driver would damange the NTFS volume.
Windows by default uses a stripe chunk size of 64k, so you probably want the
"chunk-size 64k" option for each raid-disk, too.
For example, if you have a stripe set consisting of two partitions /dev/hda5
and /dev/hdb1 your /etc/raidtab would look like this:
raiddev /dev/md0
raid-level 0
nr-raid-disks 2
nr-spare-disks 0
persistent-superblock 0
chunk-size 64k
device /dev/hda5
raid-disk 0
device /dev/hdb1
raid-disl 1
For linear raid, just change the raid-level above to "raid-level linear", for
mirrors, change it to "raid-level 1", and for stripe sets with parity, change
it to "raid-level 5".
Note for stripe sets with parity you will also need to tell the MD driver which
parity algorithm to use by specifying the option "parity-algorithm which",
where you need to replace "which" with the name of the algorithm to use (see
man 5 raidtab for available algorithms) and you will have to try the different
available algorithms until you find one that works. Make sure you are working
read-only when playing with this as you may damage your data otherwise. If you
find which algorithm works please let us know (email the linux-ntfs developers
list linux-ntfs-dev@lists.sourceforge.net or drop in on IRC in channel #ntfs
on the irc.openprojects.net network) so we can update this documentation.
Once the raidtab is setup, run for example raid0run -a to start all devices or
raid0run /dev/md0 to start a particular md device, in this case /dev/md0.
Then just use the mount command as usual to mount the ntfs volume using for
example: mount -t ntfs -o ro /dev/md0 /mnt/myntfsvolume
It is advisable to do the mount read-only to see if the md volume has been
setup correctly to avoid the possibility of causing damage to the data on the
ntfs volume.
Limitiations when using the MD driver
=====================================
Using the md driver will not work properly if any of your NTFS partitions have
an odd number of sectors. This is especially important for linear raid as all
data after the first partition with an odd number of sectors will be offset by
one or more sectors so if you mount such a partition with write support you
will cause massive damage to the data on the volume which will only become
apparent when you try to use the volume again under Windows.
So when using linear raid, make sure that all your partitions have an even
number of sectors BEFORE attempting to use it. You have been warned!
ChangeLog ChangeLog
========= =========
Note that a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. Note that a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
2.0.4:
- Cleanups and updates for kernel 2.5.11.
2.0.3: 2.0.3:
- Small bug fixes, cleanups, and performance improvements. - Small bug fixes, cleanups, and performance improvements.
2.0.2: 2.0.2:
......
...@@ -27,6 +27,20 @@ ToDo: ...@@ -27,6 +27,20 @@ ToDo:
quite big. Modularising them a bit, e.g. a-la get_block(), will make quite big. Modularising them a bit, e.g. a-la get_block(), will make
them cleaner and make code reuse easier. them cleaner and make code reuse easier.
2.0.4 - Cleanups and updates for kernel 2.5.11.
- Add documentation on how to use the MD driver to be able to use NTFS
stripe and volume sets in Linux and generally cleanup documentation
a bit.
Remove all uses of kdev_t in favour of struct block_device *:
- Change compress.c::ntfs_file_read_compressed_block() to use
sb_getblk() instead of getblk().
- Change super.c::ntfs_fill_suoer() to use bdev_hardsect_size() instead
of get_hardsect_size().
- No need to get old blocksize in super.c::ntfs_fill_super() as
fs/super.c::get_sb_bdev() already does this.
- Set bh->b_bdev instead of bh->b_dev throughout aops.c.
2.0.3 - Small bug fixes, cleanups, and performance improvements. 2.0.3 - Small bug fixes, cleanups, and performance improvements.
- Remove some dead code from mft.c. - Remove some dead code from mft.c.
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
O_TARGET := ntfs.o O_TARGET := ntfs.o
obj-y := time.o unistr.o inode.o file.o mft.o super.o debug.o aops.o \ obj-y := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \
attrib.o dir.o namei.o mst.o upcase.o compress.o sysctl.o mst.o namei.o super.o sysctl.o time.o unistr.o upcase.o
obj-m := $(O_TARGET) obj-m := $(O_TARGET)
EXTRA_CFLAGS = -DNTFS_VERSION=\"2.0.3\" EXTRA_CFLAGS = -DNTFS_VERSION=\"2.0.4\"
ifeq ($(CONFIG_NTFS_DEBUG),y) ifeq ($(CONFIG_NTFS_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG EXTRA_CFLAGS += -DDEBUG
......
...@@ -147,7 +147,7 @@ static int ntfs_file_read_block(struct page *page) ...@@ -147,7 +147,7 @@ static int ntfs_file_read_block(struct page *page)
arr[nr++] = bh; arr[nr++] = bh;
continue; continue;
} }
bh->b_dev = VFS_I(ni)->i_dev; bh->b_bdev = vol->sb->s_bdev;
/* Is the block within the allowed limits? */ /* Is the block within the allowed limits? */
if (iblock < lblock) { if (iblock < lblock) {
BOOL is_retry = FALSE; BOOL is_retry = FALSE;
...@@ -437,7 +437,7 @@ static int ntfs_mftbmp_readpage(ntfs_volume *vol, struct page *page) ...@@ -437,7 +437,7 @@ static int ntfs_mftbmp_readpage(ntfs_volume *vol, struct page *page)
arr[nr++] = bh; arr[nr++] = bh;
continue; continue;
} }
bh->b_dev = vol->mft_ino->i_dev; bh->b_bdev = vol->sb->s_bdev;
/* Is the block within the allowed limits? */ /* Is the block within the allowed limits? */
if (iblock < lblock) { if (iblock < lblock) {
/* Convert iblock into corresponding vcn and offset. */ /* Convert iblock into corresponding vcn and offset. */
...@@ -681,7 +681,7 @@ int ntfs_mst_readpage(struct file *dir, struct page *page) ...@@ -681,7 +681,7 @@ int ntfs_mst_readpage(struct file *dir, struct page *page)
arr[nr++] = bh; arr[nr++] = bh;
continue; continue;
} }
bh->b_dev = VFS_I(ni)->i_dev; bh->b_bdev = vol->sb->s_bdev;
/* Is the block within the allowed limits? */ /* Is the block within the allowed limits? */
if (iblock < lblock) { if (iblock < lblock) {
BOOL is_retry = FALSE; BOOL is_retry = FALSE;
......
...@@ -443,9 +443,9 @@ int ntfs_file_read_compressed_block(struct page *page) ...@@ -443,9 +443,9 @@ int ntfs_file_read_compressed_block(struct page *page)
struct address_space *mapping = page->mapping; struct address_space *mapping = page->mapping;
ntfs_inode *ni = NTFS_I(mapping->host); ntfs_inode *ni = NTFS_I(mapping->host);
ntfs_volume *vol = ni->vol; ntfs_volume *vol = ni->vol;
kdev_t dev = vol->sb->s_dev; struct super_block *sb = vol->sb;
unsigned long block_size = vol->sb->s_blocksize; unsigned long block_size = sb->s_blocksize;
unsigned char block_size_bits = vol->sb->s_blocksize_bits; unsigned char block_size_bits = sb->s_blocksize_bits;
u8 *cb, *cb_pos, *cb_end; u8 *cb, *cb_pos, *cb_end;
struct buffer_head **bhs; struct buffer_head **bhs;
unsigned long offset, index = page->index; unsigned long offset, index = page->index;
...@@ -575,8 +575,7 @@ int ntfs_file_read_compressed_block(struct page *page) ...@@ -575,8 +575,7 @@ int ntfs_file_read_compressed_block(struct page *page)
max_block = block + (vol->cluster_size >> block_size_bits); max_block = block + (vol->cluster_size >> block_size_bits);
do { do {
ntfs_debug("block = 0x%x.", block); ntfs_debug("block = 0x%x.", block);
if (unlikely(!(bhs[nr_bhs] = getblk(dev, block, if (unlikely(!(bhs[nr_bhs] = sb_getblk(sb, block))))
block_size))))
goto getblk_err; goto getblk_err;
nr_bhs++; nr_bhs++;
} while (++block < max_block); } while (++block < max_block);
......
...@@ -25,8 +25,7 @@ ...@@ -25,8 +25,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/locks.h> #include <linux/locks.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/genhd.h> /* For gendisk stuff. */ #include <linux/blkdev.h> /* For bdev_hardsect_size(). */
#include <linux/blkdev.h> /* Fox get_hardsect_size. */
#include "ntfs.h" #include "ntfs.h"
#include "sysctl.h" #include "sysctl.h"
...@@ -1474,12 +1473,10 @@ struct super_operations ntfs_sops = { ...@@ -1474,12 +1473,10 @@ struct super_operations ntfs_sops = {
*/ */
static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
{ {
extern int *blksize_size[];
ntfs_volume *vol; ntfs_volume *vol;
struct buffer_head *bh; struct buffer_head *bh;
struct inode *tmp_ino; struct inode *tmp_ino;
int old_blocksize, result; int result;
kdev_t dev = sb->s_dev;
ntfs_debug("Entering."); ntfs_debug("Entering.");
/* Allocate a new ntfs_volume and place it in sb->u.generic_sbp. */ /* Allocate a new ntfs_volume and place it in sb->u.generic_sbp. */
...@@ -1548,17 +1545,13 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) ...@@ -1548,17 +1545,13 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
* TODO: Fail safety check. In the future we should really be able to * TODO: Fail safety check. In the future we should really be able to
* cope with this being the case, but for now just bail out. * cope with this being the case, but for now just bail out.
*/ */
if (get_hardsect_size(dev) > NTFS_BLOCK_SIZE) { if (bdev_hardsect_size(sb->s_bdev) > NTFS_BLOCK_SIZE) {
if (!silent) if (!silent)
ntfs_error(sb, "Device has unsupported hardsect_size."); ntfs_error(sb, "Device has unsupported hardsect_size.");
goto err_out_now; goto err_out_now;
} }
/* Setup the device access block size to NTFS_BLOCK_SIZE. */ /* Setup the device access block size to NTFS_BLOCK_SIZE. */
if (!blksize_size[major(dev)])
old_blocksize = BLOCK_SIZE;
else
old_blocksize = blksize_size[major(dev)][minor(dev)];
if (sb_set_blocksize(sb, NTFS_BLOCK_SIZE) != NTFS_BLOCK_SIZE) { if (sb_set_blocksize(sb, NTFS_BLOCK_SIZE) != NTFS_BLOCK_SIZE) {
if (!silent) if (!silent)
ntfs_error(sb, "Unable to set block size."); ntfs_error(sb, "Unable to set block size.");
...@@ -1759,7 +1752,8 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) ...@@ -1759,7 +1752,8 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
} }
set_blk_size_err_out_now: set_blk_size_err_out_now:
/* Errors at this stage are irrelevant. */ /* Errors at this stage are irrelevant. */
sb_set_blocksize(sb, old_blocksize); // FIXME: This should be done in fs/super.c::get_sb_bdev() itself! (AIA)
sb_set_blocksize(sb, sb->s_old_blocksize);
err_out_now: err_out_now:
sb->u.generic_sbp = NULL; sb->u.generic_sbp = NULL;
kfree(vol); kfree(vol);
......
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