Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiphi1978
linux
提交
3a686375
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,发现更多精彩内容 >>
提交
3a686375
编写于
5月 24, 2007
作者:
C
Chris Mason
提交者:
David Woodhouse
5月 24, 2007
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Btrfs: sparse files!
Signed-off-by:
N
Chris Mason
<
chris.mason@oracle.com
>
上级
2b8d99a7
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
116 addition
and
31 deletion
+116
-31
fs/btrfs/ctree.h
fs/btrfs/ctree.h
+1
-0
fs/btrfs/extent-tree.c
fs/btrfs/extent-tree.c
+10
-4
fs/btrfs/file-item.c
fs/btrfs/file-item.c
+6
-5
fs/btrfs/super.c
fs/btrfs/super.c
+99
-22
未找到文件。
fs/btrfs/ctree.h
浏览文件 @
3a686375
...
...
@@ -1180,6 +1180,7 @@ int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
int
btrfs_insert_file_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
objectid
,
u64
pos
,
u64
offset
,
u64
disk_num_blocks
,
u64
num_blocks
);
int
btrfs_lookup_file_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
...
...
fs/btrfs/extent-tree.c
浏览文件 @
3a686375
...
...
@@ -443,6 +443,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
buf_leaf
=
btrfs_buffer_leaf
(
buf
);
for
(
i
=
0
;
i
<
btrfs_header_nritems
(
&
buf_node
->
header
);
i
++
)
{
if
(
leaf
)
{
u64
disk_blocknr
;
key
=
&
buf_leaf
->
items
[
i
].
key
;
if
(
btrfs_disk_key_type
(
key
)
!=
BTRFS_EXTENT_DATA_KEY
)
continue
;
...
...
@@ -451,8 +452,10 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
if
(
btrfs_file_extent_type
(
fi
)
==
BTRFS_FILE_EXTENT_INLINE
)
continue
;
ret
=
btrfs_inc_extent_ref
(
trans
,
root
,
btrfs_file_extent_disk_blocknr
(
fi
),
disk_blocknr
=
btrfs_file_extent_disk_blocknr
(
fi
);
if
(
disk_blocknr
==
0
)
continue
;
ret
=
btrfs_inc_extent_ref
(
trans
,
root
,
disk_blocknr
,
btrfs_file_extent_disk_num_blocks
(
fi
));
BUG_ON
(
ret
);
}
else
{
...
...
@@ -1248,6 +1251,7 @@ static int drop_leaf_ref(struct btrfs_trans_handle *trans,
leaf
=
btrfs_buffer_leaf
(
cur
);
nritems
=
btrfs_header_nritems
(
&
leaf
->
header
);
for
(
i
=
0
;
i
<
nritems
;
i
++
)
{
u64
disk_blocknr
;
key
=
&
leaf
->
items
[
i
].
key
;
if
(
btrfs_disk_key_type
(
key
)
!=
BTRFS_EXTENT_DATA_KEY
)
continue
;
...
...
@@ -1258,8 +1262,10 @@ static int drop_leaf_ref(struct btrfs_trans_handle *trans,
* FIXME make sure to insert a trans record that
* repeats the snapshot del on crash
*/
ret
=
btrfs_free_extent
(
trans
,
root
,
btrfs_file_extent_disk_blocknr
(
fi
),
disk_blocknr
=
btrfs_file_extent_disk_blocknr
(
fi
);
if
(
disk_blocknr
==
0
)
continue
;
ret
=
btrfs_free_extent
(
trans
,
root
,
disk_blocknr
,
btrfs_file_extent_disk_num_blocks
(
fi
),
0
);
BUG_ON
(
ret
);
...
...
fs/btrfs/file-item.c
浏览文件 @
3a686375
...
...
@@ -9,7 +9,8 @@
int
btrfs_insert_file_extent
(
struct
btrfs_trans_handle
*
trans
,
struct
btrfs_root
*
root
,
u64
objectid
,
u64
pos
,
u64
offset
,
u64
num_blocks
)
u64
offset
,
u64
disk_num_blocks
,
u64
num_blocks
)
{
int
ret
=
0
;
struct
btrfs_file_extent_item
*
item
;
...
...
@@ -30,7 +31,7 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
item
=
btrfs_item_ptr
(
btrfs_buffer_leaf
(
path
->
nodes
[
0
]),
path
->
slots
[
0
],
struct
btrfs_file_extent_item
);
btrfs_set_file_extent_disk_blocknr
(
item
,
offset
);
btrfs_set_file_extent_disk_num_blocks
(
item
,
num_blocks
);
btrfs_set_file_extent_disk_num_blocks
(
item
,
disk_
num_blocks
);
btrfs_set_file_extent_offset
(
item
,
0
);
btrfs_set_file_extent_num_blocks
(
item
,
num_blocks
);
btrfs_set_file_extent_generation
(
item
,
trans
->
transid
);
...
...
@@ -176,14 +177,14 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
if
(
btrfs_key_type
(
&
found_key
)
!=
BTRFS_CSUM_ITEM_KEY
||
found_key
.
objectid
!=
objectid
||
csum_offset
>=
MAX_CSUM_ITEMS
(
root
))
{
WARN_ON
(
1
);
goto
insert
;
}
if
(
csum_offset
>=
btrfs_item_size
(
leaf
->
items
+
path
->
slots
[
0
])
/
BTRFS_CRC32_SIZE
)
{
u32
diff
=
(
csum_offset
+
1
)
*
BTRFS_CRC32_SIZE
;
diff
=
diff
-
btrfs_item_size
(
leaf
->
items
+
path
->
slots
[
0
]);
WARN_ON
(
diff
!=
BTRFS_CRC32_SIZE
);
if
(
diff
!=
BTRFS_CRC32_SIZE
)
goto
insert
;
ret
=
btrfs_extend_item
(
trans
,
root
,
path
,
diff
);
BUG_ON
(
ret
);
goto
csum
;
...
...
@@ -241,7 +242,7 @@ int btrfs_csum_verify_file_block(struct btrfs_root *root,
ret
=
PTR_ERR
(
item
);
/* a csum that isn't present is a preallocated region. */
if
(
ret
==
-
ENOENT
||
ret
==
-
EFBIG
)
ret
=
1
;
ret
=
-
ENOENT
;
goto
fail
;
}
...
...
fs/btrfs/super.c
浏览文件 @
3a686375
...
...
@@ -17,6 +17,7 @@
#include "transaction.h"
#include "btrfs_inode.h"
#include "ioctl.h"
#include "print-tree.h"
struct
btrfs_iget_args
{
u64
ino
;
...
...
@@ -421,14 +422,17 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
struct
btrfs_file_extent_item
);
if
(
btrfs_file_extent_type
(
fi
)
!=
BTRFS_FILE_EXTENT_INLINE
)
{
u64
num_dec
;
extent_start
=
btrfs_file_extent_disk_blocknr
(
fi
);
extent_num_blocks
=
btrfs_file_extent_disk_num_blocks
(
fi
);
/* FIXME blocksize != 4096 */
inode
->
i_blocks
-=
btrfs_file_extent_num_blocks
(
fi
)
<<
3
;
num_dec
=
btrfs_file_extent_num_blocks
(
fi
)
<<
3
;
if
(
extent_start
!=
0
)
{
found_extent
=
1
;
inode
->
i_blocks
-=
num_dec
;
}
}
}
ret
=
btrfs_del_item
(
trans
,
root
,
path
);
...
...
@@ -448,6 +452,43 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
return
ret
;
}
static
int
btrfs_setattr
(
struct
dentry
*
dentry
,
struct
iattr
*
attr
)
{
struct
inode
*
inode
=
dentry
->
d_inode
;
int
err
;
err
=
inode_change_ok
(
inode
,
attr
);
if
(
err
)
return
err
;
if
(
S_ISREG
(
inode
->
i_mode
)
&&
attr
->
ia_valid
&
ATTR_SIZE
&&
attr
->
ia_size
>
inode
->
i_size
)
{
struct
btrfs_trans_handle
*
trans
;
struct
btrfs_root
*
root
=
BTRFS_I
(
inode
)
->
root
;
u64
mask
=
root
->
blocksize
-
1
;
u64
pos
=
(
inode
->
i_size
+
mask
)
&
~
mask
;
u64
hole_size
;
if
(
attr
->
ia_size
<
pos
)
goto
out
;
hole_size
=
(
attr
->
ia_size
-
pos
+
mask
)
&
~
mask
;
hole_size
>>=
inode
->
i_blkbits
;
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
trans
=
btrfs_start_transaction
(
root
,
1
);
btrfs_set_trans_block_group
(
trans
,
inode
);
err
=
btrfs_insert_file_extent
(
trans
,
root
,
inode
->
i_ino
,
pos
,
0
,
0
,
hole_size
);
BUG_ON
(
err
);
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
}
err
=
inode_setattr
(
inode
,
attr
);
out:
return
err
;
}
static
void
btrfs_delete_inode
(
struct
inode
*
inode
)
{
struct
btrfs_trans_handle
*
trans
;
...
...
@@ -1169,8 +1210,10 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
if
(
found_type
==
BTRFS_FILE_EXTENT_REG
)
{
extent_start
=
extent_start
>>
inode
->
i_blkbits
;
extent_end
=
extent_start
+
btrfs_file_extent_num_blocks
(
item
);
if
(
iblock
>=
extent_start
&&
iblock
<
extent_end
)
{
err
=
0
;
if
(
blocknr
==
0
)
goto
out
;
if
(
iblock
>=
extent_start
&&
iblock
<
extent_end
)
{
btrfs_map_bh_to_logical
(
root
,
result
,
blocknr
+
iblock
-
extent_start
);
goto
out
;
...
...
@@ -1591,7 +1634,7 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
ptr
,
bh
->
b_data
,
offset
+
write_bytes
);
mark_buffer_dirty
(
path
->
nodes
[
0
]);
btrfs_free_path
(
path
);
}
else
{
}
else
if
(
buffer_mapped
(
bh
))
{
btrfs_csum_file_block
(
trans
,
root
,
inode
->
i_ino
,
pages
[
i
]
->
index
<<
PAGE_CACHE_SHIFT
,
kmap
(
pages
[
i
]),
PAGE_CACHE_SIZE
);
...
...
@@ -1693,16 +1736,25 @@ static int drop_extents(struct btrfs_trans_handle *trans,
goto
out
;
}
if
(
found_inline
)
{
u64
mask
=
root
->
blocksize
-
1
;
search_start
=
(
extent_end
+
mask
)
&
~
mask
;
}
else
search_start
=
extent_end
;
if
(
end
<
extent_end
&&
end
>=
key
.
offset
)
{
if
(
found_extent
)
{
u64
disk_blocknr
=
btrfs_file_extent_disk_blocknr
(
extent
);
u64
disk_num_blocks
=
btrfs_file_extent_disk_num_blocks
(
extent
);
memcpy
(
&
old
,
extent
,
sizeof
(
old
));
if
(
disk_blocknr
!=
0
)
{
ret
=
btrfs_inc_extent_ref
(
trans
,
root
,
btrfs_file_extent_disk_blocknr
(
&
old
),
btrfs_file_extent_disk_num_blocks
(
&
old
));
disk_blocknr
,
disk_num_blocks
);
BUG_ON
(
ret
);
}
}
WARN_ON
(
found_inline
);
bookend
=
1
;
}
...
...
@@ -1719,7 +1771,10 @@ static int drop_extents(struct btrfs_trans_handle *trans,
old_num
=
btrfs_file_extent_num_blocks
(
extent
);
*
hint_block
=
btrfs_file_extent_disk_blocknr
(
extent
);
inode
->
i_blocks
-=
(
old_num
-
new_num
)
<<
3
;
if
(
btrfs_file_extent_disk_blocknr
(
extent
))
{
inode
->
i_blocks
-=
(
old_num
-
new_num
)
<<
3
;
}
btrfs_set_file_extent_num_blocks
(
extent
,
new_num
);
mark_buffer_dirty
(
path
->
nodes
[
0
]);
...
...
@@ -1745,7 +1800,7 @@ static int drop_extents(struct btrfs_trans_handle *trans,
BUG_ON
(
ret
);
btrfs_release_path
(
root
,
path
);
extent
=
NULL
;
if
(
found_extent
)
{
if
(
found_extent
&&
disk_blocknr
!=
0
)
{
inode
->
i_blocks
-=
extent_num_blocks
<<
3
;
ret
=
btrfs_free_extent
(
trans
,
root
,
disk_blocknr
,
...
...
@@ -1785,18 +1840,19 @@ static int drop_extents(struct btrfs_trans_handle *trans,
btrfs_file_extent_offset
(
&
old
)
+
((
end
-
key
.
offset
)
>>
inode
->
i_blkbits
));
WARN_ON
(
btrfs_file_extent_num_blocks
(
&
old
)
<
(
e
nd
-
key
.
offset
)
>>
inode
->
i_blkbits
);
(
e
xtent_end
-
end
)
>>
inode
->
i_blkbits
);
btrfs_set_file_extent_num_blocks
(
extent
,
btrfs_file_extent_num_blocks
(
&
old
)
-
((
end
-
key
.
offset
)
>>
inode
->
i_blkbits
));
(
extent_end
-
end
)
>>
inode
->
i_blkbits
);
btrfs_set_file_extent_type
(
extent
,
BTRFS_FILE_EXTENT_REG
);
btrfs_set_file_extent_generation
(
extent
,
btrfs_file_extent_generation
(
&
old
));
btrfs_mark_buffer_dirty
(
path
->
nodes
[
0
]);
if
(
btrfs_file_extent_disk_blocknr
(
&
old
)
!=
0
)
{
inode
->
i_blocks
+=
btrfs_file_extent_num_blocks
(
extent
)
<<
3
;
}
ret
=
0
;
goto
out
;
}
...
...
@@ -1960,6 +2016,21 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
~
((
u64
)
root
->
blocksize
-
1
),
&
hint_block
);
BUG_ON
(
ret
);
}
if
(
inode
->
i_size
<
start_pos
)
{
u64
last_pos_in_file
;
u64
hole_size
;
u64
mask
=
root
->
blocksize
-
1
;
last_pos_in_file
=
(
inode
->
i_size
+
mask
)
&
~
mask
;
hole_size
=
(
start_pos
-
last_pos_in_file
+
mask
)
&
~
mask
;
hole_size
>>=
inode
->
i_blkbits
;
if
(
last_pos_in_file
<
start_pos
)
{
ret
=
btrfs_insert_file_extent
(
trans
,
root
,
inode
->
i_ino
,
last_pos_in_file
,
0
,
0
,
hole_size
);
}
BUG_ON
(
ret
);
}
if
(
inode
->
i_size
>=
PAGE_CACHE_SIZE
||
pos
+
count
<
inode
->
i_size
||
pos
+
count
-
start_pos
>
BTRFS_MAX_INLINE_DATA_SIZE
(
root
))
{
ret
=
btrfs_alloc_extent
(
trans
,
root
,
inode
->
i_ino
,
...
...
@@ -1967,7 +2038,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
&
ins
,
1
);
BUG_ON
(
ret
);
ret
=
btrfs_insert_file_extent
(
trans
,
root
,
inode
->
i_ino
,
start_pos
,
ins
.
objectid
,
ins
.
offset
);
start_pos
,
ins
.
objectid
,
ins
.
offset
,
ins
.
offset
);
BUG_ON
(
ret
);
}
else
{
ins
.
offset
=
0
;
...
...
@@ -2044,10 +2116,13 @@ static int btrfs_read_actor(read_descriptor_t *desc, struct page *page,
page
->
index
<<
PAGE_CACHE_SHIFT
,
kmap
(
page
),
PAGE_CACHE_SIZE
);
if
(
ret
)
{
if
(
ret
!=
-
ENOENT
)
{
printk
(
"failed to verify ino %lu page %lu
\n
"
,
page
->
mapping
->
host
->
i_ino
,
page
->
index
);
memset
(
page_address
(
page
),
0
,
PAGE_CACHE_SIZE
);
flush_dcache_page
(
page
);
}
}
SetPageChecked
(
page
);
kunmap
(
page
);
...
...
@@ -2759,6 +2834,7 @@ static struct inode_operations btrfs_dir_inode_operations = {
.
rmdir
=
btrfs_rmdir
,
.
rename
=
btrfs_rename
,
.
symlink
=
btrfs_symlink
,
.
setattr
=
btrfs_setattr
,
};
static
struct
inode_operations
btrfs_dir_ro_inode_operations
=
{
...
...
@@ -2788,6 +2864,7 @@ static struct address_space_operations btrfs_symlink_aops = {
static
struct
inode_operations
btrfs_file_inode_operations
=
{
.
truncate
=
btrfs_truncate
,
.
getattr
=
btrfs_getattr
,
.
setattr
=
btrfs_setattr
,
};
static
struct
file_operations
btrfs_file_operations
=
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录