NTFS: Remove all the make_bad_inode() calls. This should only be called
[pandora-kernel.git] / fs / ntfs / mft.c
index b011369..7254391 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2005 Anton Altaparmakov
+ * Copyright (c) 2001-2006 Anton Altaparmakov
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -49,7 +49,8 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni)
        ntfs_volume *vol = ni->vol;
        struct inode *mft_vi = vol->mft_ino;
        struct page *page;
-       unsigned long index, ofs, end_index;
+       unsigned long index, end_index;
+       unsigned ofs;
 
        BUG_ON(ni->page);
        /*
@@ -92,6 +93,7 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni)
                                "Run chkdsk.", ni->mft_no);
                ntfs_unmap_page(page);
                page = ERR_PTR(-EIO);
+               NVolSetErrors(vol);
        }
 err_out:
        ni->page = NULL;
@@ -472,7 +474,7 @@ int ntfs_sync_mft_mirror(ntfs_volume *vol, const unsigned long mft_no,
        runlist_element *rl;
        unsigned int block_start, block_end, m_start, m_end, page_ofs;
        int i_bhs, nr_bhs, err = 0;
-       unsigned char blocksize_bits = vol->mftmirr_ino->i_blkbits;
+       unsigned char blocksize_bits = vol->sb->s_blocksize_bits;
 
        ntfs_debug("Entering for inode 0x%lx.", mft_no);
        BUG_ON(!max_bhs);
@@ -671,8 +673,8 @@ int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync)
 {
        ntfs_volume *vol = ni->vol;
        struct page *page = ni->page;
-       unsigned char blocksize_bits = vol->mft_ino->i_blkbits;
-       unsigned int blocksize = 1 << blocksize_bits;
+       unsigned int blocksize = vol->sb->s_blocksize;
+       unsigned char blocksize_bits = vol->sb->s_blocksize_bits;
        int max_bhs = vol->mft_record_size / blocksize;
        struct buffer_head *bhs[max_bhs];
        struct buffer_head *bh, *head;
@@ -1308,7 +1310,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
        ll = mftbmp_ni->allocated_size;
        read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
        rl = ntfs_attr_find_vcn_nolock(mftbmp_ni,
-                       (ll - 1) >> vol->cluster_size_bits, TRUE);
+                       (ll - 1) >> vol->cluster_size_bits, NULL);
        if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {
                up_write(&mftbmp_ni->runlist.lock);
                ntfs_error(vol->sb, "Failed to determine last allocated "
@@ -1354,7 +1356,8 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
                up_write(&vol->lcnbmp_lock);
                ntfs_unmap_page(page);
                /* Allocate a cluster from the DATA_ZONE. */
-               rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE);
+               rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE,
+                               TRUE);
                if (IS_ERR(rl2)) {
                        up_write(&mftbmp_ni->runlist.lock);
                        ntfs_error(vol->sb, "Failed to allocate a cluster for "
@@ -1738,7 +1741,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
        ll = mft_ni->allocated_size;
        read_unlock_irqrestore(&mft_ni->size_lock, flags);
        rl = ntfs_attr_find_vcn_nolock(mft_ni,
-                       (ll - 1) >> vol->cluster_size_bits, TRUE);
+                       (ll - 1) >> vol->cluster_size_bits, NULL);
        if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {
                up_write(&mft_ni->runlist.lock);
                ntfs_error(vol->sb, "Failed to determine last allocated "
@@ -1779,7 +1782,8 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
                        nr > min_nr ? "default" : "minimal", (long long)nr);
        old_last_vcn = rl[1].vcn;
        do {
-               rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE);
+               rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE,
+                               TRUE);
                if (likely(!IS_ERR(rl2)))
                        break;
                if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) {
@@ -1951,20 +1955,21 @@ restore_undo_alloc:
                NVolSetErrors(vol);
                return ret;
        }
-       a = ctx->attr;
-       a->data.non_resident.highest_vcn = cpu_to_sle64(old_last_vcn - 1);
+       ctx->attr->data.non_resident.highest_vcn =
+                       cpu_to_sle64(old_last_vcn - 1);
 undo_alloc:
-       if (ntfs_cluster_free(mft_ni, old_last_vcn, -1) < 0) {
+       if (ntfs_cluster_free(mft_ni, old_last_vcn, -1, ctx) < 0) {
                ntfs_error(vol->sb, "Failed to free clusters from mft data "
                                "attribute.%s", es);
                NVolSetErrors(vol);
        }
+       a = ctx->attr;
        if (ntfs_rl_truncate_nolock(vol, &mft_ni->runlist, old_last_vcn)) {
                ntfs_error(vol->sb, "Failed to truncate mft data attribute "
                                "runlist.%s", es);
                NVolSetErrors(vol);
        }
-       if (mp_rebuilt) {
+       if (mp_rebuilt && !IS_ERR(ctx->mrec)) {
                if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(
                                a->data.non_resident.mapping_pairs_offset),
                                old_alen - le16_to_cpu(
@@ -1981,6 +1986,10 @@ undo_alloc:
                }
                flush_dcache_mft_record_page(ctx->ntfs_ino);
                mark_mft_record_dirty(ctx->ntfs_ino);
+       } else if (IS_ERR(ctx->mrec)) {
+               ntfs_error(vol->sb, "Failed to restore attribute search "
+                               "context.%s", es);
+               NVolSetErrors(vol);
        }
        if (ctx)
                ntfs_attr_put_search_ctx(ctx);