All of lore.kernel.org
 help / color / mirror / Atom feed
* USB troubles in 2.5 kernels
From: André Cruz @ 2002-12-17  0:59 UTC (permalink / raw)
  To: linux-kernel

Hello.

First of all if I do a make install in a 2.5 kernel without module support it still complains in the end about /lib/modules/2.5.52 not being a directory.
I have to mkdir it and then run make install.

The first problem is with kernel 2.5.50:
I think my CF/SM reader is detected at boot but when I issue a mount
/dev/sdc1 /mnt/ this appears and nothing happens after that:

SCSI device sdc: drive cache: write through
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Command READ_CAPACITY (10 bytes)
usb-storage: 25 20 00 00 00 00 00 00 00 00 23 c0
usb-storage: Bulk command S 0x43425355 T 0x44 Trg 0 LUN 1 L 8 F 128 CL
10
usb-storage: usb_stor_bulk_transfer_buf(): xfer 31 bytes
usb-storage: Status code 0; transferred 31/31
usb-storage: -- transfer complete
usb-storage: Bulk command transfer result=0
usb-storage: usb_stor_bulk_transfer_buf(): xfer 8 bytes
usb-storage: Status code 0; transferred 8/8
usb-storage: -- transfer complete
usb-storage: Bulk data transfer result 0x0
usb-storage: Attempting to get CSW...
usb-storage: usb_stor_bulk_transfer_buf(): xfer 13 bytes
usb-storage: Status code 0; transferred 13/13
usb-storage: -- transfer complete
usb-storage: Bulk status result = 0
usb-storage: Bulk status Sig 0x53425355 T 0x44 R 0 Stat 0x0
usb-storage: scsi cmd done, result=0x0
usb-storage: *** thread sleeping.
SCSI device sdc: 31361 512-byte hdwr sectors (16 MB)
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Command MODE_SENSE (6 bytes)
usb-storage: 1a 20 3f 00 04 00 00 00 00 ee 50 c0
usb-storage: Bulk command S 0x43425355 T 0x45 Trg 0 LUN 1 L 4 F 128 CL 6
usb-storage: usb_stor_bulk_transfer_buf(): xfer 31 bytes
usb-storage: Status code 0; transferred 31/31
usb-storage: -- transfer complete
usb-storage: Bulk command transfer result=0
usb-storage: usb_stor_bulk_transfer_buf(): xfer 4 bytes
drivers/usb/host/uhci-hcd.c: uhci_result_common() failed with status
500000
[ef324270] link (2f324212) element (2f325040)
  0: [ef325040] link (00000001) e3 IOC Stalled Babble Length=3 MaxLen=3
DT0 EndPt=2 Dev=3, PID=69(IN) (buf=0050ee00)

drivers/usb/core/hcd.c: giveback urb ef2c7660 status -75 len 4
usb-storage: Status code -75; transferred 4/4
usb-storage: -- unknown error
usb-storage: Bulk data transfer result 0x3
usb-storage: -- transport indicates error, resetting
usb-storage: Bulk reset requested
drivers/usb/core/message.c: usb_control/bulk_msg: timeout
usb 1-2: wait for giveback urb ee34a380
usb-storage: command_abort() called
usb-storage: usb_stor_abort_transport called




dmesg

usb-storage: act_altsetting is 0
usb-storage: id_index calculated to be: 94
usb-storage: Array length appears to be: 96
usb-storage: USB Mass Storage device detected
usb-storage: Endpoints: In: 0xef2c8e34 Out: 0xef2c8e20 Int: 0x00000000
(Period 0)
usb-storage: New GUID 0aec5010aec501000001a003
usb-storage: GetMaxLUN command result is 1, data is 1
usb-storage: Transport: Bulk
usb-storage: Protocol: Transparent SCSI
usb-storage: Allocating usb_ctrlrequest
usb-storage: Allocating URB
usb-storage: Allocating scatter-gather request block
usb-storage: *** thread sleeping.
scsi2 : SCSI emulation for USB Mass Storage devices
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Command INQUIRY (6 bytes)
usb-storage: 12 00 00 00 24 00 00 00 87 e4 23 c0
usb-storage: Bulk command S 0x43425355 T 0x11 Trg 0 LUN 0 L 36 F 128 CL
6
usb-storage: usb_stor_bulk_transfer_buf(): xfer 31 bytes
usb-storage: Status code 0; transferred 31/31
usb-storage: -- transfer complete
usb-storage: Bulk command transfer result=0
usb-storage: usb_stor_bulk_transfer_buf(): xfer 36 bytes
usb-storage: Status code 0; transferred 36/36
usb-storage: -- transfer complete
usb-storage: Bulk data transfer result 0x0
usb-storage: Attempting to get CSW...
usb-storage: usb_stor_bulk_transfer_buf(): xfer 13 bytes
usb-storage: Status code 0; transferred 13/13
usb-storage: -- transfer complete
usb-storage: Bulk status result = 0
usb-storage: Bulk status Sig 0x53425355 T 0x11 R 0 Stat 0x0
usb-storage: Fixing INQUIRY data to show SCSI rev 2 - was 0
usb-storage: scsi cmd done, result=0x0
usb-storage: *** thread sleeping.
  Vendor:           Model: USB Storage-SMC   Rev: 0212
  Type:   Direct-Access                      ANSI SCSI revision: 02
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Faking INQUIRY command for EVPD
usb-storage: scsi cmd done, result=0x2
usb-storage: *** thread sleeping.
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Faking INQUIRY command for EVPD
usb-storage: scsi cmd done, result=0x2
usb-storage: *** thread sleeping.
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Command INQUIRY (6 bytes)
usb-storage: 12 20 00 00 24 00 00 00 87 e4 23 c0
usb-storage: Bulk command S 0x43425355 T 0x14 Trg 0 LUN 1 L 36 F 128 CL
6
usb-storage: usb_stor_bulk_transfer_buf(): xfer 31 bytes
usb-storage: Status code 0; transferred 31/31
usb-storage: -- transfer complete
usb-storage: Bulk command transfer result=0
usb-storage: usb_stor_bulk_transfer_buf(): xfer 36 bytes
usb-storage: Status code 0; transferred 36/36
usb-storage: -- transfer complete
usb-storage: Bulk data transfer result 0x0
usb-storage: Attempting to get CSW...
usb-storage: usb_stor_bulk_transfer_buf(): xfer 13 bytes
usb-storage: Status code 0; transferred 13/13
usb-storage: -- transfer complete
usb-storage: Bulk status result = 0
usb-storage: Bulk status Sig 0x53425355 T 0x14 R 0 Stat 0x0
usb-storage: Fixing INQUIRY data to show SCSI rev 2 - was 0
usb-storage: scsi cmd done, result=0x0
usb-storage: *** thread sleeping.
  Vendor:           Model: USB Storage-CFC   Rev: 0212
  Type:   Direct-Access                      ANSI SCSI revision: 02
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Faking INQUIRY command for EVPD
usb-storage: scsi cmd done, result=0x2
usb-storage: *** thread sleeping.
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Faking INQUIRY command for EVPD
usb-storage: scsi cmd done, result=0x2
usb-storage: *** thread sleeping.
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Bad LUN (0/2)
usb-storage: scsi cmd done, result=0x40000
usb-storage: *** thread sleeping.
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Bad target number (1/0)
usb-storage: scsi cmd done, result=0x40000
usb-storage: *** thread sleeping.
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Bad target number (2/0)
usb-storage: scsi cmd done, result=0x40000
usb-storage: *** thread sleeping.
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Bad target number (3/0)
usb-storage: scsi cmd done, result=0x40000
usb-storage: *** thread sleeping.
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Bad target number (4/0)
usb-storage: scsi cmd done, result=0x40000
usb-storage: *** thread sleeping.
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Bad target number (5/0)
usb-storage: scsi cmd done, result=0x40000
usb-storage: *** thread sleeping.
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Bad target number (6/0)
usb-storage: scsi cmd done, result=0x40000
usb-storage: *** thread sleeping.
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Bad target number (7/0)
usb-storage: scsi cmd done, result=0x40000
usb-storage: *** thread sleeping.
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Command TEST_UNIT_READY (6 bytes)
usb-storage: 00 00 00 00 00 00 00 00 00 00 23 c0
usb-storage: Bulk command S 0x43425355 T 0x1f Trg 0 LUN 0 L 0 F 0 CL 6
usb-storage: usb_stor_bulk_transfer_buf(): xfer 31 bytes
usb-storage: Status code 0; transferred 31/31
usb-storage: -- transfer complete
usb-storage: Bulk command transfer result=0
usb-storage: Attempting to get CSW...
usb-storage: usb_stor_bulk_transfer_buf(): xfer 13 bytes
usb-storage: Status code 0; transferred 13/13
usb-storage: -- transfer complete
usb-storage: Bulk status result = 0
usb-storage: Bulk status Sig 0x53425355 T 0x1f R 0 Stat 0x1
usb-storage: -- transport indicates command failure
usb-storage: Issuing auto-REQUEST_SENSE
usb-storage: Bulk command S 0x43425355 T 0x1f Trg 0 LUN 0 L 18 F 128 CL
6
usb-storage: usb_stor_bulk_transfer_buf(): xfer 31 bytes
usb-storage: Status code 0; transferred 31/31
usb-storage: -- transfer complete
usb-storage: Bulk command transfer result=0
usb-storage: usb_stor_bulk_transfer_buf(): xfer 18 bytes
usb-storage: Status code 0; transferred 18/18
usb-storage: -- transfer complete
usb-storage: Bulk data transfer result 0x0
usb-storage: Attempting to get CSW...
usb-storage: usb_stor_bulk_transfer_buf(): xfer 13 bytes
usb-storage: Status code 0; transferred 13/13
usb-storage: -- transfer complete
usb-storage: Bulk status result = 0
usb-storage: Bulk status Sig 0x53425355 T 0x1f R 0 Stat 0x0
usb-storage: -- Result from auto-sense is 0
usb-storage: -- code: 0x70, key: 0x2, ASC: 0x3a, ASCQ: 0x0
usb-storage: Not Ready: Medium not present
usb-storage: scsi cmd done, result=0x2
usb-storage: *** thread sleeping.
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Command MODE_SENSE (6 bytes)
usb-storage: 1a 08 08 00 80 00 00 00 00 00 23 c0
usb-storage: Bulk command S 0x43425355 T 0x20 Trg 0 LUN 0 L 128 F 128 CL
6
usb-storage: usb_stor_bulk_transfer_buf(): xfer 31 bytes
usb-storage: Status code 0; transferred 31/31
usb-storage: -- transfer complete
usb-storage: Bulk command transfer result=0
usb-storage: usb_stor_bulk_transfer_buf(): xfer 128 bytes
usb-storage: Status code 0; transferred 8/128
usb-storage: -- transferred only 8 bytes
usb-storage: Bulk data transfer result 0x1
usb-storage: Attempting to get CSW...
usb-storage: usb_stor_bulk_transfer_buf(): xfer 13 bytes
usb-storage: Status code 0; transferred 13/13
usb-storage: -- transfer complete
usb-storage: Bulk status result = 0
usb-storage: Bulk status Sig 0x53425355 T 0x20 R 0 Stat 0x0
usb-storage: scsi cmd done, result=0x0
usb-storage: *** thread sleeping.
SCSI device sdb: drive cache: write through
Attached scsi removable disk sdb at scsi2, channel 0, id 0, lun 0
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Command TEST_UNIT_READY (6 bytes)
usb-storage: 00 20 00 00 00 00 00 00 00 00 23 c0
usb-storage: Bulk command S 0x43425355 T 0x21 Trg 0 LUN 1 L 0 F 0 CL 6
usb-storage: usb_stor_bulk_transfer_buf(): xfer 31 bytes
usb-storage: Status code 0; transferred 31/31
usb-storage: -- transfer complete
usb-storage: Bulk command transfer result=0
usb-storage: Attempting to get CSW...
usb-storage: usb_stor_bulk_transfer_buf(): xfer 13 bytes
usb-storage: Status code 0; transferred 13/13
usb-storage: -- transfer complete
usb-storage: Bulk status result = 0
usb-storage: Bulk status Sig 0x53425355 T 0x21 R 0 Stat 0x1
usb-storage: -- transport indicates command failure
usb-storage: Issuing auto-REQUEST_SENSE
usb-storage: Bulk command S 0x43425355 T 0x21 Trg 0 LUN 1 L 18 F 128 CL
6
usb-storage: usb_stor_bulk_transfer_buf(): xfer 31 bytes
usb-storage: Status code 0; transferred 31/31
usb-storage: -- transfer complete
usb-storage: Bulk command transfer result=0
usb-storage: usb_stor_bulk_transfer_buf(): xfer 18 bytes
usb-storage: Status code 0; transferred 18/18
usb-storage: -- transfer complete
usb-storage: Bulk data transfer result 0x0
usb-storage: Attempting to get CSW...
usb-storage: usb_stor_bulk_transfer_buf(): xfer 13 bytes
usb-storage: Status code 0; transferred 13/13
usb-storage: -- transfer complete
usb-storage: Bulk status result = 0
usb-storage: Bulk status Sig 0x53425355 T 0x21 R 0 Stat 0x0
usb-storage: -- Result from auto-sense is 0
usb-storage: -- code: 0x70, key: 0x2, ASC: 0x3a, ASCQ: 0x0
usb-storage: Not Ready: Medium not present
usb-storage: scsi cmd done, result=0x2
usb-storage: *** thread sleeping.
usb-storage: queuecommand() called
usb-storage: *** thread awakened.
usb-storage: Command MODE_SENSE (6 bytes)
usb-storage: 1a 28 08 00 80 00 00 00 00 00 23 c0
usb-storage: Bulk command S 0x43425355 T 0x22 Trg 0 LUN 1 L 128 F 128 CL
6
usb-storage: usb_stor_bulk_transfer_buf(): xfer 31 bytes
usb-storage: Status code 0; transferred 31/31
usb-storage: -- transfer complete
usb-storage: Bulk command transfer result=0
usb-storage: usb_stor_bulk_transfer_buf(): xfer 128 bytes
usb-storage: Status code 0; transferred 8/128
usb-storage: -- transferred only 8 bytes
usb-storage: Bulk data transfer result 0x1
usb-storage: Attempting to get CSW...
usb-storage: usb_stor_bulk_transfer_buf(): xfer 13 bytes
usb-storage: Status code 0; transferred 13/13
usb-storage: -- transfer complete
usb-storage: Bulk status result = 0
usb-storage: Bulk status Sig 0x53425355 T 0x22 R 0 Stat 0x0
usb-storage: scsi cmd done, result=0x0
usb-storage: *** thread sleeping.
SCSI device sdc: drive cache: write through
Attached scsi removable disk sdc at scsi2, channel 0, id 0, lun 1
WARNING: USB Mass Storage data integrity not assured
USB Mass Storage device found at 3



The second problem started with > 2.5.50
At boot this happens:

usb-storage: act_altsetting is 0
usb-storage: id_index calculated to be: 95
usb-storage: Array length appears to be: 97
usb-storage: USB Mass Storage device detected
usb-storage: Endpoints: In: 0xef283ef4 Out: 0xef283ee0 Int: 0x00000000
(Period 0)
usb-storage: New GUID 0aec5010aec501000001a003
Unable to handle kernel NULL pointer dereference at virtual address
00000002
 printing eip:
c02aaede
*pde = 00000000
Oops: 0000
CPU:    0
EIP:    0060:[<c02aaede>]    Not tainted
EFLAGS: 00010202
eax: 00000001   ebx: 00000020   ecx: ef283ee0   edx: 00000000
esi: 00000000   edi: ef283ef4   ebp: ef280600   esp: efc5bd4c
ds: 0068   es: 0068   ss: 0068
Process khubd (pid: 4, threadinfo=efc5a000 task=c17af240)
Stack: ef280600 00000000 00000174 0001a003 00000000 efb2aa00 ef288560
ef280604
       c174b968 c03d624c c0137541 c174b968 00000000 c174b9b8 00000000
00000246
       c03d624c 000001ff effe83d0 00000000 eeb09ea0 eeb09098 c01623d0
eeb09ea0
Call Trace: [<c0137541>]  [<c01623d0>]  [<c013a38e>]  [<c028ff07>] 
[<c0200c65>]  [<c0200cff>]  [<c0200ed4>]  [<c01fff70>]  [<c029119c>] 
[<c0293546>]  [<c02939be>]  [<c0122265>]  [<c0293a65>]  [<c011e4c0>] 
[<c0293a30>]  [<c0109249>]
Code: 0f b6 46 02 24 0f 88 85 9e 00 00 00 0f b6 46 06 8d 75 30 88


Can anyone help with any of these problems? Also a backport of this
driver to 2.4 would be very good. I can't use 2.5 for production yet.
Can anyone at least tell me which driver has to be backported?

Thanks!

-- 
André Cruz <afafc@rnl.ist.utl.pt>


^ permalink raw reply

* Re: Linux 2.2.24-rc1
From: Alan Cox @ 2002-12-17  1:33 UTC (permalink / raw)
  To: Pawel Kot; +Cc: Alan Cox, Linux Kernel Mailing List
In-Reply-To: <Pine.LNX.4.33.0212170113350.14563-100000@urtica.linuxnews.pl>

On Tue, 2002-12-17 at 00:15, Pawel Kot wrote:
>                 case X86_VENDOR_AMD:
> -                       init_amd(c);
> +                       if(init_amd(c))
> +                               return;
>                         return;
> 
>                 case X86_VENDOR_CENTAUR:
> What does it fix?

If we get a vendor string, we should use it - thats all


^ permalink raw reply

