提交 271849a9 编写于 作者: A Anton Altaparmakov

NTFS: Add fs/ntfs/attrib.[hc]::ntfs_attr_vcn_to_lcn_nolock() used by the new

      write code.
Signed-off-by: NAnton Altaparmakov <aia21@cantab.net>
上级 7e693073
...@@ -88,8 +88,10 @@ ToDo/Notes: ...@@ -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) ...@@ -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 @@ ...@@ -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 { ...@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册