All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: 2.5.50-mm2
From: Andrew Morton @ 2002-12-13 19:58 UTC (permalink / raw)
  To: Christoph Hellwig, linux-xfs@oss.sgi.com; +Cc: lkml, linux-mm
In-Reply-To: <20021213175526.C2581@sgi.com>

Christoph Hellwig wrote:
> 
> On Mon, Dec 09, 2002 at 12:26:48AM -0800, Andrew Morton wrote:
> > +remove-PF_SYNC.patch
> >
> >  remove the current->flags:PF_SYNC abomination.  Adds a `sync' arg to
> >  all writepage implementations to tell them whether they are being
> >  called for memory cleansing or for data integrity.
> 
> Any chance you could pass down a struct writeback_control instead of
> just the sync flag?  XFS always used ->writepage similar to the
> ->vm_writeback in older kernel releases because writing out more
> than one page of delalloc space is really needed to be efficient and
> this would allow us to get a few more hints about the VM's intentions.

Yup, no probs.

It would be good to measure how often that codepath actually gets invoked
during testing and use.  It's typically quite rare.  It should be just
MAP_SHARED stuff, although there are probably some highmem-related scenarii
in which it will happen.

I'll add a writeback_control.for_reclaim boolean so we don't have to play
games with PF_MEMALLOC to reverse engineer the calling context.

If XFS is going to writearound extra pages in ->writepage() then it would
be best to set PG_reclaim (if wbc->for_reclaim) so end_page_writeback()
will rotate them.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/

^ permalink raw reply

* Re: [PATCH] Add CONFIG_ACPI_RELAXED_AML option
From: Craig Whitmore @ 2002-12-13 19:52 UTC (permalink / raw)
  To: Matthew Tippett, chbm-tNiY1ywYjSU
  Cc: acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <3DFA2394.40806@casero.com>

> > distributed in windows drivers.
>
> Continuing with this thread, would it make sense to be ACPI compliant
> but allow 'custom' dsdts to be passed to the acpi subsystem to allow
> users to work around less than perfect implementations from
> manufacturers.
>

Just 1 question. What do the manufacturer's say when you tell them they have
a "broken" dsdt? Do they normally fix it? or give some excuse in a reason
why they won't fix it?

Thanks
Craig



-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility 
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/

^ permalink raw reply

* Re: 2.5.50-mm2
From: Andrew Morton @ 2002-12-13 19:58 UTC (permalink / raw)
  To: Christoph Hellwig, linux-xfs@oss.sgi.com; +Cc: lkml, linux-mm
In-Reply-To: <20021213175526.C2581@sgi.com>

Christoph Hellwig wrote:
> 
> On Mon, Dec 09, 2002 at 12:26:48AM -0800, Andrew Morton wrote:
> > +remove-PF_SYNC.patch
> >
> >  remove the current->flags:PF_SYNC abomination.  Adds a `sync' arg to
> >  all writepage implementations to tell them whether they are being
> >  called for memory cleansing or for data integrity.
> 
> Any chance you could pass down a struct writeback_control instead of
> just the sync flag?  XFS always used ->writepage similar to the
> ->vm_writeback in older kernel releases because writing out more
> than one page of delalloc space is really needed to be efficient and
> this would allow us to get a few more hints about the VM's intentions.

Yup, no probs.

It would be good to measure how often that codepath actually gets invoked
during testing and use.  It's typically quite rare.  It should be just
MAP_SHARED stuff, although there are probably some highmem-related scenarii
in which it will happen.

I'll add a writeback_control.for_reclaim boolean so we don't have to play
games with PF_MEMALLOC to reverse engineer the calling context.

If XFS is going to writearound extra pages in ->writepage() then it would
be best to set PG_reclaim (if wbc->for_reclaim) so end_page_writeback()
will rotate them.

^ permalink raw reply

* Re: [PATCH] Revert module directory hierarchy and depmod invocation
From: Alex Riesen @ 2002-12-13 19:43 UTC (permalink / raw)
  To: Rusty Russell; +Cc: linux-kernel
In-Reply-To: <20021213030554.F27312C14D@lists.samba.org>

Rusty Russell, Fri, Dec 13, 2002 04:04:57 +0100:
> While the kernel, depmod et. al. don't care, other tools want the
> directory hierarchy under /lib/modules/`uname -r`/.  Sure, it's bogus
> for them to rely on kernel source layout, but noone has come up with a
> better alternative, so revert.
> 
> NOTE: You *still* can't have two modules of the same name!  (You never
> could).
> 

Are you sure it actually is the patch which does what
you have described?
And where can one find the patch, btw?

> Name: Module init reentry fix
> Author: Rusty Russell
> Status: Tested on 2.5.51
> 
> D: This changes the code to drop the module_mutex() before calling the
> D: module's init function, so module init functions can call
> D: request_module().  This was trivial before someone broke the module
> D: code to start non-live.  Now it requires us to keep info on the
> D: exact module state.
> 
> diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .27854-linux-2.5.51/include/linux/module.h .27854-linux-2.5.51.updated/include/linux/module.h
> --- .27854-linux-2.5.51/include/linux/module.h	2002-12-10 15:56:53.000000000 +1100
> +++ .27854-linux-2.5.51.updated/include/linux/module.h	2002-12-12 11:31:28.000000000 +1100

^ permalink raw reply

* RE: natting specific ports
From: Ranjeet Shetye @ 2002-12-13 19:34 UTC (permalink / raw)
  To: netfilter
In-Reply-To: <CAFAAEC91CC8D511952000062938C6F12ECDC4@ozlan.fcdomain.net>


Yes,

You need to DNAT the destination ports and therefore you need to look
for them using the --dport flag extension of the -p tcp/udp flag.

i.e. for telnet you'll have "-p tcp --dport 23".

Ranjeet Shetye
Senior Software Engineer
Zultys Technologies
771 Vaqueros Avenue
Sunnyvale  CA  94085
USA
Ranjeet.Shetye@Zultys.com
http://www.zultys.com/

 


> -----Original Message-----
> From: Simpson, Doug [mailto:DSimpson@friedmancorp.com] 
> Sent: Friday, December 13, 2002 11:19 AM
> To: 'Ranjeet Shetye'
> Subject: RE: natting specific ports
> 
> 
> I want this for traffic going out.  So that my internal 
> clients can send mail and telnet to servers out on the Public 
> Net. I need to use -dport instead of -sport? Thanks, Doug
> 
> -----Original Message-----
> From: Ranjeet Shetye [mailto:ranjeet.shetye@zultys.com]
> Sent: Friday, December 13, 2002 11:58 AM
> To: netfilter@lists.netfilter.org
> Subject: RE: natting specific ports
> 
> 
> 
> Hi Doug,
> 
> Do you want to NAT for traffic coming in or for traffic going out ?
> 
> If you want your internal network to be able to reach 
> external telnet and smtp servers, then your destination port 
> will be 23 or 25, not your source port.
> 
> If you want to host telnet and smtp servers behind a firewall 
> and allow only NATted access to these servers, then you 
> should be using DNAT, not SNAT.
> 
> Hope this helps,
> 
> Ranjeet Shetye
> Senior Software Engineer
> Zultys Technologies
> 771 Vaqueros Avenue
> Sunnyvale  CA  94085
> USA
> Ranjeet.Shetye@Zultys.com
> http://www.zultys.com/
> 
>  
> 
> 
> > -----Original Message-----
> > From: netfilter-admin@lists.netfilter.org
> > [mailto:netfilter-admin@lists.netfilter.org] On Behalf Of 
> > Simpson, Doug
> > Sent: Friday, December 13, 2002 9:49 AM
> > To: 'netfilter@lists.netfilter.org'
> > Subject: natting specific ports
> > 
> > 
> > I want to "NAT" just specific ports to my Public IP.  Do the
> > commands below make sense?  I want my internal network to be 
> > able to telnet and send email. (eth0 is my External NIC - it 
> > is exposed to the internet) 
> > iptables -t nat -A POSTROUTING -p tcp --sport 25 -o eth0 -s 
> > $INTERNAL_IP -j SNAT --to $EXTERNAL_IP iptables -t nat -A 
> > POSTROUTING -p tcp --sport 23 -o eth0 -s $INTERNAL_IP -j SNAT 
> > --to $EXTERNAL_IP
> > 
> > Thank you,
> > Doug
> > 
> 
> 




^ permalink raw reply

* Re: [PATCH][2.5][RFC] Using xAPIC apic address space on !Summit
From: James Cleverdon @ 2002-12-13 19:40 UTC (permalink / raw)
  To: Nakajima, Jun, Zwane Mwaikambo; +Cc: Martin Bligh, John Stultz, Linux Kernel
In-Reply-To: <F2DBA543B89AD51184B600508B68D40010F1CF8B@fmsmsx103.fm.intel.com>

On Friday 13 December 2002 07:43 am, Nakajima, Jun wrote:
> I/O APIC? I'm talking about xAPIC, i.e. local APIC which is part of the
> chip. Also note that I/O subsystem can generate interrupts (e.g. MSI,
> Message Signaled Interrupt), bypassing I/O APICs.
>
> Jun

Part of the "x" in xAPIC is that it can communicate over the classic 2 data / 
1 clock serial bus or send interrupts over the system bus.  If operating in 
serial mode, the old priority arbitration protocol works just fine.  It's 
parallel mode where we have problems.  All the I/O interrupts tend to hit CPU 
0, thanks to the XTPR HW's tie-breaker logic.

Intel has added a new register to I/O APICs that tells whether they're 
operating in serial or parallel mode.  It may be useful to read that bit 
before activating some of the code in my patches.

I've never worked on a system that tries to use MSIs.  Do they use lowest 
priority delivery?

(FYI, Summit boxes are hardwired into parallel mode.  There's no provision for 
a serial APIC bus connecting the PCI expansion box to the CPUs.)

