Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
a4241aeb
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看板
提交
a4241aeb
编写于
9月 09, 2014
作者:
D
Dave Chinner
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'xfs-misc-fixes-for-3.18-1' into for-next
上级
41b9d726
ab6978c2
变更
19
隐藏空白更改
内联
并排
Showing
19 changed file
with
290 addition
and
325 deletion
+290
-325
fs/xfs/libxfs/xfs_alloc.c
fs/xfs/libxfs/xfs_alloc.c
+4
-0
fs/xfs/libxfs/xfs_dir2.c
fs/xfs/libxfs/xfs_dir2.c
+12
-55
fs/xfs/libxfs/xfs_dir2.h
fs/xfs/libxfs/xfs_dir2.h
+1
-1
fs/xfs/libxfs/xfs_ialloc.c
fs/xfs/libxfs/xfs_ialloc.c
+2
-0
fs/xfs/libxfs/xfs_rtbitmap.c
fs/xfs/libxfs/xfs_rtbitmap.c
+35
-14
fs/xfs/libxfs/xfs_sb.c
fs/xfs/libxfs/xfs_sb.c
+2
-0
fs/xfs/xfs_buf.c
fs/xfs/xfs_buf.c
+1
-1
fs/xfs/xfs_file.c
fs/xfs/xfs_file.c
+53
-125
fs/xfs/xfs_globals.c
fs/xfs/xfs_globals.c
+4
-0
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.c
+15
-9
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_log_recover.c
+39
-54
fs/xfs/xfs_mru_cache.c
fs/xfs/xfs_mru_cache.c
+2
-1
fs/xfs/xfs_rtalloc.c
fs/xfs/xfs_rtalloc.c
+2
-53
fs/xfs/xfs_rtalloc.h
fs/xfs/xfs_rtalloc.h
+4
-0
fs/xfs/xfs_super.c
fs/xfs/xfs_super.c
+29
-9
fs/xfs/xfs_symlink.c
fs/xfs/xfs_symlink.c
+5
-3
fs/xfs/xfs_sysctl.h
fs/xfs/xfs_sysctl.h
+5
-0
fs/xfs/xfs_sysfs.c
fs/xfs/xfs_sysfs.c
+74
-0
fs/xfs/xfs_sysfs.h
fs/xfs/xfs_sysfs.h
+1
-0
未找到文件。
fs/xfs/libxfs/xfs_alloc.c
浏览文件 @
a4241aeb
...
...
@@ -2209,6 +2209,10 @@ xfs_agf_verify(
be32_to_cpu
(
agf
->
agf_flcount
)
<=
XFS_AGFL_SIZE
(
mp
)))
return
false
;
if
(
be32_to_cpu
(
agf
->
agf_levels
[
XFS_BTNUM_BNO
])
>
XFS_BTREE_MAXLEVELS
||
be32_to_cpu
(
agf
->
agf_levels
[
XFS_BTNUM_CNT
])
>
XFS_BTREE_MAXLEVELS
)
return
false
;
/*
* during growfs operations, the perag is not fully initialised,
* so we can't use it for any useful checking. growfs ensures we can't
...
...
fs/xfs/libxfs/xfs_dir2.c
浏览文件 @
a4241aeb
...
...
@@ -237,7 +237,8 @@ xfs_dir_init(
}
/*
Enter a name in a directory.
* Enter a name in a directory, or check for available space.
* If inum is 0, only the available space test is performed.
*/
int
xfs_dir_createname
(
...
...
@@ -254,10 +255,12 @@ xfs_dir_createname(
int
v
;
/* type-checking value */
ASSERT
(
S_ISDIR
(
dp
->
i_d
.
di_mode
));
rval
=
xfs_dir_ino_validate
(
tp
->
t_mountp
,
inum
);
if
(
rval
)
return
rval
;
XFS_STATS_INC
(
xs_dir_create
);
if
(
inum
)
{
rval
=
xfs_dir_ino_validate
(
tp
->
t_mountp
,
inum
);
if
(
rval
)
return
rval
;
XFS_STATS_INC
(
xs_dir_create
);
}
args
=
kmem_zalloc
(
sizeof
(
*
args
),
KM_SLEEP
|
KM_NOFS
);
if
(
!
args
)
...
...
@@ -276,6 +279,8 @@ xfs_dir_createname(
args
->
whichfork
=
XFS_DATA_FORK
;
args
->
trans
=
tp
;
args
->
op_flags
=
XFS_DA_OP_ADDNAME
|
XFS_DA_OP_OKNOENT
;
if
(
!
inum
)
args
->
op_flags
|=
XFS_DA_OP_JUSTCHECK
;
if
(
dp
->
i_d
.
di_format
==
XFS_DINODE_FMT_LOCAL
)
{
rval
=
xfs_dir2_sf_addname
(
args
);
...
...
@@ -535,62 +540,14 @@ xfs_dir_replace(
/*
* See if this entry can be added to the directory without allocating space.
* First checks that the caller couldn't reserve enough space (resblks = 0).
*/
int
xfs_dir_canenter
(
xfs_trans_t
*
tp
,
xfs_inode_t
*
dp
,
struct
xfs_name
*
name
,
/* name of entry to add */
uint
resblks
)
struct
xfs_name
*
name
)
/* name of entry to add */
{
struct
xfs_da_args
*
args
;
int
rval
;
int
v
;
/* type-checking value */
if
(
resblks
)
return
0
;
ASSERT
(
S_ISDIR
(
dp
->
i_d
.
di_mode
));
args
=
kmem_zalloc
(
sizeof
(
*
args
),
KM_SLEEP
|
KM_NOFS
);
if
(
!
args
)
return
-
ENOMEM
;
args
->
geo
=
dp
->
i_mount
->
m_dir_geo
;
args
->
name
=
name
->
name
;
args
->
namelen
=
name
->
len
;
args
->
filetype
=
name
->
type
;
args
->
hashval
=
dp
->
i_mount
->
m_dirnameops
->
hashname
(
name
);
args
->
dp
=
dp
;
args
->
whichfork
=
XFS_DATA_FORK
;
args
->
trans
=
tp
;
args
->
op_flags
=
XFS_DA_OP_JUSTCHECK
|
XFS_DA_OP_ADDNAME
|
XFS_DA_OP_OKNOENT
;
if
(
dp
->
i_d
.
di_format
==
XFS_DINODE_FMT_LOCAL
)
{
rval
=
xfs_dir2_sf_addname
(
args
);
goto
out_free
;
}
rval
=
xfs_dir2_isblock
(
args
,
&
v
);
if
(
rval
)
goto
out_free
;
if
(
v
)
{
rval
=
xfs_dir2_block_addname
(
args
);
goto
out_free
;
}
rval
=
xfs_dir2_isleaf
(
args
,
&
v
);
if
(
rval
)
goto
out_free
;
if
(
v
)
rval
=
xfs_dir2_leaf_addname
(
args
);
else
rval
=
xfs_dir2_node_addname
(
args
);
out_free:
kmem_free
(
args
);
return
rval
;
return
xfs_dir_createname
(
tp
,
dp
,
name
,
0
,
NULL
,
NULL
,
0
);
}
/*
...
...
fs/xfs/libxfs/xfs_dir2.h
浏览文件 @
a4241aeb
...
...
@@ -136,7 +136,7 @@ extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
xfs_fsblock_t
*
first
,
struct
xfs_bmap_free
*
flist
,
xfs_extlen_t
tot
);
extern
int
xfs_dir_canenter
(
struct
xfs_trans
*
tp
,
struct
xfs_inode
*
dp
,
struct
xfs_name
*
name
,
uint
resblks
);
struct
xfs_name
*
name
);
/*
* Direct call from the bmap code, bypassing the generic directory layer.
...
...
fs/xfs/libxfs/xfs_ialloc.c
浏览文件 @
a4241aeb
...
...
@@ -2051,6 +2051,8 @@ xfs_agi_verify(
if
(
!
XFS_AGI_GOOD_VERSION
(
be32_to_cpu
(
agi
->
agi_versionnum
)))
return
false
;
if
(
be32_to_cpu
(
agi
->
agi_level
)
>
XFS_BTREE_MAXLEVELS
)
return
false
;
/*
* during growfs operations, the perag is not fully initialised,
* so we can't use it for any useful checking. growfs ensures we can't
...
...
fs/xfs/libxfs/xfs_rtbitmap.c
浏览文件 @
a4241aeb
...
...
@@ -424,20 +424,24 @@ xfs_rtfind_forw(
}
/*
* Read and modify the summary information for a given extent size,
* Read and
/or
modify the summary information for a given extent size,
* bitmap block combination.
* Keeps track of a current summary block, so we don't keep reading
* it from the buffer cache.
*
* Summary information is returned in *sum if specified.
* If no delta is specified, returns summary only.
*/
int
xfs_rtmodify_summary
(
xfs_mount_t
*
mp
,
/* file system mount
point
*/
xfs_rtmodify_summary
_int
(
xfs_mount_t
*
mp
,
/* file system mount
structure
*/
xfs_trans_t
*
tp
,
/* transaction pointer */
int
log
,
/* log2 of extent size */
xfs_rtblock_t
bbno
,
/* bitmap block number */
int
delta
,
/* change to make to summary info */
xfs_buf_t
**
rbpp
,
/* in/out: summary block buffer */
xfs_fsblock_t
*
rsb
)
/* in/out: summary block number */
xfs_fsblock_t
*
rsb
,
/* in/out: summary block number */
xfs_suminfo_t
*
sum
)
/* out: summary info for this block */
{
xfs_buf_t
*
bp
;
/* buffer for the summary block */
int
error
;
/* error value */
...
...
@@ -456,7 +460,7 @@ xfs_rtmodify_summary(
/*
* If we have an old buffer, and the block number matches, use that.
*/
if
(
rbpp
&&
*
rbpp
&&
*
rsb
==
sb
)
if
(
*
rbpp
&&
*
rsb
==
sb
)
bp
=
*
rbpp
;
/*
* Otherwise we have to get the buffer.
...
...
@@ -465,7 +469,7 @@ xfs_rtmodify_summary(
/*
* If there was an old one, get rid of it first.
*/
if
(
rbpp
&&
*
rbpp
)
if
(
*
rbpp
)
xfs_trans_brelse
(
tp
,
*
rbpp
);
error
=
xfs_rtbuf_get
(
mp
,
tp
,
sb
,
1
,
&
bp
);
if
(
error
)
{
...
...
@@ -474,21 +478,38 @@ xfs_rtmodify_summary(
/*
* Remember this buffer and block for the next call.
*/
if
(
rbpp
)
{
*
rbpp
=
bp
;
*
rsb
=
sb
;
}
*
rbpp
=
bp
;
*
rsb
=
sb
;
}
/*
* Point to the summary information, modify
and log i
t.
* Point to the summary information, modify
/log it, and/or copy it ou
t.
*/
sp
=
XFS_SUMPTR
(
mp
,
bp
,
so
);
*
sp
+=
delta
;
xfs_trans_log_buf
(
tp
,
bp
,
(
uint
)((
char
*
)
sp
-
(
char
*
)
bp
->
b_addr
),
(
uint
)((
char
*
)
sp
-
(
char
*
)
bp
->
b_addr
+
sizeof
(
*
sp
)
-
1
));
if
(
delta
)
{
uint
first
=
(
uint
)((
char
*
)
sp
-
(
char
*
)
bp
->
b_addr
);
*
sp
+=
delta
;
xfs_trans_log_buf
(
tp
,
bp
,
first
,
first
+
sizeof
(
*
sp
)
-
1
);
}
if
(
sum
)
*
sum
=
*
sp
;
return
0
;
}
int
xfs_rtmodify_summary
(
xfs_mount_t
*
mp
,
/* file system mount structure */
xfs_trans_t
*
tp
,
/* transaction pointer */
int
log
,
/* log2 of extent size */
xfs_rtblock_t
bbno
,
/* bitmap block number */
int
delta
,
/* change to make to summary info */
xfs_buf_t
**
rbpp
,
/* in/out: summary block buffer */
xfs_fsblock_t
*
rsb
)
/* in/out: summary block number */
{
return
xfs_rtmodify_summary_int
(
mp
,
tp
,
log
,
bbno
,
delta
,
rbpp
,
rsb
,
NULL
);
}
/*
* Set the given range of bitmap bits to the given value.
* Do whatever I/O and logging is required.
...
...
fs/xfs/libxfs/xfs_sb.c
浏览文件 @
a4241aeb
...
...
@@ -279,11 +279,13 @@ xfs_mount_validate_sb(
sbp
->
sb_blocklog
<
XFS_MIN_BLOCKSIZE_LOG
||
sbp
->
sb_blocklog
>
XFS_MAX_BLOCKSIZE_LOG
||
sbp
->
sb_blocksize
!=
(
1
<<
sbp
->
sb_blocklog
)
||
sbp
->
sb_dirblklog
>
XFS_MAX_BLOCKSIZE_LOG
||
sbp
->
sb_inodesize
<
XFS_DINODE_MIN_SIZE
||
sbp
->
sb_inodesize
>
XFS_DINODE_MAX_SIZE
||
sbp
->
sb_inodelog
<
XFS_DINODE_MIN_LOG
||
sbp
->
sb_inodelog
>
XFS_DINODE_MAX_LOG
||
sbp
->
sb_inodesize
!=
(
1
<<
sbp
->
sb_inodelog
)
||
sbp
->
sb_logsunit
>
XLOG_MAX_RECORD_BSIZE
||
sbp
->
sb_inopblock
!=
howmany
(
sbp
->
sb_blocksize
,
sbp
->
sb_inodesize
)
||
(
sbp
->
sb_blocklog
-
sbp
->
sb_inodelog
!=
sbp
->
sb_inopblog
)
||
(
sbp
->
sb_rextsize
*
sbp
->
sb_blocksize
>
XFS_MAX_RTEXTSIZE
)
||
...
...
fs/xfs/xfs_buf.c
浏览文件 @
a4241aeb
...
...
@@ -1884,7 +1884,7 @@ xfs_buf_init(void)
goto
out
;
xfslogd_workqueue
=
alloc_workqueue
(
"xfslogd"
,
WQ_MEM_RECLAIM
|
WQ_HIGHPRI
,
1
);
WQ_MEM_RECLAIM
|
WQ_HIGHPRI
|
WQ_FREEZABLE
,
1
);
if
(
!
xfslogd_workqueue
)
goto
out_free_buf_zone
;
...
...
fs/xfs/xfs_file.c
浏览文件 @
a4241aeb
...
...
@@ -983,7 +983,7 @@ xfs_vm_page_mkwrite(
/*
* This type is designed to indicate the type of offset we would like
* to search from page cache for
either xfs_seek_data() or xfs_seek_hole
().
* to search from page cache for
xfs_seek_hole_data
().
*/
enum
{
HOLE_OFF
=
0
,
...
...
@@ -1040,7 +1040,7 @@ xfs_lookup_buffer_offset(
/*
* This routine is called to find out and return a data or hole offset
* from the page cache for unwritten extents according to the desired
* type for xfs_seek_
data() or xfs_seek_hole
().
* type for xfs_seek_
hole_data
().
*
* The argument offset is used to tell where we start to search from the
* page cache. Map is used to figure out the end points of the range to
...
...
@@ -1200,9 +1200,10 @@ xfs_find_get_desired_pgoff(
}
STATIC
loff_t
xfs_seek_data
(
xfs_seek_
hole_
data
(
struct
file
*
file
,
loff_t
start
)
loff_t
start
,
int
whence
)
{
struct
inode
*
inode
=
file
->
f_mapping
->
host
;
struct
xfs_inode
*
ip
=
XFS_I
(
inode
);
...
...
@@ -1214,6 +1215,9 @@ xfs_seek_data(
uint
lock
;
int
error
;
if
(
XFS_FORCED_SHUTDOWN
(
mp
))
return
-
EIO
;
lock
=
xfs_ilock_data_map_shared
(
ip
);
isize
=
i_size_read
(
inode
);
...
...
@@ -1228,6 +1232,7 @@ xfs_seek_data(
*/
fsbno
=
XFS_B_TO_FSBT
(
mp
,
start
);
end
=
XFS_B_TO_FSB
(
mp
,
isize
);
for
(;;)
{
struct
xfs_bmbt_irec
map
[
2
];
int
nmap
=
2
;
...
...
@@ -1248,29 +1253,48 @@ xfs_seek_data(
offset
=
max_t
(
loff_t
,
start
,
XFS_FSB_TO_B
(
mp
,
map
[
i
].
br_startoff
));
/* Landed in a data extent */
if
(
map
[
i
].
br_startblock
==
DELAYSTARTBLOCK
||
(
map
[
i
].
br_state
==
XFS_EXT_NORM
&&
!
isnullstartblock
(
map
[
i
].
br_startblock
)))
/* Landed in the hole we wanted? */
if
(
whence
==
SEEK_HOLE
&&
map
[
i
].
br_startblock
==
HOLESTARTBLOCK
)
goto
out
;
/* Landed in the data extent we wanted? */
if
(
whence
==
SEEK_DATA
&&
(
map
[
i
].
br_startblock
==
DELAYSTARTBLOCK
||
(
map
[
i
].
br_state
==
XFS_EXT_NORM
&&
!
isnullstartblock
(
map
[
i
].
br_startblock
))))
goto
out
;
/*
* Landed in an unwritten extent, try to search
data
* from page cache.
* Landed in an unwritten extent, try to search
* f
or hole or data f
rom page cache.
*/
if
(
map
[
i
].
br_state
==
XFS_EXT_UNWRITTEN
)
{
if
(
xfs_find_get_desired_pgoff
(
inode
,
&
map
[
i
],
DATA_OFF
,
&
offset
))
whence
==
SEEK_HOLE
?
HOLE_OFF
:
DATA_OFF
,
&
offset
))
goto
out
;
}
}
/*
* map[0] is hole or its an unwritten extent but
* without data in page cache. Probably means that
* we are reading after EOF if nothing in map[1].
* We only received one extent out of the two requested. This
* means we've hit EOF and didn't find what we are looking for.
*/
if
(
nmap
==
1
)
{
/*
* If we were looking for a hole, set offset to
* the end of the file (i.e., there is an implicit
* hole at the end of any file).
*/
if
(
whence
==
SEEK_HOLE
)
{
offset
=
isize
;
break
;
}
/*
* If we were looking for data, it's nowhere to be found
*/
ASSERT
(
whence
==
SEEK_DATA
);
error
=
-
ENXIO
;
goto
out_unlock
;
}
...
...
@@ -1279,125 +1303,30 @@ xfs_seek_data(
/*
* Nothing was found, proceed to the next round of search
* if
reading offset not beyond or hit
EOF.
* if
the next reading offset is not at or beyond
EOF.
*/
fsbno
=
map
[
i
-
1
].
br_startoff
+
map
[
i
-
1
].
br_blockcount
;
start
=
XFS_FSB_TO_B
(
mp
,
fsbno
);
if
(
start
>=
isize
)
{
if
(
whence
==
SEEK_HOLE
)
{
offset
=
isize
;
break
;
}
ASSERT
(
whence
==
SEEK_DATA
);
error
=
-
ENXIO
;
goto
out_unlock
;
}
}
out:
offset
=
vfs_setpos
(
file
,
offset
,
inode
->
i_sb
->
s_maxbytes
);
out_unlock:
xfs_iunlock
(
ip
,
lock
);
if
(
error
)
return
error
;
return
offset
;
}
STATIC
loff_t
xfs_seek_hole
(
struct
file
*
file
,
loff_t
start
)
{
struct
inode
*
inode
=
file
->
f_mapping
->
host
;
struct
xfs_inode
*
ip
=
XFS_I
(
inode
);
struct
xfs_mount
*
mp
=
ip
->
i_mount
;
loff_t
uninitialized_var
(
offset
);
xfs_fsize_t
isize
;
xfs_fileoff_t
fsbno
;
xfs_filblks_t
end
;
uint
lock
;
int
error
;
if
(
XFS_FORCED_SHUTDOWN
(
mp
))
return
-
EIO
;
lock
=
xfs_ilock_data_map_shared
(
ip
);
isize
=
i_size_read
(
inode
);
if
(
start
>=
isize
)
{
error
=
-
ENXIO
;
goto
out_unlock
;
}
fsbno
=
XFS_B_TO_FSBT
(
mp
,
start
);
end
=
XFS_B_TO_FSB
(
mp
,
isize
);
for
(;;)
{
struct
xfs_bmbt_irec
map
[
2
];
int
nmap
=
2
;
unsigned
int
i
;
error
=
xfs_bmapi_read
(
ip
,
fsbno
,
end
-
fsbno
,
map
,
&
nmap
,
XFS_BMAPI_ENTIRE
);
if
(
error
)
goto
out_unlock
;
/* No extents at given offset, must be beyond EOF */
if
(
nmap
==
0
)
{
error
=
-
ENXIO
;
goto
out_unlock
;
}
for
(
i
=
0
;
i
<
nmap
;
i
++
)
{
offset
=
max_t
(
loff_t
,
start
,
XFS_FSB_TO_B
(
mp
,
map
[
i
].
br_startoff
));
/* Landed in a hole */
if
(
map
[
i
].
br_startblock
==
HOLESTARTBLOCK
)
goto
out
;
/*
* Landed in an unwritten extent, try to search hole
* from page cache.
*/
if
(
map
[
i
].
br_state
==
XFS_EXT_UNWRITTEN
)
{
if
(
xfs_find_get_desired_pgoff
(
inode
,
&
map
[
i
],
HOLE_OFF
,
&
offset
))
goto
out
;
}
}
/*
* map[0] contains data or its unwritten but contains
* data in page cache, probably means that we are
* reading after EOF. We should fix offset to point
* to the end of the file(i.e., there is an implicit
* hole at the end of any file).
*/
if
(
nmap
==
1
)
{
offset
=
isize
;
break
;
}
ASSERT
(
i
>
1
);
/*
* Both mappings contains data, proceed to the next round of
* search if the current reading offset not beyond or hit EOF.
*/
fsbno
=
map
[
i
-
1
].
br_startoff
+
map
[
i
-
1
].
br_blockcount
;
start
=
XFS_FSB_TO_B
(
mp
,
fsbno
);
if
(
start
>=
isize
)
{
offset
=
isize
;
break
;
}
}
out:
/*
*
At this point, we must have found a hole. However
, the returned
*
If at this point we have found the hole we wanted
, the returned
* offset may be bigger than the file size as it may be aligned to
* page boundary for unwritten extents
, w
e need to deal with this
* page boundary for unwritten extents
. W
e need to deal with this
* situation in particular.
*/
offset
=
min_t
(
loff_t
,
offset
,
isize
);
if
(
whence
==
SEEK_HOLE
)
offset
=
min_t
(
loff_t
,
offset
,
isize
);
offset
=
vfs_setpos
(
file
,
offset
,
inode
->
i_sb
->
s_maxbytes
);
out_unlock:
...
...
@@ -1412,17 +1341,16 @@ STATIC loff_t
xfs_file_llseek
(
struct
file
*
file
,
loff_t
offset
,
int
origin
)
int
whence
)
{
switch
(
origin
)
{
switch
(
whence
)
{
case
SEEK_END
:
case
SEEK_CUR
:
case
SEEK_SET
:
return
generic_file_llseek
(
file
,
offset
,
origin
);
case
SEEK_DATA
:
return
xfs_seek_data
(
file
,
offset
);
return
generic_file_llseek
(
file
,
offset
,
whence
);
case
SEEK_HOLE
:
return
xfs_seek_hole
(
file
,
offset
);
case
SEEK_DATA
:
return
xfs_seek_hole_data
(
file
,
offset
,
whence
);
default:
return
-
EINVAL
;
}
...
...
fs/xfs/xfs_globals.c
浏览文件 @
a4241aeb
...
...
@@ -43,3 +43,7 @@ xfs_param_t xfs_params = {
.
fstrm_timer
=
{
1
,
30
*
100
,
3600
*
100
},
.
eofb_timer
=
{
1
,
300
,
3600
*
24
},
};
struct
xfs_globals
xfs_globals
=
{
.
log_recovery_delay
=
0
,
/* no delay by default */
};
fs/xfs/xfs_inode.c
浏览文件 @
a4241aeb
...
...
@@ -1153,9 +1153,11 @@ xfs_create(
if
(
error
)
goto
out_trans_cancel
;
error
=
xfs_dir_canenter
(
tp
,
dp
,
name
,
resblks
);
if
(
error
)
goto
out_trans_cancel
;
if
(
!
resblks
)
{
error
=
xfs_dir_canenter
(
tp
,
dp
,
name
);
if
(
error
)
goto
out_trans_cancel
;
}
/*
* A newly created regular or special file just has one directory
...
...
@@ -1421,9 +1423,11 @@ xfs_link(
goto
error_return
;
}
error
=
xfs_dir_canenter
(
tp
,
tdp
,
target_name
,
resblks
);
if
(
error
)
goto
error_return
;
if
(
!
resblks
)
{
error
=
xfs_dir_canenter
(
tp
,
tdp
,
target_name
);
if
(
error
)
goto
error_return
;
}
xfs_bmap_init
(
&
free_list
,
&
first_block
);
...
...
@@ -2759,9 +2763,11 @@ xfs_rename(
* If there's no space reservation, check the entry will
* fit before actually inserting it.
*/
error
=
xfs_dir_canenter
(
tp
,
target_dp
,
target_name
,
spaceres
);
if
(
error
)
goto
error_return
;
if
(
!
spaceres
)
{
error
=
xfs_dir_canenter
(
tp
,
target_dp
,
target_name
);
if
(
error
)
goto
error_return
;
}
/*
* If target does not exist and the rename crosses
* directories, adjust the target directory link count
...
...
fs/xfs/xfs_log_recover.c
浏览文件 @
a4241aeb
...
...
@@ -4132,41 +4132,13 @@ xlog_do_recovery_pass(
}
memset
(
rhash
,
0
,
sizeof
(
rhash
));
if
(
tail_blk
<=
head_blk
)
{
for
(
blk_no
=
tail_blk
;
blk_no
<
head_blk
;
)
{
error
=
xlog_bread
(
log
,
blk_no
,
hblks
,
hbp
,
&
offset
);
if
(
error
)
goto
bread_err2
;
rhead
=
(
xlog_rec_header_t
*
)
offset
;
error
=
xlog_valid_rec_header
(
log
,
rhead
,
blk_no
);
if
(
error
)
goto
bread_err2
;
/* blocks in data section */
bblks
=
(
int
)
BTOBB
(
be32_to_cpu
(
rhead
->
h_len
));
error
=
xlog_bread
(
log
,
blk_no
+
hblks
,
bblks
,
dbp
,
&
offset
);
if
(
error
)
goto
bread_err2
;
error
=
xlog_unpack_data
(
rhead
,
offset
,
log
);
if
(
error
)
goto
bread_err2
;
error
=
xlog_recover_process_data
(
log
,
rhash
,
rhead
,
offset
,
pass
);
if
(
error
)
goto
bread_err2
;
blk_no
+=
bblks
+
hblks
;
}
}
else
{
blk_no
=
tail_blk
;
if
(
tail_blk
>
head_blk
)
{
/*
* Perform recovery around the end of the physical log.
* When the head is not on the same cycle number as the tail,
* we can't do a sequential recovery
as above
.
* we can't do a sequential recovery.
*/
blk_no
=
tail_blk
;
while
(
blk_no
<
log
->
l_logBBsize
)
{
/*
* Check for header wrapping around physical end-of-log
...
...
@@ -4280,34 +4252,35 @@ xlog_do_recovery_pass(
ASSERT
(
blk_no
>=
log
->
l_logBBsize
);
blk_no
-=
log
->
l_logBBsize
;
}
/* read first part of physical log */
while
(
blk_no
<
head_blk
)
{
error
=
xlog_bread
(
log
,
blk_no
,
hblks
,
hbp
,
&
offset
);
if
(
error
)
goto
bread_err2
;
/* read first part of physical log */
while
(
blk_no
<
head_blk
)
{
error
=
xlog_bread
(
log
,
blk_no
,
hblks
,
hbp
,
&
offset
);
if
(
error
)
goto
bread_err2
;
rhead
=
(
xlog_rec_header_t
*
)
offset
;
error
=
xlog_valid_rec_header
(
log
,
rhead
,
blk_no
);
if
(
error
)
goto
bread_err2
;
rhead
=
(
xlog_rec_header_t
*
)
offset
;
error
=
xlog_valid_rec_header
(
log
,
rhead
,
blk_no
);
if
(
error
)
goto
bread_err2
;
bblks
=
(
int
)
BTOBB
(
be32_to_cpu
(
rhead
->
h_len
));
error
=
xlog_bread
(
log
,
blk_no
+
hblks
,
bblks
,
dbp
,
&
offset
);
if
(
error
)
goto
bread_err2
;
/* blocks in data section */
bblks
=
(
int
)
BTOBB
(
be32_to_cpu
(
rhead
->
h_len
));
error
=
xlog_bread
(
log
,
blk_no
+
hblks
,
bblks
,
dbp
,
&
offset
);
if
(
error
)
goto
bread_err2
;
error
=
xlog_unpack_data
(
rhead
,
offset
,
log
);
if
(
error
)
goto
bread_err2
;
error
=
xlog_unpack_data
(
rhead
,
offset
,
log
);
if
(
error
)
goto
bread_err2
;
error
=
xlog_recover_process_data
(
log
,
rhash
,
rhead
,
offset
,
pass
);
if
(
error
)
goto
bread_err2
;
blk_no
+=
bblks
+
hblks
;
}
error
=
xlog_recover_process_data
(
log
,
rhash
,
rhead
,
offset
,
pass
);
if
(
error
)
goto
bread_err2
;
blk_no
+=
bblks
+
hblks
;
}
bread_err2:
...
...
@@ -4509,6 +4482,18 @@ xlog_recover(
return
-
EINVAL
;
}
/*
* Delay log recovery if the debug hook is set. This is debug
* instrumention to coordinate simulation of I/O failures with
* log recovery.
*/
if
(
xfs_globals
.
log_recovery_delay
)
{
xfs_notice
(
log
->
l_mp
,
"Delaying log recovery for %d seconds."
,
xfs_globals
.
log_recovery_delay
);
msleep
(
xfs_globals
.
log_recovery_delay
*
1000
);
}
xfs_notice
(
log
->
l_mp
,
"Starting recovery (logdev: %s)"
,
log
->
l_mp
->
m_logname
?
log
->
l_mp
->
m_logname
:
"internal"
);
...
...
fs/xfs/xfs_mru_cache.c
浏览文件 @
a4241aeb
...
...
@@ -304,7 +304,8 @@ _xfs_mru_cache_reap(
int
xfs_mru_cache_init
(
void
)
{
xfs_mru_reap_wq
=
alloc_workqueue
(
"xfs_mru_cache"
,
WQ_MEM_RECLAIM
,
1
);
xfs_mru_reap_wq
=
alloc_workqueue
(
"xfs_mru_cache"
,
WQ_MEM_RECLAIM
|
WQ_FREEZABLE
,
1
);
if
(
!
xfs_mru_reap_wq
)
return
-
ENOMEM
;
return
0
;
...
...
fs/xfs/xfs_rtalloc.c
浏览文件 @
a4241aeb
...
...
@@ -46,7 +46,7 @@
* Keeps track of a current summary block, so we don't keep reading
* it from the buffer cache.
*/
STATIC
int
/* error */
int
xfs_rtget_summary
(
xfs_mount_t
*
mp
,
/* file system mount structure */
xfs_trans_t
*
tp
,
/* transaction pointer */
...
...
@@ -56,60 +56,9 @@ xfs_rtget_summary(
xfs_fsblock_t
*
rsb
,
/* in/out: summary block number */
xfs_suminfo_t
*
sum
)
/* out: summary info for this block */
{
xfs_buf_t
*
bp
;
/* buffer for summary block */
int
error
;
/* error value */
xfs_fsblock_t
sb
;
/* summary fsblock */
int
so
;
/* index into the summary file */
xfs_suminfo_t
*
sp
;
/* pointer to returned data */
/*
* Compute entry number in the summary file.
*/
so
=
XFS_SUMOFFS
(
mp
,
log
,
bbno
);
/*
* Compute the block number in the summary file.
*/
sb
=
XFS_SUMOFFSTOBLOCK
(
mp
,
so
);
/*
* If we have an old buffer, and the block number matches, use that.
*/
if
(
rbpp
&&
*
rbpp
&&
*
rsb
==
sb
)
bp
=
*
rbpp
;
/*
* Otherwise we have to get the buffer.
*/
else
{
/*
* If there was an old one, get rid of it first.
*/
if
(
rbpp
&&
*
rbpp
)
xfs_trans_brelse
(
tp
,
*
rbpp
);
error
=
xfs_rtbuf_get
(
mp
,
tp
,
sb
,
1
,
&
bp
);
if
(
error
)
{
return
error
;
}
/*
* Remember this buffer and block for the next call.
*/
if
(
rbpp
)
{
*
rbpp
=
bp
;
*
rsb
=
sb
;
}
}
/*
* Point to the summary information & copy it out.
*/
sp
=
XFS_SUMPTR
(
mp
,
bp
,
so
);
*
sum
=
*
sp
;
/*
* Drop the buffer if we're not asked to remember it.
*/
if
(
!
rbpp
)
xfs_trans_brelse
(
tp
,
bp
);
return
0
;
return
xfs_rtmodify_summary_int
(
mp
,
tp
,
log
,
bbno
,
0
,
rbpp
,
rsb
,
sum
);
}
/*
* Return whether there are any free extents in the size range given
* by low and high, for the bitmap block bbno.
...
...
fs/xfs/xfs_rtalloc.h
浏览文件 @
a4241aeb
...
...
@@ -111,6 +111,10 @@ int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp,
xfs_rtblock_t
*
rtblock
);
int
xfs_rtmodify_range
(
struct
xfs_mount
*
mp
,
struct
xfs_trans
*
tp
,
xfs_rtblock_t
start
,
xfs_extlen_t
len
,
int
val
);
int
xfs_rtmodify_summary_int
(
struct
xfs_mount
*
mp
,
struct
xfs_trans
*
tp
,
int
log
,
xfs_rtblock_t
bbno
,
int
delta
,
xfs_buf_t
**
rbpp
,
xfs_fsblock_t
*
rsb
,
xfs_suminfo_t
*
sum
);
int
xfs_rtmodify_summary
(
struct
xfs_mount
*
mp
,
struct
xfs_trans
*
tp
,
int
log
,
xfs_rtblock_t
bbno
,
int
delta
,
xfs_buf_t
**
rbpp
,
xfs_fsblock_t
*
rsb
);
...
...
fs/xfs/xfs_super.c
浏览文件 @
a4241aeb
...
...
@@ -47,6 +47,7 @@
#include "xfs_dinode.h"
#include "xfs_filestream.h"
#include "xfs_quota.h"
#include "xfs_sysfs.h"
#include <linux/namei.h>
#include <linux/init.h>
...
...
@@ -61,7 +62,11 @@
static
const
struct
super_operations
xfs_super_operations
;
static
kmem_zone_t
*
xfs_ioend_zone
;
mempool_t
*
xfs_ioend_pool
;
struct
kset
*
xfs_kset
;
struct
kset
*
xfs_kset
;
/* top-level xfs sysfs dir */
#ifdef DEBUG
static
struct
xfs_kobj
xfs_dbg_kobj
;
/* global debug sysfs attrs */
#endif
#define MNTOPT_LOGBUFS "logbufs"
/* number of XFS log buffers */
#define MNTOPT_LOGBSIZE "logbsize"
/* size of XFS log buffers */
...
...
@@ -838,32 +843,32 @@ xfs_init_mount_workqueues(
struct
xfs_mount
*
mp
)
{
mp
->
m_data_workqueue
=
alloc_workqueue
(
"xfs-data/%s"
,
WQ_MEM_RECLAIM
,
0
,
mp
->
m_fsname
);
WQ_MEM_RECLAIM
|
WQ_FREEZABLE
,
0
,
mp
->
m_fsname
);
if
(
!
mp
->
m_data_workqueue
)
goto
out
;
mp
->
m_unwritten_workqueue
=
alloc_workqueue
(
"xfs-conv/%s"
,
WQ_MEM_RECLAIM
,
0
,
mp
->
m_fsname
);
WQ_MEM_RECLAIM
|
WQ_FREEZABLE
,
0
,
mp
->
m_fsname
);
if
(
!
mp
->
m_unwritten_workqueue
)
goto
out_destroy_data_iodone_queue
;
mp
->
m_cil_workqueue
=
alloc_workqueue
(
"xfs-cil/%s"
,
WQ_MEM_RECLAIM
,
0
,
mp
->
m_fsname
);
WQ_MEM_RECLAIM
|
WQ_FREEZABLE
,
0
,
mp
->
m_fsname
);
if
(
!
mp
->
m_cil_workqueue
)
goto
out_destroy_unwritten
;
mp
->
m_reclaim_workqueue
=
alloc_workqueue
(
"xfs-reclaim/%s"
,
0
,
0
,
mp
->
m_fsname
);
WQ_FREEZABLE
,
0
,
mp
->
m_fsname
);
if
(
!
mp
->
m_reclaim_workqueue
)
goto
out_destroy_cil
;
mp
->
m_log_workqueue
=
alloc_workqueue
(
"xfs-log/%s"
,
0
,
0
,
mp
->
m_fsname
);
WQ_FREEZABLE
,
0
,
mp
->
m_fsname
);
if
(
!
mp
->
m_log_workqueue
)
goto
out_destroy_reclaim
;
mp
->
m_eofblocks_workqueue
=
alloc_workqueue
(
"xfs-eofblocks/%s"
,
0
,
0
,
mp
->
m_fsname
);
WQ_FREEZABLE
,
0
,
mp
->
m_fsname
);
if
(
!
mp
->
m_eofblocks_workqueue
)
goto
out_destroy_log
;
...
...
@@ -1715,7 +1720,8 @@ xfs_init_workqueues(void)
* AGs in all the filesystems mounted. Hence use the default large
* max_active value for this workqueue.
*/
xfs_alloc_wq
=
alloc_workqueue
(
"xfsalloc"
,
WQ_MEM_RECLAIM
,
0
);
xfs_alloc_wq
=
alloc_workqueue
(
"xfsalloc"
,
WQ_MEM_RECLAIM
|
WQ_FREEZABLE
,
0
);
if
(
!
xfs_alloc_wq
)
return
-
ENOMEM
;
...
...
@@ -1768,9 +1774,16 @@ init_xfs_fs(void)
goto
out_sysctl_unregister
;;
}
error
=
xfs_qm_init
();
#ifdef DEBUG
xfs_dbg_kobj
.
kobject
.
kset
=
xfs_kset
;
error
=
xfs_sysfs_init
(
&
xfs_dbg_kobj
,
&
xfs_dbg_ktype
,
NULL
,
"debug"
);
if
(
error
)
goto
out_kset_unregister
;
#endif
error
=
xfs_qm_init
();
if
(
error
)
goto
out_remove_kobj
;
error
=
register_filesystem
(
&
xfs_fs_type
);
if
(
error
)
...
...
@@ -1779,7 +1792,11 @@ init_xfs_fs(void)
out_qm_exit:
xfs_qm_exit
();
out_remove_kobj:
#ifdef DEBUG
xfs_sysfs_del
(
&
xfs_dbg_kobj
);
out_kset_unregister:
#endif
kset_unregister
(
xfs_kset
);
out_sysctl_unregister:
xfs_sysctl_unregister
();
...
...
@@ -1802,6 +1819,9 @@ exit_xfs_fs(void)
{
xfs_qm_exit
();
unregister_filesystem
(
&
xfs_fs_type
);
#ifdef DEBUG
xfs_sysfs_del
(
&
xfs_dbg_kobj
);
#endif
kset_unregister
(
xfs_kset
);
xfs_sysctl_unregister
();
xfs_cleanup_procfs
();
...
...
fs/xfs/xfs_symlink.c
浏览文件 @
a4241aeb
...
...
@@ -269,9 +269,11 @@ xfs_symlink(
/*
* Check for ability to enter directory entry, if no space reserved.
*/
error
=
xfs_dir_canenter
(
tp
,
dp
,
link_name
,
resblks
);
if
(
error
)
goto
error_return
;
if
(
!
resblks
)
{
error
=
xfs_dir_canenter
(
tp
,
dp
,
link_name
);
if
(
error
)
goto
error_return
;
}
/*
* Initialize the bmap freelist prior to calling either
* bmapi or the directory create code.
...
...
fs/xfs/xfs_sysctl.h
浏览文件 @
a4241aeb
...
...
@@ -92,6 +92,11 @@ enum {
extern
xfs_param_t
xfs_params
;
struct
xfs_globals
{
int
log_recovery_delay
;
/* log recovery delay (secs) */
};
extern
struct
xfs_globals
xfs_globals
;
#ifdef CONFIG_SYSCTL
extern
int
xfs_sysctl_register
(
void
);
extern
void
xfs_sysctl_unregister
(
void
);
...
...
fs/xfs/xfs_sysfs.c
浏览文件 @
a4241aeb
...
...
@@ -51,6 +51,80 @@ struct kobj_type xfs_mp_ktype = {
.
release
=
xfs_sysfs_release
,
};
#ifdef DEBUG
/* debug */
STATIC
ssize_t
log_recovery_delay_store
(
const
char
*
buf
,
size_t
count
,
void
*
data
)
{
int
ret
;
int
val
;
ret
=
kstrtoint
(
buf
,
0
,
&
val
);
if
(
ret
)
return
ret
;
if
(
val
<
0
||
val
>
60
)
return
-
EINVAL
;
xfs_globals
.
log_recovery_delay
=
val
;
return
count
;
}
STATIC
ssize_t
log_recovery_delay_show
(
char
*
buf
,
void
*
data
)
{
return
snprintf
(
buf
,
PAGE_SIZE
,
"%d
\n
"
,
xfs_globals
.
log_recovery_delay
);
}
XFS_SYSFS_ATTR_RW
(
log_recovery_delay
);
static
struct
attribute
*
xfs_dbg_attrs
[]
=
{
ATTR_LIST
(
log_recovery_delay
),
NULL
,
};
STATIC
ssize_t
xfs_dbg_show
(
struct
kobject
*
kobject
,
struct
attribute
*
attr
,
char
*
buf
)
{
struct
xfs_sysfs_attr
*
xfs_attr
=
to_attr
(
attr
);
return
xfs_attr
->
show
?
xfs_attr
->
show
(
buf
,
NULL
)
:
0
;
}
STATIC
ssize_t
xfs_dbg_store
(
struct
kobject
*
kobject
,
struct
attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
xfs_sysfs_attr
*
xfs_attr
=
to_attr
(
attr
);
return
xfs_attr
->
store
?
xfs_attr
->
store
(
buf
,
count
,
NULL
)
:
0
;
}
static
struct
sysfs_ops
xfs_dbg_ops
=
{
.
show
=
xfs_dbg_show
,
.
store
=
xfs_dbg_store
,
};
struct
kobj_type
xfs_dbg_ktype
=
{
.
release
=
xfs_sysfs_release
,
.
sysfs_ops
=
&
xfs_dbg_ops
,
.
default_attrs
=
xfs_dbg_attrs
,
};
#endif
/* DEBUG */
/* xlog */
STATIC
ssize_t
...
...
fs/xfs/xfs_sysfs.h
浏览文件 @
a4241aeb
...
...
@@ -20,6 +20,7 @@
#define __XFS_SYSFS_H__
extern
struct
kobj_type
xfs_mp_ktype
;
/* xfs_mount */
extern
struct
kobj_type
xfs_dbg_ktype
;
/* debug */
extern
struct
kobj_type
xfs_log_ktype
;
/* xlog */
static
inline
struct
xfs_kobj
*
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录