Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiphi1978
linux
提交
35b7e476
L
linux
项目概览
xiphi1978
/
linux
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
35b7e476
编写于
5月 02, 2007
作者:
C
Chris Mason
提交者:
David Woodhouse
5月 02, 2007
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: fix page cache memory leak
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
090d1875
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
59 addition
and
45 deletion
+59
-45
fs/btrfs/bit-radix.c
fs/btrfs/bit-radix.c
+0
-2
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+3
-0
fs/btrfs/dir-item.c
fs/btrfs/dir-item.c
+6
-5
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+6
-2
fs/btrfs/disk-io.h
fs/btrfs/disk-io.h
+2
-0
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+1
-11
fs/btrfs/hash.c
fs/btrfs/hash.c
+1
-0
fs/btrfs/print-tree.c
fs/btrfs/print-tree.c
+1
-0
fs/btrfs/super.c
fs/btrfs/super.c
+34
-22
fs/btrfs/transaction.c
fs/btrfs/transaction.c
+5
-3
未找到文件。
fs/btrfs/bit-radix.c
浏览文件 @
35b7e476
...
...
@@ -22,9 +22,7 @@ int set_radix_bit(struct radix_tree_root *radix, unsigned long bit)
return
-
ENOMEM
;
memset
(
bits
+
1
,
0
,
BIT_ARRAY_BYTES
-
sizeof
(
unsigned
long
));
bits
[
0
]
=
slot
;
radix_tree_preload
(
GFP_NOFS
);
ret
=
radix_tree_insert
(
radix
,
slot
,
bits
);
radix_tree_preload_end
();
if
(
ret
)
return
ret
;
}
...
...
fs/btrfs/ctree.h
浏览文件 @
35b7e476
...
...
@@ -8,6 +8,9 @@
struct
btrfs_trans_handle
;
struct
btrfs_transaction
;
extern
struct
kmem_cache
*
btrfs_trans_handle_cachep
;
extern
struct
kmem_cache
*
btrfs_transaction_cachep
;
extern
struct
kmem_cache
*
btrfs_bit_radix_cachep
;
extern
struct
kmem_cache
*
btrfs_path_cachep
;
#define BTRFS_MAGIC "_BtRfS_M"
...
...
fs/btrfs/dir-item.c
浏览文件 @
35b7e476
...
...
@@ -4,11 +4,12 @@
#include "hash.h"
#include "transaction.h"
struct
btrfs_dir_item
*
insert_with_overflow
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
struct
btrfs_key
*
cpu_key
,
u32
data_size
)
static
struct
btrfs_dir_item
*
insert_with_overflow
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
btrfs_path
*
path
,
struct
btrfs_key
*
cpu_key
,
u32
data_size
)
{
int
ret
;
char
*
ptr
;
...
...
fs/btrfs/disk-io.c
浏览文件 @
35b7e476
...
...
@@ -5,7 +5,7 @@
#include <linux/scatterlist.h>
#include <linux/swap.h>
#include <linux/radix-tree.h>
#include <linux/
file
.h>
#include <linux/
writeback
.h>
#include "ctree.h"
#include "disk-io.h"
#include "transaction.h"
...
...
@@ -694,7 +694,7 @@ static int free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
return
0
;
}
int
del_fs_roots
(
struct
btrfs_fs_info
*
fs_info
)
static
int
del_fs_roots
(
struct
btrfs_fs_info
*
fs_info
)
{
int
ret
;
struct
btrfs_root
*
gang
[
8
];
...
...
@@ -781,3 +781,7 @@ void btrfs_block_release(struct btrfs_root *root, struct buffer_head *buf)
brelse
(
buf
);
}
void
btrfs_btree_balance_dirty
(
struct
btrfs_root
*
root
)
{
balance_dirty_pages_ratelimited
(
root
->
fs_info
->
btree_inode
->
i_mapping
);
}
fs/btrfs/disk-io.h
浏览文件 @
35b7e476
...
...
@@ -55,4 +55,6 @@ int btrfs_insert_dev_radix(struct btrfs_root *root,
u64
num_blocks
);
int
btrfs_map_bh_to_logical
(
struct
btrfs_root
*
root
,
struct
buffer_head
*
bh
,
u64
logical
);
int
btrfs_releasepage
(
struct
page
*
page
,
gfp_t
flags
);
void
btrfs_btree_balance_dirty
(
struct
btrfs_root
*
root
);
#endif
fs/btrfs/extent-tree.c
浏览文件 @
35b7e476
...
...
@@ -322,18 +322,10 @@ static int update_block_group(struct btrfs_trans_handle *trans,
return
0
;
}
static
int
try_remove_page
(
struct
address_space
*
mapping
,
unsigned
long
index
)
{
int
ret
;
ret
=
invalidate_mapping_pages
(
mapping
,
index
,
index
);
return
ret
;
}
int
btrfs_finish_extent_commit
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
)
{
unsigned
long
gang
[
8
];
struct
inode
*
btree_inode
=
root
->
fs_info
->
btree_inode
;
u64
first
=
0
;
int
ret
;
int
i
;
...
...
@@ -348,9 +340,6 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
first
=
gang
[
0
];
for
(
i
=
0
;
i
<
ret
;
i
++
)
{
clear_radix_bit
(
pinned_radix
,
gang
[
i
]);
try_remove_page
(
btree_inode
->
i_mapping
,
gang
[
i
]
<<
(
PAGE_CACHE_SHIFT
-
btree_inode
->
i_blkbits
));
}
}
return
0
;
...
...
@@ -983,6 +972,7 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
break
;
if
(
wret
<
0
)
ret
=
wret
;
btrfs_btree_balance_dirty
(
root
);
}
for
(
i
=
0
;
i
<=
orig_level
;
i
++
)
{
if
(
path
->
nodes
[
i
])
{
...
...
fs/btrfs/hash.c
浏览文件 @
35b7e476
...
...
@@ -11,6 +11,7 @@
*/
#include <linux/types.h>
#include "hash.h"
#define DELTA 0x9E3779B9
static
void
TEA_transform
(
__u32
buf
[
2
],
__u32
const
in
[])
...
...
fs/btrfs/print-tree.c
浏览文件 @
35b7e476
#include <linux/module.h>
#include "ctree.h"
#include "disk-io.h"
#include "print-tree.h"
void
btrfs_print_leaf
(
struct
btrfs_root
*
root
,
struct
btrfs_leaf
*
l
)
{
...
...
fs/btrfs/super.c
浏览文件 @
35b7e476
...
...
@@ -18,14 +18,14 @@
#include "btrfs_inode.h"
#include "ioctl.h"
void
btrfs_fsinfo_release
(
struct
kobject
*
obj
)
static
void
btrfs_fsinfo_release
(
struct
kobject
*
obj
)
{
struct
btrfs_fs_info
*
fsinfo
=
container_of
(
obj
,
struct
btrfs_fs_info
,
kobj
);
kfree
(
fsinfo
);
}
struct
kobj_type
btrfs_fsinfo_ktype
=
{
st
atic
st
ruct
kobj_type
btrfs_fsinfo_ktype
=
{
.
release
=
btrfs_fsinfo_release
,
};
...
...
@@ -148,7 +148,6 @@ static void fill_inode_item(struct btrfs_inode_item *item,
BTRFS_I
(
inode
)
->
block_group
->
key
.
objectid
);
}
static
int
btrfs_update_inode
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
struct
inode
*
inode
)
...
...
@@ -251,6 +250,7 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry)
ret
=
btrfs_unlink_trans
(
trans
,
root
,
dir
,
dentry
);
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
btrfs_btree_balance_dirty
(
root
);
return
ret
;
}
...
...
@@ -324,6 +324,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
btrfs_free_path
(
path
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
ret
=
btrfs_end_transaction
(
trans
,
root
);
btrfs_btree_balance_dirty
(
root
);
if
(
ret
&&
!
err
)
err
=
ret
;
return
err
;
...
...
@@ -449,6 +450,7 @@ static void btrfs_delete_inode(struct inode *inode)
btrfs_free_inode
(
trans
,
root
,
inode
);
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
btrfs_btree_balance_dirty
(
root
);
return
;
no_delete:
clear_inode
(
inode
);
...
...
@@ -481,7 +483,7 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
return
ret
;
}
int
fixup_tree_root_location
(
struct
btrfs_root
*
root
,
static
int
fixup_tree_root_location
(
struct
btrfs_root
*
root
,
struct
btrfs_key
*
location
,
struct
btrfs_root
**
sub_root
)
{
...
...
@@ -512,7 +514,7 @@ int fixup_tree_root_location(struct btrfs_root *root,
return
0
;
}
int
btrfs_init_locked_inode
(
struct
inode
*
inode
,
void
*
p
)
static
int
btrfs_init_locked_inode
(
struct
inode
*
inode
,
void
*
p
)
{
struct
btrfs_iget_args
*
args
=
p
;
inode
->
i_ino
=
args
->
ino
;
...
...
@@ -520,15 +522,15 @@ int btrfs_init_locked_inode(struct inode *inode, void *p)
return
0
;
}
int
btrfs_find_actor
(
struct
inode
*
inode
,
void
*
opaque
)
static
int
btrfs_find_actor
(
struct
inode
*
inode
,
void
*
opaque
)
{
struct
btrfs_iget_args
*
args
=
opaque
;
return
(
args
->
ino
==
inode
->
i_ino
&&
args
->
root
==
BTRFS_I
(
inode
)
->
root
);
}
struct
inode
*
btrfs_iget_locked
(
struct
super_block
*
s
,
u64
objectid
,
struct
btrfs_root
*
root
)
st
atic
st
ruct
inode
*
btrfs_iget_locked
(
struct
super_block
*
s
,
u64
objectid
,
struct
btrfs_root
*
root
)
{
struct
inode
*
inode
;
struct
btrfs_iget_args
args
;
...
...
@@ -790,6 +792,7 @@ static void btrfs_dirty_inode(struct inode *inode)
btrfs_update_inode
(
trans
,
root
,
inode
);
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
btrfs_btree_balance_dirty
(
root
);
}
static
struct
inode
*
btrfs_new_inode
(
struct
btrfs_trans_handle
*
trans
,
...
...
@@ -913,6 +916,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
inode_dec_link_count
(
inode
);
iput
(
inode
);
}
btrfs_btree_balance_dirty
(
root
);
return
err
;
}
...
...
@@ -1002,6 +1006,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
if
(
drop_on_err
)
iput
(
inode
);
btrfs_btree_balance_dirty
(
root
);
return
err
;
}
...
...
@@ -1099,7 +1104,6 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
found_type
!=
BTRFS_EXTENT_DATA_KEY
)
{
extent_end
=
0
;
extent_start
=
0
;
btrfs_release_path
(
root
,
path
);
goto
out
;
}
found_type
=
btrfs_file_extent_type
(
item
);
...
...
@@ -1135,7 +1139,6 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
btrfs_map_bh_to_logical
(
root
,
result
,
0
);
}
out:
btrfs_release_path
(
root
,
path
);
btrfs_free_path
(
path
);
return
err
;
}
...
...
@@ -1231,13 +1234,13 @@ static int __btrfs_write_full_page(struct inode *inode, struct page *page,
}
else
if
(
!
buffer_mapped
(
bh
)
&&
buffer_dirty
(
bh
))
{
WARN_ON
(
bh
->
b_size
!=
blocksize
);
err
=
btrfs_get_block
(
inode
,
block
,
bh
,
0
);
if
(
err
)
if
(
err
)
{
printk
(
"writepage going to recovery err %d
\n
"
,
err
);
goto
recover
;
}
if
(
buffer_new
(
bh
))
{
/* blockdev mappings never come here */
clear_buffer_new
(
bh
);
unmap_underlying_metadata
(
bh
->
b_bdev
,
bh
->
b_blocknr
);
}
}
bh
=
bh
->
b_this_page
;
...
...
@@ -1303,11 +1306,6 @@ static int __btrfs_write_full_page(struct inode *inode, struct page *page,
if
(
uptodate
)
SetPageUptodate
(
page
);
end_page_writeback
(
page
);
/*
* The page and buffer_heads can be released at any time from
* here on.
*/
wbc
->
pages_skipped
++
;
/* We didn't write this page */
}
return
err
;
...
...
@@ -1409,10 +1407,11 @@ static void btrfs_truncate(struct inode *inode)
btrfs_set_trans_block_group
(
trans
,
inode
);
ret
=
btrfs_truncate_in_trans
(
trans
,
root
,
inode
);
BUG_ON
(
ret
);
btrfs_update_inode
(
trans
,
root
,
inode
);
ret
=
btrfs_end_transaction
(
trans
,
root
);
BUG_ON
(
ret
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
mark_inode_dirty
(
inode
);
btrfs_btree_balance_dirty
(
root
);
}
/*
...
...
@@ -1777,10 +1776,15 @@ static int prepare_pages(struct btrfs_root *root,
err
=
-
ENOMEM
;
goto
failed_release
;
}
cancel_dirty_page
(
pages
[
i
],
PAGE_CACHE_SIZE
);
wait_on_page_writeback
(
pages
[
i
]);
offset
=
pos
&
(
PAGE_CACHE_SIZE
-
1
);
this_write
=
min
(
PAGE_CACHE_SIZE
-
offset
,
write_bytes
);
create_empty_buffers
(
pages
[
i
],
root
->
fs_info
->
sb
->
s_blocksize
,
(
1
<<
BH_Uptodate
));
if
(
!
page_has_buffers
(
pages
[
i
]))
{
create_empty_buffers
(
pages
[
i
],
root
->
fs_info
->
sb
->
s_blocksize
,
(
1
<<
BH_Uptodate
));
}
head
=
page_buffers
(
pages
[
i
]);
bh
=
head
;
do
{
...
...
@@ -1820,7 +1824,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
struct
page
*
pages
[
8
];
struct
page
*
pinned
[
2
]
=
{
NULL
,
NULL
}
;
struct
page
*
pinned
[
2
];
unsigned
long
first_index
;
unsigned
long
last_index
;
u64
start_pos
;
...
...
@@ -1829,6 +1833,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_key
ins
;
pinned
[
0
]
=
NULL
;
pinned
[
1
]
=
NULL
;
if
(
file
->
f_flags
&
O_DIRECT
)
return
-
EINVAL
;
pos
=
*
ppos
;
...
...
@@ -1858,6 +1864,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
if
(
!
PageUptodate
(
pinned
[
0
]))
{
ret
=
mpage_readpage
(
pinned
[
0
],
btrfs_get_block
);
BUG_ON
(
ret
);
wait_on_page_locked
(
pinned
[
0
]);
}
else
{
unlock_page
(
pinned
[
0
]);
}
...
...
@@ -1869,6 +1876,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
if
(
!
PageUptodate
(
pinned
[
1
]))
{
ret
=
mpage_readpage
(
pinned
[
1
],
btrfs_get_block
);
BUG_ON
(
ret
);
wait_on_page_locked
(
pinned
[
1
]);
}
else
{
unlock_page
(
pinned
[
1
]);
}
...
...
@@ -1940,6 +1948,7 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
num_written
+=
write_bytes
;
balance_dirty_pages_ratelimited
(
inode
->
i_mapping
);
btrfs_btree_balance_dirty
(
root
);
cond_resched
();
}
out_unlock:
...
...
@@ -2165,6 +2174,7 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
iput
(
inode
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
btrfs_btree_balance_dirty
(
root
);
return
0
;
}
...
...
@@ -2220,6 +2230,7 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen)
ret
=
btrfs_commit_transaction
(
trans
,
root
);
BUG_ON
(
ret
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
btrfs_btree_balance_dirty
(
root
);
return
0
;
}
...
...
@@ -2295,6 +2306,7 @@ printk("insert failed %d\n", ret);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
out_nolock:
btrfs_free_path
(
path
);
btrfs_btree_balance_dirty
(
root
);
return
ret
;
}
...
...
fs/btrfs/transaction.c
浏览文件 @
35b7e476
...
...
@@ -199,8 +199,9 @@ struct dirty_root {
struct
btrfs_root
*
root
;
};
int
add_dirty_roots
(
struct
btrfs_trans_handle
*
trans
,
struct
radix_tree_root
*
radix
,
struct
list_head
*
list
)
static
int
add_dirty_roots
(
struct
btrfs_trans_handle
*
trans
,
struct
radix_tree_root
*
radix
,
struct
list_head
*
list
)
{
struct
dirty_root
*
dirty
;
struct
btrfs_root
*
gang
[
8
];
...
...
@@ -246,7 +247,8 @@ int add_dirty_roots(struct btrfs_trans_handle *trans,
return
0
;
}
int
drop_dirty_roots
(
struct
btrfs_root
*
tree_root
,
struct
list_head
*
list
)
static
int
drop_dirty_roots
(
struct
btrfs_root
*
tree_root
,
struct
list_head
*
list
)
{
struct
dirty_root
*
dirty
;
struct
btrfs_trans_handle
*
trans
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录