Commit 7bbbc1b5 authored by Oleg Drokin's avatar Oleg Drokin

Merge angband.namesys.com:/home/green/bk/linux-2.5

into angband.namesys.com:/home/green/bk_work/reiser3-linux-2.5
parents ea1e2d62 72c45511
...@@ -314,7 +314,7 @@ o <http://oss.software.ibm.com/jfs> ...@@ -314,7 +314,7 @@ o <http://oss.software.ibm.com/jfs>
Reiserfsprogs Reiserfsprogs
------------- -------------
o <ftp://ftp.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.x.0b.tar.gz> o <ftp://ftp.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.x.1b.tar.gz>
LVM toolset LVM toolset
----------- -----------
......
...@@ -103,7 +103,7 @@ static void _reiserfs_free_block (struct reiserfs_transaction_handle *th, unsign ...@@ -103,7 +103,7 @@ static void _reiserfs_free_block (struct reiserfs_transaction_handle *th, unsign
if (nr >= sb_bmap_nr (rs)) { if (nr >= sb_bmap_nr (rs)) {
reiserfs_warning ("vs-4075: reiserfs_free_block: " reiserfs_warning ("vs-4075: reiserfs_free_block: "
"block %lu is out of range on %s\n", "block %lu is out of range on %s\n",
block, s->s_id); block, reiserfs_bdevname (s));
return; return;
} }
...@@ -113,7 +113,7 @@ static void _reiserfs_free_block (struct reiserfs_transaction_handle *th, unsign ...@@ -113,7 +113,7 @@ static void _reiserfs_free_block (struct reiserfs_transaction_handle *th, unsign
if (!reiserfs_test_and_clear_le_bit (offset, apbh[nr]->b_data)) { if (!reiserfs_test_and_clear_le_bit (offset, apbh[nr]->b_data)) {
reiserfs_warning ("vs-4080: reiserfs_free_block: " reiserfs_warning ("vs-4080: reiserfs_free_block: "
"free_block (%s:%lu)[dev:blocknr]: bit already cleared\n", "free_block (%s:%lu)[dev:blocknr]: bit already cleared\n",
s->s_id, block); reiserfs_bdevname (s), block);
} }
journal_mark_dirty (th, s, apbh[nr]); journal_mark_dirty (th, s, apbh[nr]);
...@@ -139,10 +139,8 @@ void reiserfs_free_block (struct reiserfs_transaction_handle *th, ...@@ -139,10 +139,8 @@ void reiserfs_free_block (struct reiserfs_transaction_handle *th,
/* preallocated blocks don't need to be run through journal_mark_freed */ /* preallocated blocks don't need to be run through journal_mark_freed */
void reiserfs_free_prealloc_block (struct reiserfs_transaction_handle *th, void reiserfs_free_prealloc_block (struct reiserfs_transaction_handle *th,
unsigned long block) { unsigned long block) {
struct super_block * s = th->t_super; RFALSE(!th->t_super, "vs-4060: trying to free block on nonexistent device");
RFALSE(is_reusable (th->t_super, block, 1) == 0, "vs-4070: can not free such block");
RFALSE(!s, "vs-4060: trying to free block on nonexistent device");
RFALSE(is_reusable (s, block, 1) == 0, "vs-4070: can not free such block");
_reiserfs_free_block(th, block) ; _reiserfs_free_block(th, block) ;
} }
...@@ -670,10 +668,7 @@ int reiserfs_new_unf_blocknrs2 (struct reiserfs_transaction_handle *th, ...@@ -670,10 +668,7 @@ int reiserfs_new_unf_blocknrs2 (struct reiserfs_transaction_handle *th,
return ret; return ret;
} }
//
// a portion of this function, was derived from minix or ext2's
// analog. You should be able to tell which portion by looking at the
// ext2 code and comparing.
static void __discard_prealloc (struct reiserfs_transaction_handle * th, static void __discard_prealloc (struct reiserfs_transaction_handle * th,
struct reiserfs_inode_info *ei) struct reiserfs_inode_info *ei)
{ {
......
...@@ -24,9 +24,10 @@ struct file_operations reiserfs_dir_operations = { ...@@ -24,9 +24,10 @@ struct file_operations reiserfs_dir_operations = {
}; };
int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) { int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) {
lock_kernel(); struct inode *inode = dentry->d_inode;
reiserfs_commit_for_inode(dentry->d_inode) ; reiserfs_write_lock(inode->i_sb);
unlock_kernel() ; reiserfs_commit_for_inode(inode) ;
reiserfs_write_unlock(inode->i_sb) ;
return 0 ; return 0 ;
} }
...@@ -50,7 +51,7 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi ...@@ -50,7 +51,7 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi
struct reiserfs_dir_entry de; struct reiserfs_dir_entry de;
int ret = 0; int ret = 0;
lock_kernel(); reiserfs_write_lock(inode->i_sb);
reiserfs_check_lock_depth("readdir") ; reiserfs_check_lock_depth("readdir") ;
...@@ -109,7 +110,7 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi ...@@ -109,7 +110,7 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi
if (!d_name[d_reclen - 1]) if (!d_name[d_reclen - 1])
d_reclen = strlen (d_name); d_reclen = strlen (d_name);
if (d_reclen > REISERFS_MAX_NAME_LEN(inode->i_sb->s_blocksize)){ if (d_reclen > REISERFS_MAX_NAME(inode->i_sb->s_blocksize)){
/* too big to send back to VFS */ /* too big to send back to VFS */
continue ; continue ;
} }
...@@ -181,13 +182,12 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi ...@@ -181,13 +182,12 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi
end: end:
// FIXME: ext2_readdir does not reset f_pos
filp->f_pos = next_pos; filp->f_pos = next_pos;
pathrelse (&path_to_entry); pathrelse (&path_to_entry);
reiserfs_check_path(&path_to_entry) ; reiserfs_check_path(&path_to_entry) ;
UPDATE_ATIME(inode) ; UPDATE_ATIME(inode) ;
out: out:
unlock_kernel(); reiserfs_write_unlock(inode->i_sb);
return ret; return ret;
} }
......
...@@ -39,7 +39,7 @@ static int reiserfs_file_release (struct inode * inode, struct file * filp) ...@@ -39,7 +39,7 @@ static int reiserfs_file_release (struct inode * inode, struct file * filp)
return 0; return 0;
} }
lock_kernel() ; reiserfs_write_lock(inode->i_sb);
down (&inode->i_sem); down (&inode->i_sem);
journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ; journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
reiserfs_update_inode_transaction(inode) ; reiserfs_update_inode_transaction(inode) ;
...@@ -61,14 +61,12 @@ static int reiserfs_file_release (struct inode * inode, struct file * filp) ...@@ -61,14 +61,12 @@ static int reiserfs_file_release (struct inode * inode, struct file * filp)
pop_journal_writer(windex) ; pop_journal_writer(windex) ;
} }
up (&inode->i_sem); up (&inode->i_sem);
unlock_kernel() ; reiserfs_write_unlock(inode->i_sb);
return 0; return 0;
} }
static void reiserfs_vfs_truncate_file(struct inode *inode) { static void reiserfs_vfs_truncate_file(struct inode *inode) {
lock_kernel();
reiserfs_truncate_file(inode, 1) ; reiserfs_truncate_file(inode, 1) ;
unlock_kernel();
} }
/* Sync a reiserfs file. */ /* Sync a reiserfs file. */
...@@ -86,21 +84,21 @@ static int reiserfs_sync_file( ...@@ -86,21 +84,21 @@ static int reiserfs_sync_file(
struct inode * p_s_inode = p_s_dentry->d_inode; struct inode * p_s_inode = p_s_dentry->d_inode;
int n_err; int n_err;
lock_kernel() ; reiserfs_write_lock(p_s_inode->i_sb);
if (!S_ISREG(p_s_inode->i_mode)) if (!S_ISREG(p_s_inode->i_mode))
BUG (); BUG ();
n_err = sync_mapping_buffers(p_s_inode->i_mapping) ; n_err = sync_mapping_buffers(p_s_inode->i_mapping) ;
reiserfs_commit_for_inode(p_s_inode) ; reiserfs_commit_for_inode(p_s_inode) ;
unlock_kernel() ; reiserfs_write_unlock(p_s_inode->i_sb);
return ( n_err < 0 ) ? -EIO : 0; return ( n_err < 0 ) ? -EIO : 0;
} }
static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) { static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
struct inode *inode = dentry->d_inode ; struct inode *inode = dentry->d_inode ;
int error ; int error ;
lock_kernel(); reiserfs_write_lock(inode->i_sb);
if (attr->ia_valid & ATTR_SIZE) { if (attr->ia_valid & ATTR_SIZE) {
/* version 2 items will be caught by the s_maxbytes check /* version 2 items will be caught by the s_maxbytes check
** done for us in vmtruncate ** done for us in vmtruncate
...@@ -138,7 +136,7 @@ static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) { ...@@ -138,7 +136,7 @@ static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
inode_setattr(inode, attr) ; inode_setattr(inode, attr) ;
out: out:
unlock_kernel(); reiserfs_write_unlock(inode->i_sb);
return error ; return error ;
} }
......
...@@ -2092,21 +2092,27 @@ static void tb_buffer_sanity_check (struct super_block * p_s_sb, ...@@ -2092,21 +2092,27 @@ static void tb_buffer_sanity_check (struct super_block * p_s_sb,
if (p_s_bh) { if (p_s_bh) {
if (atomic_read (&(p_s_bh->b_count)) <= 0) { if (atomic_read (&(p_s_bh->b_count)) <= 0) {
reiserfs_panic (p_s_sb, "tb_buffer_sanity_check(): negative or zero reference counter for buffer %s[%d] (%b)\n", descr, level, p_s_bh); reiserfs_panic (p_s_sb, "jmacd-1: tb_buffer_sanity_check(): negative or zero reference counter for buffer %s[%d] (%b)\n", descr, level, p_s_bh);
} }
if ( ! buffer_uptodate (p_s_bh) ) { if ( ! buffer_uptodate (p_s_bh) ) {
reiserfs_panic (p_s_sb, "tb_buffer_sanity_check(): buffer is not up to date %s[%d] (%b)\n", descr, level, p_s_bh); reiserfs_panic (p_s_sb, "jmacd-2: tb_buffer_sanity_check(): buffer is not up to date %s[%d] (%b)\n", descr, level, p_s_bh);
} }
if ( ! B_IS_IN_TREE (p_s_bh) ) { if ( ! B_IS_IN_TREE (p_s_bh) ) {
reiserfs_panic (p_s_sb, "tb_buffer_sanity_check(): buffer is not in tree %s[%d] (%b)\n", descr, level, p_s_bh); reiserfs_panic (p_s_sb, "jmacd-3: tb_buffer_sanity_check(): buffer is not in tree %s[%d] (%b)\n", descr, level, p_s_bh);
} }
if (p_s_bh->b_bdev != p_s_sb->s_bdev || if (p_s_bh->b_bdev != p_s_sb->s_bdev) {
p_s_bh->b_size != p_s_sb->s_blocksize || reiserfs_panic (p_s_sb, "jmacd-4: tb_buffer_sanity_check(): buffer has wrong device %s[%d] (%b)\n", descr, level, p_s_bh);
p_s_bh->b_blocknr > SB_BLOCK_COUNT(p_s_sb)) { }
reiserfs_panic (p_s_sb, "tb_buffer_sanity_check(): check failed for buffer %s[%d] (%b)\n", descr, level, p_s_bh);
if (p_s_bh->b_size != p_s_sb->s_blocksize) {
reiserfs_panic (p_s_sb, "jmacd-5: tb_buffer_sanity_check(): buffer has wrong blocksize %s[%d] (%b)\n", descr, level, p_s_bh);
}
if (p_s_bh->b_blocknr > SB_BLOCK_COUNT(p_s_sb)) {
reiserfs_panic (p_s_sb, "jmacd-6: tb_buffer_sanity_check(): buffer block number too high %s[%d] (%b)\n", descr, level, p_s_bh);
} }
} }
} }
......
...@@ -20,10 +20,7 @@ ...@@ -20,10 +20,7 @@
static int reiserfs_get_block (struct inode * inode, sector_t block, static int reiserfs_get_block (struct inode * inode, sector_t block,
struct buffer_head * bh_result, int create); struct buffer_head * bh_result, int create);
//
// initially this function was derived from minix or ext2's analog and
// evolved as the prototype did
//
void reiserfs_delete_inode (struct inode * inode) void reiserfs_delete_inode (struct inode * inode)
{ {
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2; int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2;
...@@ -31,7 +28,7 @@ void reiserfs_delete_inode (struct inode * inode) ...@@ -31,7 +28,7 @@ void reiserfs_delete_inode (struct inode * inode)
struct reiserfs_transaction_handle th ; struct reiserfs_transaction_handle th ;
lock_kernel() ; reiserfs_write_lock(inode->i_sb);
/* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
...@@ -56,7 +53,7 @@ void reiserfs_delete_inode (struct inode * inode) ...@@ -56,7 +53,7 @@ void reiserfs_delete_inode (struct inode * inode)
} }
clear_inode (inode); /* note this must go after the journal_end to prevent deadlock */ clear_inode (inode); /* note this must go after the journal_end to prevent deadlock */
inode->i_blocks = 0; inode->i_blocks = 0;
unlock_kernel() ; reiserfs_write_unlock(inode->i_sb);
} }
static void _make_cpu_key (struct cpu_key * key, int version, __u32 dirid, __u32 objectid, static void _make_cpu_key (struct cpu_key * key, int version, __u32 dirid, __u32 objectid,
...@@ -112,8 +109,7 @@ static void add_to_flushlist(struct inode *inode, struct buffer_head *bh) { ...@@ -112,8 +109,7 @@ static void add_to_flushlist(struct inode *inode, struct buffer_head *bh) {
} }
// //
// FIXME: we might cache recently accessed indirect item (or at least // FIXME: we might cache recently accessed indirect item
// first 15 pointers just like ext2 does
// Ugh. Not too eager for that.... // Ugh. Not too eager for that....
// I cut the code until such time as I see a convincing argument (benchmark). // I cut the code until such time as I see a convincing argument (benchmark).
...@@ -412,10 +408,10 @@ int reiserfs_bmap (struct inode * inode, sector_t block, ...@@ -412,10 +408,10 @@ int reiserfs_bmap (struct inode * inode, sector_t block,
if (!file_capable (inode, block)) if (!file_capable (inode, block))
return -EFBIG; return -EFBIG;
lock_kernel() ; reiserfs_write_lock(inode->i_sb);
/* do not read the direct item */ /* do not read the direct item */
_get_block_create_0 (inode, block, bh_result, 0) ; _get_block_create_0 (inode, block, bh_result, 0) ;
unlock_kernel() ; reiserfs_write_unlock(inode->i_sb);
return 0; return 0;
} }
...@@ -521,12 +517,7 @@ static inline int _allocate_block(struct reiserfs_transaction_handle *th, ...@@ -521,12 +517,7 @@ static inline int _allocate_block(struct reiserfs_transaction_handle *th,
#endif #endif
return reiserfs_new_unf_blocknrs (th, allocated_block_nr, tag); return reiserfs_new_unf_blocknrs (th, allocated_block_nr, tag);
} }
//
// initially this function was derived from ext2's analog and evolved
// as the prototype did. You'll need to look at the ext2 version to
// determine which parts are derivative, if any, understanding that
// there are only so many ways to code to a given interface.
//
int reiserfs_get_block (struct inode * inode, sector_t block, int reiserfs_get_block (struct inode * inode, sector_t block,
struct buffer_head * bh_result, int create) struct buffer_head * bh_result, int create)
{ {
...@@ -554,17 +545,17 @@ int reiserfs_get_block (struct inode * inode, sector_t block, ...@@ -554,17 +545,17 @@ int reiserfs_get_block (struct inode * inode, sector_t block,
loff_t new_offset = (((loff_t)block) << inode->i_sb->s_blocksize_bits) + 1 ; loff_t new_offset = (((loff_t)block) << inode->i_sb->s_blocksize_bits) + 1 ;
/* bad.... */ /* bad.... */
lock_kernel() ; reiserfs_write_lock(inode->i_sb);
th.t_trans_id = 0 ; th.t_trans_id = 0 ;
version = get_inode_item_key_version (inode); version = get_inode_item_key_version (inode);
if (block < 0) { if (block < 0) {
unlock_kernel(); reiserfs_write_unlock(inode->i_sb);
return -EIO; return -EIO;
} }
if (!file_capable (inode, block)) { if (!file_capable (inode, block)) {
unlock_kernel() ; reiserfs_write_unlock(inode->i_sb);
return -EFBIG; return -EFBIG;
} }
...@@ -576,7 +567,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block, ...@@ -576,7 +567,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block,
/* find number of block-th logical block of the file */ /* find number of block-th logical block of the file */
ret = _get_block_create_0 (inode, block, bh_result, ret = _get_block_create_0 (inode, block, bh_result,
create | GET_BLOCK_READ_DIRECT) ; create | GET_BLOCK_READ_DIRECT) ;
unlock_kernel() ; reiserfs_write_unlock(inode->i_sb);
return ret; return ret;
} }
...@@ -667,7 +658,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block, ...@@ -667,7 +658,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block,
if (transaction_started) if (transaction_started)
journal_end(&th, inode->i_sb, jbegin_count) ; journal_end(&th, inode->i_sb, jbegin_count) ;
unlock_kernel() ; reiserfs_write_unlock(inode->i_sb);
/* the item was found, so new blocks were not added to the file /* the item was found, so new blocks were not added to the file
** there is no need to make sure the inode is updated with this ** there is no need to make sure the inode is updated with this
...@@ -866,7 +857,6 @@ int reiserfs_get_block (struct inode * inode, sector_t block, ...@@ -866,7 +857,6 @@ int reiserfs_get_block (struct inode * inode, sector_t block,
retval = 0; retval = 0;
reiserfs_check_path(&path) ;
failure: failure:
if (transaction_started) { if (transaction_started) {
...@@ -874,7 +864,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block, ...@@ -874,7 +864,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block,
journal_end(&th, inode->i_sb, jbegin_count) ; journal_end(&th, inode->i_sb, jbegin_count) ;
} }
pop_journal_writer(windex) ; pop_journal_writer(windex) ;
unlock_kernel() ; reiserfs_write_unlock(inode->i_sb);
reiserfs_check_path(&path) ; reiserfs_check_path(&path) ;
return retval; return retval;
} }
...@@ -1353,10 +1343,6 @@ int reiserfs_encode_fh(struct dentry *dentry, __u32 *data, int *lenp, int need_p ...@@ -1353,10 +1343,6 @@ int reiserfs_encode_fh(struct dentry *dentry, __u32 *data, int *lenp, int need_p
} }
//
// initially this function was derived from minix or ext2's analog and
// evolved as the prototype did
//
/* looks for stat data, then copies fields to it, marks the buffer /* looks for stat data, then copies fields to it, marks the buffer
containing stat data as dirty */ containing stat data as dirty */
/* reiserfs inodes are never really dirty, since the dirty inode call /* reiserfs inodes are never really dirty, since the dirty inode call
...@@ -1379,11 +1365,11 @@ void reiserfs_write_inode (struct inode * inode, int do_sync) { ...@@ -1379,11 +1365,11 @@ void reiserfs_write_inode (struct inode * inode, int do_sync) {
** ignored because the altered inode has already been logged. ** ignored because the altered inode has already been logged.
*/ */
if (do_sync && !(current->flags & PF_MEMALLOC)) { if (do_sync && !(current->flags & PF_MEMALLOC)) {
lock_kernel() ; reiserfs_write_lock(inode->i_sb);
journal_begin(&th, inode->i_sb, jbegin_count) ; journal_begin(&th, inode->i_sb, jbegin_count) ;
reiserfs_update_sd (&th, inode); reiserfs_update_sd (&th, inode);
journal_end_sync(&th, inode->i_sb, jbegin_count) ; journal_end_sync(&th, inode->i_sb, jbegin_count) ;
unlock_kernel() ; reiserfs_write_unlock(inode->i_sb);
} }
} }
...@@ -1725,7 +1711,8 @@ static int grab_tail_page(struct inode *p_s_inode, ...@@ -1725,7 +1711,8 @@ static int grab_tail_page(struct inode *p_s_inode,
** call prepare_write ** call prepare_write
*/ */
reiserfs_warning("clm-6000: error reading block %lu on dev %s\n", reiserfs_warning("clm-6000: error reading block %lu on dev %s\n",
bh->b_blocknr, p_s_inode->i_sb->s_id) ; bh->b_blocknr,
reiserfs_bdevname (p_s_inode->i_sb)) ;
error = -EIO ; error = -EIO ;
goto unlock ; goto unlock ;
} }
...@@ -1750,7 +1737,6 @@ static int grab_tail_page(struct inode *p_s_inode, ...@@ -1750,7 +1737,6 @@ static int grab_tail_page(struct inode *p_s_inode,
void reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) { void reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) {
struct reiserfs_transaction_handle th ; struct reiserfs_transaction_handle th ;
int windex ; int windex ;
/* we want the offset for the first byte after the end of the file */ /* we want the offset for the first byte after the end of the file */
unsigned long offset = p_s_inode->i_size & (PAGE_CACHE_SIZE - 1) ; unsigned long offset = p_s_inode->i_size & (PAGE_CACHE_SIZE - 1) ;
unsigned blocksize = p_s_inode->i_sb->s_blocksize ; unsigned blocksize = p_s_inode->i_sb->s_blocksize ;
...@@ -1759,6 +1745,8 @@ void reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) { ...@@ -1759,6 +1745,8 @@ void reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) {
int error ; int error ;
struct buffer_head *bh = NULL ; struct buffer_head *bh = NULL ;
reiserfs_write_lock(p_s_inode->i_sb);
if (p_s_inode->i_size > 0) { if (p_s_inode->i_size > 0) {
if ((error = grab_tail_page(p_s_inode, &page, &bh))) { if ((error = grab_tail_page(p_s_inode, &page, &bh))) {
// -ENOENT means we truncated past the end of the file, // -ENOENT means we truncated past the end of the file,
...@@ -1812,7 +1800,7 @@ void reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) { ...@@ -1812,7 +1800,7 @@ void reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) {
page_cache_release(page) ; page_cache_release(page) ;
} }
return ; reiserfs_write_unlock(p_s_inode->i_sb);
} }
static int map_block_for_writepage(struct inode *inode, static int map_block_for_writepage(struct inode *inode,
...@@ -1836,7 +1824,7 @@ static int map_block_for_writepage(struct inode *inode, ...@@ -1836,7 +1824,7 @@ static int map_block_for_writepage(struct inode *inode,
kmap(bh_result->b_page) ; kmap(bh_result->b_page) ;
start_over: start_over:
lock_kernel() ; reiserfs_write_lock(inode->i_sb);
journal_begin(&th, inode->i_sb, jbegin_count) ; journal_begin(&th, inode->i_sb, jbegin_count) ;
reiserfs_update_inode_transaction(inode) ; reiserfs_update_inode_transaction(inode) ;
...@@ -1894,7 +1882,7 @@ static int map_block_for_writepage(struct inode *inode, ...@@ -1894,7 +1882,7 @@ static int map_block_for_writepage(struct inode *inode,
goto research ; goto research ;
} }
} else { } else {
reiserfs_warning("clm-6003: bad item inode %lu, device %s\n", inode->i_ino, inode->i_sb->s_id) ; reiserfs_warning("clm-6003: bad item inode %lu, device %s\n", inode->i_ino, reiserfs_bdevname (inode->i_sb)) ;
retval = -EIO ; retval = -EIO ;
goto out ; goto out ;
} }
...@@ -1903,7 +1891,7 @@ static int map_block_for_writepage(struct inode *inode, ...@@ -1903,7 +1891,7 @@ static int map_block_for_writepage(struct inode *inode,
out: out:
pathrelse(&path) ; pathrelse(&path) ;
journal_end(&th, inode->i_sb, jbegin_count) ; journal_end(&th, inode->i_sb, jbegin_count) ;
unlock_kernel() ; reiserfs_write_unlock(inode->i_sb);
/* this is where we fill in holes in the file. */ /* this is where we fill in holes in the file. */
if (use_get_block) { if (use_get_block) {
...@@ -2033,18 +2021,13 @@ static int reiserfs_write_full_page(struct page *page) { ...@@ -2033,18 +2021,13 @@ static int reiserfs_write_full_page(struct page *page) {
return error ; return error ;
} }
//
// this is exactly what 2.3.99-pre9's ext2_readpage is
//
static int reiserfs_readpage (struct file *f, struct page * page) static int reiserfs_readpage (struct file *f, struct page * page)
{ {
return block_read_full_page (page, reiserfs_get_block); return block_read_full_page (page, reiserfs_get_block);
} }
//
// modified from ext2_writepage is
//
static int reiserfs_writepage (struct page * page) static int reiserfs_writepage (struct page * page)
{ {
struct inode *inode = page->mapping->host ; struct inode *inode = page->mapping->host ;
...@@ -2053,9 +2036,6 @@ static int reiserfs_writepage (struct page * page) ...@@ -2053,9 +2036,6 @@ static int reiserfs_writepage (struct page * page)
} }
//
// from ext2_prepare_write, but modified
//
int reiserfs_prepare_write(struct file *f, struct page *page, int reiserfs_prepare_write(struct file *f, struct page *page,
unsigned from, unsigned to) { unsigned from, unsigned to) {
struct inode *inode = page->mapping->host ; struct inode *inode = page->mapping->host ;
...@@ -2065,9 +2045,6 @@ int reiserfs_prepare_write(struct file *f, struct page *page, ...@@ -2065,9 +2045,6 @@ int reiserfs_prepare_write(struct file *f, struct page *page,
} }
//
// this is exactly what 2.3.99-pre9's ext2_bmap is
//
static int reiserfs_aop_bmap(struct address_space *as, long block) { static int reiserfs_aop_bmap(struct address_space *as, long block) {
return generic_block_bmap(as, block, reiserfs_bmap) ; return generic_block_bmap(as, block, reiserfs_bmap) ;
} }
...@@ -2086,13 +2063,13 @@ static int reiserfs_commit_write(struct file *f, struct page *page, ...@@ -2086,13 +2063,13 @@ static int reiserfs_commit_write(struct file *f, struct page *page,
*/ */
if (pos > inode->i_size) { if (pos > inode->i_size) {
struct reiserfs_transaction_handle th ; struct reiserfs_transaction_handle th ;
lock_kernel() ; reiserfs_write_lock(inode->i_sb);
journal_begin(&th, inode->i_sb, 1) ; journal_begin(&th, inode->i_sb, 1) ;
reiserfs_update_inode_transaction(inode) ; reiserfs_update_inode_transaction(inode) ;
inode->i_size = pos ; inode->i_size = pos ;
reiserfs_update_sd(&th, inode) ; reiserfs_update_sd(&th, inode) ;
journal_end(&th, inode->i_sb, 1) ; journal_end(&th, inode->i_sb, 1) ;
unlock_kernel() ; reiserfs_write_unlock(inode->i_sb);
} }
ret = generic_commit_write(f, page, from, to) ; ret = generic_commit_write(f, page, from, to) ;
...@@ -2101,9 +2078,9 @@ static int reiserfs_commit_write(struct file *f, struct page *page, ...@@ -2101,9 +2078,9 @@ static int reiserfs_commit_write(struct file *f, struct page *page,
** for any packed tails the file might have had ** for any packed tails the file might have had
*/ */
if (f && (f->f_flags & O_SYNC)) { if (f && (f->f_flags & O_SYNC)) {
lock_kernel() ; reiserfs_write_lock(inode->i_sb);
reiserfs_commit_for_inode(inode) ; reiserfs_commit_for_inode(inode) ;
unlock_kernel(); reiserfs_write_unlock(inode->i_sb);
} }
return ret ; return ret ;
} }
......
...@@ -49,7 +49,7 @@ int reiserfs_unpack (struct inode * inode, struct file * filp) ...@@ -49,7 +49,7 @@ int reiserfs_unpack (struct inode * inode, struct file * filp)
if (REISERFS_I(inode)->i_flags & i_nopack_mask) { if (REISERFS_I(inode)->i_flags & i_nopack_mask) {
return 0 ; return 0 ;
} }
lock_kernel(); reiserfs_write_lock(inode->i_sb);
/* we need to make sure nobody is changing the file size beneath /* we need to make sure nobody is changing the file size beneath
** us ** us
...@@ -88,6 +88,6 @@ int reiserfs_unpack (struct inode * inode, struct file * filp) ...@@ -88,6 +88,6 @@ int reiserfs_unpack (struct inode * inode, struct file * filp)
out: out:
up(&inode->i_sem) ; up(&inode->i_sem) ;
unlock_kernel(); reiserfs_write_unlock(inode->i_sb);
return retval; return retval;
} }
...@@ -99,21 +99,6 @@ static int journal_join(struct reiserfs_transaction_handle *th, struct super_blo ...@@ -99,21 +99,6 @@ static int journal_join(struct reiserfs_transaction_handle *th, struct super_blo
static int release_journal_dev( struct super_block *super, static int release_journal_dev( struct super_block *super,
struct reiserfs_journal *journal ); struct reiserfs_journal *journal );
static inline struct buffer_head *journ_get_hash_table(struct super_block *s, int block)
{
return __get_hash_table(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize);
}
static inline struct buffer_head *journ_getblk(struct super_block *s, int block)
{
return __getblk(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize);
}
static inline struct buffer_head *journ_bread(struct super_block *s, int block)
{
return __bread(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize);
}
static void init_journal_hash(struct super_block *p_s_sb) { static void init_journal_hash(struct super_block *p_s_sb) {
memset(SB_JOURNAL(p_s_sb)->j_hash_table, 0, JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *)) ; memset(SB_JOURNAL(p_s_sb)->j_hash_table, 0, JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *)) ;
} }
...@@ -704,7 +689,7 @@ static int flush_commit_list(struct super_block *s, struct reiserfs_journal_list ...@@ -704,7 +689,7 @@ static int flush_commit_list(struct super_block *s, struct reiserfs_journal_list
count = 0 ; count = 0 ;
for (i = 0 ; atomic_read(&(jl->j_commit_left)) > 1 && i < (jl->j_len + 1) ; i++) { /* everything but commit_bh */ for (i = 0 ; atomic_read(&(jl->j_commit_left)) > 1 && i < (jl->j_len + 1) ; i++) { /* everything but commit_bh */
bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start+i) % SB_ONDISK_JOURNAL_SIZE(s); bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start+i) % SB_ONDISK_JOURNAL_SIZE(s);
tbh = journ_get_hash_table(s, bn) ; tbh = journal_get_hash_table(s, bn) ;
/* kill this sanity check */ /* kill this sanity check */
if (count > (orig_commit_left + 2)) { if (count > (orig_commit_left + 2)) {
...@@ -733,7 +718,7 @@ reiserfs_panic(s, "journal-539: flush_commit_list: BAD count(%d) > orig_commit_l ...@@ -733,7 +718,7 @@ reiserfs_panic(s, "journal-539: flush_commit_list: BAD count(%d) > orig_commit_l
for (i = 0 ; atomic_read(&(jl->j_commit_left)) > 1 && for (i = 0 ; atomic_read(&(jl->j_commit_left)) > 1 &&
i < (jl->j_len + 1) ; i++) { /* everything but commit_bh */ i < (jl->j_len + 1) ; i++) { /* everything but commit_bh */
bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start + i) % SB_ONDISK_JOURNAL_SIZE(s) ; bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start + i) % SB_ONDISK_JOURNAL_SIZE(s) ;
tbh = journ_get_hash_table(s, bn) ; tbh = journal_get_hash_table(s, bn) ;
wait_on_buffer(tbh) ; wait_on_buffer(tbh) ;
if (!buffer_uptodate(tbh)) { if (!buffer_uptodate(tbh)) {
...@@ -1426,7 +1411,7 @@ static int journal_transaction_is_valid(struct super_block *p_s_sb, struct buffe ...@@ -1426,7 +1411,7 @@ static int journal_transaction_is_valid(struct super_block *p_s_sb, struct buffe
offset = d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ; offset = d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
/* ok, we have a journal description block, lets see if the transaction was valid */ /* ok, we have a journal description block, lets see if the transaction was valid */
c_bh = journ_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + c_bh = journal_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
((offset + le32_to_cpu(desc->j_len) + 1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ; ((offset + le32_to_cpu(desc->j_len) + 1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
if (!c_bh) if (!c_bh)
return 0 ; return 0 ;
...@@ -1481,7 +1466,7 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu ...@@ -1481,7 +1466,7 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu
unsigned long trans_offset ; unsigned long trans_offset ;
int i; int i;
d_bh = journ_bread(p_s_sb, cur_dblock) ; d_bh = journal_bread(p_s_sb, cur_dblock) ;
if (!d_bh) if (!d_bh)
return 1 ; return 1 ;
desc = (struct reiserfs_journal_desc *)d_bh->b_data ; desc = (struct reiserfs_journal_desc *)d_bh->b_data ;
...@@ -1505,7 +1490,7 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu ...@@ -1505,7 +1490,7 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu
brelse(d_bh) ; brelse(d_bh) ;
return 1 ; return 1 ;
} }
c_bh = journ_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + c_bh = journal_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
((trans_offset + le32_to_cpu(desc->j_len) + 1) % ((trans_offset + le32_to_cpu(desc->j_len) + 1) %
SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ; SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
if (!c_bh) { if (!c_bh) {
...@@ -1536,7 +1521,7 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu ...@@ -1536,7 +1521,7 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu
} }
/* get all the buffer heads */ /* get all the buffer heads */
for(i = 0 ; i < le32_to_cpu(desc->j_len) ; i++) { for(i = 0 ; i < le32_to_cpu(desc->j_len) ; i++) {
log_blocks[i] = journ_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + (trans_offset + 1 + i) % SB_ONDISK_JOURNAL_SIZE(p_s_sb)); log_blocks[i] = journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + (trans_offset + 1 + i) % SB_ONDISK_JOURNAL_SIZE(p_s_sb));
if (i < JOURNAL_TRANS_HALF) { if (i < JOURNAL_TRANS_HALF) {
real_blocks[i] = sb_getblk(p_s_sb, le32_to_cpu(desc->j_realblock[i])) ; real_blocks[i] = sb_getblk(p_s_sb, le32_to_cpu(desc->j_realblock[i])) ;
} else { } else {
...@@ -1606,16 +1591,13 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu ...@@ -1606,16 +1591,13 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu
return 0 ; return 0 ;
} }
/* /* This function reads blocks starting from block and to max_block of bufsize
** read and replay the log size (but no more than BUFNR blocks at a time). This proved to improve
** on a clean unmount, the journal header's next unflushed pointer will be to an invalid mounting speed on self-rebuilding raid5 arrays at least.
** transaction. This tests that before finding all the transactions in the log, whic makes normal mount times fast. Right now it is only used from journal code. But later we might use it
** from other places.
** After a crash, this starts with the next unflushed transaction, and replays until it finds one too old, or invalid. Note: Do not use journal_getblk/sb_getblk functions here! */
** struct buffer_head * reiserfs_breada (struct block_device *dev, int block, int bufsize,
** On exit, it sets things up so the first transaction will work correctly.
*/
struct buffer_head * reiserfs_breada (struct super_block *sb, int block,
unsigned int max_block) unsigned int max_block)
{ {
struct buffer_head * bhlist[BUFNR]; struct buffer_head * bhlist[BUFNR];
...@@ -1623,7 +1605,7 @@ struct buffer_head * reiserfs_breada (struct super_block *sb, int block, ...@@ -1623,7 +1605,7 @@ struct buffer_head * reiserfs_breada (struct super_block *sb, int block,
struct buffer_head * bh; struct buffer_head * bh;
int i, j; int i, j;
bh = sb_getblk (sb, block); bh = __getblk (dev, block, bufsize );
if (buffer_uptodate (bh)) if (buffer_uptodate (bh))
return (bh); return (bh);
...@@ -1633,7 +1615,7 @@ struct buffer_head * reiserfs_breada (struct super_block *sb, int block, ...@@ -1633,7 +1615,7 @@ struct buffer_head * reiserfs_breada (struct super_block *sb, int block,
bhlist[0] = bh; bhlist[0] = bh;
j = 1; j = 1;
for (i = 1; i < blocks; i++) { for (i = 1; i < blocks; i++) {
bh = sb_getblk (sb, block + i); bh = __getblk (dev, block + i, bufsize);
if (buffer_uptodate (bh)) { if (buffer_uptodate (bh)) {
brelse (bh); brelse (bh);
break; break;
...@@ -1650,6 +1632,16 @@ struct buffer_head * reiserfs_breada (struct super_block *sb, int block, ...@@ -1650,6 +1632,16 @@ struct buffer_head * reiserfs_breada (struct super_block *sb, int block,
brelse (bh); brelse (bh);
return NULL; return NULL;
} }
/*
** read and replay the log
** on a clean unmount, the journal header's next unflushed pointer will be to an invalid
** transaction. This tests that before finding all the transactions in the log, whic makes normal mount times fast.
**
** After a crash, this starts with the next unflushed transaction, and replays until it finds one too old, or invalid.
**
** On exit, it sets things up so the first transaction will work correctly.
*/
static int journal_read(struct super_block *p_s_sb) { static int journal_read(struct super_block *p_s_sb) {
struct reiserfs_journal_desc *desc ; struct reiserfs_journal_desc *desc ;
unsigned long oldest_trans_id = 0; unsigned long oldest_trans_id = 0;
...@@ -1667,14 +1659,14 @@ static int journal_read(struct super_block *p_s_sb) { ...@@ -1667,14 +1659,14 @@ static int journal_read(struct super_block *p_s_sb) {
cur_dblock = SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ; cur_dblock = SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
printk("reiserfs: checking transaction log (%s) for (%s)\n", printk("reiserfs: checking transaction log (%s) for (%s)\n",
__bdevname(SB_JOURNAL_DEV(p_s_sb)), p_s_sb->s_id) ; bdevname(SB_JOURNAL(p_s_sb)->j_dev_bd), reiserfs_bdevname(p_s_sb));
start = CURRENT_TIME ; start = CURRENT_TIME ;
/* step 1, read in the journal header block. Check the transaction it says /* step 1, read in the journal header block. Check the transaction it says
** is the first unflushed, and if that transaction is not valid, ** is the first unflushed, and if that transaction is not valid,
** replay is done ** replay is done
*/ */
SB_JOURNAL(p_s_sb)->j_header_bh = journ_bread(p_s_sb, SB_JOURNAL(p_s_sb)->j_header_bh = journal_bread(p_s_sb,
SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
SB_ONDISK_JOURNAL_SIZE(p_s_sb)); SB_ONDISK_JOURNAL_SIZE(p_s_sb));
if (!SB_JOURNAL(p_s_sb)->j_header_bh) { if (!SB_JOURNAL(p_s_sb)->j_header_bh) {
...@@ -1698,7 +1690,7 @@ static int journal_read(struct super_block *p_s_sb) { ...@@ -1698,7 +1690,7 @@ static int journal_read(struct super_block *p_s_sb) {
** there is nothing more we can do, and it makes no sense to read ** there is nothing more we can do, and it makes no sense to read
** through the whole log. ** through the whole log.
*/ */
d_bh = journ_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + le32_to_cpu(jh->j_first_unflushed_offset)) ; d_bh = journal_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + le32_to_cpu(jh->j_first_unflushed_offset)) ;
ret = journal_transaction_is_valid(p_s_sb, d_bh, NULL, NULL) ; ret = journal_transaction_is_valid(p_s_sb, d_bh, NULL, NULL) ;
if (!ret) { if (!ret) {
continue_replay = 0 ; continue_replay = 0 ;
...@@ -1716,7 +1708,9 @@ static int journal_read(struct super_block *p_s_sb) { ...@@ -1716,7 +1708,9 @@ static int journal_read(struct super_block *p_s_sb) {
** all the valid transactions, and pick out the oldest. ** all the valid transactions, and pick out the oldest.
*/ */
while(continue_replay && cur_dblock < (SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb))) { while(continue_replay && cur_dblock < (SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb))) {
d_bh = reiserfs_breada(p_s_sb, cur_dblock, /* Note that it is required for blocksize of primary fs device and journal
device to be the same */
d_bh = reiserfs_breada(SB_JOURNAL(p_s_sb)->j_dev_bd, cur_dblock, p_s_sb->s_blocksize,
SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb)) ; SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb)) ;
ret = journal_transaction_is_valid(p_s_sb, d_bh, &oldest_invalid_trans_id, &newest_mount_id) ; ret = journal_transaction_is_valid(p_s_sb, d_bh, &oldest_invalid_trans_id, &newest_mount_id) ;
if (ret == 1) { if (ret == 1) {
...@@ -1925,13 +1919,20 @@ static int release_journal_dev( struct super_block *super, ...@@ -1925,13 +1919,20 @@ static int release_journal_dev( struct super_block *super,
result = 0; result = 0;
if( journal -> j_dev_bd != NULL ) {
result = blkdev_put( journal -> j_dev_bd, BDEV_FS );
journal -> j_dev_bd = NULL;
}
if( journal -> j_dev_file != NULL ) { if( journal -> j_dev_file != NULL ) {
/*
* journal block device was taken via filp_open
*/
result = filp_close( journal -> j_dev_file, NULL ); result = filp_close( journal -> j_dev_file, NULL );
journal -> j_dev_file = NULL; journal -> j_dev_file = NULL;
journal -> j_dev_bd = NULL;
} else if( journal -> j_dev_bd != NULL ) {
/*
* journal block device was taken via bdget and blkdev_get
*/
result = blkdev_put( journal -> j_dev_bd, BDEV_FS );
journal -> j_dev_bd = NULL;
} }
if( result != 0 ) { if( result != 0 ) {
reiserfs_warning("sh-457: release_journal_dev: Cannot release journal device: %i", result ); reiserfs_warning("sh-457: release_journal_dev: Cannot release journal device: %i", result );
...@@ -1966,6 +1967,9 @@ static int journal_init_dev( struct super_block *super, ...@@ -1966,6 +1967,9 @@ static int journal_init_dev( struct super_block *super,
printk( "sh-458: journal_init_dev: cannot init journal device\n '%s': %i", printk( "sh-458: journal_init_dev: cannot init journal device\n '%s': %i",
kdevname( jdev ), result ); kdevname( jdev ), result );
else if (!kdev_same(jdev, super->s_dev)) {
set_blocksize(journal->j_dev_bd, super->s_blocksize);
}
return result; return result;
} }
...@@ -1981,15 +1985,12 @@ static int journal_init_dev( struct super_block *super, ...@@ -1981,15 +1985,12 @@ static int journal_init_dev( struct super_block *super,
} else if( jdev_inode -> i_bdev == NULL ) { } else if( jdev_inode -> i_bdev == NULL ) {
printk( "journal_init_dev: bdev unintialized for '%s'", jdev_name ); printk( "journal_init_dev: bdev unintialized for '%s'", jdev_name );
result = -ENOMEM; result = -ENOMEM;
} else if( ( result = blkdev_get( jdev_inode -> i_bdev, } else {
FMODE_READ | FMODE_WRITE,
0, BDEV_FS ) ) != 0 ) {
printk( "journal_init_dev: Cannot load device '%s': %i", jdev_name,
result );
} else
/* ok */ /* ok */
SB_JOURNAL_DEV( super ) = SB_JOURNAL_DEV( super ) =
to_kdev_t( jdev_inode -> i_bdev -> bd_dev ); to_kdev_t( jdev_inode -> i_bdev -> bd_dev );
set_blocksize(journal->j_dev_bd, super->s_blocksize);
}
} else { } else {
result = PTR_ERR( journal -> j_dev_file ); result = PTR_ERR( journal -> j_dev_file );
journal -> j_dev_file = NULL; journal -> j_dev_file = NULL;
...@@ -2041,7 +2042,7 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo ...@@ -2041,7 +2042,7 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo
rs = SB_DISK_SUPER_BLOCK(p_s_sb); rs = SB_DISK_SUPER_BLOCK(p_s_sb);
/* read journal header */ /* read journal header */
bhjh = journ_bread(p_s_sb, bhjh = journal_bread(p_s_sb,
SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb)); SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb));
if (!bhjh) { if (!bhjh) {
printk("sh-459: unable to read journal header\n") ; printk("sh-459: unable to read journal header\n") ;
...@@ -2052,15 +2053,11 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo ...@@ -2052,15 +2053,11 @@ int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_fo
/* make sure that journal matches to the super block */ /* make sure that journal matches to the super block */
if (is_reiserfs_jr(rs) && (jh->jh_journal.jp_journal_magic != sb_jp_journal_magic(rs))) { if (is_reiserfs_jr(rs) && (jh->jh_journal.jp_journal_magic != sb_jp_journal_magic(rs))) {
char jname[ 32 ];
char fname[ 32 ];
strcpy( jname, kdevname( SB_JOURNAL_DEV(p_s_sb) ) );
strcpy( fname, p_s_sb->s_id);
printk("sh-460: journal header magic %x (device %s) does not match " printk("sh-460: journal header magic %x (device %s) does not match "
"to magic found in super block %x (device %s)\n", "to magic found in super block %x (device %s)\n",
jh->jh_journal.jp_journal_magic, jname, jh->jh_journal.jp_journal_magic, kdevname( SB_JOURNAL_DEV(p_s_sb) ),
sb_jp_journal_magic(rs), fname); sb_jp_journal_magic(rs), reiserfs_bdevname (p_s_sb));
brelse (bhjh); brelse (bhjh);
release_journal_dev(p_s_sb, journal); release_journal_dev(p_s_sb, journal);
return 1 ; return 1 ;
...@@ -2985,7 +2982,7 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, struct super_b ...@@ -2985,7 +2982,7 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, struct super_b
rs = SB_DISK_SUPER_BLOCK(p_s_sb) ; rs = SB_DISK_SUPER_BLOCK(p_s_sb) ;
/* setup description block */ /* setup description block */
d_bh = journ_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_JOURNAL(p_s_sb)->j_start) ; d_bh = journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_JOURNAL(p_s_sb)->j_start) ;
set_buffer_uptodate(d_bh) ; set_buffer_uptodate(d_bh) ;
desc = (struct reiserfs_journal_desc *)(d_bh)->b_data ; desc = (struct reiserfs_journal_desc *)(d_bh)->b_data ;
memset(desc, 0, sizeof(struct reiserfs_journal_desc)) ; memset(desc, 0, sizeof(struct reiserfs_journal_desc)) ;
...@@ -2993,7 +2990,7 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, struct super_b ...@@ -2993,7 +2990,7 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, struct super_b
desc->j_trans_id = cpu_to_le32(SB_JOURNAL(p_s_sb)->j_trans_id) ; desc->j_trans_id = cpu_to_le32(SB_JOURNAL(p_s_sb)->j_trans_id) ;
/* setup commit block. Don't write (keep it clean too) this one until after everyone else is written */ /* setup commit block. Don't write (keep it clean too) this one until after everyone else is written */
c_bh = journ_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + c_bh = journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
((SB_JOURNAL(p_s_sb)->j_start + SB_JOURNAL(p_s_sb)->j_len + 1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ; ((SB_JOURNAL(p_s_sb)->j_start + SB_JOURNAL(p_s_sb)->j_len + 1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
commit = (struct reiserfs_journal_commit *)c_bh->b_data ; commit = (struct reiserfs_journal_commit *)c_bh->b_data ;
memset(commit, 0, sizeof(struct reiserfs_journal_commit)) ; memset(commit, 0, sizeof(struct reiserfs_journal_commit)) ;
...@@ -3084,7 +3081,7 @@ printk("journal-2020: do_journal_end: BAD desc->j_len is ZERO\n") ; ...@@ -3084,7 +3081,7 @@ printk("journal-2020: do_journal_end: BAD desc->j_len is ZERO\n") ;
/* copy all the real blocks into log area. dirty log blocks */ /* copy all the real blocks into log area. dirty log blocks */
if (test_bit(BH_JDirty, &cn->bh->b_state)) { if (test_bit(BH_JDirty, &cn->bh->b_state)) {
struct buffer_head *tmp_bh ; struct buffer_head *tmp_bh ;
tmp_bh = journ_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + tmp_bh = journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
((cur_write_start + jindex) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ; ((cur_write_start + jindex) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
set_buffer_uptodate(tmp_bh) ; set_buffer_uptodate(tmp_bh) ;
memcpy(tmp_bh->b_data, cn->bh->b_data, cn->bh->b_size) ; memcpy(tmp_bh->b_data, cn->bh->b_data, cn->bh->b_size) ;
......
...@@ -195,13 +195,6 @@ static __u32 get_third_component (struct super_block * s, ...@@ -195,13 +195,6 @@ static __u32 get_third_component (struct super_block * s,
} }
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
static int reiserfs_match (struct reiserfs_dir_entry * de, static int reiserfs_match (struct reiserfs_dir_entry * de,
const char * name, int namelen) const char * name, int namelen)
{ {
...@@ -284,13 +277,6 @@ static int linear_search_in_dir_item (struct cpu_key * key, struct reiserfs_dir_ ...@@ -284,13 +277,6 @@ static int linear_search_in_dir_item (struct cpu_key * key, struct reiserfs_dir_
} }
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
// may return NAME_FOUND, NAME_FOUND_INVISIBLE, NAME_NOT_FOUND // may return NAME_FOUND, NAME_FOUND_INVISIBLE, NAME_NOT_FOUND
// FIXME: should add something like IOERROR // FIXME: should add something like IOERROR
static int reiserfs_find_entry (struct inode * dir, const char * name, int namelen, static int reiserfs_find_entry (struct inode * dir, const char * name, int namelen,
...@@ -300,7 +286,7 @@ static int reiserfs_find_entry (struct inode * dir, const char * name, int namel ...@@ -300,7 +286,7 @@ static int reiserfs_find_entry (struct inode * dir, const char * name, int namel
int retval; int retval;
if (namelen > REISERFS_MAX_NAME_LEN (dir->i_sb->s_blocksize)) if (namelen > REISERFS_MAX_NAME (dir->i_sb->s_blocksize))
return NAME_NOT_FOUND; return NAME_NOT_FOUND;
/* we will search for this key in the tree */ /* we will search for this key in the tree */
...@@ -330,13 +316,6 @@ static int reiserfs_find_entry (struct inode * dir, const char * name, int namel ...@@ -330,13 +316,6 @@ static int reiserfs_find_entry (struct inode * dir, const char * name, int namel
} }
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dentry) static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dentry)
{ {
int retval; int retval;
...@@ -344,21 +323,21 @@ static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dent ...@@ -344,21 +323,21 @@ static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dent
struct reiserfs_dir_entry de; struct reiserfs_dir_entry de;
INITIALIZE_PATH (path_to_entry); INITIALIZE_PATH (path_to_entry);
if (dentry->d_name.len > REISERFS_MAX_NAME_LEN (dir->i_sb->s_blocksize)) if (REISERFS_MAX_NAME (dir->i_sb->s_blocksize) < dentry->d_name.len)
return ERR_PTR(-ENAMETOOLONG); return ERR_PTR(-ENAMETOOLONG);
lock_kernel(); reiserfs_write_lock(dir->i_sb);
de.de_gen_number_bit_string = 0; de.de_gen_number_bit_string = 0;
retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de); retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de);
pathrelse (&path_to_entry); pathrelse (&path_to_entry);
if (retval == NAME_FOUND) { if (retval == NAME_FOUND) {
inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id)); inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
if (!inode || IS_ERR(inode)) { if (!inode || IS_ERR(inode)) {
unlock_kernel(); reiserfs_write_unlock(dir->i_sb);
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
} }
unlock_kernel(); reiserfs_write_unlock(dir->i_sb);
if ( retval == IO_ERROR ) { if ( retval == IO_ERROR ) {
return ERR_PTR(-EIO); return ERR_PTR(-EIO);
} }
...@@ -390,15 +369,15 @@ struct dentry *reiserfs_get_parent(struct dentry *child) ...@@ -390,15 +369,15 @@ struct dentry *reiserfs_get_parent(struct dentry *child)
} }
de.de_gen_number_bit_string = 0; de.de_gen_number_bit_string = 0;
lock_kernel(); reiserfs_write_lock(dir->i_sb);
retval = reiserfs_find_entry (dir, "..", 2, &path_to_entry, &de); retval = reiserfs_find_entry (dir, "..", 2, &path_to_entry, &de);
pathrelse (&path_to_entry); pathrelse (&path_to_entry);
if (retval != NAME_FOUND) { if (retval != NAME_FOUND) {
unlock_kernel(); reiserfs_write_unlock(dir->i_sb);
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
} }
inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id)); inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
unlock_kernel(); reiserfs_write_unlock(dir->i_sb);
if (!inode || IS_ERR(inode)) { if (!inode || IS_ERR(inode)) {
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
...@@ -412,14 +391,6 @@ struct dentry *reiserfs_get_parent(struct dentry *child) ...@@ -412,14 +391,6 @@ struct dentry *reiserfs_get_parent(struct dentry *child)
} }
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
/* add entry to the directory (entry can be hidden). /* add entry to the directory (entry can be hidden).
insert definition of when hidden directories are used here -Hans insert definition of when hidden directories are used here -Hans
...@@ -447,7 +418,7 @@ static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct in ...@@ -447,7 +418,7 @@ static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct in
if (!namelen) if (!namelen)
return -EINVAL; return -EINVAL;
if (namelen > REISERFS_MAX_NAME_LEN (dir->i_sb->s_blocksize)) if (namelen > REISERFS_MAX_NAME (dir->i_sb->s_blocksize))
return -ENAMETOOLONG; return -ENAMETOOLONG;
/* each entry has unique key. compose it */ /* each entry has unique key. compose it */
...@@ -463,7 +434,7 @@ static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct in ...@@ -463,7 +434,7 @@ static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct in
} else } else
buffer = small_buf; buffer = small_buf;
paste_size = (old_format_only (dir->i_sb)) ? (DEH_SIZE + namelen) : buflen; paste_size = (get_inode_sd_version (dir) == STAT_DATA_V1) ? (DEH_SIZE + namelen) : buflen;
/* fill buffer : directory entry head, name[, dir objectid | , stat data | ,stat data, dir objectid ] */ /* fill buffer : directory entry head, name[, dir objectid | , stat data | ,stat data, dir objectid ] */
deh = (struct reiserfs_de_head *)buffer; deh = (struct reiserfs_de_head *)buffer;
...@@ -587,13 +558,6 @@ static int new_inode_init(struct inode *inode, struct inode *dir, int mode) { ...@@ -587,13 +558,6 @@ static int new_inode_init(struct inode *inode, struct inode *dir, int mode) {
return 0 ; return 0 ;
} }
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode) static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode)
{ {
int retval; int retval;
...@@ -601,15 +565,14 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode) ...@@ -601,15 +565,14 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode)
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ; int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ;
struct reiserfs_transaction_handle th ; struct reiserfs_transaction_handle th ;
inode = new_inode(dir->i_sb) ; if (!(inode = new_inode(dir->i_sb))) {
if (!inode) {
return -ENOMEM ; return -ENOMEM ;
} }
retval = new_inode_init(inode, dir, mode); retval = new_inode_init(inode, dir, mode);
if (retval) if (retval)
return retval; return retval;
lock_kernel(); reiserfs_write_lock(dir->i_sb);
journal_begin(&th, dir->i_sb, jbegin_count) ; journal_begin(&th, dir->i_sb, jbegin_count) ;
th.t_caller = "create" ; th.t_caller = "create" ;
retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode); retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode);
...@@ -637,18 +600,11 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode) ...@@ -637,18 +600,11 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode)
journal_end(&th, dir->i_sb, jbegin_count) ; journal_end(&th, dir->i_sb, jbegin_count) ;
out_failed: out_failed:
unlock_kernel(); reiserfs_write_unlock(dir->i_sb);
return retval; return retval;
} }
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev) static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
{ {
int retval; int retval;
...@@ -656,15 +612,14 @@ static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, ...@@ -656,15 +612,14 @@ static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode,
struct reiserfs_transaction_handle th ; struct reiserfs_transaction_handle th ;
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
inode = new_inode(dir->i_sb) ; if (!(inode = new_inode(dir->i_sb))) {
if (!inode) {
return -ENOMEM ; return -ENOMEM ;
} }
retval = new_inode_init(inode, dir, mode); retval = new_inode_init(inode, dir, mode);
if (retval) if (retval)
return retval; return retval;
lock_kernel(); reiserfs_write_lock(dir->i_sb);
journal_begin(&th, dir->i_sb, jbegin_count) ; journal_begin(&th, dir->i_sb, jbegin_count) ;
retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode); retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode);
...@@ -694,18 +649,11 @@ static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, ...@@ -694,18 +649,11 @@ static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode,
journal_end(&th, dir->i_sb, jbegin_count) ; journal_end(&th, dir->i_sb, jbegin_count) ;
out_failed: out_failed:
unlock_kernel(); reiserfs_write_unlock(dir->i_sb);
return retval; return retval;
} }
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode) static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode)
{ {
int retval; int retval;
...@@ -714,15 +662,14 @@ static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode) ...@@ -714,15 +662,14 @@ static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode)
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
mode = S_IFDIR | mode; mode = S_IFDIR | mode;
inode = new_inode(dir->i_sb) ; if (!(inode = new_inode(dir->i_sb))) {
if (!inode) {
return -ENOMEM ; return -ENOMEM ;
} }
retval = new_inode_init(inode, dir, mode); retval = new_inode_init(inode, dir, mode);
if (retval) if (retval)
return retval; return retval;
lock_kernel(); reiserfs_write_lock(dir->i_sb);
journal_begin(&th, dir->i_sb, jbegin_count) ; journal_begin(&th, dir->i_sb, jbegin_count) ;
/* inc the link count now, so another writer doesn't overflow it while /* inc the link count now, so another writer doesn't overflow it while
...@@ -762,7 +709,7 @@ static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode) ...@@ -762,7 +709,7 @@ static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode)
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
journal_end(&th, dir->i_sb, jbegin_count) ; journal_end(&th, dir->i_sb, jbegin_count) ;
out_failed: out_failed:
unlock_kernel(); reiserfs_write_unlock(dir->i_sb);
return retval; return retval;
} }
...@@ -779,14 +726,6 @@ static inline int reiserfs_empty_dir(struct inode *inode) { ...@@ -779,14 +726,6 @@ static inline int reiserfs_empty_dir(struct inode *inode) {
return 1 ; return 1 ;
} }
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry) static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry)
{ {
int retval; int retval;
...@@ -801,7 +740,7 @@ static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry) ...@@ -801,7 +740,7 @@ static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry)
/* we will be doing 2 balancings and update 2 stat data */ /* we will be doing 2 balancings and update 2 stat data */
jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2; jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
lock_kernel(); reiserfs_write_lock(dir->i_sb);
journal_begin(&th, dir->i_sb, jbegin_count) ; journal_begin(&th, dir->i_sb, jbegin_count) ;
windex = push_journal_writer("reiserfs_rmdir") ; windex = push_journal_writer("reiserfs_rmdir") ;
...@@ -855,7 +794,7 @@ static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry) ...@@ -855,7 +794,7 @@ static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry)
pop_journal_writer(windex) ; pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ; journal_end(&th, dir->i_sb, jbegin_count) ;
reiserfs_check_path(&path) ; reiserfs_check_path(&path) ;
unlock_kernel(); reiserfs_write_unlock(dir->i_sb);
return 0; return 0;
end_rmdir: end_rmdir:
...@@ -865,18 +804,10 @@ static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry) ...@@ -865,18 +804,10 @@ static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry)
pathrelse (&path); pathrelse (&path);
pop_journal_writer(windex) ; pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ; journal_end(&th, dir->i_sb, jbegin_count) ;
unlock_kernel(); reiserfs_write_unlock(dir->i_sb);
return retval; return retval;
} }
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
static int reiserfs_unlink (struct inode * dir, struct dentry *dentry) static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
{ {
int retval; int retval;
...@@ -893,7 +824,7 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry) ...@@ -893,7 +824,7 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
two stat datas */ two stat datas */
jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2; jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
lock_kernel(); reiserfs_write_lock(dir->i_sb);
journal_begin(&th, dir->i_sb, jbegin_count) ; journal_begin(&th, dir->i_sb, jbegin_count) ;
windex = push_journal_writer("reiserfs_unlink") ; windex = push_journal_writer("reiserfs_unlink") ;
...@@ -918,7 +849,7 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry) ...@@ -918,7 +849,7 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
if (!inode->i_nlink) { if (!inode->i_nlink) {
printk("reiserfs_unlink: deleting nonexistent file (%s:%lu), %d\n", printk("reiserfs_unlink: deleting nonexistent file (%s:%lu), %d\n",
inode->i_sb->s_id, inode->i_ino, inode->i_nlink); reiserfs_bdevname (inode->i_sb), inode->i_ino, inode->i_nlink);
inode->i_nlink = 1; inode->i_nlink = 1;
} }
...@@ -942,7 +873,7 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry) ...@@ -942,7 +873,7 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
pop_journal_writer(windex) ; pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ; journal_end(&th, dir->i_sb, jbegin_count) ;
reiserfs_check_path(&path) ; reiserfs_check_path(&path) ;
unlock_kernel(); reiserfs_write_unlock(dir->i_sb);
return 0; return 0;
end_unlink: end_unlink:
...@@ -950,19 +881,12 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry) ...@@ -950,19 +881,12 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
pop_journal_writer(windex) ; pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ; journal_end(&th, dir->i_sb, jbegin_count) ;
reiserfs_check_path(&path) ; reiserfs_check_path(&path) ;
unlock_kernel(); reiserfs_write_unlock(dir->i_sb);
return retval; return retval;
} }
static int reiserfs_symlink (struct inode * parent_dir,
// struct dentry * dentry, const char * symname)
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
static int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const char * symname)
{ {
int retval; int retval;
struct inode * inode; struct inode * inode;
...@@ -972,24 +896,23 @@ static int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const c ...@@ -972,24 +896,23 @@ static int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const c
int mode = S_IFLNK | S_IRWXUGO; int mode = S_IFLNK | S_IRWXUGO;
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
inode = new_inode(dir->i_sb) ; if (!(inode = new_inode(parent_dir->i_sb))) {
if (!inode) {
return -ENOMEM ; return -ENOMEM ;
} }
retval = new_inode_init(inode, dir, mode); retval = new_inode_init(inode, parent_dir, mode);
if (retval) { if (retval) {
return retval; return retval;
} }
lock_kernel(); reiserfs_write_lock(parent_dir->i_sb);
item_len = ROUND_UP (strlen (symname)); item_len = ROUND_UP (strlen (symname));
if (item_len > MAX_DIRECT_ITEM_LEN (dir->i_sb->s_blocksize)) { if (item_len > MAX_DIRECT_ITEM_LEN (parent_dir->i_sb->s_blocksize)) {
retval = -ENAMETOOLONG; retval = -ENAMETOOLONG;
drop_new_inode(inode); drop_new_inode(inode);
goto out_failed; goto out_failed;
} }
name = reiserfs_kmalloc (item_len, GFP_NOFS, dir->i_sb); name = reiserfs_kmalloc (item_len, GFP_NOFS, parent_dir->i_sb);
if (!name) { if (!name) {
drop_new_inode(inode); drop_new_inode(inode);
retval = -ENOMEM; retval = -ENOMEM;
...@@ -998,17 +921,17 @@ static int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const c ...@@ -998,17 +921,17 @@ static int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const c
memcpy (name, symname, strlen (symname)); memcpy (name, symname, strlen (symname));
padd_item (name, item_len, strlen (symname)); padd_item (name, item_len, strlen (symname));
journal_begin(&th, dir->i_sb, jbegin_count) ; journal_begin(&th, parent_dir->i_sb, jbegin_count) ;
retval = reiserfs_new_inode (&th, dir, mode, name, strlen (symname), retval = reiserfs_new_inode (&th, parent_dir, mode, name, strlen (symname),
dentry, inode); dentry, inode);
reiserfs_kfree (name, item_len, dir->i_sb); reiserfs_kfree (name, item_len, parent_dir->i_sb);
if (retval) { /* reiserfs_new_inode iputs for us */ if (retval) { /* reiserfs_new_inode iputs for us */
goto out_failed; goto out_failed;
} }
reiserfs_update_inode_transaction(inode) ; reiserfs_update_inode_transaction(inode) ;
reiserfs_update_inode_transaction(dir) ; reiserfs_update_inode_transaction(parent_dir) ;
inode->i_op = &page_symlink_inode_operations; inode->i_op = &page_symlink_inode_operations;
inode->i_mapping->a_ops = &reiserfs_address_space_operations; inode->i_mapping->a_ops = &reiserfs_address_space_operations;
...@@ -1017,31 +940,23 @@ static int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const c ...@@ -1017,31 +940,23 @@ static int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const c
// //
//reiserfs_update_sd (&th, inode, READ_BLOCKS); //reiserfs_update_sd (&th, inode, READ_BLOCKS);
retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, retval = reiserfs_add_entry (&th, parent_dir, dentry->d_name.name,
inode, 1/*visible*/); dentry->d_name.len, inode, 1/*visible*/);
if (retval) { if (retval) {
inode->i_nlink--; inode->i_nlink--;
reiserfs_update_sd (&th, inode); reiserfs_update_sd (&th, inode);
journal_end(&th, dir->i_sb, jbegin_count) ; journal_end(&th, parent_dir->i_sb, jbegin_count) ;
iput (inode); iput (inode);
goto out_failed; goto out_failed;
} }
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
journal_end(&th, dir->i_sb, jbegin_count) ; journal_end(&th, parent_dir->i_sb, jbegin_count) ;
out_failed: out_failed:
unlock_kernel(); reiserfs_write_unlock(parent_dir->i_sb);
return retval; return retval;
} }
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry) static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry)
{ {
int retval; int retval;
...@@ -1049,11 +964,12 @@ static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct ...@@ -1049,11 +964,12 @@ static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct
int windex ; int windex ;
struct reiserfs_transaction_handle th ; struct reiserfs_transaction_handle th ;
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
time_t ctime;
lock_kernel(); reiserfs_write_lock(dir->i_sb);
if (inode->i_nlink >= REISERFS_LINK_MAX) { if (inode->i_nlink >= REISERFS_LINK_MAX) {
//FIXME: sd_nlink is 32 bit for new files //FIXME: sd_nlink is 32 bit for new files
unlock_kernel(); reiserfs_write_unlock(dir->i_sb);
return -EMLINK; return -EMLINK;
} }
...@@ -1070,19 +986,20 @@ static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct ...@@ -1070,19 +986,20 @@ static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct
if (retval) { if (retval) {
pop_journal_writer(windex) ; pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ; journal_end(&th, dir->i_sb, jbegin_count) ;
unlock_kernel(); reiserfs_write_unlock(dir->i_sb);
return retval; return retval;
} }
inode->i_nlink++; inode->i_nlink++;
inode->i_ctime = CURRENT_TIME; ctime = CURRENT_TIME;
inode->i_ctime = ctime;
reiserfs_update_sd (&th, inode); reiserfs_update_sd (&th, inode);
atomic_inc(&inode->i_count) ; atomic_inc(&inode->i_count) ;
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
pop_journal_writer(windex) ; pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ; journal_end(&th, dir->i_sb, jbegin_count) ;
unlock_kernel(); reiserfs_write_unlock(dir->i_sb);
return 0; return 0;
} }
...@@ -1129,14 +1046,6 @@ static void set_ino_in_dir_entry (struct reiserfs_dir_entry * de, struct key * k ...@@ -1129,14 +1046,6 @@ static void set_ino_in_dir_entry (struct reiserfs_dir_entry * de, struct key * k
} }
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
/* /*
* process, that is going to call fix_nodes/do_balance must hold only * process, that is going to call fix_nodes/do_balance must hold only
* one path. If it holds 2 or more, it can get into endless waiting in * one path. If it holds 2 or more, it can get into endless waiting in
...@@ -1151,10 +1060,12 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, ...@@ -1151,10 +1060,12 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
INITIALIZE_PATH (dot_dot_entry_path); INITIALIZE_PATH (dot_dot_entry_path);
struct item_head new_entry_ih, old_entry_ih, dot_dot_ih ; struct item_head new_entry_ih, old_entry_ih, dot_dot_ih ;
struct reiserfs_dir_entry old_de, new_de, dot_dot_de; struct reiserfs_dir_entry old_de, new_de, dot_dot_de;
struct inode * old_inode, * new_inode; struct inode * old_inode, * new_dentry_inode;
int windex ; int windex ;
struct reiserfs_transaction_handle th ; struct reiserfs_transaction_handle th ;
int jbegin_count ; int jbegin_count ;
umode_t old_inode_mode;
time_t ctime;
/* two balancings: old name removal, new name insertion or "save" link, /* two balancings: old name removal, new name insertion or "save" link,
...@@ -1163,33 +1074,34 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, ...@@ -1163,33 +1074,34 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 3; jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 3;
old_inode = old_dentry->d_inode; old_inode = old_dentry->d_inode;
new_inode = new_dentry->d_inode; new_dentry_inode = new_dentry->d_inode;
// make sure, that oldname still exists and points to an object we // make sure, that oldname still exists and points to an object we
// are going to rename // are going to rename
old_de.de_gen_number_bit_string = 0; old_de.de_gen_number_bit_string = 0;
lock_kernel(); reiserfs_write_lock(old_dir->i_sb);
retval = reiserfs_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len, retval = reiserfs_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len,
&old_entry_path, &old_de); &old_entry_path, &old_de);
pathrelse (&old_entry_path); pathrelse (&old_entry_path);
if (retval == IO_ERROR) { if (retval == IO_ERROR) {
unlock_kernel(); reiserfs_write_unlock(old_dir->i_sb);
return -EIO; return -EIO;
} }
if (retval != NAME_FOUND || old_de.de_objectid != old_inode->i_ino) { if (retval != NAME_FOUND || old_de.de_objectid != old_inode->i_ino) {
unlock_kernel(); reiserfs_write_unlock(old_dir->i_sb);
return -ENOENT; return -ENOENT;
} }
if (S_ISDIR(old_inode->i_mode)) { old_inode_mode = old_inode->i_mode;
if (S_ISDIR(old_inode_mode)) {
// make sure, that directory being renamed has correct ".." // make sure, that directory being renamed has correct ".."
// and that its new parent directory has not too many links // and that its new parent directory has not too many links
// already // already
if (new_inode) { if (new_dentry_inode) {
if (!reiserfs_empty_dir(new_inode)) { if (!reiserfs_empty_dir(new_dentry_inode)) {
unlock_kernel(); reiserfs_write_unlock(old_dir->i_sb);
return -ENOTEMPTY; return -ENOTEMPTY;
} }
} }
...@@ -1201,13 +1113,13 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, ...@@ -1201,13 +1113,13 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
retval = reiserfs_find_entry (old_inode, "..", 2, &dot_dot_entry_path, &dot_dot_de); retval = reiserfs_find_entry (old_inode, "..", 2, &dot_dot_entry_path, &dot_dot_de);
pathrelse (&dot_dot_entry_path); pathrelse (&dot_dot_entry_path);
if (retval != NAME_FOUND) { if (retval != NAME_FOUND) {
unlock_kernel(); reiserfs_write_unlock(old_dir->i_sb);
return -EIO; return -EIO;
} }
/* inode number of .. must equal old_dir->i_ino */ /* inode number of .. must equal old_dir->i_ino */
if (dot_dot_de.de_objectid != old_dir->i_ino) { if (dot_dot_de.de_objectid != old_dir->i_ino) {
unlock_kernel(); reiserfs_write_unlock(old_dir->i_sb);
return -EIO; return -EIO;
} }
} }
...@@ -1219,16 +1131,14 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, ...@@ -1219,16 +1131,14 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
retval = reiserfs_add_entry (&th, new_dir, new_dentry->d_name.name, new_dentry->d_name.len, retval = reiserfs_add_entry (&th, new_dir, new_dentry->d_name.name, new_dentry->d_name.len,
old_inode, 0); old_inode, 0);
if (retval == -EEXIST) { if (retval == -EEXIST) {
// FIXME: is it possible, that new_inode == 0 here? If yes, it if (!new_dentry_inode) {
// is not clear how does ext2 handle that
if (!new_inode) {
reiserfs_panic (old_dir->i_sb, reiserfs_panic (old_dir->i_sb,
"vs-7050: new entry is found, new inode == 0\n"); "vs-7050: new entry is found, new inode == 0\n");
} }
} else if (retval) { } else if (retval) {
pop_journal_writer(windex) ; pop_journal_writer(windex) ;
journal_end(&th, old_dir->i_sb, jbegin_count) ; journal_end(&th, old_dir->i_sb, jbegin_count) ;
unlock_kernel(); reiserfs_write_unlock(old_dir->i_sb);
return retval; return retval;
} }
...@@ -1240,8 +1150,8 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, ...@@ -1240,8 +1150,8 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
*/ */
reiserfs_update_inode_transaction(old_inode) ; reiserfs_update_inode_transaction(old_inode) ;
if (new_inode) if (new_dentry_inode)
reiserfs_update_inode_transaction(new_inode) ; reiserfs_update_inode_transaction(new_dentry_inode) ;
while (1) { while (1) {
// look for old name using corresponding entry key (found by reiserfs_find_entry) // look for old name using corresponding entry key (found by reiserfs_find_entry)
...@@ -1288,18 +1198,18 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, ...@@ -1288,18 +1198,18 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
if (item_moved(&new_entry_ih, &new_entry_path) || if (item_moved(&new_entry_ih, &new_entry_path) ||
!entry_points_to_object(new_dentry->d_name.name, !entry_points_to_object(new_dentry->d_name.name,
new_dentry->d_name.len, new_dentry->d_name.len,
&new_de, new_inode) || &new_de, new_dentry_inode) ||
item_moved(&old_entry_ih, &old_entry_path) || item_moved(&old_entry_ih, &old_entry_path) ||
!entry_points_to_object (old_dentry->d_name.name, !entry_points_to_object (old_dentry->d_name.name,
old_dentry->d_name.len, old_dentry->d_name.len,
&old_de, old_inode)) { &old_de, old_inode)) {
reiserfs_restore_prepared_buffer (old_inode->i_sb, new_de.de_bh); reiserfs_restore_prepared_buffer (old_inode->i_sb, new_de.de_bh);
reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh); reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh);
if (S_ISDIR(old_inode->i_mode)) if (S_ISDIR(old_inode_mode))
reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh); reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh);
continue; continue;
} }
if (S_ISDIR(old_inode->i_mode)) { if (S_ISDIR(old_inode_mode)) {
if ( item_moved(&dot_dot_ih, &dot_dot_entry_path) || if ( item_moved(&dot_dot_ih, &dot_dot_entry_path) ||
!entry_points_to_object ( "..", 2, &dot_dot_de, old_dir) ) { !entry_points_to_object ( "..", 2, &dot_dot_de, old_dir) ) {
reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh); reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh);
...@@ -1309,7 +1219,7 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, ...@@ -1309,7 +1219,7 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
} }
} }
RFALSE( S_ISDIR(old_inode->i_mode) && RFALSE( S_ISDIR(old_inode_mode) &&
!reiserfs_buffer_prepared(dot_dot_de.de_bh), "" ); !reiserfs_buffer_prepared(dot_dot_de.de_bh), "" );
break; break;
...@@ -1327,22 +1237,23 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, ...@@ -1327,22 +1237,23 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME; old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME; new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;
if (new_inode) { if (new_dentry_inode) {
// adjust link number of the victim // adjust link number of the victim
if (S_ISDIR(new_inode->i_mode)) { if (S_ISDIR(new_dentry_inode->i_mode)) {
new_inode->i_nlink = 0; new_dentry_inode->i_nlink = 0;
} else { } else {
new_inode->i_nlink--; new_dentry_inode->i_nlink--;
} }
new_inode->i_ctime = CURRENT_TIME; ctime = CURRENT_TIME;
new_dentry_inode->i_ctime = ctime;
} }
if (S_ISDIR(old_inode->i_mode)) { if (S_ISDIR(old_inode_mode)) {
// adjust ".." of renamed directory // adjust ".." of renamed directory
set_ino_in_dir_entry (&dot_dot_de, INODE_PKEY (new_dir)); 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); journal_mark_dirty (&th, new_dir->i_sb, dot_dot_de.de_bh);
if (!new_inode) if (!new_dentry_inode)
/* there (in new_dir) was no directory, so it got new link /* there (in new_dir) was no directory, so it got new link
(".." of renamed directory) */ (".." of renamed directory) */
INC_DIR_INODE_NLINK(new_dir); INC_DIR_INODE_NLINK(new_dir);
...@@ -1367,15 +1278,15 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, ...@@ -1367,15 +1278,15 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
reiserfs_update_sd (&th, old_dir); reiserfs_update_sd (&th, old_dir);
reiserfs_update_sd (&th, new_dir); reiserfs_update_sd (&th, new_dir);
if (new_inode) { if (new_dentry_inode) {
if (new_inode->i_nlink == 0) if (new_dentry_inode->i_nlink == 0)
add_save_link (&th, new_inode, 0/* not truncate */); add_save_link (&th, new_dentry_inode, 0/* not truncate */);
reiserfs_update_sd (&th, new_inode); reiserfs_update_sd (&th, new_dentry_inode);
} }
pop_journal_writer(windex) ; pop_journal_writer(windex) ;
journal_end(&th, old_dir->i_sb, jbegin_count) ; journal_end(&th, old_dir->i_sb, jbegin_count) ;
unlock_kernel(); reiserfs_write_unlock(old_dir->i_sb);
return 0; return 0;
} }
......
...@@ -337,7 +337,7 @@ void reiserfs_panic (struct super_block * sb, const char * fmt, ...) ...@@ -337,7 +337,7 @@ void reiserfs_panic (struct super_block * sb, const char * fmt, ...)
/* this is not actually called, but makes reiserfs_panic() "noreturn" */ /* this is not actually called, but makes reiserfs_panic() "noreturn" */
panic ("REISERFS: panic (device %s): %s\n", panic ("REISERFS: panic (device %s): %s\n",
sb ? sb->s_id : "sb == 0", error_buf); reiserfs_bdevname (sb), error_buf);
} }
...@@ -490,6 +490,7 @@ char * reiserfs_hashname(int code) ...@@ -490,6 +490,7 @@ char * reiserfs_hashname(int code)
return "unknown"; return "unknown";
} }
/* return 1 if this is not super block */ /* return 1 if this is not super block */
static int print_super_block (struct buffer_head * bh) static int print_super_block (struct buffer_head * bh)
{ {
...@@ -509,8 +510,8 @@ static int print_super_block (struct buffer_head * bh) ...@@ -509,8 +510,8 @@ static int print_super_block (struct buffer_head * bh)
return 1; return 1;
} }
printk ("%s\'s super block in block %ld\n======================\n", printk ("%s\'s super block is in block %ld\n", bdevname (bh->b_bdev),
bdevname (bh->b_bdev), bh->b_blocknr); bh->b_blocknr);
printk ("Reiserfs version %s\n", version ); printk ("Reiserfs version %s\n", version );
printk ("Block count %u\n", sb_block_count(rs)); printk ("Block count %u\n", sb_block_count(rs));
printk ("Blocksize %d\n", sb_blocksize(rs)); printk ("Blocksize %d\n", sb_blocksize(rs));
......
...@@ -36,7 +36,7 @@ static struct super_block *procinfo_prologue( kdev_t dev ) ...@@ -36,7 +36,7 @@ static struct super_block *procinfo_prologue( kdev_t dev )
/* get super-block by device */ /* get super-block by device */
result = get_super( dev ); result = get_super( dev );
if( result != NULL ) { if( result != NULL ) {
if( !reiserfs_is_super( result ) ) { if( !is_reiserfs_super( result ) ) {
printk( KERN_DEBUG "reiserfs: procfs-52: " printk( KERN_DEBUG "reiserfs: procfs-52: "
"non-reiserfs super found\n" ); "non-reiserfs super found\n" );
drop_super( result ); drop_super( result );
...@@ -500,7 +500,7 @@ int reiserfs_journal_in_proc( char *buffer, char **start, off_t offset, ...@@ -500,7 +500,7 @@ int reiserfs_journal_in_proc( char *buffer, char **start, off_t offset,
"prepare_retry: \t%12lu\n", "prepare_retry: \t%12lu\n",
DJP( jp_journal_1st_block ), DJP( jp_journal_1st_block ),
DJP( jp_journal_dev ) == 0 ? "none" : __bdevname(to_kdev_t(DJP( jp_journal_dev ))), bdevname(SB_JOURNAL(sb)->j_dev_bd),
DJP( jp_journal_dev ), DJP( jp_journal_dev ),
DJP( jp_journal_size ), DJP( jp_journal_size ),
DJP( jp_journal_trans_max ), DJP( jp_journal_trans_max ),
...@@ -556,13 +556,13 @@ static const char *proc_info_root_name = "fs/reiserfs"; ...@@ -556,13 +556,13 @@ static const char *proc_info_root_name = "fs/reiserfs";
int reiserfs_proc_info_init( struct super_block *sb ) int reiserfs_proc_info_init( struct super_block *sb )
{ {
spin_lock_init( & __PINFO( sb ).lock ); spin_lock_init( & __PINFO( sb ).lock );
REISERFS_SB(sb)->procdir = proc_mkdir(sb->s_id, proc_info_root); REISERFS_SB(sb)->procdir = proc_mkdir(reiserfs_bdevname (sb), proc_info_root);
if( REISERFS_SB(sb)->procdir ) { if( REISERFS_SB(sb)->procdir ) {
REISERFS_SB(sb)->procdir -> owner = THIS_MODULE; REISERFS_SB(sb)->procdir -> owner = THIS_MODULE;
return 0; return 0;
} }
reiserfs_warning( "reiserfs: cannot create /proc/%s/%s\n", reiserfs_warning( "reiserfs: cannot create /proc/%s/%s\n",
proc_info_root_name, sb->s_id ); proc_info_root_name, reiserfs_bdevname (sb) );
return 1; return 1;
} }
...@@ -573,7 +573,7 @@ int reiserfs_proc_info_done( struct super_block *sb ) ...@@ -573,7 +573,7 @@ int reiserfs_proc_info_done( struct super_block *sb )
__PINFO( sb ).exiting = 1; __PINFO( sb ).exiting = 1;
spin_unlock( & __PINFO( sb ).lock ); spin_unlock( & __PINFO( sb ).lock );
if ( proc_info_root ) { if ( proc_info_root ) {
remove_proc_entry( sb->s_id, proc_info_root ); remove_proc_entry( reiserfs_bdevname (sb), proc_info_root );
REISERFS_SB(sb)->procdir = NULL; REISERFS_SB(sb)->procdir = NULL;
} }
return 0; return 0;
......
...@@ -1715,13 +1715,13 @@ void reiserfs_do_truncate (struct reiserfs_transaction_handle *th, ...@@ -1715,13 +1715,13 @@ void reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
/* Cut or delete file item. */ /* Cut or delete file item. */
n_deleted = reiserfs_cut_from_item(th, &s_search_path, &s_item_key, p_s_inode, page, n_new_file_size); n_deleted = reiserfs_cut_from_item(th, &s_search_path, &s_item_key, p_s_inode, page, n_new_file_size);
if (n_deleted < 0) { if (n_deleted < 0) {
reiserfs_warning ("vs-5665: reiserfs_truncate_file: cut_from_item failed"); reiserfs_warning ("vs-5665: reiserfs_do_truncate: reiserfs_cut_from_item failed");
reiserfs_check_path(&s_search_path) ; reiserfs_check_path(&s_search_path) ;
return; return;
} }
RFALSE( n_deleted > n_file_size, RFALSE( n_deleted > n_file_size,
"PAP-5670: reiserfs_truncate_file returns too big number: deleted %d, file_size %lu, item_key %K", "PAP-5670: reiserfs_cut_from_item: too many bytes deleted: deleted %d, file_size %lu, item_key %K",
n_deleted, n_file_size, &s_item_key); n_deleted, n_file_size, &s_item_key);
/* Change key to search the last file item. */ /* Change key to search the last file item. */
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#define REISERFS_OLD_BLOCKSIZE 4096 #define REISERFS_OLD_BLOCKSIZE 4096
#define REISERFS_SUPER_MAGIC_STRING_OFFSET_NJ 20 #define REISERFS_SUPER_MAGIC_STRING_OFFSET_NJ 20
static struct file_system_type reiserfs_fs_type;
const char reiserfs_3_5_magic_string[] = REISERFS_SUPER_MAGIC_STRING; const char reiserfs_3_5_magic_string[] = REISERFS_SUPER_MAGIC_STRING;
const char reiserfs_3_6_magic_string[] = REISER2FS_SUPER_MAGIC_STRING; const char reiserfs_3_6_magic_string[] = REISER2FS_SUPER_MAGIC_STRING;
const char reiserfs_jr_magic_string[] = REISER2FS_JR_SUPER_MAGIC_STRING; const char reiserfs_jr_magic_string[] = REISER2FS_JR_SUPER_MAGIC_STRING;
...@@ -55,41 +57,32 @@ static int is_any_reiserfs_magic_string (struct reiserfs_super_block * rs) ...@@ -55,41 +57,32 @@ static int is_any_reiserfs_magic_string (struct reiserfs_super_block * rs)
is_reiserfs_jr (rs)); is_reiserfs_jr (rs));
} }
int is_reiserfs_super (struct super_block *s)
{
return s -> s_type == & reiserfs_fs_type ;
}
static int reiserfs_remount (struct super_block * s, int * flags, char * data); static int reiserfs_remount (struct super_block * s, int * flags, char * data);
static int reiserfs_statfs (struct super_block * s, struct statfs * buf); static int reiserfs_statfs (struct super_block * s, struct statfs * buf);
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
static void reiserfs_write_super (struct super_block * s) static void reiserfs_write_super (struct super_block * s)
{ {
int dirty = 0 ; int dirty = 0 ;
lock_kernel() ; reiserfs_write_lock(s);
if (!(s->s_flags & MS_RDONLY)) { if (!(s->s_flags & MS_RDONLY)) {
dirty = flush_old_commits(s, 1) ; dirty = flush_old_commits(s, 1) ;
} }
s->s_dirt = dirty; s->s_dirt = dirty;
unlock_kernel() ; reiserfs_write_unlock(s);
} }
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
static void reiserfs_write_super_lockfs (struct super_block * s) static void reiserfs_write_super_lockfs (struct super_block * s)
{ {
int dirty = 0 ; int dirty = 0 ;
struct reiserfs_transaction_handle th ; struct reiserfs_transaction_handle th ;
lock_kernel() ; reiserfs_write_lock(s);
if (!(s->s_flags & MS_RDONLY)) { if (!(s->s_flags & MS_RDONLY)) {
journal_begin(&th, s, 1) ; journal_begin(&th, s, 1) ;
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
...@@ -98,7 +91,7 @@ static void reiserfs_write_super_lockfs (struct super_block * s) ...@@ -98,7 +91,7 @@ static void reiserfs_write_super_lockfs (struct super_block * s)
journal_end(&th, s, 1) ; journal_end(&th, s, 1) ;
} }
s->s_dirt = dirty; s->s_dirt = dirty;
unlock_kernel() ; reiserfs_write_unlock(s);
} }
void reiserfs_unlockfs(struct super_block *s) { void reiserfs_unlockfs(struct super_block *s) {
...@@ -362,13 +355,6 @@ void remove_save_link (struct inode * inode, int truncate) ...@@ -362,13 +355,6 @@ void remove_save_link (struct inode * inode, int truncate)
} }
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
static void reiserfs_put_super (struct super_block * s) static void reiserfs_put_super (struct super_block * s)
{ {
int i; int i;
...@@ -469,7 +455,7 @@ static void reiserfs_dirty_inode (struct inode * inode) { ...@@ -469,7 +455,7 @@ static void reiserfs_dirty_inode (struct inode * inode) {
inode->i_ino) ; inode->i_ino) ;
return ; return ;
} }
lock_kernel() ; reiserfs_write_lock(inode->i_sb);
/* this is really only used for atime updates, so they don't have /* this is really only used for atime updates, so they don't have
** to be included in O_SYNC or fsync ** to be included in O_SYNC or fsync
...@@ -477,7 +463,7 @@ static void reiserfs_dirty_inode (struct inode * inode) { ...@@ -477,7 +463,7 @@ static void reiserfs_dirty_inode (struct inode * inode) {
journal_begin(&th, inode->i_sb, 1) ; journal_begin(&th, inode->i_sb, 1) ;
reiserfs_update_sd (&th, inode); reiserfs_update_sd (&th, inode);
journal_end(&th, inode->i_sb, 1) ; journal_end(&th, inode->i_sb, 1) ;
unlock_kernel() ; reiserfs_write_unlock(inode->i_sb);
} }
struct super_operations reiserfs_sops = struct super_operations reiserfs_sops =
...@@ -503,100 +489,190 @@ static struct export_operations reiserfs_export_ops = { ...@@ -503,100 +489,190 @@ static struct export_operations reiserfs_export_ops = {
get_dentry: reiserfs_get_dentry, get_dentry: reiserfs_get_dentry,
} ; } ;
/* this was (ext2)parse_options */ /* this struct is used in reiserfs_getopt () for containing the value for those
static int parse_options (char * options, unsigned long * mount_options, unsigned long * blocks, char **jdev_name) mount options that have values rather than being toggles. */
{ typedef struct {
char * this_char;
char * value; char * value;
int bitmask; /* bit which is to be set in mount_options bitmask when this
value is found, 0 is no bits are to be set */
} arg_desc_t;
/* this struct is used in reiserfs_getopt() for describing the set of reiserfs
mount options */
typedef struct {
char * option_name;
int arg_required; /* 0 if argument is not required, not 0 otherwise */
const arg_desc_t * values; /* list of values accepted by an option */
int bitmask; /* bit which is to be set in mount_options bitmask when this
option is selected, 0 is not bits are to be set */
} opt_desc_t;
/* possible values for "-o block-allocator=" and bits which are to be set in
s_mount_opt of reiserfs specific part of in-core super block */
const arg_desc_t balloc[] = {
{"noborder", REISERFS_NO_BORDER},
{"no_unhashed_relocation", REISERFS_NO_UNHASHED_RELOCATION},
{"hashed_relocation", REISERFS_HASHED_RELOCATION},
{"test4", REISERFS_TEST4},
{NULL, -1}
};
/* proceed only one option from a list *cur - string containing of mount options
opts - array of options which are accepted
opt_arg - if option is found and requires an argument and if it is specifed
in the input - pointer to the argument is stored here
bit_flags - if option requires to set a certain bit - it is set here
return -1 if unknown option is found, opt->arg_required otherwise */
static int reiserfs_getopt (char ** cur, opt_desc_t * opts, char ** opt_arg,
unsigned long * bit_flags)
{
char * p;
/* foo=bar,
^ ^ ^
| | +-- option_end
| +-- arg_start
+-- option_start
*/
const opt_desc_t * opt;
const arg_desc_t * arg;
p = *cur;
/* assume argument cannot contain commas */
*cur = strchr (p, ',');
if (*cur) {
*(*cur) = '\0';
(*cur) ++;
}
/* for every option in the list */
for (opt = opts; opt->option_name; opt ++) {
if (!strncmp (p, opt->option_name, strlen (opt->option_name))) {
if (bit_flags && opt->bitmask != -1)
set_bit (opt->bitmask, bit_flags);
break;
}
}
if (!opt->option_name) {
printk ("reiserfs_getopt: unknown option \"%s\"\n", p);
return -1;
}
p += strlen (opt->option_name);
switch (*p) {
case '=':
if (!opt->arg_required) {
printk ("reiserfs_getopt: the option \"%s\" does not require an argument\n",
opt->option_name);
return -1;
}
break;
case 0:
if (opt->arg_required) {
printk ("reiserfs_getopt: the option \"%s\" requires an argument\n", opt->option_name);
return -1;
}
break;
default:
printk ("reiserfs_getopt: head of option \"%s\" is only correct\n", opt->option_name);
return -1;
}
/* move to the argument, or to next option if argument is not required */
p ++;
if ( opt->arg_required && !strlen (p) ) {
/* this catches "option=," */
printk ("reiserfs_getopt: empty argument for \"%s\"\n", opt->option_name);
return -1;
}
if (!opt->values) {
/* *opt_arg contains pointer to argument */
*opt_arg = p;
return opt->arg_required;
}
/* values possible for this option are listed in opt->values */
for (arg = opt->values; arg->value; arg ++) {
if (!strcmp (p, arg->value)) {
if (bit_flags && arg->bitmask != -1 )
set_bit (arg->bitmask, bit_flags);
return opt->arg_required;
}
}
printk ("reiserfs_getopt: bad value \"%s\" for option \"%s\"\n", p, opt->option_name);
return -1;
}
/* returns 0 if something is wrong in option string, 1 - otherwise */
static int reiserfs_parse_options (char * options, /* string given via mount's -o */
unsigned long * mount_options,
/* after the parsing phase, contains the
collection of bitflags defining what
mount options were selected. */
unsigned long * blocks, /* strtol-ed from NNN of resize=NNN */
char ** jdev_name)
{
int c;
char * arg = NULL;
char * pos;
opt_desc_t opts[] = {
{"notail", 0, 0, NOTAIL},
{"conv", 0, 0, REISERFS_CONVERT},
{"attrs", 0, 0, REISERFS_ATTRS},
{"nolog", 0, 0, -1},
{"replayonly", 0, 0, REPLAYONLY},
{"block-allocator", 'a', balloc, -1},
{"resize", 'r', 0, -1},
{"jdev", 'j', 0, -1},
{NULL, 0, 0, -1}
};
*blocks = 0; *blocks = 0;
if (!options) if (!options || !*options)
/* use default configuration: create tails, journaling on, no /* use default configuration: create tails, journaling on, no
conversion to newest format */ conversion to newest format */
return 1; return 1;
while ((this_char = strsep (&options, ",")) != NULL) {
if (!*this_char) for (pos = options; pos; ) {
continue; c = reiserfs_getopt (&pos, opts, &arg, mount_options);
if ((value = strchr (this_char, '=')) != NULL) if (c == -1)
*value++ = 0; /* wrong option is given */
if (!strcmp (this_char, "notail")) { return 0;
set_bit (NOTAIL, mount_options);
} else if (!strcmp (this_char, "conv")) { if (c == 'r') {
// if this is set, we update super block such that char * p;
// the partition will not be mounable by 3.5.x anymore
set_bit (REISERFS_CONVERT, mount_options); p = 0;
} else if (!strcmp (this_char, "noborder")) { /* "resize=NNN" */
/* this is used for benchmarking *blocks = simple_strtoul (arg, &p, 0);
experimental variations, it is not if (*p != '\0') {
intended for users to use, only for /* NNN does not look like a number */
developers who want to casually printk ("reiserfs_parse_options: bad value %s\n", arg);
hack in something to test */
set_bit (REISERFS_NO_BORDER, mount_options);
} else if (!strcmp (this_char, "no_unhashed_relocation")) {
set_bit (REISERFS_NO_UNHASHED_RELOCATION, mount_options);
} else if (!strcmp (this_char, "hashed_relocation")) {
set_bit (REISERFS_HASHED_RELOCATION, mount_options);
} else if (!strcmp (this_char, "test4")) {
set_bit (REISERFS_TEST4, mount_options);
} else if (!strcmp (this_char, "nolog")) {
reiserfs_warning("reiserfs: nolog mount option not supported yet\n");
} else if (!strcmp (this_char, "replayonly")) {
set_bit (REPLAYONLY, mount_options);
} else if (!strcmp (this_char, "resize")) {
if (value && *value){
*blocks = simple_strtoul (value, &value, 0);
} else {
printk("reiserfs: resize option requires a value\n");
return 0; return 0;
} }
} else if (!strcmp (this_char, "hash")) { }
if (value && *value) {
/* if they specify any hash option, we force detection if (c == 'j') {
** to make sure they aren't using the wrong hash if (arg && *arg && jdev_name) {
*/ *jdev_name = arg;
if (!strcmp(value, "rupasov")) {
set_bit (FORCE_RUPASOV_HASH, mount_options);
set_bit (FORCE_HASH_DETECT, mount_options);
} else if (!strcmp(value, "tea")) {
set_bit (FORCE_TEA_HASH, mount_options);
set_bit (FORCE_HASH_DETECT, mount_options);
} else if (!strcmp(value, "r5")) {
set_bit (FORCE_R5_HASH, mount_options);
set_bit (FORCE_HASH_DETECT, mount_options);
} else if (!strcmp(value, "detect")) {
set_bit (FORCE_HASH_DETECT, mount_options);
} else {
printk("reiserfs: invalid hash function specified\n") ;
return 0 ;
}
} else {
printk("reiserfs: hash option requires a value\n");
return 0 ;
}
} else if (!strcmp (this_char, "jdev")) {
if (value && *value && jdev_name) {
*jdev_name = value;
} else {
printk("reiserfs: jdev option requires a value\n");
return 0 ;
} }
} else {
printk ("reiserfs: Unrecognized mount option %s\n", this_char);
return 0;
} }
} }
return 1; return 1;
} }
static int reiserfs_remount (struct super_block * s, int * mount_flags, char * arg)
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
static int reiserfs_remount (struct super_block * s, int * flags, char * data)
{ {
struct reiserfs_super_block * rs; struct reiserfs_super_block * rs;
struct reiserfs_transaction_handle th ; struct reiserfs_transaction_handle th ;
...@@ -604,21 +680,21 @@ static int reiserfs_remount (struct super_block * s, int * flags, char * data) ...@@ -604,21 +680,21 @@ static int reiserfs_remount (struct super_block * s, int * flags, char * data)
unsigned long mount_options; unsigned long mount_options;
rs = SB_DISK_SUPER_BLOCK (s); rs = SB_DISK_SUPER_BLOCK (s);
if (!parse_options(data, &mount_options, &blocks, NULL))
return 0;
if (!reiserfs_parse_options(arg, &mount_options, &blocks, NULL))
return -EINVAL;
if(blocks) { if(blocks) {
int rc = reiserfs_resize(s, blocks); int rc = reiserfs_resize(s, blocks);
if (rc != 0) if (rc != 0)
return rc; return rc;
} }
if ((unsigned long)(*flags & MS_RDONLY) == (s->s_flags & MS_RDONLY)) { if (*mount_flags & MS_RDONLY) {
/* there is nothing to do to remount read-only fs as read-only fs */ /* remount rean-only */
return 0; if (s->s_flags & MS_RDONLY)
} /* it is read-only already */
return 0;
if (*flags & MS_RDONLY) {
/* try to remount file system with read-only permissions */ /* try to remount file system with read-only permissions */
if (sb_umount_state(rs) == REISERFS_VALID_FS || REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) { if (sb_umount_state(rs) == REISERFS_VALID_FS || REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) {
return 0; return 0;
...@@ -634,7 +710,7 @@ static int reiserfs_remount (struct super_block * s, int * flags, char * data) ...@@ -634,7 +710,7 @@ static int reiserfs_remount (struct super_block * s, int * flags, char * data)
REISERFS_SB(s)->s_mount_state = sb_umount_state(rs) ; REISERFS_SB(s)->s_mount_state = sb_umount_state(rs) ;
s->s_flags &= ~MS_RDONLY ; /* now it is safe to call journal_begin */ s->s_flags &= ~MS_RDONLY ; /* now it is safe to call journal_begin */
journal_begin(&th, s, 10) ; journal_begin(&th, s, 10) ;
/* Mount a partition which is read-only, read-write */ /* Mount a partition which is read-only, read-write */
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ; reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
REISERFS_SB(s)->s_mount_state = sb_umount_state(rs); REISERFS_SB(s)->s_mount_state = sb_umount_state(rs);
...@@ -649,7 +725,7 @@ static int reiserfs_remount (struct super_block * s, int * flags, char * data) ...@@ -649,7 +725,7 @@ static int reiserfs_remount (struct super_block * s, int * flags, char * data)
SB_JOURNAL(s)->j_must_wait = 1 ; SB_JOURNAL(s)->j_must_wait = 1 ;
journal_end(&th, s, 10) ; journal_end(&th, s, 10) ;
if (!( *flags & MS_RDONLY ) ) if (!( *mount_flags & MS_RDONLY ) )
finish_unfinished( s ); finish_unfinished( s );
return 0; return 0;
...@@ -658,14 +734,14 @@ static int reiserfs_remount (struct super_block * s, int * flags, char * data) ...@@ -658,14 +734,14 @@ static int reiserfs_remount (struct super_block * s, int * flags, char * data)
static int read_bitmaps (struct super_block * s) static int read_bitmaps (struct super_block * s)
{ {
int i, bmp; int i, bmap_nr;
SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * SB_BMAP_NR(s), GFP_NOFS, s); SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * SB_BMAP_NR(s), GFP_NOFS, s);
if (SB_AP_BITMAP (s) == 0) if (SB_AP_BITMAP (s) == 0)
return 1; return 1;
for (i = 0, bmp = REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1; for (i = 0, bmap_nr = REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1;
i < SB_BMAP_NR(s); i++, bmp = s->s_blocksize * 8 * i) { i < SB_BMAP_NR(s); i++, bmap_nr = s->s_blocksize * 8 * i) {
SB_AP_BITMAP (s)[i] = sb_getblk(s, bmp); SB_AP_BITMAP (s)[i] = sb_getblk(s, bmap_nr);
if (!buffer_uptodate(SB_AP_BITMAP(s)[i])) if (!buffer_uptodate(SB_AP_BITMAP(s)[i]))
ll_rw_block(READ, 1, SB_AP_BITMAP(s) + i); ll_rw_block(READ, 1, SB_AP_BITMAP(s) + i);
} }
...@@ -735,7 +811,7 @@ static int read_super_block (struct super_block * s, int offset) ...@@ -735,7 +811,7 @@ static int read_super_block (struct super_block * s, int offset)
if (!bh) { if (!bh) {
printk ("sh-2006: read_super_block: " printk ("sh-2006: read_super_block: "
"bread failed (dev %s, block %lu, size %lu)\n", "bread failed (dev %s, block %lu, size %lu)\n",
s->s_id, offset / s->s_blocksize, s->s_blocksize); reiserfs_bdevname (s), offset / s->s_blocksize, s->s_blocksize);
return 1; return 1;
} }
...@@ -755,7 +831,7 @@ static int read_super_block (struct super_block * s, int offset) ...@@ -755,7 +831,7 @@ static int read_super_block (struct super_block * s, int offset)
if (!bh) { if (!bh) {
printk("sh-2007: read_super_block: " printk("sh-2007: read_super_block: "
"bread failed (dev %s, block %lu, size %lu)\n", "bread failed (dev %s, block %lu, size %lu)\n",
s->s_id, offset / s->s_blocksize, s->s_blocksize); reiserfs_bdevname (s), offset / s->s_blocksize, s->s_blocksize);
return 1; return 1;
} }
...@@ -763,7 +839,7 @@ static int read_super_block (struct super_block * s, int offset) ...@@ -763,7 +839,7 @@ static int read_super_block (struct super_block * s, int offset)
if (sb_blocksize(rs) != s->s_blocksize) { if (sb_blocksize(rs) != s->s_blocksize) {
printk ("sh-2011: read_super_block: " printk ("sh-2011: read_super_block: "
"can't find a reiserfs filesystem on (dev %s, block %lu, size %lu)\n", "can't find a reiserfs filesystem on (dev %s, block %lu, size %lu)\n",
s->s_id, bh->b_blocknr, s->s_blocksize); reiserfs_bdevname (s), bh->b_blocknr, s->s_blocksize);
brelse (bh); brelse (bh);
return 1; return 1;
} }
...@@ -772,7 +848,7 @@ static int read_super_block (struct super_block * s, int offset) ...@@ -772,7 +848,7 @@ static int read_super_block (struct super_block * s, int offset)
brelse(bh) ; brelse(bh) ;
printk("dev %s: Unfinished reiserfsck --rebuild-tree run detected. Please run\n" printk("dev %s: Unfinished reiserfsck --rebuild-tree run detected. Please run\n"
"reiserfsck --rebuild-tree and wait for a completion. If that fails\n" "reiserfsck --rebuild-tree and wait for a completion. If that fails\n"
"get newer reiserfsprogs package\n", s->s_id); "get newer reiserfsprogs package\n", reiserfs_bdevname (s));
return 1; return 1;
} }
...@@ -884,7 +960,7 @@ __u32 find_hash_out (struct super_block * s) ...@@ -884,7 +960,7 @@ __u32 find_hash_out (struct super_block * s)
( (r5hash == yurahash) && (yurahash == GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])))) ) ) { ( (r5hash == yurahash) && (yurahash == GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])))) ) ) {
reiserfs_warning("reiserfs: Unable to automatically detect hash" reiserfs_warning("reiserfs: Unable to automatically detect hash"
"function for device %s\n" "function for device %s\n"
"please mount with -o hash={tea,rupasov,r5}\n", s->s_id); "please mount with -o hash={tea,rupasov,r5}\n", reiserfs_bdevname (s));
hash = UNSET_HASH; hash = UNSET_HASH;
break; break;
} }
...@@ -896,7 +972,7 @@ __u32 find_hash_out (struct super_block * s) ...@@ -896,7 +972,7 @@ __u32 find_hash_out (struct super_block * s)
hash = R5_HASH; hash = R5_HASH;
else { else {
reiserfs_warning("reiserfs: Unrecognised hash function for " reiserfs_warning("reiserfs: Unrecognised hash function for "
"device %s\n", s->s_id); "device %s\n", reiserfs_bdevname (s));
hash = UNSET_HASH; hash = UNSET_HASH;
} }
} while (0); } while (0);
...@@ -990,14 +1066,7 @@ int function2code (hashf_t func) ...@@ -990,14 +1066,7 @@ int function2code (hashf_t func)
return 0; return 0;
} }
// static int reiserfs_fill_super (struct super_block * s, void * data, int silent)
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
{ {
struct inode *root_inode; struct inode *root_inode;
int j; int j;
...@@ -1009,21 +1078,24 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) ...@@ -1009,21 +1078,24 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
struct reiserfs_super_block * rs; struct reiserfs_super_block * rs;
char *jdev_name; char *jdev_name;
struct reiserfs_sb_info *sbi; struct reiserfs_sb_info *sbi;
int errval = -EINVAL;
sbi = kmalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL); sbi = kmalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);
if (!sbi) if (!sbi) {
return -ENOMEM; errval = -ENOMEM;
goto error;
}
s->u.generic_sbp = sbi; s->u.generic_sbp = sbi;
memset (sbi, 0, sizeof (struct reiserfs_sb_info)); memset (sbi, 0, sizeof (struct reiserfs_sb_info));
jdev_name = NULL; jdev_name = NULL;
if (parse_options ((char *) data, &(sbi->s_mount_opt), &blocks, &jdev_name) == 0) { if (reiserfs_parse_options ((char *) data, &(sbi->s_mount_opt), &blocks, &jdev_name) == 0) {
return -EINVAL; goto error;
} }
if (blocks) { if (blocks) {
printk("reserfs: resize option for remount only\n"); printk("jmacd-7: reiserfs_fill_super: resize option for remount only\n");
return -EINVAL; goto error;
} }
/* try old format (undistributed bitmap, super block in 8-th 1k block of a device) */ /* try old format (undistributed bitmap, super block in 8-th 1k block of a device) */
...@@ -1031,14 +1103,14 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) ...@@ -1031,14 +1103,14 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
old_format = 1; old_format = 1;
/* try new format (64-th 1k block), which can contain reiserfs super block */ /* try new format (64-th 1k block), which can contain reiserfs super block */
else if (read_super_block (s, REISERFS_DISK_OFFSET_IN_BYTES)) { else if (read_super_block (s, REISERFS_DISK_OFFSET_IN_BYTES)) {
printk("sh-2021: reiserfs_fill_super: can not find reiserfs on %s\n", s->s_id); printk("sh-2021: reiserfs_fill_super: can not find reiserfs on %s\n", reiserfs_bdevname (s));
goto error; goto error;
} }
sbi->s_mount_state = SB_REISERFS_STATE(s); sbi->s_mount_state = SB_REISERFS_STATE(s);
sbi->s_mount_state = REISERFS_VALID_FS ; sbi->s_mount_state = REISERFS_VALID_FS ;
if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) { if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) {
printk ("reiserfs_fill_super: unable to read bitmap\n"); printk ("jmacd-8: reiserfs_fill_super: unable to read bitmap\n");
goto error; goto error;
} }
#ifdef CONFIG_REISERFS_CHECK #ifdef CONFIG_REISERFS_CHECK
...@@ -1056,7 +1128,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) ...@@ -1056,7 +1128,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
*/ */
} }
if (reread_meta_blocks(s)) { if (reread_meta_blocks(s)) {
printk("reiserfs_fill_super: unable to reread meta blocks after journal init\n") ; printk("jmacd-9: reiserfs_fill_super: unable to reread meta blocks after journal init\n") ;
goto error ; goto error ;
} }
...@@ -1071,7 +1143,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) ...@@ -1071,7 +1143,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
args.dirid = REISERFS_ROOT_PARENT_OBJECTID ; args.dirid = REISERFS_ROOT_PARENT_OBJECTID ;
root_inode = iget5_locked (s, REISERFS_ROOT_OBJECTID, reiserfs_find_actor, reiserfs_init_locked_inode, (void *)(&args)); root_inode = iget5_locked (s, REISERFS_ROOT_OBJECTID, reiserfs_find_actor, reiserfs_init_locked_inode, (void *)(&args));
if (!root_inode) { if (!root_inode) {
printk ("reiserfs_fill_super: get root inode failed\n"); printk ("jmacd-10: reiserfs_fill_super: get root inode failed\n");
goto error; goto error;
} }
...@@ -1155,7 +1227,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) ...@@ -1155,7 +1227,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
reiserfs_proc_register( s, "journal", reiserfs_journal_in_proc ); reiserfs_proc_register( s, "journal", reiserfs_journal_in_proc );
init_waitqueue_head (&(sbi->s_wait)); init_waitqueue_head (&(sbi->s_wait));
return 0; return (0);
error: error:
if (jinit_done) { /* kill the commit thread, free journal ram */ if (jinit_done) { /* kill the commit thread, free journal ram */
...@@ -1172,96 +1244,85 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) ...@@ -1172,96 +1244,85 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
if (SB_BUFFER_WITH_SB (s)) if (SB_BUFFER_WITH_SB (s))
brelse(SB_BUFFER_WITH_SB (s)); brelse(SB_BUFFER_WITH_SB (s));
kfree(sbi); if (sbi != NULL) {
s->u.generic_sbp = NULL; kfree(sbi);
}
return -EINVAL; s->u.generic_sbp = NULL;
return errval;
} }
//
// a portion of this function, particularly the VFS interface portion,
// was derived from minix or ext2's analog and evolved as the
// prototype did. You should be able to tell which portion by looking
// at the ext2 code and comparing. It's subfunctions contain no code
// used as a template unless they are so labeled.
//
static int reiserfs_statfs (struct super_block * s, struct statfs * buf) static int reiserfs_statfs (struct super_block * s, struct statfs * buf)
{ {
struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s); struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);
/* changed to accomodate gcc folks.*/ buf->f_namelen = (REISERFS_MAX_NAME (s->s_blocksize));
buf->f_type = REISERFS_SUPER_MAGIC; buf->f_ffree = -1;
buf->f_bsize = s->s_blocksize; buf->f_files = -1;
buf->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1;
buf->f_bfree = sb_free_blocks(rs); buf->f_bfree = sb_free_blocks(rs);
buf->f_bavail = buf->f_bfree; buf->f_bavail = buf->f_bfree;
buf->f_files = -1; buf->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1;
buf->f_ffree = -1; buf->f_bsize = s->s_blocksize;
buf->f_namelen = (REISERFS_MAX_NAME_LEN (s->s_blocksize)); /* changed to accomodate gcc folks.*/
buf->f_type = REISERFS_SUPER_MAGIC;
return 0; return 0;
} }
static struct super_block *reiserfs_get_sb(struct file_system_type *fs_type, static struct super_block*
int flags, char *dev_name, void *data) get_super_block (struct file_system_type *fs_type,
int flags,
char *dev_name,
void *data)
{ {
return get_sb_bdev(fs_type, flags, dev_name, data, reiserfs_fill_super); return get_sb_bdev (fs_type, flags, dev_name, data, reiserfs_fill_super);
} }
static struct file_system_type reiserfs_fs_type = { static int __init
owner: THIS_MODULE, init_reiserfs_fs ( void )
name: "reiserfs",
get_sb: reiserfs_get_sb,
kill_sb: kill_block_super,
fs_flags: FS_REQUIRES_DEV,
};
int reiserfs_is_super(struct super_block *s)
{ {
return s->s_type == &reiserfs_fs_type; int ret;
}
// if ((ret = init_inodecache ())) {
// this is exactly what 2.3.99-pre9's init_ext2_fs is return ret;
// }
static int __init init_reiserfs_fs (void)
{
int err = init_inodecache();
if (err)
goto out1;
reiserfs_proc_info_global_init();
reiserfs_proc_register_global( "version",
reiserfs_global_version_in_proc );
err = register_filesystem(&reiserfs_fs_type);
if (err)
goto out;
return 0;
out:
reiserfs_proc_unregister_global( "version" );
reiserfs_proc_info_global_done();
destroy_inodecache();
out1:
return err;
}
reiserfs_proc_info_global_init ();
reiserfs_proc_register_global ("version", reiserfs_global_version_in_proc);
MODULE_DESCRIPTION("ReiserFS journaled filesystem"); ret = register_filesystem (& reiserfs_fs_type);
MODULE_AUTHOR("Hans Reiser <reiser@namesys.com>");
MODULE_LICENSE("GPL");
// if (ret == 0) {
// this is exactly what 2.3.99-pre9's init_ext2_fs is return 0;
// }
static void __exit exit_reiserfs_fs(void)
{ reiserfs_proc_unregister_global ("version");
reiserfs_proc_unregister_global( "version" ); reiserfs_proc_info_global_done ();
reiserfs_proc_info_global_done(); destroy_inodecache ();
unregister_filesystem(&reiserfs_fs_type);
destroy_inodecache(); return ret;
} }
module_init(init_reiserfs_fs) ; static void __exit
module_exit(exit_reiserfs_fs) ; exit_reiserfs_fs ( void )
{
reiserfs_proc_unregister_global ("version");
reiserfs_proc_info_global_done ();
unregister_filesystem (& reiserfs_fs_type);
destroy_inodecache ();
}
static struct file_system_type reiserfs_fs_type = {
owner: THIS_MODULE,
name: "reiserfs",
get_sb: get_super_block,
kill_sb: kill_block_super,
fs_flags: FS_REQUIRES_DEV,
};
MODULE_DESCRIPTION ("ReiserFS journaled filesystem");
MODULE_AUTHOR ("Hans Reiser <reiser@namesys.com>");
MODULE_LICENSE ("GPL");
module_init (init_reiserfs_fs);
module_exit (exit_reiserfs_fs);
...@@ -214,7 +214,7 @@ int indirect2direct (struct reiserfs_transaction_handle *th, ...@@ -214,7 +214,7 @@ int indirect2direct (struct reiserfs_transaction_handle *th,
copy_item_head (&s_ih, PATH_PITEM_HEAD(p_s_path)); copy_item_head (&s_ih, PATH_PITEM_HEAD(p_s_path));
tail_len = (n_new_file_size & (n_block_size - 1)); tail_len = (n_new_file_size & (n_block_size - 1));
if (!old_format_only (p_s_sb)) if (get_inode_sd_version (p_s_inode) == STAT_DATA_V2)
round_tail_len = ROUND_UP (tail_len); round_tail_len = ROUND_UP (tail_len);
else else
round_tail_len = tail_len; round_tail_len = tail_len;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/reiserfs_fs_i.h> #include <linux/reiserfs_fs_i.h>
#include <linux/reiserfs_fs_sb.h> #include <linux/reiserfs_fs_sb.h>
...@@ -1062,9 +1063,7 @@ static inline int entry_length (const struct buffer_head * bh, ...@@ -1062,9 +1063,7 @@ static inline int entry_length (const struct buffer_head * bh,
#define B_I_E_NAME(bh,ih,entry_num) ((char *)(bh->b_data + ih_location(ih) + deh_location(B_I_DEH(bh,ih)+(entry_num)))) #define B_I_E_NAME(bh,ih,entry_num) ((char *)(bh->b_data + ih_location(ih) + deh_location(B_I_DEH(bh,ih)+(entry_num))))
// two entries per block (at least) // two entries per block (at least)
//#define REISERFS_MAX_NAME_LEN(block_size) #define REISERFS_MAX_NAME(block_size) 255
//((block_size - BLKH_SIZE - IH_SIZE - DEH_SIZE * 2) / 2)
#define REISERFS_MAX_NAME_LEN(block_size) 255
/* this structure is used for operations on directory entries. It is /* this structure is used for operations on directory entries. It is
...@@ -1654,6 +1653,11 @@ extern wait_queue_head_t reiserfs_commit_thread_wait ; ...@@ -1654,6 +1653,11 @@ extern wait_queue_head_t reiserfs_commit_thread_wait ;
*/ */
#define JOURNAL_BUFFER(j,n) ((j)->j_ap_blocks[((j)->j_start + (n)) % JOURNAL_BLOCK_COUNT]) #define JOURNAL_BUFFER(j,n) ((j)->j_ap_blocks[((j)->j_start + (n)) % JOURNAL_BLOCK_COUNT])
// We need these to make journal.c code more readable
#define journal_get_hash_table(s, block) __get_hash_table(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize)
#define journal_getblk(s, block) __getblk(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize)
#define journal_bread(s, block) __bread(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize)
void reiserfs_commit_for_inode(struct inode *) ; void reiserfs_commit_for_inode(struct inode *) ;
void reiserfs_update_inode_transaction(struct inode *) ; void reiserfs_update_inode_transaction(struct inode *) ;
void reiserfs_wait_on_write_block(struct super_block *s) ; void reiserfs_wait_on_write_block(struct super_block *s) ;
...@@ -2073,6 +2077,12 @@ int reiserfs_unpack (struct inode * inode, struct file * filp); ...@@ -2073,6 +2077,12 @@ int reiserfs_unpack (struct inode * inode, struct file * filp);
/* ioctl's command */ /* ioctl's command */
#define REISERFS_IOC_UNPACK _IOW(0xCD,1,long) #define REISERFS_IOC_UNPACK _IOW(0xCD,1,long)
/* Locking primitives */
/* Right now we are still falling back to (un)lock_kernel, but eventually that
would evolve into real per-fs locks */
#define reiserfs_write_lock( sb ) lock_kernel()
#define reiserfs_write_unlock( sb ) unlock_kernel()
#endif /* _LINUX_REISER_FS_H */ #endif /* _LINUX_REISER_FS_H */
......
...@@ -408,6 +408,8 @@ struct reiserfs_sb_info ...@@ -408,6 +408,8 @@ struct reiserfs_sb_info
#define REISERFS_HASHED_RELOCATION 13 #define REISERFS_HASHED_RELOCATION 13
#define REISERFS_TEST4 14 #define REISERFS_TEST4 14
#define REISERFS_ATTRS 15
#define REISERFS_TEST1 11 #define REISERFS_TEST1 11
#define REISERFS_TEST2 12 #define REISERFS_TEST2 12
#define REISERFS_TEST3 13 #define REISERFS_TEST3 13
...@@ -430,7 +432,7 @@ struct reiserfs_sb_info ...@@ -430,7 +432,7 @@ struct reiserfs_sb_info
void reiserfs_file_buffer (struct buffer_head * bh, int list); void reiserfs_file_buffer (struct buffer_head * bh, int list);
int reiserfs_is_super(struct super_block *s) ; int is_reiserfs_super(struct super_block *s) ;
int journal_mark_dirty(struct reiserfs_transaction_handle *, struct super_block *, struct buffer_head *bh) ; int journal_mark_dirty(struct reiserfs_transaction_handle *, struct super_block *, struct buffer_head *bh) ;
int flush_old_commits(struct super_block *s, int) ; int flush_old_commits(struct super_block *s, int) ;
int show_reiserfs_locks(void) ; int show_reiserfs_locks(void) ;
...@@ -456,4 +458,12 @@ int reiserfs_resize(struct super_block *, unsigned long) ; ...@@ -456,4 +458,12 @@ int reiserfs_resize(struct super_block *, unsigned long) ;
#define SB_JOURNAL_MAX_TRANS_AGE(s) (SB_JOURNAL(s)->s_journal_max_trans_age) #define SB_JOURNAL_MAX_TRANS_AGE(s) (SB_JOURNAL(s)->s_journal_max_trans_age)
#define SB_JOURNAL_DEV(s) (SB_JOURNAL(s)->j_dev) #define SB_JOURNAL_DEV(s) (SB_JOURNAL(s)->j_dev)
/* A safe version of the "bdevname", which returns the "s_id" field of
* a superblock or else "Null superblock" if the super block is NULL.
*/
static inline char *reiserfs_bdevname(struct super_block *s)
{
return (s == NULL) ? "Null superblock" : s -> s_id;
}
#endif /* _LINUX_REISER_FS_SB */ #endif /* _LINUX_REISER_FS_SB */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment