Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
e3df41f9
cloud-kernel
项目概览
openanolis
/
cloud-kernel
接近 2 年 前同步成功
通知
169
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
e3df41f9
编写于
11月 30, 2016
作者:
D
Dave Chinner
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'xfs-4.10-misc-fixes-2' into iomap-4.10-directio
上级
9484ab1b
f782088c
变更
30
展开全部
隐藏空白更改
内联
并排
Showing
30 changed file
with
961 addition
and
1064 deletion
+961
-1064
fs/iomap.c
fs/iomap.c
+2
-3
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_bmap.c
+365
-366
fs/xfs/libxfs/xfs_bmap.h
fs/xfs/libxfs/xfs_bmap.h
+9
-8
fs/xfs/libxfs/xfs_btree.c
fs/xfs/libxfs/xfs_btree.c
+1
-1
fs/xfs/libxfs/xfs_defer.c
fs/xfs/libxfs/xfs_defer.c
+5
-12
fs/xfs/libxfs/xfs_dir2.c
fs/xfs/libxfs/xfs_dir2.c
+1
-1
fs/xfs/libxfs/xfs_dquot_buf.c
fs/xfs/libxfs/xfs_dquot_buf.c
+1
-2
fs/xfs/libxfs/xfs_format.h
fs/xfs/libxfs/xfs_format.h
+0
-1
fs/xfs/libxfs/xfs_inode_buf.c
fs/xfs/libxfs/xfs_inode_buf.c
+12
-1
fs/xfs/libxfs/xfs_inode_buf.h
fs/xfs/libxfs/xfs_inode_buf.h
+2
-0
fs/xfs/libxfs/xfs_inode_fork.c
fs/xfs/libxfs/xfs_inode_fork.c
+65
-12
fs/xfs/libxfs/xfs_inode_fork.h
fs/xfs/libxfs/xfs_inode_fork.h
+7
-0
fs/xfs/libxfs/xfs_types.h
fs/xfs/libxfs/xfs_types.h
+0
-1
fs/xfs/xfs_aops.c
fs/xfs/xfs_aops.c
+28
-10
fs/xfs/xfs_bmap_util.c
fs/xfs/xfs_bmap_util.c
+15
-18
fs/xfs/xfs_buf.h
fs/xfs/xfs_buf.h
+1
-0
fs/xfs/xfs_file.c
fs/xfs/xfs_file.c
+33
-199
fs/xfs/xfs_icache.c
fs/xfs/xfs_icache.c
+24
-18
fs/xfs/xfs_icreate_item.c
fs/xfs/xfs_icreate_item.c
+1
-1
fs/xfs/xfs_inode.h
fs/xfs/xfs_inode.h
+6
-5
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_inode_item.c
+2
-2
fs/xfs/xfs_ioctl.c
fs/xfs/xfs_ioctl.c
+2
-4
fs/xfs/xfs_iomap.c
fs/xfs/xfs_iomap.c
+63
-48
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.c
+1
-0
fs/xfs/xfs_qm.c
fs/xfs/xfs_qm.c
+1
-1
fs/xfs/xfs_reflink.c
fs/xfs/xfs_reflink.c
+294
-328
fs/xfs/xfs_reflink.h
fs/xfs/xfs_reflink.h
+6
-11
fs/xfs/xfs_sysfs.c
fs/xfs/xfs_sysfs.c
+2
-2
fs/xfs/xfs_trace.h
fs/xfs/xfs_trace.h
+1
-3
include/linux/iomap.h
include/linux/iomap.h
+11
-6
未找到文件。
fs/iomap.c
浏览文件 @
e3df41f9
...
...
@@ -433,8 +433,7 @@ iomap_page_mkwrite_actor(struct inode *inode, loff_t pos, loff_t length,
struct
page
*
page
=
data
;
int
ret
;
ret
=
__block_write_begin_int
(
page
,
pos
&
~
PAGE_MASK
,
length
,
NULL
,
iomap
);
ret
=
__block_write_begin_int
(
page
,
pos
,
length
,
NULL
,
iomap
);
if
(
ret
)
return
ret
;
...
...
@@ -562,7 +561,7 @@ int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fi,
}
while
(
len
>
0
)
{
ret
=
iomap_apply
(
inode
,
start
,
len
,
0
,
ops
,
&
ctx
,
ret
=
iomap_apply
(
inode
,
start
,
len
,
IOMAP_REPORT
,
ops
,
&
ctx
,
iomap_fiemap_actor
);
/* inode with no (attribute) mapping will give ENOENT */
if
(
ret
==
-
ENOENT
)
...
...
fs/xfs/libxfs/xfs_bmap.c
浏览文件 @
e3df41f9
此差异已折叠。
点击以展开。
fs/xfs/libxfs/xfs_bmap.h
浏览文件 @
e3df41f9
...
...
@@ -190,6 +190,8 @@ void xfs_bmap_trace_exlist(struct xfs_inode *ip, xfs_extnum_t cnt,
#define XFS_BMAP_TRACE_EXLIST(ip,c,w)
#endif
void
xfs_trim_extent
(
struct
xfs_bmbt_irec
*
irec
,
xfs_fileoff_t
bno
,
xfs_filblks_t
len
);
int
xfs_bmap_add_attrfork
(
struct
xfs_inode
*
ip
,
int
size
,
int
rsvd
);
void
xfs_bmap_local_to_extents_empty
(
struct
xfs_inode
*
ip
,
int
whichfork
);
void
xfs_bmap_add_free
(
struct
xfs_mount
*
mp
,
struct
xfs_defer_ops
*
dfops
,
...
...
@@ -221,7 +223,11 @@ int xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip,
xfs_fileoff_t
bno
,
xfs_filblks_t
len
,
int
flags
,
xfs_extnum_t
nexts
,
xfs_fsblock_t
*
firstblock
,
struct
xfs_defer_ops
*
dfops
,
int
*
done
);
int
xfs_bunmapi_cow
(
struct
xfs_inode
*
ip
,
struct
xfs_bmbt_irec
*
del
);
int
xfs_bmap_del_extent_delay
(
struct
xfs_inode
*
ip
,
int
whichfork
,
xfs_extnum_t
*
idx
,
struct
xfs_bmbt_irec
*
got
,
struct
xfs_bmbt_irec
*
del
);
void
xfs_bmap_del_extent_cow
(
struct
xfs_inode
*
ip
,
xfs_extnum_t
*
idx
,
struct
xfs_bmbt_irec
*
got
,
struct
xfs_bmbt_irec
*
del
);
int
xfs_check_nostate_extents
(
struct
xfs_ifork
*
ifp
,
xfs_extnum_t
idx
,
xfs_extnum_t
num
);
uint
xfs_default_attroffset
(
struct
xfs_inode
*
ip
);
...
...
@@ -231,14 +237,9 @@ int xfs_bmap_shift_extents(struct xfs_trans *tp, struct xfs_inode *ip,
struct
xfs_defer_ops
*
dfops
,
enum
shift_direction
direction
,
int
num_exts
);
int
xfs_bmap_split_extent
(
struct
xfs_inode
*
ip
,
xfs_fileoff_t
split_offset
);
struct
xfs_bmbt_rec_host
*
xfs_bmap_search_extents
(
struct
xfs_inode
*
ip
,
xfs_fileoff_t
bno
,
int
fork
,
int
*
eofp
,
xfs_extnum_t
*
lastxp
,
struct
xfs_bmbt_irec
*
gotp
,
struct
xfs_bmbt_irec
*
prevp
);
int
xfs_bmapi_reserve_delalloc
(
struct
xfs_inode
*
ip
,
int
whichfork
,
xfs_fileoff_t
aoff
,
xfs_filblks_t
len
,
struct
xfs_bmbt_irec
*
got
,
struct
xfs_bmbt_irec
*
prev
,
xfs_extnum_t
*
lastx
,
int
eof
);
xfs_fileoff_t
off
,
xfs_filblks_t
len
,
xfs_filblks_t
prealloc
,
struct
xfs_bmbt_irec
*
got
,
xfs_extnum_t
*
lastx
,
int
eof
);
enum
xfs_bmap_intent_type
{
XFS_BMAP_MAP
=
1
,
...
...
fs/xfs/libxfs/xfs_btree.c
浏览文件 @
e3df41f9
...
...
@@ -4826,7 +4826,7 @@ xfs_btree_calc_size(
return
rval
;
}
int
static
int
xfs_btree_count_blocks_helper
(
struct
xfs_btree_cur
*
cur
,
int
level
,
...
...
fs/xfs/libxfs/xfs_defer.c
浏览文件 @
e3df41f9
...
...
@@ -199,9 +199,9 @@ xfs_defer_intake_work(
struct
xfs_defer_pending
*
dfp
;
list_for_each_entry
(
dfp
,
&
dop
->
dop_intake
,
dfp_list
)
{
trace_xfs_defer_intake_work
(
tp
->
t_mountp
,
dfp
);
dfp
->
dfp_intent
=
dfp
->
dfp_type
->
create_intent
(
tp
,
dfp
->
dfp_count
);
trace_xfs_defer_intake_work
(
tp
->
t_mountp
,
dfp
);
list_sort
(
tp
->
t_mountp
,
&
dfp
->
dfp_work
,
dfp
->
dfp_type
->
diff_items
);
list_for_each
(
li
,
&
dfp
->
dfp_work
)
...
...
@@ -221,21 +221,14 @@ xfs_defer_trans_abort(
struct
xfs_defer_pending
*
dfp
;
trace_xfs_defer_trans_abort
(
tp
->
t_mountp
,
dop
);
/*
* If the transaction was committed, drop the intent reference
* since we're bailing out of here. The other reference is
* dropped when the intent hits the AIL. If the transaction
* was not committed, the intent is freed by the intent item
* unlock handler on abort.
*/
if
(
!
dop
->
dop_committed
)
return
;
/* Abort intent items. */
/* Abort intent items
that don't have a done item
. */
list_for_each_entry
(
dfp
,
&
dop
->
dop_pending
,
dfp_list
)
{
trace_xfs_defer_pending_abort
(
tp
->
t_mountp
,
dfp
);
if
(
!
dfp
->
dfp_done
)
if
(
dfp
->
dfp_intent
&&
!
dfp
->
dfp_done
)
{
dfp
->
dfp_type
->
abort_intent
(
dfp
->
dfp_intent
);
dfp
->
dfp_intent
=
NULL
;
}
}
/* Shut down FS. */
...
...
fs/xfs/libxfs/xfs_dir2.c
浏览文件 @
e3df41f9
...
...
@@ -93,7 +93,7 @@ xfs_ascii_ci_compname(
return
result
;
}
static
struct
xfs_nameops
xfs_ascii_ci_nameops
=
{
static
const
struct
xfs_nameops
xfs_ascii_ci_nameops
=
{
.
hashname
=
xfs_ascii_ci_hashname
,
.
compname
=
xfs_ascii_ci_compname
,
};
...
...
fs/xfs/libxfs/xfs_dquot_buf.c
浏览文件 @
e3df41f9
...
...
@@ -191,8 +191,7 @@ xfs_dquot_buf_verify_crc(
if
(
mp
->
m_quotainfo
)
ndquots
=
mp
->
m_quotainfo
->
qi_dqperchunk
;
else
ndquots
=
xfs_calc_dquots_per_chunk
(
XFS_BB_TO_FSB
(
mp
,
bp
->
b_length
));
ndquots
=
xfs_calc_dquots_per_chunk
(
bp
->
b_length
);
for
(
i
=
0
;
i
<
ndquots
;
i
++
,
d
++
)
{
if
(
!
xfs_verify_cksum
((
char
*
)
d
,
sizeof
(
struct
xfs_dqblk
),
...
...
fs/xfs/libxfs/xfs_format.h
浏览文件 @
e3df41f9
...
...
@@ -865,7 +865,6 @@ typedef struct xfs_timestamp {
* padding field for v3 inodes.
*/
#define XFS_DINODE_MAGIC 0x494e
/* 'IN' */
#define XFS_DINODE_GOOD_VERSION(v) ((v) >= 1 && (v) <= 3)
typedef
struct
xfs_dinode
{
__be16
di_magic
;
/* inode magic # = XFS_DINODE_MAGIC */
__be16
di_mode
;
/* mode and type of file */
...
...
fs/xfs/libxfs/xfs_inode_buf.c
浏览文件 @
e3df41f9
...
...
@@ -57,6 +57,17 @@ xfs_inobp_check(
}
#endif
bool
xfs_dinode_good_version
(
struct
xfs_mount
*
mp
,
__u8
version
)
{
if
(
xfs_sb_version_hascrc
(
&
mp
->
m_sb
))
return
version
==
3
;
return
version
==
1
||
version
==
2
;
}
/*
* If we are doing readahead on an inode buffer, we might be in log recovery
* reading an inode allocation buffer that hasn't yet been replayed, and hence
...
...
@@ -91,7 +102,7 @@ xfs_inode_buf_verify(
dip
=
xfs_buf_offset
(
bp
,
(
i
<<
mp
->
m_sb
.
sb_inodelog
));
di_ok
=
dip
->
di_magic
==
cpu_to_be16
(
XFS_DINODE_MAGIC
)
&&
XFS_DINODE_GOOD_VERSION
(
dip
->
di_version
);
xfs_dinode_good_version
(
mp
,
dip
->
di_version
);
if
(
unlikely
(
XFS_TEST_ERROR
(
!
di_ok
,
mp
,
XFS_ERRTAG_ITOBP_INOTOBP
,
XFS_RANDOM_ITOBP_INOTOBP
)))
{
...
...
fs/xfs/libxfs/xfs_inode_buf.h
浏览文件 @
e3df41f9
...
...
@@ -74,6 +74,8 @@ void xfs_inode_from_disk(struct xfs_inode *ip, struct xfs_dinode *from);
void
xfs_log_dinode_to_disk
(
struct
xfs_log_dinode
*
from
,
struct
xfs_dinode
*
to
);
bool
xfs_dinode_good_version
(
struct
xfs_mount
*
mp
,
__u8
version
);
#if defined(DEBUG)
void
xfs_inobp_check
(
struct
xfs_mount
*
,
struct
xfs_buf
*
);
#else
...
...
fs/xfs/libxfs/xfs_inode_fork.c
浏览文件 @
e3df41f9
...
...
@@ -775,6 +775,13 @@ xfs_idestroy_fork(
}
}
/* Count number of incore extents based on if_bytes */
xfs_extnum_t
xfs_iext_count
(
struct
xfs_ifork
*
ifp
)
{
return
ifp
->
if_bytes
/
(
uint
)
sizeof
(
xfs_bmbt_rec_t
);
}
/*
* Convert in-core extents to on-disk form
*
...
...
@@ -803,7 +810,7 @@ xfs_iextents_copy(
ASSERT
(
xfs_isilocked
(
ip
,
XFS_ILOCK_EXCL
|
XFS_ILOCK_SHARED
));
ASSERT
(
ifp
->
if_bytes
>
0
);
nrecs
=
ifp
->
if_bytes
/
(
uint
)
sizeof
(
xfs_bmbt_rec_t
);
nrecs
=
xfs_iext_count
(
ifp
);
XFS_BMAP_TRACE_EXLIST
(
ip
,
nrecs
,
whichfork
);
ASSERT
(
nrecs
>
0
);
...
...
@@ -941,7 +948,7 @@ xfs_iext_get_ext(
xfs_extnum_t
idx
)
/* index of target extent */
{
ASSERT
(
idx
>=
0
);
ASSERT
(
idx
<
ifp
->
if_bytes
/
sizeof
(
xfs_bmbt_rec_t
));
ASSERT
(
idx
<
xfs_iext_count
(
ifp
));
if
((
ifp
->
if_flags
&
XFS_IFEXTIREC
)
&&
(
idx
==
0
))
{
return
ifp
->
if_u1
.
if_ext_irec
->
er_extbuf
;
...
...
@@ -1017,7 +1024,7 @@ xfs_iext_add(
int
new_size
;
/* size of extents after adding */
xfs_extnum_t
nextents
;
/* number of extents in file */
nextents
=
ifp
->
if_bytes
/
(
uint
)
sizeof
(
xfs_bmbt_rec_t
);
nextents
=
xfs_iext_count
(
ifp
);
ASSERT
((
idx
>=
0
)
&&
(
idx
<=
nextents
));
byte_diff
=
ext_diff
*
sizeof
(
xfs_bmbt_rec_t
);
new_size
=
ifp
->
if_bytes
+
byte_diff
;
...
...
@@ -1241,7 +1248,7 @@ xfs_iext_remove(
trace_xfs_iext_remove
(
ip
,
idx
,
state
,
_RET_IP_
);
ASSERT
(
ext_diff
>
0
);
nextents
=
ifp
->
if_bytes
/
(
uint
)
sizeof
(
xfs_bmbt_rec_t
);
nextents
=
xfs_iext_count
(
ifp
);
new_size
=
(
nextents
-
ext_diff
)
*
sizeof
(
xfs_bmbt_rec_t
);
if
(
new_size
==
0
)
{
...
...
@@ -1270,7 +1277,7 @@ xfs_iext_remove_inline(
ASSERT
(
!
(
ifp
->
if_flags
&
XFS_IFEXTIREC
));
ASSERT
(
idx
<
XFS_INLINE_EXTS
);
nextents
=
ifp
->
if_bytes
/
(
uint
)
sizeof
(
xfs_bmbt_rec_t
);
nextents
=
xfs_iext_count
(
ifp
);
ASSERT
(((
nextents
-
ext_diff
)
>
0
)
&&
(
nextents
-
ext_diff
)
<
XFS_INLINE_EXTS
);
...
...
@@ -1309,7 +1316,7 @@ xfs_iext_remove_direct(
ASSERT
(
!
(
ifp
->
if_flags
&
XFS_IFEXTIREC
));
new_size
=
ifp
->
if_bytes
-
(
ext_diff
*
sizeof
(
xfs_bmbt_rec_t
));
nextents
=
ifp
->
if_bytes
/
(
uint
)
sizeof
(
xfs_bmbt_rec_t
);
nextents
=
xfs_iext_count
(
ifp
);
if
(
new_size
==
0
)
{
xfs_iext_destroy
(
ifp
);
...
...
@@ -1546,7 +1553,7 @@ xfs_iext_indirect_to_direct(
int
size
;
/* size of file extents */
ASSERT
(
ifp
->
if_flags
&
XFS_IFEXTIREC
);
nextents
=
ifp
->
if_bytes
/
(
uint
)
sizeof
(
xfs_bmbt_rec_t
);
nextents
=
xfs_iext_count
(
ifp
);
ASSERT
(
nextents
<=
XFS_LINEAR_EXTS
);
size
=
nextents
*
sizeof
(
xfs_bmbt_rec_t
);
...
...
@@ -1620,7 +1627,7 @@ xfs_iext_bno_to_ext(
xfs_extnum_t
nextents
;
/* number of file extents */
xfs_fileoff_t
startoff
=
0
;
/* start offset of extent */
nextents
=
ifp
->
if_bytes
/
(
uint
)
sizeof
(
xfs_bmbt_rec_t
);
nextents
=
xfs_iext_count
(
ifp
);
if
(
nextents
==
0
)
{
*
idxp
=
0
;
return
NULL
;
...
...
@@ -1733,8 +1740,8 @@ xfs_iext_idx_to_irec(
ASSERT
(
ifp
->
if_flags
&
XFS_IFEXTIREC
);
ASSERT
(
page_idx
>=
0
);
ASSERT
(
page_idx
<=
ifp
->
if_bytes
/
sizeof
(
xfs_bmbt_rec_t
));
ASSERT
(
page_idx
<
ifp
->
if_bytes
/
sizeof
(
xfs_bmbt_rec_t
)
||
realloc
);
ASSERT
(
page_idx
<=
xfs_iext_count
(
ifp
));
ASSERT
(
page_idx
<
xfs_iext_count
(
ifp
)
||
realloc
);
nlists
=
ifp
->
if_real_bytes
/
XFS_IEXT_BUFSZ
;
erp_idx
=
0
;
...
...
@@ -1782,7 +1789,7 @@ xfs_iext_irec_init(
xfs_extnum_t
nextents
;
/* number of extents in file */
ASSERT
(
!
(
ifp
->
if_flags
&
XFS_IFEXTIREC
));
nextents
=
ifp
->
if_bytes
/
(
uint
)
sizeof
(
xfs_bmbt_rec_t
);
nextents
=
xfs_iext_count
(
ifp
);
ASSERT
(
nextents
<=
XFS_LINEAR_EXTS
);
erp
=
kmem_alloc
(
sizeof
(
xfs_ext_irec_t
),
KM_NOFS
);
...
...
@@ -1906,7 +1913,7 @@ xfs_iext_irec_compact(
ASSERT
(
ifp
->
if_flags
&
XFS_IFEXTIREC
);
nlists
=
ifp
->
if_real_bytes
/
XFS_IEXT_BUFSZ
;
nextents
=
ifp
->
if_bytes
/
(
uint
)
sizeof
(
xfs_bmbt_rec_t
);
nextents
=
xfs_iext_count
(
ifp
);
if
(
nextents
==
0
)
{
xfs_iext_destroy
(
ifp
);
...
...
@@ -1996,3 +2003,49 @@ xfs_ifork_init_cow(
ip
->
i_cformat
=
XFS_DINODE_FMT_EXTENTS
;
ip
->
i_cnextents
=
0
;
}
/*
* Lookup the extent covering bno.
*
* If there is an extent covering bno return the extent index, and store the
* expanded extent structure in *gotp, and the extent index in *idx.
* If there is no extent covering bno, but there is an extent after it (e.g.
* it lies in a hole) return that extent in *gotp and its index in *idx
* instead.
* If bno is beyond the last extent return false, and return the index after
* the last valid index in *idxp.
*/
bool
xfs_iext_lookup_extent
(
struct
xfs_inode
*
ip
,
struct
xfs_ifork
*
ifp
,
xfs_fileoff_t
bno
,
xfs_extnum_t
*
idxp
,
struct
xfs_bmbt_irec
*
gotp
)
{
struct
xfs_bmbt_rec_host
*
ep
;
XFS_STATS_INC
(
ip
->
i_mount
,
xs_look_exlist
);
ep
=
xfs_iext_bno_to_ext
(
ifp
,
bno
,
idxp
);
if
(
!
ep
)
return
false
;
xfs_bmbt_get_all
(
ep
,
gotp
);
return
true
;
}
/*
* Return true if there is an extent at index idx, and return the expanded
* extent structure at idx in that case. Else return false.
*/
bool
xfs_iext_get_extent
(
struct
xfs_ifork
*
ifp
,
xfs_extnum_t
idx
,
struct
xfs_bmbt_irec
*
gotp
)
{
if
(
idx
<
0
||
idx
>=
xfs_iext_count
(
ifp
))
return
false
;
xfs_bmbt_get_all
(
xfs_iext_get_ext
(
ifp
,
idx
),
gotp
);
return
true
;
}
fs/xfs/libxfs/xfs_inode_fork.h
浏览文件 @
e3df41f9
...
...
@@ -152,6 +152,7 @@ void xfs_init_local_fork(struct xfs_inode *, int, const void *, int);
struct
xfs_bmbt_rec_host
*
xfs_iext_get_ext
(
struct
xfs_ifork
*
,
xfs_extnum_t
);
xfs_extnum_t
xfs_iext_count
(
struct
xfs_ifork
*
);
void
xfs_iext_insert
(
struct
xfs_inode
*
,
xfs_extnum_t
,
xfs_extnum_t
,
struct
xfs_bmbt_irec
*
,
int
);
void
xfs_iext_add
(
struct
xfs_ifork
*
,
xfs_extnum_t
,
int
);
...
...
@@ -181,6 +182,12 @@ void xfs_iext_irec_compact_pages(struct xfs_ifork *);
void
xfs_iext_irec_compact_full
(
struct
xfs_ifork
*
);
void
xfs_iext_irec_update_extoffs
(
struct
xfs_ifork
*
,
int
,
int
);
bool
xfs_iext_lookup_extent
(
struct
xfs_inode
*
ip
,
struct
xfs_ifork
*
ifp
,
xfs_fileoff_t
bno
,
xfs_extnum_t
*
idxp
,
struct
xfs_bmbt_irec
*
gotp
);
bool
xfs_iext_get_extent
(
struct
xfs_ifork
*
ifp
,
xfs_extnum_t
idx
,
struct
xfs_bmbt_irec
*
gotp
);
extern
struct
kmem_zone
*
xfs_ifork_zone
;
extern
void
xfs_ifork_init_cow
(
struct
xfs_inode
*
ip
);
...
...
fs/xfs/libxfs/xfs_types.h
浏览文件 @
e3df41f9
...
...
@@ -57,7 +57,6 @@ typedef __int64_t xfs_sfiloff_t; /* signed block number in a file */
#define NULLAGBLOCK ((xfs_agblock_t)-1)
#define NULLAGNUMBER ((xfs_agnumber_t)-1)
#define NULLEXTNUM ((xfs_extnum_t)-1)
#define NULLCOMMITLSN ((xfs_lsn_t)-1)
...
...
fs/xfs/xfs_aops.c
浏览文件 @
e3df41f9
...
...
@@ -777,7 +777,7 @@ xfs_map_cow(
{
struct
xfs_inode
*
ip
=
XFS_I
(
inode
);
struct
xfs_bmbt_irec
imap
;
bool
is_cow
=
false
,
need_alloc
=
false
;
bool
is_cow
=
false
;
int
error
;
/*
...
...
@@ -795,7 +795,7 @@ xfs_map_cow(
* Else we need to check if there is a COW mapping at this offset.
*/
xfs_ilock
(
ip
,
XFS_ILOCK_SHARED
);
is_cow
=
xfs_reflink_find_cow_mapping
(
ip
,
offset
,
&
imap
,
&
need_alloc
);
is_cow
=
xfs_reflink_find_cow_mapping
(
ip
,
offset
,
&
imap
);
xfs_iunlock
(
ip
,
XFS_ILOCK_SHARED
);
if
(
!
is_cow
)
...
...
@@ -805,7 +805,7 @@ xfs_map_cow(
* And if the COW mapping has a delayed extent here we need to
* allocate real space for it now.
*/
if
(
need_alloc
)
{
if
(
isnullstartblock
(
imap
.
br_startblock
)
)
{
error
=
xfs_iomap_write_allocate
(
ip
,
XFS_COW_FORK
,
offset
,
&
imap
);
if
(
error
)
...
...
@@ -1311,7 +1311,6 @@ __xfs_get_blocks(
ssize_t
size
;
int
new
=
0
;
bool
is_cow
=
false
;
bool
need_alloc
=
false
;
BUG_ON
(
create
&&
!
direct
);
...
...
@@ -1337,9 +1336,11 @@ __xfs_get_blocks(
end_fsb
=
XFS_B_TO_FSB
(
mp
,
(
xfs_ufsize_t
)
offset
+
size
);
offset_fsb
=
XFS_B_TO_FSBT
(
mp
,
offset
);
if
(
create
&&
direct
&&
xfs_is_reflink_inode
(
ip
))
is_cow
=
xfs_reflink_find_cow_mapping
(
ip
,
offset
,
&
imap
,
&
need_alloc
);
if
(
create
&&
direct
&&
xfs_is_reflink_inode
(
ip
))
{
is_cow
=
xfs_reflink_find_cow_mapping
(
ip
,
offset
,
&
imap
);
ASSERT
(
!
is_cow
||
!
isnullstartblock
(
imap
.
br_startblock
));
}
if
(
!
is_cow
)
{
error
=
xfs_bmapi_read
(
ip
,
offset_fsb
,
end_fsb
-
offset_fsb
,
&
imap
,
&
nimaps
,
XFS_BMAPI_ENTIRE
);
...
...
@@ -1356,10 +1357,29 @@ __xfs_get_blocks(
xfs_reflink_trim_irec_to_next_cow
(
ip
,
offset_fsb
,
&
imap
);
}
ASSERT
(
!
need_alloc
);
if
(
error
)
goto
out_unlock
;
/*
* The only time we can ever safely find delalloc blocks on direct I/O
* is a dio write to post-eof speculative preallocation. All other
* scenarios are indicative of a problem or misuse (such as mixing
* direct and mapped I/O).
*
* The file may be unmapped by the time we get here so we cannot
* reliably fail the I/O based on mapping. Instead, fail the I/O if this
* is a read or a write within eof. Otherwise, carry on but warn as a
* precuation if the file happens to be mapped.
*/
if
(
direct
&&
imap
.
br_startblock
==
DELAYSTARTBLOCK
)
{
if
(
!
create
||
offset
<
i_size_read
(
VFS_I
(
ip
)))
{
WARN_ON_ONCE
(
1
);
error
=
-
EIO
;
goto
out_unlock
;
}
WARN_ON_ONCE
(
mapping_mapped
(
VFS_I
(
ip
)
->
i_mapping
));
}
/* for DAX, we convert unwritten extents directly */
if
(
create
&&
(
!
nimaps
||
...
...
@@ -1444,8 +1464,6 @@ __xfs_get_blocks(
(
new
||
ISUNWRITTEN
(
&
imap
))))
set_buffer_new
(
bh_result
);
BUG_ON
(
direct
&&
imap
.
br_startblock
==
DELAYSTARTBLOCK
);
return
0
;
out_unlock:
...
...
fs/xfs/xfs_bmap_util.c
浏览文件 @
e3df41f9
...
...
@@ -359,9 +359,7 @@ xfs_bmap_count_blocks(
mp
=
ip
->
i_mount
;
ifp
=
XFS_IFORK_PTR
(
ip
,
whichfork
);
if
(
XFS_IFORK_FORMAT
(
ip
,
whichfork
)
==
XFS_DINODE_FMT_EXTENTS
)
{
xfs_bmap_count_leaves
(
ifp
,
0
,
ifp
->
if_bytes
/
(
uint
)
sizeof
(
xfs_bmbt_rec_t
),
count
);
xfs_bmap_count_leaves
(
ifp
,
0
,
xfs_iext_count
(
ifp
),
count
);
return
0
;
}
...
...
@@ -426,7 +424,7 @@ xfs_getbmapx_fix_eof_hole(
ifp
=
XFS_IFORK_PTR
(
ip
,
whichfork
);
if
(
!
moretocome
&&
xfs_iext_bno_to_ext
(
ifp
,
fileblock
,
&
lastx
)
&&
(
lastx
==
(
ifp
->
if_bytes
/
(
uint
)
sizeof
(
xfs_bmbt_rec_t
))
-
1
))
(
lastx
==
xfs_iext_count
(
ifp
)
-
1
))
out
->
bmv_oflags
|=
BMV_OF_LAST
;
}
...
...
@@ -1792,6 +1790,7 @@ xfs_swap_extent_forks(
struct
xfs_ifork
tempifp
,
*
ifp
,
*
tifp
;
int
aforkblks
=
0
;
int
taforkblks
=
0
;
xfs_extnum_t
nextents
;
__uint64_t
tmp
;
int
error
;
...
...
@@ -1877,14 +1876,13 @@ xfs_swap_extent_forks(
switch
(
ip
->
i_d
.
di_format
)
{
case
XFS_DINODE_FMT_EXTENTS
:
/*
If the extents fit in the inode, fix the
*
pointer. Otherwise it's already NULL or
* pointing to the extent.
/*
*
If the extents fit in the inode, fix the pointer. Otherwise
*
it's already NULL or
pointing to the extent.
*/
if
(
ip
->
i_d
.
di_nextents
<=
XFS_INLINE_EXTS
)
{
ifp
->
if_u1
.
if_extents
=
ifp
->
if_u2
.
if_inline_ext
;
}
nextents
=
xfs_iext_count
(
&
ip
->
i_df
);
if
(
nextents
<=
XFS_INLINE_EXTS
)
ifp
->
if_u1
.
if_extents
=
ifp
->
if_u2
.
if_inline_ext
;
(
*
src_log_flags
)
|=
XFS_ILOG_DEXT
;
break
;
case
XFS_DINODE_FMT_BTREE
:
...
...
@@ -1896,14 +1894,13 @@ xfs_swap_extent_forks(
switch
(
tip
->
i_d
.
di_format
)
{
case
XFS_DINODE_FMT_EXTENTS
:
/*
If the extents fit in the inode, fix the
*
pointer. Otherwise it's already NULL or
* pointing to the extent.
/*
*
If the extents fit in the inode, fix the pointer. Otherwise
*
it's already NULL or
pointing to the extent.
*/
if
(
tip
->
i_d
.
di_nextents
<=
XFS_INLINE_EXTS
)
{
tifp
->
if_u1
.
if_extents
=
tifp
->
if_u2
.
if_inline_ext
;
}
nextents
=
xfs_iext_count
(
&
tip
->
i_df
);
if
(
nextents
<=
XFS_INLINE_EXTS
)
tifp
->
if_u1
.
if_extents
=
tifp
->
if_u2
.
if_inline_ext
;
(
*
target_log_flags
)
|=
XFS_ILOG_DEXT
;
break
;
case
XFS_DINODE_FMT_BTREE
:
...
...
fs/xfs/xfs_buf.h
浏览文件 @
e3df41f9
...
...
@@ -71,6 +71,7 @@ typedef unsigned int xfs_buf_flags_t;
{ XBF_READ, "READ" }, \
{ XBF_WRITE, "WRITE" }, \
{ XBF_READ_AHEAD, "READ_AHEAD" }, \
{ XBF_NO_IOACCT, "NO_IOACCT" }, \
{ XBF_ASYNC, "ASYNC" }, \
{ XBF_DONE, "DONE" }, \
{ XBF_STALE, "STALE" }, \
...
...
fs/xfs/xfs_file.c
浏览文件 @
e3df41f9
...
...
@@ -249,6 +249,7 @@ xfs_file_dio_aio_read(
struct
xfs_inode
*
ip
=
XFS_I
(
inode
);
loff_t
isize
=
i_size_read
(
inode
);
size_t
count
=
iov_iter_count
(
to
);
loff_t
end
=
iocb
->
ki_pos
+
count
-
1
;
struct
iov_iter
data
;
struct
xfs_buftarg
*
target
;
ssize_t
ret
=
0
;
...
...
@@ -272,49 +273,21 @@ xfs_file_dio_aio_read(
file_accessed
(
iocb
->
ki_filp
);
/*
* Locking is a bit tricky here. If we take an exclusive lock for direct
* IO, we effectively serialise all new concurrent read IO to this file
* and block it behind IO that is currently in progress because IO in
* progress holds the IO lock shared. We only need to hold the lock
* exclusive to blow away the page cache, so only take lock exclusively
* if the page cache needs invalidation. This allows the normal direct
* IO case of no page cache pages to proceeed concurrently without
* serialisation.
*/
xfs_rw_ilock
(
ip
,
XFS_IOLOCK_SHARED
);
if
(
mapping
->
nrpages
)
{
xfs_rw_iunlock
(
ip
,
XFS_IOLOCK_SHARED
);
xfs_rw_ilock
(
ip
,
XFS_IOLOCK_EXCL
);
ret
=
filemap_write_and_wait_range
(
mapping
,
iocb
->
ki_pos
,
end
);
if
(
ret
)
goto
out_unlock
;
/*
* The generic dio code only flushes the range of the particular
* I/O. Because we take an exclusive lock here, this whole
* sequence is considerably more expensive for us. This has a
* noticeable performance impact for any file with cached pages,
* even when outside of the range of the particular I/O.
*
* Hence, amortize the cost of the lock against a full file
* flush and reduce the chances of repeated iolock cycles going
* forward.
* Invalidate whole pages. This can return an error if we fail
* to invalidate a page, but this should never happen on XFS.
* Warn if it does fail.
*/
if
(
mapping
->
nrpages
)
{
ret
=
filemap_write_and_wait
(
mapping
);
if
(
ret
)
{
xfs_rw_iunlock
(
ip
,
XFS_IOLOCK_EXCL
);
return
ret
;
}
/*
* Invalidate whole pages. This can return an error if
* we fail to invalidate a page, but this should never
* happen on XFS. Warn if it does fail.
*/
ret
=
invalidate_inode_pages2
(
mapping
);
WARN_ON_ONCE
(
ret
);
ret
=
0
;
}
xfs_rw_ilock_demote
(
ip
,
XFS_IOLOCK_EXCL
);
ret
=
invalidate_inode_pages2_range
(
mapping
,
iocb
->
ki_pos
>>
PAGE_SHIFT
,
end
>>
PAGE_SHIFT
);
WARN_ON_ONCE
(
ret
);
ret
=
0
;
}
data
=
*
to
;
...
...
@@ -324,8 +297,9 @@ xfs_file_dio_aio_read(
iocb
->
ki_pos
+=
ret
;
iov_iter_advance
(
to
,
ret
);
}
xfs_rw_iunlock
(
ip
,
XFS_IOLOCK_SHARED
);
out_unlock:
xfs_rw_iunlock
(
ip
,
XFS_IOLOCK_SHARED
);
return
ret
;
}
...
...
@@ -570,61 +544,49 @@ xfs_file_dio_aio_write(
if
((
iocb
->
ki_pos
|
count
)
&
target
->
bt_logical_sectormask
)
return
-
EINVAL
;
/* "unaligned" here means not aligned to a filesystem block */
if
((
iocb
->
ki_pos
&
mp
->
m_blockmask
)
||
((
iocb
->
ki_pos
+
count
)
&
mp
->
m_blockmask
))
unaligned_io
=
1
;
/*
*
We don't need to take an exclusive lock unless there page cache needs
* t
o be invalidated or unaligned IO is being executed. We don't need to
*
consider the EOF extension case here because
*
xfs_file_aio_write_checks() will relock the inode as necessary for
*
EOF zeroing cases and fill out the new
inode size as appropriate.
*
Don't take the exclusive iolock here unless the I/O is unaligned to
* t
he file system block size. We don't need to consider the EOF
*
extension case here because xfs_file_aio_write_checks() will relock
*
the inode as necessary for EOF zeroing cases and fill out the new
* inode size as appropriate.
*/
if
(
unaligned_io
||
mapping
->
nrpages
)
if
((
iocb
->
ki_pos
&
mp
->
m_blockmask
)
||
((
iocb
->
ki_pos
+
count
)
&
mp
->
m_blockmask
))
{
unaligned_io
=
1
;
iolock
=
XFS_IOLOCK_EXCL
;
else
}
else
{
iolock
=
XFS_IOLOCK_SHARED
;
xfs_rw_ilock
(
ip
,
iolock
);
/*
* Recheck if there are cached pages that need invalidate after we got
* the iolock to protect against other threads adding new pages while
* we were waiting for the iolock.
*/
if
(
mapping
->
nrpages
&&
iolock
==
XFS_IOLOCK_SHARED
)
{
xfs_rw_iunlock
(
ip
,
iolock
);
iolock
=
XFS_IOLOCK_EXCL
;
xfs_rw_ilock
(
ip
,
iolock
);
}
xfs_rw_ilock
(
ip
,
iolock
);
ret
=
xfs_file_aio_write_checks
(
iocb
,
from
,
&
iolock
);
if
(
ret
)
goto
out
;
count
=
iov_iter_count
(
from
);
end
=
iocb
->
ki_pos
+
count
-
1
;
/*
* See xfs_file_dio_aio_read() for why we do a full-file flush here.
*/
if
(
mapping
->
nrpages
)
{
ret
=
filemap_write_and_wait
(
VFS_I
(
ip
)
->
i_mapping
);
ret
=
filemap_write_and_wait
_range
(
mapping
,
iocb
->
ki_pos
,
end
);
if
(
ret
)
goto
out
;
/*
* Invalidate whole pages. This can return an error if we fail
* to invalidate a page, but this should never happen on XFS.
* Warn if it does fail.
*/
ret
=
invalidate_inode_pages2
(
VFS_I
(
ip
)
->
i_mapping
);
ret
=
invalidate_inode_pages2_range
(
mapping
,
iocb
->
ki_pos
>>
PAGE_SHIFT
,
end
>>
PAGE_SHIFT
);
WARN_ON_ONCE
(
ret
);
ret
=
0
;
}
/*
* If we are doing unaligned IO, wait for all other IO to drain,
* otherwise demote the lock if we had to flush cached pages
* otherwise demote the lock if we had to take the exclusive lock
* for other reasons in xfs_file_aio_write_checks.
*/
if
(
unaligned_io
)
inode_dio_wait
(
inode
);
...
...
@@ -947,134 +909,6 @@ xfs_file_fallocate(
return
error
;
}
/*
* Flush all file writes out to disk.
*/
static
int
xfs_file_wait_for_io
(
struct
inode
*
inode
,
loff_t
offset
,
size_t
len
)
{
loff_t
rounding
;
loff_t
ioffset
;
loff_t
iendoffset
;
loff_t
bs
;
int
ret
;
bs
=
inode
->
i_sb
->
s_blocksize
;
inode_dio_wait
(
inode
);
rounding
=
max_t
(
xfs_off_t
,
bs
,
PAGE_SIZE
);
ioffset
=
round_down
(
offset
,
rounding
);
iendoffset
=
round_up
(
offset
+
len
,
rounding
)
-
1
;
ret
=
filemap_write_and_wait_range
(
inode
->
i_mapping
,
ioffset
,
iendoffset
);
return
ret
;
}
/* Hook up to the VFS reflink function */
STATIC
int
xfs_file_share_range
(
struct
file
*
file_in
,
loff_t
pos_in
,
struct
file
*
file_out
,
loff_t
pos_out
,
u64
len
,
bool
is_dedupe
)
{
struct
inode
*
inode_in
;
struct
inode
*
inode_out
;
ssize_t
ret
;
loff_t
bs
;
loff_t
isize
;
int
same_inode
;
loff_t
blen
;
unsigned
int
flags
=
0
;
inode_in
=
file_inode
(
file_in
);
inode_out
=
file_inode
(
file_out
);
bs
=
inode_out
->
i_sb
->
s_blocksize
;
/* Don't touch certain kinds of inodes */
if
(
IS_IMMUTABLE
(
inode_out
))
return
-
EPERM
;
if
(
IS_SWAPFILE
(
inode_in
)
||
IS_SWAPFILE
(
inode_out
))
return
-
ETXTBSY
;
/* Reflink only works within this filesystem. */
if
(
inode_in
->
i_sb
!=
inode_out
->
i_sb
)
return
-
EXDEV
;
same_inode
=
(
inode_in
->
i_ino
==
inode_out
->
i_ino
);
/* Don't reflink dirs, pipes, sockets... */
if
(
S_ISDIR
(
inode_in
->
i_mode
)
||
S_ISDIR
(
inode_out
->
i_mode
))
return
-
EISDIR
;
if
(
S_ISFIFO
(
inode_in
->
i_mode
)
||
S_ISFIFO
(
inode_out
->
i_mode
))
return
-
EINVAL
;
if
(
!
S_ISREG
(
inode_in
->
i_mode
)
||
!
S_ISREG
(
inode_out
->
i_mode
))
return
-
EINVAL
;
/* Don't share DAX file data for now. */
if
(
IS_DAX
(
inode_in
)
||
IS_DAX
(
inode_out
))
return
-
EINVAL
;
/* Are we going all the way to the end? */
isize
=
i_size_read
(
inode_in
);
if
(
isize
==
0
)
return
0
;
if
(
len
==
0
)
len
=
isize
-
pos_in
;
/* Ensure offsets don't wrap and the input is inside i_size */
if
(
pos_in
+
len
<
pos_in
||
pos_out
+
len
<
pos_out
||
pos_in
+
len
>
isize
)
return
-
EINVAL
;
/* Don't allow dedupe past EOF in the dest file */
if
(
is_dedupe
)
{
loff_t
disize
;
disize
=
i_size_read
(
inode_out
);
if
(
pos_out
>=
disize
||
pos_out
+
len
>
disize
)
return
-
EINVAL
;
}
/* If we're linking to EOF, continue to the block boundary. */
if
(
pos_in
+
len
==
isize
)
blen
=
ALIGN
(
isize
,
bs
)
-
pos_in
;
else
blen
=
len
;
/* Only reflink if we're aligned to block boundaries */
if
(
!
IS_ALIGNED
(
pos_in
,
bs
)
||
!
IS_ALIGNED
(
pos_in
+
blen
,
bs
)
||
!
IS_ALIGNED
(
pos_out
,
bs
)
||
!
IS_ALIGNED
(
pos_out
+
blen
,
bs
))
return
-
EINVAL
;
/* Don't allow overlapped reflink within the same file */
if
(
same_inode
&&
pos_out
+
blen
>
pos_in
&&
pos_out
<
pos_in
+
blen
)
return
-
EINVAL
;
/* Wait for the completion of any pending IOs on srcfile */
ret
=
xfs_file_wait_for_io
(
inode_in
,
pos_in
,
len
);
if
(
ret
)
goto
out
;
ret
=
xfs_file_wait_for_io
(
inode_out
,
pos_out
,
len
);
if
(
ret
)
goto
out
;
if
(
is_dedupe
)
flags
|=
XFS_REFLINK_DEDUPE
;
ret
=
xfs_reflink_remap_range
(
XFS_I
(
inode_in
),
pos_in
,
XFS_I
(
inode_out
),
pos_out
,
len
,
flags
);
if
(
ret
<
0
)
goto
out
;
out:
return
ret
;
}
STATIC
ssize_t
xfs_file_copy_range
(
struct
file
*
file_in
,
...
...
@@ -1086,7 +920,7 @@ xfs_file_copy_range(
{
int
error
;
error
=
xfs_
file_share
_range
(
file_in
,
pos_in
,
file_out
,
pos_out
,
error
=
xfs_
reflink_remap
_range
(
file_in
,
pos_in
,
file_out
,
pos_out
,
len
,
false
);
if
(
error
)
return
error
;
...
...
@@ -1101,7 +935,7 @@ xfs_file_clone_range(
loff_t
pos_out
,
u64
len
)
{
return
xfs_
file_share
_range
(
file_in
,
pos_in
,
file_out
,
pos_out
,
return
xfs_
reflink_remap
_range
(
file_in
,
pos_in
,
file_out
,
pos_out
,
len
,
false
);
}
...
...
@@ -1124,7 +958,7 @@ xfs_file_dedupe_range(
if
(
len
>
XFS_MAX_DEDUPE_LEN
)
len
=
XFS_MAX_DEDUPE_LEN
;
error
=
xfs_
file_share
_range
(
src_file
,
loff
,
dst_file
,
dst_loff
,
error
=
xfs_
reflink_remap
_range
(
src_file
,
loff
,
dst_file
,
dst_loff
,
len
,
true
);
if
(
error
)
return
error
;
...
...
fs/xfs/xfs_icache.c
浏览文件 @
e3df41f9
...
...
@@ -123,7 +123,6 @@ __xfs_inode_free(
{
/* asserts to verify all state is correct here */
ASSERT
(
atomic_read
(
&
ip
->
i_pincount
)
==
0
);
ASSERT
(
!
xfs_isiflocked
(
ip
));
XFS_STATS_DEC
(
ip
->
i_mount
,
vn_active
);
call_rcu
(
&
VFS_I
(
ip
)
->
i_rcu
,
xfs_inode_free_callback
);
...
...
@@ -133,6 +132,8 @@ void
xfs_inode_free
(
struct
xfs_inode
*
ip
)
{
ASSERT
(
!
xfs_isiflocked
(
ip
));
/*
* Because we use RCU freeing we need to ensure the inode always
* appears to be reclaimed with an invalid inode number when in the
...
...
@@ -981,6 +982,7 @@ xfs_reclaim_inode(
if
(
XFS_FORCED_SHUTDOWN
(
ip
->
i_mount
))
{
xfs_iunpin_wait
(
ip
);
/* xfs_iflush_abort() drops the flush lock */
xfs_iflush_abort
(
ip
,
false
);
goto
reclaim
;
}
...
...
@@ -989,10 +991,10 @@ xfs_reclaim_inode(
goto
out_ifunlock
;
xfs_iunpin_wait
(
ip
);
}
if
(
xfs_iflags_test
(
ip
,
XFS_ISTALE
))
goto
reclaim
;
if
(
xfs_inode_clean
(
ip
))
if
(
xfs_iflags_test
(
ip
,
XFS_ISTALE
)
||
xfs_inode_clean
(
ip
))
{
xfs_ifunlock
(
ip
);
goto
reclaim
;
}
/*
* Never flush out dirty data during non-blocking reclaim, as it would
...
...
@@ -1030,25 +1032,24 @@ xfs_reclaim_inode(
xfs_buf_relse
(
bp
);
}
xfs_iflock
(
ip
);
reclaim:
ASSERT
(
!
xfs_isiflocked
(
ip
));
/*
* Because we use RCU freeing we need to ensure the inode always appears
* to be reclaimed with an invalid inode number when in the free state.
* We do this as early as possible under the ILOCK and flush lock so
* that xfs_iflush_cluster() can be guaranteed to detect races with us
* here. By doing this, we guarantee that once xfs_iflush_cluster has
* locked both the XFS_ILOCK and the flush lock that it will see either
* a valid, flushable inode that will serialise correctly against the
* locks below, or it will see a clean (and invalid) inode that it can
* skip.
* We do this as early as possible under the ILOCK so that
* xfs_iflush_cluster() can be guaranteed to detect races with us here.
* By doing this, we guarantee that once xfs_iflush_cluster has locked
* XFS_ILOCK that it will see either a valid, flushable inode that will
* serialise correctly, or it will see a clean (and invalid) inode that
* it can skip.
*/
spin_lock
(
&
ip
->
i_flags_lock
);
ip
->
i_flags
=
XFS_IRECLAIM
;
ip
->
i_ino
=
0
;
spin_unlock
(
&
ip
->
i_flags_lock
);
xfs_ifunlock
(
ip
);
xfs_iunlock
(
ip
,
XFS_ILOCK_EXCL
);
XFS_STATS_INC
(
ip
->
i_mount
,
xs_ig_reclaims
);
...
...
@@ -1580,10 +1581,15 @@ xfs_inode_free_cowblocks(
struct
xfs_eofblocks
*
eofb
=
args
;
bool
need_iolock
=
true
;
int
match
;
struct
xfs_ifork
*
ifp
=
XFS_IFORK_PTR
(
ip
,
XFS_COW_FORK
);
ASSERT
(
!
eofb
||
(
eofb
&&
eofb
->
eof_scan_owner
!=
0
));
if
(
!
xfs_reflink_has_real_cow_blocks
(
ip
))
{
/*
* Just clear the tag if we have an empty cow fork or none at all. It's
* possible the inode was fully unshared since it was originally tagged.
*/
if
(
!
xfs_is_reflink_inode
(
ip
)
||
!
ifp
->
if_bytes
)
{
trace_xfs_inode_free_cowblocks_invalid
(
ip
);
xfs_inode_clear_cowblocks_tag
(
ip
);
return
0
;
...
...
@@ -1656,9 +1662,9 @@ void
xfs_inode_set_cowblocks_tag
(
xfs_inode_t
*
ip
)
{
trace_xfs_inode_set_
eof
blocks_tag
(
ip
);
trace_xfs_inode_set_
cow
blocks_tag
(
ip
);
return
__xfs_inode_set_eofblocks_tag
(
ip
,
xfs_queue_cowblocks
,
trace_xfs_perag_set_
eof
blocks
,
trace_xfs_perag_set_
cow
blocks
,
XFS_ICI_COWBLOCKS_TAG
);
}
...
...
@@ -1666,7 +1672,7 @@ void
xfs_inode_clear_cowblocks_tag
(
xfs_inode_t
*
ip
)
{
trace_xfs_inode_clear_
eof
blocks_tag
(
ip
);
trace_xfs_inode_clear_
cow
blocks_tag
(
ip
);
return
__xfs_inode_clear_eofblocks_tag
(
ip
,
trace_xfs_perag_clear_
eof
blocks
,
XFS_ICI_COWBLOCKS_TAG
);
trace_xfs_perag_clear_
cow
blocks
,
XFS_ICI_COWBLOCKS_TAG
);
}
fs/xfs/xfs_icreate_item.c
浏览文件 @
e3df41f9
...
...
@@ -133,7 +133,7 @@ xfs_icreate_item_committing(
/*
* This is the ops vector shared by all buf log items.
*/
static
struct
xfs_item_ops
xfs_icreate_item_ops
=
{
static
const
struct
xfs_item_ops
xfs_icreate_item_ops
=
{
.
iop_size
=
xfs_icreate_item_size
,
.
iop_format
=
xfs_icreate_item_format
,
.
iop_pin
=
xfs_icreate_item_pin
,
...
...
fs/xfs/xfs_inode.h
浏览文件 @
e3df41f9
...
...
@@ -246,6 +246,11 @@ static inline bool xfs_is_reflink_inode(struct xfs_inode *ip)
* Synchronize processes attempting to flush the in-core inode back to disk.
*/
static
inline
int
xfs_isiflocked
(
struct
xfs_inode
*
ip
)
{
return
xfs_iflags_test
(
ip
,
XFS_IFLOCK
);
}
extern
void
__xfs_iflock
(
struct
xfs_inode
*
ip
);
static
inline
int
xfs_iflock_nowait
(
struct
xfs_inode
*
ip
)
...
...
@@ -261,16 +266,12 @@ static inline void xfs_iflock(struct xfs_inode *ip)
static
inline
void
xfs_ifunlock
(
struct
xfs_inode
*
ip
)
{
ASSERT
(
xfs_isiflocked
(
ip
));
xfs_iflags_clear
(
ip
,
XFS_IFLOCK
);
smp_mb
();
wake_up_bit
(
&
ip
->
i_flags
,
__XFS_IFLOCK_BIT
);
}
static
inline
int
xfs_isiflocked
(
struct
xfs_inode
*
ip
)
{
return
xfs_iflags_test
(
ip
,
XFS_IFLOCK
);
}
/*
* Flags for inode locking.
* Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield)
...
...
fs/xfs/xfs_inode_item.c
浏览文件 @
e3df41f9
...
...
@@ -164,7 +164,7 @@ xfs_inode_item_format_data_fork(
struct
xfs_bmbt_rec
*
p
;
ASSERT
(
ip
->
i_df
.
if_u1
.
if_extents
!=
NULL
);
ASSERT
(
ip
->
i_df
.
if_bytes
/
sizeof
(
xfs_bmbt_rec_t
)
>
0
);
ASSERT
(
xfs_iext_count
(
&
ip
->
i_df
)
>
0
);
p
=
xlog_prepare_iovec
(
lv
,
vecp
,
XLOG_REG_TYPE_IEXT
);
data_bytes
=
xfs_iextents_copy
(
ip
,
p
,
XFS_DATA_FORK
);
...
...
@@ -261,7 +261,7 @@ xfs_inode_item_format_attr_fork(
ip
->
i_afp
->
if_bytes
>
0
)
{
struct
xfs_bmbt_rec
*
p
;
ASSERT
(
ip
->
i_afp
->
if_bytes
/
sizeof
(
xfs_bmbt_rec_t
)
==
ASSERT
(
xfs_iext_count
(
ip
->
i_afp
)
==
ip
->
i_d
.
di_anextents
);
ASSERT
(
ip
->
i_afp
->
if_u1
.
if_extents
!=
NULL
);
...
...
fs/xfs/xfs_ioctl.c
浏览文件 @
e3df41f9
...
...
@@ -910,16 +910,14 @@ xfs_ioc_fsgetxattr(
if
(
attr
)
{
if
(
ip
->
i_afp
)
{
if
(
ip
->
i_afp
->
if_flags
&
XFS_IFEXTENTS
)
fa
.
fsx_nextents
=
ip
->
i_afp
->
if_bytes
/
sizeof
(
xfs_bmbt_rec_t
);
fa
.
fsx_nextents
=
xfs_iext_count
(
ip
->
i_afp
);
else
fa
.
fsx_nextents
=
ip
->
i_d
.
di_anextents
;
}
else
fa
.
fsx_nextents
=
0
;
}
else
{
if
(
ip
->
i_df
.
if_flags
&
XFS_IFEXTENTS
)
fa
.
fsx_nextents
=
ip
->
i_df
.
if_bytes
/
sizeof
(
xfs_bmbt_rec_t
);
fa
.
fsx_nextents
=
xfs_iext_count
(
&
ip
->
i_df
);
else
fa
.
fsx_nextents
=
ip
->
i_d
.
di_nextents
;
}
...
...
fs/xfs/xfs_iomap.c
浏览文件 @
e3df41f9
...
...
@@ -395,11 +395,12 @@ xfs_iomap_prealloc_size(
struct
xfs_inode
*
ip
,
loff_t
offset
,
loff_t
count
,
xfs_extnum_t
idx
,
struct
xfs_bmbt_irec
*
prev
)
xfs_extnum_t
idx
)
{
struct
xfs_mount
*
mp
=
ip
->
i_mount
;
struct
xfs_ifork
*
ifp
=
XFS_IFORK_PTR
(
ip
,
XFS_DATA_FORK
);
xfs_fileoff_t
offset_fsb
=
XFS_B_TO_FSBT
(
mp
,
offset
);
struct
xfs_bmbt_irec
prev
;
int
shift
=
0
;
int64_t
freesp
;
xfs_fsblock_t
qblocks
;
...
...
@@ -419,8 +420,8 @@ xfs_iomap_prealloc_size(
*/
if
((
mp
->
m_flags
&
XFS_MOUNT_DFLT_IOSIZE
)
||
XFS_ISIZE
(
ip
)
<
XFS_FSB_TO_B
(
mp
,
mp
->
m_dalign
)
||
idx
==
0
||
prev
->
br_startoff
+
prev
->
br_blockcount
<
offset_fsb
)
!
xfs_iext_get_extent
(
ifp
,
idx
-
1
,
&
prev
)
||
prev
.
br_startoff
+
prev
.
br_blockcount
<
offset_fsb
)
return
mp
->
m_writeio_blocks
;
/*
...
...
@@ -439,8 +440,8 @@ xfs_iomap_prealloc_size(
* always extends to MAXEXTLEN rather than falling short due to things
* like stripe unit/width alignment of real extents.
*/
if
(
prev
->
br_blockcount
<=
(
MAXEXTLEN
>>
1
))
alloc_blocks
=
prev
->
br_blockcount
<<
1
;
if
(
prev
.
br_blockcount
<=
(
MAXEXTLEN
>>
1
))
alloc_blocks
=
prev
.
br_blockcount
<<
1
;
else
alloc_blocks
=
XFS_B_TO_FSB
(
mp
,
offset
);
if
(
!
alloc_blocks
)
...
...
@@ -535,11 +536,11 @@ xfs_file_iomap_begin_delay(
xfs_fileoff_t
offset_fsb
=
XFS_B_TO_FSBT
(
mp
,
offset
);
xfs_fileoff_t
maxbytes_fsb
=
XFS_B_TO_FSB
(
mp
,
mp
->
m_super
->
s_maxbytes
);
xfs_fileoff_t
end_fsb
,
orig_end_fsb
;
xfs_fileoff_t
end_fsb
;
int
error
=
0
,
eof
=
0
;
struct
xfs_bmbt_irec
got
;
struct
xfs_bmbt_irec
prev
;
xfs_extnum_t
idx
;
xfs_fsblock_t
prealloc_blocks
=
0
;
ASSERT
(
!
XFS_IS_REALTIME_INODE
(
ip
));
ASSERT
(
!
xfs_get_extsz_hint
(
ip
));
...
...
@@ -563,9 +564,19 @@ xfs_file_iomap_begin_delay(
goto
out_unlock
;
}
xfs_bmap_search_extents
(
ip
,
offset_fsb
,
XFS_DATA_FORK
,
&
eof
,
&
idx
,
&
got
,
&
prev
);
eof
=
!
xfs_iext_lookup_extent
(
ip
,
ifp
,
offset_fsb
,
&
idx
,
&
got
);
if
(
!
eof
&&
got
.
br_startoff
<=
offset_fsb
)
{
if
(
xfs_is_reflink_inode
(
ip
))
{
bool
shared
;
end_fsb
=
min
(
XFS_B_TO_FSB
(
mp
,
offset
+
count
),
maxbytes_fsb
);
xfs_trim_extent
(
&
got
,
offset_fsb
,
end_fsb
-
offset_fsb
);
error
=
xfs_reflink_reserve_cow
(
ip
,
&
got
,
&
shared
);
if
(
error
)
goto
out_unlock
;
}
trace_xfs_iomap_found
(
ip
,
offset
,
count
,
0
,
&
got
);
goto
done
;
}
...
...
@@ -584,35 +595,32 @@ xfs_file_iomap_begin_delay(
* the lower level functions are updated.
*/
count
=
min_t
(
loff_t
,
count
,
1024
*
PAGE_SIZE
);
end_fsb
=
orig_end_fsb
=
min
(
XFS_B_TO_FSB
(
mp
,
offset
+
count
),
maxbytes_fsb
);
end_fsb
=
min
(
XFS_B_TO_FSB
(
mp
,
offset
+
count
),
maxbytes_fsb
);
if
(
eof
)
{
xfs_fsblock_t
prealloc_blocks
;
prealloc_blocks
=
xfs_iomap_prealloc_size
(
ip
,
offset
,
count
,
idx
,
&
prev
);
prealloc_blocks
=
xfs_iomap_prealloc_size
(
ip
,
offset
,
count
,
idx
);
if
(
prealloc_blocks
)
{
xfs_extlen_t
align
;
xfs_off_t
end_offset
;
xfs_fileoff_t
p_end_fsb
;
end_offset
=
XFS_WRITEIO_ALIGN
(
mp
,
offset
+
count
-
1
);
end_fsb
=
XFS_B_TO_FSBT
(
mp
,
end_offset
)
+
prealloc_blocks
;
p_
end_fsb
=
XFS_B_TO_FSBT
(
mp
,
end_offset
)
+
prealloc_blocks
;
align
=
xfs_eof_alignment
(
ip
,
0
);
if
(
align
)
end_fsb
=
roundup_64
(
end_fsb
,
align
);
p_end_fsb
=
roundup_64
(
p_
end_fsb
,
align
);
end_fsb
=
min
(
end_fsb
,
maxbytes_fsb
);
ASSERT
(
end_fsb
>
offset_fsb
);
p_end_fsb
=
min
(
p_end_fsb
,
maxbytes_fsb
);
ASSERT
(
p_end_fsb
>
offset_fsb
);
prealloc_blocks
=
p_end_fsb
-
end_fsb
;
}
}
retry:
error
=
xfs_bmapi_reserve_delalloc
(
ip
,
XFS_DATA_FORK
,
offset_fsb
,
end_fsb
-
offset_fsb
,
&
got
,
&
prev
,
&
idx
,
eof
);
end_fsb
-
offset_fsb
,
prealloc_blocks
,
&
got
,
&
idx
,
eof
);
switch
(
error
)
{
case
0
:
break
;
...
...
@@ -620,8 +628,8 @@ xfs_file_iomap_begin_delay(
case
-
EDQUOT
:
/* retry without any preallocation */
trace_xfs_delalloc_enospc
(
ip
,
offset
,
count
);
if
(
end_fsb
!=
orig_end_fsb
)
{
end_fsb
=
orig_end_fsb
;
if
(
prealloc_blocks
)
{
prealloc_blocks
=
0
;
goto
retry
;
}
/*FALLTHRU*/
...
...
@@ -629,13 +637,6 @@ xfs_file_iomap_begin_delay(
goto
out_unlock
;
}
/*
* Tag the inode as speculatively preallocated so we can reclaim this
* space on demand, if necessary.
*/
if
(
end_fsb
!=
orig_end_fsb
)
xfs_inode_set_eofblocks_tag
(
ip
);
trace_xfs_iomap_alloc
(
ip
,
offset
,
count
,
0
,
&
got
);
done:
if
(
isnullstartblock
(
got
.
br_startblock
))
...
...
@@ -961,19 +962,13 @@ xfs_file_iomap_begin(
struct
xfs_mount
*
mp
=
ip
->
i_mount
;
struct
xfs_bmbt_irec
imap
;
xfs_fileoff_t
offset_fsb
,
end_fsb
;
bool
shared
,
trimmed
;
int
nimaps
=
1
,
error
=
0
;
bool
shared
=
false
,
trimmed
=
false
;
unsigned
lockmode
;
if
(
XFS_FORCED_SHUTDOWN
(
mp
))
return
-
EIO
;
if
((
flags
&
(
IOMAP_WRITE
|
IOMAP_ZERO
))
&&
xfs_is_reflink_inode
(
ip
))
{
error
=
xfs_reflink_reserve_cow_range
(
ip
,
offset
,
length
);
if
(
error
<
0
)
return
error
;
}
if
((
flags
&
IOMAP_WRITE
)
&&
!
IS_DAX
(
inode
)
&&
!
xfs_get_extsz_hint
(
ip
))
{
/* Reserve delalloc blocks for regular writeback. */
...
...
@@ -981,7 +976,16 @@ xfs_file_iomap_begin(
iomap
);
}
lockmode
=
xfs_ilock_data_map_shared
(
ip
);
/*
* COW writes will allocate delalloc space, so we need to make sure
* to take the lock exclusively here.
*/
if
((
flags
&
(
IOMAP_WRITE
|
IOMAP_ZERO
))
&&
xfs_is_reflink_inode
(
ip
))
{
lockmode
=
XFS_ILOCK_EXCL
;
xfs_ilock
(
ip
,
XFS_ILOCK_EXCL
);
}
else
{
lockmode
=
xfs_ilock_data_map_shared
(
ip
);
}
ASSERT
(
offset
<=
mp
->
m_super
->
s_maxbytes
);
if
((
xfs_fsize_t
)
offset
+
length
>
mp
->
m_super
->
s_maxbytes
)
...
...
@@ -991,16 +995,24 @@ xfs_file_iomap_begin(
error
=
xfs_bmapi_read
(
ip
,
offset_fsb
,
end_fsb
-
offset_fsb
,
&
imap
,
&
nimaps
,
0
);
if
(
error
)
{
xfs_iunlock
(
ip
,
lockmode
);
return
error
;
if
(
error
)
goto
out_unlock
;
if
(
flags
&
IOMAP_REPORT
)
{
/* Trim the mapping to the nearest shared extent boundary. */
error
=
xfs_reflink_trim_around_shared
(
ip
,
&
imap
,
&
shared
,
&
trimmed
);
if
(
error
)
goto
out_unlock
;
}
/* Trim the mapping to the nearest shared extent boundary. */
error
=
xfs_reflink_trim_around_shared
(
ip
,
&
imap
,
&
shared
,
&
trimmed
);
if
(
error
)
{
xfs_iunlock
(
ip
,
lockmode
);
return
error
;
if
((
flags
&
(
IOMAP_WRITE
|
IOMAP_ZERO
))
&&
xfs_is_reflink_inode
(
ip
))
{
error
=
xfs_reflink_reserve_cow
(
ip
,
&
imap
,
&
shared
);
if
(
error
)
goto
out_unlock
;
end_fsb
=
imap
.
br_startoff
+
imap
.
br_blockcount
;
length
=
XFS_FSB_TO_B
(
mp
,
end_fsb
)
-
offset
;
}
if
((
flags
&
IOMAP_WRITE
)
&&
imap_needs_alloc
(
inode
,
&
imap
,
nimaps
))
{
...
...
@@ -1039,6 +1051,9 @@ xfs_file_iomap_begin(
if
(
shared
)
iomap
->
flags
|=
IOMAP_F_SHARED
;
return
0
;
out_unlock:
xfs_iunlock
(
ip
,
lockmode
);
return
error
;
}
static
int
...
...
fs/xfs/xfs_mount.c
浏览文件 @
e3df41f9
...
...
@@ -1009,6 +1009,7 @@ xfs_mountfs(
out_quota:
xfs_qm_unmount_quotas
(
mp
);
out_rtunmount:
mp
->
m_super
->
s_flags
&=
~
MS_ACTIVE
;
xfs_rtunmount_inodes
(
mp
);
out_rele_rip:
IRELE
(
rip
);
...
...
fs/xfs/xfs_qm.c
浏览文件 @
e3df41f9
...
...
@@ -1135,7 +1135,7 @@ xfs_qm_get_rtblks(
return
error
;
}
rtblks
=
0
;
nextents
=
ifp
->
if_bytes
/
(
uint
)
sizeof
(
xfs_bmbt_rec_t
);
nextents
=
xfs_iext_count
(
ifp
);
for
(
idx
=
0
;
idx
<
nextents
;
idx
++
)
rtblks
+=
xfs_bmbt_get_blockcount
(
xfs_iext_get_ext
(
ifp
,
idx
));
*
O_rtblks
=
(
xfs_qcnt_t
)
rtblks
;
...
...
fs/xfs/xfs_reflink.c
浏览文件 @
e3df41f9
此差异已折叠。
点击以展开。
fs/xfs/xfs_reflink.h
浏览文件 @
e3df41f9
...
...
@@ -26,13 +26,13 @@ extern int xfs_reflink_find_shared(struct xfs_mount *mp, xfs_agnumber_t agno,
extern
int
xfs_reflink_trim_around_shared
(
struct
xfs_inode
*
ip
,
struct
xfs_bmbt_irec
*
irec
,
bool
*
shared
,
bool
*
trimmed
);
extern
int
xfs_reflink_reserve_cow
_range
(
struct
xfs_inode
*
ip
,
xfs_off_t
offset
,
xfs_off_t
count
);
extern
int
xfs_reflink_reserve_cow
(
struct
xfs_inode
*
ip
,
struct
xfs_bmbt_irec
*
imap
,
bool
*
shared
);
extern
int
xfs_reflink_allocate_cow_range
(
struct
xfs_inode
*
ip
,
xfs_off_t
offset
,
xfs_off_t
count
);
extern
bool
xfs_reflink_find_cow_mapping
(
struct
xfs_inode
*
ip
,
xfs_off_t
offset
,
struct
xfs_bmbt_irec
*
imap
,
bool
*
need_alloc
);
extern
int
xfs_reflink_trim_irec_to_next_cow
(
struct
xfs_inode
*
ip
,
struct
xfs_bmbt_irec
*
imap
);
extern
void
xfs_reflink_trim_irec_to_next_cow
(
struct
xfs_inode
*
ip
,
xfs_fileoff_t
offset_fsb
,
struct
xfs_bmbt_irec
*
imap
);
extern
int
xfs_reflink_cancel_cow_blocks
(
struct
xfs_inode
*
ip
,
...
...
@@ -43,16 +43,11 @@ extern int xfs_reflink_cancel_cow_range(struct xfs_inode *ip, xfs_off_t offset,
extern
int
xfs_reflink_end_cow
(
struct
xfs_inode
*
ip
,
xfs_off_t
offset
,
xfs_off_t
count
);
extern
int
xfs_reflink_recover_cow
(
struct
xfs_mount
*
mp
);
#define XFS_REFLINK_DEDUPE 1
/* only reflink if contents match */
#define XFS_REFLINK_ALL (XFS_REFLINK_DEDUPE)
extern
int
xfs_reflink_remap_range
(
struct
xfs_inode
*
src
,
xfs_off_t
srcoff
,
struct
xfs_inode
*
dest
,
xfs_off_t
destoff
,
xfs_off_t
len
,
unsigned
int
flags
);
extern
int
xfs_reflink_remap_range
(
struct
file
*
file_in
,
loff_t
pos_in
,
struct
file
*
file_out
,
loff_t
pos_out
,
u64
len
,
bool
is_dedupe
);
extern
int
xfs_reflink_clear_inode_flag
(
struct
xfs_inode
*
ip
,
struct
xfs_trans
**
tpp
);
extern
int
xfs_reflink_unshare
(
struct
xfs_inode
*
ip
,
xfs_off_t
offset
,
xfs_off_t
len
);
extern
bool
xfs_reflink_has_real_cow_blocks
(
struct
xfs_inode
*
ip
);
#endif
/* __XFS_REFLINK_H */
fs/xfs/xfs_sysfs.c
浏览文件 @
e3df41f9
...
...
@@ -512,13 +512,13 @@ static struct attribute *xfs_error_attrs[] = {
};
struct
kobj_type
xfs_error_cfg_ktype
=
{
st
atic
st
ruct
kobj_type
xfs_error_cfg_ktype
=
{
.
release
=
xfs_sysfs_release
,
.
sysfs_ops
=
&
xfs_sysfs_ops
,
.
default_attrs
=
xfs_error_attrs
,
};
struct
kobj_type
xfs_error_ktype
=
{
st
atic
st
ruct
kobj_type
xfs_error_ktype
=
{
.
release
=
xfs_sysfs_release
,
.
sysfs_ops
=
&
xfs_sysfs_ops
,
};
...
...
fs/xfs/xfs_trace.h
浏览文件 @
e3df41f9
...
...
@@ -3346,7 +3346,7 @@ DEFINE_INODE_IREC_EVENT(xfs_reflink_cow_alloc);
DEFINE_INODE_IREC_EVENT
(
xfs_reflink_cow_found
);
DEFINE_INODE_IREC_EVENT
(
xfs_reflink_cow_enospc
);
DEFINE_RW_EVENT
(
xfs_reflink_reserve_cow
_range
);
DEFINE_RW_EVENT
(
xfs_reflink_reserve_cow
);
DEFINE_RW_EVENT
(
xfs_reflink_allocate_cow_range
);
DEFINE_INODE_IREC_EVENT
(
xfs_reflink_bounce_dio_write
);
...
...
@@ -3356,9 +3356,7 @@ DEFINE_INODE_IREC_EVENT(xfs_reflink_trim_irec);
DEFINE_SIMPLE_IO_EVENT
(
xfs_reflink_cancel_cow_range
);
DEFINE_SIMPLE_IO_EVENT
(
xfs_reflink_end_cow
);
DEFINE_INODE_IREC_EVENT
(
xfs_reflink_cow_remap
);
DEFINE_INODE_IREC_EVENT
(
xfs_reflink_cow_remap_piece
);
DEFINE_INODE_ERROR_EVENT
(
xfs_reflink_reserve_cow_range_error
);
DEFINE_INODE_ERROR_EVENT
(
xfs_reflink_allocate_cow_range_error
);
DEFINE_INODE_ERROR_EVENT
(
xfs_reflink_cancel_cow_range_error
);
DEFINE_INODE_ERROR_EVENT
(
xfs_reflink_end_cow_error
);
...
...
include/linux/iomap.h
浏览文件 @
e3df41f9
...
...
@@ -19,11 +19,15 @@ struct vm_fault;
#define IOMAP_UNWRITTEN 0x04
/* blocks allocated @blkno in unwritten state */
/*
* Flags for iomap mappings:
* Flags for
all
iomap mappings:
*/
#define IOMAP_F_MERGED 0x01
/* contains multiple blocks/extents */
#define IOMAP_F_SHARED 0x02
/* block shared with another file */
#define IOMAP_F_NEW 0x04
/* blocks have been newly allocated */
#define IOMAP_F_NEW 0x01
/* blocks have been newly allocated */
/*
* Flags that only need to be reported for IOMAP_REPORT requests:
*/
#define IOMAP_F_MERGED 0x10
/* contains multiple blocks/extents */
#define IOMAP_F_SHARED 0x20
/* block shared with another file */
/*
* Magic value for blkno:
...
...
@@ -42,8 +46,9 @@ struct iomap {
/*
* Flags for iomap_begin / iomap_end. No flag implies a read.
*/
#define IOMAP_WRITE (1 << 0)
#define IOMAP_ZERO (1 << 1)
#define IOMAP_WRITE (1 << 0)
/* writing, must allocate blocks */
#define IOMAP_ZERO (1 << 1)
/* zeroing operation, may skip holes */
#define IOMAP_REPORT (1 << 2)
/* report extent status, e.g. FIEMAP */
#define IOMAP_FAULT (1 << 3)
/* mapping for page fault */
struct
iomap_ops
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录