Commit fec95414 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[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.
parent 1ce35178
......@@ -1310,7 +1310,7 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
* 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;
}
/**
......
......@@ -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);
......
......@@ -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
......
......@@ -1584,19 +1584,6 @@ static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs)
return 0;
}
/**
* 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.
*/
......@@ -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 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
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)
......
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