* Re: PROBLEM: kernel 2.4.20 option CONFIG_BLK_STATS breaks /proc/partitons so "mount" can't mount devices by UUID.
From: Andries Brouwer @ 2002-12-17  0:55 UTC (permalink / raw)
  To: jiri.wichern; +Cc: linux-kernel, marcelo
In-Reply-To: <3DFE6ED2.7174.1395ABF@localhost>

On Tue, Dec 17, 2002 at 12:24:50AM +0100, jiri.wichern@hccnet.nl wrote:

> Short description of the problem: You can't mount hard drive 
> volumes by using their UUID number when also using extra 
> statistics for your block devices by the CONFIG_BLK_STATS 
> kernel option.

Yes, we know.
You use an old version of mount, and the mount will always fail.

Two solutions:
(i) Do not use CONFIG_BLK_STATS.
(ii) Upgrade mount to a recent version (mount is part of util-linux,
recent is for example 2.11y).

Note that solution (ii) gives you a situation where mount and fdisk
fail sporadically instead of always, maybe not precisely what one
had hoped. Thus, (i) is the preferred solution.

It was really bad that CONFIG_BLK_STATS went into 2.4.20,
but you need not use it.

Andries


Two months ago I sent the below Doc patch. It is still needed.


--- Documentation/Configure.help~ Mon Oct 14 01:12:13 2002 
+++ Documentation/Configure.help Tue Oct 22 20:30:39 2002 
@@ -561,6 +561,8 @@ 
  
   This is required for the full functionality of sar(8) and interesting 
   if you want to do performance tuning, by tweaking the elevator, e.g. 
+  On the other hand, it will cause random and mysterious failures for 
+  fdisk, mount and other programs reading /proc/partitions. 
  
   If unsure, say N. 

(this is about CONFIG_BLK_STATS). 

^ permalink raw reply

* Re: [CryptoAPI-devel] [RFC] Hardware support notes for the kernel crypto API (2.5+)
From: Steve Isaacs @ 2002-12-17  0:56 UTC (permalink / raw)
  To: James Morris, linux-kernel; +Cc: David S. Miller, cryptoapi-devel
In-Reply-To: <Mutt.LNX.4.44.0212150025190.24712-100000@blackbird.intercode.com.au>

On Saturday 14 December 2002 05:51, James Morris wrote:
>  
>
> GPL Driver status:
>
>   HiFn 7751
>     James Morris (in progress).
>  
>   HiFn 7951
>     David Bryson (in progress).
>     Also see http://sourceforge.net/projects/hifn7951/
>  
>   HiFn 7901
>     See http://sources.colubris.com/en/projects/FreeSWAN/
>    
>   Motorola MPC190, MPC184
>     Steve (in progress).
>    

The driver for the MPC190 is now running with limited capability (although not 
very clean at the moment). Most of what I've done is workout the details of 
configuring the co-processor that are not described in the User's Manuala and 
builtind a basic framework to support mutiple coprocessors (of the same type) 
and callbacks. Motorola has been very helpful with this.

In case you're interrested here are some details (you can pick me apart if you 
want to -- I'm somewhat new to this so I could use some advice):

At this time only MD5 is supported but, now that I've got a better handle on 
the ideosyncrasies, implementing additional transforms should take less 
effort (and time). The driver is able to detect multiple mpc190s on the PCI 
bus and use them dynamically. 

Each mpc190 supports 9 execution "channels" (Motorola's term). The driver 
hides the fact that there are multiple channels or even multiple coprocessors 
and instead only exposes the various transforms (e.g. MD5, DES...). 

The driver internally allocates channels to satisfy cipher requests on an as 
need basis and does support callback from the bottom-half (interrupt tasklet) 
for asynchronous notification of completion of the task. 

To simplify management I implemented an abstract I call a "virtual channel" 
and maintain linked lists of "virtual channels" on idle and busy queues. 
Allocation of a channel is simply moving a channel from the idle queue to the 
busy queue. Deallocation is the reverse. 

Two of the attributes of a "virtual channel" are the base IO address of the 
processor and the offset of the channel to facilitate code that can work with 
any channel. 

Calling tasks are placed on sleep_interruptable queues (there is one for each 
"virtual channel") and are not awakened until after the callback has 
completed (if one was requested).

"Virtual channel" states are maintained internally to help track the progress 
of a channel and include IDLE, BUSY, PENDING, and CALLBACK. The IDLE and BUSY 
states are obvious. The PENDING state identifies a channel that has been 
queued for the bottom-half (interrupt tasklet) to process. The CALLBACK state 
indicates a channel that is awaiting a return from a call to a client 
callback function.

Thoughts for the future:

The MPC184 also uses the channel concept but provides fewer of them (4 versus 
9) and doesn't support all of transforms of the mpc190 (MD4 and HMAC-MD5 are 
missing). At the same time the mpc184 provides AES whereas the mpc190 does 
not. I've been struggling trying to figure out how to extend the "virtual 
channel" scheme to allow concurrent use of both an mpc190 and and mpc184 but 
not have to support both in the same driver (not something I want to do). The 
project which is the true motivation behind all of this has the possibility 
of having both on the bus at the same time.

Steve


^ permalink raw reply

* Re: mouse grabbing gotcha (was: dosemu 1.1.3.9 user report)
From: Bart Oldeman @ 2002-12-17  0:49 UTC (permalink / raw)
  To: linux-msdos
In-Reply-To: <3DFE7060.6030009@yahoo.com>

On Tue, 17 Dec 2002, Stas Sergeev wrote:

> Peter Jay Salzman wrote:
> > i guess enlightenment traps cntl-alt-home, because the key combo won't
> > let dosemu grab the mouse.
> > however, it DOES work with twm.
> Can you figure out a more reliable
> combination then?
> Set $_X_mgrab_key to, say, "Scroll_Lock"
> or "Pause" and if there is something
> that works everywhere, then I think the
> default "Home" should be changed.

Pause is already taken as being a force pause (freeze).
One problem is that you can define just about any keycombo in some of
these window managers, so there is nothing that works everywhere; however
some combinations are used more often than others.

ctrl+alt+scroll_lock might be something that makes sense though, since
you're locking the mouse. something to think about post-1.1.4 :)

For KDE I have ctrl+alt+esc (kill), ctrl+alt+del (logout).

Bart


^ permalink raw reply

* buggy scsi_register behaviour in 2.5.51
From: Willem Riede @ 2002-12-17  0:50 UTC (permalink / raw)
  To: linux-scsi

I was investigating why I get 

Dec 14 14:50:55 fallguy kernel: Badness in kobject_register at lib/kobject.c:113
Dec 14 14:50:55 fallguy kernel: Call Trace:
Dec 14 14:50:55 fallguy kernel:  [<c01c7c88>] kobject_register+0x58/0x70
Dec 14 14:50:55 fallguy kernel:  [<c01db442>] bus_add_driver+0x82/0xd0
Dec 14 14:50:55 fallguy kernel:  [<c022bd00>] ide_drive_remove+0x0/0x30
Dec 14 14:50:55 fallguy kernel:  [<c022bdec>] ide_register_driver+0xbc/0xf0
Dec 14 14:50:55 fallguy kernel:  [<c0133f6a>] sys_init_module+0x1ba/0x1d0
Dec 14 14:50:55 fallguy kernel:  [<c010b643>] syscall_call+0x7/0xb

when re-insmod-ing ide-scsi, and the "badness" is in sysfs create_dir, 
appearently because the ide-scsi directory is not removed when ide-scsi 
is unloaded so the create fails because it already exists.

But that's not the only thing going wrong when repeatedly (un)loading.
See below for some really horrible effects:

[root@fallguy linux-2.5.51]# insmod drivers/scsi/ide-scsi.ko
[root@fallguy linux-2.5.51]# cat /proc/scsi/scsi
Attached devices: 
Host: scsi0 Channel: 00 Id: 03 Lun: 00
  Vendor: OnStream Model: SC-30            Rev: 1.09
  Type:   Sequential-Access                ANSI SCSI revision: 02
Host: scsi0 Channel: 00 Id: 06 Lun: 00
  Vendor: MATSHITA Model: CD-R   CW-7502   Rev: 4.17
  Type:   CD-ROM                           ANSI SCSI revision: 02
Host: scsi1 Channel: 00 Id: 00 Lun: 00
  Vendor: IBM      Model: DNES-318350W     Rev: SA30
  Type:   Direct-Access                    ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 00
  Vendor: IBM      Model: DGHS09U          Rev: 0350
  Type:   Direct-Access                    ANSI SCSI revision: 03
Host: scsi3 Channel: 00 Id: 00 Lun: 00
  Vendor: CONNER   Model: CTT8000-A        Rev: 2.08
  Type:   Sequential-Access                ANSI SCSI revision: 02
Host: scsi3 Channel: 00 Id: 01 Lun: 00
  Vendor: OnStream Model: DI-30            Rev: 1.09
  Type:   Sequential-Access                ANSI SCSI revision: 02
Host: scsi3 Channel: 00 Id: 02 Lun: 00
  Vendor: OnStream Model: ADR Series       Rev: 5.05
  Type:   Sequential-Access                ANSI SCSI revision: 02
[root@fallguy linux-2.5.51]# ls -l /sysfs/bus/ide/drivers/ide-scsi
total 0
[root@fallguy linux-2.5.51]# ls -ld /sysfs/bus/ide/drivers/ide-scsi
drwxr-xr-x    2 root     root            0 Dec 15 15:54 /sysfs/bus/ide/drivers/ide-scsi
[root@fallguy linux-2.5.51]# rmmod ide_scsi
[root@fallguy linux-2.5.51]# ls -ld /sysfs/bus/ide/drivers/ide-scsi
drwxr-xr-x    2 root     root            0 Dec 15 15:54 /sysfs/bus/ide/drivers/ide-scsi

        ^^ the directory is still there ! ^^

[root@fallguy linux-2.5.51]# cat /proc/scsi/scsi
Attached devices: 
Host: scsi0 Channel: 00 Id: 03 Lun: 00
  Vendor: OnStream Model: SC-30            Rev: 1.09
  Type:   Sequential-Access                ANSI SCSI revision: 02
Host: scsi0 Channel: 00 Id: 06 Lun: 00
  Vendor: MATSHITA Model: CD-R   CW-7502   Rev: 4.17
  Type:   CD-ROM                           ANSI SCSI revision: 02
Host: scsi1 Channel: 00 Id: 00 Lun: 00
  Vendor: IBM      Model: DNES-318350W     Rev: SA30
  Type:   Direct-Access                    ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 00
  Vendor: IBM      Model: DGHS09U          Rev: 0350
  Type:   Direct-Access                    ANSI SCSI revision: 03
[root@fallguy linux-2.5.51]# insmod drivers/scsi/ide-scsi.ko
[root@fallguy linux-2.5.51]# ls -ld /sysfs/bus/ide/drivers/ide-scsi
drwxr-xr-x    2 root     root            0 Dec 15 15:54 /sysfs/bus/ide/drivers/ide-scsi
[root@fallguy linux-2.5.51]# cat /proc/scsi/scsi
Attached devices: 
Host: scsi0 Channel: 00 Id: 03 Lun: 00
  Vendor: OnStream Model: SC-30            Rev: 1.09
  Type:   Sequential-Access                ANSI SCSI revision: 02
Host: scsi0 Channel: 00 Id: 06 Lun: 00
  Vendor: MATSHITA Model: CD-R   CW-7502   Rev: 4.17
  Type:   CD-ROM                           ANSI SCSI revision: 02
Host: scsi1 Channel: 00 Id: 00 Lun: 00
  Vendor: IBM      Model: DNES-318350W     Rev: SA30
  Type:   Direct-Access                    ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 00
  Vendor: IBM      Model: DGHS09U          Rev: 0350
  Type:   Direct-Access                    ANSI SCSI revision: 03
Host: scsi3 Channel: 00 Id: 00 Lun: 00
  Vendor: OnStream Model: ADR Series       Rev: 5.05
  Type:   Sequential-Access                ANSI SCSI revision: 02
Host: scsi3 Channel: 00 Id: 01 Lun: 00
  Vendor: OnStream Model: DI-30            Rev: 1.09
  Type:   Sequential-Access                ANSI SCSI revision: 02
Host: scsi3 Channel: 00 Id: 02 Lun: 00
  Vendor: CONNER   Model: CTT8000-A        Rev: 2.08
  Type:   Sequential-Access                ANSI SCSI revision: 02
Host: scsi4 Channel: 00 Id: 00 Lun: 00
  Vendor: OnStream Model: ADR Series       Rev: 5.05
  Type:   Sequential-Access                ANSI SCSI revision: 02
Host: scsi4 Channel: 00 Id: 01 Lun: 00
  Vendor: OnStream Model: DI-30            Rev: 1.09
  Type:   Sequential-Access                ANSI SCSI revision: 02
Host: scsi4 Channel: 00 Id: 02 Lun: 00
  Vendor: CONNER   Model: CTT8000-A        Rev: 2.08
  Type:   Sequential-Access                ANSI SCSI revision: 02

ide-scsi has now been assigned both scsi3 and scsi4?? Its devices appear twice!

Clearly not correct. I'll work on fixing this, but first I have a question.

Reading the source (hosts.c), it appears that a host adapter will only get
the same number as it had before, if it has been specified in the module
parameter "scsihosts".

Is it a concious design decision to not try and re-assign the same number as
before if an adapter not in "scsihosts" gets (un)loaded repeatedly?

I think a fix for this would be different if I would try to reassign the
same number than if the intention is to keep assigning new numbers.

Thanks for your advise. Willem Riede.


^ permalink raw reply

* Re: Intel P6 vs P7 system call performance
From: Dave Jones @ 2002-12-17  1:03 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Ingo Molnar, linux-kernel
In-Reply-To: <Pine.LNX.4.44.0212161639310.1623-100000@penguin.transmeta.com>

On Mon, Dec 16, 2002 at 04:47:00PM -0800, Linus Torvalds wrote:

