Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
d4119ee0
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看板
提交
d4119ee0
编写于
1月 13, 2015
作者:
J
Jens Axboe
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-3.20/core' into for-3.20/drivers
上级
91117a20
dd22f551
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
86 addition
and
58 deletion
+86
-58
Documentation/filesystems/xip.txt
Documentation/filesystems/xip.txt
+9
-6
arch/powerpc/sysdev/axonram.c
arch/powerpc/sysdev/axonram.c
+4
-13
drivers/block/brd.c
drivers/block/brd.c
+7
-7
drivers/s390/block/dcssblk.c
drivers/s390/block/dcssblk.c
+9
-12
fs/block_dev.c
fs/block_dev.c
+40
-0
fs/ext2/xip.c
fs/ext2/xip.c
+13
-18
include/linux/blkdev.h
include/linux/blkdev.h
+4
-2
未找到文件。
Documentation/filesystems/xip.txt
浏览文件 @
d4119ee0
...
...
@@ -28,12 +28,15 @@ Implementation
Execute-in-place is implemented in three steps: block device operation,
address space operation, and file operations.
A block device operation named direct_access is used to retrieve a
reference (pointer) to a block on-disk. The reference is supposed to be
cpu-addressable, physical address and remain valid until the release operation
is performed. A struct block_device reference is used to address the device,
and a sector_t argument is used to identify the individual block. As an
alternative, memory technology devices can be used for this.
A block device operation named direct_access is used to translate the
block device sector number to a page frame number (pfn) that identifies
the physical page for the memory. It also returns a kernel virtual
address that can be used to access the memory.
The direct_access method takes a 'size' parameter that indicates the
number of bytes being requested. The function should return the number
of bytes that can be contiguously accessed at that offset. It may also
return a negative errno if an error occurs.
The block device operation is optional, these block devices support it as of
today:
...
...
arch/powerpc/sysdev/axonram.c
浏览文件 @
d4119ee0
...
...
@@ -139,26 +139,17 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
* axon_ram_direct_access - direct_access() method for block device
* @device, @sector, @data: see block_device_operations method
*/
static
int
static
long
axon_ram_direct_access
(
struct
block_device
*
device
,
sector_t
sector
,
void
**
kaddr
,
unsigned
long
*
pfn
)
void
**
kaddr
,
unsigned
long
*
pfn
,
long
size
)
{
struct
axon_ram_bank
*
bank
=
device
->
bd_disk
->
private_data
;
loff_t
offset
;
offset
=
sector
;
if
(
device
->
bd_part
!=
NULL
)
offset
+=
device
->
bd_part
->
start_sect
;
offset
<<=
AXON_RAM_SECTOR_SHIFT
;
if
(
offset
>=
bank
->
size
)
{
dev_err
(
&
bank
->
device
->
dev
,
"Access outside of address space
\n
"
);
return
-
ERANGE
;
}
loff_t
offset
=
(
loff_t
)
sector
<<
AXON_RAM_SECTOR_SHIFT
;
*
kaddr
=
(
void
*
)(
bank
->
ph_addr
+
offset
);
*
pfn
=
virt_to_phys
(
*
kaddr
)
>>
PAGE_SHIFT
;
return
0
;
return
bank
->
size
-
offset
;
}
static
const
struct
block_device_operations
axon_ram_devops
=
{
...
...
drivers/block/brd.c
浏览文件 @
d4119ee0
...
...
@@ -370,25 +370,25 @@ static int brd_rw_page(struct block_device *bdev, sector_t sector,
}
#ifdef CONFIG_BLK_DEV_XIP
static
int
brd_direct_access
(
struct
block_device
*
bdev
,
sector_t
sector
,
void
**
kaddr
,
unsigned
long
*
pfn
)
static
long
brd_direct_access
(
struct
block_device
*
bdev
,
sector_t
sector
,
void
**
kaddr
,
unsigned
long
*
pfn
,
long
size
)
{
struct
brd_device
*
brd
=
bdev
->
bd_disk
->
private_data
;
struct
page
*
page
;
if
(
!
brd
)
return
-
ENODEV
;
if
(
sector
&
(
PAGE_SECTORS
-
1
))
return
-
EINVAL
;
if
(
sector
+
PAGE_SECTORS
>
get_capacity
(
bdev
->
bd_disk
))
return
-
ERANGE
;
page
=
brd_insert_page
(
brd
,
sector
);
if
(
!
page
)
return
-
ENOSPC
;
*
kaddr
=
page_address
(
page
);
*
pfn
=
page_to_pfn
(
page
);
return
0
;
/*
* TODO: If size > PAGE_SIZE, we could look to see if the next page in
* the file happens to be mapped to the next page of physical RAM.
*/
return
PAGE_SIZE
;
}
#endif
...
...
drivers/s390/block/dcssblk.c
浏览文件 @
d4119ee0
...
...
@@ -28,8 +28,8 @@
static
int
dcssblk_open
(
struct
block_device
*
bdev
,
fmode_t
mode
);
static
void
dcssblk_release
(
struct
gendisk
*
disk
,
fmode_t
mode
);
static
void
dcssblk_make_request
(
struct
request_queue
*
q
,
struct
bio
*
bio
);
static
int
dcssblk_direct_access
(
struct
block_device
*
bdev
,
sector_t
secnum
,
void
**
kaddr
,
unsigned
long
*
pfn
);
static
long
dcssblk_direct_access
(
struct
block_device
*
bdev
,
sector_t
secnum
,
void
**
kaddr
,
unsigned
long
*
pfn
,
long
size
);
static
char
dcssblk_segments
[
DCSSBLK_PARM_LEN
]
=
"
\0
"
;
...
...
@@ -866,25 +866,22 @@ dcssblk_make_request(struct request_queue *q, struct bio *bio)
bio_io_error
(
bio
);
}
static
int
static
long
dcssblk_direct_access
(
struct
block_device
*
bdev
,
sector_t
secnum
,
void
**
kaddr
,
unsigned
long
*
pfn
)
void
**
kaddr
,
unsigned
long
*
pfn
,
long
size
)
{
struct
dcssblk_dev_info
*
dev_info
;
unsigned
long
pgoff
;
unsigned
long
offset
,
dev_sz
;
dev_info
=
bdev
->
bd_disk
->
private_data
;
if
(
!
dev_info
)
return
-
ENODEV
;
if
(
secnum
%
(
PAGE_SIZE
/
512
))
return
-
EINVAL
;
pgoff
=
secnum
/
(
PAGE_SIZE
/
512
);
if
((
pgoff
+
1
)
*
PAGE_SIZE
-
1
>
dev_info
->
end
-
dev_info
->
start
)
return
-
ERANGE
;
*
kaddr
=
(
void
*
)
(
dev_info
->
start
+
pgoff
*
PAGE_SIZE
);
dev_sz
=
dev_info
->
end
-
dev_info
->
start
;
offset
=
secnum
*
512
;
*
kaddr
=
(
void
*
)
(
dev_info
->
start
+
offset
);
*
pfn
=
virt_to_phys
(
*
kaddr
)
>>
PAGE_SHIFT
;
return
0
;
return
dev_sz
-
offset
;
}
static
void
...
...
fs/block_dev.c
浏览文件 @
d4119ee0
...
...
@@ -429,6 +429,46 @@ int bdev_write_page(struct block_device *bdev, sector_t sector,
}
EXPORT_SYMBOL_GPL
(
bdev_write_page
);
/**
* bdev_direct_access() - Get the address for directly-accessibly memory
* @bdev: The device containing the memory
* @sector: The offset within the device
* @addr: Where to put the address of the memory
* @pfn: The Page Frame Number for the memory
* @size: The number of bytes requested
*
* If a block device is made up of directly addressable memory, this function
* will tell the caller the PFN and the address of the memory. The address
* may be directly dereferenced within the kernel without the need to call
* ioremap(), kmap() or similar. The PFN is suitable for inserting into
* page tables.
*
* Return: negative errno if an error occurs, otherwise the number of bytes
* accessible at this address.
*/
long
bdev_direct_access
(
struct
block_device
*
bdev
,
sector_t
sector
,
void
**
addr
,
unsigned
long
*
pfn
,
long
size
)
{
long
avail
;
const
struct
block_device_operations
*
ops
=
bdev
->
bd_disk
->
fops
;
if
(
size
<
0
)
return
size
;
if
(
!
ops
->
direct_access
)
return
-
EOPNOTSUPP
;
if
((
sector
+
DIV_ROUND_UP
(
size
,
512
))
>
part_nr_sects_read
(
bdev
->
bd_part
))
return
-
ERANGE
;
sector
+=
get_start_sect
(
bdev
);
if
(
sector
%
(
PAGE_SIZE
/
512
))
return
-
EINVAL
;
avail
=
ops
->
direct_access
(
bdev
,
sector
,
addr
,
pfn
,
size
);
if
(
!
avail
)
return
-
ERANGE
;
return
min
(
avail
,
size
);
}
EXPORT_SYMBOL_GPL
(
bdev_direct_access
);
/*
* pseudo-fs
*/
...
...
fs/ext2/xip.c
浏览文件 @
d4119ee0
...
...
@@ -13,18 +13,12 @@
#include "ext2.h"
#include "xip.h"
static
inline
int
__inode_direct_access
(
struct
inode
*
inode
,
sector_t
block
,
void
**
kaddr
,
unsigned
long
*
pfn
)
static
inline
long
__inode_direct_access
(
struct
inode
*
inode
,
sector_t
block
,
void
**
kaddr
,
unsigned
long
*
pfn
,
long
size
)
{
struct
block_device
*
bdev
=
inode
->
i_sb
->
s_bdev
;
const
struct
block_device_operations
*
ops
=
bdev
->
bd_disk
->
fops
;
sector_t
sector
;
sector
=
block
*
(
PAGE_SIZE
/
512
);
/* ext2 block to bdev sector */
BUG_ON
(
!
ops
->
direct_access
);
return
ops
->
direct_access
(
bdev
,
sector
,
kaddr
,
pfn
);
sector_t
sector
=
block
*
(
PAGE_SIZE
/
512
);
return
bdev_direct_access
(
bdev
,
sector
,
kaddr
,
pfn
,
size
);
}
static
inline
int
...
...
@@ -53,12 +47,13 @@ ext2_clear_xip_target(struct inode *inode, sector_t block)
{
void
*
kaddr
;
unsigned
long
pfn
;
int
rc
;
long
size
;
rc
=
__inode_direct_access
(
inode
,
block
,
&
kaddr
,
&
pfn
);
if
(
!
rc
)
clear_page
(
kaddr
);
return
rc
;
size
=
__inode_direct_access
(
inode
,
block
,
&
kaddr
,
&
pfn
,
PAGE_SIZE
);
if
(
size
<
0
)
return
size
;
clear_page
(
kaddr
);
return
0
;
}
void
ext2_xip_verify_sb
(
struct
super_block
*
sb
)
...
...
@@ -77,7 +72,7 @@ void ext2_xip_verify_sb(struct super_block *sb)
int
ext2_get_xip_mem
(
struct
address_space
*
mapping
,
pgoff_t
pgoff
,
int
create
,
void
**
kmem
,
unsigned
long
*
pfn
)
{
int
rc
;
long
rc
;
sector_t
block
;
/* first, retrieve the sector number */
...
...
@@ -86,6 +81,6 @@ int ext2_get_xip_mem(struct address_space *mapping, pgoff_t pgoff, int create,
return
rc
;
/* retrieve address of the target data */
rc
=
__inode_direct_access
(
mapping
->
host
,
block
,
kmem
,
pfn
);
return
rc
;
rc
=
__inode_direct_access
(
mapping
->
host
,
block
,
kmem
,
pfn
,
PAGE_SIZE
);
return
(
rc
<
0
)
?
rc
:
0
;
}
include/linux/blkdev.h
浏览文件 @
d4119ee0
...
...
@@ -1601,8 +1601,8 @@ struct block_device_operations {
int
(
*
rw_page
)(
struct
block_device
*
,
sector_t
,
struct
page
*
,
int
rw
);
int
(
*
ioctl
)
(
struct
block_device
*
,
fmode_t
,
unsigned
,
unsigned
long
);
int
(
*
compat_ioctl
)
(
struct
block_device
*
,
fmode_t
,
unsigned
,
unsigned
long
);
int
(
*
direct_access
)
(
struct
block_device
*
,
sector_t
,
void
**
,
unsigned
long
*
);
long
(
*
direct_access
)
(
struct
block_device
*
,
sector_t
,
void
**
,
unsigned
long
*
pfn
,
long
size
);
unsigned
int
(
*
check_events
)
(
struct
gendisk
*
disk
,
unsigned
int
clearing
);
/* ->media_changed() is DEPRECATED, use ->check_events() instead */
...
...
@@ -1620,6 +1620,8 @@ extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,
extern
int
bdev_read_page
(
struct
block_device
*
,
sector_t
,
struct
page
*
);
extern
int
bdev_write_page
(
struct
block_device
*
,
sector_t
,
struct
page
*
,
struct
writeback_control
*
);
extern
long
bdev_direct_access
(
struct
block_device
*
,
sector_t
,
void
**
addr
,
unsigned
long
*
pfn
,
long
size
);
#else
/* CONFIG_BLOCK */
struct
block_device
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录