patch-2.4.7 linux/fs/reiserfs/inode.c
Next file: linux/fs/reiserfs/journal.c
Previous file: linux/fs/reiserfs/fix_node.c
Back to the patch index
Back to the overall index
- Lines: 378
- Date:
Wed Jul 18 07:46:02 2001
- Orig file:
v2.4.6/linux/fs/reiserfs/inode.c
- Orig date:
Tue Jul 3 17:08:21 2001
diff -u --recursive --new-file v2.4.6/linux/fs/reiserfs/inode.c linux/fs/reiserfs/inode.c
@@ -44,7 +44,6 @@
windex = push_journal_writer("delete_inode") ;
reiserfs_delete_object (&th, inode);
- reiserfs_remove_page_from_flush_list(&th, inode) ;
pop_journal_writer(windex) ;
reiserfs_release_objectid (&th, inode->i_ino);
@@ -103,6 +102,11 @@
ih->u.ih_entry_count = cpu_to_le16 (entry_count);
}
+static void add_to_flushlist(struct inode *inode, struct buffer_head *bh) {
+ struct inode *jinode = &(SB_JOURNAL(inode->i_sb)->j_dummy_inode) ;
+
+ buffer_insert_inode_queue(bh, jinode) ;
+}
//
// FIXME: we might cache recently accessed indirect item (or at least
@@ -129,60 +133,6 @@
** --chris
*/
-/* people who call journal_begin with a page locked must call this
-** BEFORE calling journal_begin
-*/
-static int prevent_flush_page_lock(struct page *page,
- struct inode *inode) {
- struct reiserfs_page_list *pl ;
- struct super_block *s = inode->i_sb ;
- /* we don't care if the inode has a stale pointer from an old
- ** transaction
- */
- if(!page || inode->u.reiserfs_i.i_conversion_trans_id != SB_JOURNAL(s)->j_trans_id) {
- return 0 ;
- }
- pl = inode->u.reiserfs_i.i_converted_page ;
- if (pl && pl->page == page) {
- pl->do_not_lock = 1 ;
- }
- /* this last part is really important. The address space operations have
- ** the page locked before they call the journal functions. So it is possible
- ** for one process to be waiting in flush_pages_before_commit for a
- ** page, then for the process with the page locked to call journal_begin.
- **
- ** We'll deadlock because the process flushing pages will never notice
- ** the process with the page locked has called prevent_flush_page_lock.
- ** So, we wake up the page waiters, even though the page is still locked.
- ** The process waiting in flush_pages_before_commit must check the
- ** pl->do_not_lock flag, and stop trying to lock the page.
- */
- wake_up(&page->wait) ;
- return 0 ;
-
-}
-/* people who call journal_end with a page locked must call this
-** AFTER calling journal_end
-*/
-static int allow_flush_page_lock(struct page *page,
- struct inode *inode) {
-
- struct reiserfs_page_list *pl ;
- struct super_block *s = inode->i_sb ;
- /* we don't care if the inode has a stale pointer from an old
- ** transaction
- */
- if(!page || inode->u.reiserfs_i.i_conversion_trans_id != SB_JOURNAL(s)->j_trans_id) {
- return 0 ;
- }
- pl = inode->u.reiserfs_i.i_converted_page ;
- if (pl && pl->page == page) {
- pl->do_not_lock = 0 ;
- }
- return 0 ;
-
-}
-
/* If this page has a file tail in it, and
** it was read in by get_block_create_0, the page data is valid,
** but tail is still sitting in a direct item, and we can't write to
@@ -324,7 +274,7 @@
}
//
- bh = get_bh (&path);
+ bh = get_last_bh (&path);
ih = get_ih (&path);
if (is_indirect_le_ih (ih)) {
__u32 * ind_item = (__u32 *)B_I_PITEM (bh, ih);
@@ -419,7 +369,7 @@
if (search_for_position_by_key (inode->i_sb, &key, &path) != POSITION_FOUND)
// we read something from tail, even if now we got IO_ERROR
break;
- bh = get_bh (&path);
+ bh = get_last_bh (&path);
ih = get_ih (&path);
} while (1);
@@ -607,7 +557,6 @@
return -EIO;
}
- prevent_flush_page_lock(bh_result->b_page, inode) ;
inode->u.reiserfs_i.i_pack_on_close = 1 ;
windex = push_journal_writer("reiserfs_get_block") ;
@@ -628,7 +577,7 @@
goto failure;
}
- bh = get_bh (&path);
+ bh = get_last_bh (&path);
ih = get_ih (&path);
item = get_item (&path);
pos_in_item = path.pos_in_item;
@@ -693,7 +642,6 @@
if (transaction_started)
journal_end(&th, inode->i_sb, jbegin_count) ;
- allow_flush_page_lock(bh_result->b_page, inode) ;
unlock_kernel() ;
/* the item was found, so new blocks were not added to the file
@@ -794,8 +742,12 @@
/* we've converted the tail, so we must
** flush unbh before the transaction commits
*/
- reiserfs_add_page_to_flush_list(&th, inode, unbh) ;
- mark_buffer_dirty(unbh) ;
+ add_to_flushlist(inode, unbh) ;
+
+ /* mark it dirty now to prevent commit_write from adding
+ ** this buffer to the inode's dirty buffer list
+ */
+ __mark_buffer_dirty(unbh) ;
//inode->i_blocks += inode->i_sb->s_blocksize / 512;
//mark_tail_converted (inode);
@@ -871,7 +823,7 @@
pathrelse(&path) ;
goto failure;
}
- bh = get_bh (&path);
+ bh = get_last_bh (&path);
ih = get_ih (&path);
item = get_item (&path);
pos_in_item = path.pos_in_item;
@@ -887,7 +839,6 @@
journal_end(&th, inode->i_sb, jbegin_count) ;
}
pop_journal_writer(windex) ;
- allow_flush_page_lock(bh_result->b_page, inode) ;
unlock_kernel() ;
reiserfs_check_path(&path) ;
return retval;
@@ -914,7 +865,6 @@
copy_key (INODE_PKEY (inode), &(ih->ih_key));
- inode->i_generation = INODE_PKEY (inode)->k_dir_id;
inode->i_blksize = PAGE_SIZE;
INIT_LIST_HEAD(&inode->u.reiserfs_i.i_prealloc_list) ;
@@ -934,6 +884,7 @@
inode->i_ctime = le32_to_cpu (sd->sd_ctime);
inode->i_blocks = le32_to_cpu (sd->u.sd_blocks);
+ inode->i_generation = INODE_PKEY (inode)->k_dir_id;
blocks = (inode->i_size + 511) >> 9;
blocks = _ROUND_UP (blocks, inode->i_blksize >> 9);
if (inode->i_blocks > blocks) {
@@ -968,6 +919,10 @@
inode->i_ctime = le32_to_cpu (sd->sd_ctime);
inode->i_blocks = le32_to_cpu (sd->sd_blocks);
rdev = le32_to_cpu (sd->u.sd_rdev);
+ if( S_ISCHR( inode -> i_mode ) || S_ISBLK( inode -> i_mode ) )
+ inode->i_generation = INODE_PKEY (inode)->k_dir_id;
+ else
+ inode->i_generation = le32_to_cpu( sd->u.sd_generation );
}
/* nopack = 0, by default */
@@ -1005,8 +960,11 @@
sd_v2->sd_atime = cpu_to_le32 (inode->i_atime);
sd_v2->sd_ctime = cpu_to_le32 (inode->i_ctime);
sd_v2->sd_blocks = cpu_to_le32 (inode->i_blocks);
- if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
sd_v2->u.sd_rdev = cpu_to_le32 (inode->i_rdev);
+ } else {
+ sd_v2->u.sd_generation = cpu_to_le32( inode -> i_generation );
+ }
}
@@ -1099,7 +1057,7 @@
** FS might change. We have to detect that, and loop back to the
** search if the stat data item has moved
*/
- bh = get_bh(&path) ;
+ bh = get_last_bh(&path) ;
ih = get_ih(&path) ;
copy_item_head (&tmp_ih, ih);
fs_gen = get_generation (inode->i_sb);
@@ -1208,10 +1166,20 @@
key.on_disk_key.k_objectid = data[0] ;
key.on_disk_key.k_dir_id = data[1] ;
inode = reiserfs_iget(sb, &key) ;
+ if (inode && (fhtype == 3 || fhtype == 6) &&
+ data[2] != inode->i_generation) {
+ iput(inode) ;
+ inode = NULL ;
+ }
} else {
- key.on_disk_key.k_objectid = data[2] ;
- key.on_disk_key.k_dir_id = data[3] ;
+ key.on_disk_key.k_objectid = data[fhtype==6?3:2] ;
+ key.on_disk_key.k_dir_id = data[fhtype==6?4:3] ;
inode = reiserfs_iget(sb, &key) ;
+ if (inode && fhtype == 6 &&
+ data[5] != inode->i_generation) {
+ iput(inode) ;
+ inode = NULL ;
+ }
}
out:
if (!inode)
@@ -1246,21 +1214,23 @@
struct inode *inode = dentry->d_inode ;
int maxlen = *lenp;
- if (maxlen < 2)
+ if (maxlen < 3)
return 255 ;
data[0] = inode->i_ino ;
data[1] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ;
- *lenp = 2;
+ data[2] = inode->i_generation ;
+ *lenp = 3;
/* no room for directory info? return what we've stored so far */
- if (maxlen < 4 || ! need_parent)
- return 2 ;
+ if (maxlen < 6 || ! need_parent)
+ return 3;
inode = dentry->d_parent->d_inode ;
- data[2] = inode->i_ino ;
- data[3] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ;
- *lenp = 4;
- return 4;
+ data[3] = inode->i_ino ;
+ data[4] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ;
+ data[5] = inode->i_generation ;
+ *lenp = 6;
+ return 6;
}
@@ -1447,6 +1417,20 @@
return NULL;
}
if (old_format_only (sb))
+ /* not a perfect generation count, as object ids can be reused, but this
+ ** is as good as reiserfs can do right now.
+ ** note that the private part of inode isn't filled in yet, we have
+ ** to use the directory.
+ */
+ inode->i_generation = INODE_PKEY (dir)->k_objectid;
+ else
+#if defined( USE_INODE_GENERATION_COUNTER )
+ inode->i_generation =
+ le32_to_cpu( sb -> u.reiserfs_sb.s_rs -> s_inode_generation );
+#else
+ 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);
else
make_le_item_head (&ih, 0, ITEM_VERSION_2, SD_OFFSET, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT);
@@ -1536,10 +1520,6 @@
return NULL;
}
- /* not a perfect generation count, as object ids can be reused, but this
- ** is as good as reiserfs can do right now
- */
- inode->i_generation = INODE_PKEY (inode)->k_dir_id;
insert_inode_hash (inode);
// we do not mark inode dirty: on disk content matches to the
// in-core one
@@ -1671,13 +1651,11 @@
** because the truncate might pack the item anyway
** (it will unmap bh if it packs).
*/
- prevent_flush_page_lock(page, p_s_inode) ;
journal_begin(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 ) ;
windex = push_journal_writer("reiserfs_vfs_truncate_file") ;
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 ) ;
- allow_flush_page_lock(page, p_s_inode) ;
if (page) {
length = offset & (blocksize - 1) ;
@@ -1719,7 +1697,6 @@
start_over:
lock_kernel() ;
- prevent_flush_page_lock(bh_result->b_page, inode) ;
journal_begin(&th, inode->i_sb, jbegin_count) ;
make_cpu_key(&key, inode, byte_offset, TYPE_ANY, 3) ;
@@ -1731,7 +1708,7 @@
goto out ;
}
- bh = get_bh(&path) ;
+ bh = get_last_bh(&path) ;
ih = get_ih(&path) ;
item = get_item(&path) ;
pos_in_item = path.pos_in_item ;
@@ -1785,7 +1762,6 @@
out:
pathrelse(&path) ;
journal_end(&th, inode->i_sb, jbegin_count) ;
- allow_flush_page_lock(bh_result->b_page, inode) ;
unlock_kernel() ;
/* this is where we fill in holes in the file. */
@@ -1814,7 +1790,7 @@
for(i = 0 ; i < nr ; i++) {
bh = bhp[i] ;
lock_buffer(bh) ;
- atomic_inc(&bh->b_count) ; /* async end_io handler decs this */
+ get_bh(bh) ; /* async end_io handler puts this */
set_buffer_async_io(bh) ;
/* submit_bh doesn't care if the buffer is dirty, but nobody
** later on in the call chain will be cleaning it. So, we
@@ -1950,29 +1926,27 @@
return generic_block_bmap(as, block, reiserfs_bmap) ;
}
+static int reiserfs_commit_write(struct file *f, struct page *page,
+ unsigned from, unsigned to) {
+ struct inode *inode = page->mapping->host;
+ int ret ;
-static int reiserfs_commit_write(struct file *f, struct page *page,
- unsigned from, unsigned to) {
- struct inode *inode = page->mapping->host ;
- int ret ;
- struct reiserfs_transaction_handle th ;
-
reiserfs_wait_on_write_block(inode->i_sb) ;
- lock_kernel();
- prevent_flush_page_lock(page, inode) ;
ret = generic_commit_write(f, page, from, to) ;
+
/* we test for O_SYNC here so we can commit the transaction
** for any packed tails the file might have had
*/
if (f->f_flags & O_SYNC) {
+ struct reiserfs_transaction_handle th ;
+ lock_kernel() ;
journal_begin(&th, inode->i_sb, 1) ;
reiserfs_prepare_for_journal(inode->i_sb,
SB_BUFFER_WITH_SB(inode->i_sb), 1) ;
journal_mark_dirty(&th, inode->i_sb, SB_BUFFER_WITH_SB(inode->i_sb)) ;
journal_end_sync(&th, inode->i_sb, 1) ;
+ unlock_kernel() ;
}
- allow_flush_page_lock(page, inode) ;
- unlock_kernel();
return ret ;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)