> > -----Original Message-----
> > From: James Cleverdon [mailto:jamesclv@us.ibm.com]
> > Sent: Thursday, December 12, 2002 7:22 PM
> > To: Nakajima, Jun; Zwane Mwaikambo
> > Cc: Martin Bligh; John Stultz; Linux Kernel
> > Subject: Re: [PATCH][2.5][RFC] Using xAPIC apic address space on !Summit
> >
> > On Thursday 12 December 2002 07:05 pm, Nakajima, Jun wrote:
> > > BTW, we are working on a xAPIC patch that supports more than 8 CPUs in
> > > a generic fashion (don't use hardcode OEM checking). We already tested
> > > it
> >
> > on
> >
> > > two OEM systems with 16 CPUs.
> > > - It uses clustered mode. We don't want to use physical mode because it
> > > does not support lowest priority delivery mode.
> > > - We also check the version of the local APIC if it's xAPIC or not.
> > > It's possible that some other x86 architecture (other than P4P) uses
> > > xAPIC.
> > >
> > > Stay tuned.
> > >
> > > Jun
> >
> > See my 2.5 summit patch for one that uses logical mode and lowest
> > priority delivery.  I haven't submitted that for 2.4 because the physical
> > patch has the most run time on it, both in Alan's tree and SuSE 8.0+.
> >
> > The hardcoded OEM checking was necessary because the Summit I/O APICs
> > were still using the older version number.  (The HW folks claim that
> > Intel didn't
> > specify the new number soon enough for them.)
> >
> > I'm hesitant to key xAPIC vs. flat off the local APIC version number
> > because
> > it's possible to build a flat system out of P4 CPUs.  I/O APIC version
> > numbers combined with the parallel vs. serial bit would be safer (except
> > for
> > the Summit problem above).  I've also tried checking all the CPU's
> > physical
> > APIC IDs to see if they use multiple APIC clusters.
> >
> > > > -----Original Message-----
> > > > From: James Cleverdon [mailto:jamesclv@us.ibm.com]
> > > > Sent: Thursday, December 12, 2002 6:42 PM
> > > > To: Zwane Mwaikambo
> > > > Cc: Martin Bligh; John Stultz; Linux Kernel
> > > > Subject: Re: [PATCH][2.5][RFC] Using xAPIC apic address space on
> >
> > !Summit
> >
> > > > On Thursday 12 December 2002 06:21 pm, Zwane Mwaikambo wrote:
> > > > > On Thu, 12 Dec 2002, James Cleverdon wrote:
> > > > > > On Thursday 12 December 2002 05:44 pm, Zwane Mwaikambo wrote:
> > > > > > > Hi,
> > > > > > > 	I've got an 32x SMP system which has an xAPIC but utilises
> > > >
> > > > flat
> > > >
> > > > > > > addressing. This patch is to rename what was formerly
> > > > > > > x86_summit
> >
> > to
> >
> > > > > > > x86_xapic (just to avoid confusion) and then select mask
> >
> > depending
> >
> > > > on
> > > >
> > > > > > > that.
> > > > > > >
> > > > > > > Untested/uncompiled patch
> > > > > >
> > > > > > Hi Zwane,
> > > > > >
> > > > > > How can you have a 32-way SMP system with flat addressing?  There
> >
> > are
> >
> > > > > > only 8 bits in the destination address field.  Even if you work
> > > > > > around that by assigning a set of CPUs to each dest addr bit,
> >
> > there
> >
> > > > > > can only
> > > >
> > > > be
> > > >
> > > > > > 15 physical APIC IDs in flat mode.  To get to 32 you must switch
> >
> > into
> >
> > > > > > clustered mode.
> > > > > >
> > > > > > Please tell me more.  I'm intrigued how this can be done.
> > > > >
> > > > > Hi James,
> > > > > 	with the xAPIC we can use the 8bit address space everywhere
>
> in
>
> > > > > physical destination mode. For example the ICR now has an 8bit
> > > > > space for destination.
> > > > >
> > > > > "Specifies the target processor or processors. This field is only
> >
> > used
> >
> > > > > when the destination shorthand field is set to 00B. If the
> >
> > destination
> >
> > > > > mode is set to physical, then bits 56 through 59 contain the APIC
> > > > > ID
> >
> > of
> >
> > > > > the target processor for Pentium and P6 family processors and bits
> >
> > 56
> >
> > > > > through 63 contain the APIC ID of the target processor the for
> >
> > Pentium
> >
> > > > > 4 and Intel Xeon processors. If the destination mode is set to
> >
> > logical,
> >
> > > > the
> > > >
> > > > > interpretation of the 8-bit destination field depends on the
> >
> > settings
> >
> > > > > of the DFR and LDR registers of the local APICs in all the
> >
> > processors
> >
> > > > > in
> > > >
> > > > the
> > > >
> > > > > system (see Section 8.6.2.,  Determining IPI Destination )."
> > > > > 	- System Developer's Manual vol3 p291
> > > > >
> > > > > Regards,
> > > > > 	Zwane
> > > >
> > > > Sure you can physically address them, if you assign IDs using Intel's
> > > > official
> > > > xAPIC numbering scheme (which must be clustered for more than 7
> > > > CPUs). But,
> > > > you still don't have enough destination address bits to go around. 
> > > > In flat
> > > > mode, the kernel assumes you have one bit per CPU and phys IDs will
> > > > be
> >
> > <
> >
> > > > 0xF.
> > > >
> > > > Bill tells me that you may be doing this for an emulator.  Why not
> > > > emulate clusered APIC mode, like the real hardware uses?
> > > >
> > > > I know the name x86_summit doesn't really fit.  The summit patch
> >
> > should
> >
> > > > work
> > > > for any xAPIC box that uses the system bus for interrupt delivery and
> >
> > has
> >
> > > > multiple APIC clusters.  Is that what you're working towards?
> > > >
> > > > --
> > > > James Cleverdon
> > > > IBM xSeries Linux Solutions
> > > > {jamesclv(Unix, preferred), cleverdj(Notes)} at us dot ibm dot com
> >
> > --
> > James Cleverdon
> > IBM xSeries Linux Solutions
> > {jamesclv(Unix, preferred), cleverdj(Notes)} at us dot ibm dot com

-- 
James Cleverdon
IBM xSeries Linux Solutions
{jamesclv(Unix, preferred), cleverdj(Notes)} at us dot ibm dot com


^ permalink raw reply

* Re: [PATCH] sys_epoll for 2.4
From: Marc-Christian Petersen @ 2002-12-13 19:40 UTC (permalink / raw)
  To: linux-kernel; +Cc: Janet Morgan
In-Reply-To: <200212122303.gBCN3O721003@eng2.beaverton.ibm.com>

On Friday 13 December 2002 00:03, Janet Morgan wrote:

Hi Janet,

> The attached patch is a port of Davide's sys_epoll from 2.5.51 to 2.4.20.
I get this while make modules:

gcc -D__KERNEL__ -I/usr/src/linux-2.4.20/include  -Wall -Wstrict-prototypes 
-Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fomit-frame-pointer 
-mpreferred-stack-boundary=2 -march=i686 -DMODULE -DSMBFS_PARANOIA -nostdinc 
-iwithprefix include -DKBUILD_BASENAME=sock  -c -o sock.o sock.c
sock.c: In function `smb_receive_poll':
sock.c:323: warning: passing arg 1 of `poll_initwait' from incompatible 
pointer type
sock.c:328: warning: passing arg 1 of `poll_freewait' from incompatible 
pointer type
sock.c:334: warning: passing arg 1 of `poll_freewait' from incompatible 
pointer type
sock.c:337: structure has no member named `error'
sock.c:338: structure has no member named `error'
make[2]: *** [sock.o] Error 1
make[2]: Leaving directory `/usr/src/linux-2.4.20/fs/smbfs'
make[1]: *** [_modsubdir_smbfs] Error 2
make[1]: Leaving directory `/usr/src/linux-2.4.20/fs'
make: *** [_mod_fs] Error 2

This is SMBfs as module.

The code is this starting at line 333:

                timeout = schedule_timeout(timeout);
                poll_freewait(&wait_table);
                set_current_state(TASK_RUNNING);

                if (wait_table.error) {
                        result = wait_table.error;
                        break;
                }

                if (signal_pending(current)) {


ciao, Marc

^ permalink raw reply

* Re: [PATCH][2.5][RFC] Using xAPIC apic address space on !Summit
From: James Cleverdon @ 2002-12-13 19:32 UTC (permalink / raw)
  To: Steffen Persvold
  Cc: Zwane Mwaikambo, Nakajima, Jun, Martin Bligh, John Stultz,
	Linux Kernel
In-Reply-To: <Pine.LNX.4.44.0212130644540.1053-100000@sp-laptop.isdn.scali.no>

On Thursday 12 December 2002 09:53 pm, Steffen Persvold wrote:
> On Thu, 12 Dec 2002, James Cleverdon wrote:
> > On Thursday 12 December 2002 07:26 pm, Zwane Mwaikambo wrote:
> > > On Thu, 12 Dec 2002, Nakajima, Jun wrote:
> > > > BTW, we are working on a xAPIC patch that supports more than 8 CPUs
> > > > in a generic fashion (don't use hardcode OEM checking). We already
> > > > tested it on two OEM systems with 16 CPUs.
> > > > - It uses clustered mode. We don't want to use physical mode because
> > > > it does not support lowest priority delivery mode.
> > >
> > > Wouldn't that only be for all including self? Or is the documentation
> > > incorrect?
> > >
> > > Thanks,
> > > 	Zwane
> >
> > I'm not sure I understand your question.  Lowest Priority delivery mode
> > only works with logical interrupts.  (I've tried it with physical intrs. 
> > It fails miserably.)  The "all including self" and "all excluding self"
> > destination shorthands don't do lowest priority arbitration.  They always
> > deliver the interrupt to the CPUs mentioned in the shortand.
> >
> > Lowest priority delivery mode isn't _too_ useful in Linux yet.  It would
> > be nice to preferentially target idle CPUs with interrupts in real time. 
> > That means changing each CPU's Task Priority Register (TPR) to represent
> > how busy it is.  I've got some patches to do that, but haven't posted
> > them as anything more than a RFC.
>
> Hmm, I though the APIC routing patch found in the LSE project
> (http://sourceforge.net/projects/lse/) did this already. Atleast I've
> tested this patch on a couple of Dual E7500 Xeon boxes (kernel 2.4.20) and
> it distributes interrupts nicely.
>
> However with the patch enabled, the interrupt latency on for example the
> Intel GbE 82544GC devices increased a fraction with this patch (a
> microsecond or two).
>
> Regards,

Sure, Dave Olien's patch adjusted the TPR.  However, he wrote that for the 
classic APIC; it does most of the priority adjustments in the lower nibble of 
the TPR's value.  xAPIC routing is done via HW in the PCI-to-host bridge 
chips.  There they keep a copy of each CPU's TPR value in eight XTPR 
registers for lowest priority interrupt routing -- but only the TPR's upper 
nibble.  So, Dave's patch is less useful on xAPIC systems.

I came up with something simpler.   Just 2 lines added to idle_cpu() and 
do_IRQ respectively.  It's a hack but it seemed useful.

Interesting that it would be a microsecond slower.  Maybe that's the time it 
takes to adjust the TPR.  One more reason to keep those adjustments as simple 
as possible.

-- 
James Cleverdon
IBM xSeries Linux Solutions
{jamesclv(Unix, preferred), cleverdj(Notes)} at us dot ibm dot com


^ permalink raw reply

* Re: Support for Arctic platform (405LP based)
From: Todd Poynor @ 2002-12-13 19:25 UTC (permalink / raw)
  To: David Gibson; +Cc: linuxppc-embedded
In-Reply-To: <20021213043628.GI21319@zax.zax>


A few comments and questions...

I assume symbol CONFIG_ARCTIC2 is more appropriate than CONFIG_ARCTIC,
with additional symbols possibly to be invented in the future to
distinguish minor changes in board rev 3, 4, ... But mentioning this
just in case it might make future maintenance easier to use a single
symbol for common Arctic family code.

CONFIG_IBM_OPENBIOS is taken out of the CONFIG_SYCAMORE section of
arch/ppc/config.in?

Duplication of the CONFIG_BEECH case in
arch/ppc/boot/simple/embed_config.c: might be trying to enable the SSX
bootloader for Beech, but since CONFIG_IBM_OPENBIOS is on for Beech it
seems we'd have dup definitions?  Would more SSX code would be necessary
anyhow?

CONFIG_PPC_RTC is used to protect RTC code, most of these were
explicitly removed from other platforms some time ago, not sure what the
status of this is since there are a couple platforms that still use it.

I notice the bd_t has no entry for the ethernet MAC address in firmware,
like Beech, but am hoping there's an EEPROM on the device that holds
this info.  On Beech it causes some ugliness because the usual EEPROM is
not provided, so only the bootloader can program the ether dev's MAC.
And consequently the generic ethernet driver is hacked to deal with that.


--
Todd


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply

* Re: Intel P6 vs P7 system call performance
From: Dieter Nützel @ 2002-12-13 19:32 UTC (permalink / raw)
  To: Margit Schubert-While; +Cc: Linux Kernel List

> Well, in the 2.4.x kernels, the P4 gets compiled as a I686 with NO special
> treatment :-) (Not even prefetch, because of an ifdef bug)
> The P3 at least gets one level of prefetch and the AMD's get special compile
> options(arch=k6,athlon), full prefetch and SSE.
>
> >From Mike Hayward
> >Dual Pentium 4 Xeon 2.4Ghz 2.4.19 kernel 33661.9 lps (10 secs, 6 samples)
>
> Hmm, P4 2.4Ghz , also gcc -O3 -march=i686
>
> margit:/disk03/bytebench-3.1/src # ./hanoi 10
> 576264 loops
> margit:/disk03/bytebench-3.1/src # ./hanoi 10
> 571001 loops
> margit:/disk03/bytebench-3.1/src # ./hanoi 10
> 571133 loops
> margit:/disk03/bytebench-3.1/src # ./hanoi 10
> 570517 loops
> margit:/disk03/bytebench-3.1/src # ./hanoi 10
> 571019 loops
> margit:/disk03/bytebench-3.1/src # ./hanoi 10
> 582688 loops

Apples and oranges? ;-)

dual AMD Athlon MP 1900+, 1.6 GHz
(but single threaded app)
2.4.20-aa1
gcc-2.95.3

unixbench-4.1.0/src> gcc -O -mcpu=k6 -march=i686 -fomit-frame-pointer 
-mpreferred-stack-boundary=2 -malign-functions=4 -o hanoi hanoi.c
unixbench-4.1.0/src> sync
unixbench-4.1.0/src> ./hanoi 10                                                            
565338 loops
unixbench-4.1.0/src> ./hanoi 10
565379 loops
unixbench-4.1.0/src> ./hanoi 10
565448 loops
unixbench-4.1.0/src> ./hanoi 10
565218 loops
unixbench-4.1.0/src> ./hanoi 10
565148 loops
unixbench-4.1.0/src> ./hanoi 10
565136 loops

You should run "./Run hanoi"...

Recursion Test--Tower of Hanoi            58404.5 lps   (19.3 secs, 3 samples)

Regards,
	Dieter
-- 
Dieter Nützel
Graduate Student, Computer Science

University of Hamburg
Department of Computer Science
@home: Dieter.Nuetzel at hamburg.de (replace at with @)

^ permalink raw reply

* Compiling ucd-snmp using ELDK for PPC
From: Jin Cheng @ 2002-12-13 19:23 UTC (permalink / raw)
  To: linuxppc-embedded


Hi,

Anybody succeeded in compiling ucd-snmp.4.2.6 using ELDK? Could you
please share
your option run with configure?

I have compiled one, but only can snmpget/snmpwalk/etc, but can not
snmpset, it always
returns timeout.

Thanks

Jin

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply

* Re: orinoco_cs not working in 2.5.51
From: Matthew Harrell,,, @ 2002-12-13 19:27 UTC (permalink / raw)
  To: Thomas Molina, Kernel List
In-Reply-To: <1039654621.1410.4.camel@lap>

> After building 2.5.51 I am still unable to unable to load and configure
> drivers for an eth0 wireless interface on my Presario 12XL325 laptop. The
> SMC2632W card works on all 2.4 kernels and 2.5 kernels through  2.5.47 as
> previously documented in messages to this list.  Nothing after 47 will
> load and configure the eth0 device.
> 
> Mindful of the unsettled nature of module loading in latter 2.5 versions,
> I do a build with modular components and a build with everything built in.
> Rusty Russell's latest module init tools work well with both 2.4 and 2.5
> kernels, so I'm skeptical that module loading problems are the cause of
> my problem.

Well, in my case the modules load fine and appear to be working but pump 
gets errors and cannot use dhcp to get me an address.  When I manually configure
the interface with an IP then it works fine.  No idea what the proble with
that is.

Anyway, have you run "ifconfig" and "iwconfig" on the device to check that
the settings are alright?  If they are then manually give it an IP and see
if that works.

-- 
  Matthew Harrell                          Any sufficiently advanced bug is
  Bit Twiddlers, Inc.                       indistinguishable from a feature.
  mharrell@bittwiddlers.com     

^ permalink raw reply

* Re: [PATCH] S4Bios support for 2.4.20 + acpi-20021205
From: Ducrot Bruno @ 2002-12-13 19:17 UTC (permalink / raw)
  To: Nils Faerber; +Cc: Ducrot Bruno, acpi-devel-pyega4qmqnRoyOMFzWx49A
In-Reply-To: <20021213194907.5d99fc57.nils-t93Ne7XHvje5bSeCtf/tX7NAH6kLmebB@public.gmane.org>

On Fri, Dec 13, 2002 at 07:49:07PM +0100, Nils Faerber wrote:

[...]

> 
> My result:
> 	S4BIOS_REQ:       0x00
> 
> > For ./acpidmp FACS | ./acpitbl:
> > Flags have bit 0 set.
> 
> Signature:              FACS
> Length:                 64
> Hardware Signature:     0x00000000
> Firmware Waking Vector: 0x00000000
> Global Lock:            0x00000000
> Flags:                  0x00000000
> 
> Hmm ... and now?
> What does that mean?
> 

Your BIOS cry loudly that it do not support S4Bios (certainly due
to a lack of a suspend partition).  I supposed that my patch does it
right, so that if someone insist, it give up, but that is not the case.
I have to look what stupid brain-damaged bogosity I have written then.

-- 
Ducrot Bruno

--  Which is worse:  ignorance or apathy?
--  Don't know.  Don't care.


-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility 
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/

^ permalink raw reply

* Re: [LARTC] VRRPD (rfc2338)
From: sabat @ 2002-12-13 19:17 UTC (permalink / raw)
  To: lartc
In-Reply-To: <marc-lartc-103950635007394@msgid-missing>

[-- Attachment #1: Type: text/plain, Size: 4430 bytes --]

Dmitry Golubev wrote:

>Hello,
>
>And then bridge these interfaces together? I do not want to use any king of
>switch simply to make the card respond for multiple MAC addrs. Moreover
>I have seen VLAN probems with some eth cards that cannot work with
>1504 byte packets
>
Well, any good switch (at least Cisco) has spanning tree on so that such 
a bridge loop would not actually happen. But no, I mean that only the 
'live' router would have this MAC address. Maybe I don't understand what 
you're saying, exactly, but multiple MACs are how things are done in 
VRRP anyway. It's just a matter of whether you want multicast MACs or not.

>
>Anyway, Alexandre claims VLAN solution hacky. Do You use it in production?
>
I don't use it in production yet -- I'm about to start testing -- but I 
got the idea from someone who does use it in production, and seems quite 
satisfied that it works well, hacky or not. :) Check out the Linux 
Virtual Router Project: http://www.cs.fiu.edu/~flynnj/work/virtrouter.html

>
>BR, Dmitry
>
>======= At 2002-12-12, 15:05:00 you wrote: =======
>
>  
>
>>Dmitry Golubev wrote:
>>
>>    
>>
>>>But as far as I know, there is no VRRP implementations that fully comply
>>>with rfc2338 as it requires multiple MAC addresses for the one poor linux
>>>box's interface. Maybe, someone can suggest a working solution of this
>>>problem?
>>>
>>>      
>>>
>>Yes, there is a way -- the VLAN code in the linux kernel supports 
>>setting the MAC address of virtual interfaces (eth0.5, for instance). 
>>AFAIC, this is much superior (in concept) to multicast MACs, given the 
>>Cisco problem.
>>
>>    
>>
>>>I have seen one idea, but haven't tested it yet (hope someone can try it out):
>>>
>>>To bridge the physical iface with TAP on which the vrrpd (or keepalived) is
>>>running. In that case we could make the VRRP-router that fully comply with RFC.
>>>
>>>For more info see: http://www.math.leidenuniv.nl/pipermail/bridge/2002-June/002021.html
>>>
>>>BR, Dmitry
>>>
>>>======= At 2002-12-11, 03:56:00 you wrote: =======
>>>
>>> 
>>>
>>>      
>>>
>>>>The daemon at http://www.keepalived.org/ is the VRRPd implementation 
>>>>that's supposed to be the best. It's actually part of the Linux Virtual 
>>>>Server project (layer 4 load balancer), but the author claims you should 
>>>>be able to use it as a pure VRRP daemon -- although when I've read the 
>>>>doc, I couldn't figure out how. (But don't be discouraged by my 
>>>>impatience. :) It's supposed to be the most mature and ready-for-production.
>>>>
>>>>There's also Jerome Etienne's reference implementation (don't have a 
>>>>URL, but it's easy to Google). However, I've heard from more than place 
>>>>that this is too proof-of-concept and perhaps not production-worthy. 
>>>>Here's a link to a paper about running VRRPd as the hotspare protocol 
>>>>for linux firewalls (uses Jerome Etienne's implementation): 
>>>>http://www.gnusec.com/resource/security/docs/HAFirewallLinux-VRRP.pdf.
>>>>
>>>>BTW, keep in mind that if you intend to use VRRP in an environment with 
>>>>Cisco routers, you'll need to do some work on them too. Cisco routers do 
>>>>not accept multicast MAC addresses as legit ARP replies by default. 
>>>>Unfortunately, the VRRP RFC and all implementations use multicast MACs. 
>>>>What that means is that you'll need to either 1) turn the switch on the 
>>>>Cisco routers that makes them accept multicast MAC ARP replies (good), 
>>>>or 2) put a static ARP entry in the Cisco routers for the VRRP multicast 
>>>>MACs (better).
>>>>
>>>>Hope that helps.
>>>>
>>>>-S
>>>>
>>>>
>>>>Anton Tinchev wrote:
>>>>
>>>>   
>>>>
>>>>        
>>>>
>>>>>Can someone point me for good VRRPD (rfc2338) implementation on linux.
>>>>>Some stable and live project
>>>>>Thanks
>>>>>
>>>>>_______________________________________________
>>>>>LARTC mailing list / LARTC@mailman.ds9a.nl
>>>>>http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/
>>>>>
>>>>>
>>>>>     
>>>>>
>>>>>          
>>>>>
>>>>_______________________________________________
>>>>LARTC mailing list / LARTC@mailman.ds9a.nl
>>>>http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/
>>>>   
>>>>
>>>>        
>>>>
>>>			
>>>
>>>
>>>
>>>_______________________________________________
>>>LARTC mailing list / LARTC@mailman.ds9a.nl
>>>http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/
>>> 
>>>
>>>      
>>>
>
>			
>
>
>  
>

[-- Attachment #2: Type: text/html, Size: 6127 bytes --]

^ permalink raw reply

* Re: raid5: switching cache buffer size
From: Kanoalani Withington @ 2002-12-13 19:17 UTC (permalink / raw)
  To: Luca Berra; +Cc: Gordon Henderson, linux-raid
In-Reply-To: <3DFA2E2A.20601@comedia.it>

You might also be using a journaled filesystem with the journal on the 
same volume as the data. XFS does this by default for example, writes to 
the journal are not the same block size as writes to the data volume so 
the RAID layer reports tons of messages like the ones you describe. The 
proper solution (according the XFS maintainers) is to create a small 
disk mirror for the journal separate from the data volume.

-Kanoa

Luca Berra wrote:

> Gordon Henderson wrote:
>
>> Anyone know what this means?
>>
>> My big server is currently fscking a lvm partition which sits on-top 
>> of a
>> raid5 device and the console is scrolling these messages as fast as 
>> it can.
>> It says it's switching from 0 to 512, from 512 to 0 and 0 to 1024 ( or
>> maybe 512 to 1024, its hard to tell).
>>
>> What's happening and how do I stop it?
>
>
> hi,
> you probably have filesystems of different block in the volume group,
> raid cache cannot cope with requests of varying block size so it has 
> to flush the cache each time, this only hurts performance and is not 
> problem for data safety.
>
> fix:
> 1) make sure everything on your raid5 is the same block size, if you 
> have swap you are locked to using 4k blocks, if you are using 
> snapshots 1k blocks, if you use both jump.
> 2) comment the printk in the raid5 source
>
> L.
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-raid" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>



^ permalink raw reply

* Re: Promise Ultra100 TX2 driver problems
From: Adam Majer @ 2002-12-13 19:19 UTC (permalink / raw)
  To: Linux Kernel Mailing List
In-Reply-To: <20021111231126.GA1689@galacticasoftware.com>

Hi all,

This is just a followup, if anyone cares. The problem is
probably _not_ in the APIC code but most probably it's 
fucked up hardware. When any card, even ISA, is switched
to use IRQ 10 and APIC is enabled, it will cause thousands
of interrupts to be generated. Moving all cards from IRQ 10
to something else solved the problem completely. Yes,
even when APIC is enabled :)

adamm@polaris:/proc$ cat interrupts
           CPU0       CPU1       
  0:   24768091   22109926    IO-APIC-edge  timer
  1:       3856       3201    IO-APIC-edge  keyboard
  2:          0          0          XT-PIC  cascade
  7:          0          0    IO-APIC-edge  soundblaster
  8:      15815      15414    IO-APIC-edge  rtc
  9:    1314813    1317096   IO-APIC-level  ide2, ide3, sym53c8xx
 12:    7903733    7886885   IO-APIC-level  eth1, eth0
NMI:          0          0 
LOC:   46877866   46877865 
ERR:          0
MIS:      14052

- Adam

PS. This is for an old Compaq proliant 800 dual PPro but
it might be helpful to others.


