NTFS: Add fs/ntfs/attrib.[hc]::ntfs_attr_vcn_to_lcn_nolock() used by the new
write code. Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
This commit is contained in:
@@ -88,8 +88,10 @@ ToDo/Notes:
|
|||||||
checked and set in the ntfs inode as done for compressed files and
|
checked and set in the ntfs inode as done for compressed files and
|
||||||
the compressed size needs to be used for vfs inode->i_blocks instead
|
the compressed size needs to be used for vfs inode->i_blocks instead
|
||||||
of the allocated size, again, as done for compressed files.
|
of the allocated size, again, as done for compressed files.
|
||||||
- Add AT_EA in addition to AT_DATA to whitelist for being allowed to
|
- Add AT_EA in addition to AT_DATA to whitelist for being allowed to be
|
||||||
be non-resident in fs/ntfs/attrib.c::ntfs_attr_can_be_non_resident().
|
non-resident in fs/ntfs/attrib.c::ntfs_attr_can_be_non_resident().
|
||||||
|
- Add fs/ntfs/attrib.c::ntfs_attr_vcn_to_lcn_nolock() used by the new
|
||||||
|
write code.
|
||||||
|
|
||||||
2.1.22 - Many bug and race fixes and error handling improvements.
|
2.1.22 - Many bug and race fixes and error handling improvements.
|
||||||
|
|
||||||
|
@@ -105,6 +105,93 @@ int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ntfs_attr_vcn_to_lcn_nolock - convert a vcn into a lcn given an ntfs inode
|
||||||
|
* @ni: ntfs inode of the attribute whose runlist to search
|
||||||
|
* @vcn: vcn to convert
|
||||||
|
* @write_locked: true if the runlist is locked for writing
|
||||||
|
*
|
||||||
|
* Find the virtual cluster number @vcn in the runlist of the ntfs attribute
|
||||||
|
* described by the ntfs inode @ni and return the corresponding logical cluster
|
||||||
|
* number (lcn).
|
||||||
|
*
|
||||||
|
* If the @vcn is not mapped yet, the attempt is made to map the attribute
|
||||||
|
* extent containing the @vcn and the vcn to lcn conversion is retried.
|
||||||
|
*
|
||||||
|
* If @write_locked is true the caller has locked the runlist for writing and
|
||||||
|
* if false for reading.
|
||||||
|
*
|
||||||
|
* Since lcns must be >= 0, we use negative return codes with special meaning:
|
||||||
|
*
|
||||||
|
* Return code Meaning / Description
|
||||||
|
* ==========================================
|
||||||
|
* LCN_HOLE Hole / not allocated on disk.
|
||||||
|
* LCN_ENOENT There is no such vcn in the runlist, i.e. @vcn is out of bounds.
|
||||||
|
* LCN_ENOMEM Not enough memory to map runlist.
|
||||||
|
* LCN_EIO Critical error (runlist/file is corrupt, i/o error, etc).
|
||||||
|
*
|
||||||
|
* Locking: - The runlist must be locked on entry and is left locked on return.
|
||||||
|
* - If @write_locked is FALSE, i.e. the runlist is locked for reading,
|
||||||
|
* the lock may be dropped inside the function so you cannot rely on
|
||||||
|
* the runlist still being the same when this function returns.
|
||||||
|
*/
|
||||||
|
LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
|
||||||
|
const BOOL write_locked)
|
||||||
|
{
|
||||||
|
LCN lcn;
|
||||||
|
BOOL is_retry = FALSE;
|
||||||
|
|
||||||
|
ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
|
||||||
|
ni->mft_no, (unsigned long long)vcn,
|
||||||
|
write_locked ? "write" : "read");
|
||||||
|
BUG_ON(!ni);
|
||||||
|
BUG_ON(!NInoNonResident(ni));
|
||||||
|
BUG_ON(vcn < 0);
|
||||||
|
retry_remap:
|
||||||
|
/* Convert vcn to lcn. If that fails map the runlist and retry once. */
|
||||||
|
lcn = ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn);
|
||||||
|
if (likely(lcn >= LCN_HOLE)) {
|
||||||
|
ntfs_debug("Done, lcn 0x%llx.", (long long)lcn);
|
||||||
|
return lcn;
|
||||||
|
}
|
||||||
|
if (lcn != LCN_RL_NOT_MAPPED) {
|
||||||
|
if (lcn != LCN_ENOENT)
|
||||||
|
lcn = LCN_EIO;
|
||||||
|
} else if (!is_retry) {
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!write_locked) {
|
||||||
|
up_read(&ni->runlist.lock);
|
||||||
|
down_write(&ni->runlist.lock);
|
||||||
|
if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) !=
|
||||||
|
LCN_RL_NOT_MAPPED)) {
|
||||||
|
up_write(&ni->runlist.lock);
|
||||||
|
down_read(&ni->runlist.lock);
|
||||||
|
goto retry_remap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = ntfs_map_runlist_nolock(ni, vcn);
|
||||||
|
if (!write_locked) {
|
||||||
|
up_write(&ni->runlist.lock);
|
||||||
|
down_read(&ni->runlist.lock);
|
||||||
|
}
|
||||||
|
if (likely(!err)) {
|
||||||
|
is_retry = TRUE;
|
||||||
|
goto retry_remap;
|
||||||
|
}
|
||||||
|
if (err == -ENOENT)
|
||||||
|
lcn = LCN_ENOENT;
|
||||||
|
else if (err == -ENOMEM)
|
||||||
|
lcn = LCN_ENOMEM;
|
||||||
|
else
|
||||||
|
lcn = LCN_EIO;
|
||||||
|
}
|
||||||
|
if (lcn != LCN_ENOENT)
|
||||||
|
ntfs_error(ni->vol->sb, "Failed with error code %lli.",
|
||||||
|
(long long)lcn);
|
||||||
|
return lcn;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ntfs_find_vcn_nolock - find a vcn in the runlist described by an ntfs inode
|
* ntfs_find_vcn_nolock - find a vcn in the runlist described by an ntfs inode
|
||||||
* @ni: ntfs inode describing the runlist to search
|
* @ni: ntfs inode describing the runlist to search
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* attrib.h - Defines for attribute handling in NTFS Linux kernel driver.
|
* attrib.h - Defines for attribute handling in NTFS Linux kernel driver.
|
||||||
* Part of the Linux-NTFS project.
|
* Part of the Linux-NTFS project.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2004 Anton Altaparmakov
|
* Copyright (c) 2001-2005 Anton Altaparmakov
|
||||||
* Copyright (c) 2002 Richard Russon
|
* Copyright (c) 2002 Richard Russon
|
||||||
*
|
*
|
||||||
* This program/include file is free software; you can redistribute it and/or
|
* This program/include file is free software; you can redistribute it and/or
|
||||||
@@ -63,6 +63,9 @@ typedef struct {
|
|||||||
extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn);
|
extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn);
|
||||||
extern int ntfs_map_runlist(ntfs_inode *ni, VCN vcn);
|
extern int ntfs_map_runlist(ntfs_inode *ni, VCN vcn);
|
||||||
|
|
||||||
|
extern LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
|
||||||
|
const BOOL write_locked);
|
||||||
|
|
||||||
extern runlist_element *ntfs_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
|
extern runlist_element *ntfs_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
|
||||||
const BOOL write_locked);
|
const BOOL write_locked);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user