Commit 72c45511 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-test
parents a9907091 4cf11356
......@@ -314,7 +314,7 @@ o <http://oss.software.ibm.com/jfs>
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
-----------
......
......@@ -103,7 +103,7 @@ static void _reiserfs_free_block (struct reiserfs_transaction_handle *th, unsign
if (nr >= sb_bmap_nr (rs)) {
reiserfs_warning ("vs-4075: reiserfs_free_block: "
"block %lu is out of range on %s\n",
block, s->s_id);
block, reiserfs_bdevname (s));
return;
}
......@@ -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)) {
reiserfs_warning ("vs-4080: reiserfs_free_block: "
"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]);
......@@ -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 */
void reiserfs_free_prealloc_block (struct reiserfs_transaction_handle *th,
unsigned long block) {
struct super_block * s = th->t_super;
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");
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");
_reiserfs_free_block(th, block) ;
}
......@@ -670,10 +668,7 @@ int reiserfs_new_unf_blocknrs2 (struct reiserfs_transaction_handle *th,
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,
struct reiserfs_inode_info *ei)
{
......
......@@ -24,9 +24,10 @@ struct file_operations reiserfs_dir_operations = {
};
int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) {
lock_kernel();
reiserfs_commit_for_inode(dentry->d_inode) ;
unlock_kernel() ;
struct inode *inode = dentry->d_inode;
reiserfs_write_lock(inode->i_sb);
reiserfs_commit_for_inode(inode) ;
reiserfs_write_unlock(inode->i_sb) ;
return 0 ;
}
......@@ -50,7 +51,7 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi
struct reiserfs_dir_entry de;
int ret = 0;
lock_kernel();
reiserfs_write_lock(inode->i_sb);
reiserfs_check_lock_depth("readdir") ;
......@@ -109,7 +110,7 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi
if (!d_name[d_reclen - 1])
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 */
continue ;
}
......@@ -181,13 +182,12 @@ static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldi
end:
// FIXME: ext2_readdir does not reset f_pos
filp->f_pos = next_pos;
pathrelse (&path_to_entry);
reiserfs_check_path(&path_to_entry) ;
UPDATE_ATIME(inode) ;
out:
unlock_kernel();
reiserfs_write_unlock(inode->i_sb);
return ret;
}
......
......@@ -39,7 +39,7 @@ static int reiserfs_file_release (struct inode * inode, struct file * filp)
return 0;
}
lock_kernel() ;
reiserfs_write_lock(inode->i_sb);
down (&inode->i_sem);
journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
reiserfs_update_inode_transaction(inode) ;
......@@ -61,14 +61,12 @@ static int reiserfs_file_release (struct inode * inode, struct file * filp)
pop_journal_writer(windex) ;
}
up (&inode->i_sem);
unlock_kernel() ;
reiserfs_write_unlock(inode->i_sb);
return 0;
}
static void reiserfs_vfs_truncate_file(struct inode *inode) {
lock_kernel();
reiserfs_truncate_file(inode, 1) ;
unlock_kernel();
}
/* Sync a reiserfs file. */
......@@ -86,21 +84,21 @@ static int reiserfs_sync_file(
struct inode * p_s_inode = p_s_dentry->d_inode;
int n_err;
lock_kernel() ;
reiserfs_write_lock(p_s_inode->i_sb);
if (!S_ISREG(p_s_inode->i_mode))
BUG ();
n_err = sync_mapping_buffers(p_s_inode->i_mapping) ;
reiserfs_commit_for_inode(p_s_inode) ;
unlock_kernel() ;
reiserfs_write_unlock(p_s_inode->i_sb);
return ( n_err < 0 ) ? -EIO : 0;
}
static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
struct inode *inode = dentry->d_inode ;
int error ;
lock_kernel();
reiserfs_write_lock(inode->i_sb);
if (attr->ia_valid & ATTR_SIZE) {
/* version 2 items will be caught by the s_maxbytes check
** done for us in vmtruncate
......@@ -138,7 +136,7 @@ static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
inode_setattr(inode, attr) ;
out:
unlock_kernel();
reiserfs_write_unlock(inode->i_sb);
return error ;
}
......
......@@ -2092,21 +2092,27 @@ static void tb_buffer_sanity_check (struct super_block * p_s_sb,
if (p_s_bh) {
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) ) {
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) ) {
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 ||
p_s_bh->b_size != p_s_sb->s_blocksize ||
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_bdev != p_s_sb->s_bdev) {
reiserfs_panic (p_s_sb, "jmacd-4: tb_buffer_sanity_check(): buffer has wrong device %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 @@
static int reiserfs_get_block (struct inode * inode, sector_t block,
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)
{
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2;
......@@ -31,7 +28,7 @@ void reiserfs_delete_inode (struct inode * inode)
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.. */
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)
}
clear_inode (inode); /* note this must go after the journal_end to prevent deadlock */
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,
......@@ -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
// first 15 pointers just like ext2 does
// FIXME: we might cache recently accessed indirect item
// Ugh. Not too eager for that....
// 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,
if (!file_capable (inode, block))
return -EFBIG;
lock_kernel() ;
reiserfs_write_lock(inode->i_sb);
/* do not read the direct item */
_get_block_create_0 (inode, block, bh_result, 0) ;
unlock_kernel() ;
reiserfs_write_unlock(inode->i_sb);
return 0;
}
......@@ -521,12 +517,7 @@ static inline int _allocate_block(struct reiserfs_transaction_handle *th,
#endif
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,
struct buffer_head * bh_result, int create)
{
......@@ -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 ;
/* bad.... */
lock_kernel() ;
reiserfs_write_lock(inode->i_sb);
th.t_trans_id = 0 ;
version = get_inode_item_key_version (inode);
if (block < 0) {
unlock_kernel();
reiserfs_write_unlock(inode->i_sb);
return -EIO;
}
if (!file_capable (inode, block)) {
unlock_kernel() ;
reiserfs_write_unlock(inode->i_sb);
return -EFBIG;
}
......@@ -576,7 +567,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block,
/* find number of block-th logical block of the file */
ret = _get_block_create_0 (inode, block, bh_result,
create | GET_BLOCK_READ_DIRECT) ;
unlock_kernel() ;
reiserfs_write_unlock(inode->i_sb);
return ret;
}
......@@ -667,7 +658,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block,
if (transaction_started)
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
** 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,
retval = 0;
reiserfs_check_path(&path) ;
failure:
if (transaction_started) {
......@@ -874,7 +864,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block,
journal_end(&th, inode->i_sb, jbegin_count) ;
}
pop_journal_writer(windex) ;
unlock_kernel() ;
reiserfs_write_unlock(inode->i_sb);
reiserfs_check_path(&path) ;
return retval;
}
......@@ -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
containing stat data as dirty */
/* 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) {
** ignored because the altered inode has already been logged.
*/
if (do_sync && !(current->flags & PF_MEMALLOC)) {
lock_kernel() ;
reiserfs_write_lock(inode->i_sb);
journal_begin(&th, inode->i_sb, jbegin_count) ;
reiserfs_update_sd (&th, inode);
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,
** call prepare_write
*/
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 ;
goto unlock ;
}
......@@ -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) {
struct reiserfs_transaction_handle th ;
int windex ;
/* 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 blocksize = p_s_inode->i_sb->s_blocksize ;
......@@ -1759,6 +1745,8 @@ void reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) {
int error ;
struct buffer_head *bh = NULL ;
reiserfs_write_lock(p_s_inode->i_sb);
if (p_s_inode->i_size > 0) {
if ((error = grab_tail_page(p_s_inode, &page, &bh))) {
// -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) {
page_cache_release(page) ;
}
return ;
reiserfs_write_unlock(p_s_inode->i_sb);
}
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) ;
start_over:
lock_kernel() ;
reiserfs_write_lock(inode->i_sb);
journal_begin(&th, inode->i_sb, jbegin_count) ;
reiserfs_update_inode_transaction(inode) ;
......@@ -1894,7 +1882,7 @@ static int map_block_for_writepage(struct inode *inode,
goto research ;
}
} 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 ;
goto out ;
}
......@@ -1903,7 +1891,7 @@ static int map_block_for_writepage(struct inode *inode,
out:
pathrelse(&path) ;
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. */
if (use_get_block) {
......@@ -2033,18 +2021,13 @@ static int reiserfs_write_full_page(struct page *page) {
return error ;
}
//
// this is exactly what 2.3.99-pre9's ext2_readpage is
//
static int reiserfs_readpage (struct file *f, struct page * page)
{
return block_read_full_page (page, reiserfs_get_block);
}
//
// modified from ext2_writepage is
//
static int reiserfs_writepage (struct page * page)
{
struct inode *inode = page->mapping->host ;
......@@ -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,
unsigned from, unsigned to) {
struct inode *inode = page->mapping->host ;
......@@ -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) {
return generic_block_bmap(as, block, reiserfs_bmap) ;
}
......@@ -2086,13 +2063,13 @@ static int reiserfs_commit_write(struct file *f, struct page *page,
*/
if (pos > inode->i_size) {
struct reiserfs_transaction_handle th ;
lock_kernel() ;
reiserfs_write_lock(inode->i_sb);
journal_begin(&th, inode->i_sb, 1) ;
reiserfs_update_inode_transaction(inode) ;
inode->i_size = pos ;
reiserfs_update_sd(&th, inode) ;
journal_end(&th, inode->i_sb, 1) ;
unlock_kernel() ;
reiserfs_write_unlock(inode->i_sb);
}
ret = generic_commit_write(f, page, from, to) ;
......@@ -2101,9 +2078,9 @@ static int reiserfs_commit_write(struct file *f, struct page *page,
** for any packed tails the file might have had
*/
if (f && (f->f_flags & O_SYNC)) {
lock_kernel() ;
reiserfs_write_lock(inode->i_sb);
reiserfs_commit_for_inode(inode) ;
unlock_kernel();
reiserfs_write_unlock(inode->i_sb);
}
return ret ;
}
......
......@@ -49,7 +49,7 @@ int reiserfs_unpack (struct inode * inode, struct file * filp)
if (REISERFS_I(inode)->i_flags & i_nopack_mask) {
return 0 ;
}
lock_kernel();
reiserfs_write_lock(inode->i_sb);
/* we need to make sure nobody is changing the file size beneath
** us
......@@ -88,6 +88,6 @@ int reiserfs_unpack (struct inode * inode, struct file * filp)
out:
up(&inode->i_sem) ;
unlock_kernel();
reiserfs_write_unlock(inode->i_sb);
return retval;
}
......@@ -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,
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) {
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
count = 0 ;
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);
tbh = journ_get_hash_table(s, bn) ;
tbh = journal_get_hash_table(s, bn) ;
/* kill this sanity check */
if (count > (orig_commit_left + 2)) {
......@@ -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 &&
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) ;
tbh = journ_get_hash_table(s, bn) ;
tbh = journal_get_hash_table(s, bn) ;
wait_on_buffer(tbh) ;
if (!buffer_uptodate(tbh)) {
......@@ -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) ;
/* 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))) ;
if (!c_bh)
return 0 ;
......@@ -1481,7 +1466,7 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu
unsigned long trans_offset ;
int i;
d_bh = journ_bread(p_s_sb, cur_dblock) ;
d_bh = journal_bread(p_s_sb, cur_dblock) ;
if (!d_bh)
return 1 ;
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
brelse(d_bh) ;
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) %
SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
if (!c_bh) {
......@@ -1536,7 +1521,7 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu
}
/* get all the buffer heads */
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) {
real_blocks[i] = sb_getblk(p_s_sb, le32_to_cpu(desc->j_realblock[i])) ;
} else {
......@@ -1606,16 +1591,13 @@ static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cu
return 0 ;
}
/*
** 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.
*/
struct buffer_head * reiserfs_breada (struct super_block *sb, int block,
/* This function reads blocks starting from block and to max_block of bufsize
size (but no more than BUFNR blocks at a time). This proved to improve
mounting speed on self-rebuilding raid5 arrays at least.
Right now it is only used from journal code. But later we might use it
from other places.
Note: Do not use journal_getblk/sb_getblk functions here! */
struct buffer_head * reiserfs_breada (struct block_device *dev, int block, int bufsize,
unsigned int max_block)
{
struct buffer_head * bhlist[BUFNR];
......@@ -1623,7 +1605,7 @@ struct buffer_head * reiserfs_breada (struct super_block *sb, int block,
struct buffer_head * bh;
int i, j;
bh = sb_getblk (sb, block);
bh = __getblk (dev, block, bufsize );
if (buffer_uptodate (bh))
return (bh);
......@@ -1633,7 +1615,7 @@ struct buffer_head * reiserfs_breada (struct super_block *sb, int block,
bhlist[0] = bh;
j = 1;
for (i = 1; i < blocks; i++) {
bh = sb_getblk (sb, block + i);
bh = __getblk (dev, block + i, bufsize);
if (buffer_uptodate (bh)) {
brelse (bh);
break;
......@@ -1650,6 +1632,16 @@ struct buffer_head * reiserfs_breada (struct super_block *sb, int block,
brelse (bh);
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) {
struct reiserfs_journal_desc *desc ;
unsigned long oldest_trans_id = 0;
......@@ -1667,14 +1659,14 @@ static int journal_read(struct super_block *p_s_sb) {
cur_dblock = SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
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 ;
/* step 1, read in the journal header block. Check the transaction it says
** is the first unflushed, and if that transaction is not valid,
** 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_SIZE(p_s_sb));
if (!SB_JOURNAL(p_s_sb)->j_header_bh) {
......@@ -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
** 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) ;
if (!ret) {
continue_replay = 0 ;
......@@ -1716,7 +1708,9 @@ static int journal_read(struct super_block *p_s_sb) {
** 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))) {
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)) ;
ret = journal_transaction_is_valid(p_s_sb, d_bh, &oldest_invalid_trans_id, &newest_mount_id) ;
if (ret == 1) {
......@@ -1925,13 +1919,20 @@ static int release_journal_dev( struct super_block *super,
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 ) {
/*
* journal block device was taken via filp_open
*/
result = filp_close( 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 ) {
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,
printk( "sh-458: journal_init_dev: cannot init journal device\n '%s': %i",
kdevname( jdev ), result );
else if (!kdev_same(jdev, super->s_dev)) {
set_blocksize(journal->j_dev_bd, super->s_blocksize);
}
return result;
}
......@@ -1981,15 +1985,12 @@ static int journal_init_dev( struct super_block *super,
} else if( jdev_inode -> i_bdev == NULL ) {
printk( "journal_init_dev: bdev unintialized for '%s'", jdev_name );
result = -ENOMEM;
} else if( ( result = blkdev_get( jdev_inode -> i_bdev,
FMODE_READ | FMODE_WRITE,
0, BDEV_FS ) ) != 0 ) {
printk( "journal_init_dev: Cannot load device '%s': %i", jdev_name,
result );
} else
} else {
/* ok */
SB_JOURNAL_DEV( super ) =
to_kdev_t( jdev_inode -> i_bdev -> bd_dev );
set_blocksize(journal->j_dev_bd, super->s_blocksize);
}
} else {
result = PTR_ERR( journal -> j_dev_file );
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
rs = SB_DISK_SUPER_BLOCK(p_s_sb);
/* 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));
if (!bhjh) {
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
/* 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))) {
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 "
"to magic found in super block %x (device %s)\n",
jh->jh_journal.jp_journal_magic, jname,
sb_jp_journal_magic(rs), fname);
jh->jh_journal.jp_journal_magic, kdevname( SB_JOURNAL_DEV(p_s_sb) ),
sb_jp_journal_magic(rs), reiserfs_bdevname (p_s_sb));
brelse (bhjh);
release_journal_dev(p_s_sb, journal);
return 1 ;
......@@ -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) ;
/* 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) ;
desc = (struct reiserfs_journal_desc *)(d_bh)->b_data ;
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
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 */
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))) ;
commit = (struct reiserfs_journal_commit *)c_bh->b_data ;
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") ;
/* copy all the real blocks into log area. dirty log blocks */
if (test_bit(BH_JDirty, &cn->bh->b_state)) {
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))) ;
set_buffer_uptodate(tmp_bh) ;
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,
}
//
// 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,
const char * name, int namelen)
{
......@@ -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
// FIXME: should add something like IOERROR
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
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;
/* 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
}
//
// 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)
{
int retval;
......@@ -344,21 +323,21 @@ static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dent
struct reiserfs_dir_entry de;
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);
lock_kernel();
reiserfs_write_lock(dir->i_sb);
de.de_gen_number_bit_string = 0;
retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de);
pathrelse (&path_to_entry);
if (retval == NAME_FOUND) {
inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
if (!inode || IS_ERR(inode)) {
unlock_kernel();
reiserfs_write_unlock(dir->i_sb);
return ERR_PTR(-EACCES);
}
}
unlock_kernel();
reiserfs_write_unlock(dir->i_sb);
if ( retval == IO_ERROR ) {
return ERR_PTR(-EIO);
}
......@@ -390,15 +369,15 @@ struct dentry *reiserfs_get_parent(struct dentry *child)
}
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);
pathrelse (&path_to_entry);
if (retval != NAME_FOUND) {
unlock_kernel();
reiserfs_write_unlock(dir->i_sb);
return ERR_PTR(-ENOENT);
}
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)) {
return ERR_PTR(-EACCES);
......@@ -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).
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
if (!namelen)
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;
/* each entry has unique key. compose it */
......@@ -463,7 +434,7 @@ static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct in
} else
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 ] */
deh = (struct reiserfs_de_head *)buffer;
......@@ -587,13 +558,6 @@ static int new_inode_init(struct inode *inode, struct inode *dir, int mode) {
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)
{
int retval;
......@@ -601,15 +565,14 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode)
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 ;
struct reiserfs_transaction_handle th ;
inode = new_inode(dir->i_sb) ;
if (!inode) {
if (!(inode = new_inode(dir->i_sb))) {
return -ENOMEM ;
}
retval = new_inode_init(inode, dir, mode);
if (retval)
return retval;
lock_kernel();
reiserfs_write_lock(dir->i_sb);
journal_begin(&th, dir->i_sb, jbegin_count) ;
th.t_caller = "create" ;
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)
journal_end(&th, dir->i_sb, jbegin_count) ;
out_failed:
unlock_kernel();
reiserfs_write_unlock(dir->i_sb);
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)
{
int retval;
......@@ -656,15 +612,14 @@ static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode,
struct reiserfs_transaction_handle th ;
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
inode = new_inode(dir->i_sb) ;
if (!inode) {
if (!(inode = new_inode(dir->i_sb))) {
return -ENOMEM ;
}
retval = new_inode_init(inode, dir, mode);
if (retval)
return retval;
lock_kernel();
reiserfs_write_lock(dir->i_sb);
journal_begin(&th, dir->i_sb, jbegin_count) ;
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,
journal_end(&th, dir->i_sb, jbegin_count) ;
out_failed:
unlock_kernel();
reiserfs_write_unlock(dir->i_sb);
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)
{
int retval;
......@@ -714,15 +662,14 @@ static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode)
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
mode = S_IFDIR | mode;
inode = new_inode(dir->i_sb) ;
if (!inode) {
if (!(inode = new_inode(dir->i_sb))) {
return -ENOMEM ;
}
retval = new_inode_init(inode, dir, mode);
if (retval)
return retval;
lock_kernel();
reiserfs_write_lock(dir->i_sb);
journal_begin(&th, dir->i_sb, jbegin_count) ;
/* 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)
d_instantiate(dentry, inode);
journal_end(&th, dir->i_sb, jbegin_count) ;
out_failed:
unlock_kernel();
reiserfs_write_unlock(dir->i_sb);
return retval;
}
......@@ -779,14 +726,6 @@ static inline int reiserfs_empty_dir(struct inode *inode) {
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)
{
int retval;
......@@ -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 */
jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
lock_kernel();
reiserfs_write_lock(dir->i_sb);
journal_begin(&th, dir->i_sb, jbegin_count) ;
windex = push_journal_writer("reiserfs_rmdir") ;
......@@ -855,7 +794,7 @@ static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry)
pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ;
reiserfs_check_path(&path) ;
unlock_kernel();
reiserfs_write_unlock(dir->i_sb);
return 0;
end_rmdir:
......@@ -865,18 +804,10 @@ static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry)
pathrelse (&path);
pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ;
unlock_kernel();
reiserfs_write_unlock(dir->i_sb);
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)
{
int retval;
......@@ -893,7 +824,7 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
two stat datas */
jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2;
lock_kernel();
reiserfs_write_lock(dir->i_sb);
journal_begin(&th, dir->i_sb, jbegin_count) ;
windex = push_journal_writer("reiserfs_unlink") ;
......@@ -918,7 +849,7 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
if (!inode->i_nlink) {
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;
}
......@@ -942,7 +873,7 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ;
reiserfs_check_path(&path) ;
unlock_kernel();
reiserfs_write_unlock(dir->i_sb);
return 0;
end_unlink:
......@@ -950,19 +881,12 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ;
reiserfs_check_path(&path) ;
unlock_kernel();
reiserfs_write_unlock(dir->i_sb);
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_symlink (struct inode * dir, struct dentry * dentry, const char * symname)
static int reiserfs_symlink (struct inode * parent_dir,
struct dentry * dentry, const char * symname)
{
int retval;
struct inode * inode;
......@@ -972,24 +896,23 @@ static int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const c
int mode = S_IFLNK | S_IRWXUGO;
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
inode = new_inode(dir->i_sb) ;
if (!inode) {
if (!(inode = new_inode(parent_dir->i_sb))) {
return -ENOMEM ;
}
retval = new_inode_init(inode, dir, mode);
retval = new_inode_init(inode, parent_dir, mode);
if (retval) {
return retval;
}
lock_kernel();
reiserfs_write_lock(parent_dir->i_sb);
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;
drop_new_inode(inode);
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) {
drop_new_inode(inode);
retval = -ENOMEM;
......@@ -998,17 +921,17 @@ static int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const c
memcpy (name, symname, 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);
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 */
goto out_failed;
}
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_mapping->a_ops = &reiserfs_address_space_operations;
......@@ -1017,31 +940,23 @@ static int reiserfs_symlink (struct inode * dir, struct dentry * dentry, const c
//
//reiserfs_update_sd (&th, inode, READ_BLOCKS);
retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
inode, 1/*visible*/);
retval = reiserfs_add_entry (&th, parent_dir, dentry->d_name.name,
dentry->d_name.len, inode, 1/*visible*/);
if (retval) {
inode->i_nlink--;
reiserfs_update_sd (&th, inode);
journal_end(&th, dir->i_sb, jbegin_count) ;
journal_end(&th, parent_dir->i_sb, jbegin_count) ;
iput (inode);
goto out_failed;
}
d_instantiate(dentry, inode);
journal_end(&th, dir->i_sb, jbegin_count) ;
journal_end(&th, parent_dir->i_sb, jbegin_count) ;
out_failed:
unlock_kernel();
reiserfs_write_unlock(parent_dir->i_sb);
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)
{
int retval;
......@@ -1049,11 +964,12 @@ static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct
int windex ;
struct reiserfs_transaction_handle th ;
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) {
//FIXME: sd_nlink is 32 bit for new files
unlock_kernel();
reiserfs_write_unlock(dir->i_sb);
return -EMLINK;
}
......@@ -1070,19 +986,20 @@ static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct
if (retval) {
pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ;
unlock_kernel();
reiserfs_write_unlock(dir->i_sb);
return retval;
}
inode->i_nlink++;
inode->i_ctime = CURRENT_TIME;
ctime = CURRENT_TIME;
inode->i_ctime = ctime;
reiserfs_update_sd (&th, inode);
atomic_inc(&inode->i_count) ;
d_instantiate(dentry, inode);
pop_journal_writer(windex) ;
journal_end(&th, dir->i_sb, jbegin_count) ;
unlock_kernel();
reiserfs_write_unlock(dir->i_sb);
return 0;
}
......@@ -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
* 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,
INITIALIZE_PATH (dot_dot_entry_path);
struct item_head new_entry_ih, old_entry_ih, dot_dot_ih ;
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 ;
struct reiserfs_transaction_handle th ;
int jbegin_count ;
umode_t old_inode_mode;
time_t ctime;
/* 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,
jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 3;
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
// are going to rename
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,
&old_entry_path, &old_de);
pathrelse (&old_entry_path);
if (retval == IO_ERROR) {
unlock_kernel();
reiserfs_write_unlock(old_dir->i_sb);
return -EIO;
}
if (retval != NAME_FOUND || old_de.de_objectid != old_inode->i_ino) {
unlock_kernel();
reiserfs_write_unlock(old_dir->i_sb);
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 ".."
// and that its new parent directory has not too many links
// already
if (new_inode) {
if (!reiserfs_empty_dir(new_inode)) {
unlock_kernel();
if (new_dentry_inode) {
if (!reiserfs_empty_dir(new_dentry_inode)) {
reiserfs_write_unlock(old_dir->i_sb);
return -ENOTEMPTY;
}
}
......@@ -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);
pathrelse (&dot_dot_entry_path);
if (retval != NAME_FOUND) {
unlock_kernel();
reiserfs_write_unlock(old_dir->i_sb);
return -EIO;
}
/* inode number of .. must equal 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;
}
}
......@@ -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,
old_inode, 0);
if (retval == -EEXIST) {
// FIXME: is it possible, that new_inode == 0 here? If yes, it
// is not clear how does ext2 handle that
if (!new_inode) {
if (!new_dentry_inode) {
reiserfs_panic (old_dir->i_sb,
"vs-7050: new entry is found, new inode == 0\n");
}
} else if (retval) {
pop_journal_writer(windex) ;
journal_end(&th, old_dir->i_sb, jbegin_count) ;
unlock_kernel();
reiserfs_write_unlock(old_dir->i_sb);
return retval;
}
......@@ -1240,8 +1150,8 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
*/
reiserfs_update_inode_transaction(old_inode) ;
if (new_inode)
reiserfs_update_inode_transaction(new_inode) ;
if (new_dentry_inode)
reiserfs_update_inode_transaction(new_dentry_inode) ;
while (1) {
// 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,
if (item_moved(&new_entry_ih, &new_entry_path) ||
!entry_points_to_object(new_dentry->d_name.name,
new_dentry->d_name.len,
&new_de, new_inode) ||
&new_de, new_dentry_inode) ||
item_moved(&old_entry_ih, &old_entry_path) ||
!entry_points_to_object (old_dentry->d_name.name,
old_dentry->d_name.len,
&old_de, old_inode)) {
reiserfs_restore_prepared_buffer (old_inode->i_sb, new_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);
continue;
}
if (S_ISDIR(old_inode->i_mode)) {
if (S_ISDIR(old_inode_mode)) {
if ( item_moved(&dot_dot_ih, &dot_dot_entry_path) ||
!entry_points_to_object ( "..", 2, &dot_dot_de, old_dir) ) {
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,
}
}
RFALSE( S_ISDIR(old_inode->i_mode) &&
RFALSE( S_ISDIR(old_inode_mode) &&
!reiserfs_buffer_prepared(dot_dot_de.de_bh), "" );
break;
......@@ -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;
new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;
if (new_inode) {
if (new_dentry_inode) {
// adjust link number of the victim
if (S_ISDIR(new_inode->i_mode)) {
new_inode->i_nlink = 0;
if (S_ISDIR(new_dentry_inode->i_mode)) {
new_dentry_inode->i_nlink = 0;
} 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
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);
if (!new_inode)
if (!new_dentry_inode)
/* there (in new_dir) was no directory, so it got new link
(".." of renamed directory) */
INC_DIR_INODE_NLINK(new_dir);
......@@ -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, new_dir);
if (new_inode) {
if (new_inode->i_nlink == 0)
add_save_link (&th, new_inode, 0/* not truncate */);
reiserfs_update_sd (&th, new_inode);
if (new_dentry_inode) {
if (new_dentry_inode->i_nlink == 0)
add_save_link (&th, new_dentry_inode, 0/* not truncate */);
reiserfs_update_sd (&th, new_dentry_inode);
}
pop_journal_writer(windex) ;
journal_end(&th, old_dir->i_sb, jbegin_count) ;
unlock_kernel();
reiserfs_write_unlock(old_dir->i_sb);
return 0;
}
......
......@@ -337,7 +337,7 @@ void reiserfs_panic (struct super_block * sb, const char * fmt, ...)
/* this is not actually called, but makes reiserfs_panic() "noreturn" */
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)
return "unknown";
}
/* return 1 if this is not super block */
static int print_super_block (struct buffer_head * bh)
{
......@@ -509,8 +510,8 @@ static int print_super_block (struct buffer_head * bh)
return 1;
}
printk ("%s\'s super block in block %ld\n======================\n",
bdevname (bh->b_bdev), bh->b_blocknr);
printk ("%s\'s super block is in block %ld\n", bdevname (bh->b_bdev),
bh->b_blocknr);
printk ("Reiserfs version %s\n", version );
printk ("Block count %u\n", sb_block_count(rs));
printk ("Blocksize %d\n", sb_blocksize(rs));
......
......@@ -36,7 +36,7 @@ static struct super_block *procinfo_prologue( kdev_t dev )
/* get super-block by device */
result = get_super( dev );
if( result != NULL ) {
if( !reiserfs_is_super( result ) ) {
if( !is_reiserfs_super( result ) ) {
printk( KERN_DEBUG "reiserfs: procfs-52: "
"non-reiserfs super found\n" );
drop_super( result );
......@@ -500,7 +500,7 @@ int reiserfs_journal_in_proc( char *buffer, char **start, off_t offset,
"prepare_retry: \t%12lu\n",
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_size ),
DJP( jp_journal_trans_max ),
......@@ -556,13 +556,13 @@ static const char *proc_info_root_name = "fs/reiserfs";
int reiserfs_proc_info_init( struct super_block *sb )
{
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 ) {
REISERFS_SB(sb)->procdir -> owner = THIS_MODULE;
return 0;
}
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;
}
......@@ -573,7 +573,7 @@ int reiserfs_proc_info_done( struct super_block *sb )
__PINFO( sb ).exiting = 1;
spin_unlock( & __PINFO( sb ).lock );
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;
}
return 0;
......
......@@ -1715,13 +1715,13 @@ void reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
/* 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);
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) ;
return;
}
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);
/* Change key to search the last file item. */
......
......@@ -24,6 +24,8 @@
#define REISERFS_OLD_BLOCKSIZE 4096
#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_6_magic_string[] = REISER2FS_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)
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_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)
{
int dirty = 0 ;
lock_kernel() ;
reiserfs_write_lock(s);
if (!(s->s_flags & MS_RDONLY)) {
dirty = flush_old_commits(s, 1) ;
}
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)
{
int dirty = 0 ;
struct reiserfs_transaction_handle th ;
lock_kernel() ;
reiserfs_write_lock(s);
if (!(s->s_flags & MS_RDONLY)) {
journal_begin(&th, 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)
journal_end(&th, s, 1) ;
}
s->s_dirt = dirty;
unlock_kernel() ;
reiserfs_write_unlock(s);
}
void reiserfs_unlockfs(struct super_block *s) {
......@@ -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)
{
int i;
......@@ -469,7 +455,7 @@ static void reiserfs_dirty_inode (struct inode * inode) {
inode->i_ino) ;
return ;
}
lock_kernel() ;
reiserfs_write_lock(inode->i_sb);
/* this is really only used for atime updates, so they don't have
** to be included in O_SYNC or fsync
......@@ -477,7 +463,7 @@ static void reiserfs_dirty_inode (struct inode * inode) {
journal_begin(&th, inode->i_sb, 1) ;
reiserfs_update_sd (&th, inode);
journal_end(&th, inode->i_sb, 1) ;
unlock_kernel() ;
reiserfs_write_unlock(inode->i_sb);
}
struct super_operations reiserfs_sops =
......@@ -503,100 +489,190 @@ static struct export_operations reiserfs_export_ops = {
get_dentry: reiserfs_get_dentry,
} ;
/* this was (ext2)parse_options */
static int parse_options (char * options, unsigned long * mount_options, unsigned long * blocks, char **jdev_name)
{
char * this_char;
/* this struct is used in reiserfs_getopt () for containing the value for those
mount options that have values rather than being toggles. */
typedef struct {
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;
if (!options)
if (!options || !*options)
/* use default configuration: create tails, journaling on, no
conversion to newest format */
conversion to newest format */
return 1;
while ((this_char = strsep (&options, ",")) != NULL) {
if (!*this_char)
continue;
if ((value = strchr (this_char, '=')) != NULL)
*value++ = 0;
if (!strcmp (this_char, "notail")) {
set_bit (NOTAIL, mount_options);
} else if (!strcmp (this_char, "conv")) {
// if this is set, we update super block such that
// the partition will not be mounable by 3.5.x anymore
set_bit (REISERFS_CONVERT, mount_options);
} else if (!strcmp (this_char, "noborder")) {
/* this is used for benchmarking
experimental variations, it is not
intended for users to use, only for
developers who want to casually
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");
for (pos = options; pos; ) {
c = reiserfs_getopt (&pos, opts, &arg, mount_options);
if (c == -1)
/* wrong option is given */
return 0;
if (c == 'r') {
char * p;
p = 0;
/* "resize=NNN" */
*blocks = simple_strtoul (arg, &p, 0);
if (*p != '\0') {
/* NNN does not look like a number */
printk ("reiserfs_parse_options: bad value %s\n", arg);
return 0;
}
} else if (!strcmp (this_char, "hash")) {
if (value && *value) {
/* if they specify any hash option, we force detection
** to make sure they aren't using the wrong hash
*/
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 ;
}
if (c == 'j') {
if (arg && *arg && jdev_name) {
*jdev_name = arg;
}
} else {
printk ("reiserfs: Unrecognized mount option %s\n", this_char);
return 0;
}
}
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_remount (struct super_block * s, int * flags, char * data)
static int reiserfs_remount (struct super_block * s, int * mount_flags, char * arg)
{
struct reiserfs_super_block * rs;
struct reiserfs_transaction_handle th ;
......@@ -604,21 +680,21 @@ static int reiserfs_remount (struct super_block * s, int * flags, char * data)
unsigned long mount_options;
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) {
int rc = reiserfs_resize(s, blocks);
if (rc != 0)
return rc;
int rc = reiserfs_resize(s, blocks);
if (rc != 0)
return rc;
}
if ((unsigned long)(*flags & MS_RDONLY) == (s->s_flags & MS_RDONLY)) {
/* there is nothing to do to remount read-only fs as read-only fs */
return 0;
}
if (*flags & MS_RDONLY) {
if (*mount_flags & MS_RDONLY) {
/* remount rean-only */
if (s->s_flags & MS_RDONLY)
/* it is read-only already */
return 0;
/* 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) {
return 0;
......@@ -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) ;
s->s_flags &= ~MS_RDONLY ; /* now it is safe to call journal_begin */
journal_begin(&th, s, 10) ;
/* Mount a partition which is read-only, read-write */
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
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)
SB_JOURNAL(s)->j_must_wait = 1 ;
journal_end(&th, s, 10) ;
if (!( *flags & MS_RDONLY ) )
if (!( *mount_flags & MS_RDONLY ) )
finish_unfinished( s );
return 0;
......@@ -658,14 +734,14 @@ static int reiserfs_remount (struct super_block * s, int * flags, char * data)
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);
if (SB_AP_BITMAP (s) == 0)
return 1;
for (i = 0, bmp = REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1;
i < SB_BMAP_NR(s); i++, bmp = s->s_blocksize * 8 * i) {
SB_AP_BITMAP (s)[i] = sb_getblk(s, bmp);
for (i = 0, bmap_nr = REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1;
i < SB_BMAP_NR(s); i++, bmap_nr = s->s_blocksize * 8 * i) {
SB_AP_BITMAP (s)[i] = sb_getblk(s, bmap_nr);
if (!buffer_uptodate(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)
if (!bh) {
printk ("sh-2006: read_super_block: "
"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;
}
......@@ -755,7 +831,7 @@ static int read_super_block (struct super_block * s, int offset)
if (!bh) {
printk("sh-2007: read_super_block: "
"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;
}
......@@ -763,7 +839,7 @@ static int read_super_block (struct super_block * s, int offset)
if (sb_blocksize(rs) != s->s_blocksize) {
printk ("sh-2011: read_super_block: "
"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);
return 1;
}
......@@ -772,7 +848,7 @@ static int read_super_block (struct super_block * s, int offset)
brelse(bh) ;
printk("dev %s: Unfinished reiserfsck --rebuild-tree run detected. Please run\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;
}
......@@ -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])))) ) ) {
reiserfs_warning("reiserfs: Unable to automatically detect hash"
"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;
break;
}
......@@ -896,7 +972,7 @@ __u32 find_hash_out (struct super_block * s)
hash = R5_HASH;
else {
reiserfs_warning("reiserfs: Unrecognised hash function for "
"device %s\n", s->s_id);
"device %s\n", reiserfs_bdevname (s));
hash = UNSET_HASH;
}
} while (0);
......@@ -990,14 +1066,7 @@ int function2code (hashf_t func)
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_fill_super(struct super_block *s, void *data, int silent)
static int reiserfs_fill_super (struct super_block * s, void * data, int silent)
{
struct inode *root_inode;
int j;
......@@ -1009,21 +1078,24 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
struct reiserfs_super_block * rs;
char *jdev_name;
struct reiserfs_sb_info *sbi;
int errval = -EINVAL;
sbi = kmalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);
if (!sbi)
return -ENOMEM;
if (!sbi) {
errval = -ENOMEM;
goto error;
}
s->u.generic_sbp = sbi;
memset (sbi, 0, sizeof (struct reiserfs_sb_info));
jdev_name = NULL;
if (parse_options ((char *) data, &(sbi->s_mount_opt), &blocks, &jdev_name) == 0) {
return -EINVAL;
if (reiserfs_parse_options ((char *) data, &(sbi->s_mount_opt), &blocks, &jdev_name) == 0) {
goto error;
}
if (blocks) {
printk("reserfs: resize option for remount only\n");
return -EINVAL;
printk("jmacd-7: reiserfs_fill_super: resize option for remount only\n");
goto error;
}
/* 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)
old_format = 1;
/* try new format (64-th 1k block), which can contain reiserfs super block */
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;
}
sbi->s_mount_state = SB_REISERFS_STATE(s);
sbi->s_mount_state = REISERFS_VALID_FS ;
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;
}
#ifdef CONFIG_REISERFS_CHECK
......@@ -1056,7 +1128,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
*/
}
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 ;
}
......@@ -1071,7 +1143,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
args.dirid = REISERFS_ROOT_PARENT_OBJECTID ;
root_inode = iget5_locked (s, REISERFS_ROOT_OBJECTID, reiserfs_find_actor, reiserfs_init_locked_inode, (void *)(&args));
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;
}
......@@ -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 );
init_waitqueue_head (&(sbi->s_wait));
return 0;
return (0);
error:
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)
if (SB_BUFFER_WITH_SB (s))
brelse(SB_BUFFER_WITH_SB (s));
kfree(sbi);
s->u.generic_sbp = NULL;
if (sbi != 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)
{
struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);
/* changed to accomodate gcc folks.*/
buf->f_type = REISERFS_SUPER_MAGIC;
buf->f_bsize = s->s_blocksize;
buf->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1;
buf->f_namelen = (REISERFS_MAX_NAME (s->s_blocksize));
buf->f_ffree = -1;
buf->f_files = -1;
buf->f_bfree = sb_free_blocks(rs);
buf->f_bavail = buf->f_bfree;
buf->f_files = -1;
buf->f_ffree = -1;
buf->f_namelen = (REISERFS_MAX_NAME_LEN (s->s_blocksize));
buf->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1;
buf->f_bsize = s->s_blocksize;
/* changed to accomodate gcc folks.*/
buf->f_type = REISERFS_SUPER_MAGIC;
return 0;
}
static struct super_block *reiserfs_get_sb(struct file_system_type *fs_type,
int flags, char *dev_name, void *data)
static struct super_block*
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 = {
owner: THIS_MODULE,
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)
static int __init
init_reiserfs_fs ( void )
{
return s->s_type == &reiserfs_fs_type;
}
int ret;
//
// this is exactly what 2.3.99-pre9's init_ext2_fs is
//
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;
}
if ((ret = init_inodecache ())) {
return ret;
}
reiserfs_proc_info_global_init ();
reiserfs_proc_register_global ("version", reiserfs_global_version_in_proc);
MODULE_DESCRIPTION("ReiserFS journaled filesystem");
MODULE_AUTHOR("Hans Reiser <reiser@namesys.com>");
MODULE_LICENSE("GPL");
ret = register_filesystem (& reiserfs_fs_type);
//
// this is exactly what 2.3.99-pre9's init_ext2_fs is
//
static void __exit exit_reiserfs_fs(void)
{
reiserfs_proc_unregister_global( "version" );
reiserfs_proc_info_global_done();
unregister_filesystem(&reiserfs_fs_type);
destroy_inodecache();
if (ret == 0) {
return 0;
}
reiserfs_proc_unregister_global ("version");
reiserfs_proc_info_global_done ();
destroy_inodecache ();
return ret;
}
module_init(init_reiserfs_fs) ;
module_exit(exit_reiserfs_fs) ;
static void __exit
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,
copy_item_head (&s_ih, PATH_PITEM_HEAD(p_s_path));
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);
else
round_tail_len = tail_len;
......
......@@ -20,6 +20,7 @@
#include <asm/unaligned.h>
#include <linux/bitops.h>
#include <linux/proc_fs.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/reiserfs_fs_i.h>
#include <linux/reiserfs_fs_sb.h>
......@@ -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))))
// two entries per block (at least)
//#define REISERFS_MAX_NAME_LEN(block_size)
//((block_size - BLKH_SIZE - IH_SIZE - DEH_SIZE * 2) / 2)
#define REISERFS_MAX_NAME_LEN(block_size) 255
#define REISERFS_MAX_NAME(block_size) 255
/* this structure is used for operations on directory entries. It is
......@@ -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])
// 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_update_inode_transaction(struct inode *) ;
void reiserfs_wait_on_write_block(struct super_block *s) ;
......@@ -2073,6 +2077,12 @@ int reiserfs_unpack (struct inode * inode, struct file * filp);
/* ioctl's command */
#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 */
......
......@@ -408,6 +408,8 @@ struct reiserfs_sb_info
#define REISERFS_HASHED_RELOCATION 13
#define REISERFS_TEST4 14
#define REISERFS_ATTRS 15
#define REISERFS_TEST1 11
#define REISERFS_TEST2 12
#define REISERFS_TEST3 13
......@@ -430,7 +432,7 @@ struct reiserfs_sb_info
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 flush_old_commits(struct super_block *s, int) ;
int show_reiserfs_locks(void) ;
......@@ -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_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 */
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