Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
3f7fc6f2
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
3f7fc6f2
编写于
10月 16, 2014
作者:
A
Anton Altaparmakov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
NTFS: Add bmap address space operation needed for FIBMAP ioctl.
Signed-off-by:
N
Anton Altaparmakov
<
anton@tuxera.com
>
上级
2b522cc1
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
124 addition
and
0 deletion
+124
-0
fs/ntfs/aops.c
fs/ntfs/aops.c
+124
-0
未找到文件。
fs/ntfs/aops.c
浏览文件 @
3f7fc6f2
...
...
@@ -1537,6 +1537,129 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
#endif
/* NTFS_RW */
/**
* ntfs_bmap - map logical file block to physical device block
* @mapping: address space mapping to which the block to be mapped belongs
* @block: logical block to map to its physical device block
*
* For regular, non-resident files (i.e. not compressed and not encrypted), map
* the logical @block belonging to the file described by the address space
* mapping @mapping to its physical device block.
*
* The size of the block is equal to the @s_blocksize field of the super block
* of the mounted file system which is guaranteed to be smaller than or equal
* to the cluster size thus the block is guaranteed to fit entirely inside the
* cluster which means we do not need to care how many contiguous bytes are
* available after the beginning of the block.
*
* Return the physical device block if the mapping succeeded or 0 if the block
* is sparse or there was an error.
*
* Note: This is a problem if someone tries to run bmap() on $Boot system file
* as that really is in block zero but there is nothing we can do. bmap() is
* just broken in that respect (just like it cannot distinguish sparse from
* not available or error).
*/
static
sector_t
ntfs_bmap
(
struct
address_space
*
mapping
,
sector_t
block
)
{
s64
ofs
,
size
;
loff_t
i_size
;
LCN
lcn
;
unsigned
long
blocksize
,
flags
;
ntfs_inode
*
ni
=
NTFS_I
(
mapping
->
host
);
ntfs_volume
*
vol
=
ni
->
vol
;
unsigned
delta
;
unsigned
char
blocksize_bits
,
cluster_size_shift
;
ntfs_debug
(
"Entering for mft_no 0x%lx, logical block 0x%llx."
,
ni
->
mft_no
,
(
unsigned
long
long
)
block
);
if
(
ni
->
type
!=
AT_DATA
||
!
NInoNonResident
(
ni
)
||
NInoEncrypted
(
ni
))
{
ntfs_error
(
vol
->
sb
,
"BMAP does not make sense for %s "
"attributes, returning 0."
,
(
ni
->
type
!=
AT_DATA
)
?
"non-data"
:
(
!
NInoNonResident
(
ni
)
?
"resident"
:
"encrypted"
));
return
0
;
}
/* None of these can happen. */
BUG_ON
(
NInoCompressed
(
ni
));
BUG_ON
(
NInoMstProtected
(
ni
));
blocksize
=
vol
->
sb
->
s_blocksize
;
blocksize_bits
=
vol
->
sb
->
s_blocksize_bits
;
ofs
=
(
s64
)
block
<<
blocksize_bits
;
read_lock_irqsave
(
&
ni
->
size_lock
,
flags
);
size
=
ni
->
initialized_size
;
i_size
=
i_size_read
(
VFS_I
(
ni
));
read_unlock_irqrestore
(
&
ni
->
size_lock
,
flags
);
/*
* If the offset is outside the initialized size or the block straddles
* the initialized size then pretend it is a hole unless the
* initialized size equals the file size.
*/
if
(
unlikely
(
ofs
>=
size
||
(
ofs
+
blocksize
>
size
&&
size
<
i_size
)))
goto
hole
;
cluster_size_shift
=
vol
->
cluster_size_bits
;
down_read
(
&
ni
->
runlist
.
lock
);
lcn
=
ntfs_attr_vcn_to_lcn_nolock
(
ni
,
ofs
>>
cluster_size_shift
,
false
);
up_read
(
&
ni
->
runlist
.
lock
);
if
(
unlikely
(
lcn
<
LCN_HOLE
))
{
/*
* Step down to an integer to avoid gcc doing a long long
* comparision in the switch when we know @lcn is between
* LCN_HOLE and LCN_EIO (i.e. -1 to -5).
*
* Otherwise older gcc (at least on some architectures) will
* try to use __cmpdi2() which is of course not available in
* the kernel.
*/
switch
((
int
)
lcn
)
{
case
LCN_ENOENT
:
/*
* If the offset is out of bounds then pretend it is a
* hole.
*/
goto
hole
;
case
LCN_ENOMEM
:
ntfs_error
(
vol
->
sb
,
"Not enough memory to complete "
"mapping for inode 0x%lx. "
"Returning 0."
,
ni
->
mft_no
);
break
;
default:
ntfs_error
(
vol
->
sb
,
"Failed to complete mapping for "
"inode 0x%lx. Run chkdsk. "
"Returning 0."
,
ni
->
mft_no
);
break
;
}
return
0
;
}
if
(
lcn
<
0
)
{
/* It is a hole. */
hole:
ntfs_debug
(
"Done (returning hole)."
);
return
0
;
}
/*
* The block is really allocated and fullfils all our criteria.
* Convert the cluster to units of block size and return the result.
*/
delta
=
ofs
&
vol
->
cluster_size_mask
;
if
(
unlikely
(
sizeof
(
block
)
<
sizeof
(
lcn
)))
{
block
=
lcn
=
((
lcn
<<
cluster_size_shift
)
+
delta
)
>>
blocksize_bits
;
/* If the block number was truncated return 0. */
if
(
unlikely
(
block
!=
lcn
))
{
ntfs_error
(
vol
->
sb
,
"Physical block 0x%llx is too "
"large to be returned, returning 0."
,
(
long
long
)
lcn
);
return
0
;
}
}
else
block
=
((
lcn
<<
cluster_size_shift
)
+
delta
)
>>
blocksize_bits
;
ntfs_debug
(
"Done (returning block 0x%llx)."
,
(
unsigned
long
long
)
lcn
);
return
block
;
}
/**
* ntfs_normal_aops - address space operations for normal inodes and attributes
*
...
...
@@ -1549,6 +1672,7 @@ const struct address_space_operations ntfs_normal_aops = {
.
writepage
=
ntfs_writepage
,
.
set_page_dirty
=
__set_page_dirty_buffers
,
#endif
/* NTFS_RW */
.
bmap
=
ntfs_bmap
,
.
migratepage
=
buffer_migrate_page
,
.
is_partially_uptodate
=
block_is_partially_uptodate
,
.
error_remove_page
=
generic_error_remove_page
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录