On Mon, Nov 11, 2002 at 05:11:26PM -0600, Adam Majer wrote:
> On Mon, Nov 11, 2002 at 10:38:08PM +0000, Alan Cox wrote:
> > On Mon, 2002-11-11 at 19:26, adamm@galacticasoftware.com wrote:
> > > Hi all,
> > > 
> > > There seems to be a major problem with the promise drivers.
> > > It is detected and seems to work, but there is a very 
> > > large number of interrupts being generated:
> > 
> > Im dubious those interrupts are coming from the TX2 - what happens if
> > you boot with the "noapic" option ?
> 
> Yes, you are right. It is the APIC problem...
> 
> polaris:/proc# cat interrupts
>            CPU0       CPU1
>   0:     155563          0          XT-PIC  timer
>   1:       2510          0          XT-PIC  keyboard
>   2:          0          0          XT-PIC  cascade
>   5:       3421          0          XT-PIC  eth0
>   8:         23          0          XT-PIC  rtc
>   9:      26243          0          XT-PIC  sym53c8xx, eth1
>  10:     301052          0          XT-PIC  ide2, ide3
> NMI:          0          0
> LOC:     155501     155500
> ERR:       1427
> MIS:          0
> 
> 
> I'm not sure if the following will make the problem abvious
> for people that know anything about the APIC, but here it goes.
> The following are the relevant boot message for APIC. It was fine with
> all of the cards in there except for that Promise controller.
> Maybe the interrupt should have triggered on edge not on level?
> 
> PS. This is for 2.4.18 kernel
> 
> dmesg snip:
> 
> Intel MultiProcessor Specification v1.4
>     Virtual Wire compatibility mode.
> OEM ID: COMPAQ   Product ID: PROLIANT     APIC at: 0xFEE00000
> Processor #1 Pentium(tm) Pro APIC version 16
> Processor #0 Pentium(tm) Pro APIC version 16
> I/O APIC #2 Version 17 at 0xFEC00000.
> 
> [...]
> 
> ENABLING IO-APIC IRQs
> Setting 2 in the phys_id_present_map
> ...changing IO-APIC physical APIC ID to 2 ... ok.
> init IO_APIC IRQs
>  IO-APIC (apicid-pin) 2-0, 2-16, 2-17, 2-18, 2-19, 2-20, 2-21, 2-22, 2-23 not connected.
> ..TIMER: vector=0x31 pin1=2 pin2=0
> ..MP-BIOS bug: 8254 timer not connected to IO-APIC
> ...trying to set up timer (IRQ0) through the 8259A ...
> ..... (found pin 0) ...works.
> number of MP IRQ sources: 16.
> number of IO-APIC #2 registers: 24.
> testing the IO APIC.......................
> 
> IO APIC #2......
> .... register #00: 02000000
> .......    : physical APIC id: 02
> .... register #01: 00170011
> .......     : max redirection entries: 0017
> .......     : PRQ implemented: 0
> .......     : IO APIC version: 0011
> .... register #02: 00000000
> .......     : arbitration: 00
> .... IRQ redirection table:
>  NR Log Phy Mask Trig IRR Pol Stat Dest Deli Vect:
>  00 003 03  0    0    0   0   0    1    1    31
>  01 003 03  0    0    0   0   0    1    1    39
>  02 000 00  1    0    0   0   0    0    0    00
>  03 003 03  0    0    0   0   0    1    1    41
>  04 003 03  0    0    0   0   0    1    1    49
>  05 003 03  1    1    0   1   0    1    1    51
>  06 003 03  0    0    0   0   0    1    1    59
>  07 003 03  0    0    0   0   0    1    1    61
>  08 003 03  0    0    0   0   0    1    1    69
>  09 003 03  1    1    0   1   0    1    1    71
>  0a 003 03  1    1    0   1   0    1    1    79
>  0b 003 03  0    0    0   0   0    1    1    81
>  0c 003 03  0    0    0   0   0    1    1    89
>  0d 003 03  0    0    0   0   0    1    1    91
>  0e 003 03  0    0    0   0   0    1    1    99
>  0f 003 03  0    0    0   0   0    1    1    A1
>  10 000 00  1    0    0   0   0    0    0    00
>  11 000 00  1    0    0   0   0    0    0    00
>  12 000 00  1    0    0   0   0    0    0    00
>  13 000 00  1    0    0   0   0    0    0    00
>  14 000 00  1    0    0   0   0    0    0    00
>  15 000 00  1    0    0   0   0    0    0    00
>  16 000 00  1    0    0   0   0    0    0    00
>  17 000 00  1    0    0   0   0    0    0    00
> IRQ to pin mappings:
> IRQ0 -> 0:2
> IRQ1 -> 0:1
> IRQ3 -> 0:3
> IRQ4 -> 0:4
> IRQ5 -> 0:5
> IRQ6 -> 0:6
> IRQ7 -> 0:7
> IRQ8 -> 0:8
> IRQ9 -> 0:9
> IRQ10 -> 0:10
> IRQ11 -> 0:11
> IRQ12 -> 0:12
> IRQ13 -> 0:13
> IRQ14 -> 0:14
> IRQ15 -> 0:15
> .................................... done.
> Using local APIC timer interrupts.
> calibrating APIC timer ...
> ..... CPU clock speed is 179.6287 MHz.
> ..... host bus clock speed is 59.8760 MHz.
> cpu: 0, clocks: 598760, slice: 199586
> CPU0<T0:598752,T1:399152,D:14,S:199586,C:598760>
> cpu: 1, clocks: 598760, slice: 199586
> CPU1<T0:598752,T1:199568,D:12,S:199586,C:598760>
> checking TSC synchronization across CPUs: passed.
> Waiting on wait_init_idle (map = 0x2)
> All processors have done init_idle
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

-- 
---

www.GalacticaSoftware.com

^ permalink raw reply

* Re: NFS mounted rootfs possible via PCMCIA NIC ?
From: Andreas Schaufler @ 2002-12-13 20:28 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linux Kernel Mailing List
In-Reply-To: <3DF8C8E2.654208CE@digeo.com>

Am Donnerstag, 12. Dezember 2002 18:35 schrieb Andrew Morton:
...
> >
> > Maybe this patch is to be used on some Pre Version of 2.4.17 ?!?!
>
> Sorry, that patch was against 2.4.20.  It was last tested in 2.4.17.

Ok, thank you very much. It did not patch automatically in 2.4.20 though. But 
after I applied it manually everything works fine.

Now I can use my old Notebook, which has a broken IDE Controller, again :-)

best regards from a happy Linux User
-Andreas

^ permalink raw reply

* DMA from SCSI controller to PCI frame buffer memory.
From: Jason Howard @ 2002-12-13 19:15 UTC (permalink / raw)
  To: linux-kernel

Hello All,

I am wondering if the functionality exists in the Linux kernel to DMA 
from a SCSI controller directly into frame buffer memory of a PCI video
card?  Is there a standard method for this (similar to sendfile) or will
it require some hacking?

Jason

-- 
 Jason Howard

Professional:
  SpectSoft, LLC
  http://www.spectsoft.com  jason@spectsoft.com      
  Phone: +1.209.847.7812    Fax: +1.209.847.7859
Personal:
  http://www.psinux.org     jason@psinux.org
  Cell: +1.209.968.1289
  Text Message: jasonsphone@psinux.org



^ permalink raw reply

* Re: raid5: switching cache buffer size
From: Luca Berra @ 2002-12-13 18:59 UTC (permalink / raw)
  To: Gordon Henderson; +Cc: linux-raid
In-Reply-To: <Pine.LNX.4.43.0212131530510.6085-100000@unicorn.drogon.net>

Gordon Henderson wrote:
> Anyone know what this means?
> 
> My big server is currently fscking a lvm partition which sits on-top of a
> raid5 device and the console is scrolling these messages as fast as it can.
> It says it's switching from 0 to 512, from 512 to 0 and 0 to 1024 ( or
> maybe 512 to 1024, its hard to tell).
> 
> What's happening and how do I stop it?

hi,
you probably have filesystems of different block in the volume group,
raid cache cannot cope with requests of varying block size so it has to 
flush the cache each time, this only hurts performance and is not 
problem for data safety.

fix:
1) make sure everything on your raid5 is the same block size, if you 
have swap you are locked to using 4k blocks, if you are using snapshots 
1k blocks, if you use both jump.
2) comment the printk in the raid5 source

L.



^ permalink raw reply

* [BK][PATCH] ReiserFS additional inode attributes support for 2.5.51
From: Hans Reiser @ 2002-12-13 19:05 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 141 bytes --]

This adds such things as the immutable attribute to reiserfs, thereby 
making ReiserFS more conformant to the Linux (or at least ext2) norm.

[-- Attachment #2: reiserfs inode attributes support for 2.5.51 --]
[-- Type: message/rfc822, Size: 18650 bytes --]

From: Oleg Drokin <green@namesys.com>
To: reiser@namesys.com
Subject: reiserfs inode attributes support for 2.5.51
Date: Fri, 13 Dec 2002 20:05:14 +0300
Message-ID: <20021213200514.A8892@namesys.com>

Hello!

   These two changesets implement ext2 compatible extended inode attributes
   in reiserfs (the ones visible to lsattr(1) and friends).
   Second changeset also allows for some mount options to take effect on
   remount.
   Both changesets are forwardports from 2.4. Original work was performed
   by Nikita Danilov.

   You can pull these from bk://thebsh.namesys.com/bk/reiser3-linux-2.5-iattrs 

ChangeSet@1.846, 2002-12-07 14:29:56+03:00, green@angband.namesys.com
  reiserfs: Allow for remount options to take effect.

ChangeSet@1.845, 2002-12-07 14:26:28+03:00, green@angband.namesys.com
  reiserfs: Extended inode attributes support

Diffstat:
 fs/reiserfs/dir.c              |    1
 fs/reiserfs/inode.c            |   73 ++++++++++++++++++++++++++++++++++++-----
 fs/reiserfs/ioctl.c            |   62 ++++++++++++++++++++++++++++++++--
 fs/reiserfs/procfs.c           |    6 +++
 fs/reiserfs/super.c            |   36 ++++++++++++++++++++
 include/linux/reiserfs_fs.h    |   43 +++++++++++++++++++++++-
 include/linux/reiserfs_fs_i.h  |    3 +
 include/linux/reiserfs_fs_sb.h |    5 ++
 8 files changed, 215 insertions(+), 14 deletions(-)

Plain text patch:
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.844   -> 1.846  
#	fs/reiserfs/procfs.c	1.14    -> 1.15   
#	 fs/reiserfs/inode.c	1.68    -> 1.69   
#	 fs/reiserfs/ioctl.c	1.10    -> 1.11   
#	 fs/reiserfs/super.c	1.54    -> 1.56   
#	include/linux/reiserfs_fs_sb.h	1.20    -> 1.21   
#	   fs/reiserfs/dir.c	1.17    -> 1.18   
#	include/linux/reiserfs_fs_i.h	1.7     -> 1.8    
#	include/linux/reiserfs_fs.h	1.45    -> 1.46   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/12/07	green@angband.namesys.com	1.845
# reiserfs: Extended inode attributes support
# --------------------------------------------
# 02/12/07	green@angband.namesys.com	1.846
# reiserfs: Allow for remount options to take effect.
# --------------------------------------------
#
diff -Nru a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
--- a/fs/reiserfs/dir.c	Sat Dec  7 14:30:33 2002
+++ b/fs/reiserfs/dir.c	Sat Dec  7 14:30:33 2002
@@ -21,6 +21,7 @@
     read:	generic_read_dir,
     readdir:	reiserfs_readdir,
     fsync:	reiserfs_dir_fsync,
+    ioctl:	reiserfs_ioctl,
 };
 
 int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) {
diff -Nru a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
--- a/fs/reiserfs/inode.c	Sat Dec  7 14:30:33 2002
+++ b/fs/reiserfs/inode.c	Sat Dec  7 14:30:33 2002
@@ -871,8 +871,6 @@
     REISERFS_I(inode)->i_prealloc_count = 0;
     REISERFS_I(inode)->i_trans_id = 0;
     REISERFS_I(inode)->i_trans_index = 0;
-    /* nopack = 0, by default */
-    REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
 
     if (stat_data_v1 (ih)) {
 	struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
@@ -907,6 +905,9 @@
 
         rdev = sd_v1_rdev(sd);
 	REISERFS_I(inode)->i_first_direct_byte = sd_v1_first_direct_byte(sd);
+	/* nopack is initially zero for v1 objects. For v2 objects,
+	   nopack is initialised from sd_attrs */
+	REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
     } else {
 	// new stat data found, but object may have old items
 	// (directories and symlinks)
@@ -936,6 +937,10 @@
 	    set_inode_item_key_version (inode, KEY_FORMAT_3_6);
 	REISERFS_I(inode)->i_first_direct_byte = 0;
 	set_inode_sd_version (inode, STAT_DATA_V2);
+	/* read persistent inode attributes from sd and initalise
+	   generic inode flags from them */
+	REISERFS_I(inode)->i_attrs = sd_v2_attrs( sd );
+	sd_attrs_to_i_attrs( sd_v2_attrs( sd ), inode );
     }
 
     pathrelse (path);
@@ -960,6 +965,7 @@
 static void inode2sd (void * sd, struct inode * inode)
 {
     struct stat_data * sd_v2 = (struct stat_data *)sd;
+    __u16 flags;
 
     set_sd_v2_mode(sd_v2, inode->i_mode );
     set_sd_v2_nlink(sd_v2, inode->i_nlink );
@@ -970,13 +976,13 @@
     set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec );
     set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec );
     set_sd_v2_blocks(sd_v2, inode->i_blocks );
-    if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
-        set_sd_v2_rdev(sd_v2, kdev_t_to_nr(inode->i_rdev) );
-}
+    if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+	set_sd_v2_rdev(sd_v2, kdev_t_to_nr(inode->i_rdev) );
     else
-    {
-        set_sd_v2_generation(sd_v2, inode->i_generation);
-    }
+	set_sd_v2_generation(sd_v2, inode->i_generation);
+    flags = REISERFS_I(inode)->i_attrs;
+    i_attrs_to_sd_attrs( inode, &flags );
+    set_sd_v2_attrs( sd_v2, flags );
 }
 
 
@@ -1507,6 +1513,10 @@
 
     /* uid and gid must already be set by the caller for quota init */
 
+    /* symlink cannot be immutable or append only, right? */
+    if( S_ISLNK( inode -> i_mode ) )
+	    inode -> i_flags &= ~ ( S_IMMUTABLE | S_APPEND );
+
     inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
     inode->i_size = i_size;
     inode->i_blocks = (inode->i_size + 511) >> 9;
@@ -1519,6 +1529,9 @@
     REISERFS_I(inode)->i_prealloc_count = 0;
     REISERFS_I(inode)->i_trans_id = 0;
     REISERFS_I(inode)->i_trans_index = 0;
+    REISERFS_I(inode)->i_attrs =
+	REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK;
+    sd_attrs_to_i_attrs( REISERFS_I(inode) -> i_attrs, inode );
 
     if (old_format_only (sb))
 	make_le_item_head (&ih, 0, KEY_FORMAT_3_5, SD_OFFSET, TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT);
@@ -2073,6 +2086,50 @@
 	reiserfs_write_unlock(inode->i_sb);
     }
     return ret ;
+}
+
+void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode )
+{
+	if( reiserfs_attrs( inode -> i_sb ) ) {
+		if( sd_attrs & REISERFS_SYNC_FL )
+			inode -> i_flags |= S_SYNC;
+		else
+			inode -> i_flags &= ~S_SYNC;
+		if( sd_attrs & REISERFS_IMMUTABLE_FL )
+			inode -> i_flags |= S_IMMUTABLE;
+		else
+			inode -> i_flags &= ~S_IMMUTABLE;
+		if( sd_attrs & REISERFS_NOATIME_FL )
+			inode -> i_flags |= S_NOATIME;
+		else
+			inode -> i_flags &= ~S_NOATIME;
+		if( sd_attrs & REISERFS_NOTAIL_FL )
+			REISERFS_I(inode)->i_flags |= i_nopack_mask;
+		else
+			REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
+	}
+}
+
+void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs )
+{
+	if( reiserfs_attrs( inode -> i_sb ) ) {
+		if( inode -> i_flags & S_IMMUTABLE )
+			*sd_attrs |= REISERFS_IMMUTABLE_FL;
+		else
+			*sd_attrs &= ~REISERFS_IMMUTABLE_FL;
+		if( inode -> i_flags & S_SYNC )
+			*sd_attrs |= REISERFS_SYNC_FL;
+		else
+			*sd_attrs &= ~REISERFS_SYNC_FL;
+		if( inode -> i_flags & S_NOATIME )
+			*sd_attrs |= REISERFS_NOATIME_FL;
+		else
+			*sd_attrs &= ~REISERFS_NOATIME_FL;
+		if( REISERFS_I(inode)->i_flags & i_nopack_mask )
+			*sd_attrs |= REISERFS_NOTAIL_FL;
+		else
+			*sd_attrs &= ~REISERFS_NOTAIL_FL;
+	}
 }
 
 /*
diff -Nru a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
--- a/fs/reiserfs/ioctl.c	Sat Dec  7 14:30:33 2002
+++ b/fs/reiserfs/ioctl.c	Sat Dec  7 14:30:33 2002
@@ -14,17 +14,70 @@
 ** supported commands:
 **  1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect
 **                           and prevent packing file (argument arg has to be non-zero)
-**  2) That's all for a while ...
+**  2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION
+**  3) That's all for a while ...
 */
 int reiserfs_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
 		unsigned long arg)
 {
+	unsigned int flags;
+
 	switch (cmd) {
 	    case REISERFS_IOC_UNPACK:
+		if( S_ISREG( inode -> i_mode ) ) {
 		if (arg)
 		    return reiserfs_unpack (inode, filp);
+			else
+				return 0;
+		} else
+			return -ENOTTY;
+	/* following two cases are taken from fs/ext2/ioctl.c by Remy
+	   Card (card@masi.ibp.fr) */
+	case REISERFS_IOC_GETFLAGS:
+		flags = REISERFS_I(inode) -> i_attrs;
+		i_attrs_to_sd_attrs( inode, ( __u16 * ) &flags );
+		return put_user(flags, (int *) arg);
+	case REISERFS_IOC_SETFLAGS: {
+		if (IS_RDONLY(inode))
+			return -EROFS;
+
+		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+			return -EPERM;
+
+		if (get_user(flags, (int *) arg))
+			return -EFAULT;
+
+		if ( ( flags & REISERFS_IMMUTABLE_FL ) && 
+		     !capable( CAP_LINUX_IMMUTABLE ) )
+			return -EPERM;
 			
-	    default:
+		if( ( flags & REISERFS_NOTAIL_FL ) &&
+		    S_ISREG( inode -> i_mode ) ) {
+				int result;
+
+				result = reiserfs_unpack( inode, filp );
+				if( result )
+					return result;
+		}
+		sd_attrs_to_i_attrs( flags, inode );
+		REISERFS_I(inode) -> i_attrs = flags;
+		inode->i_ctime = CURRENT_TIME;
+		mark_inode_dirty(inode);
+		return 0;
+	}
+	case REISERFS_IOC_GETVERSION:
+		return put_user(inode->i_generation, (int *) arg);
+	case REISERFS_IOC_SETVERSION:
+		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+			return -EPERM;
+		if (IS_RDONLY(inode))
+			return -EROFS;
+		if (get_user(inode->i_generation, (int *) arg))
+			return -EFAULT;	
+		inode->i_ctime = CURRENT_TIME;
+		mark_inode_dirty(inode);
+		return 0;
+	default:
 		return -ENOTTY;
 	}
 }
