summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Viro <viro@parcelfarce.linux.theplanet.co.uk>2004-05-10 02:13:18 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-05-10 02:13:18 -0700
commitfec95414a1bf1939b1b22ceca6b033be7ccb2d1d (patch)
tree855689a83aefcda155fa7fbb63f88c4bf2436e6b
parent1ce351789ad5ea21ff9a9d451cc3b3e292cce425 (diff)
[PATCH] ntfs cleanup
ntfs_fill_super() and ntfs_read_inode_mount() cleaned up. Removed the kludges around the first iget() on NTFS. Instead of playing with (re)setting ->s_op we have the MFT_FILE inode set up by explicit new_inode()/ set ->i_ino/insert_inode_hash()/call ntfs_read_inode_mount() directly. That kills the need of second super_operations and it allows to return error from ntfs_read_inode_mount() without resorting to ugly "poisoning" tricks.
-rw-r--r--fs/ntfs/inode.c29
-rw-r--r--fs/ntfs/inode.h2
-rw-r--r--fs/ntfs/ntfs.h10
-rw-r--r--fs/ntfs/super.c45
4 files changed, 20 insertions, 66 deletions
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index cb8c51959a71..d3276aeb66bb 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -1310,7 +1310,7 @@ err_out:
* This should work but there are two possible pit falls (see inline comments
* below), but only time will tell if they are real pits or just smoke...
*/
-void ntfs_read_inode_mount(struct inode *vi)
+int ntfs_read_inode_mount(struct inode *vi)
{
VCN next_vcn, last_vcn, highest_vcn;
s64 block;
@@ -1326,12 +1326,6 @@ void ntfs_read_inode_mount(struct inode *vi)
ntfs_debug("Entering.");
- if (vi->i_ino != FILE_MFT) {
- ntfs_error(sb, "Called for inode 0x%lx but only inode %d "
- "allowed.", vi->i_ino, FILE_MFT);
- goto err_out;
- }
-
/* Initialize the ntfs specific part of @vi. */
ntfs_init_big_inode(vi);
@@ -1616,13 +1610,7 @@ void ntfs_read_inode_mount(struct inode *vi)
/*
* We have got the first extent of the run_list for
* $MFT which means it is now relatively safe to call
- * the normal ntfs_read_inode() function. Thus, take
- * us out of the calling chain. Also we need to do this
- * now because we need ntfs_read_inode() in place to
- * get at subsequent extents.
- */
- sb->s_op = &ntfs_sops;
- /*
+ * the normal ntfs_read_inode() function.
* Complete reading the inode, this will actually
* re-read the mft record for $MFT, this time entering
* it into the page cache with which we complete the
@@ -1649,8 +1637,8 @@ void ntfs_read_inode_mount(struct inode *vi)
"sourceforge.net");
put_attr_search_ctx(ctx);
/* Revert to the safe super operations. */
- sb->s_op = &ntfs_mount_sops;
- goto out_now;
+ ntfs_free(m);
+ return -1;
}
/*
* Re-initialize some specifics about $MFT's inode as
@@ -1699,20 +1687,19 @@ void ntfs_read_inode_mount(struct inode *vi)
}
put_attr_search_ctx(ctx);
ntfs_debug("Done.");
-out_now:
ntfs_free(m);
- return;
+ return 0;
+
em_put_err_out:
ntfs_error(sb, "Couldn't find first extent of $DATA attribute in "
"attribute list. $MFT is corrupt. Run chkdsk.");
put_err_out:
put_attr_search_ctx(ctx);
err_out:
- /* Make sure we revert to the safe super operations. */
- sb->s_op = &ntfs_mount_sops;
ntfs_error(sb, "Failed. Marking inode as bad.");
make_bad_inode(vi);
- goto out_now;
+ ntfs_free(m);
+ return -1;
}
/**
diff --git a/fs/ntfs/inode.h b/fs/ntfs/inode.h
index 31d522034498..8e6a74e0f959 100644
--- a/fs/ntfs/inode.h
+++ b/fs/ntfs/inode.h
@@ -269,7 +269,7 @@ extern ntfs_inode *ntfs_new_extent_inode(struct super_block *sb,
unsigned long mft_no);
extern void ntfs_clear_extent_inode(ntfs_inode *ni);
-extern void ntfs_read_inode_mount(struct inode *vi);
+extern int ntfs_read_inode_mount(struct inode *vi);
extern void ntfs_put_inode(struct inode *vi);
diff --git a/fs/ntfs/ntfs.h b/fs/ntfs/ntfs.h
index 82f17d696046..9e6d13c6cee2 100644
--- a/fs/ntfs/ntfs.h
+++ b/fs/ntfs/ntfs.h
@@ -61,8 +61,6 @@ extern kmem_cache_t *ntfs_attr_ctx_cache;
/* The various operations structs defined throughout the driver files. */
extern struct super_operations ntfs_sops;
-extern struct super_operations ntfs_mount_sops;
-
extern struct address_space_operations ntfs_aops;
extern struct address_space_operations ntfs_mft_aops;
@@ -75,14 +73,6 @@ extern struct inode_operations ntfs_dir_inode_ops;
extern struct file_operations ntfs_empty_file_ops;
extern struct inode_operations ntfs_empty_inode_ops;
-/* Generic macros to convert pointers to values and vice versa. */
-#ifndef p2n
-#define p2n(p) ((ptrdiff_t)((ptrdiff_t*)(p)))
-#endif
-#ifndef n2p
-#define n2p(p) ((ptrdiff_t*)((ptrdiff_t)(p)))
-#endif
-
/**
* NTFS_SB - return the ntfs volume given a vfs super block
* @sb: VFS super block
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index e5aa70018a12..dfe3b3c0abee 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1585,19 +1585,6 @@ static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs)
}
/**
- * Super operations for mount time when we don't have enough setup to use the
- * proper functions.
- */
-struct super_operations ntfs_mount_sops = {
- .alloc_inode = ntfs_alloc_big_inode, /* VFS: Allocate new inode. */
- .destroy_inode = ntfs_destroy_big_inode, /* VFS: Deallocate inode. */
- .read_inode = ntfs_read_inode_mount, /* VFS: Load inode from disk,
- called from iget(). */
- .clear_inode = ntfs_clear_big_inode, /* VFS: Called when inode is
- removed from memory. */
-};
-
-/**
* The complete super operations.
*/
struct super_operations ntfs_sops = {
@@ -1814,28 +1801,20 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
* the inode for $MFT which is sufficient to allow our normal inode
* operations and associated address space operations to function.
*/
- /*
- * Poison vol->mft_ino so we know whether iget() called into our
- * ntfs_read_inode_mount() method.
- */
-#define OGIN ((struct inode*)n2p(le32_to_cpu(0x4e49474f))) /* OGIN */
- vol->mft_ino = OGIN;
- sb->s_op = &ntfs_mount_sops;
- tmp_ino = iget(vol->sb, FILE_MFT);
- if (!tmp_ino || tmp_ino != vol->mft_ino || is_bad_inode(tmp_ino)) {
+ sb->s_op = &ntfs_sops;
+ tmp_ino = new_inode(sb);
+ if (!tmp_ino) {
+ if (!silent)
+ ntfs_error(sb, "Failed to load essential metadata.");
+ goto err_out_now;
+ }
+ tmp_ino->i_ino = FILE_MFT;
+ insert_inode_hash(tmp_ino);
+ if (ntfs_read_inode_mount(tmp_ino) < 0) {
if (!silent)
ntfs_error(sb, "Failed to load essential metadata.");
- if (tmp_ino && vol->mft_ino == OGIN)
- ntfs_error(sb, "BUG: iget() did not call "
- "ntfs_read_inode_mount() method!\n");
- if (!tmp_ino)
- goto cond_iput_mft_ino_err_out_now;
goto iput_tmp_ino_err_out_now;
}
- /*
- * Note: sb->s_op has already been set to &ntfs_sops by our specialized
- * ntfs_read_inode_mount() method when it was invoked by iget().
- */
down(&ntfs_lock);
/*
* The current mount is a compression user if the cluster size is
@@ -1931,12 +1910,10 @@ unl_upcase_iput_tmp_ino_err_out_now:
up(&ntfs_lock);
iput_tmp_ino_err_out_now:
iput(tmp_ino);
-cond_iput_mft_ino_err_out_now:
- if (vol->mft_ino && vol->mft_ino != OGIN && vol->mft_ino != tmp_ino) {
+ if (vol->mft_ino && vol->mft_ino != tmp_ino) {
iput(vol->mft_ino);
vol->mft_ino = NULL;
}
-#undef OGIN
/*
* This is needed to get ntfs_clear_extent_inode() called for each
* inode we have ever called ntfs_iget()/iput() on, otherwise we A)