summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2012-11-28 16:12:41 +0900
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2012-12-11 13:43:42 +0900
commit25ca923b2a766b9c93b63777ead351137533a623 (patch)
tree6414cd58a9573177310a9f0ccfdfaca9cf45eb70
parentcf0e3a64cad19acd5904946d0647d751c1671620 (diff)
f2fs: fix endian conversion bugs reported by sparse
This patch should resolve the bugs reported by the sparse tool. Initial reports were written by "kbuild test robot" managed by fengguang.wu. In my local machines, I've tested also by running: > make C=2 CF="-D__CHECK_ENDIAN__" Accordingly, I've found lots of warnings and bugs related to the endian conversion. And I've fixed all at this moment. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
-rw-r--r--fs/f2fs/checkpoint.c32
-rw-r--r--fs/f2fs/data.c2
-rw-r--r--fs/f2fs/debug.c2
-rw-r--r--fs/f2fs/dir.c8
-rw-r--r--fs/f2fs/f2fs.h25
-rw-r--r--fs/f2fs/hash.c3
-rw-r--r--fs/f2fs/node.c4
-rw-r--r--fs/f2fs/node.h2
-rw-r--r--fs/f2fs/recovery.c2
-rw-r--r--fs/f2fs/segment.c14
-rw-r--r--fs/f2fs/super.c8
-rw-r--r--include/linux/f2fs_fs.h6
12 files changed, 65 insertions, 43 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index ab743f92ee06..7c18f8efaadc 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -268,7 +268,7 @@ int recover_orphan_inodes(struct f2fs_sb_info *sbi)
{
block_t start_blk, orphan_blkaddr, i, j;
- if (!(F2FS_CKPT(sbi)->ckpt_flags & CP_ORPHAN_PRESENT_FLAG))
+ if (!is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ORPHAN_PRESENT_FLAG))
return 0;
sbi->por_doing = 1;
@@ -287,7 +287,7 @@ int recover_orphan_inodes(struct f2fs_sb_info *sbi)
f2fs_put_page(page, 1);
}
/* clear Orphan Flag */
- F2FS_CKPT(sbi)->ckpt_flags &= (~CP_ORPHAN_PRESENT_FLAG);
+ clear_ckpt_flags(F2FS_CKPT(sbi), CP_ORPHAN_PRESENT_FLAG);
sbi->por_doing = 0;
return 0;
}
@@ -376,7 +376,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
pre_version = le64_to_cpu(cp_block->checkpoint_ver);
/* Read the 2nd cp block in this CP pack */
- cp_addr += le64_to_cpu(cp_block->cp_pack_total_block_count) - 1;
+ cp_addr += le32_to_cpu(cp_block->cp_pack_total_block_count) - 1;
cp_page_2 = get_meta_page(sbi, cp_addr);
cp_block = (struct f2fs_checkpoint *)page_address(cp_page_2);
@@ -605,8 +605,8 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
block_t start_blk;
struct page *cp_page;
unsigned int data_sum_blocks, orphan_blocks;
+ unsigned int crc32 = 0;
void *kaddr;
- __u32 crc32 = 0;
int i;
/* Flush all the NAT/SIT pages */
@@ -646,33 +646,35 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
/* 2 cp + n data seg summary + orphan inode blocks */
data_sum_blocks = npages_for_summary_flush(sbi);
if (data_sum_blocks < 3)
- ckpt->ckpt_flags |= CP_COMPACT_SUM_FLAG;
+ set_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG);
else
- ckpt->ckpt_flags &= (~CP_COMPACT_SUM_FLAG);
+ clear_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG);
orphan_blocks = (sbi->n_orphans + F2FS_ORPHANS_PER_BLOCK - 1)
/ F2FS_ORPHANS_PER_BLOCK;
- ckpt->cp_pack_start_sum = 1 + orphan_blocks;
- ckpt->cp_pack_total_block_count = 2 + data_sum_blocks + orphan_blocks;
+ ckpt->cp_pack_start_sum = cpu_to_le32(1 + orphan_blocks);
if (is_umount) {
- ckpt->ckpt_flags |= CP_UMOUNT_FLAG;
- ckpt->cp_pack_total_block_count += NR_CURSEG_NODE_TYPE;
+ set_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
+ ckpt->cp_pack_total_block_count = cpu_to_le32(2 +
+ data_sum_blocks + orphan_blocks + NR_CURSEG_NODE_TYPE);
} else {
- ckpt->ckpt_flags &= (~CP_UMOUNT_FLAG);
+ clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
+ ckpt->cp_pack_total_block_count = cpu_to_le32(2 +
+ data_sum_blocks + orphan_blocks);
}
if (sbi->n_orphans)
- ckpt->ckpt_flags |= CP_ORPHAN_PRESENT_FLAG;
+ set_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG);
else
- ckpt->ckpt_flags &= (~CP_ORPHAN_PRESENT_FLAG);
+ clear_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG);
/* update SIT/NAT bitmap */
get_sit_bitmap(sbi, __bitmap_ptr(sbi, SIT_BITMAP));
get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP));
crc32 = f2fs_crc32(ckpt, le32_to_cpu(ckpt->checksum_offset));
- *(__u32 *)((unsigned char *)ckpt +
+ *(__le32 *)((unsigned char *)ckpt +
le32_to_cpu(ckpt->checksum_offset))
= cpu_to_le32(crc32);
@@ -716,7 +718,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
sbi->alloc_valid_block_count = 0;
/* Here, we only have one bio having CP pack */
- if (sbi->ckpt->ckpt_flags & CP_ERROR_FLAG)
+ if (is_set_ckpt_flags(ckpt, CP_ERROR_FLAG))
sbi->sb->s_flags |= MS_RDONLY;
else
sync_meta_pages(sbi, META_FLUSH, LONG_MAX);
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index c2fd0a80db16..5635cc5a9d4d 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -545,7 +545,7 @@ redirty_out:
#define MAX_DESIRED_PAGES_WP 4096
-int f2fs_write_data_pages(struct address_space *mapping,
+static int f2fs_write_data_pages(struct address_space *mapping,
struct writeback_control *wbc)
{
struct inode *inode = mapping->host;
diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
index a56181c1b28b..fb62960a1dc1 100644
--- a/fs/f2fs/debug.c
+++ b/fs/f2fs/debug.c
@@ -27,7 +27,7 @@
static LIST_HEAD(f2fs_stat_list);
static struct dentry *debugfs_root;
-void update_general_status(struct f2fs_sb_info *sbi)
+static void update_general_status(struct f2fs_sb_info *sbi)
{
struct f2fs_stat_info *si = sbi->stat_info;
int i;
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index 5975568d03df..5ec7a06120e1 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -80,7 +80,7 @@ static bool early_match_name(const char *name, int namelen,
if (le16_to_cpu(de->name_len) != namelen)
return false;
- if (le32_to_cpu(de->hash_code) != namehash)
+ if (de->hash_code != namehash)
return false;
return true;
@@ -143,7 +143,7 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir,
nbucket = dir_buckets(level);
nblock = bucket_blocks(level);
- bidx = dir_block_index(level, namehash % nbucket);
+ bidx = dir_block_index(level, le32_to_cpu(namehash) % nbucket);
end_block = bidx + nblock;
for (; bidx < end_block; bidx++) {
@@ -406,7 +406,7 @@ start:
nbucket = dir_buckets(level);
nblock = bucket_blocks(level);
- bidx = dir_block_index(level, (dentry_hash % nbucket));
+ bidx = dir_block_index(level, (le32_to_cpu(dentry_hash) % nbucket));
for (block = bidx; block <= (bidx + nblock - 1); block++) {
mutex_lock_op(sbi, DENTRY_OPS);
@@ -437,7 +437,7 @@ add_dentry:
wait_on_page_writeback(dentry_page);
de = &dentry_blk->dentry[bit_pos];
- de->hash_code = cpu_to_le32(dentry_hash);
+ de->hash_code = dentry_hash;
de->name_len = cpu_to_le16(namelen);
memcpy(dentry_blk->filename[bit_pos], name, namelen);
de->ino = cpu_to_le32(inode->i_ino);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index d3f5a70e2a49..8d7fde1bda1e 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -463,6 +463,26 @@ static inline void F2FS_RESET_SB_DIRT(struct f2fs_sb_info *sbi)
sbi->s_dirty = 0;
}
+static inline bool is_set_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f)
+{
+ unsigned int ckpt_flags = le32_to_cpu(cp->ckpt_flags);
+ return ckpt_flags & f;
+}
+
+static inline void set_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f)
+{
+ unsigned int ckpt_flags = le32_to_cpu(cp->ckpt_flags);
+ ckpt_flags |= f;
+ cp->ckpt_flags = cpu_to_le32(ckpt_flags);
+}
+
+static inline void clear_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f)
+{
+ unsigned int ckpt_flags = le32_to_cpu(cp->ckpt_flags);
+ ckpt_flags &= (~f);
+ cp->ckpt_flags = cpu_to_le32(ckpt_flags);
+}
+
static inline void mutex_lock_op(struct f2fs_sb_info *sbi, enum lock_type t)
{
mutex_lock_nested(&sbi->fs_lock[t], t);
@@ -577,7 +597,8 @@ static inline unsigned long __bitmap_size(struct f2fs_sb_info *sbi, int flag)
static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag)
{
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
- int offset = (flag == NAT_BITMAP) ? ckpt->sit_ver_bitmap_bytesize : 0;
+ int offset = (flag == NAT_BITMAP) ?
+ le32_to_cpu(ckpt->sit_ver_bitmap_bytesize) : 0;
return &ckpt->sit_nat_version_bitmap + offset;
}
@@ -587,7 +608,7 @@ static inline block_t __start_cp_addr(struct f2fs_sb_info *sbi)
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
unsigned long long ckpt_version = le64_to_cpu(ckpt->checkpoint_ver);
- start_addr = le64_to_cpu(F2FS_RAW_SUPER(sbi)->cp_blkaddr);
+ start_addr = le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_blkaddr);
/*
* odd numbered checkpoint should at cp segment 0
diff --git a/fs/f2fs/hash.c b/fs/f2fs/hash.c
index 098a1963d7c7..beb155e8d06d 100644
--- a/fs/f2fs/hash.c
+++ b/fs/f2fs/hash.c
@@ -92,7 +92,6 @@ f2fs_hash_t f2fs_dentry_hash(const char *name, int len)
hash = buf[0];
minor_hash = buf[1];
- f2fs_hash = hash;
- f2fs_hash &= ~F2FS_HASH_COL_BIT;
+ f2fs_hash = cpu_to_le32(hash & ~F2FS_HASH_COL_BIT);
return f2fs_hash;
}
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 216f04dc1177..5d421fe22575 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1445,8 +1445,8 @@ int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
memcpy(dst, src, (unsigned long)&src->i.i_ext - (unsigned long)&src->i);
dst->i.i_size = 0;
- dst->i.i_blocks = 1;
- dst->i.i_links = 1;
+ dst->i.i_blocks = cpu_to_le64(1);
+ dst->i.i_links = cpu_to_le32(1);
dst->i.i_xattr_nid = 0;
new_ni = old_ni;
diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h
index 5d525ed312ba..0ab92d643052 100644
--- a/fs/f2fs/node.h
+++ b/fs/f2fs/node.h
@@ -177,7 +177,7 @@ static inline void fill_node_footer_blkaddr(struct page *page, block_t blkaddr)
void *kaddr = page_address(page);
struct f2fs_node *rn = (struct f2fs_node *)kaddr;
rn->footer.cp_ver = ckpt->checkpoint_ver;
- rn->footer.next_blkaddr = blkaddr;
+ rn->footer.next_blkaddr = cpu_to_le32(blkaddr);
}
static inline nid_t ino_of_node(struct page *node_page)
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 7a43df0b72c1..222a7bb92214 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -81,7 +81,7 @@ static int recover_inode(struct inode *inode, struct page *node_page)
struct f2fs_node *raw_node = (struct f2fs_node *)kaddr;
struct f2fs_inode *raw_inode = &(raw_node->i);
- inode->i_mode = le32_to_cpu(raw_inode->i_mode);
+ inode->i_mode = le16_to_cpu(raw_inode->i_mode);
i_size_write(inode, le64_to_cpu(raw_inode->i_size));
inode->i_atime.tv_sec = le64_to_cpu(raw_inode->i_mtime);
inode->i_ctime.tv_sec = le64_to_cpu(raw_inode->i_ctime);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index ed7c079cfc7f..d973c56e8bd6 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -630,7 +630,7 @@ static void f2fs_end_io_write(struct bio *bio, int err)
SetPageError(page);
if (page->mapping)
set_bit(AS_EIO, &page->mapping->flags);
- p->sbi->ckpt->ckpt_flags |= CP_ERROR_FLAG;
+ set_ckpt_flags(p->sbi->ckpt, CP_ERROR_FLAG);
set_page_dirty(page);
}
end_page_writeback(page);
@@ -1067,7 +1067,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
segno = le32_to_cpu(ckpt->cur_data_segno[type]);
blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type -
CURSEG_HOT_DATA]);
- if (ckpt->ckpt_flags & CP_UMOUNT_FLAG)
+ if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
blk_addr = sum_blk_addr(sbi, NR_CURSEG_TYPE, type);
else
blk_addr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, type);
@@ -1076,7 +1076,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
CURSEG_HOT_NODE]);
blk_off = le16_to_cpu(ckpt->cur_node_blkoff[type -
CURSEG_HOT_NODE]);
- if (ckpt->ckpt_flags & CP_UMOUNT_FLAG)
+ if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
blk_addr = sum_blk_addr(sbi, NR_CURSEG_NODE_TYPE,
type - CURSEG_HOT_NODE);
else
@@ -1087,7 +1087,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
sum = (struct f2fs_summary_block *)page_address(new);
if (IS_NODESEG(type)) {
- if (ckpt->ckpt_flags & CP_UMOUNT_FLAG) {
+ if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG)) {
struct f2fs_summary *ns = &sum->entries[0];
int i;
for (i = 0; i < sbi->blocks_per_seg; i++, ns++) {
@@ -1119,7 +1119,7 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
{
int type = CURSEG_HOT_DATA;
- if (sbi->ckpt->ckpt_flags & CP_COMPACT_SUM_FLAG) {
+ if (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_COMPACT_SUM_FLAG)) {
/* restore for compacted data summary */
if (read_compacted_summaries(sbi))
return -EINVAL;
@@ -1208,7 +1208,7 @@ static void write_normal_summaries(struct f2fs_sb_info *sbi,
void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
{
- if (sbi->ckpt->ckpt_flags & CP_COMPACT_SUM_FLAG)
+ if (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_COMPACT_SUM_FLAG))
write_compacted_summaries(sbi, start_blk);
else
write_normal_summaries(sbi, start_blk, CURSEG_HOT_DATA);
@@ -1216,7 +1216,7 @@ void write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
void write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk)
{
- if (sbi->ckpt->ckpt_flags & CP_UMOUNT_FLAG)
+ if (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_UMOUNT_FLAG))
write_normal_summaries(sbi, start_blk, CURSEG_HOT_NODE);
return;
}
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 8661c93538af..878bf382f848 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -89,7 +89,7 @@ static void f2fs_i_callback(struct rcu_head *head)
kmem_cache_free(f2fs_inode_cachep, F2FS_I(inode));
}
-void f2fs_destroy_inode(struct inode *inode)
+static void f2fs_destroy_inode(struct inode *inode)
{
call_rcu(&inode->i_rcu, f2fs_i_callback);
}
@@ -445,7 +445,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
if (sanity_check_raw_super(raw_super))
goto free_sb_buf;
- sb->s_maxbytes = max_file_size(raw_super->log_blocksize);
+ sb->s_maxbytes = max_file_size(le32_to_cpu(raw_super->log_blocksize));
sb->s_max_links = F2FS_LINK_MAX;
get_random_bytes(&sbi->s_next_generation, sizeof(u32));
@@ -527,7 +527,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
/* if there are nt orphan nodes free them */
err = -EINVAL;
- if (!(sbi->ckpt->ckpt_flags & CP_UMOUNT_FLAG) &&
+ if (!is_set_ckpt_flags(F2FS_CKPT(sbi), CP_UMOUNT_FLAG) &&
recover_orphan_inodes(sbi))
goto free_node_inode;
@@ -547,7 +547,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
}
/* recover fsynced data */
- if (!(sbi->ckpt->ckpt_flags & CP_UMOUNT_FLAG) &&
+ if (!is_set_ckpt_flags(F2FS_CKPT(sbi), CP_UMOUNT_FLAG) &&
!test_opt(sbi, DISABLE_ROLL_FORWARD))
recover_fsync_data(sbi);
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index 1429ece7caab..c2fbbc35c1e6 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -272,8 +272,8 @@ struct f2fs_sit_block {
* ex) data_blkaddr = (block_t)(nodepage_start_address + ofs_in_node)
*/
#define ENTRIES_IN_SUM 512
-#define SUMMARY_SIZE (sizeof(struct f2fs_summary))
-#define SUM_FOOTER_SIZE (sizeof(struct summary_footer))
+#define SUMMARY_SIZE (7) /* sizeof(struct summary) */
+#define SUM_FOOTER_SIZE (5) /* sizeof(struct summary_footer) */
#define SUM_ENTRY_SIZE (SUMMARY_SIZE * ENTRIES_IN_SUM)
/* a summary entry for a 4KB-sized block in a segment */
@@ -297,7 +297,7 @@ struct summary_footer {
__u32 check_sum; /* summary checksum */
} __packed;
-#define SUM_JOURNAL_SIZE (PAGE_CACHE_SIZE - SUM_FOOTER_SIZE -\
+#define SUM_JOURNAL_SIZE (F2FS_BLKSIZE - SUM_FOOTER_SIZE -\
SUM_ENTRY_SIZE)
#define NAT_JOURNAL_ENTRIES ((SUM_JOURNAL_SIZE - 2) /\
sizeof(struct nat_journal_entry))