@@ -32,7 +85,7 @@
 /*
 ** reiserfs_unpack
 ** Function try to convert tail from direct item into indirect.
-** It set up nopack attribute in the inode.u.reiserfs_i.nopack
+** It set up nopack attribute in the REISERFS_I(inode)->nopack
 */
 int reiserfs_unpack (struct inode * inode, struct file * filp)
 {
@@ -43,7 +96,8 @@
     unsigned long blocksize = inode->i_sb->s_blocksize ;
     	
     if (inode->i_size == 0) {
-        return -EINVAL ;
+        REISERFS_I(inode)->i_flags |= i_nopack_mask;
+        return 0 ;
     }
     /* ioctl already done */
     if (REISERFS_I(inode)->i_flags & i_nopack_mask) {
diff -Nru a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
--- a/fs/reiserfs/procfs.c	Sat Dec  7 14:30:32 2002
+++ b/fs/reiserfs/procfs.c	Sat Dec  7 14:30:32 2002
@@ -350,6 +350,7 @@
 	struct reiserfs_sb_info *sb_info;
 	struct reiserfs_super_block *rs;
 	int hash_code;
+	__u32 flags;
 	int len = 0;
     
 	sb = procinfo_prologue((dev_t)data);
@@ -358,6 +359,7 @@
 	sb_info = REISERFS_SB(sb);
 	rs = sb_info -> s_rs;
 	hash_code = DFL( s_hash_function_code );
+	flags = DJF( s_flags );
 
 	len += sprintf( &buffer[ len ], 
 			"block_count: \t%i\n"
@@ -373,6 +375,7 @@
 			"tree_height: \t%i\n"
 			"bmap_nr: \t%i\n"
 			"version: \t%i\n"
+			"flags: \t%x[%s]\n"
 			"reserved_for_journal: \t%i\n",
 
 			DFL( s_block_count ),
@@ -391,6 +394,9 @@
 			DF( s_tree_height ),
 			DF( s_bmap_nr ),
 			DF( s_version ),
+			flags,
+			( flags & reiserfs_attrs_cleared )
+			? "attrs_cleared" : "",
 			DF (s_reserved_for_journal));
 
 	procinfo_epilogue( sb );
diff -Nru a/fs/reiserfs/super.c b/fs/reiserfs/super.c
--- a/fs/reiserfs/super.c	Sat Dec  7 14:30:33 2002
+++ b/fs/reiserfs/super.c	Sat Dec  7 14:30:33 2002
@@ -697,6 +697,24 @@
     return 1;
 }
 
+static void handle_attrs( struct super_block *s )
+{
+	struct reiserfs_super_block * rs;
+
+	if( reiserfs_attrs( s ) ) {
+		rs = SB_DISK_SUPER_BLOCK (s);
+		if( old_format_only(s) ) {
+			reiserfs_warning( "reiserfs: cannot support attributes on 3.5.x disk format\n" );
+			REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
+			return;
+		}
+		if( !( le32_to_cpu( rs -> s_flags ) & reiserfs_attrs_cleared ) ) {
+				reiserfs_warning( "reiserfs: cannot support attributes until flag is set in super-block\n" );
+				REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
+		}
+	}
+}
+
 static int reiserfs_remount (struct super_block * s, int * mount_flags, char * arg)
 {
   struct reiserfs_super_block * rs;
@@ -708,7 +726,23 @@
 
   if (!reiserfs_parse_options(s, arg, &mount_options, &blocks, NULL))
     return -EINVAL;
+
+#define SET_OPT( opt, bits, super )                                     \
+    if( ( bits ) & ( 1 << ( opt ) ) )                                   \
+            REISERFS_SB( super ) -> s_mount_opt |= ( 1 << ( opt ) )
+
+  /* set options in the super-block bitmask */
+  SET_OPT( REISERFS_LARGETAIL, mount_options, s );
+  SET_OPT( REISERFS_SMALLTAIL, mount_options, s );
+  SET_OPT( REISERFS_NO_BORDER, mount_options, s );
+  SET_OPT( REISERFS_NO_UNHASHED_RELOCATION, mount_options, s );
+  SET_OPT( REISERFS_HASHED_RELOCATION, mount_options, s );
+  SET_OPT( REISERFS_TEST4, mount_options, s );
+  SET_OPT( REISERFS_ATTRS, mount_options, s );
+#undef SET_OPT
   
+  handle_attrs( s );
+
   if(blocks) {
     int rc = reiserfs_resize(s, blocks);
     if (rc != 0)
@@ -1303,6 +1337,8 @@
     }
     // mark hash in super block: it could be unset. overwrite should be ok
     set_sb_hash_function_code( rs, function2code(sbi->s_hash_function ) );
+
+    handle_attrs( s );
 
     reiserfs_proc_info_init( s );
     reiserfs_proc_register( s, "version", reiserfs_version_in_proc );
diff -Nru a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
--- a/include/linux/reiserfs_fs.h	Sat Dec  7 14:30:33 2002
+++ b/include/linux/reiserfs_fs.h	Sat Dec  7 14:30:33 2002
@@ -872,11 +872,41 @@
 #define set_sd_v1_first_direct_byte(sdp,v) \
                                 ((sdp)->sd_first_direct_byte = cpu_to_le32(v))
 
+#include <linux/ext2_fs.h>
+
+/* inode flags stored in sd_attrs (nee sd_reserved) */
+
+/* we want common flags to have the same values as in ext2,
+   so chattr(1) will work without problems */
+#define REISERFS_IMMUTABLE_FL EXT2_IMMUTABLE_FL
+#define REISERFS_SYNC_FL      EXT2_SYNC_FL
+#define REISERFS_NOATIME_FL   EXT2_NOATIME_FL
+#define REISERFS_NODUMP_FL    EXT2_NODUMP_FL
+#define REISERFS_SECRM_FL     EXT2_SECRM_FL
+#define REISERFS_UNRM_FL      EXT2_UNRM_FL
+#define REISERFS_COMPR_FL     EXT2_COMPR_FL
+/* persistent flag to disable tails on per-file basic.
+   Note, that is inheritable: mark directory with this and
+   all new files inside will not have tails. 
+
+   Teodore Tso allocated EXT2_NODUMP_FL (0x00008000) for this. Change
+   numeric constant to ext2 macro when available. */
+#define REISERFS_NOTAIL_FL    (0x00008000) /* EXT2_NOTAIL_FL */
+
+/* persistent flags that file inherits from the parent directory */
+#define REISERFS_INHERIT_MASK ( REISERFS_IMMUTABLE_FL |	\
+				REISERFS_SYNC_FL |	\
+				REISERFS_NOATIME_FL |	\
+				REISERFS_NODUMP_FL |	\
+				REISERFS_SECRM_FL |	\
+				REISERFS_COMPR_FL |	\
+				REISERFS_NOTAIL_FL )
+
 /* Stat Data on disk (reiserfs version of UFS disk inode minus the
    address blocks) */
 struct stat_data {
     __u16 sd_mode;	/* file type, permissions */
-    __u16 sd_reserved;
+    __u16 sd_attrs;     /* persistent inode flags */
     __u32 sd_nlink;	/* number of hard links */
     __u64 sd_size;	/* file size */
     __u32 sd_uid;		/* owner */
@@ -929,6 +959,8 @@
 #define set_sd_v2_rdev(sdp,v)   ((sdp)->u.sd_rdev = cpu_to_le32(v))
 #define sd_v2_generation(sdp)   (le32_to_cpu((sdp)->u.sd_generation))
 #define set_sd_v2_generation(sdp,v) ((sdp)->u.sd_generation = cpu_to_le32(v))
+#define sd_v2_attrs(sdp)         (le16_to_cpu((sdp)->sd_attrs))
+#define set_sd_v2_attrs(sdp,v)   ((sdp)->sd_attrs = cpu_to_le16(v))
 
 
 /***************************************************************************/
@@ -1870,6 +1902,9 @@
 int reiserfs_sync_inode (struct reiserfs_transaction_handle *th, struct inode * inode);
 void reiserfs_update_sd (struct reiserfs_transaction_handle *th, struct inode * inode);
 
+void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode );
+void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs );
+
 /* namei.c */
 inline void set_de_name_and_namelen (struct reiserfs_dir_entry * de);
 int search_by_entry_key (struct super_block * sb, const struct cpu_key * key, 
@@ -2142,6 +2177,12 @@
  
 /* ioctl's command */
 #define REISERFS_IOC_UNPACK		_IOW(0xCD,1,long)
+/* define following flags to be the same as in ext2, so that chattr(1),
+   lsattr(1) will work with us. */
+#define REISERFS_IOC_GETFLAGS		EXT2_IOC_GETFLAGS
+#define REISERFS_IOC_SETFLAGS		EXT2_IOC_SETFLAGS
+#define REISERFS_IOC_GETVERSION		EXT2_IOC_GETVERSION
+#define REISERFS_IOC_SETVERSION		EXT2_IOC_SETVERSION
 
 /* Locking primitives */
 /* Right now we are still falling back to (un)lock_kernel, but eventually that
diff -Nru a/include/linux/reiserfs_fs_i.h b/include/linux/reiserfs_fs_i.h
--- a/include/linux/reiserfs_fs_i.h	Sat Dec  7 14:30:33 2002
+++ b/include/linux/reiserfs_fs_i.h	Sat Dec  7 14:30:33 2002
@@ -32,6 +32,9 @@
 
     __u32 i_first_direct_byte; // offset of first byte stored in direct item.
 
+    /* copy of persistent inode flags read from sd_attrs. */
+    __u32 i_attrs;
+
     int i_prealloc_block; /* first unused block of a sequence of unused blocks */
     int i_prealloc_count; /* length of that sequence */
     struct list_head i_prealloc_list; /* per-transaction list of inodes which
diff -Nru a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
--- a/include/linux/reiserfs_fs_sb.h	Sat Dec  7 14:30:33 2002
+++ b/include/linux/reiserfs_fs_sb.h	Sat Dec  7 14:30:33 2002
@@ -8,6 +8,9 @@
 #include <linux/workqueue.h>
 #endif
 
+typedef enum {
+  reiserfs_attrs_cleared	= 0x00000001,
+} reiserfs_super_block_flags;
 
 /* struct reiserfs_super_block accessors/mutators
  * since this is a disk structure, it will always be in 
@@ -435,7 +438,6 @@
 #define REISERFS_NO_BORDER 11
 #define REISERFS_NO_UNHASHED_RELOCATION 12
 #define REISERFS_HASHED_RELOCATION 13
-#define REISERFS_TEST4 14 
 
 #define REISERFS_ATTRS 15
 
@@ -457,6 +459,7 @@
 #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 reiserfs_attrs(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_ATTRS))
 #define old_format_only(s) (REISERFS_SB(s)->s_properties & (1 << REISERFS_3_5))
 #define convert_reiserfs(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_CONVERT))
 



^ permalink raw reply

* Re: 2.5.5[01]]: Xircom Cardbus broken (PCI resource collisions)
From: Jeff Garzik @ 2002-12-13 19:03 UTC (permalink / raw)
  To: Dave Jones; +Cc: Valdis.Kletnieks, Petr Konecny, linux-kernel
In-Reply-To: <20021213173656.GC1633@suse.de>

Dave Jones wrote:
> It's my understanding that pci_enable_device() *must* be called
> before we fiddle with dev->resource, dev->irq and the like.


True and correct, but -- this particular case is inside the cardbus 
core, where it presumeably might have a better idea of when it is best 
to call pci_enable_device (or perhaps even not at all, and twiddle the 
bits itself).


^ permalink raw reply

* [LARTC] Confusion about MTU
From: Daniel @ 2002-12-13 18:54 UTC (permalink / raw)
  To: lartc

Hi!

This is acctually my first mail to the list, I never really
planned on joining but I could find any answers so, well...

I'm kind of a perfecttionist... or rather I like to play around
alot with stuff so that they work the best that they possibly can.

I know most of the stuff about HTB and IMQ and the setup I use now
works great, not to say that there aren't room for improvement, there
always is. Anyways I'm really enjoying the setup, finally I can play
online games not having to constantly worrying about my siblings destroying
my game using som filesharing app or whatever.

Ok, this is my question : What should I consider to be the maximum
packetsize
inside an IMQ and using the HTB queue?

I'm thinking 1500b i.e without the 14b ethernet encap, small proof of this
is that
an sfq queue withing the IMQ device defaults it's quantum to 1500b instead
of the
1514b as it does if attached to a real ethernet device. This could also be a
bug, dunno.

I want to use the smallest possible value for burst, cburst and quantum, so
what
would that be? Note I'm shaping traffic that is small enough that setting
those settings to the mtu wont affect troughoutput.

//Daniel

ps. Sorry if the mail got a little messy, I wrote it in a hurry


_______________________________________________
LARTC mailing list / LARTC@mailman.ds9a.nl
http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/

^ permalink raw reply

* Integrating Linux Desktop With MS Exchange Server
From: Kumar, Pradeep (MED, TCS) @ 2002-12-13 18:54 UTC (permalink / raw)
  To: 'linux-admin@vger.kernel.org'

Hi,
I am sorry if I am posting this to a wrong mailing list. In that case,
please suggest me the correct one.

We are currently running Microsoft Exchange 5.5 server. Now we would
like to run Red Hat Linux on some desktops. 
But we would like to have a unified logon procedure i.e all the windows
users should be able to login on the linux desktop
with their windows username and passwords. Whenever a user wants to
login to the linux desktop, the authentication
should be redirected to the Windows Primary Domain Controller. As a
whole , it is just putting a linux desktop into
a Windows domain. But all the usernames and passwords are created and
maintained on the Exchange Server database and 
and authentication of all users should be done on the Exchange server.

Please help me how to proceed on this. I would appreciate any useful
information provided. What should I do to achieve this?
What and all should be ruuning at Linux side? How to achieve this
integration?

Thanks in anticipation,

Regards,
Pradeep

S.Pradeep Kumar
Pradeep.Kumar@med.ge.com

^ permalink raw reply

* Re: [PATCH] S4Bios support for 2.4.20 + acpi-20021205
From: Nils Faerber @ 2002-12-13 18:49 UTC (permalink / raw)
  Cc: ducrot-kk6yZipjEM5g9hUCZPvPmw, acpi-devel-pyega4qmqnRoyOMFzWx49A
In-Reply-To: <20021213183622.GN4327-j6u/t2rXLliUoIHC/UFpr9i2O/JbrIOy@public.gmane.org>

On Fri, 13 Dec 2002 19:36:22 +0100
Ducrot Bruno <ducrot-kk6yZipjEM5g9hUCZPvPmw@public.gmane.org> wrote:
> On Fri, Dec 13, 2002 at 06:13:16PM +0100, Nils Faerber wrote:
> > On Fri, 13 Dec 2002 17:36:15 +0100
> > Ducrot Bruno <ducrot-kk6yZipjEM5g9hUCZPvPmw@public.gmane.org> wrote:
> > > On Fri, Dec 13, 2002 at 05:14:31PM +0100, Nils Faerber wrote:
> > > > On Fri, 13 Dec 2002 16:53:09 +0100
> > > > Ducrot Bruno <ducrot-kk6yZipjEM5g9hUCZPvPmw@public.gmane.org> wrote:
> > > > > Patch for 2.4.20 and acpi-20021205 for adding s4bios feature.
> > > Well, I don't know.  Perhaps lphdisk (I don't remember the URI)
> > > could help.  Some googling permit to get it.  Or (who knows?) even
> > > a/dev/hda1 as a vfat partition can help?
> > 
> > AFAIK this is only good for Phoenix BIOS whereas mine is AWARD
> > Medallion. Couldn't this also be specified in ACPI specs, i.e. how a
> > suspend partition has to look like?
> 
> You will find nothing.  This is not ACPI problem, but a BIOS one.

Surely, but I was also speaking about "ideal world" :)

> > > > does it suspend? I know for Phoenix BIOSes there is a tool on
> > > > the net to create that partition. I have a Asus L3800C notebook
> > > > which has AFAIK an AWARD BIOS. And AFAIK there is no tool
> > > > available from ASUS or AWARD to create such a partition.
> > > In a really perfect world:
> > > echo 1 > /proc/acpi/sleep	# for standby
> > > echo 2 > /proc/acpi/sleep	# for suspend to ram
> > > echo 3 > /proc/acpi/sleep	# for suspend to ram, but with more power conservative
> > > echo 4 > /proc/acpi/sleep	# for suspend to disk
> > > echo 5 > /proc/acpi/sleep	# for shutdown unfriendly the system
> 
> I wanted only to speak for a 'perfect world', not for what is the
> patch. My apologies for confusion.

Sure, I think I was not clear about what I said.

> > That would really be perfect :)
> > S1 on mine does just switch of the fan and stops the CPU. Nothing
> > more. S2 does not exist.
> > S3 does nothing except for funny ACPI messages:
> > 	acpi: sleep 3
> > 	acpi: GO!
> > 	acpi: acpi_suspend call 3
> > 
> > And your S4BIOS patch ends up freezing the machine after "saving CPU
> > context". Oh, but S5 behaves as expected :)
> 
> My patch is NOT for S3.

Yep, knew that :) Just wanted to let you (and others maybe) know.

> S4bios requrire that the bios have necessary support.  I check that
> it has before going to s4bios. Could you please :
> 
> get pmtools from Intel site:
> http://developer.intel.com/technology/iapc/acpi/downloads.htm
> 
> Then under pmtools-20010730:
> make
> cd acpidmp
> Could you then send me output of:
> ./acpidmp FACP | ./acpitbl
> and
> ./acpidmp FACS | ./acpitbl
> 
> I check for those values:
> For ./acpidmp FACP | ./acpitbl
> S4BIOS_REQ is not 0;

My result:
	S4BIOS_REQ:       0x00

> For ./acpidmp FACS | ./acpitbl:
> Flags have bit 0 set.

Signature:              FACS
Length:                 64
Hardware Signature:     0x00000000
Firmware Waking Vector: 0x00000000
Global Lock:            0x00000000
Flags:                  0x00000000

Hmm ... and now?
What does that mean?

> I supposed that the latest check would be sufficient?

No idea.
Maybe I should start to read the ACPI spec I downloaded some time ago :)

> Ducrot Bruno
CU
  nils faerber

-- 
kernel concepts          Tel: +49-271-771091-12
Dreisbachstr. 24         Fax: +49-271-771091-19
D-57250 Netphen          D1 : +49-170-2729106
--


-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility 
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/

^ permalink raw reply

* [BK][PATCH] ReiserFS CPU and memory bandwidth efficient large writes
From: Hans Reiser @ 2002-12-13 18:56 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: reiserfs_file_write() for 2.5.51 --]
[-- Type: message/rfc822, Size: 66294 bytes --]

From: Oleg Drokin <green@namesys.com>
To: reiser@namesys.com
Subject: reiserfs_file_write() for 2.5.51
Date: Fri, 13 Dec 2002 20:04:50 +0300
Message-ID: <20021213200450.A8885@namesys.com>

Hello!

    These three changesets implement reiserfs_file_write. Also third one
    exports generic_osync_inode,block_commit_write and remove_suid
    because these are now needed for reiserfs.
    There was no reiserfs_file_write in the 2.4 port of reiserfs
    (and Hans was very unhappy about it).
    With current 'one block at a time' algorithm, writes past the end of a file
    are slow because each new file block is separately added into the tree
    causing shifting of other items which is CPU expensive.
    With this new implementation if you write into file with big enough chunks,
    it uses half as much CPU. Also this version is more SMP friendly than
    the current one.

    You can pull these from bk://thebsh.namesys.com/bk/reiser3-linux-2.5-own-filewrite

ChangeSet@1.847, 2002-12-07 16:56:59+03:00, green@angband.namesys.com
  export generic_osync_inode,block_commit_write, remove_suid

ChangeSet@1.846, 2002-12-07 16:55:03+03:00, green@angband.namesys.com
  reiserfs_file_write() implemenation. Ported from 2.4

ChangeSet@1.845, 2002-12-07 13:38:05+03:00, green@angband.namesys.com
  reiserfs: Implement insertion of more than one unformatted pointer insertion at a time. This considerably speedups hole creation.

Diffstat:
 fs/reiserfs/bitmap.c           |   21
 fs/reiserfs/do_balan.c         |  105 ++--
 fs/reiserfs/file.c             | 1071 ++++++++++++++++++++++++++++++++++++++++-
 fs/reiserfs/inode.c            |   52 +
 fs/reiserfs/super.c            |    1
 fs/reiserfs/tail_conversion.c  |    5
 include/linux/reiserfs_fs.h    |    1
 include/linux/reiserfs_fs_sb.h |    1
 kernel/ksyms.c                 |    3
 9 files changed, 1193 insertions(+), 67 deletions(-)

Plain text patch:
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.844   -> 1.847  
#	  fs/reiserfs/file.c	1.18    -> 1.19   
#	      kernel/ksyms.c	1.169   -> 1.170  
#	fs/reiserfs/do_balan.c	1.15    -> 1.16   
#	 fs/reiserfs/inode.c	1.68    -> 1.70   
#	 fs/reiserfs/super.c	1.54    -> 1.55   
#	include/linux/reiserfs_fs_sb.h	1.20    -> 1.21   
#	fs/reiserfs/bitmap.c	1.24    -> 1.25   
#	include/linux/reiserfs_fs.h	1.45    -> 1.46   
#	fs/reiserfs/tail_conversion.c	1.23    -> 1.24   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/12/07	green@angband.namesys.com	1.845
# reiserfs: Implement insertion of more than one unformatted pointer insertion at a time. This considerably speedups hole creation.
# --------------------------------------------
# 02/12/07	green@angband.namesys.com	1.846
# reiserfs_file_write() implemenation. Ported from 2.4
# --------------------------------------------
# 02/12/07	green@angband.namesys.com	1.847
# export generic_osync_inode,block_commit_write, remove_suid
# --------------------------------------------
#
diff -Nru a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
--- a/fs/reiserfs/bitmap.c	Sat Dec  7 16:58:48 2002
+++ b/fs/reiserfs/bitmap.c	Sat Dec  7 16:58:48 2002
@@ -9,6 +9,7 @@
 #include <linux/errno.h>
 #include <linux/buffer_head.h>
 #include <linux/kernel.h>
+#include <linux/pagemap.h>
 #include <linux/reiserfs_fs_sb.h>
 #include <linux/reiserfs_fs_i.h>
 
@@ -733,7 +734,7 @@
     int rest = amount_needed;
     int nr_allocated;
   
-    while (rest > 0) {
+    while (rest > 0 && start <= finish) {
 	nr_allocated = scan_bitmap (hint->th, &start, finish, 1,
 				    rest + prealloc_size, !hint->formatted_node,
 				    hint->block);
@@ -879,7 +880,9 @@
     if ( !blocks )
 	return;
 
+    spin_lock(&REISERFS_SB(sb)->bitmap_lock);
     REISERFS_SB(sb)->reserved_blocks += blocks;
+    spin_unlock(&REISERFS_SB(sb)->bitmap_lock);
 }
 
 /* Unreserve @blocks amount of blocks in fs pointed by @sb */
@@ -896,6 +899,22 @@
     if ( !blocks )
 	return;
 
+    spin_lock(&REISERFS_SB(sb)->bitmap_lock);
     REISERFS_SB(sb)->reserved_blocks -= blocks;
+    spin_unlock(&REISERFS_SB(sb)->bitmap_lock);
     RFALSE( REISERFS_SB(sb)->reserved_blocks < 0, "amount of blocks reserved became zero?");
+}
+
+/* This function estimates how much pages we will be able to write to FS
+   used for reiserfs_file_write() purposes for now. */
+int reiserfs_can_fit_pages ( struct super_block *sb /* superblock of filesystem
+						       to estimate space */ )
+{
+	unsigned long space;
+
+	spin_lock(&REISERFS_SB(sb)->bitmap_lock);
+	space = (SB_FREE_BLOCKS(sb) - REISERFS_SB(sb)->reserved_blocks) / ( PAGE_CACHE_SIZE/sb->s_blocksize);
+	spin_unlock(&REISERFS_SB(sb)->bitmap_lock);
+
+	return space;
 }
