mirror of https://gitee.com/openkylin/linux.git
NTFS: Change ntfs_attr_make_non_resident to take the attribute value size
as an extra parameter. This is needed since we need to know the size before we can map the mft record and our callers always know it. The reason we cannot simply read the size from the vfs inode i_size is that this is not necessarily uptodate. This happens when ntfs_attr_make_non_resident() is called in the ->truncate call path. Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
This commit is contained in:
parent
fc0fa7dc7d
commit
8925d4f0d3
|
@ -37,6 +37,12 @@ ToDo/Notes:
|
||||||
- Change ntfs_attr_make_non_resident() to call ntfs_cluster_alloc()
|
- Change ntfs_attr_make_non_resident() to call ntfs_cluster_alloc()
|
||||||
with @is_extension set to TRUE and remove the runlist terminator
|
with @is_extension set to TRUE and remove the runlist terminator
|
||||||
fixup code as this is now done by ntfs_cluster_alloc().
|
fixup code as this is now done by ntfs_cluster_alloc().
|
||||||
|
- Change ntfs_attr_make_non_resident to take the attribute value size
|
||||||
|
as an extra parameter. This is needed since we need to know the size
|
||||||
|
before we can map the mft record and our callers always know it. The
|
||||||
|
reason we cannot simply read the size from the vfs inode i_size is
|
||||||
|
that this is not necessarily uptodate. This happens when
|
||||||
|
ntfs_attr_make_non_resident() is called in the ->truncate call path.
|
||||||
|
|
||||||
2.1.24 - Lots of bug fixes and support more clean journal states.
|
2.1.24 - Lots of bug fixes and support more clean journal states.
|
||||||
|
|
||||||
|
|
|
@ -1501,10 +1501,17 @@ int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
|
||||||
/**
|
/**
|
||||||
* ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
|
* ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
|
||||||
* @ni: ntfs inode describing the attribute to convert
|
* @ni: ntfs inode describing the attribute to convert
|
||||||
|
* @data_size: size of the resident data to copy to the non-resident attribute
|
||||||
*
|
*
|
||||||
* Convert the resident ntfs attribute described by the ntfs inode @ni to a
|
* Convert the resident ntfs attribute described by the ntfs inode @ni to a
|
||||||
* non-resident one.
|
* non-resident one.
|
||||||
*
|
*
|
||||||
|
* @data_size must be equal to the attribute value size. This is needed since
|
||||||
|
* we need to know the size before we can map the mft record and our callers
|
||||||
|
* always know it. The reason we cannot simply read the size from the vfs
|
||||||
|
* inode i_size is that this is not necessarily uptodate. This happens when
|
||||||
|
* ntfs_attr_make_non_resident() is called in the ->truncate call path(s).
|
||||||
|
*
|
||||||
* Return 0 on success and -errno on error. The following error return codes
|
* Return 0 on success and -errno on error. The following error return codes
|
||||||
* are defined:
|
* are defined:
|
||||||
* -EPERM - The attribute is not allowed to be non-resident.
|
* -EPERM - The attribute is not allowed to be non-resident.
|
||||||
|
@ -1525,7 +1532,7 @@ int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
|
||||||
*
|
*
|
||||||
* Locking: - The caller must hold i_sem on the inode.
|
* Locking: - The caller must hold i_sem on the inode.
|
||||||
*/
|
*/
|
||||||
int ntfs_attr_make_non_resident(ntfs_inode *ni)
|
int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)
|
||||||
{
|
{
|
||||||
s64 new_size;
|
s64 new_size;
|
||||||
struct inode *vi = VFS_I(ni);
|
struct inode *vi = VFS_I(ni);
|
||||||
|
@ -1563,7 +1570,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
|
||||||
* The size needs to be aligned to a cluster boundary for allocation
|
* The size needs to be aligned to a cluster boundary for allocation
|
||||||
* purposes.
|
* purposes.
|
||||||
*/
|
*/
|
||||||
new_size = (i_size_read(vi) + vol->cluster_size - 1) &
|
new_size = (data_size + vol->cluster_size - 1) &
|
||||||
~(vol->cluster_size - 1);
|
~(vol->cluster_size - 1);
|
||||||
if (new_size > 0) {
|
if (new_size > 0) {
|
||||||
/*
|
/*
|
||||||
|
@ -1647,7 +1654,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
|
||||||
* attribute value.
|
* attribute value.
|
||||||
*/
|
*/
|
||||||
attr_size = le32_to_cpu(a->data.resident.value_length);
|
attr_size = le32_to_cpu(a->data.resident.value_length);
|
||||||
BUG_ON(attr_size != i_size_read(vi));
|
BUG_ON(attr_size != data_size);
|
||||||
if (page && !PageUptodate(page)) {
|
if (page && !PageUptodate(page)) {
|
||||||
kaddr = kmap_atomic(page, KM_USER0);
|
kaddr = kmap_atomic(page, KM_USER0);
|
||||||
memcpy(kaddr, (u8*)a +
|
memcpy(kaddr, (u8*)a +
|
||||||
|
|
|
@ -103,7 +103,7 @@ extern int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size);
|
||||||
extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
|
extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
|
||||||
const u32 new_size);
|
const u32 new_size);
|
||||||
|
|
||||||
extern int ntfs_attr_make_non_resident(ntfs_inode *ni);
|
extern int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size);
|
||||||
|
|
||||||
extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt,
|
extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt,
|
||||||
const u8 val);
|
const u8 val);
|
||||||
|
|
Loading…
Reference in New Issue