linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / fs / ntfs / inode.c
index 4c86b7e..55263b7 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * inode.c - NTFS kernel inode handling. Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2006 Anton Altaparmakov
+ * Copyright (c) 2001-2005 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
  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <linux/buffer_head.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/buffer_head.h>
 #include <linux/smp_lock.h>
+#include <linux/quotaops.h>
+#include <linux/mount.h>
 
 #include "aops.h"
-#include "attrib.h"
-#include "bitmap.h"
 #include "dir.h"
 #include "debug.h"
 #include "inode.h"
@@ -388,7 +382,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);
-       mutex_init(&ni->mrec_lock);
+       init_MUTEX(&ni->mrec_lock);
        ni->page = NULL;
        ni->page_ofs = 0;
        ni->attr_list_size = 0;
@@ -400,7 +394,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;
-       mutex_init(&ni->extent_lock);
+       init_MUTEX(&ni->extent_lock);
        ni->nr_extents = 0;
        ni->ext.base_ntfs_ino = NULL;
 }
@@ -1070,10 +1064,10 @@ skip_large_dir_stuff:
                if (a->non_resident) {
                        NInoSetNonResident(ni);
                        if (NInoCompressed(ni) || NInoSparse(ni)) {
-                               if (NInoCompressed(ni) && a->data.non_resident.
-                                               compression_unit != 4) {
+                               if (a->data.non_resident.compression_unit !=
+                                               4) {
                                        ntfs_error(vi->i_sb, "Found "
-                                                       "non-standard "
+                                                       "nonstandard "
                                                        "compression unit (%u "
                                                        "instead of 4).  "
                                                        "Cannot handle this.",
@@ -1082,26 +1076,16 @@ skip_large_dir_stuff:
                                        err = -EOPNOTSUPP;
                                        goto unm_err_out;
                                }
-                               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.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;
                                ni->itype.compressed.size = sle64_to_cpu(
                                                a->data.non_resident.
                                                compressed_size);
@@ -1354,9 +1338,8 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
                        goto unm_err_out;
                }
                if (NInoCompressed(ni) || NInoSparse(ni)) {
-                       if (NInoCompressed(ni) && a->data.non_resident.
-                                       compression_unit != 4) {
-                               ntfs_error(vi->i_sb, "Found non-standard "
+                       if (a->data.non_resident.compression_unit != 4) {
+                               ntfs_error(vi->i_sb, "Found nonstandard "
                                                "compression unit (%u instead "
                                                "of 4).  Cannot handle this.",
                                                a->data.non_resident.
@@ -1364,22 +1347,13 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
                                err = -EOPNOTSUPP;
                                goto unm_err_out;
                        }
-                       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.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;
                        ni->itype.compressed.size = sle64_to_cpu(
                                        a->data.non_resident.compressed_size);
                }
@@ -1432,6 +1406,7 @@ 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;
@@ -1616,7 +1591,6 @@ 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.");
@@ -2849,8 +2823,11 @@ done:
 old_bad_out:
        old_size = -1;
 bad_out:
-       if (err != -ENOMEM && err != -EOPNOTSUPP)
+       if (err != -ENOMEM && err != -EOPNOTSUPP) {
+               make_bad_inode(vi);
+               make_bad_inode(VFS_I(base_ni));
                NVolSetErrors(vol);
+       }
        if (err != -EOPNOTSUPP)
                NInoSetTruncateFailed(ni);
        else if (old_size >= 0)
@@ -2865,8 +2842,11 @@ out:
        ntfs_debug("Failed.  Returning error code %i.", err);
        return err;
 conv_err_out:
-       if (err != -ENOMEM && err != -EOPNOTSUPP)
+       if (err != -ENOMEM && err != -EOPNOTSUPP) {
+               make_bad_inode(vi);
+               make_bad_inode(VFS_I(base_ni));
                NVolSetErrors(vol);
+       }
        if (err != -EOPNOTSUPP)
                NInoSetTruncateFailed(ni);
        else
@@ -3064,18 +3044,15 @@ 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) {
-               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);
-       }
+       if (modified && !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. */
-       mutex_lock(&ni->extent_lock);
+       down(&ni->extent_lock);
        if (ni->nr_extents > 0) {
                ntfs_inode **extent_nis = ni->ext.extent_ntfs_inos;
                int i;
@@ -3102,7 +3079,7 @@ int ntfs_write_inode(struct inode *vi, int sync)
                        }
                }
        }
-       mutex_unlock(&ni->extent_lock);
+       up(&ni->extent_lock);
        unmap_mft_record(ni);
        if (unlikely(err))
                goto err_out;
@@ -3117,7 +3094,9 @@ err_out:
                                "retries later.");
                mark_inode_dirty(vi);
        } else {
-               ntfs_error(vi->i_sb, "Failed (error %i):  Run chkdsk.", -err);
+               ntfs_error(vi->i_sb, "Failed (error code %i):  Marking inode "
+                               "as bad.  You should run chkdsk.", -err);
+               make_bad_inode(vi);
                NVolSetErrors(ni->vol);
        }
        return err;