diff -Nru a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c
--- a/fs/reiserfs/do_balan.c	Sat Dec  7 16:58:48 2002
+++ b/fs/reiserfs/do_balan.c	Sat Dec  7 16:58:48 2002
@@ -319,8 +319,6 @@
 		    int new_item_len;
 		    int version;
 
-		    RFALSE (!is_direct_le_ih (ih),
-			    "PAP-12075: only direct inserted item can be broken. %h", ih);
 		    ret_val = leaf_shift_left (tb, tb->lnum[0]-1, -1);
 
 		    /* Calculate item length to insert to S[0] */
@@ -343,7 +341,7 @@
 		    version = ih_version (ih);
 
 		    /* Calculate key component, item length and body to insert into S[0] */
-                    set_le_ih_k_offset( ih, le_ih_k_offset( ih ) + tb->lbytes );
+                    set_le_ih_k_offset( ih, le_ih_k_offset( ih ) + tb->lbytes * (is_indirect_le_ih(ih)?tb->tb_sb->s_blocksize/UNFM_P_SIZE:1) );
 
 		    put_ih_item_len( ih, new_item_len );
 		    if ( tb->lbytes >  zeros_num ) {
@@ -452,23 +450,28 @@
 				ih_item_len( B_N_PITEM_HEAD(tb->L[0],n+item_pos-ret_val)),
 				l_n,body, zeros_num > l_n ? l_n : zeros_num
 				);
-
-			    RFALSE( l_n && 
-				    is_indirect_le_ih(B_N_PITEM_HEAD
-						      (tb->L[0],
-						       n + item_pos - ret_val)),
-				    "PAP-12110: pasting more than 1 unformatted node pointer into indirect item");
-
 			    /* 0-th item in S0 can be only of DIRECT type when l_n != 0*/
 			    {
-			      int version;
-
-			      version = ih_version (B_N_PITEM_HEAD (tbS0, 0));
-			      set_le_key_k_offset (version, B_N_PKEY (tbS0, 0), 
-						   le_key_k_offset (version, B_N_PKEY (tbS0, 0)) + l_n);
-			      version = ih_version (B_N_PITEM_HEAD(tb->CFL[0],tb->lkey[0]));
-			      set_le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0]),
-						   le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0])) + l_n);
+				int version;
+				int temp_l = l_n;
+				
+				RFALSE (ih_item_len (B_N_PITEM_HEAD (tbS0, 0)),
+					"PAP-12106: item length must be 0");
+				RFALSE (comp_short_le_keys (B_N_PKEY (tbS0, 0),
+							    B_N_PKEY (tb->L[0],
+									    n + item_pos - ret_val)),
+					"PAP-12107: items must be of the same file");
+				if (is_indirect_le_ih(B_N_PITEM_HEAD (tb->L[0],
+								      n + item_pos - ret_val)))	{
+				    temp_l = (l_n / UNFM_P_SIZE) * tb->tb_sb->s_blocksize;
+				}
+				/* update key of first item in S0 */
+				version = ih_version (B_N_PITEM_HEAD (tbS0, 0));
+				set_le_key_k_offset (version, B_N_PKEY (tbS0, 0), 
+						     le_key_k_offset (version, B_N_PKEY (tbS0, 0)) + temp_l);
+				/* update left delimiting key */
+				set_le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0]),
+						     le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0])) + temp_l);
 			    }
 
 			    /* Calculate new body, position in item and insert_size[0] */
@@ -537,7 +540,7 @@
 			    );
 		    /* if appended item is indirect item, put unformatted node into un list */
 		    if (is_indirect_le_ih (pasted))
-			set_ih_free_space (pasted, ((struct unfm_nodeinfo*)body)->unfm_freespace);
+			set_ih_free_space (pasted, 0);
 		    tb->insert_size[0] = 0;
 		    zeros_num = 0;
 		}
@@ -565,15 +568,11 @@
 	    { /* new item or its part falls to R[0] */
 		if ( item_pos == n - tb->rnum[0] + 1 && tb->rbytes != -1 )
 		{ /* part of new item falls into R[0] */
-		    int old_key_comp, old_len, r_zeros_number;
+		    loff_t old_key_comp, old_len, r_zeros_number;
 		    const char * r_body;
 		    int version;
 		    loff_t offset;
 
-		    RFALSE( !is_direct_le_ih (ih),
-			    "PAP-12135: only direct item can be split. (%h)", 
-			    ih);
-
 		    leaf_shift_right(tb,tb->rnum[0]-1,-1);
 
 		    version = ih_version(ih);
@@ -582,7 +581,7 @@
 		    old_len = ih_item_len(ih);
 
 		    /* Calculate key component and item length to insert into R[0] */
-                    offset = le_ih_k_offset( ih ) + (old_len - tb->rbytes );
+                    offset = le_ih_k_offset( ih ) + (old_len - tb->rbytes )*(is_indirect_le_ih(ih)?tb->tb_sb->s_blocksize/UNFM_P_SIZE:1);
                     set_le_ih_k_offset( ih, offset );
 		    put_ih_item_len( ih, tb->rbytes);
 		    /* Insert part of the item into R[0] */
@@ -590,13 +589,13 @@
 		    bi.bi_bh = tb->R[0];
 		    bi.bi_parent = tb->FR[0];
 		    bi.bi_position = get_right_neighbor_position (tb, 0);
-		    if ( offset - old_key_comp > zeros_num ) {
+		    if ( (old_len - tb->rbytes) > zeros_num ) {
 			r_zeros_number = 0;
-			r_body = body + offset - old_key_comp - zeros_num;
+			r_body = body + (old_len - tb->rbytes) - zeros_num;
 		    }
 		    else {
 			r_body = body;
-			r_zeros_number = zeros_num - (offset - old_key_comp);
+			r_zeros_number = zeros_num - (old_len - tb->rbytes);
 			zeros_num -= r_zeros_number;
 		    }
 
@@ -707,12 +706,17 @@
 			
 			{
 			  int version;
+			  unsigned long temp_rem = n_rem;
 			  
 			  version = ih_version (B_N_PITEM_HEAD (tb->R[0],0));
+			  if (is_indirect_le_key(version,B_N_PKEY(tb->R[0],0))){
+			      temp_rem = (n_rem / UNFM_P_SIZE) * 
+			                 tb->tb_sb->s_blocksize;
+			  }
 			  set_le_key_k_offset (version, B_N_PKEY(tb->R[0],0), 
-					       le_key_k_offset (version, B_N_PKEY(tb->R[0],0)) + n_rem);
+					       le_key_k_offset (version, B_N_PKEY(tb->R[0],0)) + temp_rem);
 			  set_le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0]), 
-					       le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) + n_rem);
+					       le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) + temp_rem);
 			}
 /*		  k_offset (B_N_PKEY(tb->R[0],0)) += n_rem;
 		  k_offset (B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) += n_rem;*/
@@ -736,13 +740,12 @@
 			leaf_paste_in_buffer(&bi, 0, n_shift, tb->insert_size[0] - n_rem, r_body, r_zeros_number);
 
 			if (is_indirect_le_ih (B_N_PITEM_HEAD(tb->R[0],0))) {
-
+#if 0
 			    RFALSE( n_rem,
 				    "PAP-12160: paste more than one unformatted node pointer");
-
-			    set_ih_free_space (B_N_PITEM_HEAD(tb->R[0],0), ((struct unfm_nodeinfo*)body)->unfm_freespace);
+#endif
+			    set_ih_free_space (B_N_PITEM_HEAD(tb->R[0],0), 0);
 			}
-
 			tb->insert_size[0] = n_rem;
 			if ( ! n_rem )
 			    pos_in_item ++;
@@ -781,7 +784,7 @@
 		    }
 
 		    if (is_indirect_le_ih (pasted))
-			set_ih_free_space (pasted, ((struct unfm_nodeinfo*)body)->unfm_freespace);
+			set_ih_free_space (pasted, 0);
 		    zeros_num = tb->insert_size[0] = 0;
 		}
 	    }
@@ -858,12 +861,6 @@
 		    const char * r_body;
 		    int version;
 
-		    RFALSE( !is_direct_le_ih(ih),
-			/* The items which can be inserted are:
-			   Stat_data item, direct item, indirect item and directory item which consist of only two entries "." and "..".
-			   These items must not be broken except for a direct one. */
-			    "PAP-12205: non-direct item can not be broken when inserting");
-
 		    /* Move snum[i]-1 items from S[0] to S_new[i] */
 		    leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i] - 1, -1, S_new[i]);
 		    /* Remember key component and item length */
@@ -873,7 +870,7 @@
 
 		    /* Calculate key component and item length to insert into S_new[i] */
                     set_le_ih_k_offset( ih,
-                                le_ih_k_offset(ih) + (old_len - sbytes[i] ) );
+                                le_ih_k_offset(ih) + (old_len - sbytes[i] )*(is_indirect_le_ih(ih)?tb->tb_sb->s_blocksize/UNFM_P_SIZE:1) );
 
 		    put_ih_item_len( ih, sbytes[i] );
 
@@ -883,13 +880,13 @@
 		    bi.bi_parent = 0;
 		    bi.bi_position = 0;
 
-		    if ( le_ih_k_offset (ih) - old_key_comp > zeros_num ) {
+		    if ( (old_len - sbytes[i]) > zeros_num ) {
 			r_zeros_number = 0;
-			r_body = body + (le_ih_k_offset(ih) - old_key_comp) - zeros_num;
+			r_body = body + (old_len - sbytes[i]) - zeros_num;
 		    }
 		    else {
 			r_body = body;
-			r_zeros_number = zeros_num - (le_ih_k_offset (ih) - old_key_comp);
+			r_zeros_number = zeros_num - (old_len - sbytes[i]);
 			zeros_num -= r_zeros_number;
 		    }
 
@@ -1010,11 +1007,14 @@
 
 			    tmp = B_N_PITEM_HEAD(S_new[i],0);
 			    if (is_indirect_le_ih (tmp)) {
-				if (n_rem)
-				    reiserfs_panic (tb->tb_sb, "PAP-12230: balance_leaf: invalid action with indirect item");
-				set_ih_free_space (tmp, ((struct unfm_nodeinfo*)body)->unfm_freespace);
+				set_ih_free_space (tmp, 0);
+				set_le_ih_k_offset( tmp, le_ih_k_offset(tmp) + 
+					            (n_rem / UNFM_P_SIZE) *
+						    tb->tb_sb->s_blocksize);
+			    } else {
+				set_le_ih_k_offset( tmp, le_ih_k_offset(tmp) + 
+				                    n_rem );
 			    }
-                            set_le_ih_k_offset( tmp, le_ih_k_offset(tmp) + n_rem );
 			}
 
 			tb->insert_size[0] = n_rem;
@@ -1060,7 +1060,7 @@
 
 		    /* if we paste to indirect item update ih_free_space */
 		    if (is_indirect_le_ih (pasted))
-			set_ih_free_space (pasted, ((struct unfm_nodeinfo*)body)->unfm_freespace);
+			set_ih_free_space (pasted, 0);
 		    zeros_num = tb->insert_size[0] = 0;
 		}
 	    }
@@ -1152,11 +1152,12 @@
 		    leaf_paste_in_buffer (&bi, item_pos, pos_in_item, tb->insert_size[0], body, zeros_num);
 
 		    if (is_indirect_le_ih (pasted)) {
-
+#if 0
 			RFALSE( tb->insert_size[0] != UNFM_P_SIZE,
 				"PAP-12280: insert_size for indirect item must be %d, not %d",
 				UNFM_P_SIZE, tb->insert_size[0]);
-			set_ih_free_space (pasted, ((struct unfm_nodeinfo*)body)->unfm_freespace);
+#endif
+			set_ih_free_space (pasted, 0);
 		    }
 		    tb->insert_size[0] = 0;
 		}
