--- linux-2.5.3-pre4.o/fs/reiserfs/dir.c Thu Jan 24 12:21:23 2002
+++ linux-2.5.3-pre4/fs/reiserfs/dir.c Thu Jan 24 12:23:57 2002
@@ -170,7 +170,7 @@
}
/* directory continues in the right neighboring block */
- set_cpu_key_k_offset (&pos_key, le_key_k_offset (ITEM_VERSION_1, rkey));
+ set_cpu_key_k_offset (&pos_key, le_key_k_offset (KEY_FORMAT_3_5, rkey));
} /* while */
--- linux-2.5.3-pre4.o/fs/reiserfs/file.c Thu Jan 24 10:45:26 2002
+++ linux-2.5.3-pre4/fs/reiserfs/file.c Thu Jan 24 12:23:57 2002
@@ -33,7 +33,7 @@
/* fast out for when nothing needs to be done */
if ((atomic_read(&inode->i_count) > 1 ||
- REISERFS_I(inode)->i_pack_on_close ||
+ (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) ||
!tail_has_to_be_packed(inode)) &&
REISERFS_I(inode)->i_prealloc_count <= 0) {
return 0;
@@ -50,7 +50,7 @@
journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
if (atomic_read(&inode->i_count) <= 1 &&
- REISERFS_I(inode)->i_pack_on_close &&
+ (REISERFS_I(inode)->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
@@ -97,7 +97,7 @@
/* version 2 items will be caught by the s_maxbytes check
** done for us in vmtruncate
*/
- if (inode_items_version(inode) == ITEM_VERSION_1 &&
+ if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
attr->ia_size > MAX_NON_LFS)
return -EFBIG ;
}
--- linux-2.5.3-pre4.o/fs/reiserfs/inode.c Thu Jan 24 12:21:23 2002
+++ linux-2.5.3-pre4/fs/reiserfs/inode.c Thu Jan 24 12:23:57 2002
@@ -42,11 +42,13 @@
reiserfs_delete_object (&th, inode);
pop_journal_writer(windex) ;
- reiserfs_release_objectid (&th, inode->i_ino);
journal_end(&th, inode->i_sb, jbegin_count) ;
- up (&inode->i_sem);
+ up (&inode->i_sem);
+
+ /* all items of file are deleted, so we can remove "save" link */
+ remove_save_link (inode, 0/* not truncate */);
} else {
/* no object items are in the tree */
;
@@ -74,9 +76,9 @@
void make_cpu_key (struct cpu_key * key, struct inode * inode, loff_t offset,
int type, int length )
{
- _make_cpu_key (key, inode_items_version (inode), le32_to_cpu (INODE_PKEY (inode)->k_dir_id),
- le32_to_cpu (INODE_PKEY (inode)->k_objectid),
- offset, type, length);
+ _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);
}
@@ -217,7 +219,7 @@
//
int file_capable (struct inode * inode, long block)
{
- if (inode_items_version (inode) != ITEM_VERSION_1 || // 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;
@@ -543,7 +545,7 @@
/* bad.... */
lock_kernel() ;
th.t_trans_id = 0 ;
- version = inode_items_version (inode);
+ version = get_inode_item_key_version (inode);
if (block < 0) {
unlock_kernel();
@@ -567,7 +569,7 @@
return ret;
}
- REISERFS_I(inode)->i_pack_on_close = 1 ;
+ REISERFS_I(inode)->i_flags |= i_pack_on_close_mask ;
windex = push_journal_writer("reiserfs_get_block") ;
@@ -880,7 +882,8 @@
struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
unsigned long blocks;
- inode_items_version (inode) = ITEM_VERSION_1;
+ 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);
@@ -929,18 +932,18 @@
inode->i_generation = sd_v2_generation(sd);
if (S_ISDIR (inode->i_mode) || S_ISLNK (inode->i_mode))
- inode_items_version (inode) = ITEM_VERSION_1;
+ set_inode_item_key_version (inode, KEY_FORMAT_3_5);
else
- inode_items_version (inode) = ITEM_VERSION_2;
+ set_inode_item_key_version (inode, KEY_FORMAT_3_6);
REISERFS_I(inode)->i_first_direct_byte = 0;
}
- REISERFS_I(inode)->i_pack_on_close = 0;
+ REISERFS_I(inode)->i_flags = 0;
REISERFS_I(inode)->i_prealloc_block = 0;
REISERFS_I(inode)->i_prealloc_count = 0;
REISERFS_I(inode)->i_trans_id = 0;
REISERFS_I(inode)->i_trans_index = 0;
/* nopack = 0, by default */
- REISERFS_I(inode)->nopack = 0;
+ REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
pathrelse (path);
if (S_ISREG (inode->i_mode)) {
@@ -1120,7 +1123,7 @@
/* set version 1, version 2 could be used too, because stat data
key is the same in both versions */
- key.version = ITEM_VERSION_1;
+ key.version = KEY_FORMAT_3_5;
key.on_disk_key.k_dir_id = dirino;
key.on_disk_key.k_objectid = inode->i_ino;
key.on_disk_key.u.k_offset_v1.k_offset = SD_OFFSET;
@@ -1354,20 +1357,20 @@
struct cpu_key key;
int retval;
- _make_cpu_key (&key, ITEM_VERSION_1, le32_to_cpu (ih->ih_key.k_dir_id),
+ _make_cpu_key (&key, KEY_FORMAT_3_5, le32_to_cpu (ih->ih_key.k_dir_id),
le32_to_cpu (ih->ih_key.k_objectid), DOT_OFFSET, TYPE_DIRENTRY, 3/*key length*/);
/* compose item head for new item. Directories consist of items of
old type (ITEM_VERSION_1). Do not set key (second arg is 0), it
is done by reiserfs_new_inode */
if (old_format_only (sb)) {
- make_le_item_head (ih, 0, ITEM_VERSION_1, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2);
+ make_le_item_head (ih, 0, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2);
make_empty_dir_item_v1 (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid,
INODE_PKEY (dir)->k_dir_id,
INODE_PKEY (dir)->k_objectid );
} else {
- make_le_item_head (ih, 0, ITEM_VERSION_1, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2);
+ make_le_item_head (ih, 0, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2);
make_empty_dir_item (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid,
INODE_PKEY (dir)->k_dir_id,
@@ -1403,12 +1406,12 @@
struct cpu_key key;
int retval;
- _make_cpu_key (&key, ITEM_VERSION_1,
+ _make_cpu_key (&key, KEY_FORMAT_3_5,
le32_to_cpu (ih->ih_key.k_dir_id),
le32_to_cpu (ih->ih_key.k_objectid),
1, TYPE_DIRECT, 3/*key length*/);
- make_le_item_head (ih, 0, ITEM_VERSION_1, 1, TYPE_DIRECT, item_len, 0/*free_space*/);
+ make_le_item_head (ih, 0, KEY_FORMAT_3_5, 1, TYPE_DIRECT, item_len, 0/*free_space*/);
/* look for place in the tree for new item */
retval = search_item (sb, &key, path);
@@ -1479,13 +1482,13 @@
inode->i_generation = ++event;
#endif
if (old_format_only (sb))
- make_le_item_head (&ih, 0, ITEM_VERSION_1, SD_OFFSET, TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT);
+ make_le_item_head (&ih, 0, KEY_FORMAT_3_5, SD_OFFSET, TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT);
else
- make_le_item_head (&ih, 0, ITEM_VERSION_2, SD_OFFSET, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT);
+ make_le_item_head (&ih, 0, KEY_FORMAT_3_6, SD_OFFSET, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT);
/* key to search for correct place for new stat data */
- _make_cpu_key (&key, ITEM_VERSION_2, le32_to_cpu (ih.ih_key.k_dir_id),
+ _make_cpu_key (&key, KEY_FORMAT_3_6, le32_to_cpu (ih.ih_key.k_dir_id),
le32_to_cpu (ih.ih_key.k_objectid), SD_OFFSET, TYPE_STAT_DATA, 3/*key length*/);
/* find proper place for inserting of stat data */
@@ -1519,10 +1522,9 @@
REISERFS_I(inode)->i_first_direct_byte = S_ISLNK(mode) ? 1 :
U32_MAX/*NO_BYTES_IN_DIRECT_ITEM*/;
- REISERFS_I(inode)->i_pack_on_close = 0;
+ REISERFS_I(inode)->i_flags = 0;
REISERFS_I(inode)->i_prealloc_block = 0;
REISERFS_I(inode)->i_prealloc_count = 0;
- REISERFS_I(inode)->nopack = 0;
REISERFS_I(inode)->i_trans_id = 0;
REISERFS_I(inode)->i_trans_index = 0;
@@ -1540,10 +1542,14 @@
// 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_items_version (inode) = ITEM_VERSION_1;
+ set_inode_item_key_version (inode, KEY_FORMAT_3_5);
else
- inode_items_version (inode) = ITEM_VERSION_2;
-
+ set_inode_item_key_version (inode, KEY_FORMAT_3_6);
+ if (old_format_only (sb))
+ set_inode_sd_version (inode, STAT_DATA_V1);
+ else
+ 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));
if (retval) {
@@ -1703,12 +1709,23 @@
** because the truncate might pack the item anyway
** (it will unmap bh if it packs).
*/
- journal_begin(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 ) ;
+ /* it is enough to reserve space in transaction for 2 balancings:
+ one for "save" link adding and another for the first
+ cut_from_item. 1 is for update_sd */
+ journal_begin(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1 ) ;
reiserfs_update_inode_transaction(p_s_inode) ;
windex = push_journal_writer("reiserfs_vfs_truncate_file") ;
+ if (update_timestamps)
+ /* we are doing real truncate: if the system crashes before the last
+ transaction of truncating gets committed - on reboot the file
+ either appears truncated properly or not truncated at all */
+ add_save_link (&th, p_s_inode, 1);
reiserfs_do_truncate (&th, p_s_inode, page, update_timestamps) ;
pop_journal_writer(windex) ;
- journal_end(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 ) ;
+ journal_end(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1 ) ;
+
+ if (update_timestamps)
+ remove_save_link (p_s_inode, 1/* truncate */);
if (page) {
length = offset & (blocksize - 1) ;
--- linux-2.5.3-pre4.o/fs/reiserfs/ioctl.c Thu Jan 24 10:45:26 2002
+++ linux-2.5.3-pre4/fs/reiserfs/ioctl.c Thu Jan 24 12:23:57 2002
@@ -46,7 +46,7 @@
return -EINVAL ;
}
/* ioctl already done */
- if (REISERFS_I(inode)->nopack) {
+ if (REISERFS_I(inode)->i_flags & i_nopack_mask) {
return 0 ;
}
lock_kernel();
@@ -59,7 +59,7 @@
write_from = inode->i_size & (blocksize - 1) ;
/* if we are on a block boundary, we are already unpacked. */
if ( write_from == 0) {
- REISERFS_I(inode)->nopack = 1;
+ REISERFS_I(inode)->i_flags |= i_nopack_mask;
goto out ;
}
@@ -79,7 +79,7 @@
/* conversion can change page contents, must flush */
flush_dcache_page(page) ;
- REISERFS_I(inode)->nopack = 1;
+ REISERFS_I(inode)->i_flags |= i_nopack_mask;
kunmap(page) ; /* mapped by prepare_write */
out_unlock:
--- linux-2.5.3-pre4.o/fs/reiserfs/journal.c Thu Jan 24 12:21:23 2002
+++ linux-2.5.3-pre4/fs/reiserfs/journal.c Thu Jan 24 12:23:57 2002
@@ -92,6 +92,7 @@
static int flush_journal_list(struct super_block *s, struct reiserfs_journal_list *jl, int flushall) ;
static int flush_commit_list(struct super_block *s, struct reiserfs_journal_list *jl, int flushall) ;
static int can_dirty(struct reiserfs_journal_cnode *cn) ;
+static int journal_join(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks);
static int release_journal_dev( struct super_block *super,
struct reiserfs_journal *journal );
@@ -2269,7 +2270,7 @@
}
-int journal_join(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
+static int journal_join(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
return do_journal_begin_r(th, p_s_sb, nblocks, 1) ;
}
@@ -2424,7 +2425,7 @@
**
** returns 1 if it cleaned and relsed the buffer. 0 otherwise
*/
-int remove_from_transaction(struct super_block *p_s_sb, unsigned long blocknr, int already_cleaned) {
+static int remove_from_transaction(struct super_block *p_s_sb, unsigned long blocknr, int already_cleaned) {
struct buffer_head *bh ;
struct reiserfs_journal_cnode *cn ;
int ret = 0;
--- linux-2.5.3-pre4.o/fs/reiserfs/lbalance.c Wed Oct 31 02:11:34 2001
+++ linux-2.5.3-pre4/fs/reiserfs/lbalance.c Thu Jan 24 12:23:57 2002
@@ -63,7 +63,7 @@
/* form item header */
memcpy (&new_ih.ih_key, &ih->ih_key, KEY_SIZE);
- put_ih_version( &new_ih, ITEM_VERSION_1 );
+ put_ih_version( &new_ih, KEY_FORMAT_3_5 );
/* calculate item len */
put_ih_item_len( &new_ih, DEH_SIZE * copy_count + copy_records_len );
put_ih_entry_count( &new_ih, 0 );
@@ -78,7 +78,7 @@
set_le_ih_k_offset (&new_ih, U32_MAX);
/* this item is not yet valid, but we want I_IS_DIRECTORY_ITEM to return 1 for it, so we -1 */
}
- set_le_key_k_type (ITEM_VERSION_1, &(new_ih.ih_key), TYPE_DIRENTRY);
+ set_le_key_k_type (KEY_FORMAT_3_5, &(new_ih.ih_key), TYPE_DIRENTRY);
}
/* insert item into dest buffer */
--- linux-2.5.3-pre4.o/fs/reiserfs/namei.c Thu Jan 24 12:21:23 2002
+++ linux-2.5.3-pre4/fs/reiserfs/namei.c Thu Jan 24 12:23:57 2002
@@ -94,7 +94,7 @@
BUG ();
/* store key of the found entry */
- de->de_entry_key.version = ITEM_VERSION_1;
+ de->de_entry_key.version = KEY_FORMAT_3_5;
de->de_entry_key.on_disk_key.k_dir_id = le32_to_cpu (de->de_ih->ih_key.k_dir_id);
de->de_entry_key.on_disk_key.k_objectid = le32_to_cpu (de->de_ih->ih_key.k_objectid);
set_cpu_key_k_offset (&(de->de_entry_key), deh_offset (deh));
@@ -702,11 +702,14 @@
struct inode * inode;
int windex ;
struct reiserfs_transaction_handle th ;
- int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
+ int jbegin_count;
INITIALIZE_PATH (path);
struct reiserfs_dir_entry de;
+ /* we will be doing 2 balancings and update 2 stat data */
+ jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
+
journal_begin(&th, dir->i_sb, jbegin_count) ;
windex = push_journal_writer("reiserfs_rmdir") ;
@@ -750,6 +753,9 @@
dir->i_blocks = ((dir->i_size + 511) >> 9);
reiserfs_update_sd (&th, dir);
+ /* prevent empty directory from getting lost */
+ add_save_link (&th, inode, 0/* not truncate */);
+
pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ;
reiserfs_check_path(&path) ;
@@ -781,7 +787,13 @@
INITIALIZE_PATH (path);
int windex ;
struct reiserfs_transaction_handle th ;
- int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
+ int jbegin_count;
+
+ inode = dentry->d_inode;
+
+ /* in this transaction we can be doing at max two balancings and update
+ two stat datas */
+ jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
journal_begin(&th, dir->i_sb, jbegin_count) ;
windex = push_journal_writer("reiserfs_unlink") ;
@@ -791,7 +803,6 @@
retval = -ENOENT;
goto end_unlink;
}
- inode = dentry->d_inode;
reiserfs_update_inode_transaction(inode) ;
reiserfs_update_inode_transaction(dir) ;
@@ -822,6 +833,10 @@
dir->i_ctime = dir->i_mtime = CURRENT_TIME;
reiserfs_update_sd (&th, dir);
+ if (!inode->i_nlink)
+ /* prevent file from getting lost */
+ add_save_link (&th, inode, 0/* not truncate */);
+
pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ;
reiserfs_check_path(&path) ;
@@ -1032,8 +1047,13 @@
struct inode * old_inode, * new_inode;
int windex ;
struct reiserfs_transaction_handle th ;
- int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
+ int jbegin_count ;
+
+ /* two balancings: old name removal, new name insertion or "save" link,
+ stat data updates: old directory and new directory and maybe block
+ containing ".." of renamed directory */
+ jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 3;
old_inode = old_dentry->d_inode;
new_inode = new_dentry->d_inode;
@@ -1176,29 +1196,25 @@
if (new_inode) {
// adjust link number of the victim
if (S_ISDIR(new_inode->i_mode)) {
- DEC_DIR_INODE_NLINK(new_inode)
+ new_inode->i_nlink = 0;
} else {
- new_inode->i_nlink--;
+ new_inode->i_nlink--;
}
new_inode->i_ctime = CURRENT_TIME;
}
if (S_ISDIR(old_inode->i_mode)) {
- //if (dot_dot_de.de_bh) {
- // adjust ".." of renamed directory
+ // adjust ".." of renamed directory
set_ino_in_dir_entry (&dot_dot_de, INODE_PKEY (new_dir));
journal_mark_dirty (&th, new_dir->i_sb, dot_dot_de.de_bh);
-
- DEC_DIR_INODE_NLINK(old_dir)
- if (new_inode) {
- if (S_ISDIR(new_inode->i_mode)) {
- DEC_DIR_INODE_NLINK(new_inode)
- } else {
- new_inode->i_nlink--;
- }
- } else {
- INC_DIR_INODE_NLINK(new_dir)
- }
+
+ if (!new_inode)
+ /* there (in new_dir) was no directory, so it got new link
+ (".." of renamed directory) */
+ INC_DIR_INODE_NLINK(new_dir);
+
+ /* old directory lost one link - ".. " of renamed directory */
+ DEC_DIR_INODE_NLINK(old_dir);
}
// looks like in 2.3.99pre3 brelse is atomic. so we can use pathrelse
@@ -1216,13 +1232,19 @@
reiserfs_update_sd (&th, old_dir);
reiserfs_update_sd (&th, new_dir);
- if (new_inode)
+
+ if (new_inode) {
+ if (new_inode->i_nlink == 0)
+ add_save_link (&th, new_inode, 0/* not truncate */);
reiserfs_update_sd (&th, new_inode);
+ }
pop_journal_writer(windex) ;
journal_end(&th, old_dir->i_sb, jbegin_count) ;
return 0;
}
+
+
/*
* directories can handle most operations...
--- linux-2.5.3-pre4.o/fs/reiserfs/objectid.c Thu Jan 24 12:21:23 2002
+++ linux-2.5.3-pre4/fs/reiserfs/objectid.c Thu Jan 24 12:23:57 2002
@@ -163,7 +163,7 @@
i += 2;
}
- reiserfs_warning ("vs-15010: reiserfs_release_objectid: tried to free free object id (%lu)",
+ reiserfs_warning ("vs-15011: reiserfs_release_objectid: tried to free free object id (%lu)\n",
( long unsigned ) objectid_to_release);
}
--- linux-2.5.3-pre4.o/fs/reiserfs/prints.c Thu Jan 24 12:21:23 2002
+++ linux-2.5.3-pre4/fs/reiserfs/prints.c Thu Jan 24 12:23:57 2002
@@ -109,7 +109,7 @@
static void sprintf_item_head (char * buf, struct item_head * ih)
{
if (ih) {
- sprintf (buf, "%s", (ih_version (ih) == ITEM_VERSION_2) ? "*NEW* " : "*OLD*");
+ sprintf (buf, "%s", (ih_version (ih) == KEY_FORMAT_3_6) ? "*3.6* " : "*3.5*");
sprintf_le_key (buf + strlen (buf), &(ih->ih_key));
sprintf (buf + strlen (buf), ", item_len %d, item_location %d, "
"free_space(entry_count) %d",
--- linux-2.5.3-pre4.o/fs/reiserfs/stree.c Thu Jan 24 12:21:23 2002
+++ linux-2.5.3-pre4/fs/reiserfs/stree.c Thu Jan 24 12:23:57 2002
@@ -225,7 +225,7 @@
// find out version of the key
to->version = le_key_version (from);
- if (to->version == ITEM_VERSION_1) {
+ if (to->version == KEY_FORMAT_3_5) {
to->on_disk_key.u.k_offset_v1.k_offset = le32_to_cpu (from->u.k_offset_v1.k_offset);
to->on_disk_key.u.k_offset_v1.k_uniqueness = le32_to_cpu (from->u.k_offset_v1.k_uniqueness);
} else {
@@ -726,7 +726,11 @@
continue;
}
- RFALSE( ! key_in_buffer(p_s_search_path, p_s_key, p_s_sb),
+ /* only check that the key is in the buffer if p_s_key is not
+ equal to the MAX_KEY. Latter case is only possible in
+ "finish_unfinished()" processing during mount. */
+ RFALSE( COMP_KEYS( &MAX_KEY, p_s_key ) &&
+ ! key_in_buffer(p_s_search_path, p_s_key, p_s_sb),
"PAP-5130: key is not in the buffer");
#ifdef CONFIG_REISERFS_CHECK
if ( cur_tb ) {
@@ -916,7 +920,7 @@
}
// new file gets truncated
- if (inode_items_version (inode) == ITEM_VERSION_2) {
+ 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 ... */
@@ -1313,8 +1317,8 @@
/* this deletes item which never gets split */
-static void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,
- struct key * key)
+void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,
+ struct key * key)
{
struct tree_balance tb;
INITIALIZE_PATH (path);
@@ -1407,7 +1411,7 @@
*/
if (atomic_read(&p_s_inode->i_count) > 1 ||
!tail_has_to_be_packed (p_s_inode) ||
- !page || REISERFS_I(p_s_inode)->nopack) {
+ !page || (REISERFS_I(p_s_inode)->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));
@@ -1609,7 +1613,7 @@
** be flushed before the transaction commits, so we don't need to
** deal with it here.
*/
- REISERFS_I(p_s_inode)->i_pack_on_close = 0 ;
+ REISERFS_I(p_s_inode)->i_flags &= ~i_pack_on_close_mask ;
}
return n_ret_value;
}
@@ -1618,14 +1622,14 @@
static void truncate_directory (struct reiserfs_transaction_handle *th, struct inode * inode)
{
if (inode->i_nlink)
- reiserfs_warning ("vs-5655: truncate_directory: link count != 0");
+ reiserfs_warning ("vs-5655: truncate_directory: link count != 0\n");
- set_le_key_k_offset (ITEM_VERSION_1, INODE_PKEY (inode), DOT_OFFSET);
- set_le_key_k_type (ITEM_VERSION_1, INODE_PKEY (inode), TYPE_DIRENTRY);
+ set_le_key_k_offset (KEY_FORMAT_3_5, INODE_PKEY (inode), DOT_OFFSET);
+ set_le_key_k_type (KEY_FORMAT_3_5, INODE_PKEY (inode), TYPE_DIRENTRY);
reiserfs_delete_solid_item (th, INODE_PKEY (inode));
- set_le_key_k_offset (ITEM_VERSION_1, INODE_PKEY (inode), SD_OFFSET);
- set_le_key_k_type (ITEM_VERSION_1, INODE_PKEY (inode), TYPE_STAT_DATA);
+ set_le_key_k_offset (KEY_FORMAT_3_5, INODE_PKEY (inode), SD_OFFSET);
+ set_le_key_k_type (KEY_FORMAT_3_5, INODE_PKEY (inode), TYPE_STAT_DATA);
}
@@ -1698,6 +1702,7 @@
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);
@@ -1734,7 +1739,6 @@
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) ;
--- linux-2.5.3-pre4.o/fs/reiserfs/super.c Thu Jan 24 12:21:23 2002
+++ linux-2.5.3-pre4/fs/reiserfs/super.c Thu Jan 24 12:23:57 2002
@@ -105,6 +105,247 @@
reiserfs_allow_writes(s) ;
}
+extern const struct key MAX_KEY;
+
+
+/* this is used to delete "save link" when there are no items of a
+ file it points to. It can either happen if unlink is completed but
+ "save unlink" removal, or if file has both unlink and truncate
+ pending and as unlink completes first (because key of "save link"
+ protecting unlink is bigger that a key lf "save link" which
+ protects truncate), so there left no items to make truncate
+ completion on */
+static void remove_save_link_only (struct super_block * s, struct key * key)
+{
+ struct reiserfs_transaction_handle th;
+
+ /* we are going to do one balancing */
+ journal_begin (&th, s, JOURNAL_PER_BALANCE_CNT);
+
+ reiserfs_delete_solid_item (&th, key);
+ if (is_direct_le_key (KEY_FORMAT_3_5, key))
+ /* removals are protected by direct items */
+ reiserfs_release_objectid (&th, le32_to_cpu (key->k_objectid));
+
+ journal_end (&th, s, JOURNAL_PER_BALANCE_CNT);
+}
+
+
+/* look for uncompleted unlinks and truncates and complete them */
+static void finish_unfinished (struct super_block * s)
+{
+ INITIALIZE_PATH (path);
+ struct cpu_key max_cpu_key, obj_key;
+ struct key save_link_key;
+ int retval;
+ struct item_head * ih;
+ struct buffer_head * bh;
+ int item_pos;
+ char * item;
+ int done;
+ struct inode * inode;
+ int truncate;
+
+
+ /* compose key to look for "save" links */
+ max_cpu_key.version = KEY_FORMAT_3_5;
+ max_cpu_key.on_disk_key = MAX_KEY;
+ max_cpu_key.key_length = 3;
+
+ done = 0;
+ s -> u.reiserfs_sb.s_is_unlinked_ok = 1;
+ while (1) {
+ retval = search_item (s, &max_cpu_key, &path);
+ if (retval != ITEM_NOT_FOUND) {
+ reiserfs_warning ("vs-2140: finish_unfinished: search_by_key returned %d\n",
+ retval);
+ break;
+ }
+
+ bh = get_last_bh (&path);
+ item_pos = get_item_pos (&path);
+ if (item_pos != B_NR_ITEMS (bh)) {
+ reiserfs_warning ("vs-2060: finish_unfinished: wrong position found\n");
+ break;
+ }
+ item_pos --;
+ ih = B_N_PITEM_HEAD (bh, item_pos);
+
+ if (le32_to_cpu (ih->ih_key.k_dir_id) != MAX_KEY_OBJECTID)
+ /* there are no "save" links anymore */
+ break;
+
+ save_link_key = ih->ih_key;
+ if (is_indirect_le_ih (ih))
+ truncate = 1;
+ else
+ truncate = 0;
+
+ /* reiserfs_iget needs k_dirid and k_objectid only */
+ item = B_I_PITEM (bh, ih);
+ obj_key.on_disk_key.k_dir_id = le32_to_cpu (*(__u32 *)item);
+ obj_key.on_disk_key.k_objectid = le32_to_cpu (ih->ih_key.k_objectid);
+ obj_key.on_disk_key.u.k_offset_v1.k_offset = 0;
+ obj_key.on_disk_key.u.k_offset_v1.k_uniqueness = 0;
+
+ pathrelse (&path);
+
+ inode = reiserfs_iget (s, &obj_key);
+ if (!inode) {
+ /* the unlink almost completed, it just did not manage to remove
+ "save" link and release objectid */
+ reiserfs_warning ("vs-2180: finish_unfinished: iget failed for %K\n",
+ &obj_key);
+ remove_save_link_only (s, &save_link_key);
+ continue;
+ }
+
+ if (!truncate && inode->i_nlink) {
+ /* file is not unlinked */
+ reiserfs_warning ("vs-2185: finish_unfinished: file %K is not unlinked\n",
+ &obj_key);
+ remove_save_link_only (s, &save_link_key);
+ continue;
+ }
+
+ if (truncate) {
+ REISERFS_I(inode) -> i_flags |= i_link_saved_truncate_mask;
+ /* not completed truncate found. New size was committed together
+ with "save" link */
+ reiserfs_warning ("Truncating %k to %Ld ..",
+ INODE_PKEY (inode), inode->i_size);
+ reiserfs_truncate_file (inode, 0/*don't update modification time*/);
+ remove_save_link (inode, truncate);
+ } else {
+ REISERFS_I(inode) -> i_flags |= i_link_saved_unlink_mask;
+ /* not completed unlink (rmdir) found */
+ reiserfs_warning ("Removing %k..", INODE_PKEY (inode));
+ /* removal gets completed in iput */
+ }
+
+ iput (inode);
+ printk ("done\n");
+ done ++;
+ }
+ s -> u.reiserfs_sb.s_is_unlinked_ok = 0;
+
+ pathrelse (&path);
+ if (done)
+ reiserfs_warning ("There were %d uncompleted unlinks/truncates. "
+ "Completed\n", done);
+}
+
+/* to protect file being unlinked from getting lost we "safe" link files
+ being unlinked. This link will be deleted in the same transaction with last
+ item of file. mounting the filesytem we scan all these links and remove
+ files which almost got lost */
+void add_save_link (struct reiserfs_transaction_handle * th,
+ struct inode * inode, int truncate)
+{
+ INITIALIZE_PATH (path);
+ int retval;
+ struct cpu_key key;
+ struct item_head ih;
+ __u32 link;
+
+ /* file can only get one "save link" of each kind */
+ RFALSE( truncate &&
+ ( REISERFS_I(inode) -> i_flags & i_link_saved_truncate_mask ),
+ "saved link already exists for truncated inode %lx",
+ ( long ) inode -> i_ino );
+ RFALSE( !truncate &&
+ ( REISERFS_I(inode) -> i_flags & i_link_saved_unlink_mask ),
+ "saved link already exists for unlinked inode %lx",
+ ( long ) inode -> i_ino );
+
+ /* setup key of "save" link */
+ key.version = KEY_FORMAT_3_5;
+ key.on_disk_key.k_dir_id = MAX_KEY_OBJECTID;
+ key.on_disk_key.k_objectid = inode->i_ino;
+ if (!truncate) {
+ /* unlink, rmdir, rename */
+ set_cpu_key_k_offset (&key, 1 + inode->i_sb->s_blocksize);
+ set_cpu_key_k_type (&key, TYPE_DIRECT);
+
+ /* item head of "safe" link */
+ make_le_item_head (&ih, &key, key.version, 1 + inode->i_sb->s_blocksize, TYPE_DIRECT,
+ 4/*length*/, 0xffff/*free space*/);
+ } else {
+ /* truncate */
+ set_cpu_key_k_offset (&key, 1);
+ set_cpu_key_k_type (&key, TYPE_INDIRECT);
+
+ /* item head of "safe" link */
+ make_le_item_head (&ih, &key, key.version, 1, TYPE_INDIRECT,
+ 4/*length*/, 0/*free space*/);
+ }
+ key.key_length = 3;
+
+ /* look for its place in the tree */
+ retval = search_item (inode->i_sb, &key, &path);
+ if (retval != ITEM_NOT_FOUND) {
+ reiserfs_warning ("vs-2100: add_save_link:"
+ "search_by_key (%K) returned %d\n", &key, retval);
+ pathrelse (&path);
+ return;
+ }
+
+ /* body of "save" link */
+ link = cpu_to_le32 (INODE_PKEY (inode)->k_dir_id);
+
+ /* put "save" link inot tree */
+ retval = reiserfs_insert_item (th, &path, &key, &ih, (char *)&link);
+ if (retval)
+ reiserfs_warning ("vs-2120: add_save_link: insert_item returned %d\n",
+ retval);
+ else {
+ if( truncate )
+ REISERFS_I(inode) -> i_flags |= i_link_saved_truncate_mask;
+ else
+ REISERFS_I(inode) -> i_flags |= i_link_saved_unlink_mask;
+ }
+}
+
+
+/* this opens transaction unlike add_save_link */
+void remove_save_link (struct inode * inode, int truncate)
+{
+ struct reiserfs_transaction_handle th;
+ struct key key;
+
+
+ /* we are going to do one balancing only */
+ journal_begin (&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
+
+ /* setup key of "save" link */
+ key.k_dir_id = cpu_to_le32 (MAX_KEY_OBJECTID);
+ key.k_objectid = INODE_PKEY (inode)->k_objectid;
+ if (!truncate) {
+ /* unlink, rmdir, rename */
+ set_le_key_k_offset (KEY_FORMAT_3_5, &key,
+ 1 + inode->i_sb->s_blocksize);
+ set_le_key_k_type (KEY_FORMAT_3_5, &key, TYPE_DIRECT);
+ } else {
+ /* truncate */
+ set_le_key_k_offset (KEY_FORMAT_3_5, &key, 1);
+ set_le_key_k_type (KEY_FORMAT_3_5, &key, TYPE_INDIRECT);
+ }
+
+ if( ( truncate &&
+ ( REISERFS_I(inode) -> i_flags & i_link_saved_truncate_mask ) ) ||
+ ( !truncate &&
+ ( REISERFS_I(inode) -> i_flags & i_link_saved_unlink_mask ) ) )
+ reiserfs_delete_solid_item (&th, &key);
+ if (!truncate) {
+ reiserfs_release_objectid (&th, inode->i_ino);
+ REISERFS_I(inode) -> i_flags &= ~i_link_saved_unlink_mask;
+ } else
+ REISERFS_I(inode) -> i_flags &= ~i_link_saved_truncate_mask;
+
+ journal_end (&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
+}
+
+
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
@@ -388,6 +629,10 @@
/* this will force a full flush of all journal lists */
SB_JOURNAL(s)->j_must_wait = 1 ;
journal_end(&th, s, 10) ;
+
+ if (!( *flags & MS_RDONLY ) )
+ finish_unfinished( s );
+
return 0;
}
@@ -837,6 +1082,10 @@
journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
journal_end(&th, s, 1) ;
+
+ /* look for files which were to be removed in previous session */
+ finish_unfinished (s);
+
s->s_dirt = 0;
}
@@ -918,6 +1167,7 @@
out1:
return err;
}
+
MODULE_DESCRIPTION("ReiserFS journaled filesystem");
MODULE_AUTHOR("Hans Reiser <
[email protected]>");
--- linux-2.5.3-pre4.o/fs/reiserfs/tail_conversion.c Thu Jan 24 10:45:26 2002
+++ linux-2.5.3-pre4/fs/reiserfs/tail_conversion.c Thu Jan 24 12:23:57 2002
@@ -241,7 +241,7 @@
/* Set direct item header to insert. */
- make_le_item_head (&s_ih, 0, inode_items_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.
--- linux-2.5.3-pre4.o/include/linux/reiserfs_fs.h Thu Jan 24 12:21:23 2002
+++ linux-2.5.3-pre4/include/linux/reiserfs_fs.h Thu Jan 24 12:23:57 2002
@@ -273,14 +273,39 @@
unsigned short unfm_freespace;
};
+/* there are two formats of keys: 3.5 and 3.6
+ */
+#define KEY_FORMAT_3_5 0
+#define KEY_FORMAT_3_6 1
+
+/* there are two stat datas */
+#define STAT_DATA_V1 0
+#define STAT_DATA_V2 1
+
+
static inline struct reiserfs_inode_info *REISERFS_I(struct inode *inode)
{
return list_entry(inode, struct reiserfs_inode_info, vfs_inode);
}
-// this says about version of all items (but stat data) the object
-// consists of
-#define inode_items_version(inode) (REISERFS_I(inode)->i_version)
-
+/** this says about version of key of all items (but stat data) the
+ object consists of */
+#define get_inode_item_key_version( inode ) \
+ ((REISERFS_I(inode)->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) \
+ REISERFS_I(inode)->i_flags |= i_item_key_version_mask; \
+ else \
+ REISERFS_I(inode)->i_flags &= ~i_item_key_version_mask; })
+
+#define get_inode_sd_version(inode) \
+ ((REISERFS_I(inode)->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) \
+ REISERFS_I(inode)->i_flags |= i_stat_data_version_mask; \
+ else \
+ REISERFS_I(inode)->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 percentage
@@ -319,18 +344,6 @@
/***************************************************************************/
//
-// we do support for old format of reiserfs: the problem is to
-// distinuquish keys with 32 bit offset and keys with 60 bit ones. On
-// leaf level we use ih_version of struct item_head (was
-// ih_reserved). For all old items it is set to 0
-// (ITEM_VERSION_1). For new items it is ITEM_VERSION_2. On internal
-// levels we have to know version of item key belongs to.
-//
-#define ITEM_VERSION_1 0
-#define ITEM_VERSION_2 1
-
-
-//
// directories use this key as well as old files
//
struct offset_v1 {
@@ -497,8 +510,8 @@
#define unreachable_item(ih) (ih_version(ih) & (1 << 15))
-#define get_ih_free_space(ih) (ih_version (ih) == ITEM_VERSION_2 ? 0 : ih_free_space (ih))
-#define set_ih_free_space(ih,val) put_ih_free_space((ih), ((ih_version(ih) == ITEM_VERSION_2) ? 0 : (val)))
+#define get_ih_free_space(ih) (ih_version (ih) == KEY_FORMAT_3_6 ? 0 : ih_free_space (ih))
+#define set_ih_free_space(ih,val) put_ih_free_space((ih), ((ih_version(ih) == KEY_FORMAT_3_6) ? 0 : (val)))
/* these operate on indirect items, where you've got an array of ints
** at a possibly unaligned location. These are a noop on ia32
@@ -570,7 +583,7 @@
//
static inline loff_t le_key_k_offset (int version, const struct key * key)
{
- return (version == ITEM_VERSION_1) ?
+ return (version == KEY_FORMAT_3_5) ?
le32_to_cpu( key->u.k_offset_v1.k_offset ) :
offset_v2_k_offset( &(key->u.k_offset_v2) );
}
@@ -582,7 +595,7 @@
static inline loff_t le_key_k_type (int version, const struct key * key)
{
- return (version == ITEM_VERSION_1) ?
+ return (version == KEY_FORMAT_3_5) ?
uniqueness2type( le32_to_cpu( key->u.k_offset_v1.k_uniqueness)) :
offset_v2_k_type( &(key->u.k_offset_v2) );
}
@@ -595,20 +608,21 @@
static inline void set_le_key_k_offset (int version, struct key * key, loff_t offset)
{
- (version == ITEM_VERSION_1) ?
+ (version == KEY_FORMAT_3_5) ?
(key->u.k_offset_v1.k_offset = cpu_to_le32 (offset)) : /* jdm check */
(set_offset_v2_k_offset( &(key->u.k_offset_v2), offset ));
}
+
+
static inline void set_le_ih_k_offset (struct item_head * ih, loff_t offset)
{
set_le_key_k_offset (ih_version (ih), &(ih->ih_key), offset);
}
-
static inline void set_le_key_k_type (int version, struct key * key, int type)
{
- (version == ITEM_VERSION_1) ?
+ (version == KEY_FORMAT_3_5) ?
(key->u.k_offset_v1.k_uniqueness = cpu_to_le32(type2uniqueness(type))):
(set_offset_v2_k_type( &(key->u.k_offset_v2), type ));
}
@@ -638,21 +652,21 @@
//
static inline loff_t cpu_key_k_offset (const struct cpu_key * key)
{
- return (key->version == ITEM_VERSION_1) ?
+ return (key->version == KEY_FORMAT_3_5) ?
key->on_disk_key.u.k_offset_v1.k_offset :
key->on_disk_key.u.k_offset_v2.k_offset;
}
static inline loff_t cpu_key_k_type (const struct cpu_key * key)
{
- return (key->version == ITEM_VERSION_1) ?
+ return (key->version == KEY_FORMAT_3_5) ?
uniqueness2type (key->on_disk_key.u.k_offset_v1.k_uniqueness) :
key->on_disk_key.u.k_offset_v2.k_type;
}
static inline void set_cpu_key_k_offset (struct cpu_key * key, loff_t offset)
{
- (key->version == ITEM_VERSION_1) ?
+ (key->version == KEY_FORMAT_3_5) ?
(key->on_disk_key.u.k_offset_v1.k_offset = offset) :
(key->on_disk_key.u.k_offset_v2.k_offset = offset);
}
@@ -660,14 +674,15 @@
static inline void set_cpu_key_k_type (struct cpu_key * key, int type)
{
- (key->version == ITEM_VERSION_1) ?
+ (key->version == KEY_FORMAT_3_5) ?
(key->on_disk_key.u.k_offset_v1.k_uniqueness = type2uniqueness (type)):
(key->on_disk_key.u.k_offset_v2.k_type = type);
}
+
static inline void cpu_key_k_offset_dec (struct cpu_key * key)
{
- if (key->version == ITEM_VERSION_1)
+ if (key->version == KEY_FORMAT_3_5)
key->on_disk_key.u.k_offset_v1.k_offset --;
else
key->on_disk_key.u.k_offset_v2.k_offset --;
@@ -810,7 +825,7 @@
} __attribute__ ((__packed__));
#define SD_V1_SIZE (sizeof(struct stat_data_v1))
-#define stat_data_v1(ih) (ih_version (ih) == ITEM_VERSION_1)
+#define stat_data_v1(ih) (ih_version (ih) == KEY_FORMAT_3_5)
#define sd_v1_mode(sdp) (le16_to_cpu((sdp)->sd_mode))
#define set_sd_v1_mode(sdp,v) ((sdp)->sd_mode = cpu_to_le16(v))
#define sd_v1_nlink(sdp) (le16_to_cpu((sdp)->sd_nlink))
@@ -864,11 +879,11 @@
} __attribute__ ((__packed__)) u;
} __attribute__ ((__packed__));
//
-// this is 40 bytes long
+// this is 44 bytes long
//
#define SD_SIZE (sizeof(struct stat_data))
#define SD_V2_SIZE SD_SIZE
-#define stat_data_v2(ih) (ih_version (ih) == ITEM_VERSION_2)
+#define stat_data_v2(ih) (ih_version (ih) == KEY_FORMAT_3_6)
#define sd_v2_mode(sdp) (le16_to_cpu((sdp)->sd_mode))
#define set_sd_v2_mode(sdp,v) ((sdp)->sd_mode = cpu_to_le16(v))
/* sd_reserved */
@@ -1244,9 +1259,10 @@
// reiserfs version 2 has max offset 60 bits. Version 1 - 32 bit offset
#define U32_MAX (~(__u32)0)
+
static inline loff_t max_reiserfs_offset (struct inode * inode)
{
- if (inode_items_version (inode) == ITEM_VERSION_1)
+ if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5)
return (loff_t)U32_MAX;
return (loff_t)((~(__u64)0) >> 4);
@@ -1501,11 +1517,7 @@
#define COMP_KEYS comp_keys
#define COMP_SHORT_KEYS comp_short_keys
-#define keys_of_same_object 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))*/
-
+/*#define keys_of_same_object comp_short_keys*/
/* 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 )
@@ -1644,17 +1656,12 @@
int journal_mark_freed(struct reiserfs_transaction_handle *, struct super_block *, unsigned long blocknr) ;
int push_journal_writer(char *w) ;
int pop_journal_writer(int windex) ;
-int journal_lock_dobalance(struct super_block *p_s_sb) ;
-int journal_unlock_dobalance(struct super_block *p_s_sb) ;
int journal_transaction_should_end(struct reiserfs_transaction_handle *, int) ;
int reiserfs_in_journal(struct super_block *p_s_sb, unsigned long bl, int searchall, unsigned long *next) ;
int journal_begin(struct reiserfs_transaction_handle *, struct super_block *p_s_sb, unsigned long) ;
-int journal_join(struct reiserfs_transaction_handle *, struct super_block *p_s_sb, unsigned long) ;
struct super_block *reiserfs_get_super(kdev_t dev) ;
void flush_async_commits(struct super_block *p_s_sb) ;
-int remove_from_transaction(struct super_block *p_s_sb, unsigned long blocknr, int already_cleaned) ;
-
int buffer_journaled(const struct buffer_head *bh) ;
int mark_buffer_journal_new(struct buffer_head *bh) ;
int reiserfs_sync_all_buffers(kdev_t dev, int wait) ;
@@ -1693,6 +1700,10 @@
return 0 ;
}
+void add_save_link (struct reiserfs_transaction_handle * th,
+ struct inode * inode, int truncate);
+void remove_save_link (struct inode * inode, int truncate);
+
/* objectid.c */
__u32 reiserfs_get_unused_objectid (struct reiserfs_transaction_handle *th);
void reiserfs_release_objectid (struct reiserfs_transaction_handle *th, __u32 objectid_to_release);
@@ -1730,16 +1741,16 @@
type = offset_v2_k_type( &(key->u.k_offset_v2));
if (type != TYPE_DIRECT && type != TYPE_INDIRECT && type != TYPE_DIRENTRY)
- return ITEM_VERSION_1;
+ return KEY_FORMAT_3_5;
- return ITEM_VERSION_2;
+ return KEY_FORMAT_3_6;
}
static inline void copy_key (struct key *to, const struct key *from)
{
- memcpy (to, from, KEY_SIZE);
+ memcpy (to, from, KEY_SIZE);
}
@@ -1783,7 +1794,8 @@
struct inode * inode,
struct buffer_head * p_s_un_bh);
-
+void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,
+ struct key * key);
void reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode * p_s_inode);
void reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
struct inode * p_s_inode, struct page *,
--- linux-2.5.3-pre4.o/include/linux/reiserfs_fs_i.h Thu Jan 24 10:45:26 2002
+++ linux-2.5.3-pre4/include/linux/reiserfs_fs_i.h Thu Jan 24 12:23:57 2002
@@ -3,51 +3,46 @@
#include <linux/list.h>
-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_version; // this says whether file is old or new
+/** bitmasks for i_flags field in reiserfs-specific part of inode */
+typedef enum {
+ /** this says what format of key do all items (but stat data) of
+ an object have. If this is set, that format is 3.6 otherwise
+ - 3.5 */
+ i_item_key_version_mask = 0x0001,
+ /** If this is unset, object has 3.5 stat data, otherwise, it has
+ 3.6 stat data 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;
+
- int i_pack_on_close ; // file might need tail packing on close
+struct reiserfs_inode_info {
+ __u32 i_key [4];/* key is still 4 32 bit integers */
+ /** 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.
+ __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.....
+ int i_prealloc_block; /* first unused block of a sequence of unused blocks */
+ int i_prealloc_count; /* length of that sequence */
+ struct list_head i_prealloc_list; /* per-transaction list of inodes which
+ * have preallocated blocks */
- 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
- */
- unsigned long i_trans_id ;
- unsigned long i_trans_index ;
- struct inode vfs_inode;
+ /* 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 */
+ unsigned long i_trans_id ;
+ unsigned long i_trans_index ;
+ struct inode vfs_inode;
};
-
#endif