Hello, Alan,
in reiserfs-specific part of inode there are several fields that are
actually used as single-bit flags. This patch, replaces them with single
bit-field.
Please, apply.
Nikita.
diff -rup linux/fs/reiserfs/file.c linux.patched/fs/reiserfs/file.c
--- linux/fs/reiserfs/file.c Thu Sep 20 21:26:39 2001
+++ linux.patched/fs/reiserfs/file.c Thu Sep 20 19:17:11 2001
@@ -33,7 +33,7 @@ static int reiserfs_file_release (struct
/* fast out for when nothing needs to be done */
if ((atomic_read(&inode->i_count) > 1 ||
- !inode->u.reiserfs_i.i_pack_on_close ||
+ !(inode->u.reiserfs_i.i_flags & i_pack_on_close_mask) ||
!tail_has_to_be_packed(inode)) &&
inode->u.reiserfs_i.i_prealloc_count <= 0) {
return 0;
@@ -50,7 +50,7 @@ static int reiserfs_file_release (struct
journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
if (atomic_read(&inode->i_count) <= 1 &&
- inode->u.reiserfs_i.i_pack_on_close &&
+ (inode->u.reiserfs_i.i_flags & i_pack_on_close_mask) &&
tail_has_to_be_packed (inode)) {
/* if regular file is released by last holder and it has been
appended (we append by unformatted node only) or its direct
@@ -96,20 +96,20 @@ static int reiserfs_setattr(struct dentr
/* version 2 items will be caught by the s_maxbytes check
** done for us in vmtruncate
*/
- if (inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
+ if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
attr->ia_size > MAX_NON_LFS)
return -EFBIG ;
}
if (attr->ia_valid & ATTR_UID) {
- if ((attr->ia_uid & ~0xffff) && inode_sd_version (inode) == STAT_DATA_V1) {
+ if ((attr->ia_uid & ~0xffff) && get_inode_sd_version (inode) == STAT_DATA_V1) {
/* stat data of format v1 has 16 bit uid */
return -EINVAL;
}
}
if (attr->ia_valid & ATTR_GID) {
- if ((attr->ia_gid & ~0xffff) && inode_sd_version (inode) == STAT_DATA_V1) {
+ if ((attr->ia_gid & ~0xffff) && get_inode_sd_version (inode) == STAT_DATA_V1) {
/* stat data of format v1 has 16 bit gid */
return -EINVAL;
}
diff -rup linux/fs/reiserfs/inode.c linux.patched/fs/reiserfs/inode.c
--- linux/fs/reiserfs/inode.c Thu Sep 20 21:26:39 2001
+++ linux.patched/fs/reiserfs/inode.c Thu Sep 20 19:17:11 2001
@@ -69,7 +72,7 @@ static void _make_cpu_key (struct cpu_ke
void make_cpu_key (struct cpu_key * key, const struct inode * inode, loff_t offset,
int type, int length)
{
- _make_cpu_key (key, inode_item_key_version (inode),
+ _make_cpu_key (key, get_inode_item_key_version (inode),
le32_to_cpu (INODE_PKEY (inode)->k_dir_id),
le32_to_cpu (INODE_PKEY (inode)->k_objectid),
offset, type, length);
@@ -182,7 +185,7 @@ static inline void set_block_dev_mapped
//
static int file_capable (struct inode * inode, long block)
{
- if (inode_item_key_version (inode) != KEY_FORMAT_3_5 || // it is new file.
+ if (get_inode_item_key_version (inode) != KEY_FORMAT_3_5 || // it is new file.
block < (1 << (31 - inode->i_sb->s_blocksize_bits))) // old file, but 'block'
is inside of 2gb
return 1;
@@ -662,7 +665,7 @@ static inline int _allocate_block(struct
/* key of item to be inserted */
tmp_key = *key;
/* ih of indirect item to be inserted */
- make_le_item_head (&tmp_ih, key, inode_item_key_version (inode), 1,
TYPE_INDIRECT,
+ make_le_item_head (&tmp_ih, key, get_inode_item_key_version (inode), 1,
+TYPE_INDIRECT,
UNFM_P_SIZE, 0/* free_space */);
/* item itself */
unp = cpu_to_le32 (block);
@@ -832,7 +835,7 @@ int reiserfs_get_block (struct inode * i
/* bad.... */
lock_kernel() ;
th.t_trans_id = 0 ;
- version = inode_item_key_version (inode);
+ version = get_inode_item_key_version (inode);
if (!file_capable (inode, block)) {
unlock_kernel() ;
@@ -851,7 +854,7 @@ int reiserfs_get_block (struct inode * i
return ret;
}
- inode->u.reiserfs_i.i_pack_on_close = 1 ;
+ inode->u.reiserfs_i.i_flags |= i_pack_on_close_mask;
windex = push_journal_writer("reiserfs_get_block") ;
@@ -1039,8 +1042,8 @@ static void init_inode (struct inode * i
struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
unsigned long blocks;
- inode_item_key_version (inode) = KEY_FORMAT_3_5;
- inode_sd_version (inode) = STAT_DATA_V1;
+ set_inode_item_key_version (inode, KEY_FORMAT_3_5);
+ set_inode_sd_version (inode, STAT_DATA_V1);
inode->i_mode = sd_v1_mode(sd);
inode->i_nlink = sd_v1_nlink(sd);
inode->i_uid = sd_v1_uid(sd);
@@ -1088,13 +1091,13 @@ static void init_inode (struct inode * i
if (S_ISDIR (inode->i_mode) || S_ISLNK (inode->i_mode))
/* items of directories and symlinks have keys in 3.5 format */
- inode_item_key_version (inode) = KEY_FORMAT_3_5;
+ set_inode_item_key_version (inode, KEY_FORMAT_3_5);
else
- inode_item_key_version (inode) = KEY_FORMAT_3_6;
+ set_inode_item_key_version (inode, KEY_FORMAT_3_6);
}
/* nopack = 0, by default */
- inode->u.reiserfs_i.nopack = 0;
+ inode->u.reiserfs_i.i_flags &= ~i_nopack_mask;
pathrelse (path);
if (S_ISREG (inode->i_mode)) {
@@ -1676,13 +1679,13 @@ struct inode * reiserfs_new_inode (struc
// format, other new objects will consist of new items)
memcpy (INODE_PKEY (inode), &(ih.ih_key), KEY_SIZE);
if (old_format_only (sb) || S_ISDIR(mode) || S_ISLNK(mode))
- inode_item_key_version (inode) = KEY_FORMAT_3_5;
+ set_inode_item_key_version (inode, KEY_FORMAT_3_5);
else
- inode_item_key_version (inode) = KEY_FORMAT_3_6;
+ set_inode_item_key_version (inode, KEY_FORMAT_3_6);
if (old_format_only (sb))
- inode_sd_version (inode) = STAT_DATA_V1;
+ set_inode_sd_version (inode, STAT_DATA_V1);
else
- inode_sd_version (inode) = STAT_DATA_V2;
+ set_inode_sd_version (inode, STAT_DATA_V2);
/* insert the stat data into the tree */
retval = reiserfs_insert_item (th, &path_to_key, &key, &ih, (char *)(&sd));
diff -rup linux/fs/reiserfs/ioctl.c linux.patched/fs/reiserfs/ioctl.c
--- linux/fs/reiserfs/ioctl.c Thu Sep 20 21:26:39 2001
+++ linux.patched/fs/reiserfs/ioctl.c Thu Sep 20 18:55:17 2001
@@ -46,7 +46,7 @@ int reiserfs_unpack (struct inode * inod
return -EINVAL ;
}
/* ioctl already done */
- if (inode->u.reiserfs_i.nopack) {
+ if (inode->u.reiserfs_i.i_flags & i_nopack_mask) {
return 0 ;
}
lock_kernel();
@@ -59,7 +59,7 @@ int reiserfs_unpack (struct inode * inod
write_from = inode->i_size & (blocksize - 1) ;
/* if we are on a block boundary, we are already unpacked. */
if ( write_from == 0) {
- inode->u.reiserfs_i.nopack = 1;
+ inode->u.reiserfs_i.i_flags |= i_nopack_mask;
goto out ;
}
@@ -79,7 +79,7 @@ int reiserfs_unpack (struct inode * inod
/* conversion can change page contents, must flush */
flush_dcache_page(page) ;
- inode->u.reiserfs_i.nopack = 1;
+ inode->u.reiserfs_i.i_flags |= i_nopack_mask;
kunmap(page) ; /* mapped by prepare_write */
out_unlock:
diff -rup linux/fs/reiserfs/stree.c linux.patched/fs/reiserfs/stree.c
--- linux/fs/reiserfs/stree.c Thu Sep 20 21:26:39 2001
+++ linux.patched/fs/reiserfs/stree.c Thu Sep 20 20:00:59 2001
@@ -916,7 +920,7 @@ static inline int prepare_for_direct_ite
}
// new file gets truncated
- if (inode_item_key_version (inode) == KEY_FORMAT_3_6) {
+ if (get_inode_item_key_version (inode) == KEY_FORMAT_3_6) {
//
round_len = ROUND_UP (new_file_length);
/* this was n_new_file_length < le_ih ... */
@@ -1487,7 +1492,7 @@ static int maybe_indirect_to_direct (str
*/
if (atomic_read(&p_s_inode->i_count) > 1 ||
!tail_has_to_be_packed (p_s_inode) ||
- !page || p_s_inode->u.reiserfs_i.nopack) {
+ !page || (p_s_inode->u.reiserfs_i.i_flags & i_nopack_mask)) {
// leave tail in an unformatted node
*p_c_mode = M_SKIP_BALANCING;
cut_bytes = n_block_size - (n_new_file_size & (n_block_size - 1));
@@ -1689,7 +1694,7 @@ int reiserfs_cut_from_item (struct reise
** be flushed before the transaction commits, so we don't need to
** deal with it here.
*/
- p_s_inode->u.reiserfs_i.i_pack_on_close = 0 ;
+ p_s_inode->u.reiserfs_i.i_flags &= ~i_pack_on_close_mask;
}
return n_ret_value;
}
@@ -1778,6 +1783,7 @@ void reiserfs_do_truncate (struct reiser
pathrelse(&s_search_path);
return;
}
+
/* Update key to search for the last file item. */
set_cpu_key_k_offset (&s_item_key, n_file_size);
@@ -1814,7 +1820,6 @@ void reiserfs_do_truncate (struct reiser
if (update_timestamps) {
p_s_inode->i_mtime = p_s_inode->i_ctime = CURRENT_TIME;
- // FIXME: sd gets wrong size here
}
reiserfs_update_sd(th, p_s_inode) ;
diff -rup linux/fs/reiserfs/tail_conversion.c
linux.patched/fs/reiserfs/tail_conversion.c
--- linux/fs/reiserfs/tail_conversion.c Thu Sep 20 21:26:39 2001
+++ linux.patched/fs/reiserfs/tail_conversion.c Thu Sep 20 19:16:10 2001
@@ -247,7 +247,7 @@ int indirect2direct (struct reiserfs_tra
/* Set direct item header to insert. */
- make_le_item_head (&s_ih, 0, inode_item_key_version (p_s_inode), pos1 + 1,
+ make_le_item_head (&s_ih, 0, get_inode_item_key_version (p_s_inode), pos1 + 1,
TYPE_DIRECT, round_tail_len, 0xffff/*ih_free_space*/);
/* we want a pointer to the first byte of the tail in the page.
diff -rup linux/include/linux/reiserfs_fs.h linux.patched/include/linux/reiserfs_fs.h
--- linux/include/linux/reiserfs_fs.h Thu Sep 20 21:26:44 2001
+++ linux.patched/include/linux/reiserfs_fs.h Thu Sep 20 19:56:43 2001
@@ -180,10 +180,23 @@ typedef __u32 unp_t;
*/
#define MIN_PACK_ON_CLOSE 512
-// this says about version of all items (but stat data) the object
-// consists of
-#define inode_item_key_version(inode) ((inode)->u.reiserfs_i.i_item_key_version)
-#define inode_sd_version(inode) ((inode)->u.reiserfs_i.i_stat_data_version)
+/** this says about version of all items (but stat data) the object
+ consists of */
+#define get_inode_item_key_version( inode ) \
+ (((inode)->u.reiserfs_i.i_flags & i_item_key_version_mask) ? KEY_FORMAT_3_6 :
+KEY_FORMAT_3_5)
+#define set_inode_item_key_version( inode, version )
+ \
+ ({ if((version)==KEY_FORMAT_3_6)
+ \
+ (inode)->u.reiserfs_i.i_flags |= i_item_key_version_mask;
+ \
+ else
+ \
+ (inode)->u.reiserfs_i.i_flags &= ~i_item_key_version_mask; })
+
+#define get_inode_sd_version(inode) \
+ (((inode)->u.reiserfs_i.i_flags & i_stat_data_version_mask) ? STAT_DATA_V2 :
+STAT_DATA_V1)
+#define set_inode_sd_version(inode, version)
+ \
+ ({ if( (version) == STAT_DATA_V2 )
+ \
+ (inode)->u.reiserfs_i.i_flags |= i_stat_data_version_mask;
+ \
+ else
+ \
+ (inode)->u.reiserfs_i.i_flags &= ~i_stat_data_version_mask; })
/* This is an aggressive tail suppression policy, I am hoping it
improves our benchmarks. The principle behind it is that
@@ -231,9 +244,8 @@ typedef __u32 unp_t;
#define KEY_FORMAT_3_5 0
#define KEY_FORMAT_3_6 1
-
-/* loff_t - long long */
-
+#define KEY_FORMAT_1 0
+#define KEY_FORMAT_2 1
//
// directories use this key as well as old files
@@ -1251,7 +1263,7 @@ struct path var = {ILLEGAL_PATH_ELEMENT_
#define U32_MAX (~(__u32)0)
extern inline loff_t max_reiserfs_offset (const struct inode * inode)
{
- if (inode_item_key_version (inode) == KEY_FORMAT_3_5)
+ if (get_inode_item_key_version (inode) == KEY_FORMAT_3_5)
return (loff_t)U32_MAX;
return (loff_t)((~(__u64)0) >> 4);
@@ -1530,10 +1542,6 @@ extern struct item_operations * item_ops
#define COMP_SHORT_KEYS comp_short_keys
#define not_of_one_file comp_short_keys
-/*#define COMP_KEYS(p_s_key1, p_s_key2) comp_keys((unsigned long
*)(p_s_key1), (unsigned long *)(p_s_key2))
-#define COMP_SHORT_KEYS(p_s_key1, p_s_key2) comp_short_keys((unsigned long
*)(p_s_key1), (unsigned long *)(p_s_key2))*/
-
-
/* number of blocks pointed to by the indirect item */
#define I_UNFM_NUM(p_s_ih) ( ih_item_len(p_s_ih) / UNFM_P_SIZE )
diff -rup linux/include/linux/reiserfs_fs_i.h
linux.patched/include/linux/reiserfs_fs_i.h
--- linux/include/linux/reiserfs_fs_i.h Thu Sep 20 21:26:44 2001
+++ linux.patched/include/linux/reiserfs_fs_i.h Thu Sep 20 19:45:59 2001
@@ -3,46 +3,47 @@
#include <linux/list.h>
+/** bitmasks for i_flags field in reiserfs-specific part of inode */
+typedef enum {
+ /** this says in what version keys of file's items are stored. If
+ this is set, item key is in 3.6 format otherwise in 3.5 format */
+ i_item_key_version_mask = 0x0001,
+ /** If this is unset, inode is stored on disk in 3.5 format of stat
+ data, otherwise, it is stored in 3.6 format with 64bit size, 32bit
+ nlink etc. */
+ i_stat_data_version_mask = 0x0002,
+ /** file might need tail packing on close */
+ i_pack_on_close_mask = 0x0004,
+ /** don't pack tail of file */
+ i_nopack_mask = 0x0008,
+ /** If those is set, "safe link" was created for this file during
+ truncate or unlink. Safe link is used to avoid leakage of disk
+ space on crash with some files open, but unlinked. */
+ i_link_saved_unlink_mask = 0x0010,
+ i_link_saved_truncate_mask = 0x0020
+} reiserfs_inode_flags;
+
struct reiserfs_inode_info {
__u32 i_key [4];/* key is still 4 32 bit integers */
- /* this comment will be totally
- cryptic to readers not familiar
- with 3.5/3.6 format conversion, and
- it does not consider that that 3.6
- might not be the last version */
- int i_item_key_version; // this says whether file is old or new
- int i_stat_data_version; // 1 if file has stat data of v1 format, 2 if file
- // has sd of v2 format
-
- int i_pack_on_close ; // file might need tail packing on close
-
+ /** transient inode flags that are never stored on disk. Bitmasks for
+ this field are defined above. */
+ __u32 i_flags;
__u32 i_first_direct_byte; // offset of first byte stored in direct item.
- /* My guess is this contains the first
- unused block of a sequence of
- blocks plus the length of the
- sequence, which I think is always
- at least two at the time of the
- preallocation. I really prefer
- allocate on flush conceptually.....
+ /* My guess is this contains the first unused block of a sequence of
+ blocks plus the length of the sequence, which I think is always at
+ least two at the time of the preallocation. I really prefer
+ allocate on flush conceptually.....
- You know, it really annoys me when
- code is this badly commented that I
- have to guess what it does.
- Neither I nor anyone else has time
- for guessing what your
- datastructures mean. -Hans */
+ You know, it really annoys me when code is this badly commented
+ that I have to guess what it does. Neither I nor anyone else has
+ time for guessing what your datastructures mean. -Hans */
//For preallocation
int i_prealloc_block;
int i_prealloc_count;
struct list_head i_prealloc_list; /* per-transaction list of inodes which
* have preallocated blocks */
- /* I regret that you think the below
- is a comment you should make.... -Hans */
- //nopack-attribute
- int nopack;
-
/* we use these for fsync or O_SYNC to decide which transaction needs
** to be committed in order for this inode to be properly flushed
*/