Cool, new toys 8-) I'll have a play with this tomorrow.
after a quick glance, one thing jumped out at me.

 > +static int __init sysenter_setup(void)
 > +{
 > +	if (!boot_cpu_has(X86_FEATURE_SEP))
 > +		return 0;
 > +
 > +	enable_sep_cpu(NULL);
 > +	smp_call_function(enable_sep_cpu, NULL, 1, 1);
 > +	return 0;

I'm sure I recall seeing errata on at least 1 CPU re sysenter.
If we do decide to go this route, we'll need to blacklist ones
with any really icky problems.

		Dave

-- 
| Dave Jones.        http://www.codemonkey.org.uk
| SuSE Labs

^ permalink raw reply

* Re: Linux 2.2.24-rc1
From: Dave Jones @ 2002-12-17  1:06 UTC (permalink / raw)
  To: Alan Cox; +Cc: Pawel Kot, Linux Kernel Mailing List
In-Reply-To: <1040088833.13837.115.camel@irongate.swansea.linux.org.uk>

On Tue, Dec 17, 2002 at 01:33:53AM +0000, Alan Cox wrote:
 > On Tue, 2002-12-17 at 00:15, Pawel Kot wrote:
 > >                 case X86_VENDOR_AMD:
 > > -                       init_amd(c);
 > > +                       if(init_amd(c))
 > > +                               return;
 > >                         return;
 > > 
 > >                 case X86_VENDOR_CENTAUR:
 > > What does it fix?
 > 
 > If we get a vendor string, we should use it - thats all

This patch also makes us unconditionally skip the mcheck_init
if we have a vendor string. That doesn't seem right.

		Dave

-- 
| Dave Jones.        http://www.codemonkey.org.uk
| SuSE Labs

^ permalink raw reply

* Re: USB troubles in 2.5 kernels
From: Greg KH @ 2002-12-17  1:12 UTC (permalink / raw)
  To: André Cruz; +Cc: linux-kernel
In-Reply-To: <1040086793.1083.4.camel@giga.netcabo.pt>

On Tue, Dec 17, 2002 at 12:59:54AM +0000, André Cruz wrote:
> 
> usb-storage: act_altsetting is 0
> usb-storage: id_index calculated to be: 95
> usb-storage: Array length appears to be: 97
> usb-storage: USB Mass Storage device detected
> usb-storage: Endpoints: In: 0xef283ef4 Out: 0xef283ee0 Int: 0x00000000
> (Period 0)
> usb-storage: New GUID 0aec5010aec501000001a003
> Unable to handle kernel NULL pointer dereference at virtual address
> 00000002
>  printing eip:
> c02aaede
> *pde = 00000000
> Oops: 0000
> CPU:    0
> EIP:    0060:[<c02aaede>]    Not tainted
> EFLAGS: 00010202
> eax: 00000001   ebx: 00000020   ecx: ef283ee0   edx: 00000000
> esi: 00000000   edi: ef283ef4   ebp: ef280600   esp: efc5bd4c
> ds: 0068   es: 0068   ss: 0068
> Process khubd (pid: 4, threadinfo=efc5a000 task=c17af240)
> Stack: ef280600 00000000 00000174 0001a003 00000000 efb2aa00 ef288560
> ef280604
>        c174b968 c03d624c c0137541 c174b968 00000000 c174b9b8 00000000
> 00000246
>        c03d624c 000001ff effe83d0 00000000 eeb09ea0 eeb09098 c01623d0
> eeb09ea0
> Call Trace: [<c0137541>]  [<c01623d0>]  [<c013a38e>]  [<c028ff07>] 
> [<c0200c65>]  [<c0200cff>]  [<c0200ed4>]  [<c01fff70>]  [<c029119c>] 
> [<c0293546>]  [<c02939be>]  [<c0122265>]  [<c0293a65>]  [<c011e4c0>] 
> [<c0293a30>]  [<c0109249>]
> Code: 0f b6 46 02 24 0f 88 85 9e 00 00 00 0f b6 46 06 8d 75 30 88
> 
> 
> Can anyone help with any of these problems?

Can you run that oops through ksymoops and send it to the
linux-usb-devel mailing list?

thanks,

greg k-h

^ permalink raw reply

* [Linux-ia64] Re: ia64 cache flushing?
From: Rusty Russell @ 2002-12-17  1:14 UTC (permalink / raw)
  To: linux-ia64
In-Reply-To: <marc-linux-ia64-105590709805582@msgid-missing>

In message <20021216162551.B13547@twiddle.net> you write:
> On Tue, Dec 17, 2002 at 10:22:11AM +1100, Rusty Russell wrote:
> > Could someone who is Attuned with the way of ia64 linking and asm
> > please look at this?  It's a userspace framework which tests the 2.5
> > module code (as modified by RTH to use shared objects rather than
> > simple object files).  You can see 9 architectures already done, but
> > ia64 doesn't work, for reasons beyond my humble abilities.
> 
> This has nothing to do with the icache.

Yes, subject line was stale, sorry for the miscue.

> The program crashes
> the first time it calls through the PLT, *not* on the first
> instruction it executes.
> 
> The PLT has been relocated incorrectly.  More in a moment...

Well, yes, something is wrong with the relocations.  The asm there
looks OK (assuming I'm reading it correctly, which is not guaranteed),
and I thought I put everything in the right place, but obviously not
8(  After two days on and off of trying to get ia64 to work, I passed
the buck. 8(

Thanks for doing the hard work,
Rusty.
--
  Anyone who quotes me in their sig is an idiot. -- Rusty Russell.


^ permalink raw reply

* [PATCH] : More module parameter compatibility for 2.5.52
From: Jean Tourrilhes @ 2002-12-17  1:26 UTC (permalink / raw)
  To: Linux kernel mailing list, Rusty Russell, Jeff Garzik

	Hi,

	I've just downloaded 2.5.52 to try the new module parameter
support. Unfortunately, the letter 'c' was not implemented, and I need
it. This is used in few drivers (such as hp100, wavelan, wlan_cs...).
	I've only checked that with this patch my hp100 cards load
fine, but I didn't test the various corner cases.

	Have fun...

	Jean

---------------------------------------------------------------

diff -u -p linux/include/linux/moduleparam.r1.h linux/include/linux/moduleparam.h
--- linux/include/linux/moduleparam.r1.h	Mon Dec 16 16:19:59 2002
+++ linux/include/linux/moduleparam.h	Mon Dec 16 16:23:55 2002
@@ -25,6 +25,7 @@ struct kernel_param {
 	param_set_fn set;
 	param_get_fn get;
 	void *arg;
+	void *priv;
 };
 
 /* Special one for strings we want to copy into */
diff -u -p linux/kernel/module.r1.c linux/kernel/module.c
--- linux/kernel/module.r1.c	Mon Dec 16 16:08:42 2002
+++ linux/kernel/module.c	Mon Dec 16 16:39:00 2002
@@ -569,9 +569,41 @@ static int param_string(const char *name
 	return 0;
 }
 
+/* Do char array. This probably should be made available in the new stuff.
+ * Note : driver has already allocated the char array and tell us the
+ * size. The array is in fact two dimensional.
+ * Quick'n'dirty hack by Jean II */
+int param_set_chara(const char *val, struct kernel_param *kp)
+{
+	int	maxchar = (int) kp->priv;
+
+	if (!val) {
+		printk(KERN_ERR "%s: char array parameter expected\n",
+		       kp->name);
+		return -EINVAL;
+	}
+
+	/* Let's be on the safe side with respect to nul-termination
+	 * and always set strings with a nul. */
+	if ((strlen(val) + 1) > maxchar) {
+		printk(KERN_ERR "%s: char array parameter too long\n",
+		       kp->name);
+		return -ENOSPC;
+	}
+
+	strcpy((char *)kp->arg, (char *) val);
+	return 0;
+}
+
+int param_get_chara(char *buffer, struct kernel_param *kp)
+{
+	/* We may want to check the array size ? */
+	return sprintf(buffer, "%s", ((char *)kp->arg));
+}
+
 extern int set_obsolete(const char *val, struct kernel_param *kp)
 {
-	unsigned int min, max;
+	unsigned int min, max, line;
 	char *p, *endp;
 	struct obsolete_modparm *obsparm = kp->arg;
 
@@ -581,6 +613,7 @@ extern int set_obsolete(const char *val,
 	}
 
 	/* type is: [min[-max]]{b,h,i,l,s} */
+	/* or [min[-max]]{c}line for 2d array of chars - Jean II */
 	p = obsparm->type;
 	min = simple_strtol(p, &endp, 10);
 	if (endp == obsparm->type)
@@ -605,6 +638,13 @@ extern int set_obsolete(const char *val,
 				   sizeof(long), param_set_long);
 	case 's':
 		return param_string(kp->name, val, min, max, obsparm->addr);
+	case 'c':
+		p = endp+1;
+		line = simple_strtol(p, &endp, 10);
+		/* Maybe we should check that line doesn't get absurdly big */
+		kp->priv = (void *) line;
+		return param_array(kp->name, val, min, max, obsparm->addr,
+				   line, param_set_chara);
 	}
 	printk(KERN_ERR "Unknown obsolete parameter type %s\n", obsparm->type);
 	return -EINVAL;

^ permalink raw reply

* Re: Linux 2.2.24-rc1
From: Alan Cox @ 2002-12-17  2:16 UTC (permalink / raw)
  To: Dave Jones; +Cc: Pawel Kot, Linux Kernel Mailing List
In-Reply-To: <20021217010612.GA32560@suse.de>

On Tue, 2002-12-17 at 01:06, Dave Jones wrote:

>  > If we get a vendor string, we should use it - thats all
> 
> This patch also makes us unconditionally skip the mcheck_init
> if we have a vendor string. That doesn't seem right.

True.. ok its more complicated to fix 8(


^ permalink raw reply

* [Linux-ia64] Re: ia64 cache flushing?
From: Richard Henderson @ 2002-12-17  1:32 UTC (permalink / raw)
  To: linux-ia64
In-Reply-To: <marc-linux-ia64-105590709805582@msgid-missing>

On Tue, Dec 17, 2002 at 12:14:43PM +1100, Rusty Russell wrote:
> Well, yes, something is wrong with the relocations.  The asm there
> looks OK (assuming I'm reading it correctly, which is not guaranteed),
> and I thought I put everything in the right place, but obviously not
> 8(  After two days on and off of trying to get ia64 to work, I passed
> the buck. 8(

Found it.  First, some general fixes, attached.  

The remaining problem is that you're confusing the code address of a
symbol as seen via the module's local symbol table, and the descriptor
address as seen via EXPORT_SYMBOL from another module.

This makes

+			fixup_plt(location, value);

incorrect for local symbols.  Which can be seen when the call to
function() crashes.

You're going to have to distinguish between symbols retrieved from 
the local symbol table and symbols retrieved from EXPORT_SYMBOL, and
treat them differently in the IPLT case.



r~



diff -rup module-test-framework/Makefile module-test-framework.rth/Makefile
--- module-test-framework/Makefile	Mon Dec 16 20:23:55 2002
+++ module-test-framework.rth/Makefile	Mon Dec 16 19:32:49 2002
@@ -35,7 +35,7 @@ KCCFLAGS_sparc64:=-m64
 KLDFLAGS_sparc:=-N #-Bsymbolic
 KCCFLAGS_sparc: 
-KLDFLAGS_ia64:+KLDFLAGS_ia64:= -N
 KCCFLAGS_ia64:=#-fPIC
 
 KLDFLAGS_arm:=-N #-Bsymbolic
diff -rup module-test-framework/arch-ia64/module.c module-test-framework.rth/arch-ia64/module.c
--- module-test-framework/arch-ia64/module.c	Mon Dec 16 00:33:11 2002
+++ module-test-framework.rth/arch-ia64/module.c	Mon Dec 16 19:41:53 2002
@@ -46,14 +46,6 @@ struct ia64_callout_stub
  	unsigned char plt[16 * 3];
 };
 
-/* Confusingly, the pltoff section referred to by the (generated)
-   .plt, expects descriptors which look like this: */
-struct ia64_plt
-{
-	u64 gp;		/* global pointer */
-	u64 entry;	/* code entry point */
-};
-
 /* We need to create a function descriptor for any internal function
    which is referenced.  ld.so uses the size of the dynamic symbol
    table to allocated them: it does this by assuming the DT_STRTAB
@@ -132,11 +124,12 @@ static u64 calculate_got(struct module *
 	return got;
 }
 
-static void fixup_plt(struct ia64_plt *plt, u64 value)
+static inline void fixup_plt(void *xplt, u64 value)
 {
+	struct ia64_fdesc *plt = xplt;
 	struct ia64_fdesc *fdesc = (void *)value;
-	plt->gp = fdesc->gp;
-	plt->entry = fdesc->entry;
+	
+	*plt = *fdesc;
 }
 
 int apply_relocate(Elf_Rel *rel,
@@ -206,7 +199,7 @@ int apply_relocate_add(Elf_Rela *rela,
 		case R_IA64_IPLTLSB:
 			printk("PLT location %p -> %p\n", location,
 			       (void *)value);
-			fixup_plt((void *)location, value);
+			fixup_plt(location, value);
 			break;
 
 		default:
diff -rup module-test-framework/arch-ia64/module.lds module-test-framework.rth/arch-ia64/module.lds
--- module-test-framework/arch-ia64/module.lds	Mon Dec 16 00:33:11 2002
+++ module-test-framework.rth/arch-ia64/module.lds	Mon Dec 16 20:03:46 2002
@@ -7,15 +7,17 @@ PHDRS {
 
 SECTIONS
 {
+  .text : { *(.text) } :core
+  .plt : { *(.plt) } :core
   .rodata : { *(.rodata) *(.rodata.*) } :core
   .data : { *(.data) CONSTRUCTORS } :core
+  .opd : { *(.opd) } :core
+  .IA_64.unwind_info : { *(.IA_64.unwind_info* .gnu.linkonce.ia64unwi.*) } :core
+  .IA_64.unwind : { *(.IA_64.unwind* .gnu.linkonce.ia64unw.*) } :core
   .got : { *(.got.plt) *(.got) } :core
+  .IA_64.pltoff   : { *(.IA_64.pltoff) }
   .sdata : { *(.sdata) *(.sdata2) } :core
-  /* PLT placed incorrectly if moved after common. --RR */
-  .plt : { *(.plt) } :core
   .sbss : { *(.sbss) *(.dynsbss) *(.scommon) } :core
-  .text : { *(.text) } :core
-  .IA_64.unwind : { *(.IA_64.unwind*) } :core
 
   /* Generated module information */
   __ex_table : { 
@@ -59,6 +61,9 @@ SECTIONS
   .hash : { *(.hash) } :init
   .dynsym : { *(.dynsym) } :init
   .dynstr : { *(.dynstr) } :init
+  .gnu.version    : { *(.gnu.version) } :init
+  .gnu.version_d  : { *(.gnu.version_d) } :init
+  .gnu.version_r  : { *(.gnu.version_r) } :init
 
   /* .rela.IA_64.pltoff needs its own section, which means no wildcards. */
   .rela.dyn :
@@ -91,6 +96,7 @@ SECTIONS
   .rela.IA_64.pltoff : { *(.rela.IA_64.pltoff) } :init
 
   /* For some reason, this needs to be in init too? */
+  /* Of course.  It has to be loaded.  */
   .dynamic : { *(.dynamic) }  :init :dyn
 
   /* Buggy lds drop random sections in the last mentioned segment. */


^ permalink raw reply

* Re: mouse grabbing gotcha (was: dosemu 1.1.3.9 user report)
From: Peter Jay Salzman @ 2002-12-17  1:39 UTC (permalink / raw)
  To: linux-msdos
In-Reply-To: <Pine.LNX.4.33.0212161940500.9915-100000@DHCP-94-246.math.ohio-state.edu>

omg.  getting dosemu has been bad for me.  i just spent the last 3 hours
playing non-stop redneck rampage.  :)

so far, it has been nearly flawless.  it runs better under dosemu on a
celeron 550 than it does under microsoft on a celeron 450 (my girlfriend
has a dual boot that i used to compare).

dosemu hung once in 3 hours of playing, but it didn't take out my
system.  i flipped to virtual console and killall'ed it.

holy moley.  thank you guys.  i really appreciate all the work you've
done!

begin Bart Oldeman <oldeman@math.ohio-state.edu> 
> On Tue, 17 Dec 2002, Stas Sergeev wrote:
> 
> > Peter Jay Salzman wrote:
> > > i guess enlightenment traps cntl-alt-home, because the key combo won't
> > > let dosemu grab the mouse.
> > > however, it DOES work with twm.
> > Can you figure out a more reliable
> > combination then?
> > Set $_X_mgrab_key to, say, "Scroll_Lock"
> > or "Pause" and if there is something
> > that works everywhere, then I think the
> > default "Home" should be changed.
> 
> Pause is already taken as being a force pause (freeze).
> One problem is that you can define just about any keycombo in some of
> these window managers, so there is nothing that works everywhere; however
> some combinations are used more often than others.

i'd have to agree.  i'm not hip onto all the window managers;
enlightenment and twm are the only ones i use.

btw, for gaming purposes (and i guess this is general, but is more
appropriate for gamers), placing the line:

exec xdosemu

in .xinitrc, restarting X, and using ctl-alt-+ to cycle through video
modes till xdosemu fills the entire screen gives the illusion of
fullscreen.

it's not *true* fullscreen in the sense of SDL's "fullscreen" bit when
you initialize SDL video, but honestly, you can't really tell the
difference.

> ctrl+alt+scroll_lock might be something that makes sense though, since
> you're locking the mouse. something to think about post-1.1.4 :)

i'm not sure if there's any safe keycombos to use, but frankly,
ctl-alt-home is pretty exotic.  i'd recommend keeping it or perhaps
using ctl-alt-scroll_lock, which is definitely more intuitive.
 
i know a lot of people who'd love to play these old games again, but
weren't able to get dosemu to run the games.  the doom in linux howto is
very good, but there's no reason why the advice applies just to doom.
most of it applies to all games.

i used that howto as a guide, but did other things like use a more
recent freedos and used 1.1.3.9 (which came out after the howto was last
updated).  i'm detailing everything i did in a general DOS gaming under
linux HOWTO.  i'll having something useful by this evening after i come
back from our local LUG meeting[1].

pete

[1]- funny story.  tonight the guest speaker is talking about C99.
while my friend was putting up flyers advertising the event, an asian
guy asked him what was going on.  they started talking, and it turns out
the guy is on the C99 standards committee.   :)   it's be cool if he
came to the meeting.  :)

-- 
First they ignore you, then they laugh at you, then they fight you,
then you win. -- Gandhi, being prophetic about Linux.

Fingerprint: B9F1 6CF3 47C4 7CD8 D33E 70A9 A3B9 1945 67EA 951D

^ permalink raw reply

* [drm:drm_init] *ERROR* Cannot initialize the agpgart module.
From: Ed Tomlinson @ 2002-12-17  1:49 UTC (permalink / raw)
  To: linux-kernel; +Cc: Dave Jones

I am getting the above message in 2.5.51, 52, and 52+bk current.  
Pci info follows:

oscar# lspci -vv
00:00.0 Host bridge: VIA Technologies, Inc. VT82C598 [Apollo MVP3] (rev 04)
        Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
        Status: Cap+ 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR+
        Latency: 16
        Region 0: Memory at e0000000 (32-bit, prefetchable) [size=64M]
        Capabilities: [a0] AGP version 1.0
                Status: RQ=7 SBA+ 64bit- FW- Rate=x1,x2
                Command: RQ=0 SBA- AGP- 64bit- FW- Rate=<none>


with a mga G400

01:00.0 VGA compatible controller: Matrox Graphics, Inc. MGA G400 AGP (rev 04) (prog-if 00 [VGA])
        Subsystem: Matrox Graphics, Inc. Millennium G400 MAX/Dual Head 32Mb
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
        Status: Cap+ 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
        Latency: 64 (4000ns min, 8000ns max), cache line size 08
        Interrupt: pin A routed to IRQ 11
        Region 0: Memory at e8000000 (32-bit, prefetchable) [size=32M]
        Region 1: Memory at e4000000 (32-bit, non-prefetchable) [size=16K]
        Region 2: Memory at e5000000 (32-bit, non-prefetchable) [size=8M]
        Expansion ROM at <unassigned> [disabled] [size=64K]
        Capabilities: [dc] Power Management version 2
                Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
                Status: D0 PME-Enable- DSel=0 DScale=0 PME-
        Capabilities: [f0] AGP version 2.0
                Status: RQ=31 SBA+ 64bit- FW- Rate=x1,x2
                Command: RQ=31 SBA+ AGP+ 64bit- FW- Rate=x1

What else would help to debug this?  The drm error above is all I find in the logs...

TIA
Ed Tomlinson



^ permalink raw reply

* Re: possible problems with rc6 aplay
From: Mark Knecht @ 2002-12-17  1:44 UTC (permalink / raw)
  To: patrick reardon; +Cc: Paul Davis, Alsa-Devel
In-Reply-To: <3DFE5965.90F4A8B7@earthlink.net>

Patrick,
   I believe the AI-3 operates at 48K if it is not receiving a clock via
it's ADAT input. If the ADAT input is applied and provides 44.1K, then
it is my understanding that the AI-3 operates at 44.1K.

Mark

On Mon, 2002-12-16 at 14:53, patrick reardon wrote:
> 
> yes, thnx, it's much clearer now.  my converter is external with no rate switches and from
> the manual i just discovered it always operates at 48000 (Alesis AI-3).  i'm still
> uncertain how to change the card's configuration though.  "alsactl" doesn't seem to
> provide an obvious way to do this (looking at the man page).  but my asound.state file has




-------------------------------------------------------
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

* Help with ftp connection throttling
From: Mark Ryan @ 2002-12-17  1:51 UTC (permalink / raw)
  To: netfilter

I am in need of a way to setup ipatbles to throttle connection attempts
to my ftp server.

I use Proftpd and I have it set up with 2 logins...1 for download and 1
for upload.  Many users use each account.

What I would like is to limit connection attemts to 1 per minute.  Then,
if a user connects more than that I would like their ip address placed
into the hosts.deny file.  If this is not possible then just ignoring
the extra attempts per minute would work also.
 
Any help would be greatly appreciated.  I am running Redhat 7.2 with
2.4.7-10 as a firewall/router with a homegrown iptables ruleset.
 
Thanks,
Mark
markryan@cfl.rr.com




^ permalink raw reply

* Re: [PATCH] sys_epoll for 2.4
From: Janet Morgan @ 2002-12-17  2:02 UTC (permalink / raw)
  To: Marc-Christian Petersen; +Cc: linux-kernel, davidel
In-Reply-To: <200212140436.23519.m.c.p@wolk-project.de>

> 
> > Thanks for finding this.  fs/ncpfs/sock.c is likewise broken.
> np :)
> 
> > The following patch compiles, but I haven't tested it.
> also works :-)
> 
> Thnx alot.
> 
> ciao, Marc
> 

Thanks for the feedback.  Here's a refresh of the sys_epoll patch 
which includes the sock.c updates and a minor correction to timod.c:

--- linux-2.4.20/arch/i386/kernel/entry.S	Thu Nov 28 15:53:09 2002
+++ sys_epoll/arch/i386/kernel/entry.S	Mon Dec 16 16:24:04 2002
@@ -657,6 +657,10 @@
 	.long SYMBOL_NAME(sys_ni_syscall)	/* 250 sys_alloc_hugepages */
 	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_free_hugepages */
 	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_exit_group */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sys_lookup_dcookie */
+	.long SYMBOL_NAME(sys_epoll_create)     
+	.long SYMBOL_NAME(sys_epoll_ctl)	/* 255 sys_epoll_ctl */
+	.long SYMBOL_NAME(sys_epoll_wait)
 
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long SYMBOL_NAME(sys_ni_syscall)
--- linux-2.4.20/arch/sparc64/solaris/timod.c	Fri Aug  2 17:39:43 2002
+++ sys_epoll/arch/sparc64/solaris/timod.c	Mon Dec 16 16:26:08 2002
@@ -651,10 +651,11 @@
 		SOLD("LISTEN done");
 	}
 	if (!(filp->f_flags & O_NONBLOCK)) {
-		poll_table wait_table, *wait;
+		struct poll_wqueues wait_table;
+		poll_table *wait;
 
 		poll_initwait(&wait_table);
-		wait = &wait_table;
+		wait = &wait_table.pt;
 		for(;;) {
 			SOLD("loop");
 			set_current_state(TASK_INTERRUPTIBLE);
--- linux-2.4.20/fs/Makefile	Thu Nov 28 15:53:15 2002
+++ sys_epoll/fs/Makefile	Mon Dec 16 16:24:04 2002
@@ -14,7 +14,7 @@
 		super.o block_dev.o char_dev.o stat.o exec.o pipe.o namei.o \
 		fcntl.o ioctl.o readdir.o select.o fifo.o locks.o \
 		dcache.o inode.o attr.o bad_inode.o file.o iobuf.o dnotify.o \
-		filesystems.o namespace.o seq_file.o xattr.o
+		filesystems.o namespace.o seq_file.o xattr.o eventpoll.o
 
 ifeq ($(CONFIG_QUOTA),y)
 obj-y += dquot.o
--- linux-2.4.20/fs/eventpoll.c	Wed Dec 31 16:00:00 1969
+++ sys_epoll/fs/eventpoll.c	Mon Dec 16 16:24:04 2002
@@ -0,0 +1,1624 @@
+/*
+ *  fs/eventpoll.c ( Efficent event polling implementation )
+ *  Copyright (C) 2001,...,2002	 Davide Libenzi
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Davide Libenzi <davidel@xmailserver.org>
+ *  
+ *  11 December 2002	
+ *	Ported from 2.5.51 - janetinc@us.ibm.com
+ * 		
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/smp_lock.h>
+#include <linux/string.h>
+#include <linux/list.h>
+#include <linux/hash.h>
+#include <linux/spinlock.h>
+#include <linux/rwsem.h>
+#include <linux/wait.h>
+#include <linux/eventpoll.h>
+#include <linux/mount.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/mman.h>
+#include <asm/atomic.h>
+
+
+
+#define EVENTPOLLFS_MAGIC 0x03111965 /* My birthday should work for this :) */
+
+#define DEBUG_EPOLL 0
+
+#if DEBUG_EPOLL > 0
+#define DPRINTK(x) printk x
+#define DNPRINTK(n, x) do { if ((n) <= DEBUG_EPOLL) printk x; } while (0)
+#else /* #if DEBUG_EPOLL > 0 */
+#define DPRINTK(x) (void) 0
+#define DNPRINTK(n, x) (void) 0
+#endif /* #if DEBUG_EPOLL > 0 */
+
+#define DEBUG_EPI 0
+
+#if DEBUG_EPI != 0
+#define EPI_SLAB_DEBUG (SLAB_DEBUG_FREE | SLAB_RED_ZONE /* | SLAB_POISON */)
+#else /* #if DEBUG_EPI != 0 */
+#define EPI_SLAB_DEBUG 0
+#endif /* #if DEBUG_EPI != 0 */
+
+
+/* Maximum number of poll wake up nests we are allowing */
+#define EP_MAX_POLLWAKE_NESTS 4
+
+/* Maximum size of the hash in bits ( 2^N ) */
+#define EP_MAX_HASH_BITS 17
+
+/* Minimum size of the hash in bits ( 2^N ) */
+#define EP_MIN_HASH_BITS 9
+
+/* Number of hash entries ( "struct list_head" ) inside a page */
+#define EP_HENTRY_X_PAGE (PAGE_SIZE / sizeof(struct list_head))
+
+/* Maximum size of the hash in pages */
+#define EP_MAX_HPAGES ((1 << EP_MAX_HASH_BITS) / EP_HENTRY_X_PAGE + 1)
+
+/* Number of pages allocated for an "hbits" sized hash table */
+#define EP_HASH_PAGES(hbits) ((int) ((1 << (hbits)) / EP_HENTRY_X_PAGE + \
+				     ((1 << (hbits)) % EP_HENTRY_X_PAGE ? 1: 0)))
+
+/* Macro to allocate a "struct epitem" from the slab cache */
+#define EPI_MEM_ALLOC()	(struct epitem *) kmem_cache_alloc(epi_cache, SLAB_KERNEL)
+
+/* Macro to free a "struct epitem" to the slab cache */
+#define EPI_MEM_FREE(p) kmem_cache_free(epi_cache, p)
+
+/* Macro to allocate a "struct eppoll_entry" from the slab cache */
+#define PWQ_MEM_ALLOC()	(struct eppoll_entry *) kmem_cache_alloc(pwq_cache, SLAB_KERNEL)
+
+/* Macro to free a "struct eppoll_entry" to the slab cache */
+#define PWQ_MEM_FREE(p) kmem_cache_free(pwq_cache, p)
+
+/* Fast test to see if the file is an evenpoll file */
+#define IS_FILE_EPOLL(f) ((f)->f_op == &eventpoll_fops)
+
+/*
+ * Remove the item from the list and perform its initialization.
+ * This is usefull for us because we can test if the item is linked
+ * using "EP_IS_LINKED(p)".
+ */
+#define EP_LIST_DEL(p) do { list_del(p); INIT_LIST_HEAD(p); } while (0)
+
+/* Tells us if the item is currently linked */
+#define EP_IS_LINKED(p) (!list_empty(p))
+
+/* Get the "struct epitem" from a wait queue pointer */
+#define EP_ITEM_FROM_WAIT(p) ((struct epitem *) container_of(p, struct eppoll_entry, wait)->base)
+
+/* Get the "struct epitem" from an epoll queue wrapper */
+#define EP_ITEM_FROM_EPQUEUE(p) (container_of(p, struct ep_pqueue, pt)->epi)
+
+/*
+ * This is used to optimize the event transfer to userspace. Since this
+ * is kept on stack, it should be pretty small.
+ */
+#define EP_MAX_BUF_EVENTS 32
+
+/*
+ * Used to optimize ready items collection by reducing the irqlock/irqunlock
+ * switching rate. This is kept in stack too, so do not go wild with this number.
+ */
+#define EP_MAX_COLLECT_ITEMS 64
+
+
+/*
+ * Node that is linked into the "wake_task_list" member of the "struct poll_safewake".
+ * It is used to keep track on all tasks that are currently inside the wake_up() code
+ * to 1) short-circuit the one coming from the same task and same wait queue head
+ * ( loop ) 2) allow a maximum number of epoll descriptors inclusion nesting
+ * 3) let go the ones coming from other tasks.
+ */
+struct wake_task_node {
+	struct list_head llink;
+	task_t *task;
+	wait_queue_head_t *wq;
+};
+
+/*
+ * This is used to implement the safe poll wake up avoiding to reenter
+ * the poll callback from inside wake_up().
+ */
+struct poll_safewake {
+	struct list_head wake_task_list;
+	spinlock_t lock;
+};
+
+/*
+ * This structure is stored inside the "private_data" member of the file
+ * structure and rapresent the main data sructure for the eventpoll
+ * interface.
+ */
+struct eventpoll {
+	/* Protect the this structure access */
+	rwlock_t lock;
+
+	/* Wait queue used by sys_epoll_wait() */
+	wait_queue_head_t wq;
+
+	/* Wait queue used by file->poll() */
+	wait_queue_head_t poll_wait;
+
+	/* List of ready file descriptors */
+	struct list_head rdllist;
+
+	/* Size of the hash */
+	unsigned int hashbits;
+
+	/* Pages for the "struct epitem" hash */
+	char *hpages[EP_MAX_HPAGES];
+};
+
+/* Wait structure used by the poll hooks */
+struct eppoll_entry {
+	/* List header used to link this structure to the "struct epitem" */
+	struct list_head llink;
+
+	/* The "base" pointer is set to the container "struct epitem" */
+	void *base;
+
+	/*
+	 * Wait queue item that will be linked to the target file wait
+	 * queue head.
+	 */
+	wait_queue_t wait;
+
+	/* The wait queue head that linked the "wait" wait queue item */
+	wait_queue_head_t *whead;
+};
+
+/*
+ * Each file descriptor added to the eventpoll interface will
+ * have an entry of this type linked to the hash.
+ */
+struct epitem {
+	/* List header used to link this structure to the eventpoll hash */
+	struct list_head llink;
+
+	/* List header used to link this structure to the eventpoll ready list */
+	struct list_head rdllink;
+
+	/* Number of active wait queue attached to poll operations */
+	int nwait;
+
+	/* List containing poll wait queues */
+	struct list_head pwqlist;
+
+	/* The "container" of this item */
+	struct eventpoll *ep;
+
+	/* The file this item refers to */
+	struct file *file;
+
+	/* The structure that describe the interested events and the source fd */
+	struct epoll_event event;
+
+	/*
+	 * Used to keep track of the usage count of the structure. This avoids
+	 * that the structure will desappear from underneath our processing.
+	 */
+	atomic_t usecnt;
+
+	/* List header used to link this item to the "struct file" items list */
+	struct list_head fllink;
+};
+
+/* Wrapper struct used by poll queueing */
+struct ep_pqueue {
+	poll_table pt;
+	struct epitem *epi;
+};
+
+
+
+static void ep_poll_safewake_init(struct poll_safewake *psw);
+static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq);
+static unsigned int ep_get_hash_bits(unsigned int hintsize);
+static int ep_getfd(int *efd, struct inode **einode, struct file **efile);
+static int ep_alloc_pages(char **pages, int numpages);
+static int ep_free_pages(char **pages, int numpages);
+static int ep_file_init(struct file *file, unsigned int hashbits);
+static unsigned int ep_hash_index(struct eventpoll *ep, struct file *file);
+static struct list_head *ep_hash_entry(struct eventpoll *ep, unsigned int index);
+static int ep_init(struct eventpoll *ep, unsigned int hashbits);
+static void ep_free(struct eventpoll *ep);
+static struct epitem *ep_find(struct eventpoll *ep, struct file *file);
+static void ep_use_epitem(struct epitem *epi);
+static void ep_release_epitem(struct epitem *epi);
+static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead, poll_table *pt);
+static int ep_insert(struct eventpoll *ep, struct epoll_event *event, struct file *tfile);
+static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_event *event);
+static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi);
+static int ep_unlink(struct eventpoll *ep, struct epitem *epi);
+static int ep_remove(struct eventpoll *ep, struct epitem *epi);
+static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync);
+static int ep_eventpoll_close(struct inode *inode, struct file *file);
+static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait);
+static int ep_collect_ready_items(struct eventpoll *ep, struct epitem **aepi, int maxepi);
+static int ep_send_events(struct eventpoll *ep, struct epitem **aepi, int nepi,
+			  struct epoll_event *events);
+static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events, int maxevents);
+static int ep_poll(struct eventpoll *ep, struct epoll_event *events, int maxevents,
+		   int timeout);
+static int eventpollfs_delete_dentry(struct dentry *dentry);
+static struct inode *ep_eventpoll_inode(void);
+
+
+/* Safe wake up implementation */
+static struct poll_safewake psw;
+
+/*
+ * This semaphore is used to ensure that files are not removed
+ * while epoll is using them. Namely the f_op->poll(), since
+ * it has to be called from outside the lock, must be protected.
+ * This is read-held during the event transfer loop to userspace
+ * and it is write-held during the file cleanup path and the epoll
+ * file exit code.
+ */
+static struct rw_semaphore epsem;
+
+/* Slab cache used to allocate "struct epitem" */
+static kmem_cache_t *epi_cache;
+
+/* Slab cache used to allocate "struct eppoll_entry" */
+static kmem_cache_t *pwq_cache;
+
+/* Virtual fs used to allocate inodes for eventpoll files */
+static struct vfsmount *eventpoll_mnt;
+
+/* File callbacks that implement the eventpoll file behaviour */
+static struct file_operations eventpoll_fops = {
+	.release	= ep_eventpoll_close,
+	.poll		= ep_eventpoll_poll
+};
+
+static int eventpollfs_statfs(struct super_block *sb, struct statfs *buf)
+{
+        buf->f_type = EVENTPOLLFS_MAGIC;
+        buf->f_bsize = 1024;
+        buf->f_namelen = 255;
+        return 0;
+}
+
+static struct super_operations eventpollfs_ops = {
+        statfs:         eventpollfs_statfs,
+};
+
+static struct super_block * eventpollfs_read_super(struct super_block *sb, void *data, int silent)
+{
+	struct inode *root = new_inode(sb);
+	if (!root)
+		return NULL;
+	root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
+	root->i_uid = root->i_gid = 0;
+	root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
+	sb->s_blocksize = 1024;
+	sb->s_blocksize_bits = 10;
+	sb->s_magic = EVENTPOLLFS_MAGIC;
+	sb->s_op = &eventpollfs_ops;
+	sb->s_root = d_alloc(NULL, &(const struct qstr) {"eventpoll:", 10, 0 });
+	if (!sb->s_root) {
+		iput(root);
+		return NULL;
+	}
+	sb->s_root->d_sb = sb;
+	sb->s_root->d_parent = sb->s_root;
+	d_instantiate(sb->s_root, root);
+	return sb;
+}
+
+static DECLARE_FSTYPE(eventpoll_fs_type, "eventpollfs", eventpollfs_read_super, FS_NOMOUNT);
+
+
+/* Very basic directory entry operations for the eventpoll virtual file system */
+static struct dentry_operations eventpollfs_dentry_operations = {
+	.d_delete	= eventpollfs_delete_dentry,
+};
+
+
+
+/* Initialize the poll safe wake up structure */
+static void ep_poll_safewake_init(struct poll_safewake *psw)
+{
+
+	INIT_LIST_HEAD(&psw->wake_task_list);
+	spin_lock_init(&psw->lock);
+}
+
+
+/*
+ * Perform a safe wake up of the poll wait list. The problem is that
+ * with the new callback'd wake up system, it is possible that the
+ * poll callback is reentered from inside the call to wake_up() done
+ * on the poll wait queue head. The rule is that we cannot reenter the
+ * wake up code from the same task more than EP_MAX_POLLWAKE_NESTS times,
+ * and we cannot reenter the same wait queue head at all. This will
+ * enable to have a hierarchy of epoll file descriptor of no more than
+ * EP_MAX_POLLWAKE_NESTS deep. We need the irq version of the spin lock
+ * because this one gets called by the poll callback, that in turn is called
+ * from inside a wake_up(), that might be called from irq context.
+ */
+static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq)
+{
+	int wake_nests = 0;
+	unsigned long flags;
+	task_t *this_task = current;
+	struct list_head *lsthead = &psw->wake_task_list, *lnk;
+	struct wake_task_node tnode;
+
+	spin_lock_irqsave(&psw->lock, flags);
+
+	/* Try to see if the current task is already inside this wakeup call */
+	list_for_each(lnk, lsthead) {
+		struct wake_task_node *tncur = list_entry(lnk, struct wake_task_node, llink);
+
+		if (tncur->task == this_task) {
+			if (tncur->wq == wq || ++wake_nests > EP_MAX_POLLWAKE_NESTS) {
+				/*
+				 * Ops ... loop detected or maximum nest level reached.
+				 * We abort this wake by breaking the cycle itself.
+				 */
+				spin_unlock_irqrestore(&psw->lock, flags);
+				return;
+			}
+		}
+	}
+
+	/* Add the current task to the list */
+	tnode.task = this_task;
+	tnode.wq = wq;
+	list_add(&tnode.llink, lsthead);
+
+	spin_unlock_irqrestore(&psw->lock, flags);
+
+	/* Do really wake up now */
+	wake_up(wq);
+
+	/* Remove the current task from the list */
+	spin_lock_irqsave(&psw->lock, flags);
+	list_del(&tnode.llink);
+	spin_unlock_irqrestore(&psw->lock, flags);
+}
+
+
+/*
+ * Calculate the size of the hash in bits. The returned size will be
+ * bounded between EP_MIN_HASH_BITS and EP_MAX_HASH_BITS.
+ */
+static unsigned int ep_get_hash_bits(unsigned int hintsize)
+{
+	unsigned int i, val;
+
+	for (i = 0, val = 1; val < hintsize && i < EP_MAX_HASH_BITS; i++, val <<= 1);
+	return i <  EP_MIN_HASH_BITS ?  EP_MIN_HASH_BITS: i;
+}
+
+
+/* Used to initialize the epoll bits inside the "struct file" */
+void eventpoll_init_file(struct file *file)
+{
+
+	INIT_LIST_HEAD(&file->f_ep_links);
+	spin_lock_init(&file->f_ep_lock);
+}
+
+
+/*
+ * This is called from inside fs/file_table.c:__fput() to unlink files
+ * from the eventpoll interface. We need to have this facility to cleanup
+ * correctly files that are closed without being removed from the eventpoll
+ * interface.
+ */
+void eventpoll_release(struct file *file)
+{
+	struct list_head *lsthead = &file->f_ep_links;
+	struct epitem *epi;
+
+	/*
+	 * Fast check to avoid the get/release of the semaphore. Since
+	 * we're doing this outside the semaphore lock, it might return
+	 * false negatives, but we don't care. It'll help in 99.99% of cases
+	 * to avoid the semaphore lock. False positives simply cannot happen
+	 * because the file in on the way to be removed and nobody ( but
+	 * eventpoll ) has still a reference to this file.
+	 */
+	if (list_empty(lsthead))
+		return;
+
+	/*
+	 * We don't want to get "file->f_ep_lock" because it is not
+	 * necessary. It is not necessary because we're in the "struct file"
+	 * cleanup path, and this means that noone is using this file anymore.
+	 * The only hit might come from ep_free() but by holding the semaphore
+	 * will correctly serialize the operation.
+	 */
+	down_write(&epsem);
+	while (!list_empty(lsthead)) {
+		epi = list_entry(lsthead->next, struct epitem, fllink);
+
+		EP_LIST_DEL(&epi->fllink);
+		ep_remove(epi->ep, epi);
+	}
+	up_write(&epsem);
+}
+
+
+/*
+ * It opens an eventpoll file descriptor by suggesting a storage of "size"
+ * file descriptors. The size parameter is just an hint about how to size
+ * data structures. It won't prevent the user to store more than "size"
+ * file descriptors inside the epoll interface. It is the kernel part of
+ * the userspace epoll_create(2).
+ */
+asmlinkage int sys_epoll_create(int size)
+{
+	int error, fd;
+	unsigned int hashbits;
+	struct inode *inode;
+	struct file *file;
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n",
+		     current, size));
+
+	/* Correctly size the hash */
+	hashbits = ep_get_hash_bits((unsigned int) size);
+
+	/*
+	 * Creates all the items needed to setup an eventpoll file. That is,
+	 * a file structure, and inode and a free file descriptor.
+	 */
+	error = ep_getfd(&fd, &inode, &file);
+	if (error)
+		goto eexit_1;
+
+	/* Setup the file internal data structure ( "struct eventpoll" ) */
+	error = ep_file_init(file, hashbits);
+	if (error)
+		goto eexit_2;
+
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
+		     current, size, fd));
+
+	return fd;
+
+eexit_2:
+	sys_close(fd);
+eexit_1:
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
+		     current, size, error));
+	return error;
+}
+
+
+/*
+ * The following function implement the controller interface for the eventpoll
+ * file that enable the insertion/removal/change of file descriptors inside
+ * the interest set. It rapresents the kernel part of the user spcae epoll_ctl(2).
+ */
+asmlinkage int sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
+{
+	int error;
+	struct file *file, *tfile;
+	struct eventpoll *ep;
+	struct epitem *epi;
+	struct epoll_event epds;
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u)\n",
+		     current, epfd, op, fd, event->events));
+
+	error = -EFAULT;
+	if (copy_from_user(&epds, event, sizeof(struct epoll_event)))
+		goto eexit_1;
+
+	/* Get the "struct file *" for the eventpoll file */
+	error = -EBADF;
+	file = fget(epfd);
+	if (!file)
+		goto eexit_1;
+
+	/* Get the "struct file *" for the target file */
+	tfile = fget(fd);
+	if (!tfile)
+		goto eexit_2;
+
+	/* The target file descriptor must support poll */
+	error = -EPERM;
+	if (!tfile->f_op || !tfile->f_op->poll)
+		goto eexit_3;
+
+	/*
+	 * We have to check that the file structure underneath the file descriptor
+	 * the user passed to us _is_ an eventpoll file. And also we do not permit
+	 * adding an epoll file descriptor inside itself.
+	 */
+	error = -EINVAL;
+	if (file == tfile || !IS_FILE_EPOLL(file))
+		goto eexit_3;
+
+	/*
+	 * At this point it is safe to assume that the "private_data" contains
+	 * our own data structure.
+	 */
+	ep = file->private_data;
+
+	/*
+	 * Try to lookup the file inside our hash table. When an item is found
+	 * ep_find() increases the usage count of the item so that it won't
+	 * desappear underneath us. The only thing that might happen, if someone
+	 * tries very hard, is a double insertion of the same file descriptor.
+	 * This does not rapresent a problem though and we don't really want
+	 * to put an extra syncronization object to deal with this harmless condition.
+	 */
+	epi = ep_find(ep, tfile);
+
+	error = -EINVAL;
+	switch (op) {
+	case EPOLL_CTL_ADD:
+		if (!epi) {
+			epds.events |= POLLERR | POLLHUP;
+
+			error = ep_insert(ep, &epds, tfile);
+		} else
+			error = -EEXIST;
+		break;
+	case EPOLL_CTL_DEL:
+		if (epi)
+			error = ep_remove(ep, epi);
+		else
+			error = -ENOENT;
+		break;
+	case EPOLL_CTL_MOD:
+		if (epi) {
+			epds.events |= POLLERR | POLLHUP;
+			error = ep_modify(ep, epi, &epds);
+		} else
+			error = -ENOENT;
+		break;
+	}
+
+	/*
+	 * The function ep_find() increments the usage count of the structure
+	 * so, if this is not NULL, we need to release it.
+	 */
+	if (epi)
+		ep_release_epitem(epi);
+
+eexit_3:
+	fput(tfile);
+eexit_2:
+	fput(file);
+eexit_1:
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u) = %d\n",
+		     current, epfd, op, fd, event->events, error));
+
+	return error;
+}
+
+
+/*
+ * Implement the event wait interface for the eventpoll file. It is the kernel
+ * part of the user space epoll_wait(2).
+ */
+asmlinkage int sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
+			      int timeout)
+{
+	int error;
+	struct file *file;
+	struct eventpoll *ep;
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d)\n",
+		     current, epfd, events, maxevents, timeout));
+
+	/* The maximum number of event must be greater than zero */
+	if (maxevents <= 0)
+		return -EINVAL;
+
+	/* Verify that the area passed by the user is writeable */
+	if ((error = verify_area(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event))))
+		goto eexit_1;
+
+	/* Get the "struct file *" for the eventpoll file */
+	error = -EBADF;
+	file = fget(epfd);
+	if (!file)
+		goto eexit_1;
+
+	/*
+	 * We have to check that the file structure underneath the file descriptor
+	 * the user passed to us _is_ an eventpoll file.
+	 */
+	error = -EINVAL;
+	if (!IS_FILE_EPOLL(file))
+		goto eexit_2;
+
+	/*
+	 * At this point it is safe to assume that the "private_data" contains
+	 * our own data structure.
+	 */
+	ep = file->private_data;
+
+	/* Time to fish for events ... */
+	error = ep_poll(ep, events, maxevents, timeout);
+
+eexit_2:
+	fput(file);
+eexit_1:
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d) = %d\n",
+		     current, epfd, events, maxevents, timeout, error));
+
+	return error;
+}
+
+
+/*
+ * Creates the file descriptor to be used by the epoll interface.
+ */
+static int ep_getfd(int *efd, struct inode **einode, struct file **efile)
+{
+	struct qstr this;
+	char name[32];
+	struct dentry *dentry;
+	struct inode *inode;
+	struct file *file;
+	int error, fd;
+
+	/* Get an ready to use file */
+	error = -ENFILE;
+	file = get_empty_filp();
+	if (!file)
+		goto eexit_1;
+
+	/* Allocates an inode from the eventpoll file system */
+	inode = ep_eventpoll_inode();
+	error = PTR_ERR(inode);
+	if (IS_ERR(inode))
+		goto eexit_2;
+
+	/* Allocates a free descriptor to plug the file onto */
+	error = get_unused_fd();
+	if (error < 0)
+		goto eexit_3;
+	fd = error;
+
+	/*
+	 * Link the inode to a directory entry by creating a unique name
+	 * using the inode number.
+	 */
+	error = -ENOMEM;
+	sprintf(name, "[%lu]", inode->i_ino);
+	this.name = name;
+	this.len = strlen(name);
+	this.hash = inode->i_ino;
+	dentry = d_alloc(eventpoll_mnt->mnt_sb->s_root, &this);
+	if (!dentry)
+		goto eexit_4;
+	dentry->d_op = &eventpollfs_dentry_operations;
+	d_add(dentry, inode);
+	file->f_vfsmnt = mntget(eventpoll_mnt);
+	file->f_dentry = dget(dentry);
+
+	/*
+	 * Initialize the file as read/write because it could be used
+	 * with write() to add/remove/change interest sets.
+	 */
+	file->f_pos = 0;
+	file->f_flags = O_RDONLY;
+	file->f_op = &eventpoll_fops;
+	file->f_mode = FMODE_READ;
+	file->f_version = 0;
+	file->private_data = NULL;
+
+	/* Install the new setup file into the allocated fd. */
+	fd_install(fd, file);
+
+	*efd = fd;
+	*einode = inode;
+	*efile = file;
+	return 0;
+
+eexit_4:
+	put_unused_fd(fd);
+eexit_3:
+	iput(inode);
+eexit_2:
+	put_filp(file);
+eexit_1:
+	return error;
+}
+
+
+static int ep_alloc_pages(char **pages, int numpages)
+{
+	int i;
+
+	for (i = 0; i < numpages; i++) {
+		pages[i] = (char *) __get_free_pages(GFP_KERNEL, 0);
+		if (!pages[i]) {
+			for (--i; i >= 0; i--) {
+				ClearPageReserved(virt_to_page(pages[i]));
+				free_pages((unsigned long) pages[i], 0);
+			}
+			return -ENOMEM;
+		}
+		SetPageReserved(virt_to_page(pages[i]));
+	}
+	return 0;
+}
+
+
+static int ep_free_pages(char **pages, int numpages)
+{
+	int i;
+
+	for (i = 0; i < numpages; i++) {
+		ClearPageReserved(virt_to_page(pages[i]));
+		free_pages((unsigned long) pages[i], 0);
+	}
+	return 0;
+}
+
+
+static int ep_file_init(struct file *file, unsigned int hashbits)
+{
+	int error;
+	struct eventpoll *ep;
+
+	if (!(ep = kmalloc(sizeof(struct eventpoll), GFP_KERNEL)))
+		return -ENOMEM;
+
+	memset(ep, 0, sizeof(*ep));
+
+	error = ep_init(ep, hashbits);
+	if (error) {
+		kfree(ep);
+		return error;
+	}
+
+	file->private_data = ep;
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_file_init() ep=%p\n",
+		     current, ep));
+	return 0;
+}
+
+
+/*
+ * Calculate the index of the hash relative to "file".
+ */
+static unsigned int ep_hash_index(struct eventpoll *ep, struct file *file)
+{
+
+	return (unsigned int) hash_ptr(file, ep->hashbits);
+}
+
+
+/*
+ * Returns the hash entry ( struct list_head * ) of the passed index.
+ */
+static struct list_head *ep_hash_entry(struct eventpoll *ep, unsigned int index)
+{
+
+	return (struct list_head *) (ep->hpages[index / EP_HENTRY_X_PAGE] +
+				     (index % EP_HENTRY_X_PAGE) * sizeof(struct list_head));
+}
+
+
+static int ep_init(struct eventpoll *ep, unsigned int hashbits)
+{
+	int error;
+	unsigned int i, hsize;
+
+	rwlock_init(&ep->lock);
+	init_waitqueue_head(&ep->wq);
+	init_waitqueue_head(&ep->poll_wait);
+	INIT_LIST_HEAD(&ep->rdllist);
+
+	/* Hash allocation and setup */
+	ep->hashbits = hashbits;
+	error = ep_alloc_pages(ep->hpages, EP_HASH_PAGES(ep->hashbits));
+	if (error)
+		goto eexit_1;
+
+	/* Initialize hash buckets */
+	for (i = 0, hsize = 1 << hashbits; i < hsize; i++)
+		INIT_LIST_HEAD(ep_hash_entry(ep, i));
+
+	return 0;
+eexit_1:
+	return error;
+}
+
+
+static void ep_free(struct eventpoll *ep)
+{
+	unsigned int i, hsize;
+	struct list_head *lsthead, *lnk;
+
+	/*
+	 * We need to lock this because we could be hit by
+	 * eventpoll_release() while we're freeing the "struct eventpoll".
+	 */
+	down_write(&epsem);
+
+	/*
+	 * Walks through the whole hash by unregistering poll callbacks.
+	 */
+	for (i = 0, hsize = 1 << ep->hashbits; i < hsize; i++) {
+		lsthead = ep_hash_entry(ep, i);
+
+		list_for_each(lnk, lsthead) {
+			struct epitem *epi = list_entry(lnk, struct epitem, llink);
+
+			ep_unregister_pollwait(ep, epi);
+		}
+	}
+
+	/*
+	 * Walks through the whole hash by freeing each "struct epitem". At this
+	 * point we are sure no poll callbacks will be lingering around, and also by
+	 * write-holding "epsem" we can be sure that no file cleanup code will hit
+	 * us during this operation. So we can avoid the lock on "ep->lock".
+	 */
+	for (i = 0, hsize = 1 << ep->hashbits; i < hsize; i++) {
+		lsthead = ep_hash_entry(ep, i);
+
+		while (!list_empty(lsthead)) {
+			struct epitem *epi = list_entry(lsthead->next, struct epitem, llink);
+
+			ep_remove(ep, epi);
+		}
+	}
+
+	up_write(&epsem);
+
+	/* Free hash pages */
+	ep_free_pages(ep->hpages, EP_HASH_PAGES(ep->hashbits));
+}
+
+
+/*
+ * Search the file inside the eventpoll hash. It add usage count to
+ * the returned item, so the caller must call ep_release_epitem()
+ * after finished using the "struct epitem".
+ */
+static struct epitem *ep_find(struct eventpoll *ep, struct file *file)
+{
+	unsigned long flags;
+	struct list_head *lsthead, *lnk;
+	struct epitem *epi = NULL;
+
+	read_lock_irqsave(&ep->lock, flags);
+
+	lsthead = ep_hash_entry(ep, ep_hash_index(ep, file));
+	list_for_each(lnk, lsthead) {
+		epi = list_entry(lnk, struct epitem, llink);
+
+		if (epi->file == file) {
+			ep_use_epitem(epi);
+			break;
+		}
+		epi = NULL;
+	}
+
+	read_unlock_irqrestore(&ep->lock, flags);
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_find(%p) -> %p\n",
+		     current, file, epi));
+
+	return epi;
+}
+
+
+/*
+ * Increment the usage count of the "struct epitem" making it sure
+ * that the user will have a valid pointer to reference.
+ */
+static void ep_use_epitem(struct epitem *epi)
+{
+
+	atomic_inc(&epi->usecnt);
+}
+
+
+/*
+ * Decrement ( release ) the usage count by signaling that the user
+ * has finished using the structure. It might lead to freeing the
+ * structure itself if the count goes to zero.
+ */
+static void ep_release_epitem(struct epitem *epi)
+{
+
+	if (atomic_dec_and_test(&epi->usecnt))
+		EPI_MEM_FREE(epi);
+}
+
+
+/*
+ * This is the callback that is used to add our wait queue to the
+ * target file wakeup lists.
+ */
+static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead, poll_table *pt)
+{
+	struct epitem *epi = EP_ITEM_FROM_EPQUEUE(pt);
+	struct eppoll_entry *pwq;
+
+	if (epi->nwait >= 0 && (pwq = PWQ_MEM_ALLOC()))
+	{
+		init_waitqueue_func_entry(&pwq->wait, ep_poll_callback);
+		pwq->whead = whead;
+		pwq->base = epi;
+		add_wait_queue(whead, &pwq->wait);
+		list_add_tail(&pwq->llink, &epi->pwqlist);
+		epi->nwait++;
+	}
+	else
+	{
+		/* We have to signal that an error occured */
+		epi->nwait = -1;
+	}
+}
+
+
+static int ep_insert(struct eventpoll *ep, struct epoll_event *event, struct file *tfile)
+{
+	int error, revents, pwake = 0;
+	unsigned long flags;
+	struct epitem *epi;
+	struct ep_pqueue epq;
+
+	error = -ENOMEM;
+	if (!(epi = EPI_MEM_ALLOC()))
+		goto eexit_1;
+
+	/* Item initialization follow here ... */
+	INIT_LIST_HEAD(&epi->llink);
+	INIT_LIST_HEAD(&epi->rdllink);
+	INIT_LIST_HEAD(&epi->fllink);
+	INIT_LIST_HEAD(&epi->pwqlist);
+	epi->ep = ep;
+	epi->file = tfile;
+	epi->event = *event;
+	atomic_set(&epi->usecnt, 1);
+	epi->nwait = 0;
+
+	/* Initialize the poll table using the queue callback */
+	epq.epi = epi;
+	init_poll_funcptr(&epq.pt, ep_ptable_queue_proc);
+
+	/*
+	 * Attach the item to the poll hooks and get current event bits.
+	 * We can safely use the file* here because its usage count has
+	 * been increased by the caller of this function.
+	 */
+	revents = tfile->f_op->poll(tfile, &epq.pt);
+
+	/*
+	 * We have to check if something went wrong during the poll wait queue
+	 * install process. Namely an allocation for a wait queue failed due
+	 * high memory pressure.
+	 */
+	if (epi->nwait < 0)
+		goto eexit_2;
+
+	/* Add the current item to the list of active epoll hook for this file */
+	spin_lock(&tfile->f_ep_lock);
+	list_add_tail(&epi->fllink, &tfile->f_ep_links);
+	spin_unlock(&tfile->f_ep_lock);
+
+	/* We have to drop the new item inside our item list to keep track of it */
+	write_lock_irqsave(&ep->lock, flags);
+
+	/* Add the current item to the hash table */
+	list_add(&epi->llink, ep_hash_entry(ep, ep_hash_index(ep, tfile)));
+
+	/* If the file is already "ready" we drop it inside the ready list */
+	if ((revents & event->events) && !EP_IS_LINKED(&epi->rdllink)) {
+		list_add_tail(&epi->rdllink, &ep->rdllist);
+
+		/* Notify waiting tasks that events are available */
+		if (waitqueue_active(&ep->wq))
+			wake_up(&ep->wq);
+		if (waitqueue_active(&ep->poll_wait))
+			pwake++;
+	}
+
+	write_unlock_irqrestore(&ep->lock, flags);
+
+	/* We have to call this outside the lock */
+	if (pwake)
+		ep_poll_safewake(&psw, &ep->poll_wait);
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_insert(%p, %p)\n",
+		     current, ep, tfile));
+
+	return 0;
+
+eexit_2:
+	ep_unregister_pollwait(ep, epi);
+
+	/*
+	 * We need to do this because an event could have been arrived on some
+	 * allocated wait queue.
+	 */
+	write_lock_irqsave(&ep->lock, flags);
+	if (EP_IS_LINKED(&epi->rdllink))
+		EP_LIST_DEL(&epi->rdllink);
+	write_unlock_irqrestore(&ep->lock, flags);
+
+	EPI_MEM_FREE(epi);
+eexit_1:
+	return error;
+}
+
+
+/*
+ * Modify the interest event mask by dropping an event if the new mask
+ * has a match in the current file status.
+ */
+static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_event *event)
+{
+	int pwake = 0;
+	unsigned int revents;
+	unsigned long flags;
+
+	/*
+	 * Set the new event interest mask before calling f_op->poll(), otherwise
+	 * a potential race might occur. In fact if we do this operation inside
+	 * the lock, an event might happen between the f_op->poll() call and the
+	 * new event set registering.
+	 */
+	epi->event.events = event->events;
+
+	/*
+	 * Get current event bits. We can safely use the file* here because
+	 * its usage count has been increased by the caller of this function.
+	 */
+	revents = epi->file->f_op->poll(epi->file, NULL);
+
+	write_lock_irqsave(&ep->lock, flags);
+
+	/* Copy the data member from inside the lock */
+	epi->event.data = event->data;
+
+	/* If the file is already "ready" we drop it inside the ready list */
+	if ((revents & event->events) && EP_IS_LINKED(&epi->llink) &&
+	    !EP_IS_LINKED(&epi->rdllink)) {
+		list_add_tail(&epi->rdllink, &ep->rdllist);
+
+		/* Notify waiting tasks that events are available */
+		if (waitqueue_active(&ep->wq))
+			wake_up(&ep->wq);
+		if (waitqueue_active(&ep->poll_wait))
+			pwake++;
+	}
+
+	write_unlock_irqrestore(&ep->lock, flags);
+
+	/* We have to call this outside the lock */
+	if (pwake)
+		ep_poll_safewake(&psw, &ep->poll_wait);
+
+	return 0;
+}
+
+
+/*
+ * This function unregister poll callbacks from the associated file descriptor.
+ * Since this must be called without holding "ep->lock" the atomic exchange trick
+ * will protect us from multiple unregister.
+ */
+static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi)
+{
+	int nwait;
+	struct list_head *lsthead = &epi->pwqlist;
+	struct eppoll_entry *pwq;
+
+	/* This is called without locks, so we need the atomic exchange */
+	nwait = xchg(&epi->nwait, 0);
+
+	if (nwait)
+	{
+		while (!list_empty(lsthead)) {
+			pwq = list_entry(lsthead->next, struct eppoll_entry, llink);
+
+			EP_LIST_DEL(&pwq->llink);
+			remove_wait_queue(pwq->whead, &pwq->wait);
+			PWQ_MEM_FREE(pwq);
+		}
+	}
+}
+
+
+/*
+ * Unlink the "struct epitem" from all places it might have been hooked up.
+ * This function must be called with write IRQ lock on "ep->lock".
+ */
+static int ep_unlink(struct eventpoll *ep, struct epitem *epi)
+{
+	int error;
+
+	/*
+	 * It can happen that this one is called for an item already unlinked.
+	 * The check protect us from doing a double unlink ( crash ).
+	 */
+	error = -ENOENT;
+	if (!EP_IS_LINKED(&epi->llink))
+		goto eexit_1;
+
+	/*
+	 * At this point is safe to do the job, unlink the item from our list.
+	 * This operation togheter with the above check closes the door to
+	 * double unlinks.
+	 */
+	EP_LIST_DEL(&epi->llink);
+
+	/*
+	 * If the item we are going to remove is inside the ready file descriptors
+	 * we want to remove it from this list to avoid stale events.
+	 */
+	if (EP_IS_LINKED(&epi->rdllink))
+		EP_LIST_DEL(&epi->rdllink);
+
+	error = 0;
+eexit_1:
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_unlink(%p, %p) = %d\n",
+		     current, ep, epi->file, error));
+
+	return error;
+}
+
+
+/*
+ * Removes a "struct epitem" from the eventpoll hash and deallocates
+ * all the associated resources.
+ */
+static int ep_remove(struct eventpoll *ep, struct epitem *epi)
+{
+	int error;
+	unsigned long flags;
+
+	/*
+	 * Removes poll wait queue hooks. We _have_ to do this without holding
+	 * the "ep->lock" otherwise a deadlock might occur. This because of the
+	 * sequence of the lock acquisition. Here we do "ep->lock" then the wait
+	 * queue head lock when unregistering the wait queue. The wakeup callback
+	 * will run by holding the wait queue head lock and will call our callback
+	 * that will try to get "ep->lock".
+	 */
+	ep_unregister_pollwait(ep, epi);
+
+	/* Remove the current item from the list of epoll hooks */
+	spin_lock(&epi->file->f_ep_lock);
+	if (EP_IS_LINKED(&epi->fllink))
+		EP_LIST_DEL(&epi->fllink);
+	spin_unlock(&epi->file->f_ep_lock);
+
+	/* We need to acquire the write IRQ lock before calling ep_unlink() */
+	write_lock_irqsave(&ep->lock, flags);
+
+	/* Really unlink the item from the hash */
+	error = ep_unlink(ep, epi);
+
+	write_unlock_irqrestore(&ep->lock, flags);
+
+	if (error)
+		goto eexit_1;
+
+	/* At this point it is safe to free the eventpoll item */
+	ep_release_epitem(epi);
+
+	error = 0;
+eexit_1:
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_remove(%p, %p) = %d\n",
+		     current, ep, epi->file, error));
+
+	return error;
+}
+
+
+/*
+ * This is the callback that is passed to the wait queue wakeup
+ * machanism. It is called by the stored file descriptors when they
+ * have events to report.
+ */
+static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync)
+{
+	int pwake = 0;
+	unsigned long flags;
+	struct epitem *epi = EP_ITEM_FROM_WAIT(wait);
+	struct eventpoll *ep = epi->ep;
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: poll_callback(%p) epi=%p ep=%p\n",
+		     current, epi->file, epi, ep));
+
+	write_lock_irqsave(&ep->lock, flags);
+
+	/* If this file is already in the ready list we exit soon */
+	if (EP_IS_LINKED(&epi->rdllink))
+		goto is_linked;
+
+	list_add_tail(&epi->rdllink, &ep->rdllist);
+
+is_linked:
+	/*
+	 * Wake up ( if active ) both the eventpoll wait list and the ->poll()
+	 * wait list.
+	 */
+	if (waitqueue_active(&ep->wq))
+		wake_up(&ep->wq);
+	if (waitqueue_active(&ep->poll_wait))
+		pwake++;
+
+	write_unlock_irqrestore(&ep->lock, flags);
+
+	/* We have to call this outside the lock */
+	if (pwake)
+		ep_poll_safewake(&psw, &ep->poll_wait);
+
+	return 1;
+}
+
+
+static int ep_eventpoll_close(struct inode *inode, struct file *file)
+{
+	struct eventpoll *ep = file->private_data;
+
+	if (ep) {
+		ep_free(ep);
+		kfree(ep);
+	}
+
+	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: close() ep=%p\n", current, ep));
+	return 0;
+}
+
+
+static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait)
+{
+	unsigned int pollflags = 0;
+	unsigned long flags;
+	struct eventpoll *ep = file->private_data;
+
+	/* Insert inside our poll wait queue */
+	poll_wait(file, &ep->poll_wait, wait);
+
+	/* Check our condition */
+	read_lock_irqsave(&ep->lock, flags);
+	if (!list_empty(&ep->rdllist))
+		pollflags = POLLIN | POLLRDNORM;
+	read_unlock_irqrestore(&ep->lock, flags);
+
+	return pollflags;
+}
+
+
+/*
+ * Since we have to release the lock during the __copy_to_user() operation and
+ * during the f_op->poll() call, we try to collect the maximum number of items
+ * by reducing the irqlock/irqunlock switching rate.
+ */
+static int ep_collect_ready_items(struct eventpoll *ep, struct epitem **aepi, int maxepi)
+{
+	int nepi;
+	unsigned long flags;
+	struct list_head *lsthead = &ep->rdllist;
+
+	write_lock_irqsave(&ep->lock, flags);
+
+	for (nepi = 0; nepi < maxepi && !list_empty(lsthead);) {
+		struct epitem *epi = list_entry(lsthead->next, struct epitem, rdllink);
+
+		/* Remove the item from the ready list */
+		EP_LIST_DEL(&epi->rdllink);
+
+		/*
+		 * We need to increase the usage count of the "struct epitem" because
+		 * another thread might call EPOLL_CTL_DEL on this target and make the
+		 * object to vanish underneath our nose.
+		 */
+		ep_use_epitem(epi);
+
+		aepi[nepi++] = epi;
+	}
+
+	write_unlock_irqrestore(&ep->lock, flags);
+
+	return nepi;
+}
+
+
+/*
+ * This function is called without holding the "ep->lock" since the call to
+ * __copy_to_user() might sleep, and also f_op->poll() might reenable the IRQ
+ * because of the way poll() is traditionally implemented in Linux.
+ */
+static int ep_send_events(struct eventpoll *ep, struct epitem **aepi, int nepi,
+			  struct epoll_event *events)
+{
+	int i, eventcnt, eventbuf, revents;
+	struct epitem *epi;
+	struct epoll_event event[EP_MAX_BUF_EVENTS];
+
+	for (i = 0, eventcnt = 0, eventbuf = 0; i < nepi; i++, aepi++) {
+		epi = *aepi;
+
+		/* Get the ready file event set */
+		revents = epi->file->f_op->poll(epi->file, NULL);
+
+		if (revents & epi->event.events) {
+			event[eventbuf] = epi->event;
+			event[eventbuf].events &= revents;
+			eventbuf++;
+			if (eventbuf == EP_MAX_BUF_EVENTS) {
+				if (__copy_to_user(&events[eventcnt], event,
+						   eventbuf * sizeof(struct epoll_event))) {
+					for (; i < nepi; i++, aepi++)
+						ep_release_epitem(*aepi);
+					return -EFAULT;
+				}
+				eventcnt += eventbuf;
+				eventbuf = 0;
+			}
+		}
+
+		ep_release_epitem(epi);
+	}
+
+	if (eventbuf) {
+		if (__copy_to_user(&events[eventcnt], event,
+				   eventbuf * sizeof(struct epoll_event)))
+			return -EFAULT;
+		eventcnt += eventbuf;
+	}
+
+	return eventcnt;
+}
+
+
+/*
+ * Perform the transfer of events to user space.
+ */
+static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events, int maxevents)
+{
+	int eventcnt, nepi, sepi, maxepi;
+	struct epitem *aepi[EP_MAX_COLLECT_ITEMS];
+
+	/*
+	 * We need to lock this because we could be hit by
+	 * eventpoll_release() while we're transfering
+	 * events to userspace. Read-holding "epsem" will lock
+	 * out eventpoll_release() during the whole
+	 * transfer loop and this will garantie us that the
+	 * file will not vanish underneath our nose when
+	 * we will call f_op->poll() from ep_send_events().
+	 */
+	down_read(&epsem);
+
+	for (eventcnt = 0; eventcnt < maxevents;) {
+		/* Maximum items we can extract this time */
+		maxepi = min(EP_MAX_COLLECT_ITEMS, maxevents - eventcnt);
+
+		/* Collect/extract ready items */
+		nepi = ep_collect_ready_items(ep, aepi, maxepi);
+
+		if (nepi) {
+			/* Send events to userspace */
+			sepi = ep_send_events(ep, aepi, nepi, &events[eventcnt]);
+			if (sepi < 0) {
+				up_read(&epsem);
+				return sepi;
+			}
+			eventcnt += sepi;
+		}
+
+		if (nepi < maxepi)
+			break;
+	}
+
+	up_read(&epsem);
+
+	return eventcnt;
+}
+
+
+static int ep_poll(struct eventpoll *ep, struct epoll_event *events, int maxevents,
+		   int timeout)
+{
+	int res, eavail;
+	unsigned long flags;
+	long jtimeout;
+	wait_queue_t wait;
+
+	/*
+	 * Calculate the timeout by checking for the "infinite" value ( -1 ).
+	 * The passed timeout is in milliseconds, that why (t * HZ) / 1000.
+	 */
+	jtimeout = timeout == -1 ? MAX_SCHEDULE_TIMEOUT: (timeout * HZ) / 1000;
+
+retry:
+	write_lock_irqsave(&ep->lock, flags);
+
+	res = 0;
+	if (list_empty(&ep->rdllist)) {
+		/*
+		 * We don't have any available event to return to the caller.
+		 * We need to sleep here, and we will be wake up by
+		 * ep_poll_callback() when events will become available.
+		 */
+		init_waitqueue_entry(&wait, current);
+		add_wait_queue(&ep->wq, &wait);
+
+		for (;;) {
+			/*
+			 * We don't want to sleep if the ep_poll_callback() sends us
+			 * a wakeup in between. That's why we set the task state
+			 * to TASK_INTERRUPTIBLE before doing the checks.
+			 */
+			set_current_state(TASK_INTERRUPTIBLE);
+			if (!list_empty(&ep->rdllist) || !jtimeout)
+				break;
+			if (signal_pending(current)) {
+				res = -EINTR;
+				break;
+			}
+
+			write_unlock_irqrestore(&ep->lock, flags);
+			jtimeout = schedule_timeout(jtimeout);
+			write_lock_irqsave(&ep->lock, flags);
+		}
+		remove_wait_queue(&ep->wq, &wait);
+
+		set_current_state(TASK_RUNNING);
+	}
+
+	/* Is it worth to try to dig for events ? */
+	eavail = !list_empty(&ep->rdllist);
+
+	write_unlock_irqrestore(&ep->lock, flags);
+
+	/*
+	 * Try to transfer events to user space. In case we get 0 events and
+	 * there's still timeout left over, we go trying again in search of
+	 * more luck.
+	 */
+	if (!res && eavail &&
+	    !(res = ep_events_transfer(ep, events, maxevents)) && jtimeout)
+		goto retry;
+
+	return res;
+}
+
+
+static int eventpollfs_delete_dentry(struct dentry *dentry)
+{
+
+	return 1;
+}
+
+
+static struct inode *ep_eventpoll_inode(void)
+{
+	int error = -ENOMEM;
+	struct inode *inode = new_inode(eventpoll_mnt->mnt_sb);
+
+	if (!inode)
+		goto eexit_1;
+
+	inode->i_fop = &eventpoll_fops;
+
+	/*
+	 * Mark the inode dirty from the very beginning,
+	 * that way it will never be moved to the dirty
+	 * list because mark_inode_dirty() will think
+	 * that it already _is_ on the dirty list.
+	 */
+	inode->i_state = I_DIRTY;
+	inode->i_mode = S_IRUSR | S_IWUSR;
+	inode->i_uid = current->fsuid;
+	inode->i_gid = current->fsgid;
+	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_blksize = PAGE_SIZE;
+	return inode;
+
+eexit_1:
+	return ERR_PTR(error);
+}
+
+
+static int __init eventpoll_init(void)
+{
+	int error;
+
+	/* Initialize the semaphore used to syncronize the file cleanup code */
+	init_rwsem(&epsem);
+
+	/* Initialize the structure used to perform safe poll wait head wake ups */
+	ep_poll_safewake_init(&psw);
+
+	/* Allocates slab cache used to allocate "struct epitem" items */
+	error = -ENOMEM;
+	epi_cache = kmem_cache_create("eventpoll epi",
+				      sizeof(struct epitem),
+				      0,
+				      SLAB_HWCACHE_ALIGN | EPI_SLAB_DEBUG, NULL, NULL);
+	if (!epi_cache)
+		goto eexit_1;
+
+	/* Allocates slab cache used to allocate "struct eppoll_entry" */
+	error = -ENOMEM;
+	pwq_cache = kmem_cache_create("eventpoll pwq",
+				      sizeof(struct eppoll_entry),
+				      0,
+				      EPI_SLAB_DEBUG, NULL, NULL);
+	if (!pwq_cache)
+		goto eexit_2;
+
+	/*
+	 * Register the virtual file system that will be the source of inodes
+	 * for the eventpoll files
+	 */
+	error = register_filesystem(&eventpoll_fs_type);
+	if (error)
+		goto eexit_3;
+
+	/* Mount the above commented virtual file system */
+	eventpoll_mnt = kern_mount(&eventpoll_fs_type);
+	error = PTR_ERR(eventpoll_mnt);
+	if (IS_ERR(eventpoll_mnt))
+		goto eexit_4;
+
+	return 0;
+
+eexit_4:
+	unregister_filesystem(&eventpoll_fs_type);
+eexit_3:
+	kmem_cache_destroy(pwq_cache);
+eexit_2:
+	kmem_cache_destroy(epi_cache);
+eexit_1:
+
+	return error;
+}
+
+
+static void __exit eventpoll_exit(void)
+{
+	/* Undo all operations done inside eventpoll_init() */
+	unregister_filesystem(&eventpoll_fs_type);
+	mntput(eventpoll_mnt);
+	kmem_cache_destroy(pwq_cache);
+	kmem_cache_destroy(epi_cache);
+}
+
+module_init(eventpoll_init);
+module_exit(eventpoll_exit);
+
+MODULE_LICENSE("GPL");
+
--- linux-2.4.20/fs/file_table.c	Thu Nov 28 15:53:15 2002
+++ sys_epoll/fs/file_table.c	Mon Dec 16 16:24:04 2002
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/smp_lock.h>
 #include <linux/iobuf.h>
