Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
22b0ebda
Commit
22b0ebda
authored
Mar 30, 2007
by
Chris Mason
Committed by
David Woodhouse
Mar 30, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Btrfs: hunting slab corruption
Signed-off-by:
Chris Mason
<
chris.mason@oracle.com
>
parent
f254e52c
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
27 additions
and
6 deletions
+27
-6
fs/btrfs/ctree.c
fs/btrfs/ctree.c
+2
-0
fs/btrfs/dir-item.c
fs/btrfs/dir-item.c
+2
-0
fs/btrfs/disk-io.c
fs/btrfs/disk-io.c
+13
-3
fs/btrfs/super.c
fs/btrfs/super.c
+6
-1
fs/btrfs/transaction.c
fs/btrfs/transaction.c
+4
-2
No files found.
fs/btrfs/ctree.c
View file @
22b0ebda
...
@@ -457,6 +457,8 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -457,6 +457,8 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
int
ret
;
int
ret
;
int
level
;
int
level
;
WARN_ON
(
p
->
nodes
[
0
]
!=
NULL
);
WARN_ON
(
!
mutex_is_locked
(
&
root
->
fs_info
->
fs_mutex
));
again:
again:
b
=
root
->
node
;
b
=
root
->
node
;
get_bh
(
b
);
get_bh
(
b
);
...
...
fs/btrfs/dir-item.c
View file @
22b0ebda
...
@@ -35,6 +35,8 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
...
@@ -35,6 +35,8 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
btrfs_set_dir_name_len
(
dir_item
,
name_len
);
btrfs_set_dir_name_len
(
dir_item
,
name_len
);
name_ptr
=
(
char
*
)(
dir_item
+
1
);
name_ptr
=
(
char
*
)(
dir_item
+
1
);
memcpy
(
name_ptr
,
name
,
name_len
);
memcpy
(
name_ptr
,
name
,
name_len
);
if
(
name_ptr
+
name_len
>
path
.
nodes
[
0
]
->
b_data
+
4096
)
WARN_ON
(
1
);
mark_buffer_dirty
(
path
.
nodes
[
0
]);
mark_buffer_dirty
(
path
.
nodes
[
0
]);
out:
out:
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
&
path
);
...
...
fs/btrfs/disk-io.c
View file @
22b0ebda
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
#include <linux/blkdev.h>
#include <linux/blkdev.h>
#include <linux/crypto.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <linux/scatterlist.h>
#include <linux/swap.h>
#include "ctree.h"
#include "ctree.h"
#include "disk-io.h"
#include "disk-io.h"
#include "transaction.h"
#include "transaction.h"
...
@@ -50,6 +51,8 @@ struct buffer_head *btrfs_find_tree_block(struct btrfs_root *root, u64 blocknr)
...
@@ -50,6 +51,8 @@ struct buffer_head *btrfs_find_tree_block(struct btrfs_root *root, u64 blocknr)
}
while
(
bh
!=
head
);
}
while
(
bh
!=
head
);
out_unlock:
out_unlock:
unlock_page
(
page
);
unlock_page
(
page
);
if
(
ret
)
touch_buffer
(
ret
);
page_cache_release
(
page
);
page_cache_release
(
page
);
return
ret
;
return
ret
;
}
}
...
@@ -65,6 +68,7 @@ struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root,
...
@@ -65,6 +68,7 @@ struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root,
struct
buffer_head
*
head
;
struct
buffer_head
*
head
;
struct
buffer_head
*
ret
=
NULL
;
struct
buffer_head
*
ret
=
NULL
;
u64
first_block
=
index
<<
(
PAGE_CACHE_SHIFT
-
blockbits
);
u64
first_block
=
index
<<
(
PAGE_CACHE_SHIFT
-
blockbits
);
page
=
grab_cache_page
(
mapping
,
index
);
page
=
grab_cache_page
(
mapping
,
index
);
if
(
!
page
)
if
(
!
page
)
return
NULL
;
return
NULL
;
...
@@ -89,6 +93,8 @@ struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root,
...
@@ -89,6 +93,8 @@ struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root,
}
while
(
bh
!=
head
);
}
while
(
bh
!=
head
);
out_unlock:
out_unlock:
unlock_page
(
page
);
unlock_page
(
page
);
if
(
ret
)
touch_buffer
(
ret
);
page_cache_release
(
page
);
page_cache_release
(
page
);
return
ret
;
return
ret
;
}
}
...
@@ -139,7 +145,7 @@ int btrfs_csum_data(struct btrfs_root * root, char *data, size_t len,
...
@@ -139,7 +145,7 @@ int btrfs_csum_data(struct btrfs_root * root, char *data, size_t len,
desc
.
flags
=
0
;
desc
.
flags
=
0
;
sg_init_one
(
&
sg
,
data
,
len
);
sg_init_one
(
&
sg
,
data
,
len
);
spin_lock
(
&
root
->
fs_info
->
hash_lock
);
spin_lock
(
&
root
->
fs_info
->
hash_lock
);
ret
=
crypto_hash_digest
(
&
desc
,
&
sg
,
len
,
result
);
ret
=
crypto_hash_digest
(
&
desc
,
&
sg
,
1
,
result
);
spin_unlock
(
&
root
->
fs_info
->
hash_lock
);
spin_unlock
(
&
root
->
fs_info
->
hash_lock
);
if
(
ret
)
{
if
(
ret
)
{
printk
(
"sha256 digest failed
\n
"
);
printk
(
"sha256 digest failed
\n
"
);
...
@@ -153,6 +159,7 @@ static int csum_tree_block(struct btrfs_root *root, struct buffer_head *bh,
...
@@ -153,6 +159,7 @@ static int csum_tree_block(struct btrfs_root *root, struct buffer_head *bh,
int
ret
;
int
ret
;
struct
btrfs_node
*
node
;
struct
btrfs_node
*
node
;
return
0
;
ret
=
btrfs_csum_data
(
root
,
bh
->
b_data
+
BTRFS_CSUM_SIZE
,
ret
=
btrfs_csum_data
(
root
,
bh
->
b_data
+
BTRFS_CSUM_SIZE
,
bh
->
b_size
-
BTRFS_CSUM_SIZE
,
result
);
bh
->
b_size
-
BTRFS_CSUM_SIZE
,
result
);
if
(
ret
)
if
(
ret
)
...
@@ -165,17 +172,17 @@ static int csum_tree_block(struct btrfs_root *root, struct buffer_head *bh,
...
@@ -165,17 +172,17 @@ static int csum_tree_block(struct btrfs_root *root, struct buffer_head *bh,
}
}
}
else
{
}
else
{
node
=
btrfs_buffer_node
(
bh
);
node
=
btrfs_buffer_node
(
bh
);
memcpy
(
&
node
->
header
.
csum
,
result
,
BTRFS_CSUM_SIZE
);
memcpy
(
node
->
header
.
csum
,
result
,
BTRFS_CSUM_SIZE
);
}
}
return
0
;
return
0
;
}
}
static
int
btree_writepage
(
struct
page
*
page
,
struct
writeback_control
*
wbc
)
static
int
btree_writepage
(
struct
page
*
page
,
struct
writeback_control
*
wbc
)
{
{
#if 0
struct buffer_head *bh;
struct buffer_head *bh;
struct btrfs_root *root = btrfs_sb(page->mapping->host->i_sb);
struct btrfs_root *root = btrfs_sb(page->mapping->host->i_sb);
struct buffer_head *head;
struct buffer_head *head;
if (!page_has_buffers(page)) {
if (!page_has_buffers(page)) {
create_empty_buffers(page, root->fs_info->sb->s_blocksize,
create_empty_buffers(page, root->fs_info->sb->s_blocksize,
(1 << BH_Dirty)|(1 << BH_Uptodate));
(1 << BH_Dirty)|(1 << BH_Uptodate));
...
@@ -187,6 +194,7 @@ static int btree_writepage(struct page *page, struct writeback_control *wbc)
...
@@ -187,6 +194,7 @@ static int btree_writepage(struct page *page, struct writeback_control *wbc)
csum_tree_block(root, bh, 0);
csum_tree_block(root, bh, 0);
bh = bh->b_this_page;
bh = bh->b_this_page;
} while (bh != head);
} while (bh != head);
#endif
return
block_write_full_page
(
page
,
btree_get_block
,
wbc
);
return
block_write_full_page
(
page
,
btree_get_block
,
wbc
);
}
}
...
@@ -312,6 +320,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
...
@@ -312,6 +320,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
fs_info
->
btree_inode
->
i_ino
=
1
;
fs_info
->
btree_inode
->
i_ino
=
1
;
fs_info
->
btree_inode
->
i_size
=
sb
->
s_bdev
->
bd_inode
->
i_size
;
fs_info
->
btree_inode
->
i_size
=
sb
->
s_bdev
->
bd_inode
->
i_size
;
fs_info
->
btree_inode
->
i_mapping
->
a_ops
=
&
btree_aops
;
fs_info
->
btree_inode
->
i_mapping
->
a_ops
=
&
btree_aops
;
insert_inode_hash
(
fs_info
->
btree_inode
);
mapping_set_gfp_mask
(
fs_info
->
btree_inode
->
i_mapping
,
GFP_NOFS
);
mapping_set_gfp_mask
(
fs_info
->
btree_inode
->
i_mapping
,
GFP_NOFS
);
fs_info
->
hash_tfm
=
crypto_alloc_hash
(
"sha256"
,
0
,
CRYPTO_ALG_ASYNC
);
fs_info
->
hash_tfm
=
crypto_alloc_hash
(
"sha256"
,
0
,
CRYPTO_ALG_ASYNC
);
spin_lock_init
(
&
fs_info
->
hash_lock
);
spin_lock_init
(
&
fs_info
->
hash_lock
);
...
...
fs/btrfs/super.c
View file @
22b0ebda
...
@@ -361,13 +361,16 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
...
@@ -361,13 +361,16 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
struct
nameidata
*
nd
)
struct
nameidata
*
nd
)
{
{
struct
inode
*
inode
;
struct
inode
*
inode
;
struct
btrfs_root
*
root
=
btrfs_sb
(
dir
->
i_sb
);
ino_t
ino
;
ino_t
ino
;
int
ret
;
int
ret
;
if
(
dentry
->
d_name
.
len
>
BTRFS_NAME_LEN
)
if
(
dentry
->
d_name
.
len
>
BTRFS_NAME_LEN
)
return
ERR_PTR
(
-
ENAMETOOLONG
);
return
ERR_PTR
(
-
ENAMETOOLONG
);
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
ret
=
btrfs_inode_by_name
(
dir
,
dentry
,
&
ino
);
ret
=
btrfs_inode_by_name
(
dir
,
dentry
,
&
ino
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ERR_PTR
(
ret
);
return
ERR_PTR
(
ret
);
inode
=
NULL
;
inode
=
NULL
;
...
@@ -395,6 +398,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
...
@@ -395,6 +398,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
unsigned
char
d_type
=
DT_UNKNOWN
;
unsigned
char
d_type
=
DT_UNKNOWN
;
int
over
=
0
;
int
over
=
0
;
mutex_lock
(
&
root
->
fs_info
->
fs_mutex
);
key
.
objectid
=
inode
->
i_ino
;
key
.
objectid
=
inode
->
i_ino
;
key
.
flags
=
0
;
key
.
flags
=
0
;
btrfs_set_key_type
(
&
key
,
BTRFS_DIR_ITEM_KEY
);
btrfs_set_key_type
(
&
key
,
BTRFS_DIR_ITEM_KEY
);
...
@@ -446,6 +450,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
...
@@ -446,6 +450,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
ret
=
0
;
ret
=
0
;
err:
err:
btrfs_release_path
(
root
,
&
path
);
btrfs_release_path
(
root
,
&
path
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
return
ret
;
return
ret
;
}
}
...
@@ -667,8 +672,8 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
...
@@ -667,8 +672,8 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
inode
->
i_op
=
&
btrfs_file_inode_operations
;
inode
->
i_op
=
&
btrfs_file_inode_operations
;
}
}
dir
->
i_sb
->
s_dirt
=
1
;
dir
->
i_sb
->
s_dirt
=
1
;
btrfs_end_transaction
(
trans
,
root
);
out_unlock:
out_unlock:
btrfs_end_transaction
(
trans
,
root
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
mutex_unlock
(
&
root
->
fs_info
->
fs_mutex
);
if
(
drop_inode
)
{
if
(
drop_inode
)
{
inode_dec_link_count
(
inode
);
inode_dec_link_count
(
inode
);
...
...
fs/btrfs/transaction.c
View file @
22b0ebda
...
@@ -197,8 +197,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
...
@@ -197,8 +197,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
ret
=
btrfs_del_root
(
trans
,
root
->
fs_info
->
tree_root
,
ret
=
btrfs_del_root
(
trans
,
root
->
fs_info
->
tree_root
,
&
snap_key
);
&
snap_key
);
BUG_ON
(
ret
);
root
->
fs_info
->
generation
=
root
->
root_key
.
offset
+
1
;
ret
=
btrfs_end_transaction
(
trans
,
root
);
BUG_ON
(
ret
);
BUG_ON
(
ret
);
printk
(
"at free, total trans %d
\n
"
,
total_trans
);
root
->
fs_info
->
generation
=
root
->
root_key
.
offset
+
1
;
ret
=
btrfs_end_transaction
(
trans
,
root
);
BUG_ON
(
ret
);
}
}
return
ret
;
return
ret
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment