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
...
@@ -28,12 +28,15 @@ Implementation
Execute-in-place is implemented in three steps: block device operation,
Execute-in-place is implemented in three steps: block device operation,
address space operation, and file operations.
address space operation, and file operations.
A block device operation named direct_access is used to retrieve a
A block device operation named direct_access is used to translate the
reference (pointer) to a block on-disk. The reference is supposed to be
block device sector number to a page frame number (pfn) that identifies
cpu-addressable, physical address and remain valid until the release operation
the physical page for the memory. It also returns a kernel virtual
is performed. A struct block_device reference is used to address the device,
address that can be used to access the memory.
and a sector_t argument is used to identify the individual block. As an
alternative, memory technology devices can be used for this.
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
The block device operation is optional, these block devices support it as of
today:
today:
...
...
arch/powerpc/sysdev/axonram.c
浏览文件 @
d4119ee0
...
@@ -139,26 +139,17 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
...
@@ -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
* axon_ram_direct_access - direct_access() method for block device
* @device, @sector, @data: see block_device_operations method
* @device, @sector, @data: see block_device_operations method
*/
*/
static
int
static
long
axon_ram_direct_access
(
struct
block_device
*
device
,
sector_t
sector
,
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
;
struct
axon_ram_bank
*
bank
=
device
->
bd_disk
->
private_data
;
loff_t
offset
;
loff_t
offset
=
(
loff_t
)
sector
<<
AXON_RAM_SECTOR_SHIFT
;
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
;
}
*
kaddr
=
(
void
*
)(
bank
->
ph_addr
+
offset
);
*
kaddr
=
(
void
*
)(
bank
->
ph_addr
+
offset
);
*
pfn
=
virt_to_phys
(
*
kaddr
)
>>
PAGE_SHIFT
;
*
pfn
=
virt_to_phys
(
*
kaddr
)
>>
PAGE_SHIFT
;
return
0
;
return
bank
->
size
-
offset
;
}
}
static
const
struct
block_device_operations
axon_ram_devops
=
{
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,
...
@@ -370,25 +370,25 @@ static int brd_rw_page(struct block_device *bdev, sector_t sector,
}
}
#ifdef CONFIG_BLK_DEV_XIP
#ifdef CONFIG_BLK_DEV_XIP
static
int
brd_direct_access
(
struct
block_device
*
bdev
,
sector_t
sector
,
static
long
brd_direct_access
(
struct
block_device
*
bdev
,
sector_t
sector
,
void
**
kaddr
,
unsigned
long
*
pfn
)
void
**
kaddr
,
unsigned
long
*
pfn
,
long
size
)
{
{
struct
brd_device
*
brd
=
bdev
->
bd_disk
->
private_data
;
struct
brd_device
*
brd
=
bdev
->
bd_disk
->
private_data
;
struct
page
*
page
;
struct
page
*
page
;
if
(
!
brd
)
if
(
!
brd
)
return
-
ENODEV
;
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
);
page
=
brd_insert_page
(
brd
,
sector
);
if
(
!
page
)
if
(
!
page
)
return
-
ENOSPC
;
return
-
ENOSPC
;
*
kaddr
=
page_address
(
page
);
*
kaddr
=
page_address
(
page
);
*
pfn
=
page_to_pfn
(
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
#endif
...
...
drivers/s390/block/dcssblk.c
浏览文件 @
d4119ee0
...
@@ -28,8 +28,8 @@
...
@@ -28,8 +28,8 @@
static
int
dcssblk_open
(
struct
block_device
*
bdev
,
fmode_t
mode
);
static
int
dcssblk_open
(
struct
block_device
*
bdev
,
fmode_t
mode
);
static
void
dcssblk_release
(
struct
gendisk
*
disk
,
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
void
dcssblk_make_request
(
struct
request_queue
*
q
,
struct
bio
*
bio
);
static
int
dcssblk_direct_access
(
struct
block_device
*
bdev
,
sector_t
secnum
,
static
long
dcssblk_direct_access
(
struct
block_device
*
bdev
,
sector_t
secnum
,
void
**
kaddr
,
unsigned
long
*
pfn
);
void
**
kaddr
,
unsigned
long
*
pfn
,
long
size
);
static
char
dcssblk_segments
[
DCSSBLK_PARM_LEN
]
=
"
\0
"
;
static
char
dcssblk_segments
[
DCSSBLK_PARM_LEN
]
=
"
\0
"
;
...
@@ -866,25 +866,22 @@ dcssblk_make_request(struct request_queue *q, struct bio *bio)
...
@@ -866,25 +866,22 @@ dcssblk_make_request(struct request_queue *q, struct bio *bio)
bio_io_error
(
bio
);
bio_io_error
(
bio
);
}
}
static
int
static
long
dcssblk_direct_access
(
struct
block_device
*
bdev
,
sector_t
secnum
,
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
;
struct
dcssblk_dev_info
*
dev_info
;
unsigned
long
pgoff
;
unsigned
long
offset
,
dev_sz
;
dev_info
=
bdev
->
bd_disk
->
private_data
;
dev_info
=
bdev
->
bd_disk
->
private_data
;
if
(
!
dev_info
)
if
(
!
dev_info
)
return
-
ENODEV
;
return
-
ENODEV
;
if
(
secnum
%
(
PAGE_SIZE
/
512
))
dev_sz
=
dev_info
->
end
-
dev_info
->
start
;
return
-
EINVAL
;
offset
=
secnum
*
512
;
pgoff
=
secnum
/
(
PAGE_SIZE
/
512
);
*
kaddr
=
(
void
*
)
(
dev_info
->
start
+
offset
);
if
((
pgoff
+
1
)
*
PAGE_SIZE
-
1
>
dev_info
->
end
-
dev_info
->
start
)
return
-
ERANGE
;
*
kaddr
=
(
void
*
)
(
dev_info
->
start
+
pgoff
*
PAGE_SIZE
);
*
pfn
=
virt_to_phys
(
*
kaddr
)
>>
PAGE_SHIFT
;
*
pfn
=
virt_to_phys
(
*
kaddr
)
>>
PAGE_SHIFT
;
return
0
;
return
dev_sz
-
offset
;
}
}
static
void
static
void
...
...
fs/block_dev.c
浏览文件 @
d4119ee0
...
@@ -429,6 +429,46 @@ int bdev_write_page(struct block_device *bdev, sector_t sector,
...
@@ -429,6 +429,46 @@ int bdev_write_page(struct block_device *bdev, sector_t sector,
}
}
EXPORT_SYMBOL_GPL
(
bdev_write_page
);
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
* pseudo-fs
*/
*/
...
...
fs/ext2/xip.c
浏览文件 @
d4119ee0
...
@@ -13,18 +13,12 @@
...
@@ -13,18 +13,12 @@
#include "ext2.h"
#include "ext2.h"
#include "xip.h"
#include "xip.h"
static
inline
int
static
inline
long
__inode_direct_access
(
struct
inode
*
inode
,
sector_t
block
,
__inode_direct_access
(
struct
inode
*
inode
,
sector_t
block
,
void
**
kaddr
,
unsigned
long
*
pfn
,
long
size
)
void
**
kaddr
,
unsigned
long
*
pfn
)
{
{
struct
block_device
*
bdev
=
inode
->
i_sb
->
s_bdev
;
struct
block_device
*
bdev
=
inode
->
i_sb
->
s_bdev
;
const
struct
block_device_operations
*
ops
=
bdev
->
bd_disk
->
fops
;
sector_t
sector
=
block
*
(
PAGE_SIZE
/
512
);
sector_t
sector
;
return
bdev_direct_access
(
bdev
,
sector
,
kaddr
,
pfn
,
size
);
sector
=
block
*
(
PAGE_SIZE
/
512
);
/* ext2 block to bdev sector */
BUG_ON
(
!
ops
->
direct_access
);
return
ops
->
direct_access
(
bdev
,
sector
,
kaddr
,
pfn
);
}
}
static
inline
int
static
inline
int
...
@@ -53,12 +47,13 @@ ext2_clear_xip_target(struct inode *inode, sector_t block)
...
@@ -53,12 +47,13 @@ ext2_clear_xip_target(struct inode *inode, sector_t block)
{
{
void
*
kaddr
;
void
*
kaddr
;
unsigned
long
pfn
;
unsigned
long
pfn
;
int
rc
;
long
size
;
rc
=
__inode_direct_access
(
inode
,
block
,
&
kaddr
,
&
pfn
);
size
=
__inode_direct_access
(
inode
,
block
,
&
kaddr
,
&
pfn
,
PAGE_SIZE
);
if
(
!
rc
)
if
(
size
<
0
)
clear_page
(
kaddr
);
return
size
;
return
rc
;
clear_page
(
kaddr
);
return
0
;
}
}
void
ext2_xip_verify_sb
(
struct
super_block
*
sb
)
void
ext2_xip_verify_sb
(
struct
super_block
*
sb
)
...
@@ -77,7 +72,7 @@ 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
,
int
ext2_get_xip_mem
(
struct
address_space
*
mapping
,
pgoff_t
pgoff
,
int
create
,
void
**
kmem
,
unsigned
long
*
pfn
)
void
**
kmem
,
unsigned
long
*
pfn
)
{
{
int
rc
;
long
rc
;
sector_t
block
;
sector_t
block
;
/* first, retrieve the sector number */
/* first, retrieve the sector number */
...
@@ -86,6 +81,6 @@ int ext2_get_xip_mem(struct address_space *mapping, pgoff_t pgoff, int create,
...
@@ -86,6 +81,6 @@ int ext2_get_xip_mem(struct address_space *mapping, pgoff_t pgoff, int create,
return
rc
;
return
rc
;
/* retrieve address of the target data */
/* retrieve address of the target data */
rc
=
__inode_direct_access
(
mapping
->
host
,
block
,
kmem
,
pfn
);
rc
=
__inode_direct_access
(
mapping
->
host
,
block
,
kmem
,
pfn
,
PAGE_SIZE
);
return
rc
;
return
(
rc
<
0
)
?
rc
:
0
;
}
}
include/linux/blkdev.h
浏览文件 @
d4119ee0
...
@@ -1601,8 +1601,8 @@ struct block_device_operations {
...
@@ -1601,8 +1601,8 @@ struct block_device_operations {
int
(
*
rw_page
)(
struct
block_device
*
,
sector_t
,
struct
page
*
,
int
rw
);
int
(
*
rw_page
)(
struct
block_device
*
,
sector_t
,
struct
page
*
,
int
rw
);
int
(
*
ioctl
)
(
struct
block_device
*
,
fmode_t
,
unsigned
,
unsigned
long
);
int
(
*
ioctl
)
(
struct
block_device
*
,
fmode_t
,
unsigned
,
unsigned
long
);
int
(
*
compat_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
,
long
(
*
direct_access
)
(
struct
block_device
*
,
sector_t
,
void
**
,
unsigned
long
*
);
void
**
,
unsigned
long
*
pfn
,
long
size
);
unsigned
int
(
*
check_events
)
(
struct
gendisk
*
disk
,
unsigned
int
(
*
check_events
)
(
struct
gendisk
*
disk
,
unsigned
int
clearing
);
unsigned
int
clearing
);
/* ->media_changed() is DEPRECATED, use ->check_events() instead */
/* ->media_changed() is DEPRECATED, use ->check_events() instead */
...
@@ -1620,6 +1620,8 @@ extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,
...
@@ -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_read_page
(
struct
block_device
*
,
sector_t
,
struct
page
*
);
extern
int
bdev_write_page
(
struct
block_device
*
,
sector_t
,
struct
page
*
,
extern
int
bdev_write_page
(
struct
block_device
*
,
sector_t
,
struct
page
*
,
struct
writeback_control
*
);
struct
writeback_control
*
);
extern
long
bdev_direct_access
(
struct
block_device
*
,
sector_t
,
void
**
addr
,
unsigned
long
*
pfn
,
long
size
);
#else
/* CONFIG_BLOCK */
#else
/* CONFIG_BLOCK */
struct
block_device
;
struct
block_device
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录