+#include <linux/eventpoll.h>
 
 /* sysctl tunables... */
 struct files_stat_struct files_stat = {0, 0, NR_FILE};
@@ -42,6 +43,7 @@
 		files_stat.nr_free_files--;
 	new_one:
 		memset(f, 0, sizeof(*f));
+		eventpoll_init_file(f);
 		atomic_set(&f->f_count,1);
 		f->f_version = ++event;
 		f->f_uid = current->fsuid;
@@ -85,6 +87,7 @@
 int init_private_file(struct file *filp, struct dentry *dentry, int mode)
 {
 	memset(filp, 0, sizeof(*filp));
+	eventpoll_init_file(filp);
 	filp->f_mode   = mode;
 	atomic_set(&filp->f_count, 1);
 	filp->f_dentry = dentry;
@@ -104,6 +107,11 @@
 	struct inode * inode = dentry->d_inode;
 
 	if (atomic_dec_and_test(&file->f_count)) {
+		/*
+	 	 * The function eventpoll_release() should be the 
+	 	 * first called in the file cleanup chain.
+	 	 */
+		eventpoll_release(file);
 		locks_remove_flock(file);
 
 		if (file->f_iobuf)
--- linux-2.4.20/fs/select.c	Mon Sep 10 13:04:33 2001
+++ sys_epoll/fs/select.c	Mon Dec 16 16:24:04 2002
@@ -19,6 +19,7 @@
 #include <linux/poll.h>
 #include <linux/personality.h> /* for STICKY_TIMEOUTS */
 #include <linux/file.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 
@@ -52,10 +53,18 @@
  * as all select/poll functions have to call it to add an entry to the
  * poll table.
  */
+void __pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p);
 
-void poll_freewait(poll_table* pt)
+void poll_initwait(struct poll_wqueues *pwq)
 {
-	struct poll_table_page * p = pt->table;
+	init_poll_funcptr(&pwq->pt, __pollwait);
+	pwq->error = 0;
+	pwq->table = NULL;
+}
+
+void poll_freewait(struct poll_wqueues *pwq)
+{
+	struct poll_table_page * p = pwq->table;
 	while (p) {
 		struct poll_table_entry * entry;
 		struct poll_table_page *old;
@@ -72,8 +81,9 @@
 	}
 }
 
-void __pollwait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
+void __pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *_p)
 {
+	struct poll_wqueues *p = container_of(_p, struct poll_wqueues, pt);
 	struct poll_table_page *table = p->table;
 
 	if (!table || POLL_TABLE_FULL(table)) {
@@ -103,6 +113,7 @@
 	}
 }
 
+
 #define __IN(fds, n)		(fds->in + n)
 #define __OUT(fds, n)		(fds->out + n)
 #define __EX(fds, n)		(fds->ex + n)
@@ -163,7 +174,8 @@
 
 int do_select(int n, fd_set_bits *fds, long *timeout)
 {
-	poll_table table, *wait;
+	struct poll_wqueues table;
+	poll_table *wait;
 	int retval, i, off;
 	long __timeout = *timeout;
 
@@ -176,7 +188,7 @@
 	n = retval;
 
 	poll_initwait(&table);
-	wait = &table;
+	wait = &table.pt;
 	if (!__timeout)
 		wait = NULL;
 	retval = 0;
@@ -383,10 +395,10 @@
 }
 
 static int do_poll(unsigned int nfds, unsigned int nchunks, unsigned int nleft, 
-	struct pollfd *fds[], poll_table *wait, long timeout)
+	struct pollfd *fds[], struct poll_wqueues *wait, long timeout)
 {
 	int count;
-	poll_table* pt = wait;
+	poll_table* pt = &wait->pt;
 
 	for (;;) {
 		unsigned int i;
@@ -413,7 +425,7 @@
 {
 	int i, j, fdcount, err;
 	struct pollfd **fds;
-	poll_table table, *wait;
+	struct poll_wqueues table, *wait;
 	int nchunks, nleft;
 
 	/* Do a sanity check on nfds ... */
--- linux-2.4.20/include/asm-i386/unistd.h	Thu Nov 28 15:53:15 2002
+++ sys_epoll/include/asm-i386/unistd.h	Mon Dec 16 16:24:04 2002
@@ -257,6 +257,10 @@
 #define __NR_alloc_hugepages	250
 #define __NR_free_hugepages	251
 #define __NR_exit_group		252
+#define __NR_epoll_create	254
+#define __NR_epoll_ctl		255
+#define __NR_epoll_wait		256
+
 
 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
 
--- linux-2.4.20/include/asm-ppc/unistd.h	Thu Nov 28 15:53:15 2002
+++ sys_epoll/include/asm-ppc/unistd.h	Mon Dec 16 16:24:04 2002
@@ -241,6 +241,9 @@
 #define __NR_io_submit		230
 #define __NR_io_cancel		231
 #endif
+#define __NR_epoll_create   	254
+#define __NR_epoll_ctl      	255
+#define __NR_epoll_wait     	256
 
 #define __NR(n)	#n
 
--- linux-2.4.20/include/linux/eventpoll.h	Wed Dec 31 16:00:00 1969
+++ sys_epoll/include/linux/eventpoll.h	Mon Dec 16 16:24:04 2002
@@ -0,0 +1,49 @@
+/*
+ *  include/linux/eventpoll.h ( Efficent event polling implementation )
+ *  Copyright (C) 2001,...,2002	 Davide Libenzi
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#ifndef _LINUX_EVENTPOLL_H
+#define _LINUX_EVENTPOLL_H
+
+
+/* Valid opcodes to issue to sys_epoll_ctl() */
+#define EPOLL_CTL_ADD 1
+#define EPOLL_CTL_DEL 2
+#define EPOLL_CTL_MOD 3
+
+struct epoll_event {
+	__u32 events;
+	__u64 data;
+};
+
+#ifdef __KERNEL__
+
+/* Forward declarations to avoid compiler errors */
+struct file;
+
+
+/* Kernel space functions implementing the user space "epoll" API */
+asmlinkage int sys_epoll_create(int size);
+asmlinkage int sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
+asmlinkage int sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
+			      int timeout);
+
+/* Used to initialize the epoll bits inside the "struct file" */
+void eventpoll_init_file(struct file *file);
+
+/* Used in fs/file_table.c:__fput() to unlink files from the eventpoll interface */
+void eventpoll_release(struct file *file);
+
+#endif /* #ifdef __KERNEL__ */
+
+#endif /* #ifndef _LINUX_EVENTPOLL_H */
+
--- linux-2.4.20/include/linux/fs.h	Thu Nov 28 15:53:15 2002
+++ sys_epoll/include/linux/fs.h	Mon Dec 16 16:24:04 2002
@@ -542,6 +542,8 @@
 	/* preallocated helper kiobuf to speedup O_DIRECT */
 	struct kiobuf		*f_iobuf;
 	long			f_iobuf_lock;
+	struct list_head	f_ep_links;
+	spinlock_t		f_ep_lock;
 };
 extern spinlock_t files_lock;
 #define file_list_lock() spin_lock(&files_lock);
--- linux-2.4.20/include/linux/hash.h	Wed Dec 31 16:00:00 1969
+++ sys_epoll/include/linux/hash.h	Mon Dec 16 16:24:04 2002
@@ -0,0 +1,58 @@
+#ifndef _LINUX_HASH_H
+#define _LINUX_HASH_H
+/* Fast hashing routine for a long.
+   (C) 2002 William Lee Irwin III, IBM */
+
+/*
+ * Knuth recommends primes in approximately golden ratio to the maximum
+ * integer representable by a machine word for multiplicative hashing.
+ * Chuck Lever verified the effectiveness of this technique:
+ * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf
+ *
+ * These primes are chosen to be bit-sparse, that is operations on
+ * them can use shifts and additions instead of multiplications for
+ * machines where multiplications are slow.
+ */
+#if BITS_PER_LONG == 32
+/* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
+#define GOLDEN_RATIO_PRIME 0x9e370001UL
+#elif BITS_PER_LONG == 64
+/*  2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */
+#define GOLDEN_RATIO_PRIME 0x9e37fffffffc0001UL
+#else
+#error Define GOLDEN_RATIO_PRIME for your wordsize.
+#endif
+
+static inline unsigned long hash_long(unsigned long val, unsigned int bits)
+{
+	unsigned long hash = val;
+
+#if BITS_PER_LONG == 64
+	/*  Sigh, gcc can't optimise this alone like it does for 32 bits. */
+	unsigned long n = hash;
+	n <<= 18;
+	hash -= n;
+	n <<= 33;
+	hash -= n;
+	n <<= 3;
+	hash += n;
+	n <<= 3;
+	hash -= n;
+	n <<= 4;
+	hash += n;
+	n <<= 2;
+	hash += n;
+#else
+	/* On some cpus multiply is faster, on others gcc will do shifts */
+	hash *= GOLDEN_RATIO_PRIME;
+#endif
+
+	/* High bits are more random, so use them. */
+	return hash >> (BITS_PER_LONG - bits);
+}
+	
+static inline unsigned long hash_ptr(void *ptr, unsigned int bits)
+{
+	return hash_long((unsigned long)ptr, bits);
+}
+#endif /* _LINUX_HASH_H */
--- linux-2.4.20/include/linux/kernel.h	Thu Nov 28 15:53:15 2002
+++ sys_epoll/include/linux/kernel.h	Mon Dec 16 16:24:04 2002
@@ -174,6 +174,18 @@
 extern void __out_of_line_bug(int line) ATTRIB_NORET;
 #define out_of_line_bug() __out_of_line_bug(__LINE__)
 
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ *
+ * @ptr:        the pointer to the member.
+ * @type:       the type of the container struct this is embedded in.
+ * @member:     the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({                      \
+	const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+	(type *)( (char *)__mptr - offsetof(type,member) );})
+
 #endif /* __KERNEL__ */
 
 #define SI_LOAD_SHIFT	16
--- linux-2.4.20/include/linux/poll.h	Thu Nov 22 11:46:26 2001
+++ sys_epoll/include/linux/poll.h	Mon Dec 16 16:24:04 2002
@@ -10,28 +10,39 @@
 #include <linux/mm.h>
 #include <asm/uaccess.h>
 
-struct poll_table_page;
+struct poll_table_struct;
+
+/* 
+ * structures and helpers for f_op->poll implementations
+ */
+typedef void (*poll_queue_proc)(struct file *, wait_queue_head_t *, struct poll_table_struct *);
 
 typedef struct poll_table_struct {
-	int error;
-	struct poll_table_page * table;
+	poll_queue_proc qproc;
 } poll_table;
 
-extern void __pollwait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p);
-
 static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
 {
 	if (p && wait_address)
-		__pollwait(filp, wait_address, p);
+		p->qproc(filp, wait_address, p);
 }
 
