Ext3
code review regarding 64bit block number
Author: Laurent Vivier <Laurent.Vivier@bull.net>
Status: Draft
Last Modification: 2005/06/20
Copyright (c) 2005 Bull S.A.
RED shows fields that
should be changed to
address 64bit block number.
ORANGE shows fields that
should be changed if
we want to count blocks on a 64bit value (for instance, number of
blocks in a partition)
GREEN
shows fields we should add.
1. ON-DISK structures
1.1.
include/linux/ext3_fs.h
1.1.1. SuperBlock
struct
ext3_super_block {
/*00*/
__le32
s_inodes_count;
/*
Inodes count */
__le32
s_blocks_count;
/*
Blocks count */
__le32
s_r_blocks_count;
/*
Reserved blocks count */
__le32 s_free_blocks_count; /*
Free blocks
count */
These
fields count the total number of block in a partition.
If partition is big enough to address block using 64bit values,
we can have a total number of block (a counter) on 64bit. |
/*10*/
__le32
s_free_inodes_count; /* Free inodes count
*/
__le32
s_first_data_block; /* First
Data Block */
| s_first_data_block
should remain __le32 : its value is ever 0
or 1. |
__le32
s_log_block_size;
/*
Block size */
__le32
s_log_frag_size;
/* Fragment size */
/*20*/
__le32
s_blocks_per_group; /* # Blocks
per group */
__le32
s_frags_per_group; /*
#
Fragments per group */
__le32
s_inodes_per_group; /* # Inodes
per group */
blocks,
frags and inodes per group
are limited by the bitmap size.
64bit counter should not
be needed. |
__le32
s_mtime;
/* Mount time */
/*30*/
__le32
s_wtime;
/* Write time */
__le16
s_mnt_count;
/* Mount count */
__le16
s_max_mnt_count;
/* Maximal mount count */
__le16
s_magic;
/* Magic signature */
__le16
s_state;
/* File system state */
__le16
s_errors;
/* Behaviour when detecting errors */
__le16
s_minor_rev_level; /*
minor
revision level */
/*40*/
__le32
s_lastcheck;
/* time of last check */
__le32
s_checkinterval;
/* max. time between checks */
__le32
s_creator_os;
/* OS */
__le32
s_rev_level;
/* Revision level */
/*50*/
__le16
s_def_resuid;
/* Default uid for reserved blocks */
__le16
s_def_resgid;
/* Default gid for reserved blocks */
__le32
s_first_ino;
/* First non-reserved inode */
__le16 s_inode_size;
/* size of
inode structure */
| See struct ext3_inode for
comment |
__le16
s_block_group_nr;
/*
block group # of this superblock */
Numbers of block in a
group is
8 x numbers_of_bits_in_a_block.
With
4096 bytes block, we can manage 32768 (215)
blocks in a
group,
and thus maximum size of a group is 32768 x 4096 = 128 MiB,
and
if the maximum number of blocks in a partition is 232
( = 16
TiB filesystem size with 4Ki block size), the needed number
of block
is 232/ 215
= 232-15
= 217
= 131072 groups.
If
we have a 64 bit disk, maximum number of groups is
264/ 215
= 264-15
= 249
|
__le32
s_feature_compat;
/*
compatible feature set */
/*60*/
__le32
s_feature_incompat; /*
incompatible feature set
*/
__le32 s_feature_ro_compat; /*
readonly-compatible feature set */
/*68*/
__u8
s_uuid[16];
/* 128-bit uuid for volume */
/*78*/
char
s_volume_name[16];
/* volume name */
/*88*/
char
s_last_mounted[64]; /*
directory where last mounted */
/*C8*/
__le32
s_algorithm_usage_bitmap; /* For compression */
__u8
s_prealloc_blocks;
/* Nr of blocks to try to preallocate*/
__u8 s_prealloc_dir_blocks; /*
Nr to
preallocate for dirs */
__u16 s_reserved_gdt_blocks; /* Per group
desc for
online growth */
/*D0*/
__u8
s_journal_uuid[16]; /*
uuid of journal superblock */
/*E0*/
__le32
s_journal_inum;
/*
inode number of journal file */
__le32
s_journal_dev;
/*
device number of journal file */
__le32
s_last_orphan;
/*
start of list of inodes to delete */
__le32
s_hash_seed[4];
/*
HTREE hash seed */
__u8
s_def_hash_version; /*
Default hash version to use */
__u8 s_reserved_char_pad;
__u16 s_reserved_word_pad;
__le32 s_default_mount_opts;
__le32
s_first_meta_bg;
/* First metablock block group */
/*FC*/
__u32
s_reserved[190];
/* Padding
to the end of the block */
};
should become:
struct
ext3_super_block {
/*00*/
__le32
s_inodes_count;
/*
Inodes count */
__le32
s_blocks_count;
/*
Blocks count */
__le32
s_r_blocks_count;
/*
Reserved blocks count */
__le32 s_free_blocks_count; /*
Free blocks
count */
/*10*/
__le32 s_free_inodes_count; /*
Free inodes
count */
__le32
s_first_data_block; /* First
Data
Block */
__le32
s_log_block_size;
/*
Block size */
__le32
s_log_frag_size;
/* Fragment size */
/*20*/
__le32
s_blocks_per_group; /* # Blocks
per group */
__le32
s_frags_per_group; /*
#
Fragments per group */
__le32
s_inodes_per_group; /* # Inodes
per group */
__le32
s_mtime;
/* Mount time */
/*30*/
__le32
s_wtime;
/* Write time */
__le16
s_mnt_count;
/* Mount count */
__le16
s_max_mnt_count;
/* Maximal mount count */
__le16
s_magic;
/* Magic signature */
__le16
s_state;
/* File system state */
__le16
s_errors;
/* Behaviour when detecting errors */
__le16
s_minor_rev_level; /*
minor
revision level */
/*40*/
__le32
s_lastcheck;
/* time of last check */
__le32
s_checkinterval;
/* max. time between checks */
__le32
s_creator_os;
/* OS */
__le32
s_rev_level;
/* Revision level */
/*50*/
__le16
s_def_resuid;
/* Default uid for reserved blocks */
__le16
s_def_resgid;
/* Default gid for reserved blocks */
__le32
s_first_ino;
/* First non-reserved inode */
__le16
s_inode_size;
/*
size of inode structure */
__le16
s_block_group_nr;
/*
block group # of this superblock */
__le32
s_feature_compat;
/*
compatible feature set */
/*60*/
__le32
s_feature_incompat; /*
incompatible feature set
*/
__le32 s_feature_ro_compat; /*
readonly-compatible feature set */
/*68*/
__u8
s_uuid[16];
/* 128-bit uuid for volume */
/*78*/
char
s_volume_name[16];
/* volume name */
/*88*/
char
s_last_mounted[64]; /*
directory where last mounted */
/*C8*/
__le32
s_algorithm_usage_bitmap; /* For compression */
__u8
s_prealloc_blocks;
/* Nr of blocks to try to preallocate*/
__u8 s_prealloc_dir_blocks; /*
Nr to
preallocate for dirs */
__u16 s_reserved_gdt_blocks; /* Per group
desc for
online growth */
/*D0*/
__u8
s_journal_uuid[16]; /*
uuid of journal superblock */
/*E0*/
__le32
s_journal_inum;
/*
inode number of journal file */
__le32
s_journal_dev;
/*
device number of journal file */
__le32
s_last_orphan;
/*
start of list of inodes to delete */
__le32
s_hash_seed[4];
/*
HTREE hash seed */
/*F0*/
__u8
s_def_hash_version; /*
Default hash version to use */
__u8 s_reserved_char_pad;
__u16 s_reserved_word_pad;
__le32 s_default_mount_opts;
__le32
s_first_meta_bg;
/* First metablock block group */
/*FC*/
__le32
s_hi_blocks_count;
/*
Blocks count */
__le32
s_hi_r_blocks_count;
/* Reserved blocks count */
__le32 s_hi_free_blocks_count;
/* Free blocks
count */
__le32
s_hi_block_group_nr;
/*
block group # of this superblock */
/*10C*/
__u32
s_reserved[180];
/* Padding
to the end of the block */
};
If we want to reduce structure size, we could let s_block_group_nr to le16 as it seems it is only
used for debug purpose.
1.1.2. Group Descriptor
struct
ext3_group_desc
{
__le32
bg_block_bitmap;
/* Blocks bitmap block */
__le32
bg_inode_bitmap;
/* Inodes bitmap block */
__le32
bg_inode_table;
/*
Inodes table block */
__le16 bg_free_blocks_count; /* Free
blocks count */
__le16 bg_free_inodes_count; /* Free
inodes count */
__le16
bg_used_dirs_count; /*
Directories
count */
__u16 bg_pad;
__le32 bg_reserved[3];
};
should become:
struct
ext3_group_desc
{
__le32
bg_block_bitmap;
/* Blocks bitmap block */
__le32
bg_inode_bitmap;
/* Inodes bitmap block */
__le32
bg_inode_table;
/*
Inodes table block */
__le16 bg_free_blocks_count; /* Free
blocks count */
__le16 bg_free_inodes_count; /* Free
inodes count */
__le16
bg_used_dirs_count; /*
Directories
count */
__u16 bg_pad;
__le32
bg_hi_block_bitmap; /* Blocks
bitmap block */
__le32
bg_hi_inode_bitmap; /* Inodes
bitmap block */
__le32
bg_hi_inode_table; /*
Inodes
table block */
};
If we don't want to store high bits for all these fields, we can use a
relative addressing mode to the group base address.
For instance, if bg_block_bitmap
is lesser than the base address of the group, we add the base address
to this 32bit value.
And according to Andreas Dilger, we should swap to the METABG layout:
"A quick calculation shows
that the group descriptor table itself
will become too large to store in the first group before the filesystem
grows to 512TB:
<2^15 blocks/group * 2^12 bytes/block / 32 bytes/gdt <
2^22 gdt/group
2^15 blocks/group * 2^12 bytes/block * 2^22 group = 2^49 bytes = 512TB
This means at or before 512TB we will have to go to the METABG layout
to store the group descriptors in their respective groups, so we may
as well do this at 16TB and just do as you propose.
"
1.1.3. Inode
struct ext3_inode {
/*00*/
__le16
i_mode;
/* File mode */
__le16
i_uid;
/* Low 16
bits of Owner Uid */
__le32
i_size;
/* Size in
bytes */
__le32
i_atime;
/* Access time */
__le32
i_ctime;
/* Creation time */
/*10*/
__le32
i_mtime;
/* Modification time
*/
__le32
i_dtime;
/* Deletion Time */
__le16
i_gid;
/* Low 16
bits of Group Id */
__le16
i_links_count; /* Links count */
__le32
i_blocks;
/* Blocks count */
/*20*/
__le32
i_flags;
/* File flags */
union {
struct {
__u32 l_i_reserved1;
} linux1;
struct {
__u32 h_i_translator;
} hurd1;
struct {
__u32 m_i_reserved1;
} masix1;
}
osd1;
/* OS dependent 1 */
/*28*/
__le32
i_block[EXT3_N_BLOCKS];/*
Pointers to blocks */
/*64*/
__le32
i_generation; /* File version (for NFS) */
__le32
i_file_acl; /* File ACL */
__le32
i_dir_acl; /*
Directory ACL */
i_size
and i_dir_acl are used to
define a 64bit i_size
(in fs/ext3/inode.c, ext3_read_inode()) |
/*70*/
__le32
i_faddr;
/* Fragment address
*/
| This fields (and
following) seems not
used in linux. |
union {
struct {
__u8
l_i_frag;
/*
Fragment number */
__u8
l_i_fsize; /*
Fragment size */
__u16 i_pad1;
__le16 l_i_uid_high; /* these 2
fields */
__le16 l_i_gid_high; /* were reserved2[0]
*/
__u32 l_i_reserved2;
} linux2;
struct {
__u8
h_i_frag;
/*
Fragment number */
__u8
h_i_fsize; /*
Fragment size */
__u16 h_i_mode_high;
__u16 h_i_uid_high;
__u16 h_i_gid_high;
__u32 h_i_author;
} hurd2;
struct {
__u8
m_i_frag;
/*
Fragment number */
__u8
m_i_fsize; /*
Fragment size */
__u16 m_pad1;
__u32 m_i_reserved2[2];
} masix2;
}
osd2;
/* OS dependent 2 */
/*80*/
__le16 i_extra_isize;
__le16 i_pad1;
/*84*/};
WE SHOULD USE DYNAMIC INODE
SIZE TO STORE 64BIT BLOCK NUMBER
(i_extra_size)
or
SHOULD BE BASED ON EXTENTS
PATCH (use 48bit block number)
struct
ext3_inode {
/*00*/
__le16
i_mode;
/* File mode */
__le16
i_uid;
/* Low 16
bits of Owner Uid */
__le32
i_size;
/* Size in
bytes */
__le32
i_atime;
/* Access time */
__le32
i_ctime;
/* Creation time */
/*10*/
__le32
i_mtime;
/* Modification time
*/
__le32
i_dtime;
/* Deletion Time */
__le16
i_gid;
/* Low 16
bits of Group Id */
__le16
i_links_count; /* Links count */
__le32
i_blocks;
/* Blocks count */
/*20*/
__le32
i_flags;
/* File flags */
union {
struct {
__u32 l_i_reserved1;
} linux1;
struct {
__u32 h_i_translator;
} hurd1;
struct {
__u32 m_i_reserved1;
} masix1;
}
osd1;
/* OS dependent 1 */
/*28*/
__le32
i_block[EXT3_N_BLOCKS];/*
Pointers to blocks */
/*64*/
__le32
i_generation; /* File version (for NFS) */
__le32
i_file_acl; /* File ACL */
__le32
i_dir_acl; /*
Directory ACL */
/*70*/
__le32
i_faddr;
/* Fragment address
*/
union {
struct {
__u8
l_i_frag;
/*
Fragment number */
__u8
l_i_fsize; /*
Fragment size */
__u16 i_pad1;
__le16 l_i_uid_high; /* these 2
fields */
__le16 l_i_gid_high; /* were reserved2[0]
*/
__u32 l_i_reserved2;
} linux2;
struct {
__u8
h_i_frag;
/*
Fragment number */
__u8
h_i_fsize; /*
Fragment size */
__u16 h_i_mode_high;
__u16 h_i_uid_high;
__u16 h_i_gid_high;
__u32 h_i_author;
} hurd2;
struct {
__u8
m_i_frag;
/*
Fragment number */
__u8
m_i_fsize; /*
Fragment size */
__u16 m_pad1;
__u32 m_i_reserved2[2];
} masix2;
}
osd2;
/* OS dependent 2 */
/*80*/
__le16 i_extra_isize;
__le16 i_pad1;
/*84*/
__le32
i_hi_blocks;
/* Blocks count */
__le32 i_hi_block[EXT3_N_BLOCKS];/*
Pointers to blocks */
/*C0*/};
could impact superblock s_inode_size
field.
If we use extents patch, we don't need to increase inode size:
- block extend pointers are
stored in original i_block
space
- i_blocks (64) can be stored
in i_blocks
(32) and i_faddr (32)
or l_i_frag
(8) and l_i_fsize
(8)
1.1.4. New Group
struct ext3_new_group_input {
__u32
group;
/* Group number for this data */
__u32 block_bitmap; /* Absolute
block number of
block bitmap */
__u32 inode_bitmap; /* Absolute
block number of
inode bitmap */
__u32 inode_table; /*
Absolute block
number of inode table start */
__u32
blocks_count; /* Total number
of blocks in this
group */
__u16 reserved_blocks;
/* Number of reserved blocks in this group */
__u16 unused;
};
struct
ext3_new_group_data {
__u32 group;
__u32 block_bitmap;
__u32 inode_bitmap;
__u32 inode_table;
__u32 blocks_count;
__u16 reserved_blocks;
__u16 unused;
__u32 free_blocks_count;
};
As a size of a group is limited by the size of the bitmap block,
blocks_count and free_blocks_count
can stay a __u32.
These structures are used in an ioctl(), the best solution to keep
compatibility is to define new 64bit structure and new ioctl() calls.
struct
ext3_new_group_input64 {
__u32
group;
/* Group number for this data */
__u64 block_bitmap; /* Absolute
block number of
block bitmap */
__u64 inode_bitmap; /* Absolute
block number of
inode bitmap */
__u64 inode_table; /*
Absolute block
number of inode table start */
__u32
blocks_count; /* Total number
of blocks in this
group */
__u16 reserved_blocks;
/* Number of reserved blocks in this group */
__u16 unused;
};
struct
ext3_new_group_data64 {
__u32 group;
__u64 block_bitmap;
__u64 inode_bitmap;
__u64 inode_table;
__u32 blocks_count;
__u16 reserved_blocks;
__u16 unused;
__u32 free_blocks_count;
};
and we should define a new
iocl command:
#define EXT3_IOC_GROUP_ADD64
_IOW('f', 9,struct ext3_new_group_input64)
2. IN-MEMORY structures
2.1.
include/linux/ext3_fs_i.h
struct
ext3_reserve_window
{
__u32
_rsv_start; /* First byte
reserved */
__u32
_rsv_end;
/* Last byte reserved or
0 */
};
struct
ext3_inode_info {
__le32
i_data[15]; /* unconverted */
__u32 i_flags;
#ifdef
EXT3_FRAGMENTS
__u32
i_faddr;
__u8
i_frag_no;
__u8
i_frag_size;
#endif
__u32 i_file_acl;
__u32 i_dir_acl;
__u32 i_dtime;
__u32
i_block_group;
__u32
i_state;
/* Dynamic state flags for ext3 */
__u32
i_next_alloc_block;
__u32 i_next_alloc_goal;
struct
ext3_reserve_window_node i_rsv_window;
| Size of
i_rsv_window changes according to ext3_reserve_window node |
__u32
i_dir_start_lookup;
#ifdef
CONFIG_EXT3_FS_XATTR
struct rw_semaphore
xattr_sem;
#endif
#ifdef
CONFIG_EXT3_FS_POSIX_ACL
struct
posix_acl
*i_acl;
struct
posix_acl
*i_default_acl;
#endif
struct list_head
i_orphan; /* unlinked
but open inodes */
loff_t i_disksize;
/* on-disk additional length
*/
__u16 i_extra_isize;
struct semaphore
truncate_sem;
struct inode vfs_inode;
};
should become
struct
ext3_reserve_window
{
sector_t
_rsv_start; /* First byte
reserved */
sector_t
_rsv_end;
/* Last byte reserved or
0 */
};
struct
ext3_inode_info {
__le32
i_data[15]; /* unconverted */
__u32 i_flags;
#ifdef
EXT3_FRAGMENTS
sector_t
i_faddr;
__u8
i_frag_no;
__u8
i_frag_size;
#endif
__u32 i_file_acl;
__u32 i_dir_acl;
__u32 i_dtime;
group_t
i_block_group;
__u32
i_state;
/* Dynamic state flags for ext3 */
sector_t
i_next_alloc_block;
sector_t
i_next_alloc_goal;
struct
ext3_reserve_window_node i_rsv_window;
__u32
i_dir_start_lookup;
#ifdef
CONFIG_EXT3_FS_XATTR
struct rw_semaphore
xattr_sem;
#endif
#ifdef
CONFIG_EXT3_FS_POSIX_ACL
struct
posix_acl
*i_acl;
struct
posix_acl
*i_default_acl;
#endif
struct list_head
i_orphan; /* unlinked
but open inodes */
loff_t i_disksize;
/* on-disk additional length
*/
__u16 i_extra_isize;
struct semaphore
truncate_sem;
struct inode vfs_inode;
};
2.2.
include/linux/ext3_fs_sb.h
struct
ext3_sb_info {
unsigned long
s_frag_size; /* Size
of a
fragment in bytes */
unsigned long s_frags_per_block;/* Number of fragments per block */
unsigned long s_inodes_per_block;/* Number of inodes per block */
unsigned long s_frags_per_group;/* Number of fragments in a group */
unsigned long s_blocks_per_group;/* Number of blocks in a group */
unsigned long s_inodes_per_group;/* Number of inodes in a group */
unsigned long s_itb_per_group; /* Number of inode table
blocks
per group */
unsigned long
s_gdb_count; /*
Number of
group descriptor blocks */
unsigned long s_desc_per_block; /* Number of group descriptors per
block */
unsigned long s_groups_count; /* Number of groups
in the fs
*/
struct buffer_head * s_sbh; /*
Buffer
containing the super block */
struct ext3_super_block * s_es; /* Pointer to the super block in the
buffer */
struct buffer_head ** s_group_desc;
unsigned long s_mount_opt;
uid_t s_resuid;
gid_t s_resgid;
unsigned short s_mount_state;
unsigned short s_pad;
int s_addr_per_block_bits;
int s_desc_per_block_bits;
int s_inode_size;
int s_first_ino;
spinlock_t s_next_gen_lock;
u32 s_next_generation;
u32 s_hash_seed[4];
int s_def_hash_version;
struct percpu_counter s_freeblocks_counter;
struct percpu_counter s_freeinodes_counter;
struct percpu_counter s_dirs_counter;
should
manage sector_t type.
struct blockgroup_lock s_blockgroup_lock;
/* root of the per fs reservation window tree */
spinlock_t s_rsv_window_lock;
struct rb_root s_rsv_window_root;
struct ext3_reserve_window_node s_rsv_window_head;
/* Journaling */
struct inode * s_journal_inode;
struct journal_s * s_journal;
struct list_head s_orphan;
unsigned long s_commit_interval;
struct block_device *journal_bdev;
#ifdef
CONFIG_JBD_DEBUG
struct timer_list
turn_ro_timer;
/* For turning
read-only (crash
simulation)
*/
wait_queue_head_t
ro_wait_queue;
/* For people
waiting for the fs to go read-only */
#endif
#ifdef
CONFIG_QUOTA
char
*s_qf_names[MAXQUOTAS];
/* Names of quota files with journalled quota */
int
s_jquota_fmt;
/* Format of quota to use */
#endif
};
should
become
struct
ext3_sb_info {
unsigned long
s_frag_size; /* Size
of a
fragment in bytes */
unsigned long s_frags_per_block;/* Number of fragments per block */
unsigned long s_inodes_per_block;/* Number of inodes per block */
unsigned long s_frags_per_group;/* Number of fragments in a group */
unsigned long s_blocks_per_group;/* Number of blocks in a group */
unsigned long s_inodes_per_group;/* Number of inodes in a group */
unsigned long s_itb_per_group; /* Number of inode table
blocks
per group */
unsigned long
s_gdb_count; /*
Number of
group descriptor blocks */
unsigned long s_desc_per_block; /* Number of group descriptors per
block */
group_t
s_groups_count; /* Number of groups
in the fs
*/
struct buffer_head * s_sbh; /*
Buffer
containing the super block */
struct ext3_super_block * s_es; /* Pointer to the super block in the
buffer */
struct buffer_head ** s_group_desc;
unsigned long s_mount_opt;
uid_t s_resuid;
gid_t s_resgid;
unsigned short s_mount_state;
unsigned short s_pad;
int s_addr_per_block_bits;
int s_desc_per_block_bits;
int s_inode_size;
int s_first_ino;
spinlock_t s_next_gen_lock;
u32 s_next_generation;
u32 s_hash_seed[4];
int s_def_hash_version;
struct percpu_counter s_freeblocks_counter;
struct percpu_counter s_freeinodes_counter;
struct percpu_counter s_dirs_counter;
struct blockgroup_lock s_blockgroup_lock;
/* root of the per fs reservation window tree */
spinlock_t s_rsv_window_lock;
struct rb_root s_rsv_window_root;
struct ext3_reserve_window_node s_rsv_window_head;
/* Journaling */
struct inode * s_journal_inode;
struct journal_s * s_journal;
struct list_head s_orphan;
unsigned long s_commit_interval;
struct block_device *journal_bdev;
#ifdef
CONFIG_JBD_DEBUG
struct timer_list
turn_ro_timer;
/* For turning
read-only (crash simulation)
*/
wait_queue_head_t
ro_wait_queue;
/* For people
waiting for the fs to go read-only */
#endif
#ifdef
CONFIG_QUOTA
char
*s_qf_names[MAXQUOTAS];
/* Names of quota files with journalled quota */
int
s_jquota_fmt;
/* Format of quota to use */
#endif
};
2.3.
include/linux/percpu_counter.h
Add a 64bit compatible version of "percpu_counter".
#ifdef
CONFIG_SMP
struct
percpu_counter {
spinlock_t lock;
long
count;
long
*counters;
};
...
#else
...
struct
percpu_counter {
long
count;
};
should become
#ifdef
CONFIG_SMP
struct
percpu_counter {
spinlock_t lock;
#ifdef CONFIG_LBD
long
long count;
long
long *counters;
#else
long count;
long *counters;
#endif
};
...
#else
...
struct
percpu_counter {
#ifdef CONFIG_LBD
long
long count;
#else
long count;
#endif
};
3. Functions
3.1. Helpers
We use some functions inspired by JBD 64bit support patch by Zach Brown in "jbd and 64 bit block numbers"
at http://sourceforge.net/mailarchive/message.php?msg_id=9996513
void
ext3_write_split_le64(struct super_block * sb, __le32 *hi, __le32
*lo, u64 val)
{
*low =
cpu_to_le32(val & (u32)~0);
if
(EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_64BIT))
*high =
cpu_to_le32(val >> 32);
}
u64
ext3_read_split_le64(struct
super_block * sb, __le32 *hi, __le32 *lo)
{
u64 ret = le32_to_cpu(*low);
if
(EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_64BIT))
ret |=
(u64)le32_to_cpu(*high) << 32;
return ret;
} |
We use "sector_t" as defined in "include/asm-<arch>/types.h". It should be "u64" if "CONFIG_LBD" is defined,
"unsigned long" otherwise (see "include/linux/types.h").
We should define "group_t" to count the number of groups (see 1.1.1.), based on "CONFIG_LBD" too.
3.2. fs/ext3/acl.c
N/A
3.3. fs/ext3/acl.h
N/A
3.4. fs/ext3/balloc.c
3.4.1. ext3_get_group_desc()
block_group,
group_desc
and desc
are group numbers and thus should become "group_t".
struct
ext3_group_desc * ext3_get_group_desc(struct super_block * sb,
unsigned
int block_group,
struct buffer_head ** bh)
{
unsigned
long group_desc;
unsigned
long desc;
struct ext3_group_desc * gdp;
if (block_group >= EXT3_SB(sb)->s_groups_count) {
ext3_error (sb, "ext3_get_group_desc",
"block_group >= groups_count - "
"block_group = %d,
groups_count = %lu",
block_group, EXT3_SB(sb)->s_groups_count);
...
ext3_error (sb, "ext3_get_group_desc",
"Group descriptor not loaded - "
"block_group = %d,
group_desc = %lu,
desc = %lu",
block_group, group_desc, desc);
...
|
should become
struct ext3_group_desc *
ext3_get_group_desc(struct super_block * sb,
group_t
block_group,
struct buffer_head ** bh)
{
group_t
group_desc;
group_t
desc;
struct ext3_group_desc * gdp;
if (block_group >= EXT3_SB(sb)->s_groups_count) {
ext3_error (sb, "ext3_get_group_desc",
"block_group >= groups_count - "
"block_group = %lld,
groups_count = %llu",
(unsigned
long long)block_group,
(unsigned
long long)EXT3_SB(sb)->s_groups_count);
...
ext3_error (sb, "ext3_get_group_desc",
"Group descriptor not loaded - "
"block_group = %lld,
group_desc = %llu,
desc = %llu",
(unsigned
long long)block_group,
(unsigned
long long)group_desc,
(unsigned
long long)desc);
... |
3.4.1. read_block_bitmap()
block_group
is a block group number (group_t)
and bg_block_bitmap
is a sector number (sector_t).
static struct
buffer_head *
read_block_bitmap(struct
super_block *sb, unsigned int
block_group)
...
bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
if (!bh)
ext3_error (sb, "read_block_bitmap",
"Cannot read block bitmap - "
"block_group = %d,
block_bitmap = %u",
block_group, le32_to_cpu(desc->bg_block_bitmap)); |
should become
static struct
buffer_head *
read_block_bitmap(struct
super_block *sb, group_t
block_group)
...
bh = sb_bread(sb, ext3_read_split_le64(sb,
desc->bg_hi_block_bitmap,
desc->bg_block_bitmap));
if (!bh)
ext3_error (sb, "read_block_bitmap",
"Cannot read block bitmap - "
"block_group = %lld,
block_bitmap = %llu",
(unsigned
long long)block_group,
ext3_read_split_le64(sb,
desc->bg_hi_block_bitmap,
desc->bg_block_bitmap)); |
3.4.2. goal_in_my_reservation()
goal is a group relative block number (if there is a goal), 0 <
goal
< EXT3_BLOCKS_PER_GROUP(sb)
but
| unsigned
long group_first_block, group_last_block; |
should become
| group_t
group_first_block, group_last_block; |
3.4.3. search_reserve_window()
Find the reserved window which includes the sector "goal"
(sector_t).
| static
struct ext3_reserve_window_node
*search_reserve_window(struct rb_root *root, unsigned long goal) |
should become
| static
struct ext3_reserve_window_node
*search_reserve_window(struct rb_root *root, sector_t goal) |
3.4.4. ext3_rsv_window_add()
_rsv_start
in ext3_reserve_window
is now "sector_t",
so start
should become "sector_t".
| unsigned
int start =
rsv->rsv_start; |
should become
| sector_t start =
rsv->rsv_start; |
3.4.6. rsv_window_remove()
N/A
3.4.7. rsv_is_empty()
N/A
3.4.8.
ext3_discard_reservation()
N/A
3.4.9. ext3_free_blocks_sb()
void
ext3_free_blocks_sb(handle_t *handle, struct super_block *sb,
unsigned
long
block, unsigned long count,
int *pdquot_freed_blocks)
...
unsigned long
block_group;
unsigned long
i;
unsigned long
overflow;
...
if (block < le32_to_cpu(es->s_first_data_block)
||
block + count < block ||
block + count > le32_to_cpu(es->s_blocks_count))
{
ext3_error (sb, "ext3_free_blocks",
"Freeing blocks not in datazone - "
"block = %lu,
count = %lu",
block, count);
goto error_return;
}
ext3_debug ("freeing block %lu\n",
block);
...
block_group = (block - le32_to_cpu(es->s_first_data_block))
/
EXT3_BLOCKS_PER_GROUP(sb);
bit = (block - le32_to_cpu(es->s_first_data_block))
%
EXT3_BLOCKS_PER_GROUP(sb);
...
if (in_range (le32_to_cpu(gdp->bg_block_bitmap),
block, count) ||
in_range (le32_to_cpu(gdp->bg_inode_bitmap),
block, count) ||
in_range (block, le32_to_cpu(gdp->bg_inode_table),
EXT3_SB(sb)->s_itb_per_group) ||
in_range (block + count - 1, le32_to_cpu(gdp->bg_inode_table),
EXT3_SB(sb)->s_itb_per_group))
ext3_error (sb, "ext3_free_blocks",
"Freeing blocks in system zones - "
"Block = %lu,
count = %lu",
block, count);
|
should become
void
ext3_free_blocks_sb(handle_t *handle, struct super_block *sb,
sector_t block, sector_t count,
int *pdquot_freed_blocks)
...
group_t
block_group;
sector_t
i;
sector_t
overflow;
...
if (block < le32_to_cpu(es->s_first_data_block) ||
block + count < block ||
block + count > ext3_read_split_le64(sb, es->s_hi_blocks_count,
es->s_blocks_count)) {
ext3_error (sb, "ext3_free_blocks",
"Freeing blocks not in datazone - "
"block = %llu,
count = %llu",
(unsigned
long long)block,
(unsigned
long long)count);
goto error_return;
}
ext3_debug ("freeing block %llu\n",
(unsigned long long)block);
...
block_group = (block - le32_to_cpu(es->s_first_data_block))
/
EXT3_BLOCKS_PER_GROUP(sb);
bit = (block - le32_to_cpu(es->s_first_data_block)) %
EXT3_BLOCKS_PER_GROUP(sb);
...
if (in_range (ext3_read_split_le64(sb, gdp->bg_hi_block_bitmap,
gdp->bg_block_bitmap), block, count) ||
in_range (ext3_read_split_le64(sb, gdp->bg_hi_inode_bitmap,
gdp->bg_inode_bitmap), block, count) ||
in_range (block, ext3_read_split_le64(sb, gdp->bg_hi_inode_table,
gdp->bg_inode_table),
EXT3_SB(sb)->s_itb_per_group) ||
in_range (block + count - 1, ext3_read_split_le64(sb,
gdp->bg_hi_inode_table,
gdp->bg_inode_table),
EXT3_SB(sb)->s_itb_per_group))
ext3_error (sb, "ext3_free_blocks",
"Freeing blocks in system zones - "
"Block = %llu,
count = %llu",
(unsigned
long long)block,
(unsigned
long long)count); |
3.4.10. ext3_free_blocks()
void
ext3_free_blocks(handle_t *handle,
struct inode *inode,
unsigned long
block,
unsigned long count)
|
should become
void
ext3_free_blocks(handle_t *handle,
struct inode *inode,
sector_t
block,
sector_t count) |
3.4.11. ext3_test_allocatable()
N/A
3.4.12.
bitmap_search_next_usable_block()
N/A
3.4.13.
find_next_usable_block()
start,
here
and next
are relative to the begin
of the block group, and should stay "int".
3.4.14. claim_block()
block
is block group relative.
3.4.15. ext3_try_to_allocate()
int
group_first_block, start,
end;
|
should become
sector_t
group_first_block;
int start, end;
|
start
and end
are block group relative.
3.4.16.
find_next_reservable_window()
static struct
ext3_reserve_window_node *find_next_reservable_window(
struct ext3_reserve_window_node *search_head,
unsigned long size, int *start_block,
int last_block)
...
int cur;
... |
should become
static struct
ext3_reserve_window_node
*find_next_reservable_window(
struct ext3_reserve_window_node *search_head,
unsigned long size, sector_t
*start_block,
sector_t
last_block)
...
sector_t
cur;
... |
"size"
is initialized from
an atomic_t
and must be
lower than EXT3_MAX_RESERVE_BLOCKS
(1024).
3.4.17. alloc_new_reservation()
static int
alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
int goal, struct super_block *sb,
unsigned
int group,
struct buffer_head *bitmap_bh)
...
int
group_first_block, group_end_block, start_block;
int
first_free_block;
int
reservable_space_start;
...
|
should become
static int
alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
int goal, struct super_block *sb,
group_t
group,
struct buffer_head *bitmap_bh)
...
sector_t
group_first_block, group_end_block, start_block;
sector_t first_free_block;
sector_t reservable_space_start;
...
|
"goal"
is group relative.
3.4.18.
ext3_try_to_allocate_with_rsv()
static int
ext3_try_to_allocate_with_rsv(struct
super_block *sb, handle_t *handle,
unsigned
int group, struct
buffer_head *bitmap_bh,
int goal, struct ext3_reserve_window_node * my_rsv,
int *errp)
...
unsigned
long group_first_block;
...
|
should become
static int
ext3_try_to_allocate_with_rsv(struct
super_block *sb, handle_t *handle,
group_t group, struct
buffer_head *bitmap_bh,
int goal, struct ext3_reserve_window_node * my_rsv,
int *errp)
...
sector_t group_first_block;
...
|
"goal"
is group relative.
3.4.19. ext3_has_free_blocks()
int free_blocks,
root_blocks;
...
root_blocks
= le32_to_cpu(sbi->s_es->s_r_blocks_count); |
should become
sector_t
free_blocks,
root_blocks;
...
root_blocks
= ext3_read_split_le64(sb,
sbi->s_es->s_hi_r_blocks_count,
sbi->s_es->s_r_blocks_count); |
3.4.20.
ext3_should_retry_alloc()
N/A
3.4.21. ext3_new_block()
int
ext3_new_block(handle_t *handle,
struct inode *inode,
unsigned
long goal, int
*errp)
...
int group_no;
int goal_group;
int
ret_block;
int
bgi;
int
target_block;
...
unsigned
long ngroups;
...
if
(goal < le32_to_cpu(es->s_first_data_block)
||
goal
>= le32_to_cpu(es->s_blocks_count))
goal = le32_to_cpu(es->s_first_data_block);
group_no
= (goal - le32_to_cpu(es->s_first_data_block))
/
EXT3_BLOCKS_PER_GROUP(sb);
...
ext3_debug("using
block
group %d(%d)\n",
group_no, gdp->bg_free_blocks_count);
...
if
(target_block == le32_to_cpu(gdp->bg_block_bitmap)
||
target_block == le32_to_cpu(gdp->bg_inode_bitmap)
||
in_range(target_block, le32_to_cpu(gdp->bg_inode_table),
EXT3_SB(sb)->s_itb_per_group))
ext3_error(sb, "ext3_new_block",
"Allocating block in system zone - "
"block = %u",
target_block);
...
ext3_debug("found
bit %d\n",
ret_block);
...
if
(ret_block >= le32_to_cpu(es->s_blocks_count))
{
ext3_error(sb, "ext3_new_block",
"block(%d)
>= blocks
count(%d)
- "
"block_group = %d,
es == %p
", ret_block,
le32_to_cpu(es->s_blocks_count),
group_no, es);
...
ext3_debug("allocating
block %d.
Goal hits %d
of %d.\n",
ret_block, goal_hits, goal_attempts);
... |
should become
sector_t
ext3_new_block(handle_t
*handle,
struct inode *inode,
sector_t
goal, int
*errp)
...
group_t
group_no;
group_t goal_group;
sector_t ret_block;
group_t
bgi;
sector_t
target_block;
...
group_t ngroups;
...
if
(goal < le32_to_cpu(es->s_first_data_block) ||
goal
>= ext3_read_split_le64(sb,
es->s_hi_blocks_count,
es->s_blocks_count))
goal = le32_to_cpu(es->s_first_data_block);
group_no
= (goal - ext3_read_split_le64(sb,
es->s_hi_first_data_block,
es->s_first_data_block)) /
EXT3_BLOCKS_PER_GROUP(sb);
...
ext3_debug("using
block
group %lld(%d)\n",
(long
long)group_no,
gdp->bg_free_blocks_count);
...
if
(target_block == ext3_read_split_le64(sb,
gdp->bg_hi_block_bitmap,
gdp->bg_block_bitmap) ||
target_block == ext3_read_split_le64(sb,
gdp->bg_hi_inode_bitmap,
gdp->bg_inode_bitmap) ||
in_range(target_block, ext3_read_split_le64(sb,
gdp->bg_hi_inode_table,
gdp->bg_inode_table),
EXT3_SB(sb)->s_itb_per_group))
ext3_error(sb, "ext3_new_block",
"Allocating block in system zone - "
"block = %llu",
(unsigned
long long)target_block);
...
ext3_debug("found
bit %lld\n",
(long
long)ret_block);
...
if
(ret_block >= ext3_read_split_le64(sb, es->s_hi_blocks_count,
es->s_blocks_count)) {
ext3_error(sb, "ext3_new_block",
"block(%lld)
>= blocks
count(%lld)
- "
"block_group = %lld,
es
== %p
", (long
long)ret_block,
ext3_read_split_le64(es->s_blocks_count),
(long
long)group_no,
es);
...
ext3_debug("allocating
block %lld.
Goal hits %lld
of %lld.\n",
(long
long)ret_block, (long
long)goal_hits,
(long
long)goal_attempts);
... |
3.4.22.
ext3_count_free_blocks()
unsigned long
ext3_count_free_blocks(struct super_block *sb)
...
unsigned long
desc_count;
int
i;
unsigned long ngroups;
...
unsigned
long
bitmap_count, x;
...
printk("group %d:
stored =
%d, counted = %lu\n",
i, le16_to_cpu(gdp->bg_free_blocks_count), x);
...
printk("ext3_count_free_blocks: stored = %u,
computed = %lu,
%lu\n",
le32_to_cpu(es->s_free_blocks_count), desc_count, bitmap_count);
...
|
should become
sector_t
ext3_count_free_blocks(struct super_block *sb)
...
sector_t desc_count;
group_t
i;
group_t
ngroups;
...
sector_t
bitmap_count, x;
...
printk("group %lld:
stored = %d, counted = %llu\n",
(long
long)i,
le16_to_cpu(gdp->bg_free_blocks_count),
(unsigned
long long)x);
...
printk("ext3_count_free_blocks: stored = %llu,
computed = %llu,
%llu\n",
ext3_read_split_le64(sb,
es->s_hi_free_blocks_count,
es->s_free_blocks_count),
(unsigned
long long)desc_count,
(unsigned
long long)bitmap_count);
...
|
3.4.23.
block_in_use()
static
inline int block_in_use(unsigned
long block,
struct super_block * sb,
unsigned char * map)
{
return ext3_test_bit ((block -
le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block))
%
EXT3_BLOCKS_PER_GROUP(sb), map);
}
|
should become
static
inline int block_in_use(sector_t block,
struct super_block * sb,
unsigned char * map)
{
return ext3_test_bit ((block
-
ext3_read_split_le64(sb,
EXT3_SB(sb)->s_es->s_hi_first_data_block,
EXT3_SB(sb)->s_es->s_first_data_block)) %
EXT3_BLOCKS_PER_GROUP(sb), map);
}
|
3.4.24. test_root()
| static inline int
test_root(int a, int b) |
should become
| static inline int
test_root(group_t a, group_t b) |
3.4.25. ext3_group_sparse()
| static int
ext3_group_sparse(int group) |
should become
| static int
ext3_group_sparse(group_t group) |
3.4.26. ext3_bg_has_super()
| int
ext3_bg_has_super(struct super_block *sb, int group) |
should become
| int
ext3_bg_has_super(struct super_block *sb, group_t group) |
3.4.27. ext3_bg_num_gdb()
| unsigned
long
ext3_bg_num_gdb(struct super_block *sb, int group) |
should become
| sector_t
ext3_bg_num_gdb(struct super_block
*sb, group_t group) |
3.4.28.
ext3_check_blocks_bitmap()
unsigned
long desc_count,
bitmap_count, x, j;
unsigned
long desc_blocks;
...
int i;
...
ext3_error(sb,
__FUNCTION__,
"Superblock in group %d is marked free", i);
...
ext3_error(sb,
__FUNCTION__,
"Descriptor block #%ld in group "
"%d is marked free", j,
i);
if
(!block_in_use (le32_to_cpu(gdp->bg_block_bitmap),
sb, bitmap_bh->b_data))
ext3_error (sb, "ext3_check_blocks_bitmap",
"Block bitmap for group %d
is marked free",
i);
if
(!block_in_use (le32_to_cpu(gdp->bg_inode_bitmap),
sb, bitmap_bh->b_data))
xt3_error (sb, "ext3_check_blocks_bitmap",
"Inode bitmap for group %d
is marked free",
i);
for
(j = 0; j <
EXT3_SB(sb)->s_itb_per_group; j++)
if (!block_in_use (le32_to_cpu(gdp->bg_inode_table)
+ j,
sb, bitmap_bh->b_data))
ext3_error (sb, "ext3_check_blocks_bitmap",
"Block #%d
of the inode
table in "
"group %d
is marked free",
j, i);
...
ext3_error
(sb,
"ext3_check_blocks_bitmap",
"Wrong free blocks count for group %d,
"
"stored = %d, counted = %lu",
i,
le16_to_cpu(gdp->bg_free_blocks_count), x);
...
if
(le32_to_cpu(es->s_free_blocks_count)
!= bitmap_count)
ext3_error (sb, "ext3_check_blocks_bitmap",
"Wrong free blocks count in super block, "
"stored = %lu,
counted = %lu",
(unsigned long)le32_to_cpu(es->s_free_blocks_count),
bitmap_count);
|
should become
sector_t desc_count,
bitmap_count, x, j;
sector_t desc_blocks;
...
group_t i;
...
ext3_error(sb,
__FUNCTION__,
"Superblock in group %lld is marked free", (long long)i);
...
ext3_error(sb,
__FUNCTION__,
"Descriptor block #%lld
in
group "
"%lld is marked free", (long long)j,
(long
long)i);
if
(!block_in_use (ext3_read_split_le64(sb,
gdp->bg_hi_block_bitmap,
gdp->bg_block_bitmap),
sb, bitmap_bh->b_data))
ext3_error (sb, "ext3_check_blocks_bitmap",
"Block bitmap for group %lld
is marked free",
(long
long)i);
if
(!block_in_use (ext3_read_split_le64(sb,
gdp->bg_hi_inode_bitmap,
gdp->bg_inode_bitmap),
sb, bitmap_bh->b_data))
ext3_error (sb, "ext3_check_blocks_bitmap",
"Inode bitmap for group %lld
is marked free",
(long
long)i);
for
(j = 0; j <
EXT3_SB(sb)->s_itb_per_group; j++)
if (!block_in_use (ext3_read_split_le64(sb, gdp->bg_hi_inode_table,
gdp->bg_inode_table)
+ j,
sb, bitmap_bh->b_data))
ext3_error (sb, "ext3_check_blocks_bitmap",
"Block #%lld
of the inode
table in "
"group %lld
is marked
free",
(long long)j, (long
long)i);
...
ext3_error
(sb,
"ext3_check_blocks_bitmap",
"Wrong free blocks count for group %lld,
"
"stored = %d, counted = %llu",
(long long)i,
le16_to_cpu(gdp->bg_free_blocks_count),
(unsigned long long)x);
...
if
(ext3_read_split_le64(es->s_free_blocks_count)
!= bitmap_count)
ext3_error (sb, "ext3_check_blocks_bitmap",
"Wrong free blocks count in super block, "
"stored = %llu,
counted
= %llu",
ext3_read_split_le64(sb,
es->s_hi_free_blocks_count,
es->s_free_blocks_count),
(unsigned long long)bitmap_count); |
3.5. fs/ext3/bitmap.c
3.5.1. ext3_count_free()
N/A
3.6. fs/ext3/dir.c
Use "unsigned
long" for
offset in directory file.
For consistency, should become a "loff_t"
(long
long), like the i_size
field of the structure inode
in "include/linux/fs.h".
3.6.1. get_dtype()
N/A
3.6.2. ext3_check_dir_entry()
N/A
3.6.3. ext3_readdir()
Use "unsigned
long" for
offset in directory file.
For consistency, should become a "loff_t"
(long
long), like the i_size
field of the structure inode
in "include/linux/fs.h".
3.6.4. free_rb_tree_fname()
N/A
3.6.5. create_dir_info()
N/A
3.6.6. ext3_htree_free_dir_info()
N/A
3.6.7. ext3_htree_store_dirent()
N/A
3.6.8. call_filldir()
N/A
3.6.9. ext3_dx_readdir()
N/A
3.6.10. ext3_release_dir()
N/A
3.7. fs/ext3/file.c
Blocks
are accessed through offset in
file, not by block physical address.
3.7.1. ext3_release_file()
N/A
3.7.2. ext3_file_write()
N/A
3.8. fs/ext3/fsync.c
3.8.1. ext3_sync_file()
N/A
3.9. fs/ext3/hash.c
3.9.1. TEA_transform()
N/A
3.9.2. halfMD4Transform()
N/A
3.9.3. dx_hack_hash()
N/A
3.9.4. str2hashbuf()
N/A
3.9.5. ext3fs_dirhash()
N/A
3.10.
fs/ext3/ialloc.c
3.10.1. read_inode_bitmap()
static struct
buffer_head *
read_inode_bitmap(struct
super_block * sb, unsigned long
block_group)
...
ext3_error(sb,
"read_inode_bitmap",
"Cannot read inode bitmap - "
"block_group = %u,
inode_bitmap = %lu",
block_group, le32_to_cpu(desc->bg_inode_bitmap));
... |
should become
static struct
buffer_head *
read_inode_bitmap(struct
super_block * sb, group_t
block_group)
...
ext3_error(sb,
"read_inode_bitmap",
"Cannot read inode bitmap - "
"block_group = %llu,
inode_bitmap = %llu",
(unsigned
long long)block_group,
ext3_read_split_le64(sb,
desc->bg_hi_inode_bitmap,
desc->bg_inode_bitmap));
... |
3.10.2. ext3_free_inode()
| unsigned long
block_group; |
should become
"unsigned
long ino" should
be changed if we want to manage more than 232
- 10 files.
(but depends on VFS "struct inode",
"ino"
field which is also
an "unsigned
long")
3.10.3. find_group_dir()
static int
find_group_dir(struct
super_block *sb, struct inode *parent)
...
int
ngroups =
EXT3_SB(sb)->s_groups_count;
...
int
group, best_group =
-1; |
should become
static group_t
find_group_dir(struct
super_block *sb, struct inode *parent)
...
group_t ngroups =
EXT3_SB(sb)->s_groups_count;
...
group_t group, best_group = (group_t)-1; |
3.10.4. find_group_orlov()
static int
find_group_orlov(struct
super_block *sb, struct inode *parent)
...
int
parent_group =
EXT3_I(parent)->i_block_group;
...
int ngroups =
sbi->s_groups_count;
...
int ngroups =
sbi->s_groups_count;
...
int freeb, avefreeb;
...
int best_group = -1;
... |
should become
static group_t
find_group_orlov(struct super_block *sb, struct inode *parent)
...
group_t parent_group
= EXT3_I(parent)->i_block_group;
...
group_t ngroups =
sbi->s_groups_count;
...
group_t ngroups =
sbi->s_groups_count;
...
sector_t freeb, avefreeb;
...
group_t best_group = (group_t)-1;
... |
"freei"
and "avefreei"
are initialized with
the total numbers of free inodes and should be greater than a 32bit
value (see 3.10.2.).
3.10.5. find_group_other()
static
int
find_group_other(struct super_block *sb, struct inode *parent)
{
int
parent_group =
EXT3_I(parent)->i_block_group;
int ngroups =
EXT3_SB(sb)->s_groups_count;
...
int group, i;
...
return -1; |
should become
static
group_t
find_group_other(struct
super_block *sb, struct inode *parent)
{
group_t
parent_group =
EXT3_I(parent)->i_block_group;
group_t
ngroups
= EXT3_SB(sb)->s_groups_count;
...
group_t
group,
i;
...
return (group_t)-1; |
3.10.6. ext3_new_inode()
int
group;
...
int
i;
...
if (group == -1)
goto out; |
should become
group_t group;
...
group_t
i;
...
if (group == (group_t)-1)
goto out; |
3.10.7. ext3_orphan_get()
| unsigned long
block_group; |
should become
3.10.8. ext3_count_free_inodes()
should become
3.10.9. ext3_count_dirs()
should become
3.10.10. ext3_check_inodes_bitmap()
should become
3.11. fs/ext3/inode.c
3.11.1. ext3_inode_is_fast_symlink()
N/A
3.11.2. ext3_forget()
int
ext3_forget(handle_t *handle, int is_metadata,
struct inode *inode, struct buffer_head *bh,
int
blocknr) |
should become
int
ext3_forget(handle_t *handle, int is_metadata,
struct inode *inode, struct buffer_head *bh,
sector_t
blocknr) |
"blocknr" is in fact "buffer_head->b_blocknr", a "sector_t"
field.
3.11.3. blocks_for_truncate()
WARNING:
needed = inode->i_blocks >>
(inode->i_sb->s_blocksize_bits - 9);
in 32bit mode should already be:
needed =
le32_to_cpu(inode->i_blocks) >>
(inode->i_sb->s_blocksize_bits - 9);
should become
The return type of the function can stay "unsigned long" because maximum
returned value is EXT3_MAX_TRANS_DATA
(64U).
3.11.4. start_transaction()
N/A
3.11.5.
try_to_extend_transaction()
N/A
3.11.6.
ext3_journal_test_restart()
N/A
3.11.7. ext3_delete_inode()
N/A
3.11.8. ext3_alloc_block()
static
int ext3_alloc_block (handle_t *handle, struct inode * inode, unsigned long goal,
int *err)
...
unsigned long result; |
should be
static
int ext3_alloc_block (handle_t *handle, struct inode * inode, sector_t goal,
int *err)
...
sector_t
result; |
3.11.9. add_chain()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.10. verify_chain()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.11. ext3_block_to_path()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.12. ext3_get_branch()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.13. ext3_find_near()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.14. ext3_find_goal()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.15. ext3_alloc_branch()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.16. ext3_splice_branch()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.17.
ext3_get_block_handle()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.18. ext3_get_block()
Already uses "sector_t" for iblock.
3.11.19. ext3_direct_io_get_blocks()
Already use "sector_t" for iblock.
3.11.20. ext3_getblk()
struct buffer_head *ext3_getblk(handle_t *handle, struct
inode * inode,
long block, int
create, int * errp)
... |
should become
struct buffer_head *ext3_getblk(handle_t *handle, struct
inode * inode,
sector_t block, int
create, int * errp)
... |
3.11.21. ext3_bread()
struct buffer_head *ext3_bread(handle_t *handle, struct inode
* inode,
int block, int
create, int *err)
... |
should become
struct buffer_head *ext3_bread(handle_t *handle, struct inode
* inode,
sector_t block, int
create, int *err)
... |
3.11.22. walk_page_buffers()
N/A
3.11.23.
do_journal_get_write_access()
N/A
3.11.24. ext3_prepare_write()
N/A
3.11.25.
ext3_journal_dirty_data()
N/A
3.11.26. commit_write_fn()
N/A
3.11.27.
ext3_ordered_commit_write()
N/A
3.11.28.
ext3_writeback_commit_write()
N/A
3.11.29.
ext3_journalled_commit_write()
N/A
3.11.30. ext3_bmap()
Already use "sector_t"
3.11.31. bget_one()
N/A
3.11.32. bput_one()
N/A
3.11.33.
journal_dirty_data_fn()
N/A
3.11.34.
ext3_ordered_writepage()
N/A
3.11.35.
ext3_writeback_writepage()
N/A
3.11.36.
ext3_journalled_writepage()
N/A
3.11.37. ext3_readpage()
N/A
3.11.38. ext3_readpages()
N/A
3.11.39. ext3_invalidatepage()
"unsigned
long offset" could
stay this type because it is compared
to a buffer_head b_size (u32).
3.11.40. ext3_releasepage()
N/A
3.11.41. ext3_direct_IO()
N/A
3.11.42. ext3_set_aops()
N/A
3.11.43.
ext3_block_truncate_page()
N/A
3.11.44. all_zeroes()
N/A
3.11.45. ext3_find_shared()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.46. ext3_clear_blocks()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.47. ext3_free_data()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.48. ext3_free_branches()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.49. ext3_truncate()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.48. ext3_get_inode_block()
static unsigned long
ext3_get_inode_block(struct super_block *sb,
unsigned long ino, struct ext3_iloc *iloc)
{
unsigned long desc,
group_desc, block_group;
unsigned long offset,
block;
... |
should become
static sector_t
ext3_get_inode_block(struct super_block *sb,
unsigned long ino, struct ext3_iloc *iloc)
{
group_t desc,
group_desc, block_group;
sector_t
offset, block;
... |
The block group of a given inode is given by:
block_group = (ino - 1)
/ EXT3_INODES_PER_GROUP(sb)
Now, imagine we have a 64bit file system, and block groups number
greater or equal to 2^32. As inode number is a 32bit value, this means
EXT3_INODES_PER_GROUP is lesser or equal to 1.
of course this case happens with a filesystem greater than
(with a 4 KiB block):
= number of group (2^32) * size of a group (128 MiB)
= 2^32 * 2^27 = 2^59
= 512 PiB.
(a 64bit file system should be able to manage 2^64 * 2^12 = 2^76 =
64 ZiB)
if we introduce 64bit addressing mode in ext3 (large filesystems
support):
1-should we consider to increase size of block groups ?
(blocks bitmap is stored in several blocks instead of one per
group)
It could be interesting for some other cases to have bigger
groups
on large filesystems.
For instance, if we count groups using a 32bit value and we want
to
manage 64 ZiB, we should have a group size of
= filesystem size (2^76) / number of groups (2^32)
= group size (2^44)
= 16 TiB or 2^32 blocks of 4 KiB (2^12).
To store 2^32 blocks in a group, we need 2^32 bits in bitmap.
In a block we can store
= number of bytes (2^12) * number of bits per byte (2^3)
= 2^15 bits in 4 KiB block,
so to store 2^32 bits, we need
= 2^32 / 2^15
= 2^17
= 131072 blocks
(2^17 * 2^12 = 2^29 = 512 MiB for bitmap...
it's 100 / (2^44 / 2^29) = 100 / 2^15 = 0.003 % of the group size
currently, a block of 4 KiB in a group of 128 MiB is
100 / (2^12 / 2^27) = 100 / 2^15
we keep same ratio... seems logic).
Could we imagine to introduce new feature:
multiple bitmap blocks in a group ?
2-should we consider to introduce new mechanism to manage inode ?
For instance, like it is done in JFS, inode number is a key in a
structure instead the index in the inode array.
Moreover, this allows to reduce/increase filesystem more easily.
But this means also, as we have less inode numbers than group
numbers,
a file should fill several groups (i.e. some files are greater
than
128 MiB).
3-should we consider to introduce 64bit inode number ?
(But linux VFS manages inode on a 32bit value.)
4-should we limit the size of the filesystem to 512 PiB ?
(if we want to think like Microsoft (TM) in 1981 when MSDOS
was limited to 640 KB ;-) )
3.11.49. __ext3_get_inode_loc()
See 3.11.48. (previous comment)
should become
3.11.50. ext3_get_inode_loc()
N/A
3.11.51. ext3_set_inode_flags()
N/A
3.11.52. ext3_read_inode()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.53. ext3_do_update_inode()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.54. ext3_write_inode()
N/A
3.11.55. ext3_setattr()
N/A
3.11.56.
ext3_writepage_trans_blocks()
Be
impacted by how 64bit block address
is coded in meta-data blocks -> 48bit extents ?
3.11.57. ext3_mark_iloc_dirty()
N/A
3.11.58.
ext3_reserve_inode_write()
N/A
3.11.59.
ext3_mark_inode_dirty()
N/A
3.11.60. ext3_dirty_inode()
N/A
3.11.61.
ext3_change_inode_journal_flag()
N/A
3.12. fs/ext3/ioctl.c
3.12.1. ext3_ioctl()
should add "EXT3_IOC_GROUP_ADD64",
see 1.1.4.
3.13. fs/ext3/namei.c
3.13.1. ext3_append()
if we want 64bit file size, block
should become a 64bit integer.
3.13.2.
TO DO
3.14. fs/ext3/resize.c
3.14.1. verify_group_input()
N/A
3.14.2. bclean()
static
struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
unsigned
long blk) |
should become
static
struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
sector_t
blk) |
3.14.3.
mark_bitmap_end()
N/A
3.14.4. setup_new_group_blocks()
unsigned long
start =
input->group *
sbi->s_blocks_per_group +
le32_to_cpu(sbi->s_es->s_first_data_block);
...
unsigned
long block;
...
ext3_debug("update backup group %#04lx
(+%d)\n", block, bit);
...
ext3_debug("clear reserved block %#04lx
(+%d)\n", block, bit);
...
ext3_debug("mark block bitmap %#04x
(+%ld)\n",
input->block_bitmap,
input->block_bitmap - start);
...
ext3_debug("mark inode bitmap %#04x
(+%ld)\n",
input->inode_bitmap,
input->inode_bitmap - start);
|
should become
sector_t
start
=
input->group *
sbi->s_blocks_per_group +
le32_to_cpu(sbi->s_es->s_first_data_block);
...
sector_t
block;
...
ext3_debug("update backup group %#04llx
(+%d)\n", (unsigned long long)block,
bit);
...
ext3_debug("clear reserved block %#04lx
(+%d)\n", (unsigned long long)block,
bit);
...
ext3_debug("mark block bitmap %#04llx
(+%ld)\n",
(unsigned long long)input->block_bitmap,
input->block_bitmap - start);
...
ext3_debug("mark inode bitmap %#04llx
(+%ld)\n",
(unsigned
long long)input->inode_bitmap,
input->inode_bitmap - start);
|
3.14.5. ext3_list_backups()
N/A
3.14.6. verify_reserved_gdb()
const unsigned
long blk =
primary->b_blocknr;
const
unsigned
long end =
EXT3_SB(sb)->s_groups_count; |
should become
const sector_t
blk =
primary->b_blocknr;
const
sector_t
end =
EXT3_SB(sb)->s_groups_count; |
__u32
*p = (__u32
*)primary->b_data;
should be modified according data type in the direct/*-indirect blocks.
3.14.7. add_new_gdb()
unsigned long gdb_num
=
input->group / EXT3_DESC_PER_BLOCK(sb);
unsigned
long gdblock
= EXT3_SB(sb)->s_sbh->b_blocknr + 1
+
gdb_num;
...
__u32
*data;
...
printk(KERN_DEBUG
"EXT3-fs:
ext3_add_new_gdb: adding group block %lu\n",
gdb_num);
...
data = (__u32
*)dind->b_data;
if (le32_to_cpu(data[gdb_num
% EXT3_ADDR_PER_BLOCK(sb)]) != gdblock) {
ext3_warning(sb, __FUNCTION__,
"new group %u
GDT block %lu
not reserved\n",
input->group, gdblock);
... |
should become
group_t
gdb_num =
input->group / EXT3_DESC_PER_BLOCK(sb);
sector_t
gdblock =
EXT3_SB(sb)->s_sbh->b_blocknr + 1
+
gdb_num;
...
__u32
*data;
...
printk(KERN_DEBUG
"EXT3-fs:
ext3_add_new_gdb: adding group block %llu\n",
(unsigned
long long)gdb_num);
...
data = (__u32
*)dind->b_data;
if (le32_to_cpu(data[gdb_num
% EXT3_ADDR_PER_BLOCK(sb)]) != gdblock) {
ext3_warning(sb, __FUNCTION__,
"new group %llu
GDT
block %llu
not
reserved\n",
(unsigned
long long)input->group,
(unsigned long long)gdblock);
... |
The new type of data depends on how we address indirect block with LBD.
3.14.8. reserve_backup_gdb()
unsigned long blk;
__u32 *data, *end;
...
dind = sb_bread(sb, le32_to_cpu(*data));
...
data = (__u32 *)dind->b_data + EXT3_SB(sb)->s_gdb_count;
end = (__u32 *)dind->b_data + EXT3_ADDR_PER_BLOCK(sb);
...
if (le32_to_cpu(*data) != blk) {
ext3_warning(sb, __FUNCTION__,
"reserved block %lu not at offset %ld\n",
blk, (long)(data - (__u32 *)dind->b_data));
...
data = (__u32 *)dind->b_data;
...
data = (__u32 *)primary[i]->b_data;
...
data[gdbackups] = cpu_to_le32(blk + primary[i]->b_blocknr); |
The new type of data depends on how we address indirect block with LBD.
3.14.9. update_backups()
const unsigned long last
= sbi->s_groups_count;
... |
3.14.10. ext3_group_add()
TO DO
3.14.11. ext3_group_extend()
unsigned long
o_blocks_count;
unsigned
long
o_groups_count;
unsigned
long last;
...
o_blocks_count = le32_to_cpu(es->s_blocks_count);
...
printk(KERN_DEBUG "EXT3-fs: extending last group from %lu
to %lu
blocks\n",
o_blocks_count, n_blocks_count);
...
ext3_warning(sb, __FUNCTION__,
"will only finish group (%lu
blocks, %u new)",
o_blocks_count + add, add);
...
if
(o_blocks_count != le32_to_cpu(es->s_blocks_count))
{
...
es->s_blocks_count = cpu_to_le32(o_blocks_count
+ add);
...
ext3_debug("freeing blocks %ld
through %ld\n",
o_blocks_count,
o_blocks_count + add);
...
ext3_debug("freed blocks %ld
through %ld\n",
o_blocks_count,
o_blocks_count + add);
...
printk(KERN_DEBUG "EXT3-fs: extended group to %u
blocks\n",
le32_to_cpu(es->s_blocks_count)); |
should become
sector_t
o_blocks_count;
sector_t
o_groups_count;
sector_t
last;
...
o_blocks_count = ext3_read_split_le64(es->s_blocks_count);
...
printk(KERN_DEBUG "EXT3-fs: extending last group from %llu
to %llu
blocks\n",
(unsigned
long long)o_blocks_count,
(unsigned long long)n_blocks_count);
...
ext3_warning(sb, __FUNCTION__,
"will only finish group (%llu
blocks, %u new)",
(unsigned
long long)o_blocks_count
+ add, add);
...
if
(o_blocks_count != ext3_read_split_le64(sb,
es->s_hi_blocks_count,
es->s_blocks_count)) {
...
ext3_write_split_le64(sb,
&es->s_hi_blocks_count,
&es->s_blocks_count,
o_blocks_count +
add);
...
ext3_debug("freeing blocks %lld
through %lld\n",
(unsigned
long long)o_blocks_count,
(unsigned
long long)o_blocks_count
+ add);
...
ext3_debug("freed blocks %lld
through %lld\n",
(unsigned
long long)o_blocks_count,
(unsigned
long long)o_blocks_count
+ add);
...
printk(KERN_DEBUG "EXT3-fs: extended group to %u
blocks\n",
ext3_read_split_le64(es->s_blocks_count)); |
3.15. fs/ext3/super.c
3.15.1. ext3_journal_start_sb()
N/A
3.15.2. __ext3_journal_stop()
N/A
3.15.3. ext3_journal_abort_handle()
N/A
3.15.4. ext3_handle_error()
N/A
3.15.5. ext3_error()
N/A
3.15.6. ext3_decode_error()
N/A
3.15.7. __ext3_std_error()
N/A
3.15.8. ext3_abort()
N/A
3.15.9. ext3_warning()
N/A
3.15.10. ext3_update_dynamic_rev()
N/A
3.15.11. ext3_blkdev_get()
N/A
3.15.12. ext3_blkdev_put()
N/A
3.15.13. ext3_blkdev_remove()
N/A
3.15.14. orphan_list_entry()
N/A
3.15.15. dump_orphan_list()
N/A
3.15.16. ext3_put_super()
N/A
3.15.17. ext3_alloc_inode()
N/A
3.15.18. ext3_destroy_inode()
N/A
3.15.19. init_once()
N/A
3.15.20. init_inodecache()
N/A
3.15.21. destroy_inodecache()
N/A
3.15.22. ext3_clear_inode()
N/A
3.15.23. get_sb_block()
static unsigned
long get_sb_block(void
**data)
...unsigned
long
sb_block;
...
sb_block = simple_strtoul(options,
&options, 0); |
should become
static sector_t
get_sb_block(void
**data)
...
sector_t
sb_block;
...
sb_block = simple_strtoull(options,
&options, 0); |
3.15.24. parse_options ()
static
int parse_options (char *
options, struct super_block *sb,
unsigned long * inum, unsigned
long *n_blocks_count, int
is_remount) |
should become
static
int parse_options (char *
options, struct super_block *sb,
unsigned long * inum, sector_t
*n_blocks_count, int
is_remount) |
3.15.25.
ext3_check_descriptors()
static
int ext3_check_descriptors
(struct super_block * sb)
{
struct ext3_sb_info *sbi =
EXT3_SB(sb);
unsigned
long
block =
le32_to_cpu(sbi->s_es->s_first_data_block);
struct ext3_group_desc * gdp
= NULL;
int desc_block = 0;
int
i;
ext3_debug ("Checking group
descriptors");
for (i = 0; i <
sbi->s_groups_count; i++)
{
if ((i % EXT3_DESC_PER_BLOCK(sb)) == 0)
gdp = (struct ext3_group_desc *)
sbi->s_group_desc[desc_block++]->b_data;
if (le32_to_cpu(gdp->bg_block_bitmap)
< block ||
le32_to_cpu(gdp->bg_block_bitmap) >=
block + EXT3_BLOCKS_PER_GROUP(sb))
{
ext3_error
(sb,
"ext3_check_descriptors",
"Block bitmap for group %d"
" not in group (block %lu)!",
i, (unsigned long)
le32_to_cpu(gdp->bg_block_bitmap));
return 0;
}
if (le32_to_cpu(gdp->bg_inode_bitmap)
< block ||
le32_to_cpu(gdp->bg_inode_bitmap) >=
block + EXT3_BLOCKS_PER_GROUP(sb))
{
ext3_error
(sb,
"ext3_check_descriptors",
"Inode bitmap for group %d"
" not in group (block %lu)!",
i, (unsigned long)
le32_to_cpu(gdp->bg_inode_bitmap));
return 0;
}
if (le32_to_cpu(gdp->bg_inode_table)
< block ||
le32_to_cpu(gdp->bg_inode_table) + sbi->s_itb_per_group
>=
block + EXT3_BLOCKS_PER_GROUP(sb))
{
ext3_error
(sb,
"ext3_check_descriptors",
"Inode table for group %d"
" not in group (block %lu)!",
i, (unsigned long)
le32_to_cpu(gdp->bg_inode_table));
return 0;
}
block += EXT3_BLOCKS_PER_GROUP(sb);
gdp++;
}
sbi->s_es->s_free_blocks_count=cpu_to_le32(ext3_count_free_blocks(sb));
sbi->s_es->s_free_inodes_count=cpu_to_le32(ext3_count_free_inodes(sb));
return 1;
}
|
should
become
static int
ext3_check_descriptors (struct super_block * sb)
{
struct ext3_sb_info *sbi =
EXT3_SB(sb);
unsigned long block =
le32_to_cpu(sbi->s_es->s_first_data_block);
struct ext3_group_desc * gdp
= NULL;
int desc_block = 0;
int i;
ext3_debug ("Checking group
descriptors");
for (i = 0; i <
sbi->s_groups_count; i++)
{
if ((i % EXT3_DESC_PER_BLOCK(sb)) == 0)
gdp = (struct ext3_group_desc *)
sbi->s_group_desc[desc_block++]->b_data;
if (le32_to_cpu(gdp->bg_block_bitmap) < block ||
le32_to_cpu(gdp->bg_block_bitmap) >=
block + EXT3_BLOCKS_PER_GROUP(sb))
{
ext3_error (sb, "ext3_check_descriptors",
"Block bitmap for group %d"
" not in group (block %lu)!",
i, (unsigned long)
le32_to_cpu(gdp->bg_block_bitmap));
return 0;
}
if (le32_to_cpu(gdp->bg_inode_bitmap) < block ||
le32_to_cpu(gdp->bg_inode_bitmap) >=
block + EXT3_BLOCKS_PER_GROUP(sb))
{
ext3_error (sb, "ext3_check_descriptors",
"Inode bitmap for group %d"
" not in group (block %lu)!",
i, (unsigned long)
le32_to_cpu(gdp->bg_inode_bitmap));
return 0;
}
if (le32_to_cpu(gdp->bg_inode_table) < block ||
le32_to_cpu(gdp->bg_inode_table) + sbi->s_itb_per_group
>=
block + EXT3_BLOCKS_PER_GROUP(sb))
{
ext3_error (sb, "ext3_check_descriptors",
"Inode table for group %d"
" not in group (block %lu)!",
i, (unsigned long)
le32_to_cpu(gdp->bg_inode_table));
return 0;
}
block += EXT3_BLOCKS_PER_GROUP(sb);
gdp++;
}
sbi->s_es->s_free_blocks_count=cpu_to_le32(ext3_count_free_blocks(sb));
sbi->s_es->s_free_inodes_count=cpu_to_le32(ext3_count_free_inodes(sb));
return 1;
} |
3.15.26. ext3_max_size()
should change if we can address 64bit files and if we use extents patch.
3.15.27. descriptor_loc()
static
unsigned long descriptor_loc(struct super_block *sb,
unsigned long logic_sb_block,
int nr)
{
struct ext3_sb_info *sbi = EXT3_SB(sb);
unsigned long bg, first_data_block, first_meta_bg;
int has_super = 0;
first_data_block =
le32_to_cpu(sbi->s_es->s_first_data_block);
first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_META_BG) ||
nr < first_meta_bg)
return (logic_sb_block + nr + 1);
bg = sbi->s_desc_per_block * nr;
if (ext3_bg_has_super(sb, bg))
has_super = 1;
return (first_data_block + has_super + (bg *
sbi->s_blocks_per_group));
} |
should become
static
unsigned long descriptor_loc(struct super_block *sb,
unsigned long logic_sb_block,
int nr)
{
struct ext3_sb_info *sbi = EXT3_SB(sb);
unsigned long bg, first_data_block, first_meta_bg;
int has_super = 0;
first_data_block =
le32_to_cpu(sbi->s_es->s_first_data_block);
first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_META_BG) ||
nr < first_meta_bg)
return (logic_sb_block + nr + 1);
bg = sbi->s_desc_per_block * nr;
if (ext3_bg_has_super(sb, bg))
has_super = 1;
return (first_data_block + has_super + (bg *
sbi->s_blocks_per_group));
} |
3.15.28. ext3_fill_super()
TO DO
3.15.29. ext3_remount()
TO DO
3.15.30. ext3_statfs()
TO DO
3.16. fs/ext3/symlink.c
3.16.1. ext3_follow_link()
N/A
3.17. fs/ext3/xattr.c
3.17.1. ea_bdebug()
#
define ea_bdebug(bh, f...) do { \
char b[BDEVNAME_SIZE]; \
printk(KERN_DEBUG "block %s:%lu:
", \
bdevname(bh->b_bdev, b), \
(unsigned
long)
bh->b_blocknr); \
printk(f); \
printk("\n"); \
} while (0) |
should become
#
define ea_bdebug(bh, f...) do { \
char b[BDEVNAME_SIZE]; \
printk(KERN_DEBUG "block %s:%llu:
", \
bdevname(bh->b_bdev, b), \
(unsigned
long long) bh->b_blocknr);
\
printk(f); \
printk("\n"); \
} while (0) |
3.17.2.
ext3_xattr_cache_find(()
ext3_error(inode->i_sb,
__FUNCTION__,
"inode %ld: block %ld
read
error",
inode->i_ino, (unsigned long) ce->e_block);
...
ea_idebug(inode, "block %ld
refcount %d>=%d",
(unsigned
long)
ce->e_block,
le32_to_cpu(BHDR(bh)->h_refcount),
EXT3_XATTR_REFCOUNT_MAX); |
should become
|
ext3_error(inode->i_sb,
__FUNCTION__,
"inode %ld: block %lld read
error",
inode->i_ino, (unsigned long
long) ce->e_block);
...
ea_idebug(inode,
"block %lld
refcount %d>=%d",
(unsigned
lond long)
ce->e_block,
le32_to_cpu(BHDR(bh)->h_refcount),
EXT3_XATTR_REFCOUNT_MAX); |
3.18. fs/ext3/xattr.h
N/A
3.19. fs/ext3/xattr_security.c
N/A
3.20. fs/ext3/xattr_trusted.c
N/A
3.21. fs/ext3/xattr_user.c
N/A