diff -Nru a/fs/reiserfs/file.c b/fs/reiserfs/file.c
--- a/fs/reiserfs/file.c	Sat Dec  7 16:58:48 2002
+++ b/fs/reiserfs/file.c	Sat Dec  7 16:58:48 2002
@@ -6,6 +6,8 @@
 #include <linux/time.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/smp_lock.h>
+#include <asm/uaccess.h>
+#include <linux/pagemap.h>
 
 /*
 ** We pack the tails of files on file close, not at the time they are written.
@@ -140,9 +142,1076 @@
     return error ;
 }
 
+/* this function from inode.c would be used here, too */
+extern void restart_transaction(struct reiserfs_transaction_handle *th,
+                                struct inode *inode, struct path *path);
+
+/* I really do not want to play with memory shortage right now, so
+   to simplify the code, we are not going to write more than this much pages at
+   a time. This still should considerably improve performance compared to 4k
+   at a time case. */
+#define REISERFS_WRITE_PAGES_AT_A_TIME 32
+
+/* Allocates blocks for a file to fulfil write request.
+   Maps all unmapped but prepared pages from the list.
+   Updates metadata with newly allocated blocknumbers as needed */
+int reiserfs_allocate_blocks_for_region(
+				struct inode *inode, /* Inode we work with */
+				loff_t pos, /* Writing position */
+				int num_pages, /* number of pages write going
+						  to touch */
+				int write_bytes, /* amount of bytes to write */
+				struct page **prepared_pages, /* array of
+							         prepared pages
+							       */
+				int blocks_to_allocate /* Amount of blocks we
+							  need to allocate to
+							  fit the data into file
+							 */
+				)
+{
+    struct cpu_key key; // cpu key of item that we are going to deal with
+    struct item_head *ih; // pointer to item head that we are going to deal with
+    struct buffer_head *bh; // Buffer head that contains items that we are going to deal with
+    struct reiserfs_transaction_handle th; // transaction handle for transaction we are going to create.
+    __u32 * item; // pointer to item we are going to deal with
+    INITIALIZE_PATH(path); // path to item, that we are going to deal with.
+    b_blocknr_t allocated_blocks[blocks_to_allocate]; // Pointer to a place where allocated blocknumbers would be stored. Right now statically allocated, later that will change.
+    reiserfs_blocknr_hint_t hint; // hint structure for block allocator.
+    size_t res; // return value of various functions that we call.
+    int curr_block; // current block used to keep track of unmapped blocks.
+    int i; // loop counter
+    int itempos; // position in item
+    unsigned int from = (pos & (PAGE_CACHE_SIZE - 1)); // writing position in
+						       // first page
+    unsigned int to = ((pos + write_bytes - 1) & (PAGE_CACHE_SIZE - 1)) + 1; /* last modified byte offset in last page */
+    __u64 hole_size ; // amount of blocks for a file hole, if it needed to be created.
+    int modifying_this_item = 0; // Flag for items traversal code to keep track
+				 // of the fact that we already prepared
+				 // current block for journal
+
+
+    RFALSE(!blocks_to_allocate, "green-9004: tried to allocate zero blocks?");
+
+    /* First we compose a key to point at the writing position, we want to do
+       that outside of any locking region. */
+    make_cpu_key (&key, inode, pos+1, TYPE_ANY, 3/*key length*/);
+
+    /* If we came here, it means we absolutely need to open a transaction,
+       since we need to allocate some blocks */
+    reiserfs_write_lock(inode->i_sb); // Journaling stuff and we need that.
+    journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1); // Wish I know if this number enough
+    reiserfs_update_inode_transaction(inode) ;
+
+    /* Look for the in-tree position of our write, need path for block allocator */
+    res = search_for_position_by_key(inode->i_sb, &key, &path);
+    if ( res == IO_ERROR ) {
+	res = -EIO;
+	goto error_exit;
+    }
+   
+    /* Allocate blocks */
+    /* First fill in "hint" structure for block allocator */
+    hint.th = &th; // transaction handle.
+    hint.path = &path; // Path, so that block allocator can determine packing locality or whatever it needs to determine.
+    hint.inode = inode; // Inode is needed by block allocator too.
+    hint.search_start = 0; // We have no hint on where to search free blocks for block allocator.
+    hint.key = key.on_disk_key; // on disk key of file.
+    hint.block = inode->i_blocks/(inode->i_sb->s_blocksize/512); // Number of disk blocks this file occupies already.
+    hint.formatted_node = 0; // We are allocating blocks for unformatted node.
+    hint.preallocate = 0; // We do not do any preallocation for now.
+
+    /* Call block allocator to allocate blocks */
+    res = reiserfs_allocate_blocknrs(&hint, allocated_blocks, blocks_to_allocate, blocks_to_allocate);
+    if ( res != CARRY_ON ) {
+	if ( res == NO_DISK_SPACE ) {
+	    /* We flush the transaction in case of no space. This way some
+	       blocks might become free */
+	    SB_JOURNAL(inode->i_sb)->j_must_wait = 1;
+	    restart_transaction(&th, inode, &path);
+
+	    /* We might have scheduled, so search again */
+	    res = search_for_position_by_key(inode->i_sb, &key, &path);
+	    if ( res == IO_ERROR ) {
+		res = -EIO;
+		goto error_exit;
+	    }
+
+	    /* update changed info for hint structure. */
+	    res = reiserfs_allocate_blocknrs(&hint, allocated_blocks, blocks_to_allocate, blocks_to_allocate);
+	    if ( res != CARRY_ON ) {
+		res = -ENOSPC; 
+		pathrelse(&path);
+		goto error_exit;
+	    }
+	} else {
+	    res = -ENOSPC;
+	    pathrelse(&path);
+	    goto error_exit;
+	}
+    }
+
+#ifdef __BIG_ENDIAN
+        // Too bad, I have not found any way to convert a given region from
+        // cpu format to little endian format
+    {
+        int i;
+        for ( i = 0; i < blocks_to_allocate ; i++)
+            allocated_blocks[i]=cpu_to_le32(allocated_blocks[i]);
+    }
+#endif
+
+    /* Blocks allocating well might have scheduled and tree might have changed,
+       let's search the tree again */
+    /* find where in the tree our write should go */
+    res = search_for_position_by_key(inode->i_sb, &key, &path);
+    if ( res == IO_ERROR ) {
+	res = -EIO;
+	goto error_exit_free_blocks;
+    }
+
+    bh = get_last_bh( &path ); // Get a bufferhead for last element in path.
+    ih = get_ih( &path );      // Get a pointer to last item head in path.
+    item = get_item( &path );  // Get a pointer to last item in path
+
+    /* Let's see what we have found */
+    if ( res != POSITION_FOUND ) { /* position not found, this means that we
+				      might need to append file with holes
+				      first */
+	// Since we are writing past the file's end, we need to find out if
+	// there is a hole that needs to be inserted before our writing
+	// position, and how many blocks it is going to cover (we need to
+	//  populate pointers to file blocks representing the hole with zeros)
+
+	hole_size = (pos + 1 - (le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key))+op_bytes_number(ih, inode->i_sb->s_blocksize))) >> inode->i_sb->s_blocksize_bits;
+
+	if ( hole_size > 0 ) {
+	    int to_paste = min_t(__u64, hole_size, MAX_ITEM_LEN(inode->i_sb->s_blocksize)/UNFM_P_SIZE ); // How much data to insert first time.
+	    /* area filled with zeroes, to supply as list of zero blocknumbers
+	       We allocate it outside of loop just in case loop would spin for
+	       several iterations. */
+	    char *zeros = kmalloc(to_paste*UNFM_P_SIZE, GFP_ATOMIC); // We cannot insert more than MAX_ITEM_LEN bytes anyway.
+	    if ( !zeros ) {
+		res = -ENOMEM;
+		goto error_exit_free_blocks;
+	    }
+	    memset ( zeros, 0, to_paste*UNFM_P_SIZE);
+	    do {
+		to_paste = min_t(__u64, hole_size, MAX_ITEM_LEN(inode->i_sb->s_blocksize)/UNFM_P_SIZE );
+		if ( is_indirect_le_ih(ih) ) {
+		    /* Ok, there is existing indirect item already. Need to append it */
+		    /* Calculate position past inserted item */
+		    make_cpu_key( &key, inode, le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key)) + op_bytes_number(ih, inode->i_sb->s_blocksize), TYPE_INDIRECT, 3);
+		    res = reiserfs_paste_into_item( &th, &path, &key, (char *)zeros, UNFM_P_SIZE*to_paste);
+		    if ( res ) {
+			kfree(zeros);
+			goto error_exit_free_blocks;
+		    }
+		} else if ( is_statdata_le_ih(ih) ) {
+		    /* No existing item, create it */
+		    /* item head for new item */
+		    struct item_head ins_ih;
+
+		    /* create a key for our new item */
+		    make_cpu_key( &key, inode, 1, TYPE_INDIRECT, 3);
+
+		    /* Create new item head for our new item */
+		    make_le_item_head (&ins_ih, &key, key.version, 1,
+				       TYPE_INDIRECT, to_paste*UNFM_P_SIZE,
+				       0 /* free space */);
+
+		    /* Find where such item should live in the tree */
+		    res = search_item (inode->i_sb, &key, &path);
+		    if ( res != ITEM_NOT_FOUND ) {
+			/* item should not exist, otherwise we have error */
+			if ( res != -ENOSPC ) {
+			    reiserfs_warning ("green-9008: search_by_key (%K) returned %d\n",
+					       &key, res);
+			}
+			res = -EIO;
+		        kfree(zeros);
+			goto error_exit_free_blocks;
+		    }
+		    res = reiserfs_insert_item( &th, &path, &key, &ins_ih, (char *)zeros);
+		} else {
+		    reiserfs_panic(inode->i_sb, "green-9011: Unexpected key type %K\n", &key);
+		}
+		if ( res ) {
+		    kfree(zeros);
+		    goto error_exit_free_blocks;
+		}
+		/* Now we want to check if transaction is too full, and if it is
+		   we restart it. This will also free the path. */
+		if (journal_transaction_should_end(&th, th.t_blocks_allocated))
+		    restart_transaction(&th, inode, &path);
+
+		/* Well, need to recalculate path and stuff */
+		set_cpu_key_k_offset( &key, cpu_key_k_offset(&key) + to_paste * inode->i_sb->s_blocksize );
+		res = search_for_position_by_key(inode->i_sb, &key, &path);
+		if ( res == IO_ERROR ) {
+		    res = -EIO;
+		    kfree(zeros);
+		    goto error_exit_free_blocks;
+		}
+		bh=get_last_bh(&path);
+		ih=get_ih(&path);
+		item = get_item(&path);
+		hole_size -= to_paste;
+	    } while ( hole_size );
+	    kfree(zeros);
+	}
+    }
+
+    // Go through existing indirect items first
+    // replace all zeroes with blocknumbers from list
+    // Note that if no corresponding item was found, by previous search,
+    // it means there are no existing in-tree representation for file area
+    // we are going to overwrite, so there is nothing to scan through for holes.
+    for ( curr_block = 0, itempos = path.pos_in_item ; curr_block < blocks_to_allocate && res == POSITION_FOUND ; ) {
+
+	if ( itempos >= ih_item_len(ih)/UNFM_P_SIZE ) {
+	    /* We run out of data in this indirect item, let's look for another
+	       one. */
+	    /* First if we are already modifying current item, log it */
+	    if ( modifying_this_item ) {
+		journal_mark_dirty (&th, inode->i_sb, bh);
+		modifying_this_item = 0;
+	    }
+	    /* Then set the key to look for a new indirect item (offset of old
+	       item is added to old item length */
+	    set_cpu_key_k_offset( &key, le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key)) + op_bytes_number(ih, inode->i_sb->s_blocksize));
+	    /* Search ofor position of new key in the tree. */
+	    res = search_for_position_by_key(inode->i_sb, &key, &path);
+	    if ( res == IO_ERROR) {
+		res = -EIO;
+		goto error_exit_free_blocks;
+	    }
+	    bh=get_last_bh(&path);
+	    ih=get_ih(&path);
+	    item = get_item(&path);
+	    itempos = path.pos_in_item;
+	    continue; // loop to check all kinds of conditions and so on.
+	}
+	/* Ok, we have correct position in item now, so let's see if it is
+	   representing file hole (blocknumber is zero) and fill it if needed */
+	if ( !item[itempos] ) {
+	    /* Ok, a hole. Now we need to check if we already prepared this
+	       block to be journaled */
+	    while ( !modifying_this_item ) { // loop until succeed
+		/* Well, this item is not journaled yet, so we must prepare
+		   it for journal first, before we can change it */
+		struct item_head tmp_ih; // We copy item head of found item,
+					 // here to detect if fs changed under
+					 // us while we were preparing for
+					 // journal.
+		int fs_gen; // We store fs generation here to find if someone
+			    // changes fs under our feet
+
+		copy_item_head (&tmp_ih, ih); // Remember itemhead
+		fs_gen = get_generation (inode->i_sb); // remember fs generation
+		reiserfs_prepare_for_journal(inode->i_sb, bh, 1); // Prepare a buffer within which indirect item is stored for changing.
+		if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
+		    // Sigh, fs was changed under us, we need to look for new
+		    // location of item we are working with
+
+		    /* unmark prepaerd area as journaled and search for it's
+		       new position */
+		    reiserfs_restore_prepared_buffer(inode->i_sb, bh);
+		    res = search_for_position_by_key(inode->i_sb, &key, &path);
+		    if ( res == IO_ERROR) {
+			res = -EIO;
+			goto error_exit_free_blocks;
+		    }
+		    bh=get_last_bh(&path);
+		    ih=get_ih(&path);
+		    item = get_item(&path);
+		    // Itempos is still the same
+		    continue;
+		}
+		modifying_this_item = 1;
+	    }
+	    item[itempos] = allocated_blocks[curr_block]; // Assign new block
+	    curr_block++;
+	}
+	itempos++;
+    }
+
+    if ( modifying_this_item ) { // We need to log last-accessed block, if it
+				 // was modified, but not logged yet.
+	journal_mark_dirty (&th, inode->i_sb, bh);
+    }
+
+    if ( curr_block < blocks_to_allocate ) {
+	// Oh, well need to append to indirect item, or to create indirect item
+	// if there weren't any
+	if ( is_indirect_le_ih(ih) ) {
+	    // Existing indirect item - append. First calculate key for append
+	    // position. We do not need to recalculate path as it should
+	    // already point to correct place.
+	    make_cpu_key( &key, inode, le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key)) + op_bytes_number(ih, inode->i_sb->s_blocksize), TYPE_INDIRECT, 3);
+	    res = reiserfs_paste_into_item( &th, &path, &key, (char *)(allocated_blocks+curr_block), UNFM_P_SIZE*(blocks_to_allocate-curr_block));
+	    if ( res ) {
+		goto error_exit_free_blocks;
+	    }
+	} else if (is_statdata_le_ih(ih) ) {
+	    // Last found item was statdata. That means we need to create indirect item.
+	    struct item_head ins_ih; /* itemhead for new item */
+
+	    /* create a key for our new item */
+	    make_cpu_key( &key, inode, 1, TYPE_INDIRECT, 3); // Position one,
+							    // because that's
+							    // where first
+							    // indirect item
+							    // begins
+	    /* Create new item head for our new item */
+	    make_le_item_head (&ins_ih, &key, key.version, 1, TYPE_INDIRECT,
+			       (blocks_to_allocate-curr_block)*UNFM_P_SIZE,
+			       0 /* free space */);
+	    /* Find where such item should live in the tree */
+	    res = search_item (inode->i_sb, &key, &path);
+	    if ( res != ITEM_NOT_FOUND ) {
+		/* Well, if we have found such item already, or some error
+		   occured, we need to warn user and return error */
+		if ( res != -ENOSPC ) {
+		    reiserfs_warning ("green-9009: search_by_key (%K) returned %d\n",
+			              &key, res);
+		}
+		res = -EIO;
+		goto error_exit_free_blocks;
+	    }
+	    /* Insert item into the tree with the data as its body */
+	    res = reiserfs_insert_item( &th, &path, &key, &ins_ih, (char *)(allocated_blocks+curr_block));
+	} else {
+	    reiserfs_panic(inode->i_sb, "green-9010: unexpected item type for key %K\n",&key);
+	}
+    }
+
+    /* Now the final thing, if we have grew the file, we must update it's size*/
+    if ( pos + write_bytes > inode->i_size) {
+	inode->i_size = pos + write_bytes; // Set new size
+    }
+
+    /* Amount of on-disk blocks used by file have changed, update it */
+    inode->i_blocks += blocks_to_allocate * (inode->i_sb->s_blocksize / 512);
+    reiserfs_update_sd(&th, inode); // And update on-disk metadata
+    // finish all journal stuff now, We are not going to play with metadata
+    // anymore.
+    pathrelse(&path);
+    journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1);
+    reiserfs_write_unlock(inode->i_sb);
+
+    // go through all the pages/buffers and map the buffers to newly allocated
+    // blocks (so that system knows where to write these pages later).
+    curr_block = 0;
+    for ( i = 0; i < num_pages ; i++ ) {
+	struct page *page=prepared_pages[i]; //current page
+	struct buffer_head *head = page_buffers(page);// first buffer for a page
+	int block_start, block_end; // in-page offsets for buffers.
+
+	if (!page_buffers(page))
+	    reiserfs_panic(inode->i_sb, "green-9005: No buffers for prepared page???");
+
+	/* For each buffer in page */
+	for(bh = head, block_start = 0; bh != head || !block_start;
+	    block_start=block_end, bh = bh->b_this_page) {
+	    if (!bh)
+		reiserfs_panic(inode->i_sb, "green-9006: Allocated but absent buffer for a page?");
+	    block_end = block_start+inode->i_sb->s_blocksize;
+	    if (i == 0 && block_end <= from )
+		/* if this buffer is before requested data to map, skip it */
+		continue;
+	    if (i == num_pages - 1 && block_start >= to)
+		/* If this buffer is after requested data to map, abort
+		   processing of current page */
+		break;
+
+	    if ( !buffer_mapped(bh) ) { // Ok, unmapped buffer, need to map it
+		map_bh( bh, inode->i_sb, le32_to_cpu(allocated_blocks[curr_block]));
+		curr_block++;
+	    }
+	}
+    }
+
+    RFALSE( curr_block > blocks_to_allocate, "green-9007: Used too many blocks? weird");
+
+    return 0;
+
+// Need to deal with transaction here.
+error_exit_free_blocks:
+    pathrelse(&path);
+    // free blocks
+    for( i = 0; i < blocks_to_allocate; i++ )
+	reiserfs_free_block( &th, le32_to_cpu(allocated_blocks[i]));
+
+error_exit:
+    journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1);
+    reiserfs_write_unlock(inode->i_sb);
+
+    return res;
+}
+
+/* Unlock pages prepared by reiserfs_prepare_file_region_for_write */
+void reiserfs_unprepare_pages(struct page **prepared_pages, /* list of locked pages */
+			      int num_pages /* amount of pages */) {
+    int i; // loop counter
+
+    for (i=0; i < num_pages ; i++) {
+	struct page *page = prepared_pages[i];
+
+	try_to_free_buffers(page);
+	kunmap(page);
+	unlock_page(page);
+	page_cache_release(page);
+    }
+}
+
+/* This function will copy data from userspace to specified pages within
+   supplied byte range */
+int reiserfs_copy_from_user_to_file_region(
+				loff_t pos, /* In-file position */
+				int num_pages, /* Number of pages affected */
+				int write_bytes, /* Amount of bytes to write */
+				struct page **prepared_pages, /* pointer to 
+								 array to
+								 prepared pages
+								*/
+				const char *buf /* Pointer to user-supplied
+						   data*/
+				)
+{
+    long page_fault=0; // status of copy_from_user.
+    int i; // loop counter.
+    int offset; // offset in page
+
+    for ( i = 0, offset = (pos & (PAGE_CACHE_SIZE-1)); i < num_pages ; i++,offset=0) {
+	int count = min_t(int,PAGE_CACHE_SIZE-offset,write_bytes); // How much of bytes to write to this page
+	struct page *page=prepared_pages[i]; // Current page we process.
+
+	/* Bring in the user page. We need to do it to fight some deadlocks
+	   with copying the page to itself and page being inaccessible at
+	   the same time.*/
+	{ volatile unsigned char dummy;
+	    __get_user(dummy, buf);
+	    __get_user(dummy, buf+count-1);
+	    /* We do getuser for beginning and ending of the region just because
+	       userdata may be not page aligned, and therefore data that will
+	       go into one page of file may be splitted onto two actual pages
+	       in userspace */
+	}
+
+	/* Copy data from userspace to the current page */
+	kmap(page);
+	page_fault = __copy_from_user(page_address(page)+offset, buf, count); // Copy the data.
+	/* Flush processor's dcache for this page */
+	flush_dcache_page(page);
+	kunmap(page);
+	buf+=count;
+	write_bytes-=count;
+
+	if (page_fault)
+	    break; // Was there a fault? abort.
+    }
+
+    return page_fault?-EFAULT:0;
+}
+
+
+
+/* Submit pages for write. This was separated from actual file copying
+   because we might want to allocate block numbers in-between.
+   This function assumes that caller will adjust file size to correct value. */
+int reiserfs_submit_file_region_for_write(
+				loff_t pos, /* Writing position offset */
+				int num_pages, /* Number of pages to write */
+				int write_bytes, /* number of bytes to write */
+				struct page **prepared_pages /* list of pages */
+				)
+{
+    int status; // return status of block_commit_write.
+    int retval = 0; // Return value we are going to return.
+    int i; // loop counter
+    int offset; // Writing offset in page.
+
+    for ( i = 0, offset = (pos & (PAGE_CACHE_SIZE-1)); i < num_pages ; i++,offset=0) {
+	int count = min_t(int,PAGE_CACHE_SIZE-offset,write_bytes); // How much of bytes to write to this page
+	struct page *page=prepared_pages[i]; // Current page we process.
+
+	status = block_commit_write(page, offset, offset+count);
+	if ( status )
+	    retval = status; // To not overcomplicate matters We are going to
+			     // submit all the pages even if there was error.
+			     // we only remember error status to report it on
+			     // exit.
+	write_bytes-=count;
+	SetPageReferenced(page);
+	unlock_page(page); // We unlock the page as it was locked by earlier call
+			  // to grab_cache_page
+	page_cache_release(page);
+    }
+    return retval;
+}
+
+/* Look if passed writing region is going to touch file's tail
+   (if it is present). And if it is, convert the tail to unformatted node */
+int reiserfs_check_for_tail_and_convert( struct inode *inode, /* inode to deal with */
+					 loff_t pos, /* Writing position */
+					 int write_bytes /* amount of bytes to write */
+				        )
+{
+    INITIALIZE_PATH(path); // needed for search_for_position
+    struct cpu_key key; // Key that would represent last touched writing byte.
+    struct item_head *ih; // item header of found block;
+    int res; // Return value of various functions we call.
+    int cont_expand_offset; // We will put offset for generic_cont_expand here
+			    // This can be int just because tails are created
+			    // only for small files.
+ 
+/* this embodies a dependency on a particular tail policy */
+    if ( inode->i_size >= inode->i_sb->s_blocksize*4 ) {
+	/* such a big files do not have tails, so we won't bother ourselves
+	   to look for tails, simply return */
+	return 0;
+    }
+
+    reiserfs_write_lock(inode->i_sb);
+    /* find the item containing the last byte to be written, or if
+     * writing past the end of the file then the last item of the
+     * file (and then we check its type). */
+    make_cpu_key (&key, inode, pos+write_bytes+1, TYPE_ANY, 3/*key length*/);
+    res = search_for_position_by_key(inode->i_sb, &key, &path);
+    if ( res == IO_ERROR ) {
+        reiserfs_write_unlock(inode->i_sb);
+	return -EIO;
+    }
+    ih = get_ih(&path);
+    res = 0;
+    if ( is_direct_le_ih(ih) ) {
+	/* Ok, closest item is file tail (tails are stored in "direct"
+	 * items), so we need to unpack it. */
+	/* To not overcomplicate matters, we just call generic_cont_expand
+	   which will in turn call other stuff and finally will boil down to
+	    reiserfs_get_block() that would do necessary conversion. */
+	cont_expand_offset = le_key_k_offset(get_inode_item_key_version(inode), &(ih->ih_key));
+	pathrelse(&path);
+	res = generic_cont_expand( inode, cont_expand_offset);
+    } else
+	pathrelse(&path);
+
+    reiserfs_write_unlock(inode->i_sb);
+    return res;
+}
+
+/* This function locks pages starting from @pos for @inode.
+   @num_pages pages are locked and stored in
+   @prepared_pages array. Also buffers are allocated for these pages.
+   First and last page of the region is read if it is overwritten only
+   partially. If last page did not exist before write (file hole or file
+   append), it is zeroed, then. 
+   Returns number of unallocated blocks that should be allocated to cover
+   new file data.*/
+int reiserfs_prepare_file_region_for_write(
+				struct inode *inode /* Inode of the file */,
+				loff_t pos, /* position in the file */
+				int num_pages, /* number of pages to
+					          prepare */
+				int write_bytes, /* Amount of bytes to be
+						    overwritten from
+						    @pos */
+				struct page **prepared_pages /* pointer to array
+							       where to store
+							       prepared pages */
+					   )
+{
+    int res=0; // Return values of different functions we call.
+    unsigned long index = pos >> PAGE_CACHE_SHIFT; // Offset in file in pages.
+    int from = (pos & (PAGE_CACHE_SIZE - 1)); // Writing offset in first page
+    int to = ((pos + write_bytes - 1) & (PAGE_CACHE_SIZE - 1)) + 1;
+					 /* offset of last modified byte in last
+				            page */
+    struct address_space *mapping = inode->i_mapping; // Pages are mapped here.
+    int i; // Simple counter
+    int blocks = 0; /* Return value (blocks that should be allocated) */
+    struct buffer_head *bh, *head; // Current bufferhead and first bufferhead
+				   // of a page.
+    unsigned block_start, block_end; // Starting and ending offsets of current
+				     // buffer in the page.
+    struct buffer_head *wait[2], **wait_bh=wait; // Buffers for page, if
+						 // Page appeared to be not up
+						 // to date. Note how we have
+						 // at most 2 buffers, this is
+						 // because we at most may
+						 // partially overwrite two
+						 // buffers for one page. One at                                                 // the beginning of write area
+						 // and one at the end.
+						 // Everything inthe middle gets                                                 // overwritten totally.
+
+    struct cpu_key key; // cpu key of item that we are going to deal with
+    struct item_head *ih = NULL; // pointer to item head that we are going to deal with
+    struct buffer_head *itembuf=NULL; // Buffer head that contains items that we are going to deal with
+    INITIALIZE_PATH(path); // path to item, that we are going to deal with.
+    __u32 * item=0; // pointer to item we are going to deal with
+
+
+    if ( num_pages < 1 ) {
+	reiserfs_warning("green-9001: reiserfs_prepare_file_region_for_write called with zero number of pages to process\n");
+	return -EFAULT;
+    }
+
+    /* We have 2 loops for pages. In first loop we grab and lock the pages, so
+       that nobody would touch these until we release the pages. Then
+       we'd start to deal with mapping buffers to blocks. */
+    for ( i = 0; i < num_pages; i++) {
+	prepared_pages[i] = grab_cache_page(mapping, index + i); // locks the page
+	if ( !prepared_pages[i]) {
+	    res = -ENOMEM;
+	    goto failed_page_grabbing;
+	}
+	if (!page_has_buffers(prepared_pages[i]))
+	    create_empty_buffers(prepared_pages[i], inode->i_sb->s_blocksize, 0);
+    }
+
+    /* Let's count amount of blocks for a case where all the blocks
+       overwritten are new (we will substract already allocated blocks later)*/
+    if ( num_pages > 2 )
+	/* These are full-overwritten pages so we count all the blocks in
+	   these pages are counted as needed to be allocated */
+	blocks = (PAGE_CACHE_SIZE/inode->i_sb->s_blocksize) * (num_pages - 2);
+
+    /* count blocks needed for first page (possibly partially written) */
+    blocks += ((PAGE_CACHE_SIZE - from) >> inode->i_sb->s_blocksize_bits) +
+	   !!(from & (inode->i_sb->s_blocksize-1)); /* roundup */
+
+    /* Now we account for last page. If last page == first page (we
+       overwrite only one page), we substract all the blocks past the
+       last writing position in a page out of already calculated number
+       of blocks */
+    blocks += (PAGE_CACHE_SIZE/inode->i_sb->s_blocksize) * (num_pages > 1) -
+	   ((PAGE_CACHE_SIZE - to) >> inode->i_sb->s_blocksize_bits);
+	   /* Note how we do not roundup here since partial blocks still
+		   should be allocated */
+
+    /* Now if all the write area lies past the file end, no point in
+       maping blocks, since there is none, so we just zero out remaining
+       parts of first and last pages in write area (if needed) */
+    if ( (pos & ~(PAGE_CACHE_SIZE - 1)) > inode->i_size ) {
+	if ( from != 0 ) {/* First page needs to be partially zeroed */
+	    char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0);
+	    memset(kaddr, 0, from);
+	    kunmap_atomic( kaddr, KM_USER0);
+	    SetPageUptodate(prepared_pages[0]);
+	}
+	if ( to != PAGE_CACHE_SIZE ) { /* Last page needs to be partially zeroed */
+	    char *kaddr = kmap_atomic(prepared_pages[num_pages-1], KM_USER0);
+	    memset(kaddr+to, 0, PAGE_CACHE_SIZE - to);
+	    kunmap_atomic( kaddr, KM_USER0);
+	    SetPageUptodate(prepared_pages[num_pages-1]);
+	}
+
+	/* Since all blocks are new - use already calculated value */
+	return blocks;
+    }
+
+    /* Well, since we write somewhere into the middle of a file, there is
+       possibility we are writing over some already allocated blocks, so
+       let's map these blocks and substract number of such blocks out of blocks
+       we need to allocate (calculated above) */
+    /* Mask write position to start on blocksize, we do it out of the
+       loop for performance reasons */
+    pos &= ~(inode->i_sb->s_blocksize - 1);
+    /* Set cpu key to the starting position in a file (on left block boundary)*/
+    make_cpu_key (&key, inode, 1 + ((pos) & ~(inode->i_sb->s_blocksize - 1)), TYPE_ANY, 3/*key length*/);
+
+    reiserfs_write_lock(inode->i_sb); // We need that for at least search_by_key()
+    for ( i = 0; i < num_pages ; i++ ) { 
+	int item_pos=-1; /* Position in indirect item */
+
+	head = page_buffers(prepared_pages[i]);
+	/* For each buffer in the page */
+	for(bh = head, block_start = 0; bh != head || !block_start;
+	    block_start=block_end, bh = bh->b_this_page) {
+		if (!bh)
+		    reiserfs_panic(inode->i_sb, "green-9002: Allocated but absent buffer for a page?");
+		/* Find where this buffer ends */
+		block_end = block_start+inode->i_sb->s_blocksize;
+		if (i == 0 && block_end <= from )
+		    /* if this buffer is before requested data to map, skip it*/
+		    continue;
+
+		if (i == num_pages - 1 && block_start >= to) {
+		    /* If this buffer is after requested data to map, abort
+		       processing of current page */
+		    break;
+		}
+
+		if ( buffer_mapped(bh) && bh->b_blocknr !=0 ) {
+		    /* This is optimisation for a case where buffer is mapped
+		       and have blocknumber assigned. In case significant amount
+		       of such buffers are present, we may avoid some amount
+		       of search_by_key calls.
+		       Probably it would be possible to move parts of this code
+		       out of BKL, but I afraid that would overcomplicate code
+		       without any noticeable benefit.
+		    */
+		    item_pos++;
+		    /* Update the key */
+		    set_cpu_key_k_offset( &key, cpu_key_k_offset(&key) + inode->i_sb->s_blocksize);
+		    blocks--; // Decrease the amount of blocks that need to be
+			      // allocated
+		    continue; // Go to the next buffer
+		}
+
+		if ( !itembuf || /* if first iteration */
+		     item_pos >= ih_item_len(ih)/UNFM_P_SIZE)
+					     { /* or if we progressed past the
+						  current unformatted_item */
+			/* Try to find next item */
+			res = search_for_position_by_key(inode->i_sb, &key, &path);
+			/* Abort if no more items */
+			if ( res != POSITION_FOUND )
+			    break;
+
+			/* Update information about current indirect item */
+			itembuf = get_last_bh( &path );
+			ih = get_ih( &path );
+			item = get_item( &path );
+			item_pos = path.pos_in_item;
+
+			RFALSE( !is_indirect_le_ih (ih), "green-9003: indirect item expected");
+		}
+
+		/* See if there is some block associated with the file
+		   at that position, map the buffer to this block */
+		if ( get_block_num(item,item_pos) ) {
+		    map_bh(bh, inode->i_sb, get_block_num(item,item_pos));
+		    blocks--; // Decrease the amount of blocks that need to be
+			      // allocated
+		}
+		item_pos++;
+		/* Update the key */
+		set_cpu_key_k_offset( &key, cpu_key_k_offset(&key) + inode->i_sb->s_blocksize);
+	}
+    }
+    pathrelse(&path); // Free the path
+    reiserfs_write_unlock(inode->i_sb);
+
+	/* Now zero out unmappend buffers for the first and last pages of
+	   write area or issue read requests if page is mapped. */
+	/* First page, see if it is not uptodate */
+	if ( !PageUptodate(prepared_pages[0]) ) {
+	    head = page_buffers(prepared_pages[0]);
+
+	    /* For each buffer in page */
+	    for(bh = head, block_start = 0; bh != head || !block_start;
+		block_start=block_end, bh = bh->b_this_page) {
+
+		if (!bh)
+		    reiserfs_panic(inode->i_sb, "green-9002: Allocated but absent buffer for a page?");
+		/* Find where this buffer ends */
+		block_end = block_start+inode->i_sb->s_blocksize;
+		if ( block_end <= from )
+		    /* if this buffer is before requested data to map, skip it*/
+		    continue;
+		if ( block_start < from ) { /* Aha, our partial buffer */
+		    if ( buffer_mapped(bh) ) { /* If it is mapped, we need to
+						  issue READ request for it to
+						  not loose data */
+			ll_rw_block(READ, 1, &bh);
+			*wait_bh++=bh;
+		    } else { /* Not mapped, zero it */
+			char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0);
+			memset(kaddr+block_start, 0, from-block_start);
+			kunmap_atomic( kaddr, KM_USER0);
+			set_bit(BH_Uptodate, &bh->b_state);
+		    }
+		}
+	    }
+	}
+
+	/* Last page, see if it is not uptodate, or if the last page is past the end of the file. */
+	if ( !PageUptodate(prepared_pages[num_pages-1]) || 
+	    ((pos+write_bytes)>>PAGE_CACHE_SHIFT) > (inode->i_size>>PAGE_CACHE_SHIFT) ) {
+	    head = page_buffers(prepared_pages[num_pages-1]);
+
+	    /* for each buffer in page */
+	    for(bh = head, block_start = 0; bh != head || !block_start;
+		block_start=block_end, bh = bh->b_this_page) {
+
+		if (!bh)
+		    reiserfs_panic(inode->i_sb, "green-9002: Allocated but absent buffer for a page?");
+		/* Find where this buffer ends */
+		block_end = block_start+inode->i_sb->s_blocksize;
+		if ( block_start >= to )
+		    /* if this buffer is after requested data to map, skip it*/
+		    break;
+		if ( block_end > to ) { /* Aha, our partial buffer */
+		    if ( buffer_mapped(bh) ) { /* If it is mapped, we need to
+						  issue READ request for it to
+						  not loose data */
+			ll_rw_block(READ, 1, &bh);
+			*wait_bh++=bh;
+		    } else { /* Not mapped, zero it */
+			char *kaddr = kmap_atomic(prepared_pages[num_pages-1], KM_USER0);
+			memset(kaddr+to, 0, block_end-to);
+			kunmap_atomic( kaddr, KM_USER0);
+			set_bit(BH_Uptodate, &bh->b_state);
+		    }
+		}
+	    }
+	}
+
+    /* Wait for read requests we made to happen, if necessary */
+    while(wait_bh > wait) {
+	wait_on_buffer(*--wait_bh);
+	if (!buffer_uptodate(*wait_bh)) {
+	    res = -EIO;
+	    goto failed_read;
+	}
+    }
+
+    return blocks;
+failed_page_grabbing:
+    num_pages = i;
+failed_read:
+    reiserfs_unprepare_pages(prepared_pages, num_pages);
+    return res;
+}
+
+/* Write @count bytes at position @ppos in a file indicated by @file
+   from the buffer @buf.  
+
+   generic_file_write() is only appropriate for filesystems that are not seeking to optimize performance and want
+   something simple that works.  It is not for serious use by general purpose filesystems, excepting the one that it was
+   written for (ext2/3).  This is for several reasons:
+
+   * It has no understanding of any filesystem specific optimizations.
+
+   * It enters the filesystem repeatedly for each page that is written.
+
+   * It depends on reiserfs_get_block() function which if implemented by reiserfs performs costly search_by_key
+   * operation for each page it is supplied with. By contrast reiserfs_file_write() feeds as much as possible at a time
+   * to reiserfs which allows for fewer tree traversals.
+
+   * Each indirect pointer insertion takes a lot of cpu, because it involves memory moves inside of blocks.
+
+   * Asking the block allocation code for blocks one at a time is slightly less efficient.
+
+   All of these reasons for not using only generic file write were understood back when reiserfs was first miscoded to
+   use it, but we were in a hurry to make code freeze, and so it couldn't be revised then.  This new code should make
+   things right finally.
+
+   Future Features: providing search_by_key with hints.
+
+*/
+ssize_t reiserfs_file_write( struct file *file, /* the file we are going to write into */
+                             const char *buf, /*  pointer to user supplied data
+(in userspace) */
+                             size_t count, /* amount of bytes to write */
+                             loff_t *ppos /* pointer to position in file that we start writing at. Should be updated to
+                                           * new current position before returning. */ )
+{
+    size_t already_written = 0; // Number of bytes already written to the file.
+    loff_t pos; // Current position in the file.
+    size_t res; // return value of various functions that we call.
+    unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur; // Current filesize limit
+    struct inode *inode = file->f_dentry->d_inode; // Inode of the file that we are writing to.
+    struct page * prepared_pages[REISERFS_WRITE_PAGES_AT_A_TIME];
+				/* To simplify coding at this time, we store
+				   locked pages in array for now */
+    if ( count <= PAGE_CACHE_SIZE || file->f_flags & O_DIRECT)
+        return generic_file_write(file, buf, count, ppos);
+
+    if ( unlikely((ssize_t) count < 0 ))
+        return -EINVAL;
+
+    if (unlikely(!access_ok(VERIFY_READ, buf, count)))
+        return -EFAULT;
+
+    down(&inode->i_sem); // locks the entire file for just us
+
+    // We are going to duplicate a lot of generic_file_write checks here
+    // for now. I do not have any good idea on how to avoid these now.
+
+    res = -EINVAL;
+    if ( *ppos < 0)
+	goto out;
+
+    res = file->f_error;
+    if ( res ) {
+	file->f_error = 0;
+	goto out;
+    }
+
+    if (file->f_flags & O_APPEND)
+	pos=inode->i_size;
+    else
+	pos=*ppos;
+
+    res = -EFBIG;
+    if ( limit != RLIM_INFINITY) {
+	if (pos >= limit) {
+	    send_sig(SIGXFSZ, current, 0);
+	    goto out;
+	}
+	if ( pos > 0xFFFFFFFFULL || count > limit - (u32)pos) {
+	    count = limit - (u32)pos;
+	}
+    }
+
+    // LFS
+    if ( pos + count > MAX_NON_LFS && !(file->f_flags & O_LARGEFILE) ) {
+	if ( pos >= MAX_NON_LFS ) {
+	    send_sig(SIGXFSZ, current, 0);
+	    goto out;
+	}
+	if ( count > MAX_NON_LFS - (u32)pos ) {
+	    count = MAX_NON_LFS - (u32)pos;
+	}
+    }
+
+    // Check we are not going to exceed block limit
+    if ( pos >= inode->i_sb->s_maxbytes) {
+	if ( count || pos > inode->i_sb->s_maxbytes) {
+	    send_sig(SIGXFSZ, current, 0);
+	    goto out;
+	}
+	// zero length writes are ok.
+    }
+
+    res = 0;
+    if ( count == 0 )
+	goto out;
+
+    remove_suid(file->f_dentry);
+    inode_update_time(inode, 1); /* Both mtime and ctime */
+
+    // Ok, we are done with all the checks.
+
+    // Now we should start real work
+
+    /* If we are going to write past the file's packed tail or if we are going
+       to overwrite part of the tail, we need that tail to be converted into
+       unformatted node */
+    res = reiserfs_check_for_tail_and_convert( inode, pos, count);
+    if (res)
+	goto out;
+
+    while ( count > 0) {
+	/* This is the main loop in which we running until some error occures
+	   or until we write all of the data. */
+	int num_pages;/* amount of pages we are going to write this iteration */
+	int write_bytes; /* amount of bytes to write during this iteration */
+	int blocks_to_allocate; /* how much blocks we need to allocate for
+				   this iteration */
+        
+        /*  (pos & (PAGE_CACHE_SIZE-1)) is an idiom for offset into a page of pos*/
+	num_pages = !!((pos+count) & (PAGE_CACHE_SIZE - 1)) + /* round up partial
+							  pages */
+		    ((count + (pos & (PAGE_CACHE_SIZE-1))) >> PAGE_CACHE_SHIFT); 
+						/* convert size to amount of
+						   pages */
+	reiserfs_write_lock(inode->i_sb);
+	if ( num_pages > REISERFS_WRITE_PAGES_AT_A_TIME 
+		|| num_pages > reiserfs_can_fit_pages(inode->i_sb) ) {
+	    /* If we were asked to write more data than we want to or if there
+	       is not that much space, then we shorten amount of data to write
+	       for this iteration. */
+	    num_pages = min_t(int, REISERFS_WRITE_PAGES_AT_A_TIME, reiserfs_can_fit_pages(inode->i_sb));
+	    /* Also we should not forget to set size in bytes accordingly */
+	    write_bytes = num_pages * PAGE_CACHE_SIZE - 
+			    (pos & (PAGE_CACHE_SIZE-1));
+					 /* If position is not on the
+					    start of the page, we need
+					    to substract the offset
+					    within page */
+	} else
+	    write_bytes = count;
+
+	/* reserve the blocks to be allocated later, so that later on
+	   we still have the space to write the blocks to */
+	reiserfs_claim_blocks_to_be_allocated(inode->i_sb, num_pages * (PAGE_CACHE_SIZE/inode->i_sb->s_blocksize));
+	reiserfs_write_unlock(inode->i_sb);
+
+	if ( !num_pages ) { /* If we do not have enough space even for */
+	    res = -ENOSPC;  /* single page, return -ENOSPC */
+	    if ( pos > (inode->i_size & (inode->i_sb->s_blocksize-1)))
+		break; // In case we are writing past the file end, break.
+	    // Otherwise we are possibly overwriting the file, so
+	    // let's set write size to be equal or less than blocksize.
+	    // This way we get it correctly for file holes.
+	    // But overwriting files on absolutelly full volumes would not
+	    // be very efficient. Well, people are not supposed to fill
+	    // 100% of disk space anyway.
+	    write_bytes = min_t(int, count, inode->i_sb->s_blocksize - (pos & (inode->i_sb->s_blocksize - 1)));
+	    num_pages = 1;
+	}
+
+	/* Prepare for writing into the region, read in all the
+	   partially overwritten pages, if needed. And lock the pages,
+	   so that nobody else can access these until we are done.
+	   We get number of actual blocks needed as a result.*/
+	blocks_to_allocate = reiserfs_prepare_file_region_for_write(inode, pos, num_pages, write_bytes, prepared_pages);
+	if ( blocks_to_allocate < 0 ) {
+	    res = blocks_to_allocate;
+	    reiserfs_release_claimed_blocks(inode->i_sb, num_pages * (PAGE_CACHE_SIZE/inode->i_sb->s_blocksize));
+	    break;
+	}
+
+	/* First we correct our estimate of how many blocks we need */
+	reiserfs_release_claimed_blocks(inode->i_sb, num_pages * (PAGE_CACHE_SIZE>>inode->i_sb->s_blocksize_bits) - blocks_to_allocate );
+
+	if ( blocks_to_allocate > 0) {/*We only allocate blocks if we need to*/
+	    /* Fill in all the possible holes and append the file if needed */
+	    res = reiserfs_allocate_blocks_for_region(inode, pos, num_pages, write_bytes, prepared_pages, blocks_to_allocate);
+	} else if ( pos + write_bytes > inode->i_size ) {
+	    /* File might have grown even though no new blocks were added */
+	    inode->i_size = pos + write_bytes;
+	    inode->i_sb->s_op->dirty_inode(inode);
+	}
+
+	/* well, we have allocated the blocks, so it is time to free
+	   the reservation we made earlier. */
+	reiserfs_release_claimed_blocks(inode->i_sb, blocks_to_allocate);
+	if ( res ) {
+	    reiserfs_unprepare_pages(prepared_pages, num_pages);
+	    break;
+	}
+
+/* NOTE that allocating blocks and filling blocks can be done in reverse order
+   and probably we would do that just to get rid of garbage in files after a
+   crash */
+
+	/* Copy data from user-supplied buffer to file's pages */
+	res = reiserfs_copy_from_user_to_file_region(pos, num_pages, write_bytes, prepared_pages, buf);
+	if ( res ) {
+	    reiserfs_unprepare_pages(prepared_pages, num_pages);
+	    break;
+	}
+
+	/* Send the pages to disk and unlock them. */
+	res = reiserfs_submit_file_region_for_write(pos, num_pages, write_bytes, prepared_pages);
+	if ( res )
+	    break;
+
+	already_written += write_bytes;
+	buf += write_bytes;
+	*ppos = pos += write_bytes;
+	count -= write_bytes;
+    }
+
+    if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
+	res = generic_osync_inode(inode, OSYNC_METADATA|OSYNC_DATA);
+
+    up(&inode->i_sem);
+    return (already_written != 0)?already_written:res;
+
+out:
+    up(&inode->i_sem); // unlock the file on exit.
+    return res;
+}
+
 struct file_operations reiserfs_file_operations = {
     .read	= generic_file_read,
-    .write	= generic_file_write,
+    .write	= reiserfs_file_write,
     .ioctl	= reiserfs_ioctl,
     .mmap	= generic_file_mmap,
     .release	= reiserfs_file_release,
diff -Nru a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
--- a/fs/reiserfs/inode.c	Sat Dec  7 16:58:48 2002
+++ b/fs/reiserfs/inode.c	Sat Dec  7 16:58:48 2002
@@ -759,7 +759,11 @@
 	       pointer to 'block'-th block use block, which is already
 	       allocated */
 	    struct cpu_key tmp_key;
-	    struct unfm_nodeinfo un = {0, 0};
+	    unp_t unf_single=0; // We use this in case we need to allocate only
+				// one block which is a fastpath
+	    unp_t *un;
+	    __u64 max_to_insert=MAX_ITEM_LEN(inode->i_sb->s_blocksize)/UNFM_P_SIZE;
+	    __u64 blocks_needed;
 
 	    RFALSE( pos_in_item != ih_item_len(ih) / UNFM_P_SIZE,
 		    "vs-804: invalid position for append");
@@ -768,30 +772,58 @@
 			  le_key_k_offset (version, &(ih->ih_key)) + op_bytes_number (ih, inode->i_sb->s_blocksize),
 			  //pos_in_item * inode->i_sb->s_blocksize,
 			  TYPE_INDIRECT, 3);// key type is unimportant