-static inline void poll_initwait(poll_table* pt)
+static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc)
 {
-	pt->error = 0;
-	pt->table = NULL;
+	pt->qproc = qproc;
 }
-extern void poll_freewait(poll_table* pt);
 
+/*
+ * Structures and helpers for sys_poll/sys_poll
+ */
+struct poll_wqueues {
+	poll_table pt;
+	struct poll_table_page * table;
+	int error;
+};
+
+extern void poll_initwait(struct poll_wqueues *pwq);
+extern void poll_freewait(struct poll_wqueues *pwq);
 
 /*
  * Scaleable version of the fd_set.
--- linux-2.4.20/include/linux/sched.h	Thu Nov 28 15:53:15 2002
+++ sys_epoll/include/linux/sched.h	Mon Dec 16 16:24:04 2002
@@ -145,6 +145,8 @@
 extern spinlock_t runqueue_lock;
 extern spinlock_t mmlist_lock;
 
+typedef struct task_struct task_t;
+
 extern void sched_init(void);
 extern void init_idle(void);
 extern void show_state(void);
--- linux-2.4.20/include/linux/sys.h	Sun Dec 10 20:56:37 1995
+++ sys_epoll/include/linux/sys.h	Mon Dec 16 16:24:04 2002
@@ -4,7 +4,7 @@
 /*
  * system call entry points ... but not all are defined
  */
