Commit c7f37b79 authored by Anton Blanchard's avatar Anton Blanchard

Merge samba.org:/scratch/anton/linux-2.5

into samba.org:/scratch/anton/linux-2.5_bar
parents 0e1e2d82 2b5d7502
......@@ -161,7 +161,7 @@ KAO -->
</sect1>
<sect1><title>MTRR Handling</title>
!Earch/i386/kernel/mtrr.c
!Earch/i386/kernel/cpu/mtrr/main.c
</sect1>
<sect1><title>PCI Support Library</title>
!Edrivers/pci/pci.c
......
......@@ -80,14 +80,14 @@ would have a contended child and we had assumed that no object is its
own descendent. Moreover, there is exactly one cross-directory rename
(see above).
Consider the object blocking the cross-directory rename. One of
its descendents is locked by cross-directory rename (otherwise we would again
have an infinite set of of contended objects). But that means that means
that cross-directory rename is taking locks out of order. Due to (2) the
order hadn't changed since we had acquired filesystem lock. But locking
rules for cross-directory rename guarantee that we do not try to acquire
lock on descendent before the lock on ancestor. Contradiction. I.e.
deadlock is impossible. Q.E.D.
Consider the object blocking the cross-directory rename. One
of its descendents is locked by cross-directory rename (otherwise we
would again have an infinite set of of contended objects). But that
means that cross-directory rename is taking locks out of order. Due
to (2) the order hadn't changed since we had acquired filesystem lock.
But locking rules for cross-directory rename guarantee that we do not
try to acquire lock on descendent before the lock on ancestor.
Contradiction. I.e. deadlock is impossible. Q.E.D.
These operations are guaranteed to avoid loop creation. Indeed,
......
......@@ -69,7 +69,7 @@ Locking change: ->s_vfs_rename_sem is taken only by cross-directory renames.
Most likely there is no need to change anything, but if you relied on
global exclusion between renames for some internal purpose - you need to
change your internal locking. Otherwise exclusion warranties remain the
same (i.e. parents are victim are locked, etc.).
same (i.e. parents and victim are locked, etc.).
---
[informational]
......
VERSION = 2
PATCHLEVEL = 5
SUBLEVEL = 33
SUBLEVEL = 34
EXTRAVERSION =
# *DOCUMENTATION*
......
......@@ -156,6 +156,7 @@ static void __init init_intel(struct cpuinfo_x86 *c)
}
#endif
get_model_name(c);
if (c->cpuid_level > 1) {
/* supports eax=2 call */
......
......@@ -114,11 +114,10 @@ static int tosh_fn_status(void)
if (tosh_fn!=0) {
scan = inb(tosh_fn);
} else {
save_flags(flags);
cli();
local_irq_save(flags);
outb(0x8e, 0xe4);
scan = inb(0xe5);
restore_flags(flags);
local_irq_restore(flags);
}
return (int) scan;
......@@ -141,35 +140,32 @@ static int tosh_emulate_fan(SMMRegisters *regs)
if (tosh_id==0xfccb) {
if (eax==0xfe00) {
/* fan status */
save_flags(flags);
cli();
local_irq_save(flags);
outb(0xbe, 0xe4);
al = inb(0xe5);
restore_flags(flags);
local_irq_restore(flags);
regs->eax = 0x00;
regs->ecx = (unsigned int) (al & 0x01);
}
if ((eax==0xff00) && (ecx==0x0000)) {
/* fan off */
save_flags(flags);
cli();
local_irq_save(flags);
outb(0xbe, 0xe4);
al = inb(0xe5);
outb(0xbe, 0xe4);
outb (al | 0x01, 0xe5);
restore_flags(flags);
local_irq_restore(flags);
regs->eax = 0x00;
regs->ecx = 0x00;
}
if ((eax==0xff00) && (ecx==0x0001)) {
/* fan on */
save_flags(flags);
cli();
local_irq_save(flags);
outb(0xbe, 0xe4);
al = inb(0xe5);
outb(0xbe, 0xe4);
outb(al & 0xfe, 0xe5);
restore_flags(flags);
local_irq_restore(flags);
regs->eax = 0x00;
regs->ecx = 0x01;
}
......@@ -180,33 +176,30 @@ static int tosh_emulate_fan(SMMRegisters *regs)
if (tosh_id==0xfccc) {
if (eax==0xfe00) {
/* fan status */
save_flags(flags);
cli();
local_irq_save(flags);
outb(0xe0, 0xe4);
al = inb(0xe5);
restore_flags(flags);
local_irq_restore(flags);
regs->eax = 0x00;
regs->ecx = al & 0x01;
}
if ((eax==0xff00) && (ecx==0x0000)) {
/* fan off */
save_flags(flags);
cli();
local_irq_save(flags);
outb(0xe0, 0xe4);
al = inb(0xe5);
outw(0xe0 | ((al & 0xfe) << 8), 0xe4);
restore_flags(flags);
local_irq_restore(flags);
regs->eax = 0x00;
regs->ecx = 0x00;
}
if ((eax==0xff00) && (ecx==0x0001)) {
/* fan on */
save_flags(flags);
cli();
local_irq_save(flags);
outb(0xe0, 0xe4);
al = inb(0xe5);
outw(0xe0 | ((al | 0x01) << 8), 0xe4);
restore_flags(flags);
local_irq_restore(flags);
regs->eax = 0x00;
regs->ecx = 0x01;
}
......
This diff is collapsed.
......@@ -795,8 +795,8 @@ static int get_empty_nodes(
else /* If we have enough already then there is nothing to do. */
return CARRY_ON;
if ( reiserfs_new_blocknrs (p_s_tb->transaction_handle, a_n_blocknrs,
PATH_PLAST_BUFFER(p_s_tb->tb_path)->b_blocknr, n_amount_needed) == NO_DISK_SPACE )
if ( reiserfs_new_form_blocknrs (p_s_tb, a_n_blocknrs,
n_amount_needed) == NO_DISK_SPACE )
return NO_DISK_SPACE;
/* for each blocknumber we just got, get a buffer and stick it on FEB */
......
......@@ -19,6 +19,7 @@
//
#include <asm/types.h>
#include <asm/page.h>
......@@ -57,7 +58,6 @@ u32 keyed_hash(const signed char *msg, int len)
u32 pad;
int i;
// assert(len >= 0 && len < 256);
pad = (u32)len | ((u32)len << 8);
......@@ -92,7 +92,7 @@ u32 keyed_hash(const signed char *msg, int len)
{
//assert(len < 16);
if (len >= 16)
*(int *)0 = 0;
BUG();
a = (u32)msg[ 0] |
(u32)msg[ 1] << 8 |
......@@ -118,7 +118,7 @@ u32 keyed_hash(const signed char *msg, int len)
{
//assert(len < 12);
if (len >= 12)
*(int *)0 = 0;
BUG();
a = (u32)msg[ 0] |
(u32)msg[ 1] << 8 |
(u32)msg[ 2] << 16|
......@@ -139,7 +139,7 @@ u32 keyed_hash(const signed char *msg, int len)
{
//assert(len < 8);
if (len >= 8)
*(int *)0 = 0;
BUG();
a = (u32)msg[ 0] |
(u32)msg[ 1] << 8 |
(u32)msg[ 2] << 16|
......@@ -156,7 +156,7 @@ u32 keyed_hash(const signed char *msg, int len)
{
//assert(len < 4);
if (len >= 4)
*(int *)0 = 0;
BUG();
a = b = c = d = pad;
for(i = 0; i < len; i++)
{
......
......@@ -157,33 +157,6 @@ static inline void fix_tail_page_for_writing(struct page *page) {
}
}
/* we need to allocate a block for new unformatted node. Try to figure out
what point in bitmap reiserfs_new_blocknrs should start from. */
static b_blocknr_t find_tag (struct buffer_head * bh, struct item_head * ih,
__u32 * item, int pos_in_item)
{
__u32 block ;
if (!is_indirect_le_ih (ih))
/* something more complicated could be here */
return bh->b_blocknr;
/* for indirect item: go to left and look for the first non-hole entry in
the indirect item */
if (pos_in_item == I_UNFM_NUM (ih))
pos_in_item --;
while (pos_in_item >= 0) {
block = get_block_num(item, pos_in_item) ;
if (block)
return block ;
pos_in_item --;
}
return bh->b_blocknr;
}
/* reiserfs_get_block does not need to allocate a block only if it has been
done already or non-hole position has been found in the indirect item */
static inline int allocation_needed (int retval, b_blocknr_t allocated,
......@@ -342,10 +315,10 @@ static int _get_block_create_0 (struct inode * inode, long block,
** kmap schedules
*/
if (!p) {
p = (char *)kmap(bh_result->b_page) ;
if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
goto research;
}
p = (char *)kmap(bh_result->b_page) ;
if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
goto research;
}
}
p += offset ;
memset (p, 0, inode->i_sb->s_blocksize);
......@@ -506,24 +479,24 @@ static int convert_tail_for_hole(struct inode *inode,
}
static inline int _allocate_block(struct reiserfs_transaction_handle *th,
long block,
struct inode *inode,
b_blocknr_t *allocated_block_nr,
unsigned long tag,
struct path * path,
int flags) {
#ifdef REISERFS_PREALLOCATE
if (!(flags & GET_BLOCK_NO_ISEM)) {
return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr, tag);
return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr, path, block);
}
#endif
return reiserfs_new_unf_blocknrs (th, allocated_block_nr, tag);
return reiserfs_new_unf_blocknrs (th, allocated_block_nr, path, block);
}
int reiserfs_get_block (struct inode * inode, sector_t block,
struct buffer_head * bh_result, int create)
{
int repeat, retval;
unsigned long tag;
b_blocknr_t allocated_block_nr = 0;// b_blocknr_t is unsigned long
INITIALIZE_PATH(path);
int pos_in_item;
......@@ -602,7 +575,6 @@ int reiserfs_get_block (struct inode * inode, sector_t block,
if (allocation_needed (retval, allocated_block_nr, ih, item, pos_in_item)) {
/* we have to allocate block for the unformatted node */
tag = find_tag (bh, ih, item, pos_in_item);
if (!transaction_started) {
pathrelse(&path) ;
journal_begin(&th, inode->i_sb, jbegin_count) ;
......@@ -611,7 +583,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block,
goto research ;
}
repeat = _allocate_block(&th, inode, &allocated_block_nr, tag, create);
repeat = _allocate_block(&th, block, inode, &allocated_block_nr, &path, create);
if (repeat == NO_DISK_SPACE) {
/* restart the transaction to give the journal a chance to free
......@@ -619,7 +591,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block,
** research if we succeed on the second try
*/
restart_transaction(&th, inode, &path) ;
repeat = _allocate_block(&th, inode,&allocated_block_nr,tag,create);
repeat = _allocate_block(&th, block, inode, &allocated_block_nr, NULL, create);
if (repeat != NO_DISK_SPACE) {
goto research ;
......@@ -770,8 +742,8 @@ int reiserfs_get_block (struct inode * inode, sector_t block,
add_to_flushlist(inode, unbh) ;
/* mark it dirty now to prevent commit_write from adding
** this buffer to the inode's dirty buffer list
*/
** this buffer to the inode's dirty buffer list
*/
/*
* AKPM: changed __mark_buffer_dirty to mark_buffer_dirty().
* It's still atomic, but it sets the page dirty too,
......@@ -779,7 +751,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block,
* VM (which was also the case with __mark_buffer_dirty())
*/
mark_buffer_dirty(unbh) ;
//inode->i_blocks += inode->i_sb->s_blocksize / 512;
//mark_tail_converted (inode);
} else {
......@@ -920,7 +892,7 @@ static void init_inode (struct inode * inode, struct path * path)
inode->i_blocks = sd_v1_blocks(sd);
inode->i_generation = le32_to_cpu (INODE_PKEY (inode)->k_dir_id);
blocks = (inode->i_size + 511) >> 9;
blocks = _ROUND_UP (blocks, inode->i_blksize >> 9);
blocks = _ROUND_UP (blocks, inode->i_sb->s_blocksize >> 9);
if (inode->i_blocks > blocks) {
// there was a bug in <=3.5.23 when i_blocks could take negative
// values. Starting from 3.5.17 this value could even be stored in
......@@ -1592,6 +1564,10 @@ int reiserfs_new_inode (struct reiserfs_transaction_handle *th,
set_inode_sd_version (inode, STAT_DATA_V2);
/* insert the stat data into the tree */
#ifdef DISPLACE_NEW_PACKING_LOCALITIES
if (REISERFS_I(dir)->new_packing_locality)
th->displace_new_blocks = 1;
#endif
retval = reiserfs_insert_item (th, &path_to_key, &key, &ih, (char *)(&sd));
if (retval) {
err = retval;
......@@ -1599,6 +1575,10 @@ int reiserfs_new_inode (struct reiserfs_transaction_handle *th,
goto out_bad_inode;
}
#ifdef DISPLACE_NEW_PACKING_LOCALITIES
if (!th->displace_new_blocks)
REISERFS_I(dir)->new_packing_locality = 0;
#endif
if (S_ISDIR(mode)) {
/* insert item with "." and ".." */
retval = reiserfs_new_directory (th, &ih, &path_to_key, dir);
......@@ -1772,16 +1752,16 @@ void reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) {
reiserfs_update_inode_transaction(p_s_inode) ;
windex = push_journal_writer("reiserfs_vfs_truncate_file") ;
if (update_timestamps)
/* we are doing real truncate: if the system crashes before the last
transaction of truncating gets committed - on reboot the file
either appears truncated properly or not truncated at all */
add_save_link (&th, p_s_inode, 1);
/* we are doing real truncate: if the system crashes before the last
transaction of truncating gets committed - on reboot the file
either appears truncated properly or not truncated at all */
add_save_link (&th, p_s_inode, 1);
reiserfs_do_truncate (&th, p_s_inode, page, update_timestamps) ;
pop_journal_writer(windex) ;
journal_end(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1 ) ;
if (update_timestamps)
remove_save_link (p_s_inode, 1/* truncate */);
remove_save_link (p_s_inode, 1/* truncate */);
if (page) {
length = offset & (blocksize - 1) ;
......
......@@ -510,14 +510,12 @@ int dump_journal_writers(void) {
**
*/
int reiserfs_in_journal(struct super_block *p_s_sb,
unsigned long bl, int search_all,
int bmap_nr, int bit_nr, int search_all,
unsigned long *next_zero_bit) {
struct reiserfs_journal_cnode *cn ;
struct reiserfs_list_bitmap *jb ;
int i ;
int bmap_nr = bl / (p_s_sb->s_blocksize << 3) ;
int bit_nr = bl % (p_s_sb->s_blocksize << 3) ;
int tmp_bit ;
unsigned long bl;
*next_zero_bit = 0 ; /* always start this at zero. */
......@@ -537,15 +535,15 @@ int reiserfs_in_journal(struct super_block *p_s_sb,
jb = SB_JOURNAL(p_s_sb)->j_list_bitmap + i ;
if (jb->journal_list && jb->bitmaps[bmap_nr] &&
test_bit(bit_nr, (unsigned long *)jb->bitmaps[bmap_nr]->data)) {
tmp_bit = find_next_zero_bit((unsigned long *)
*next_zero_bit = find_next_zero_bit((unsigned long *)
(jb->bitmaps[bmap_nr]->data),
p_s_sb->s_blocksize << 3, bit_nr+1) ;
*next_zero_bit = bmap_nr * (p_s_sb->s_blocksize << 3) + tmp_bit ;
return 1 ;
}
}
}
bl = bmap_nr * (p_s_sb->s_blocksize << 3) + bit_nr;
/* is it in any old transactions? */
if (search_all && (cn = get_journal_hash_dev(p_s_sb, SB_JOURNAL(p_s_sb)->j_list_hash_table, bl))) {
return 1;
......@@ -1820,7 +1818,8 @@ static void reiserfs_journal_commit_task_func(struct reiserfs_journal_commit_tas
jl = SB_JOURNAL_LIST(ct->p_s_sb) + ct->jindex ;
flush_commit_list(ct->p_s_sb, SB_JOURNAL_LIST(ct->p_s_sb) + ct->jindex, 1) ;
if (jl->j_len > 0 && atomic_read(&(jl->j_nonzerolen)) > 0 &&
if (jl->j_len > 0 && atomic_read(&(jl->j_nonzerolen)) > 0 &&
atomic_read(&(jl->j_commit_left)) == 0) {
kupdate_one_transaction(ct->p_s_sb, jl) ;
}
......
......@@ -661,6 +661,10 @@ static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode)
struct reiserfs_transaction_handle th ;
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
#ifdef DISPLACE_NEW_PACKING_LOCALITIES
/* set flag that new packing locality created and new blocks for the content * of that directory are not displaced yet */
REISERFS_I(dir)->new_packing_locality = 1;
#endif
mode = S_IFDIR | mode;
if (!(inode = new_inode(dir->i_sb))) {
return -ENOMEM ;
......
......@@ -111,7 +111,7 @@ int reiserfs_global_version_in_proc( char *buffer, char **start, off_t offset,
#define SF( x ) ( r -> x )
#define SFP( x ) SF( s_proc_info_data.x )
#define SFPL( x ) SFP( x[ level ] )
#define SFPF( x ) SFP( find_forward.x )
#define SFPF( x ) SFP( scan_bitmap.x )
#define SFPJ( x ) SFP( journal.x )
#define D2C( x ) le16_to_cpu( x )
......@@ -165,6 +165,12 @@ int reiserfs_super_in_proc( char *buffer, char **start, off_t offset,
"search_by_key_fs_changed: \t%lu\n"
"search_by_key_restarted: \t%lu\n"
"insert_item_restarted: \t%lu\n"
"paste_into_item_restarted: \t%lu\n"
"cut_from_item_restarted: \t%lu\n"
"delete_solid_item_restarted: \t%lu\n"
"delete_item_restarted: \t%lu\n"
"leaked_oid: \t%lu\n"
"leaves_removable: \t%lu\n",
......@@ -178,7 +184,7 @@ int reiserfs_super_in_proc( char *buffer, char **start, off_t offset,
reiserfs_no_unhashed_relocation( sb ) ? "NO_UNHASHED_RELOCATION " : "",
reiserfs_hashed_relocation( sb ) ? "UNHASHED_RELOCATION " : "",
reiserfs_test4( sb ) ? "TEST4 " : "",
dont_have_tails( sb ) ? "NO_TAILS " : "TAILS ",
have_large_tails( sb ) ? "TAILS " : have_small_tails(sb)?"SMALL_TAILS ":"NO_TAILS ",
replay_only( sb ) ? "REPLAY_ONLY " : "",
reiserfs_dont_log( sb ) ? "DONT_LOG " : "LOG ",
convert_reiserfs( sb ) ? "CONV " : "",
......@@ -201,6 +207,13 @@ int reiserfs_super_in_proc( char *buffer, char **start, off_t offset,
SFP( search_by_key ),
SFP( search_by_key_fs_changed ),
SFP( search_by_key_restarted ),
SFP( insert_item_restarted ),
SFP( paste_into_item_restarted ),
SFP( cut_from_item_restarted ),
SFP( delete_solid_item_restarted ),
SFP( delete_item_restarted ),
SFP( leaked_oid ),
SFP( leaves_removable ) );
......@@ -301,27 +314,30 @@ int reiserfs_bitmap_in_proc( char *buffer, char **start, off_t offset,
r = REISERFS_SB(sb);
len += sprintf( &buffer[ len ], "free_block: %lu\n"
"find_forward:"
" wait"
" bmap"
" retry"
" journal_hint"
" journal_out"
" scan_bitmap:"
" wait"
" bmap"
" retry"
" stolen"
" journal_hint"
"journal_nohint"
"\n"
" %12lu"
" %12lu"
" %12lu"
" %12lu"
" %12lu"
" %12lu"
" %14lu"
" %14lu"
" %14lu"
" %14lu"
" %14lu"
" %14lu"
" %14lu"
"\n",
SFP( free_block ),
SFPF( call ),
SFPF( wait ),
SFPF( bmap ),
SFPF( retry ),
SFPF( stolen ),
SFPF( in_journal_hint ),
SFPF( in_journal_out ) );
SFPF( in_journal_nohint ) );
procinfo_epilogue( sb );
return reiserfs_proc_tail( len, buffer, start, offset, count, eof );
......
......@@ -19,7 +19,8 @@
int reiserfs_resize (struct super_block * s, unsigned long block_count_new)
{
struct reiserfs_super_block * sb;
struct buffer_head ** bitmap, * bh;
struct reiserfs_bitmap_info *bitmap;
struct buffer_head * bh;
struct reiserfs_transaction_handle th;
unsigned int bmap_nr_new, bmap_nr;
unsigned int block_r_new, block_r;
......@@ -103,26 +104,29 @@ int reiserfs_resize (struct super_block * s, unsigned long block_count_new)
/* allocate additional bitmap blocks, reallocate array of bitmap
* block pointers */
bitmap = reiserfs_kmalloc(sizeof(struct buffer_head *) * bmap_nr_new, GFP_KERNEL, s);
bitmap = vmalloc(sizeof(struct reiserfs_bitmap_info) * bmap_nr_new);
if (!bitmap) {
printk("reiserfs_resize: unable to allocate memory.\n");
return -ENOMEM;
}
memset (bitmap, 0, sizeof (struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
for (i = 0; i < bmap_nr; i++)
bitmap[i] = SB_AP_BITMAP(s)[i];
for (i = bmap_nr; i < bmap_nr_new; i++) {
bitmap[i] = sb_getblk(s, i * s->s_blocksize * 8);
memset(bitmap[i]->b_data, 0, sb_blocksize(sb));
reiserfs_test_and_set_le_bit(0, bitmap[i]->b_data);
mark_buffer_dirty(bitmap[i]) ;
set_buffer_uptodate(bitmap[i]);
ll_rw_block(WRITE, 1, bitmap + i);
wait_on_buffer(bitmap[i]);
bitmap[i].bh = sb_getblk(s, i * s->s_blocksize * 8);
memset(bitmap[i].bh->b_data, 0, sb_blocksize(sb));
reiserfs_test_and_set_le_bit(0, bitmap[i].bh->b_data);
mark_buffer_dirty(bitmap[i].bh) ;
set_buffer_uptodate(bitmap[i].bh);
ll_rw_block(WRITE, 1, &bitmap[i].bh);
wait_on_buffer(bitmap[i].bh);
// update bitmap_info stuff
bitmap[i].first_zero_hint=1;
bitmap[i].free_count = sb_blocksize(sb) * 8 - 1;
}
/* free old bitmap blocks array */
reiserfs_kfree(SB_AP_BITMAP(s),
sizeof(struct buffer_head *) * bmap_nr, s);
vfree(SB_AP_BITMAP(s));
SB_AP_BITMAP(s) = bitmap;
}
......@@ -130,18 +134,26 @@ int reiserfs_resize (struct super_block * s, unsigned long block_count_new)
journal_begin(&th, s, 10);
/* correct last bitmap blocks in old and new disk layout */
reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr - 1], 1);
reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr - 1].bh, 1);
for (i = block_r; i < s->s_blocksize * 8; i++)
reiserfs_test_and_clear_le_bit(i,
SB_AP_BITMAP(s)[bmap_nr - 1]->b_data);
journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr - 1]);
SB_AP_BITMAP(s)[bmap_nr - 1].bh->b_data);
SB_AP_BITMAP(s)[bmap_nr - 1].free_count += s->s_blocksize * 8 - block_r;
if ( !SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint)
SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint = block_r;
journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr - 1].bh);
reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr_new - 1], 1);
reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh, 1);
for (i = block_r_new; i < s->s_blocksize * 8; i++)
reiserfs_test_and_set_le_bit(i,
SB_AP_BITMAP(s)[bmap_nr_new - 1]->b_data);
journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr_new - 1]);
SB_AP_BITMAP(s)[bmap_nr_new - 1].bh->b_data);
journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh);
SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count -= s->s_blocksize * 8 - block_r_new;
/* Extreme case where last bitmap is the only valid block in itself. */
if ( !SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count )
SB_AP_BITMAP(s)[bmap_nr_new - 1].first_zero_hint = 0;
/* update super */
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
free_blocks = SB_FREE_BLOCKS(s);
......
......@@ -1245,6 +1245,8 @@ int reiserfs_delete_item (struct reiserfs_transaction_handle *th,
if ( n_ret_value != REPEAT_SEARCH )
break;
PROC_INFO_INC( p_s_sb, delete_item_restarted );
// file system changed, repeat search
n_ret_value = search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path);
if (n_ret_value == IO_ERROR)
......@@ -1355,8 +1357,10 @@ void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,
}
retval = fix_nodes (M_DELETE, &tb, NULL, 0);
if (retval == REPEAT_SEARCH)
if (retval == REPEAT_SEARCH) {
PROC_INFO_INC( th -> t_super, delete_solid_item_restarted );
continue;
}
if (retval == CARRY_ON) {
do_balance (&tb, 0, 0, M_DELETE);
......@@ -1543,6 +1547,8 @@ int reiserfs_cut_from_item (struct reiserfs_transaction_handle *th,
if ( n_ret_value != REPEAT_SEARCH )
break;
PROC_INFO_INC( p_s_sb, cut_from_item_restarted );
n_ret_value = search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path);
if (n_ret_value == POSITION_FOUND)
continue;
......@@ -1614,9 +1620,9 @@ int reiserfs_cut_from_item (struct reiserfs_transaction_handle *th,
do_balance(&s_cut_balance, NULL, NULL, c_mode);
if ( n_is_inode_locked ) {
/* we've done an indirect->direct conversion. when the data block
** was freed, it was removed from the list of blocks that must
** be flushed before the transaction commits, so we don't need to
/* we've done an indirect->direct conversion. when the data block
** was freed, it was removed from the list of blocks that must
** be flushed before the transaction commits, so we don't need to
** deal with it here.
*/
REISERFS_I(p_s_inode)->i_flags &= ~i_pack_on_close_mask ;
......@@ -1807,16 +1813,20 @@ int reiserfs_paste_into_item (struct reiserfs_transaction_handle *th,
int retval;
init_tb_struct(th, &s_paste_balance, th->t_super, p_s_search_path, n_pasted_size);
#ifdef DISPLACE_NEW_PACKING_LOCALITIES
s_paste_balance.key = p_s_key->on_disk_key;
#endif
while ( (retval = fix_nodes(M_PASTE, &s_paste_balance, NULL, p_c_body)) == REPEAT_SEARCH ) {
/* file system changed while we were in the fix_nodes */
PROC_INFO_INC( th -> t_super, paste_into_item_restarted );
retval = search_for_position_by_key (th->t_super, p_s_key, p_s_search_path);
if (retval == IO_ERROR) {
retval = -EIO ;
goto error_out ;
}
if (retval == POSITION_FOUND) {
reiserfs_warning ("PAP-5710: reiserfs_paste_into_item: entry or pasted byte (%K) exists", p_s_key);
reiserfs_warning ("PAP-5710: reiserfs_paste_into_item: entry or pasted byte (%K) exists\n", p_s_key);
retval = -EEXIST ;
goto error_out ;
}
......@@ -1851,6 +1861,9 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th,
int retval;
init_tb_struct(th, &s_ins_balance, th->t_super, p_s_path, IH_SIZE + ih_item_len(p_s_ih));
#ifdef DISPLACE_NEW_PACKING_LOCALITIES
s_ins_balance.key = key->on_disk_key;
#endif
/*
if (p_c_body == 0)
......@@ -1860,6 +1873,7 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th,
while ( (retval = fix_nodes(M_INSERT, &s_ins_balance, p_s_ih, p_c_body)) == REPEAT_SEARCH) {
/* file system changed while we were in the fix_nodes */
PROC_INFO_INC( th -> t_super, insert_item_restarted );
retval = search_item (th->t_super, key, p_s_path);
if (retval == IO_ERROR) {
retval = -EIO;
......
This diff is collapsed.
......@@ -59,7 +59,8 @@
#define USE_INODE_GENERATION_COUNTER
#define REISERFS_PREALLOCATE
#define PREALLOCATION_SIZE 8
#define DISPLACE_NEW_PACKING_LOCALITIES
#define PREALLOCATION_SIZE 9
/* n must be power of 2 */
#define _ROUND_UP(x,n) (((x)+(n)-1u) & ~((n)-1u))
......@@ -326,7 +327,7 @@ static inline struct reiserfs_sb_info *REISERFS_SB(const struct super_block *sb)
time cost for a 4 block file and saves an amount of space that is
less significant as a percentage of space, or so goes the hypothesis.
-Hans */
#define STORE_TAIL_IN_UNFM(n_file_size,n_tail_size,n_block_size) \
#define STORE_TAIL_IN_UNFM_S1(n_file_size,n_tail_size,n_block_size) \
(\
(!(n_tail_size)) || \
(((n_tail_size) > MAX_DIRECT_ITEM_LEN(n_block_size)) || \
......@@ -339,6 +340,18 @@ static inline struct reiserfs_sb_info *REISERFS_SB(const struct super_block *sb)
( (n_tail_size) >= (MAX_DIRECT_ITEM_LEN(n_block_size) * 3)/4) ) ) \
)
/* Another strategy for tails, this one means only create a tail if all the
file would fit into one DIRECT item.
Primary intention for this one is to increase performance by decreasing
seeking.
*/
#define STORE_TAIL_IN_UNFM_S2(n_file_size,n_tail_size,n_block_size) \
(\
(!(n_tail_size)) || \
(((n_file_size) > MAX_DIRECT_ITEM_LEN(n_block_size)) ) \
)
/*
* values for s_umount_state field
......@@ -1433,6 +1446,10 @@ struct tree_balance
int fs_gen; /* saved value of `reiserfs_generation' counter
see FILESYSTEM_CHANGED() macro in reiserfs_fs.h */
#ifdef DISPLACE_NEW_PACKING_LOCALITIES
struct key key; /* key pointer, to pass to block allocator or
another low-level subsystem */
#endif
} ;
/* These are modes of balancing */
......@@ -1673,7 +1690,7 @@ int journal_mark_freed(struct reiserfs_transaction_handle *, struct super_block
int push_journal_writer(char *w) ;
int pop_journal_writer(int windex) ;
int journal_transaction_should_end(struct reiserfs_transaction_handle *, int) ;
int reiserfs_in_journal(struct super_block *p_s_sb, unsigned long bl, int searchall, unsigned long *next) ;
int reiserfs_in_journal(struct super_block *p_s_sb, int bmap_nr, int bit_nr, int searchall, unsigned long *next) ;
int journal_begin(struct reiserfs_transaction_handle *, struct super_block *p_s_sb, unsigned long) ;
void flush_async_commits(struct super_block *p_s_sb) ;
......@@ -1818,8 +1835,8 @@ void reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
#define file_size(inode) ((inode)->i_size)
#define tail_size(inode) (file_size (inode) & (i_block_size (inode) - 1))
#define tail_has_to_be_packed(inode) (!dont_have_tails ((inode)->i_sb) &&\
!STORE_TAIL_IN_UNFM(file_size (inode), tail_size(inode), i_block_size (inode)))
#define tail_has_to_be_packed(inode) (have_large_tails ((inode)->i_sb)?\
!STORE_TAIL_IN_UNFM_S1(file_size (inode), tail_size(inode), inode->i_sb->s_blocksize):have_small_tails ((inode)->i_sb)?!STORE_TAIL_IN_UNFM_S2(file_size (inode), tail_size(inode), inode->i_sb->s_blocksize):0 )
void padd_item (char * item, int total_length, int length);
......@@ -2015,22 +2032,87 @@ void make_empty_node (struct buffer_info *);
struct buffer_head * get_FEB (struct tree_balance *);
/* bitmap.c */
/* structure contains hints for block allocator, and it is a container for
* arguments, such as node, search path, transaction_handle, etc. */
struct __reiserfs_blocknr_hint {
struct inode * inode; /* inode passed to allocator, if we allocate unf. nodes */
long block; /* file offset, in blocks */
struct key key;
struct path * path; /* search path, used by allocator to deternine search_start by
* various ways */
struct reiserfs_transaction_handle * th; /* transaction handle is needed to log super blocks and
* bitmap blocks changes */
b_blocknr_t beg, end;
b_blocknr_t search_start; /* a field used to transfer search start value (block number)
* between different block allocator procedures
* (determine_search_start() and others) */
int prealloc_size; /* is set in determine_prealloc_size() function, used by underlayed
* function that do actual allocation */
int formatted_node:1; /* the allocator uses different polices for getting disk space for
* formatted/unformatted blocks with/without preallocation */
int preallocate:1;
};
typedef struct __reiserfs_blocknr_hint reiserfs_blocknr_hint_t;
int reiserfs_parse_alloc_options (struct super_block *, char *);
int is_reusable (struct super_block * s, unsigned long block, int bit_value);
void reiserfs_free_block (struct reiserfs_transaction_handle *th, unsigned long);
int reiserfs_new_blocknrs (struct reiserfs_transaction_handle *th,
unsigned long * pblocknrs, unsigned long start_from, int amount_needed);
int reiserfs_new_unf_blocknrs (struct reiserfs_transaction_handle *th,
unsigned long * pblocknr, unsigned long start_from);
int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *, b_blocknr_t * , int, int);
extern inline int reiserfs_new_form_blocknrs (struct tree_balance * tb,
b_blocknr_t *new_blocknrs, int amount_needed)
{
reiserfs_blocknr_hint_t hint = {
th:tb->transaction_handle,
path: tb->tb_path,
inode: NULL,
key: tb->key,
block: 0,
formatted_node:1
};
return reiserfs_allocate_blocknrs(&hint, new_blocknrs, amount_needed, 0);
}
extern inline int reiserfs_new_unf_blocknrs (struct reiserfs_transaction_handle *th,
b_blocknr_t *new_blocknrs,
struct path * path, long block)
{
reiserfs_blocknr_hint_t hint = {
th: th,
path: path,
inode: NULL,
block: block,
formatted_node: 0,
preallocate: 0
};
return reiserfs_allocate_blocknrs(&hint, new_blocknrs, 1, 0);
}
#ifdef REISERFS_PREALLOCATE
int reiserfs_new_unf_blocknrs2 (struct reiserfs_transaction_handle *th,
struct inode * inode,
unsigned long * pblocknr,
unsigned long start_from);
extern inline int reiserfs_new_unf_blocknrs2(struct reiserfs_transaction_handle *th,
struct inode * inode,
b_blocknr_t *new_blocknrs,
struct path * path, long block)
{
reiserfs_blocknr_hint_t hint = {
th: th,
path: path,
inode: inode,
block: block,
formatted_node: 0,
preallocate: 1
};
return reiserfs_allocate_blocknrs(&hint, new_blocknrs, 1, 0);
}
void reiserfs_discard_prealloc (struct reiserfs_transaction_handle *th,
struct inode * inode);
void reiserfs_discard_all_prealloc (struct reiserfs_transaction_handle *th);
#endif
void reiserfs_claim_blocks_to_be_allocated( struct super_block *sb, int blocks);
void reiserfs_release_claimed_blocks( struct super_block *sb, int blocks);
/* hashes.c */
__u32 keyed_hash (const signed char *msg, int len);
......
......@@ -37,6 +37,10 @@ struct reiserfs_inode_info {
struct list_head i_prealloc_list; /* per-transaction list of inodes which
* have preallocated blocks */
int new_packing_locality:1; /* new_packig_locality is created; new blocks
* for the contents of this directory should be
* displaced */
/* we use these for fsync or O_SYNC to decide which transaction
** needs to be committed in order for this inode to be properly
** flushed */
......
......@@ -160,7 +160,10 @@ struct reiserfs_transaction_handle {
int t_blocks_allocated ; /* number of blocks this writer allocated */
unsigned long t_trans_id ; /* sanity check, equals the current trans id */
struct super_block *t_super ; /* super for this FS when journal_begin was
called. */
called. saves calls to reiserfs_get_super */
int displace_new_blocks:1; /* if new block allocation occurres, that block
should be displaced from others */
} ;
/*
......@@ -254,6 +257,14 @@ struct reiserfs_journal {
typedef __u32 (*hashf_t) (const signed char *, int);
struct reiserfs_bitmap_info
{
// FIXME: Won't work with block sizes > 8K
__u16 first_zero_hint;
__u16 free_count;
struct buffer_head *bh; /* the actual bitmap */
};
struct proc_dir_entry;
#if defined( CONFIG_PROC_FS ) && defined( CONFIG_REISERFS_PROC_INFO )
......@@ -270,6 +281,12 @@ typedef struct reiserfs_proc_info_data
stat_cnt_t search_by_key_fs_changed;
stat_cnt_t search_by_key_restarted;
stat_cnt_t insert_item_restarted;
stat_cnt_t paste_into_item_restarted;
stat_cnt_t cut_from_item_restarted;
stat_cnt_t delete_solid_item_restarted;
stat_cnt_t delete_item_restarted;
stat_cnt_t leaked_oid;
stat_cnt_t leaves_removable;
......@@ -292,14 +309,15 @@ typedef struct reiserfs_proc_info_data
stat_cnt_t need_r_neighbor[ 5 ];
stat_cnt_t free_block;
struct __find_forward_stats {
struct __scan_bitmap_stats {
stat_cnt_t call;
stat_cnt_t wait;
stat_cnt_t bmap;
stat_cnt_t retry;
stat_cnt_t in_journal_hint;
stat_cnt_t in_journal_out;
} find_forward;
stat_cnt_t in_journal_nohint;
stat_cnt_t stolen;
} scan_bitmap;
struct __journal_stats {
stat_cnt_t in_journal;
stat_cnt_t in_journal_bitmap;
......@@ -329,7 +347,7 @@ struct reiserfs_sb_info
/* both the comment and the choice of
name are unclear for s_rs -Hans */
struct reiserfs_super_block * s_rs; /* Pointer to the super block in the buffer */
struct buffer_head ** s_ap_bitmap; /* array of buffers, holding block bitmap */
struct reiserfs_bitmap_info * s_ap_bitmap;
struct reiserfs_journal *s_journal ; /* pointer to journal information */
unsigned short s_mount_state; /* reiserfs state (valid, invalid) */
......@@ -342,6 +360,16 @@ struct reiserfs_sb_info
here (currently - NOTAIL, NOLOG,
REPLAYONLY) */
struct { /* This is a structure that describes block allocator options */
unsigned long bits; /* Bitfield for enable/disable kind of options */
unsigned long large_file_size; /* size started from which we consider file to be a large one(in blocks) */
int border; /* percentage of disk, border takes */
int preallocmin; /* Minimal file size (in blocks) starting from which we do preallocations */
int preallocsize; /* Number of blocks we try to prealloc when file
reaches preallocmin size (in blocks) or
prealloc_list is empty. */
} s_alloc_options;
/* Comment? -Hans */
wait_queue_head_t s_wait;
/* To be obsoleted soon by per buffer seals.. -Hans */
......@@ -368,6 +396,7 @@ struct reiserfs_sb_info
int s_is_unlinked_ok;
reiserfs_proc_info_data_t s_proc_info_data;
struct proc_dir_entry *procdir;
int reserved_blocks; /* amount of blocks reserved for further allocations */
};
/* Definitions of reiserfs on-disk properties: */
......@@ -375,7 +404,8 @@ struct reiserfs_sb_info
#define REISERFS_3_6 1
/* Mount options */
#define NOTAIL 0 /* -o notail: no tails will be created in a session */
#define REISERFS_LARGETAIL 0 /* large tails will be created in a session */
#define REISERFS_SMALLTAIL 17 /* small (for files less than block size) tails will be created in a session */
#define REPLAYONLY 3 /* replay journal and return 0. Use by fsck */
#define REISERFS_NOLOG 4 /* -o nolog: turn journalling off */
#define REISERFS_CONVERT 5 /* -o conv: causes conversion of old
......@@ -423,7 +453,8 @@ struct reiserfs_sb_info
#define reiserfs_hashed_relocation(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_HASHED_RELOCATION))
#define reiserfs_test4(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_TEST4))
#define dont_have_tails(s) (REISERFS_SB(s)->s_mount_opt & (1 << NOTAIL))
#define have_large_tails(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_LARGETAIL))
#define have_small_tails(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_SMALLTAIL))
#define replay_only(s) (REISERFS_SB(s)->s_mount_opt & (1 << REPLAYONLY))
#define reiserfs_dont_log(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_NOLOG))
#define old_format_only(s) (REISERFS_SB(s)->s_properties & (1 << REISERFS_3_5))
......
......@@ -490,15 +490,6 @@ static void __init do_initcalls(void)
*/
static void __init do_basic_setup(void)
{
#if defined(CONFIG_MTRR) /* Do this after SMP initialization */
/*
* We should probably create some architecture-dependent "fixup after
* everything is up" style function where this would belong better
* than in init/main.c..
*/
mtrr_init();
#endif
#ifdef CONFIG_SYSCTL
sysctl_init();
#endif
......@@ -545,6 +536,15 @@ static int init(void * unused)
*/
child_reaper = current;
#if defined(CONFIG_MTRR) /* Do this after SMP initialization */
/*
* We should probably create some architecture-dependent "fixup after
* everything is up" style function where this would belong better
* than in init/main.c..
*/
mtrr_init();
#endif
/* Sets up cpus_possible() */
smp_prepare_cpus(max_cpus);
......
......@@ -532,7 +532,7 @@ static void exit_notify(void)
*
*/
if(current->exit_signal != SIGCHLD &&
if (current->exit_signal != SIGCHLD && current->exit_signal != -1 &&
( current->parent_exec_id != t->self_exec_id ||
current->self_exec_id != current->parent_exec_id)
&& !capable(CAP_KILL))
......
......@@ -1220,6 +1220,7 @@ int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs)
#endif
EXPORT_SYMBOL(recalc_sigpending);
EXPORT_SYMBOL(dequeue_signal);
EXPORT_SYMBOL(flush_signals);
EXPORT_SYMBOL(force_sig);
......
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