-		  
-	    if (cpu_key_k_offset (&tmp_key) == cpu_key_k_offset (&key)) {
+
+	    blocks_needed = 1 + ((cpu_key_k_offset (&key) - cpu_key_k_offset (&tmp_key)) >> inode->i_sb->s_blocksize_bits);
+	    RFALSE( blocks_needed < 0, "green-805: invalid offset");
+
+	    if ( blocks_needed == 1 ) {
+		un = &unf_single;
+	    } else {
+		un=kmalloc( min(blocks_needed,max_to_insert)*UNFM_P_SIZE,
+			    GFP_ATOMIC); // We need to avoid scheduling.
+		if ( !un) {
+		    un = &unf_single;
+		    blocks_needed = 1;
+		    max_to_insert = 0;
+		} else
+		    memset(un, 0, UNFM_P_SIZE * min(blocks_needed,max_to_insert));
+	    }
+	    if ( blocks_needed <= max_to_insert) {
 		/* we are going to add target block to the file. Use allocated
 		   block for that */
-		un.unfm_nodenum = cpu_to_le32 (allocated_block_nr);
+		un[blocks_needed-1] = cpu_to_le32 (allocated_block_nr);
 		set_block_dev_mapped (bh_result, allocated_block_nr, inode);
 		set_buffer_new(bh_result);
 		done = 1;
 	    } else {
 		/* paste hole to the indirect item */
+		/* If kmalloc failed, max_to_insert becomes zero and it means we
+		   only have space for one block */
+		blocks_needed=max_to_insert?max_to_insert:1;
 	    }
-	    retval = reiserfs_paste_into_item (&th, &path, &tmp_key, (char *)&un, UNFM_P_SIZE);
+	    retval = reiserfs_paste_into_item (&th, &path, &tmp_key, (char *)un, UNFM_P_SIZE * blocks_needed);
+
+	    if (blocks_needed != 1)
+		kfree(un);
+
 	    if (retval) {
 		reiserfs_free_block (&th, allocated_block_nr);
 		goto failure;
 	    }
-	    if (un.unfm_nodenum)
+	    if (done) {
 		inode->i_blocks += inode->i_sb->s_blocksize / 512;
+	    } else {
+		/* We need to mark new file size in case this function will be
+		   interrupted/aborted later on. And we may do this only for
+		   holes. */
+		inode->i_size += inode->i_sb->s_blocksize * blocks_needed;
+	    }
 	    //mark_tail_converted (inode);
 	}
