Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
59eda0e0
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看板
提交
59eda0e0
编写于
1月 10, 2015
作者:
A
Al Viro
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
new fs_pin killing logics
Signed-off-by:
N
Al Viro
<
viro@zeniv.linux.org.uk
>
上级
fdab684d
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
96 addition
and
56 deletion
+96
-56
fs/fs_pin.c
fs/fs_pin.c
+48
-6
include/linux/fs_pin.h
include/linux/fs_pin.h
+12
-1
include/linux/pid_namespace.h
include/linux/pid_namespace.h
+2
-2
kernel/acct.c
kernel/acct.c
+34
-47
未找到文件。
fs/fs_pin.c
浏览文件 @
59eda0e0
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/fs_pin.h>
#include "internal.h"
...
...
@@ -12,6 +13,10 @@ void pin_remove(struct fs_pin *pin)
hlist_del
(
&
pin
->
m_list
);
hlist_del
(
&
pin
->
s_list
);
spin_unlock
(
&
pin_lock
);
spin_lock_irq
(
&
pin
->
wait
.
lock
);
pin
->
done
=
1
;
wake_up_locked
(
&
pin
->
wait
);
spin_unlock_irq
(
&
pin
->
wait
.
lock
);
}
void
pin_insert_group
(
struct
fs_pin
*
pin
,
struct
vfsmount
*
m
,
struct
hlist_head
*
p
)
...
...
@@ -28,19 +33,58 @@ void pin_insert(struct fs_pin *pin, struct vfsmount *m)
pin_insert_group
(
pin
,
m
,
&
m
->
mnt_sb
->
s_pins
);
}
void
pin_kill
(
struct
fs_pin
*
p
)
{
wait_queue_t
wait
;
if
(
!
p
)
{
rcu_read_unlock
();
return
;
}
init_wait
(
&
wait
);
spin_lock_irq
(
&
p
->
wait
.
lock
);
if
(
likely
(
!
p
->
done
))
{
p
->
done
=
-
1
;
spin_unlock_irq
(
&
p
->
wait
.
lock
);
rcu_read_unlock
();
p
->
kill
(
p
);
return
;
}
if
(
p
->
done
>
0
)
{
spin_unlock_irq
(
&
p
->
wait
.
lock
);
rcu_read_unlock
();
return
;
}
__add_wait_queue
(
&
p
->
wait
,
&
wait
);
while
(
1
)
{
set_current_state
(
TASK_UNINTERRUPTIBLE
);
spin_unlock_irq
(
&
p
->
wait
.
lock
);
rcu_read_unlock
();
schedule
();
rcu_read_lock
();
if
(
likely
(
list_empty
(
&
wait
.
task_list
)))
break
;
/* OK, we know p couldn't have been freed yet */
spin_lock_irq
(
&
p
->
wait
.
lock
);
if
(
p
->
done
>
0
)
{
spin_unlock_irq
(
&
p
->
wait
.
lock
);
break
;
}
}
rcu_read_unlock
();
}
void
mnt_pin_kill
(
struct
mount
*
m
)
{
while
(
1
)
{
struct
hlist_node
*
p
;
struct
fs_pin
*
pin
;
rcu_read_lock
();
p
=
ACCESS_ONCE
(
m
->
mnt_pins
.
first
);
if
(
!
p
)
{
rcu_read_unlock
();
break
;
}
pin
=
hlist_entry
(
p
,
struct
fs_pin
,
m_list
);
pin
->
kill
(
pin
);
pin_kill
(
hlist_entry
(
p
,
struct
fs_pin
,
m_list
));
}
}
...
...
@@ -48,14 +92,12 @@ void group_pin_kill(struct hlist_head *p)
{
while
(
1
)
{
struct
hlist_node
*
q
;
struct
fs_pin
*
pin
;
rcu_read_lock
();
q
=
ACCESS_ONCE
(
p
->
first
);
if
(
!
q
)
{
rcu_read_unlock
();
break
;
}
pin
=
hlist_entry
(
q
,
struct
fs_pin
,
s_list
);
pin
->
kill
(
pin
);
pin_kill
(
hlist_entry
(
q
,
struct
fs_pin
,
s_list
));
}
}
include/linux/fs_pin.h
浏览文件 @
59eda0e0
#include <linux/
fs
.h>
#include <linux/
wait
.h>
struct
fs_pin
{
wait_queue_head_t
wait
;
int
done
;
struct
hlist_node
s_list
;
struct
hlist_node
m_list
;
void
(
*
kill
)(
struct
fs_pin
*
);
};
struct
vfsmount
;
static
inline
void
init_fs_pin
(
struct
fs_pin
*
p
,
void
(
*
kill
)(
struct
fs_pin
*
))
{
init_waitqueue_head
(
&
p
->
wait
);
p
->
kill
=
kill
;
}
void
pin_remove
(
struct
fs_pin
*
);
void
pin_insert_group
(
struct
fs_pin
*
,
struct
vfsmount
*
,
struct
hlist_head
*
);
void
pin_insert
(
struct
fs_pin
*
,
struct
vfsmount
*
);
void
pin_kill
(
struct
fs_pin
*
);
include/linux/pid_namespace.h
浏览文件 @
59eda0e0
...
...
@@ -19,7 +19,7 @@ struct pidmap {
#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1)
#define PIDMAP_ENTRIES ((PID_MAX_LIMIT+BITS_PER_PAGE-1)/BITS_PER_PAGE)
struct
bsd_acct_struct
;
struct
fs_pin
;
struct
pid_namespace
{
struct
kref
kref
;
...
...
@@ -37,7 +37,7 @@ struct pid_namespace {
struct
dentry
*
proc_thread_self
;
#endif
#ifdef CONFIG_BSD_PROCESS_ACCT
struct
bsd_acct_struct
*
bacct
;
struct
fs_pin
*
bacct
;
#endif
struct
user_namespace
*
user_ns
;
struct
work_struct
proc_work
;
...
...
kernel/acct.c
浏览文件 @
59eda0e0
...
...
@@ -76,7 +76,6 @@ int acct_parm[3] = {4, 2, 30};
/*
* External references and all of the globals.
*/
static
void
do_acct_process
(
struct
bsd_acct_struct
*
acct
);
struct
bsd_acct_struct
{
struct
fs_pin
pin
;
...
...
@@ -91,6 +90,8 @@ struct bsd_acct_struct {
struct
completion
done
;
};
static
void
do_acct_process
(
struct
bsd_acct_struct
*
acct
);
/*
* Check the amount of free space and suspend/resume accordingly.
*/
...
...
@@ -132,13 +133,18 @@ static void acct_put(struct bsd_acct_struct *p)
kfree_rcu
(
p
,
rcu
);
}
static
inline
struct
bsd_acct_struct
*
to_acct
(
struct
fs_pin
*
p
)
{
return
p
?
container_of
(
p
,
struct
bsd_acct_struct
,
pin
)
:
NULL
;
}
static
struct
bsd_acct_struct
*
acct_get
(
struct
pid_namespace
*
ns
)
{
struct
bsd_acct_struct
*
res
;
again:
smp_rmb
();
rcu_read_lock
();
res
=
ACCESS_ONCE
(
ns
->
bacct
);
res
=
to_acct
(
ACCESS_ONCE
(
ns
->
bacct
)
);
if
(
!
res
)
{
rcu_read_unlock
();
return
NULL
;
...
...
@@ -150,7 +156,7 @@ static struct bsd_acct_struct *acct_get(struct pid_namespace *ns)
}
rcu_read_unlock
();
mutex_lock
(
&
res
->
lock
);
if
(
!
res
->
ns
)
{
if
(
res
!=
to_acct
(
ACCESS_ONCE
(
ns
->
bacct
))
)
{
mutex_unlock
(
&
res
->
lock
);
acct_put
(
res
);
goto
again
;
...
...
@@ -158,6 +164,19 @@ static struct bsd_acct_struct *acct_get(struct pid_namespace *ns)
return
res
;
}
static
void
acct_pin_kill
(
struct
fs_pin
*
pin
)
{
struct
bsd_acct_struct
*
acct
=
to_acct
(
pin
);
mutex_lock
(
&
acct
->
lock
);
do_acct_process
(
acct
);
schedule_work
(
&
acct
->
work
);
wait_for_completion
(
&
acct
->
done
);
cmpxchg
(
&
acct
->
ns
->
bacct
,
pin
,
NULL
);
mutex_unlock
(
&
acct
->
lock
);
pin_remove
(
pin
);
acct_put
(
acct
);
}
static
void
close_work
(
struct
work_struct
*
work
)
{
struct
bsd_acct_struct
*
acct
=
container_of
(
work
,
struct
bsd_acct_struct
,
work
);
...
...
@@ -168,49 +187,13 @@ static void close_work(struct work_struct *work)
complete
(
&
acct
->
done
);
}
static
void
acct_kill
(
struct
bsd_acct_struct
*
acct
)
{
if
(
acct
)
{
struct
pid_namespace
*
ns
=
acct
->
ns
;
do_acct_process
(
acct
);
INIT_WORK
(
&
acct
->
work
,
close_work
);
init_completion
(
&
acct
->
done
);
schedule_work
(
&
acct
->
work
);
wait_for_completion
(
&
acct
->
done
);
pin_remove
(
&
acct
->
pin
);
cmpxchg
(
&
ns
->
bacct
,
acct
,
NULL
);
acct
->
ns
=
NULL
;
atomic_long_dec
(
&
acct
->
count
);
mutex_unlock
(
&
acct
->
lock
);
acct_put
(
acct
);
}
}
static
void
acct_pin_kill
(
struct
fs_pin
*
pin
)
{
struct
bsd_acct_struct
*
acct
;
acct
=
container_of
(
pin
,
struct
bsd_acct_struct
,
pin
);
if
(
!
atomic_long_inc_not_zero
(
&
acct
->
count
))
{
rcu_read_unlock
();
cpu_relax
();
return
;
}
rcu_read_unlock
();
mutex_lock
(
&
acct
->
lock
);
if
(
!
acct
->
ns
)
{
mutex_unlock
(
&
acct
->
lock
);
acct_put
(
acct
);
acct
=
NULL
;
}
acct_kill
(
acct
);
}
static
int
acct_on
(
struct
filename
*
pathname
)
{
struct
file
*
file
;
struct
vfsmount
*
mnt
,
*
internal
;
struct
pid_namespace
*
ns
=
task_active_pid_ns
(
current
);
struct
bsd_acct_struct
*
acct
,
*
old
;
struct
bsd_acct_struct
*
acct
;
struct
fs_pin
*
old
;
int
err
;
acct
=
kzalloc
(
sizeof
(
struct
bsd_acct_struct
),
GFP_KERNEL
);
...
...
@@ -252,18 +235,20 @@ static int acct_on(struct filename *pathname)
file
->
f_path
.
mnt
=
internal
;
atomic_long_set
(
&
acct
->
count
,
1
);
acct
->
pin
.
kill
=
acct_pin_kill
;
init_fs_pin
(
&
acct
->
pin
,
acct_pin_kill
)
;
acct
->
file
=
file
;
acct
->
needcheck
=
jiffies
;
acct
->
ns
=
ns
;
mutex_init
(
&
acct
->
lock
);
INIT_WORK
(
&
acct
->
work
,
close_work
);
init_completion
(
&
acct
->
done
);
mutex_lock_nested
(
&
acct
->
lock
,
1
);
/* nobody has seen it yet */
pin_insert
(
&
acct
->
pin
,
mnt
);
old
=
acct_get
(
ns
);
ns
->
bacct
=
acct
;
acct_kill
(
old
);
rcu_read_lock
();
old
=
xchg
(
&
ns
->
bacct
,
&
acct
->
pin
);
mutex_unlock
(
&
acct
->
lock
);
pin_kill
(
old
);
mnt_drop_write
(
mnt
);
mntput
(
mnt
);
return
0
;
...
...
@@ -299,7 +284,8 @@ SYSCALL_DEFINE1(acct, const char __user *, name)
mutex_unlock
(
&
acct_on_mutex
);
putname
(
tmp
);
}
else
{
acct_kill
(
acct_get
(
task_active_pid_ns
(
current
)));
rcu_read_lock
();
pin_kill
(
task_active_pid_ns
(
current
)
->
bacct
);
}
return
error
;
...
...
@@ -307,7 +293,8 @@ SYSCALL_DEFINE1(acct, const char __user *, name)
void
acct_exit_ns
(
struct
pid_namespace
*
ns
)
{
acct_kill
(
acct_get
(
ns
));
rcu_read_lock
();
pin_kill
(
ns
->
bacct
);
}
/*
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录