-#define NR_syscalls 256
+#define NR_syscalls 260 
 
 /*
  * These are system calls that will be removed at some time
--- linux-2.4.20/include/linux/wait.h	Thu Nov 22 11:46:19 2001
+++ sys_epoll/include/linux/wait.h	Mon Dec 16 16:24:04 2002
@@ -19,6 +19,9 @@
 #include <asm/page.h>
 #include <asm/processor.h>
 
+typedef struct __wait_queue wait_queue_t;
+typedef void (*wait_queue_func_t)(wait_queue_t *wait);
+
 /*
  * Debug control.  Slow but useful.
  */
@@ -32,13 +35,13 @@
 	unsigned int flags;
 #define WQ_FLAG_EXCLUSIVE	0x01
 	struct task_struct * task;
+	wait_queue_func_t func;
 	struct list_head task_list;
 #if WAITQUEUE_DEBUG
 	long __magic;
 	long __waker;
 #endif
 };
-typedef struct __wait_queue wait_queue_t;
 
 /*
  * 'dual' spinlock architecture. Can be switched between spinlock_t and
@@ -138,6 +141,7 @@
 
 #define __WAITQUEUE_INITIALIZER(name, tsk) {				\
 	task:		tsk,						\
+	func:		NULL,						\
 	task_list:	{ NULL, NULL },					\
 			 __WAITQUEUE_DEBUG_INIT(name)}
 
@@ -174,10 +178,18 @@
 #endif
 	q->flags = 0;
 	q->task = p;
+	q->func = NULL;
 #if WAITQUEUE_DEBUG
 	q->__magic = (long)&q->__magic;
 #endif
 }
+static inline void init_waitqueue_func_entry(wait_queue_t *q,
+					wait_queue_func_t func)
+{
+	q->flags = 0;
+	q->task = NULL;
+	q->func = func;
+}                      
 
 static inline int waitqueue_active(wait_queue_head_t *q)
 {
@@ -189,6 +201,22 @@
 
 	return !list_empty(&q->task_list);
 }
+#define add_wait_queue_cond(q, wait, cond) \
+	({                                                      \
+		unsigned long flags;                            \
+		int _raced = 0;                                 \
+		wq_write_lock_irqsave(&(q)->lock, flags);       \
+		(wait)->flags = 0;                              \
+		__add_wait_queue((q), (wait));                  \
+		rmb();                                          \
+		if (!(cond)) {                                  \
+			_raced = 1;                             \
+			__remove_wait_queue((q), (wait));       \
+		}                                               \
+		wq_write_unlock_irqrestore(&(q)->lock, flags);  \
+		_raced;                                         \
+	})
+
 
 static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
 {
--- linux-2.4.20/kernel/ksyms.c	Thu Nov 28 15:53:15 2002
+++ sys_epoll/kernel/ksyms.c	Mon Dec 16 16:24:04 2002
@@ -257,7 +257,7 @@
 EXPORT_SYMBOL(generic_read_dir);
 EXPORT_SYMBOL(generic_file_llseek);
 EXPORT_SYMBOL(no_llseek);
-EXPORT_SYMBOL(__pollwait);
+EXPORT_SYMBOL(poll_initwait);
 EXPORT_SYMBOL(poll_freewait);
 EXPORT_SYMBOL(ROOT_DEV);
 EXPORT_SYMBOL(__find_get_page);
--- linux-2.4.20/kernel/sched.c	Thu Nov 28 15:53:15 2002
+++ sys_epoll/kernel/sched.c	Mon Dec 16 16:24:04 2002
@@ -714,16 +714,24 @@
 static inline void __wake_up_common (wait_queue_head_t *q, unsigned int mode,
 			 	     int nr_exclusive, const int sync)
 {
-	struct list_head *tmp;
+	struct list_head *tmp, *next;
 	struct task_struct *p;
 
 	CHECK_MAGIC_WQHEAD(q);
 	WQ_CHECK_LIST_HEAD(&q->task_list);
 	
-	list_for_each(tmp,&q->task_list) {
+	list_for_each_safe(tmp, next, &q->task_list) {
 		unsigned int state;
+		wait_queue_func_t func;
                 wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list);
-
+		func = curr->func;
+		if (func) {
+			unsigned flags = curr->flags;
+			func(curr);
+			if ((flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
+				break;
+			continue;
+		}
 		CHECK_MAGIC(curr->__magic);
 		p = curr->task;
 		state = p->state;
--- linux-2.4.20/fs/smbfs/sock.c	Thu Nov 28 15:53:15 2002
+++ sys_epoll/fs/smbfs/sock.c	Mon Dec 16 16:24:29 2002
@@ -314,16 +314,18 @@
 smb_receive_poll(struct smb_sb_info *server)
 {
 	struct file *file = server->sock_file;
-	poll_table wait_table;
+	struct poll_wqueues wait_table;
+	poll_table *wait;
 	int result = 0;
 	int timeout = server->mnt->timeo * HZ;
 	int mask;
 
 	for (;;) {
 		poll_initwait(&wait_table);
+		wait = &wait_table.pt;
                 set_current_state(TASK_INTERRUPTIBLE);
 
-		mask = file->f_op->poll(file, &wait_table);
+		mask = file->f_op->poll(file, wait);
 		if (mask & POLLIN) {
 			poll_freewait(&wait_table);
 			current->state = TASK_RUNNING;
--- linux-2.4.20/fs/ncpfs/sock.c	Sat Jan 20 08:51:51 2001
+++ sys_epoll/fs/ncpfs/sock.c	Mon Dec 16 16:24:29 2002
@@ -86,7 +86,8 @@
 	struct socket *sock;
 	int result;
 	char *start = server->packet;
-	poll_table wait_table;
+	struct poll_wqueues wait_table;
+	poll_table *wait;
 	int init_timeout, max_timeout;
 	int timeout;
 	int retrans;
@@ -136,11 +137,12 @@
 		}
 	      re_select:
 		poll_initwait(&wait_table);
+		wait = &wait_table.pt;
 		/* mb() is not necessary because ->poll() will serialize
 		   instructions adding the wait_table waitqueues in the
 		   waitqueue-head before going to calculate the mask-retval. */
 		__set_current_state(TASK_INTERRUPTIBLE);
