diff options
author | Anton Altaparmakov <aia21@cantab.net> | 2005-02-15 10:08:43 +0000 |
---|---|---|
committer | Anton Altaparmakov <aia21@cantab.net> | 2005-05-05 10:56:31 +0100 |
commit | b6ad6c52fe36ab35d0fe28c064f59de2ba670c2a (patch) | |
tree | d888c28a2c3c7fa733045dc7dc9c9bc7f157bf4a /fs/ntfs/mft.c | |
parent | 1a0df15acdae065789446aca83021c72b71db9a5 (diff) | |
download | blackbird-op-linux-b6ad6c52fe36ab35d0fe28c064f59de2ba670c2a.tar.gz blackbird-op-linux-b6ad6c52fe36ab35d0fe28c064f59de2ba670c2a.zip |
NTFS: - Split ntfs_map_runlist() into ntfs_map_runlist() and a non-locking
helper ntfs_map_runlist_nolock() which is used by ntfs_map_runlist().
This allows us to map runlist fragments with the runlist lock already
held without having to drop and reacquire it around the call. Adapt
all callers.
- Change ntfs_find_vcn() to ntfs_find_vcn_nolock() which takes a locked
runlist. This allows us to find runlist elements with the runlist
lock already held without having to drop and reacquire it around the
call. Adapt all callers.
Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Diffstat (limited to 'fs/ntfs/mft.c')
-rw-r--r-- | fs/ntfs/mft.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c index 4e0bf39426cf..0975d738834c 100644 --- a/fs/ntfs/mft.c +++ b/fs/ntfs/mft.c @@ -1,7 +1,7 @@ /** * mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project. * - * Copyright (c) 2001-2004 Anton Altaparmakov + * Copyright (c) 2001-2005 Anton Altaparmakov * Copyright (c) 2002 Richard Russon * * This program/include file is free software; you can redistribute it and/or @@ -287,7 +287,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref, } unmap_mft_record(ni); ntfs_error(base_ni->vol->sb, "Found stale extent mft " - "reference! Corrupt file system. " + "reference! Corrupt filesystem. " "Run chkdsk."); return ERR_PTR(-EIO); } @@ -318,7 +318,7 @@ map_err_out: /* Verify the sequence number if it is present. */ if (seq_no && (le16_to_cpu(m->sequence_number) != seq_no)) { ntfs_error(base_ni->vol->sb, "Found stale extent mft " - "reference! Corrupt file system. Run chkdsk."); + "reference! Corrupt filesystem. Run chkdsk."); destroy_ni = TRUE; m = ERR_PTR(-EIO); goto unm_err_out; @@ -1292,19 +1292,20 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) /* * Determine the last lcn of the mft bitmap. The allocated size of the * mft bitmap cannot be zero so we are ok to do this. - * ntfs_find_vcn() returns the runlist locked on success. */ + down_write(&mftbmp_ni->runlist.lock); read_lock_irqsave(&mftbmp_ni->size_lock, flags); ll = mftbmp_ni->allocated_size; read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); - rl = ntfs_find_vcn(mftbmp_ni, (ll - 1) >> vol->cluster_size_bits, TRUE); + rl = ntfs_find_vcn_nolock(mftbmp_ni, + (ll - 1) >> vol->cluster_size_bits, TRUE); 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 " "cluster of mft bitmap attribute."); - if (!IS_ERR(rl)) { - up_write(&mftbmp_ni->runlist.lock); + if (!IS_ERR(rl)) ret = -EIO; - } else + else ret = PTR_ERR(rl); return ret; } @@ -1428,6 +1429,8 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) // TODO: Deal with this by moving this extent to a new mft // record or by starting a new extent in a new mft record or by // moving other attributes out of this mft record. + // Note: It will need to be a special mft record and if none of + // those are available it gets rather complicated... ntfs_error(vol->sb, "Not enough space in this mft record to " "accomodate extended mft bitmap attribute " "extent. Cannot handle this yet."); @@ -1719,19 +1722,20 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) * Determine the preferred allocation location, i.e. the last lcn of * the mft data attribute. The allocated size of the mft data * attribute cannot be zero so we are ok to do this. - * ntfs_find_vcn() returns the runlist locked on success. */ + down_write(&mft_ni->runlist.lock); read_lock_irqsave(&mft_ni->size_lock, flags); ll = mft_ni->allocated_size; read_unlock_irqrestore(&mft_ni->size_lock, flags); - rl = ntfs_find_vcn(mft_ni, (ll - 1) >> vol->cluster_size_bits, TRUE); + rl = ntfs_find_vcn_nolock(mft_ni, (ll - 1) >> vol->cluster_size_bits, + TRUE); 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 " "cluster of mft data attribute."); - if (!IS_ERR(rl)) { - up_write(&mft_ni->runlist.lock); + if (!IS_ERR(rl)) ret = -EIO; - } else + else ret = PTR_ERR(rl); return ret; } @@ -1858,7 +1862,11 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) // moving other attributes out of this mft record. // Note: Use the special reserved mft records and ensure that // this extent is not required to find the mft record in - // question. + // question. If no free special records left we would need to + // move an existing record away, insert ours in its place, and + // then place the moved record into the newly allocated space + // and we would then need to update all references to this mft + // record appropriately. This is rather complicated... ntfs_error(vol->sb, "Not enough space in this mft record to " "accomodate extended mft data attribute " "extent. Cannot handle this yet."); @@ -2021,7 +2029,7 @@ static int ntfs_mft_record_layout(const ntfs_volume *vol, const s64 mft_no, "reports this as corruption, please email " "linux-ntfs-dev@lists.sourceforge.net stating " "that you saw this message and that the " - "modified file system created was corrupt. " + "modified filesystem created was corrupt. " "Thank you."); } /* Set the update sequence number to 1. */ |