-		
+
 	if (done == 1)
 	    break;
-	 
+
 	/* this loop could log more blocks than we had originally asked
 	** for.  So, we have to allow the transaction to end if it is
 	** too big or too full.  Update the inode so things are 
@@ -863,7 +895,7 @@
 
 
     copy_key (INODE_PKEY (inode), &(ih->ih_key));
-    inode->i_blksize = PAGE_SIZE;
+    inode->i_blksize = PAGE_SIZE*32;
 
     INIT_LIST_HEAD(&(REISERFS_I(inode)->i_prealloc_list ));
     REISERFS_I(inode)->i_flags = 0;
@@ -1554,7 +1586,7 @@
     }
     // these do not go to on-disk stat data
     inode->i_ino = le32_to_cpu (ih.ih_key.k_objectid);
-    inode->i_blksize = PAGE_SIZE;
+    inode->i_blksize = PAGE_SIZE*32;
   
     // store in in-core inode the key of stat data and version all
     // object items will have (directory items will have old offset
diff -Nru a/fs/reiserfs/super.c b/fs/reiserfs/super.c
--- a/fs/reiserfs/super.c	Sat Dec  7 16:58:48 2002
+++ b/fs/reiserfs/super.c	Sat Dec  7 16:58:48 2002
@@ -1313,6 +1313,7 @@
     reiserfs_proc_register( s, "oidmap", reiserfs_oidmap_in_proc );
     reiserfs_proc_register( s, "journal", reiserfs_journal_in_proc );
     init_waitqueue_head (&(sbi->s_wait));
+    sbi->bitmap_lock = SPIN_LOCK_UNLOCKED;
 
     return (0);
 
diff -Nru a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c
--- a/fs/reiserfs/tail_conversion.c	Sat Dec  7 16:58:48 2002
+++ b/fs/reiserfs/tail_conversion.c	Sat Dec  7 16:58:48 2002
@@ -30,7 +30,7 @@
                                 key of unfm pointer to be pasted */
     int	n_blk_size,
       n_retval;	  /* returned value for reiserfs_insert_item and clones */
-    struct unfm_nodeinfo unfm_ptr;  /* Handle on an unformatted node
+    unp_t unfm_ptr;  /* Handle on an unformatted node
 				       that will be inserted in the
 				       tree. */
 
@@ -59,8 +59,7 @@
     
     p_le_ih = PATH_PITEM_HEAD (path);
 
-    unfm_ptr.unfm_nodenum = cpu_to_le32 (unbh->b_blocknr);
-    unfm_ptr.unfm_freespace = 0; // ???
+    unfm_ptr = cpu_to_le32 (unbh->b_blocknr);
     
     if ( is_statdata_le_ih (p_le_ih) )  {
 	/* Insert new indirect item. */
diff -Nru a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
--- a/include/linux/reiserfs_fs.h	Sat Dec  7 16:58:48 2002
+++ b/include/linux/reiserfs_fs.h	Sat Dec  7 16:58:48 2002
@@ -2110,6 +2110,7 @@
 #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);
+int reiserfs_can_fit_pages(struct super_block *sb);
 
 /* hashes.c */
 __u32 keyed_hash (const signed char *msg, int len);
diff -Nru a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
--- a/include/linux/reiserfs_fs_sb.h	Sat Dec  7 16:58:48 2002
+++ b/include/linux/reiserfs_fs_sb.h	Sat Dec  7 16:58:48 2002
@@ -397,6 +397,7 @@
     reiserfs_proc_info_data_t s_proc_info_data;
     struct proc_dir_entry *procdir;
     int reserved_blocks; /* amount of blocks reserved for further allocations */
+    spinlock_t bitmap_lock; /* this lock on now only used to protect reserved_blocks variable */
 };
 
 /* Definitions of reiserfs on-disk properties: */
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c	Sat Dec  7 16:58:48 2002
+++ b/kernel/ksyms.c	Sat Dec  7 16:58:48 2002
@@ -217,6 +217,7 @@
 EXPORT_SYMBOL(generic_cont_expand);
 EXPORT_SYMBOL(cont_prepare_write);
 EXPORT_SYMBOL(generic_commit_write);
+EXPORT_SYMBOL(block_commit_write);
 EXPORT_SYMBOL(block_truncate_page);
 EXPORT_SYMBOL(generic_block_bmap);
 EXPORT_SYMBOL(generic_file_read);
@@ -544,6 +545,8 @@
 EXPORT_SYMBOL(make_bad_inode);
 EXPORT_SYMBOL(is_bad_inode);
 EXPORT_SYMBOL(__inode_dir_notify);
+EXPORT_SYMBOL(generic_osync_inode);
+EXPORT_SYMBOL(remove_suid);
 
 #ifdef CONFIG_UID16
 EXPORT_SYMBOL(overflowuid);



^ permalink raw reply


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.