-		if (!(sock->ops->poll(file, sock, &wait_table) & POLLIN)) {
+		if (!(sock->ops->poll(file, sock, wait) & POLLIN)) {
 			int timed_out;
 			if (timeout > max_timeout) {
 				/* JEJB/JSP 2/7/94
@@ -261,7 +263,8 @@
 }
 
 static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len) {
-	poll_table wait_table;
+	struct poll_wqueues wait_table;
+	poll_table *wait;
 	struct file *file;
 	struct socket *sock;
 	int init_timeout;
@@ -281,11 +284,12 @@
 
 	while (len) {
 		poll_initwait(&wait_table);
+		wait = &wait_table.pt;
 		/* mb() is not necessary because ->poll() will serialize
 		   instructions adding the wait_table waitqueues in the
 		   waitqueue-head before going to calculate the mask-retval. */
 		__set_current_state(TASK_INTERRUPTIBLE);
-		if (!(sock->ops->poll(file, sock, &wait_table) & POLLIN)) {
+		if (!(sock->ops->poll(file, sock, wait) & POLLIN)) {
 			init_timeout = schedule_timeout(init_timeout);
 			poll_freewait(&wait_table);
 			current->state = TASK_RUNNING;

^ permalink raw reply

* [PATCH] kNFSd - 4 of 7 - Remove irrelevant warning in svc_write_space
From: NeilBrown @ 2002-12-17  1:59 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: nfs



tcp recv_msg sometimes activates the socket waitqueue
even though it isn't actually going to wait.
So printing out a warning message when the
waitqueue appears active is not appropriate now that
we support TCP.

 ----------- Diffstat output ------------
 ./net/sunrpc/svcsock.c |    5 +----
 1 files changed, 1 insertion(+), 4 deletions(-)

diff ./net/sunrpc/svcsock.c~current~ ./net/sunrpc/svcsock.c
--- ./net/sunrpc/svcsock.c~current~	2002-12-16 16:29:42.000000000 +1100
+++ ./net/sunrpc/svcsock.c	2002-12-16 16:29:42.000000000 +1100
@@ -461,11 +461,8 @@ svc_write_space(struct sock *sk)
 		svc_sock_enqueue(svsk);
 	}
 
-	if (sk->sleep && waitqueue_active(sk->sleep)) {
-		printk(KERN_WARNING "RPC svc_write_space: some sleeping on %p\n",
-		       svsk);
+	if (sk->sleep && waitqueue_active(sk->sleep))
 		wake_up_interruptible(sk->sleep);
-	}
 }
 
 /*


-------------------------------------------------------
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/
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply

* [PATCH] kNFSd - 2 of 7 - Revlaidate inodes after filehandle and name lookup in nfsd
From: NeilBrown @ 2002-12-17  1:59 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: nfs



The patch was written by Marc Eshel and Frank Schmuck. 
It was received from  "Brian Dixon" <dixonbp@us.ibm.com>
though I changed it slightly.

 ----------- Diffstat output ------------
 ./fs/nfsd/nfsfh.c |    7 +++++++
 ./fs/nfsd/vfs.c   |   12 +++++++-----
 2 files changed, 14 insertions(+), 5 deletions(-)

diff ./fs/nfsd/nfsfh.c~current~ ./fs/nfsd/nfsfh.c
--- ./fs/nfsd/nfsfh.c~current~	2002-12-16 16:28:47.000000000 +1100
+++ ./fs/nfsd/nfsfh.c	2002-12-16 16:28:47.000000000 +1100
@@ -620,6 +620,13 @@ fh_verify(struct svc_rqst *rqstp, struct
 			switch (fh->fh_fileid_type) {
 			case 0:
 				dentry = dget(exp->ex_dentry);
+				/* need to revalidate the inode */
+				inode = dentry->d_inode;
+				if (inode->i_op && inode->i_op->revalidate)
+					if (inode->i_op->revalidate(dentry)) {
+						dput(dentry);
+						dentry = ERR_PTR(-ESTALE);
+					}
 				break;
 			default:
 				dentry = find_fh_dentry(exp->ex_dentry->d_inode->i_sb,

diff ./fs/nfsd/vfs.c~current~ ./fs/nfsd/vfs.c
--- ./fs/nfsd/vfs.c~current~	2002-12-16 16:28:47.000000000 +1100
+++ ./fs/nfsd/vfs.c	2002-12-16 16:28:47.000000000 +1100
@@ -168,11 +168,13 @@ nfsd_lookup(struct svc_rqst *rqstp, stru
 			mntput(mnt);
 		}
 	}
-	/*
-	 * Note: we compose the file handle now, but as the
-	 * dentry may be negative, it may need to be updated.
-	 */
-	err = fh_compose(resfh, exp, dentry, fhp);
+
+	if (dentry->d_inode && dentry->d_inode->i_op &&
+	    dentry->d_inode->i_op->revalidate &&
+	    dentry->d_inode->i_op->revalidate(dentry))
+		err = nfserr_noent;
+	else
+		err = fh_compose(resfh, exp, dentry, fhp);
 	if (!err && !dentry->d_inode)
 		err = nfserr_noent;
 out:


-------------------------------------------------------
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/
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply

* [PATCH] kNFSd - 5 of 7 - Fix problem with lockd grace period checking.
From: NeilBrown @ 2002-12-17  1:59 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: nfs



We need to do the clear/grace period here and not before
svc_recv() because svc_recv() may sleep longer than the
grace period and the first request may be falsely processed
as if the server was in the grace period when it was not
causing unnecessary delays for the first request received.
     * Juan C. Gomez j_carlos_gome@yahoo.com

Also opencode trivial clear_grace_period function.

 ----------- Diffstat output ------------
 ./fs/lockd/svc.c |   12 ++++--------
 1 files changed, 4 insertions(+), 8 deletions(-)

diff ./fs/lockd/svc.c~current~ ./fs/lockd/svc.c
--- ./fs/lockd/svc.c~current~	2002-12-16 16:29:58.000000000 +1100
+++ ./fs/lockd/svc.c	2002-12-16 16:29:59.000000000 +1100
@@ -72,11 +72,6 @@ static unsigned long set_grace_period(vo
 	return grace_period + jiffies;
 }
 
-static inline void clear_grace_period(void)
-{
-	nlmsvc_grace_period = 0;
-}
-
 /*
  * This is the lockd kernel thread
  */
@@ -142,10 +137,8 @@ lockd(struct svc_rqst *rqstp)
 		 * (Theoretically, there shouldn't even be blocked locks
 		 * during grace period).
 		 */
-		if (!nlmsvc_grace_period) {
+		if (!nlmsvc_grace_period)
 			timeout = nlmsvc_retry_blocked();
-		} else if (time_before(grace_period_expire, jiffies))
-			clear_grace_period();
 
 		/*
 		 * Find a socket with data available and call its
@@ -175,6 +168,9 @@ lockd(struct svc_rqst *rqstp)
 				nlmsvc_ops->exp_getclient(&rqstp->rq_addr);
 		}
 
+		if (nlmsvc_grace_period &&
+		    time_before(grace_period_expire, jiffies))
+			nlmsvc_grace_period = 0;
 		svc_process(serv, rqstp);
 
 		/* Unlock export hash tables */


-------------------------------------------------------
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/
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply

* [PATCH] kNFSd - 1 of 7 - Release rpc response when dropping request.
From: NeilBrown @ 2002-12-17  1:59 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: nfs


Marcelo, 
 This is the first of 7 smallish nfsd related patches for 2.4.21-pre.
 Thanks, NeilBrown

If a kmalloc failure causes us to have to drop an nfs request,
the ->pc_release function currently isn't called, so
dentries can leak.  This fixes it.

 ----------- Diffstat output ------------
 ./net/sunrpc/svc.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletion(-)

diff ./net/sunrpc/svc.c~current~ ./net/sunrpc/svc.c
--- ./net/sunrpc/svc.c~current~	2002-12-16 16:28:08.000000000 +1100
+++ ./net/sunrpc/svc.c	2002-12-16 16:28:09.000000000 +1100
@@ -333,8 +333,12 @@ svc_process(struct svc_serv *serv, struc
 		}
 	} else {
 		dprintk("svc: calling dispatcher\n");
-		if (!versp->vs_dispatch(rqstp, statp))
+		if (!versp->vs_dispatch(rqstp, statp)) {
+			/* Release reply info */
+			if (procp->pc_release)
+				procp->pc_release(rqstp, NULL, rqstp->rq_resp);
 			goto dropit;
+		}
 	}
 
 	/* Check RPC status result */


-------------------------------------------------------
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/
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply

* [PATCH] kNFSd - 6 of 7 - Correct some error codes reutrned in nfsfh.c
From: NeilBrown @ 2002-12-17  1:59 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: nfs



These error spotted by  "Kendrick M. Smith" <kmsmith@umich.edu>

They aren't very significant as a well-behaved client is
unlikely to make a request that would result in these errors.



 ----------- Diffstat output ------------
 ./fs/nfsd/nfsfh.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff ./fs/nfsd/nfsfh.c~current~ ./fs/nfsd/nfsfh.c
--- ./fs/nfsd/nfsfh.c~current~	2002-12-16 16:30:07.000000000 +1100
+++ ./fs/nfsd/nfsfh.c	2002-12-17 09:50:09.000000000 +1100
@@ -678,11 +678,16 @@ fh_verify(struct svc_rqst *rqstp, struct
 
 	/* Type can be negative to e.g. exclude directories from linking */
 	if (type > 0 && (inode->i_mode & S_IFMT) != type) {
-		error = (type == S_IFDIR)? nfserr_notdir : nfserr_isdir;
+		if (type == S_IFDIR)
+			error = nfserr_notdir;
+		else if ((inode->i_mode & S_IFMT) == S_IFDIR)
+			error = nfserr_isdir;
+		else
+			error = nfserr_inval;
 		goto out;
 	}
 	if (type < 0 && (inode->i_mode & S_IFMT) == -type) {
-		error = (type == -S_IFDIR)? nfserr_notdir : nfserr_isdir;
+		error = (type == -S_IFDIR)? nfserr_isdir : nfserr_notdir;
 		goto out;
 	}
 


-------------------------------------------------------
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/
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply

* [PATCH] kNFSd - 7 of 7 - Ease increasing the max block size for NFS replies.
From: NeilBrown @ 2002-12-17  1:59 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: nfs



This requires making NFSv2 return the right number in statfs
requests.  NFSv3 already does.

The size should really be boot/module option.


 ----------- Diffstat output ------------
 ./fs/nfsd/nfsxdr.c           |    2 +-
 ./include/linux/nfsd/const.h |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff ./fs/nfsd/nfsxdr.c~current~ ./fs/nfsd/nfsxdr.c
--- ./fs/nfsd/nfsxdr.c~current~	2002-12-17 09:50:41.000000000 +1100
+++ ./fs/nfsd/nfsxdr.c	2002-12-17 09:50:41.000000000 +1100
@@ -385,7 +385,7 @@ nfssvc_encode_statfsres(struct svc_rqst 
 {
 	struct statfs	*stat = &resp->stats;
 
-	*p++ = htonl(8 * 1024);		/* max transfer size */
+	*p++ = htonl(NFSSVC_MAXBLKSIZE);	/* max transfer size */
 	*p++ = htonl(stat->f_bsize);
 	*p++ = htonl(stat->f_blocks);
 	*p++ = htonl(stat->f_bfree);

diff ./include/linux/nfsd/const.h~current~ ./include/linux/nfsd/const.h
--- ./include/linux/nfsd/const.h~current~	2002-12-17 09:50:41.000000000 +1100
+++ ./include/linux/nfsd/const.h	2002-12-17 09:50:41.000000000 +1100
@@ -21,7 +21,7 @@
 /*
  * Maximum blocksize supported by daemon currently at 8K
  */
-#define NFSSVC_MAXBLKSIZE	8192
+#define NFSSVC_MAXBLKSIZE	(8*1024)
 
 #ifdef __KERNEL__
 


-------------------------------------------------------
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/
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply

* [PATCH] kNFSd - 3 of 7 - Use correct value for max size for readlink response.
From: NeilBrown @ 2002-12-17  1:59 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: nfs



 ----------- Diffstat output ------------
 ./fs/nfsd/nfs3proc.c |    2 +-
 ./fs/nfsd/nfsproc.c  |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff ./fs/nfsd/nfs3proc.c~current~ ./fs/nfsd/nfs3proc.c
--- ./fs/nfsd/nfs3proc.c~current~	2002-12-16 16:29:23.000000000 +1100
+++ ./fs/nfsd/nfs3proc.c	2002-12-16 16:29:23.000000000 +1100
@@ -672,7 +672,7 @@ struct svc_procedure		nfsd_procedures3[2
   PROC(setattr,  sattr,		wccstat,	fhandle,  RC_REPLBUFF, ST+WC),
   PROC(lookup,	 dirop,		dirop,		fhandle2, RC_NOCACHE, ST+FH+pAT+pAT),
   PROC(access,	 access,	access,		fhandle,  RC_NOCACHE, ST+pAT+1),
-  PROC(readlink, fhandle,	readlink,	fhandle,  RC_NOCACHE, ST+pAT+1+256),
+  PROC(readlink, fhandle,	readlink,	fhandle,  RC_NOCACHE, ST+pAT+1+NFS3_MAXPATHLEN/4),
   PROC(read,	 read,		read,		fhandle, RC_NOCACHE, ST+pAT+4+NFSSVC_MAXBLKSIZE),
   PROC(write,	 write,		write,		fhandle,  RC_REPLBUFF, ST+WC+4),
   PROC(create,	 create,	create,		fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC),

diff ./fs/nfsd/nfsproc.c~current~ ./fs/nfsd/nfsproc.c
--- ./fs/nfsd/nfsproc.c~current~	2002-12-16 16:29:23.000000000 +1100
+++ ./fs/nfsd/nfsproc.c	2002-12-16 16:29:23.000000000 +1100
@@ -545,7 +545,7 @@ struct svc_procedure		nfsd_procedures2[1
   PROC(setattr,  sattrargs,	attrstat,	fhandle,	RC_REPLBUFF, ST+AT),
   PROC(none,	 void,		void,		none,		RC_NOCACHE, ST),
   PROC(lookup,	 diropargs,	diropres,	fhandle,	RC_NOCACHE, ST+FH+AT),
-  PROC(readlink, fhandle,	readlinkres,	none,		RC_NOCACHE, ST+1+256),
+  PROC(readlink, fhandle,	readlinkres,	none,		RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4),
   PROC(read,	 readargs,	readres,	fhandle,	RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE),
   PROC(none,	 void,		void,		none,		RC_NOCACHE, ST),
   PROC(write,	 writeargs,	attrstat,	fhandle,	RC_REPLBUFF, ST+AT),


-------------------------------------------------------
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/
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ 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.