diff options
Diffstat (limited to 'fs/ntfs/inode.c')
| -rw-r--r-- | fs/ntfs/inode.c | 111 | 
1 files changed, 66 insertions, 45 deletions
| diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 55263b7de9c..4c86b7e1d1e 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -1,7 +1,7 @@  /**   * inode.c - NTFS kernel inode handling. Part of the Linux-NTFS project.   * - * Copyright (c) 2001-2005 Anton Altaparmakov + * Copyright (c) 2001-2006 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 @@ -19,13 +19,19 @@   * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   */ -#include <linux/pagemap.h>  #include <linux/buffer_head.h> -#include <linux/smp_lock.h> -#include <linux/quotaops.h> +#include <linux/fs.h> +#include <linux/mm.h>  #include <linux/mount.h> +#include <linux/mutex.h> +#include <linux/pagemap.h> +#include <linux/quotaops.h> +#include <linux/slab.h> +#include <linux/smp_lock.h>  #include "aops.h" +#include "attrib.h" +#include "bitmap.h"  #include "dir.h"  #include "debug.h"  #include "inode.h" @@ -382,7 +388,7 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni)  	atomic_set(&ni->count, 1);  	ni->vol = NTFS_SB(sb);  	ntfs_init_runlist(&ni->runlist); -	init_MUTEX(&ni->mrec_lock); +	mutex_init(&ni->mrec_lock);  	ni->page = NULL;  	ni->page_ofs = 0;  	ni->attr_list_size = 0; @@ -394,7 +400,7 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni)  	ni->itype.index.collation_rule = 0;  	ni->itype.index.block_size_bits = 0;  	ni->itype.index.vcn_size_bits = 0; -	init_MUTEX(&ni->extent_lock); +	mutex_init(&ni->extent_lock);  	ni->nr_extents = 0;  	ni->ext.base_ntfs_ino = NULL;  } @@ -1064,10 +1070,10 @@ skip_large_dir_stuff:  		if (a->non_resident) {  			NInoSetNonResident(ni);  			if (NInoCompressed(ni) || NInoSparse(ni)) { -				if (a->data.non_resident.compression_unit != -						4) { +				if (NInoCompressed(ni) && a->data.non_resident. +						compression_unit != 4) {  					ntfs_error(vi->i_sb, "Found " -							"nonstandard " +							"non-standard "  							"compression unit (%u "  							"instead of 4).  "  							"Cannot handle this.", @@ -1076,16 +1082,26 @@ skip_large_dir_stuff:  					err = -EOPNOTSUPP;  					goto unm_err_out;  				} -				ni->itype.compressed.block_clusters = 1U << -						a->data.non_resident. -						compression_unit; -				ni->itype.compressed.block_size = 1U << ( -						a->data.non_resident. -						compression_unit + -						vol->cluster_size_bits); -				ni->itype.compressed.block_size_bits = ffs( -						ni->itype.compressed. -						block_size) - 1; +				if (a->data.non_resident.compression_unit) { +					ni->itype.compressed.block_size = 1U << +							(a->data.non_resident. +							compression_unit + +							vol->cluster_size_bits); +					ni->itype.compressed.block_size_bits = +							ffs(ni->itype. +							compressed. +							block_size) - 1; +					ni->itype.compressed.block_clusters = +							1U << a->data. +							non_resident. +							compression_unit; +				} else { +					ni->itype.compressed.block_size = 0; +					ni->itype.compressed.block_size_bits = +							0; +					ni->itype.compressed.block_clusters = +							0; +				}  				ni->itype.compressed.size = sle64_to_cpu(  						a->data.non_resident.  						compressed_size); @@ -1338,8 +1354,9 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)  			goto unm_err_out;  		}  		if (NInoCompressed(ni) || NInoSparse(ni)) { -			if (a->data.non_resident.compression_unit != 4) { -				ntfs_error(vi->i_sb, "Found nonstandard " +			if (NInoCompressed(ni) && a->data.non_resident. +					compression_unit != 4) { +				ntfs_error(vi->i_sb, "Found non-standard "  						"compression unit (%u instead "  						"of 4).  Cannot handle this.",  						a->data.non_resident. @@ -1347,13 +1364,22 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)  				err = -EOPNOTSUPP;  				goto unm_err_out;  			} -			ni->itype.compressed.block_clusters = 1U << -					a->data.non_resident.compression_unit; -			ni->itype.compressed.block_size = 1U << ( -					a->data.non_resident.compression_unit + -					vol->cluster_size_bits); -			ni->itype.compressed.block_size_bits = ffs( -					ni->itype.compressed.block_size) - 1; +			if (a->data.non_resident.compression_unit) { +				ni->itype.compressed.block_size = 1U << +						(a->data.non_resident. +						compression_unit + +						vol->cluster_size_bits); +				ni->itype.compressed.block_size_bits = +						ffs(ni->itype.compressed. +						block_size) - 1; +				ni->itype.compressed.block_clusters = 1U << +						a->data.non_resident. +						compression_unit; +			} else { +				ni->itype.compressed.block_size = 0; +				ni->itype.compressed.block_size_bits = 0; +				ni->itype.compressed.block_clusters = 0; +			}  			ni->itype.compressed.size = sle64_to_cpu(  					a->data.non_resident.compressed_size);  		} @@ -1406,7 +1432,6 @@ err_out:  			"Run chkdsk.", err, vi->i_ino, ni->type, ni->name_len,  			base_vi->i_ino);  	make_bad_inode(vi); -	make_bad_inode(base_vi);  	if (err != -ENOMEM)  		NVolSetErrors(vol);  	return err; @@ -1591,6 +1616,7 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi)  					"$INDEX_ALLOCATION attribute.");  		goto unm_err_out;  	} +	a = ctx->attr;  	if (!a->non_resident) {  		ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is "  				"resident."); @@ -2823,11 +2849,8 @@ done:  old_bad_out:  	old_size = -1;  bad_out: -	if (err != -ENOMEM && err != -EOPNOTSUPP) { -		make_bad_inode(vi); -		make_bad_inode(VFS_I(base_ni)); +	if (err != -ENOMEM && err != -EOPNOTSUPP)  		NVolSetErrors(vol); -	}  	if (err != -EOPNOTSUPP)  		NInoSetTruncateFailed(ni);  	else if (old_size >= 0) @@ -2842,11 +2865,8 @@ out:  	ntfs_debug("Failed.  Returning error code %i.", err);  	return err;  conv_err_out: -	if (err != -ENOMEM && err != -EOPNOTSUPP) { -		make_bad_inode(vi); -		make_bad_inode(VFS_I(base_ni)); +	if (err != -ENOMEM && err != -EOPNOTSUPP)  		NVolSetErrors(vol); -	}  	if (err != -EOPNOTSUPP)  		NInoSetTruncateFailed(ni);  	else @@ -3044,15 +3064,18 @@ int ntfs_write_inode(struct inode *vi, int sync)  	 * record will be cleaned and written out to disk below, i.e. before  	 * this function returns.  	 */ -	if (modified && !NInoTestSetDirty(ctx->ntfs_ino)) -		mark_ntfs_record_dirty(ctx->ntfs_ino->page, -				ctx->ntfs_ino->page_ofs); +	if (modified) { +		flush_dcache_mft_record_page(ctx->ntfs_ino); +		if (!NInoTestSetDirty(ctx->ntfs_ino)) +			mark_ntfs_record_dirty(ctx->ntfs_ino->page, +					ctx->ntfs_ino->page_ofs); +	}  	ntfs_attr_put_search_ctx(ctx);  	/* Now the access times are updated, write the base mft record. */  	if (NInoDirty(ni))  		err = write_mft_record(ni, m, sync);  	/* Write all attached extent mft records. */ -	down(&ni->extent_lock); +	mutex_lock(&ni->extent_lock);  	if (ni->nr_extents > 0) {  		ntfs_inode **extent_nis = ni->ext.extent_ntfs_inos;  		int i; @@ -3079,7 +3102,7 @@ int ntfs_write_inode(struct inode *vi, int sync)  			}  		}  	} -	up(&ni->extent_lock); +	mutex_unlock(&ni->extent_lock);  	unmap_mft_record(ni);  	if (unlikely(err))  		goto err_out; @@ -3094,9 +3117,7 @@ err_out:  				"retries later.");  		mark_inode_dirty(vi);  	} else { -		ntfs_error(vi->i_sb, "Failed (error code %i):  Marking inode " -				"as bad.  You should run chkdsk.", -err); -		make_bad_inode(vi); +		ntfs_error(vi->i_sb, "Failed (error %i):  Run chkdsk.", -err);  		NVolSetErrors(ni->vol);  	}  	return err; | 
