Commit 79c914d9 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-ntfs.bkbits.net/ntfs-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents d9fd3c1c 7eebd09b
...@@ -272,6 +272,8 @@ ChangeLog ...@@ -272,6 +272,8 @@ 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.7:
- Enable NFS exporting of mounted NTFS volumes.
2.1.6: 2.1.6:
- Fix minor bug in handling of compressed directories that fixes the - Fix minor bug in handling of compressed directories that fixes the
erroneous "du" and "stat" output people reported. erroneous "du" and "stat" output people reported.
......
ToDo: ToDo:
- Find and fix bugs. - Find and fix bugs.
- Enable NFS exporting of NTFS.
- Implement aops->set_page_dirty() in order to take control of buffer - Implement aops->set_page_dirty() in order to take control of buffer
dirtying. Not having it means if page_has_buffers(), all buffers dirtying. Not having it means if page_has_buffers(), all buffers
will be dirtied with the page. And if not they won't be. That is will be dirtied with the page. And if not they won't be. That is
...@@ -20,6 +19,26 @@ ToDo: ...@@ -20,6 +19,26 @@ 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.7 - Enable NFS exporting of mounted NTFS volumes.
- Set i_generation in the VFS inode from the seq_no of the NTFS inode.
- Make ntfs_lookup() NFS export safe, i.e. use d_splice_alias(), etc.
- Implement ->get_dentry() in fs/ntfs/namei.c::ntfs_get_dentry() as the
default doesn't allow inode number 0 which is a valid inode on NTFS
and even if it did allow that it uses iget() instead of ntfs_iget()
which makes it useless for us.
- Implement ->get_parent() in fs/ntfs/namei.c::ntfs_get_parent() as the
default just returns -EACCES which is not very useful.
- Define export operations (->s_export_op) for NTFS (ntfs_export_ops)
and set them up in the super block at mount time (super.c) this
allows mounted NTFS volumes to be exported via NFS.
- Add missing return -EOPNOTSUPP; in
fs/ntfs/aops.c::ntfs_commit_nonresident_write().
- Enforce no atime and no dir atime updates at mount/remount time as
they are not implemented yet anyway.
- Move a few assignments in fs/ntfs/attrib.c::load_attribute_list() to
after a NULL check. Thanks to Dave Jones for pointing this out.
2.1.6 - Fix minor bug in handling of compressed directories. 2.1.6 - Fix minor bug in handling of compressed directories.
- Fix bug in handling of compressed directories. A compressed - Fix bug in handling of compressed directories. A compressed
...@@ -60,6 +79,10 @@ ToDo: ...@@ -60,6 +79,10 @@ ToDo:
- Reduce function local stack usage from 0x3d4 bytes to just noise in - Reduce function local stack usage from 0x3d4 bytes to just noise in
fs/ntfs/upcase.c. (Randy Dunlap <rddunlap@osdl.ord>) fs/ntfs/upcase.c. (Randy Dunlap <rddunlap@osdl.ord>)
- Remove compiler warnings for newer gcc. - Remove compiler warnings for newer gcc.
- Pages are no longer kmapped by mm/filemap.c::generic_file_write()
around calls to ->{prepare,commit}_write. Adapt NTFS appropriately
in fs/ntfs/aops.c::ntfs_prepare_nonresident_write() by using
kmap_atomic(KM_USER0).
2.1.0 - First steps towards write support: implement file overwrite. 2.1.0 - First steps towards write support: implement file overwrite.
......
...@@ -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.6\" EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.7\"
ifeq ($(CONFIG_NTFS_DEBUG),y) ifeq ($(CONFIG_NTFS_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG EXTRA_CFLAGS += -DDEBUG
......
/** /**
* aops.c - NTFS kernel address space operations and page cache handling. * aops.c - NTFS kernel address space operations and page cache handling.
* Part of the Linux-NTFS project. * Part of the Linux-NTFS project.
* *
* Copyright (c) 2001-2003 Anton Altaparmakov * Copyright (c) 2001-2004 Anton Altaparmakov
* Copyright (c) 2002 Richard Russon * Copyright (c) 2002 Richard Russon
* *
* This program/include file is free software; you can redistribute it and/or * This program/include file is free software; you can redistribute it and/or
...@@ -10,13 +10,13 @@ ...@@ -10,13 +10,13 @@
* by the Free Software Foundation; either version 2 of the License, or * by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program/include file is distributed in the hope that it will be * This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the Linux-NTFS * along with this program (in the main directory of the Linux-NTFS
* distribution in the file COPYING); if not, write to the Free Software * distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
...@@ -572,11 +572,11 @@ static int ntfs_write_block(struct writeback_control *wbc, struct page *page) ...@@ -572,11 +572,11 @@ static int ntfs_write_block(struct writeback_control *wbc, struct page *page)
// Again for each page do: // Again for each page do:
// - wait_on_page_locked() // - wait_on_page_locked()
// - Check (PageUptodate(page) && // - Check (PageUptodate(page) &&
// !PageError(page)) // !PageError(page))
// Update initialized size in the attribute and // Update initialized size in the attribute and
// in the inode. // in the inode.
// Again, for each page do: // Again, for each page do:
// __set_page_dirty_buffers(); // __set_page_dirty_buffers();
// page_cache_release() // page_cache_release()
// We don't need to wait on the writes. // We don't need to wait on the writes.
// Update iblock. // Update iblock.
...@@ -1112,11 +1112,11 @@ static int ntfs_prepare_nonresident_write(struct page *page, ...@@ -1112,11 +1112,11 @@ static int ntfs_prepare_nonresident_write(struct page *page,
// Again for each page do: // Again for each page do:
// - wait_on_page_locked() // - wait_on_page_locked()
// - Check (PageUptodate(page) && // - Check (PageUptodate(page) &&
// !PageError(page)) // !PageError(page))
// Update initialized size in the attribute and // Update initialized size in the attribute and
// in the inode. // in the inode.
// Again, for each page do: // Again, for each page do:
// __set_page_dirty_buffers(); // __set_page_dirty_buffers();
// page_cache_release() // page_cache_release()
// We don't need to wait on the writes. // We don't need to wait on the writes.
// Update iblock. // Update iblock.
...@@ -1188,7 +1188,7 @@ static int ntfs_prepare_nonresident_write(struct page *page, ...@@ -1188,7 +1188,7 @@ static int ntfs_prepare_nonresident_write(struct page *page,
// TODO: Instantiate the hole. // TODO: Instantiate the hole.
// clear_buffer_new(bh); // clear_buffer_new(bh);
// unmap_underlying_metadata(bh->b_bdev, // unmap_underlying_metadata(bh->b_bdev,
// bh->b_blocknr); // bh->b_blocknr);
// For non-uptodate buffers, need to // For non-uptodate buffers, need to
// zero out the region outside the // zero out the region outside the
// request in this bh or all bhs, // request in this bh or all bhs,
...@@ -1279,7 +1279,7 @@ static int ntfs_prepare_nonresident_write(struct page *page, ...@@ -1279,7 +1279,7 @@ static int ntfs_prepare_nonresident_write(struct page *page,
if (PageUptodate(page)) { if (PageUptodate(page)) {
if (!buffer_uptodate(bh)) if (!buffer_uptodate(bh))
set_buffer_uptodate(bh); set_buffer_uptodate(bh);
continue; continue;
} }
/* /*
* The page is not uptodate. The buffer is mapped. If it is not * The page is not uptodate. The buffer is mapped. If it is not
...@@ -1525,6 +1525,7 @@ static int ntfs_commit_nonresident_write(struct page *page, ...@@ -1525,6 +1525,7 @@ static int ntfs_commit_nonresident_write(struct page *page,
if (pos > vi->i_size) { if (pos > vi->i_size) {
ntfs_error(vi->i_sb, "Writing beyond the existing file size is " ntfs_error(vi->i_sb, "Writing beyond the existing file size is "
"not supported yet. Sorry."); "not supported yet. Sorry.");
return -EOPNOTSUPP;
// vi->i_size = pos; // vi->i_size = pos;
// mark_inode_dirty(vi); // mark_inode_dirty(vi);
} }
...@@ -1708,7 +1709,7 @@ static int ntfs_commit_write(struct file *file, struct page *page, ...@@ -1708,7 +1709,7 @@ static int ntfs_commit_write(struct file *file, struct page *page,
/* /*
* Bring the out of bounds area(s) uptodate by copying data * Bring the out of bounds area(s) uptodate by copying data
* from the mft record to the page. * from the mft record to the page.
*/ */
if (from > 0) if (from > 0)
memcpy(kaddr, kattr, from); memcpy(kaddr, kattr, from);
if (to < bytes) if (to < bytes)
......
...@@ -1235,11 +1235,11 @@ int load_attribute_list(ntfs_volume *vol, run_list *run_list, u8 *al_start, ...@@ -1235,11 +1235,11 @@ int load_attribute_list(ntfs_volume *vol, run_list *run_list, u8 *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;
struct super_block *sb = vol->sb; struct super_block *sb;
unsigned long block_size = sb->s_blocksize; unsigned long block_size;
unsigned long block, max_block; unsigned long block, max_block;
int err = 0; int err = 0;
unsigned char block_size_bits = sb->s_blocksize_bits; unsigned char block_size_bits;
ntfs_debug("Entering."); ntfs_debug("Entering.");
if (!vol || !run_list || !al || size <= 0 || initialized_size < 0 || if (!vol || !run_list || !al || size <= 0 || initialized_size < 0 ||
...@@ -1249,6 +1249,9 @@ int load_attribute_list(ntfs_volume *vol, run_list *run_list, u8 *al_start, ...@@ -1249,6 +1249,9 @@ int load_attribute_list(ntfs_volume *vol, run_list *run_list, u8 *al_start,
memset(al, 0, size); memset(al, 0, size);
return 0; return 0;
} }
sb = vol->sb;
block_size = sb->s_blocksize;
block_size_bits = sb->s_blocksize_bits;
down_read(&run_list->lock); down_read(&run_list->lock);
rl = run_list->rl; rl = run_list->rl;
/* Read all clusters specified by the run list one run at a time. */ /* Read all clusters specified by the run list one run at a time. */
......
/** /**
* dir.c - NTFS kernel directory operations. Part of the Linux-NTFS project. * dir.c - NTFS kernel directory operations. Part of the Linux-NTFS project.
* *
* Copyright (c) 2001-2003 Anton Altaparmakov * Copyright (c) 2001-2004 Anton Altaparmakov
* Copyright (c) 2002 Richard Russon * Copyright (c) 2002 Richard Russon
* *
* This program/include file is free software; you can redistribute it and/or * This program/include file is free software; you can redistribute it and/or
...@@ -200,7 +200,8 @@ MFT_REF ntfs_lookup_inode_by_name(ntfs_inode *dir_ni, const uchar_t *uname, ...@@ -200,7 +200,8 @@ MFT_REF ntfs_lookup_inode_by_name(ntfs_inode *dir_ni, const uchar_t *uname,
"and if that doesn't find any " "and if that doesn't find any "
"errors please report you saw " "errors please report you saw "
"this message to " "this message to "
"linux-ntfs-dev@lists.sf.net."); "linux-ntfs-dev@lists."
"sourceforge.net.");
goto dir_err_out; goto dir_err_out;
} }
...@@ -457,7 +458,8 @@ MFT_REF ntfs_lookup_inode_by_name(ntfs_inode *dir_ni, const uchar_t *uname, ...@@ -457,7 +458,8 @@ MFT_REF ntfs_lookup_inode_by_name(ntfs_inode *dir_ni, const uchar_t *uname,
"and if that doesn't find any " "and if that doesn't find any "
"errors please report you saw " "errors please report you saw "
"this message to " "this message to "
"linux-ntfs-dev@lists.sf.net."); "linux-ntfs-dev@lists."
"sourceforge.net.");
ntfs_unmap_page(page); ntfs_unmap_page(page);
goto dir_err_out; goto dir_err_out;
} }
......
...@@ -196,7 +196,7 @@ struct inode *ntfs_iget(struct super_block *sb, unsigned long mft_no) ...@@ -196,7 +196,7 @@ struct inode *ntfs_iget(struct super_block *sb, unsigned long mft_no)
} }
/* /*
* There is no point in keeping bad inodes around if the failure was * There is no point in keeping bad inodes around if the failure was
* due to ENOMEM. We want to be able to retry again layer. * due to ENOMEM. We want to be able to retry again later.
*/ */
if (err == -ENOMEM) { if (err == -ENOMEM) {
iput(vi); iput(vi);
...@@ -533,7 +533,7 @@ static int ntfs_read_locked_inode(struct inode *vi) ...@@ -533,7 +533,7 @@ static int ntfs_read_locked_inode(struct inode *vi)
} }
/* Transfer information from mft record into vfs and ntfs inodes. */ /* Transfer information from mft record into vfs and ntfs inodes. */
ni->seq_no = le16_to_cpu(m->sequence_number); vi->i_generation = ni->seq_no = le16_to_cpu(m->sequence_number);
/* /*
* FIXME: Keep in mind that link_count is two for files which have both * FIXME: Keep in mind that link_count is two for files which have both
...@@ -1109,7 +1109,7 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) ...@@ -1109,7 +1109,7 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
vi->i_mtime = base_vi->i_mtime; vi->i_mtime = base_vi->i_mtime;
vi->i_ctime = base_vi->i_ctime; vi->i_ctime = base_vi->i_ctime;
vi->i_atime = base_vi->i_atime; vi->i_atime = base_vi->i_atime;
ni->seq_no = base_ni->seq_no; vi->i_generation = ni->seq_no = base_ni->seq_no;
/* Set inode type to zero but preserve permissions. */ /* Set inode type to zero but preserve permissions. */
vi->i_mode = base_vi->i_mode & ~S_IFMT; vi->i_mode = base_vi->i_mode & ~S_IFMT;
...@@ -1137,7 +1137,8 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) ...@@ -1137,7 +1137,8 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
"the attribute is resident (mft_no " "the attribute is resident (mft_no "
"0x%lx, type 0x%x, name_len %i). " "0x%lx, type 0x%x, name_len %i). "
"Please report you saw this message " "Please report you saw this message "
"to linux-ntfs-dev@lists.sf.net", "to linux-ntfs-dev@lists."
"sourceforge.net",
vi->i_ino, ni->type, ni->name_len); vi->i_ino, ni->type, ni->name_len);
goto unm_err_out; goto unm_err_out;
} }
...@@ -1157,8 +1158,9 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) ...@@ -1157,8 +1158,9 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
"type 0x%x, name_len %i). " "type 0x%x, name_len %i). "
"Please report you saw this " "Please report you saw this "
"message to linux-ntfs-dev@" "message to linux-ntfs-dev@"
"lists.sf.net", vi->i_ino, "lists.sourceforge.net",
ni->type, ni->name_len); vi->i_ino, ni->type,
ni->name_len);
goto unm_err_out; goto unm_err_out;
} }
NInoSetCompressed(ni); NInoSetCompressed(ni);
...@@ -1169,7 +1171,8 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) ...@@ -1169,7 +1171,8 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
"(mft_no 0x%lx, type 0x%x, " "(mft_no 0x%lx, type 0x%x, "
"name_len %i). Please report " "name_len %i). Please report "
"you saw this message to " "you saw this message to "
"linux-ntfs-dev@lists.sf.net", "linux-ntfs-dev@lists."
"sourceforge.net",
vi->i_ino, ni->type, vi->i_ino, ni->type,
ni->name_len); ni->name_len);
goto unm_err_out; goto unm_err_out;
...@@ -1224,8 +1227,9 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) ...@@ -1224,8 +1227,9 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
"type 0x%x, name_len %i). " "type 0x%x, name_len %i). "
"Please report you saw this " "Please report you saw this "
"message to linux-ntfs-dev@" "message to linux-ntfs-dev@"
"lists.sf.net", vi->i_ino, "lists.sourceforge.net",
ni->type, ni->name_len); vi->i_ino, ni->type,
ni->name_len);
goto unm_err_out; goto unm_err_out;
} }
NInoSetEncrypted(ni); NInoSetEncrypted(ni);
...@@ -1238,8 +1242,9 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) ...@@ -1238,8 +1242,9 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
"type 0x%x, name_len %i). " "type 0x%x, name_len %i). "
"Please report you saw this " "Please report you saw this "
"message to linux-ntfs-dev@" "message to linux-ntfs-dev@"
"lists.sf.net", vi->i_ino, "lists.sourceforge.net",
ni->type, ni->name_len); vi->i_ino, ni->type,
ni->name_len);
goto unm_err_out; goto unm_err_out;
} }
NInoSetSparse(ni); NInoSetSparse(ni);
...@@ -1414,7 +1419,7 @@ void ntfs_read_inode_mount(struct inode *vi) ...@@ -1414,7 +1419,7 @@ void ntfs_read_inode_mount(struct inode *vi)
} }
/* Need this to sanity check attribute list references to $MFT. */ /* Need this to sanity check attribute list references to $MFT. */
ni->seq_no = le16_to_cpu(m->sequence_number); vi->i_generation = ni->seq_no = le16_to_cpu(m->sequence_number);
/* Provides readpage() and sync_page() for map_mft_record(). */ /* Provides readpage() and sync_page() for map_mft_record(). */
vi->i_mapping->a_ops = &ntfs_mft_aops; vi->i_mapping->a_ops = &ntfs_mft_aops;
...@@ -1541,7 +1546,8 @@ void ntfs_read_inode_mount(struct inode *vi) ...@@ -1541,7 +1546,8 @@ void ntfs_read_inode_mount(struct inode *vi)
"of $MFT is not in the base " "of $MFT is not in the base "
"mft record. Please report " "mft record. Please report "
"you saw this message to " "you saw this message to "
"linux-ntfs-dev@lists.sf.net"); "linux-ntfs-dev@lists."
"sourceforge.net");
goto put_err_out; goto put_err_out;
} else { } else {
/* Sequence numbers must match. */ /* Sequence numbers must match. */
...@@ -1662,7 +1668,8 @@ void ntfs_read_inode_mount(struct inode *vi) ...@@ -1662,7 +1668,8 @@ void ntfs_read_inode_mount(struct inode *vi)
"Run chkdsk and if no errors " "Run chkdsk and if no errors "
"are found, please report you " "are found, please report you "
"saw this message to " "saw this message to "
"linux-ntfs-dev@lists.sf.net"); "linux-ntfs-dev@lists."
"sourceforge.net");
put_attr_search_ctx(ctx); put_attr_search_ctx(ctx);
/* Revert to the safe super operations. */ /* Revert to the safe super operations. */
sb->s_op = &ntfs_mount_sops; sb->s_op = &ntfs_mount_sops;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* layout.h - All NTFS associated on-disk structures. Part of the Linux-NTFS * layout.h - All NTFS associated on-disk structures. Part of the Linux-NTFS
* project. * project.
* *
* Copyright (c) 2001-2003 Anton Altaparmakov * Copyright (c) 2001-2004 Anton Altaparmakov
* Copyright (c) 2002 Richard Russon * Copyright (c) 2002 Richard Russon
* *
* This program/include file is free software; you can redistribute it and/or * This program/include file is free software; you can redistribute it and/or
...@@ -941,7 +941,7 @@ typedef struct { ...@@ -941,7 +941,7 @@ typedef struct {
modified. */ modified. */
/* 18*/ s64 last_mft_change_time; /* Time this mft record was last /* 18*/ s64 last_mft_change_time; /* Time this mft record was last
modified. */ modified. */
/* 20*/ s64 last_access_time; /* Last time this mft record was /* 20*/ s64 last_access_time; /* Time this mft record was last
accessed. */ accessed. */
/* 28*/ s64 allocated_size; /* Byte size of allocated space for the /* 28*/ s64 allocated_size; /* Byte size of allocated space for the
data attribute. NOTE: Is a multiple data attribute. NOTE: Is a multiple
......
This diff is collapsed.
/* /*
* super.c - NTFS kernel super block handling. Part of the Linux-NTFS project. * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project.
* *
* Copyright (c) 2001-2003 Anton Altaparmakov * Copyright (c) 2001-2004 Anton Altaparmakov
* Copyright (c) 2001,2002 Richard Russon * Copyright (c) 2001,2002 Richard Russon
* *
* This program/include file is free software; you can redistribute it and/or * This program/include file is free software; you can redistribute it and/or
...@@ -323,6 +323,9 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) ...@@ -323,6 +323,9 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
return -EROFS; return -EROFS;
} }
} }
// TODO: For now we enforce no atime and dir atime updates as they are
// not implemented.
*flags |= MS_NOATIME | MS_NODIRATIME;
#endif #endif
// FIXME/TODO: If left like this we will have problems with rw->ro and // FIXME/TODO: If left like this we will have problems with rw->ro and
...@@ -1338,6 +1341,40 @@ struct super_operations ntfs_sops = { ...@@ -1338,6 +1341,40 @@ struct super_operations ntfs_sops = {
.show_options = ntfs_show_options, /* Show mount options in proc. */ .show_options = ntfs_show_options, /* Show mount options in proc. */
}; };
/**
* Declarations for NTFS specific export operations (fs/ntfs/namei.c).
*/
extern struct dentry *ntfs_get_parent(struct dentry *child_dent);
extern struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh);
/**
* Export operations allowing NFS exporting of mounted NTFS partitions.
*
* We use the default ->decode_fh() and ->encode_fh() for now. Note that they
* use 32 bits to store the inode number which is an unsigned long so on 64-bit
* architectures is usually 64 bits so it would all fail horribly on huge
* volumes. I guess we need to define our own encode and decode fh functions
* that store 64-bit inode numbers at some point but for now we will ignore the
* problem...
*
* We also use the default ->get_name() helper (used by ->decode_fh() via
* fs/exportfs/expfs.c::find_exported_dentry()) as that is completely fs
* independent.
*
* The default ->get_parent() just returns -EACCES so we have to provide our
* own and the default ->get_dentry() is incompatible with NTFS due to not
* allowing the inode number 0 which is used in NTFS for the system file $MFT
* and due to using iget() whereas NTFS needs ntfs_iget().
*/
static struct export_operations ntfs_export_ops = {
.get_parent = ntfs_get_parent, /* Find the parent of a given
directory. */
.get_dentry = ntfs_get_dentry, /* Find a dentry for the inode
given a file handle
sub-fragment. */
};
/** /**
* ntfs_fill_super - mount an ntfs files system * ntfs_fill_super - mount an ntfs files system
* @sb: super block of ntfs file system to mount * @sb: super block of ntfs file system to mount
...@@ -1366,6 +1403,10 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) ...@@ -1366,6 +1403,10 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
ntfs_debug("Entering."); ntfs_debug("Entering.");
#ifndef NTFS_RW #ifndef NTFS_RW
sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
#else
// TODO: For now we enforce no atime and dir atime updates as they are
// not implemented.
sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
#endif #endif
/* Allocate a new ntfs_volume and place it in sb->s_fs_info. */ /* Allocate a new ntfs_volume and place it in sb->s_fs_info. */
sb->s_fs_info = kmalloc(sizeof(ntfs_volume), GFP_NOFS); sb->s_fs_info = kmalloc(sizeof(ntfs_volume), GFP_NOFS);
...@@ -1544,6 +1585,7 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) ...@@ -1544,6 +1585,7 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
default_upcase = NULL; default_upcase = NULL;
} }
up(&ntfs_lock); up(&ntfs_lock);
sb->s_export_op = &ntfs_export_ops;
return 0; return 0;
} }
ntfs_error(sb, "Failed to allocate root directory."); ntfs_error(sb, "Failed to allocate root directory.");
...@@ -1788,13 +1830,13 @@ static void __exit exit_ntfs_fs(void) ...@@ -1788,13 +1830,13 @@ static void __exit exit_ntfs_fs(void)
printk(KERN_CRIT "NTFS: This causes memory to leak! There is " printk(KERN_CRIT "NTFS: This causes memory to leak! There is "
"probably a BUG in the driver! Please report " "probably a BUG in the driver! Please report "
"you saw this message to " "you saw this message to "
"linux-ntfs-dev@lists.sf.net\n"); "linux-ntfs-dev@lists.sourceforge.net\n");
/* Unregister the ntfs sysctls. */ /* Unregister the ntfs sysctls. */
ntfs_sysctl(0); ntfs_sysctl(0);
} }
MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>"); MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>");
MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2003 Anton Altaparmakov"); MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2004 Anton Altaparmakov");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#ifdef DEBUG #ifdef DEBUG
MODULE_PARM(debug_msgs, "i"); MODULE_PARM(debug_msgs, "i");
......
/* /*
* unistr.c - NTFS Unicode string handling. Part of the Linux-NTFS project. * unistr.c - NTFS Unicode string handling. Part of the Linux-NTFS project.
* *
* Copyright (c) 2001-2003 Anton Altaparmakov * Copyright (c) 2001-2004 Anton Altaparmakov
* *
* This program/include file is free software; you can redistribute it and/or * 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 * modify it under the terms of the GNU General Public License as published
...@@ -305,8 +305,9 @@ int ntfs_nlstoucs(const ntfs_volume *vol, const char *ins, ...@@ -305,8 +305,9 @@ int ntfs_nlstoucs(const ntfs_volume *vol, const char *ins,
* Convert the input little endian, 2-byte Unicode string @ins, of length * Convert the input little endian, 2-byte Unicode string @ins, of length
* @ins_len into the string format dictated by the loaded NLS. * @ins_len into the string format dictated by the loaded NLS.
* *
* If @outs is NULL, this function allocates the string and the caller is * If *@outs is NULL, this function allocates the string and the caller is
* responsible for calling kfree(@outs); when finished with it. * responsible for calling kfree(*@outs); when finished with it. In this case
* @outs_len is ignored and can be 0.
* *
* On success the function returns the number of bytes written to the output * On success the function returns the number of bytes written to the output
* string *@outs (>= 0), not counting the terminating NULL byte. If the output * string *@outs (>= 0), not counting the terminating NULL byte. If the output
......
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