diff options
255 files changed, 2266 insertions, 2362 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index e40aecd5c0a9..3a5eec4d1be8 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -237,7 +237,10 @@ writev: no ->llseek() locking has moved from llseek to the individual llseek implementations. If your fs is not using generic_file_llseek, you -need to acquire and release the BKL in your ->llseek(). +need to acquire and release the appropriate locks in your ->llseek(). +For many filesystems, it is probably safe to acquire the inode +semaphore. Note some filesystems (i.e. remote ones) provide no +protection for i_size so you will need to use the BKL. ->open() locking is in-transit: big lock partially moved into the methods. The only exception is ->open() in the instances of file_operations that never diff --git a/Documentation/usb/ibmcam.txt b/Documentation/usb/ibmcam.txt index 21d07c0ba7d2..ce2f21a3eac4 100644 --- a/Documentation/usb/ibmcam.txt +++ b/Documentation/usb/ibmcam.txt @@ -25,12 +25,19 @@ Supported controls: SUPPORTED CAMERAS: -IBM "C-It" camera, also known as "Xirlink PC Camera" +Xirlink "C-It" camera, also known as "IBM PC Camera". The device uses proprietary ASIC (and compression method); it is manufactured by Xirlink. See http://www.xirlink.com/ http://www.ibmpccamera.com or http://www.c-itnow.com/ for details and pictures. +This very chipset ("X Chip", as marked at the factory) +is used in several other cameras, and they are supported +as well: + +- IBM NetCamera +- Veo Stingray + The Linux driver was developed with camera with following model number (or FCC ID): KSX-XVP510. This camera has three interfaces, each with one endpoint (control, iso, iso). This @@ -50,12 +57,30 @@ These cameras have two interfaces, one endpoint in each (iso, bulk). Such type of cameras is referred to as "model 2". They are supported (with exception of 352x288 native mode). +Some IBM NetCameras (Model 4) are made to generate only compressed +video streams. This is great for performance, but unfortunately +nobody knows how to decompress the stream :-( Therefore, these +cameras are *unsupported* and if you try to use one of those, all +you get is random colored horizontal streaks, not the image! +If you have one of those cameras, you probably should return it +to the store and get something that is supported. + +Tell me more about all that "model" business +-------------------------------------------- + +I just invented model numbers to uniquely identify flavors of the +hardware/firmware that were sold. It was very confusing to use +brand names or some other internal numbering schemes. So I found +by experimentation that all Xirlink chipsets fall into four big +classes, and I called them "models". Each model is programmed in +its own way, and each model sends back the video in its own way. + Quirks of Model 2 cameras: ------------------------- Model 2 does not have hardware contrast control. Corresponding V4L -control is not used at the moment. It may be possible to implement -contrast control in software, at cost of extra processor cycles. +control is implemented in software, which is not very nice to your +CPU, but at least it works. This driver provides 352x288 mode by switching the camera into quasi-352x288 RGB mode (800 Kbits per frame) essentially limiting @@ -67,17 +92,24 @@ be good at one brightness and broken at another! I did not want to fix the frame rate at slowest setting, but I had to move it pretty much down the scale (so that framerate option barely matters). I also noticed that camera after first powering up produces frames slightly faster than during -consecutive uses. All this means that if you use videosize=2 (which is +consecutive uses. All this means that if you use 352x288 (which is default), be warned - you may encounter broken picture on first connect; try to adjust brightness - brighter image is slower, so USB will be able to send all data. However if you regularly use Model 2 cameras you may -prefer videosize=1 which makes perfectly good I420, with no scaling and +prefer 176x144 which makes perfectly good I420, with no scaling and lesser demands on USB (300 Kbits per second, or 26 frames per second). +Another strange effect of 352x288 mode is the fine vertical grid visible +on some colored surfaces. I am sure it is caused by me not understanding +what the camera is trying to say. Blame trade secrets for that. + The camera that I had also has a hardware quirk: if disconnected, it needs few minutes to "relax" before it can be plugged in again (poorly designed USB processor reset circuit?) +[Veo Stingray with Product ID 0x800C is also Model 2, but I haven't +observed this particular flaw in it.] + Model 2 camera can be programmed for very high sensitivity (even starlight may be enough), this makes it convenient for tinkering with. The driver code has enough comments to help a programmer to tweak the camera @@ -98,12 +130,14 @@ or if you want to make changes to the code. Most distributions precompile all modules, so you can go directly to the next section "HOW TO USE THE DRIVER". -The driver consists of two files in usb/ directory: -ibmcam.c and ibmcam.h These files are included into the -Linux kernel build process if you configure the kernel -for CONFIG_USB_IBMCAM. Run "make xconfig" and in USB section -you will find the IBM camera driver. Select it, save the -configuration and recompile. +The ibmcam driver uses usbvideo helper library (module), +so if you are studying the ibmcam code you will be led there. + +The driver itself consists of only one file in usb/ directory: +ibmcam.c. This file is included into the Linux kernel build +process if you configure the kernel for CONFIG_USB_IBMCAM. +Run "make xconfig" and in USB section you will find the IBM +camera driver. Select it, save the configuration and recompile. HOW TO USE THE DRIVER: @@ -112,6 +146,13 @@ easier access to its configuration. The camera has many more settings than V4L can operate, so some settings are done using module options. +To begin with, on most modern Linux distributions the driver +will be automatically loaded whenever you plug the supported +camera in. Therefore, you don't need to do anything. However +if you want to experiment with some module parameters then +you can load and unload the driver manually, with camera +plugged in or unplugged. + Typically module is installed with command 'modprobe', like this: # modprobe ibmcam framerate=1 @@ -138,7 +179,7 @@ init_color Integer 0-255 [128] init_color=130 init_hue Integer 0-255 [128] init_hue=115 lighting Integer 0-2* [1] lighting=2 sharpness Integer 0-6* [4] sharpness=3 -videosize Integer 0-2* [2] videosize=1 +size Integer 0-2* [2] size=1 Options for Model 2 only: @@ -181,6 +222,11 @@ flags This is a bit mask, and you can combine any number of this is a little faster but may produce flicker if frame rate is too high and Isoc data gets lost. + FLAGS_NO_DECODING 128 This flag turns the video stream + decoder off, and dumps the raw + Isoc data from the camera into + the reading process. Useful to + developers, but not to users. framerate This setting controls frame rate of the camera. This is an approximate setting (in terms of "worst" ... "best") @@ -227,35 +273,38 @@ sharpness This option controls smoothing (noise reduction) be greeted with "snowy" image. Default is 4. Model 2 cameras do not support this feature. -videosize This setting chooses one if three image sizes that are - supported by this driver. Camera supports more, but +size This setting chooses one of several image sizes that are + supported by this driver. Cameras may support more, but it's difficult to reverse-engineer all formats. Following video sizes are supported: - videosize=0 128x96 (Model 1 only) - videosize=1 176x144 - videosize=2 352x288 - videosize=3 320x240 (Model 2 only) - videosize=4 352x240 (Model 2 only) + size=0 128x96 (Model 1 only) + size=1 160x120 + size=2 176x144 + size=3 320x240 (Model 2 only) + size=4 352x240 (Model 2 only) + size=5 352x288 + size=6 640x480 (Model 3 only) - The last one (352x288) is the native size of the sensor - array, so it's the best resolution camera (Model 1) can + The 352x288 is the native size of the Model 1 sensor + array, so it's the best resolution the camera can yield. The best resolution of Model 2 is 176x144, and larger images are produced by stretching the bitmap. + Model 3 has sensor with 640x480 grid, and it works too, + but the frame rate will be exceptionally low (1-2 FPS); + it may be still OK for some applications, like security. Choose the image size you need. The smaller image can support faster frame rate. Default is 352x288. +For more information and the Troubleshooting FAQ visit this URL: + + http://www.linux-usb.org/ibmcam/ + WHAT NEEDS TO BE DONE: -- The box freezes if camera is unplugged after being used (OHCI). - Workaround: remove usb-ohci module first. -- On occasion camera (model 1) does not start properly (xawtv reports - errors), or camera produces negative image (funny colors.) - Workaround: reload the driver module. Reason: [1]. - The button on the camera is not used. I don't know how to get to it. I know now how to read button on Model 2, but what to do with it? -[1] - Camera reports its status back to the driver; however I don't know what returned data means. If camera fails at some initialization stage then something should be done, and I don't do that because @@ -263,26 +312,13 @@ WHAT NEEDS TO BE DONE: concern because Model 2 uses different commands which do not return status (and seem to complete successfully every time). -VIDEO SIZE AND IMAGE SIZE - -Camera produces picture X by Y pixels. This is camera-specific and can be -altered by programming the camera accordingly. This image is placed onto -larger (or equal) area W by H, this is V4L image. At this time the driver -uses V4L image size (W by H) 352x288 pixels because many programs (such -as xawtv) expect quite specific sizes and don't want to deal with arbitrary, -camera-specific sizes. However this approach "hides" real image size, and -application always sees the camera as producing only 352x288 image. It is -possible to change the V4L image size to 128x96, and then if camera is -switched to 128x96 mode then xawtv will correctly accept this image size. But -many other popular sizes (such as 176x144) will not be welcomed. This is the -reason why all camera images are at this time placed onto 352x288 "canvas", -and size of that canvas (V4L) is reported to applications. It will be easy -to add options to control the canvas size, but it will be application- -specific because not all applications are ready to work with variety of -camera-specific sizes. +- Some flavors of Model 4 NetCameras produce only compressed video + streams, and I don't know how to decode them. CREDITS: The code is based in no small part on the CPiA driver by Johannes Erdfelt, Randy Dunlap, and others. Big thanks to them for their pioneering work on that and the USB stack. + +I also thank John Lightsey for his donation of the Veo Stingray camera. @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 5 SUBLEVEL = 4 -EXTRAVERSION =-pre1 +EXTRAVERSION =-pre2 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index 04533d30037b..4c1bd59cc94f 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -1148,3 +1148,4 @@ sys_call_table: .quad sys_gettid .quad sys_readahead .quad sys_ni_syscall /* 380, sys_security */ + .quad sys_tkill diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index ebf1463baec2..de6e44e8ad47 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c @@ -717,9 +717,7 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw, default: lock_kernel(); - sigaddset(¤t->pending.signal, signr); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } continue; diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index cfc646968e83..74278f6a4e65 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -236,6 +236,8 @@ __syscall_start: .long SYMBOL_NAME(sys_mincore) /* 220 */ .long SYMBOL_NAME(sys_madvise) .long SYMBOL_NAME(sys_fcntl64) + .long SYMBOL_NAME(sys_gettid) + .long SYMBOL_NAME(sys_tkill) __syscall_end: .rept NR_syscalls - (__syscall_end - __syscall_start) / 4 diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index d2bc87e2eec6..434fdd178047 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -637,10 +637,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) /* FALLTHRU */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } } diff --git a/arch/cris/drivers/eeprom.c b/arch/cris/drivers/eeprom.c index cb39cf10319a..4766f649cb4e 100644 --- a/arch/cris/drivers/eeprom.c +++ b/arch/cris/drivers/eeprom.c @@ -74,6 +74,7 @@ #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include "i2c.h" @@ -448,36 +449,39 @@ static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig) * orig 1: relative from current position * orig 2: position from last eeprom address */ - + loff_t ret; + + lock_kernel(); switch (orig) { case 0: - file->f_pos = offset; + ret = file->f_pos = offset; break; case 1: - file->f_pos += offset; + ret = file->f_pos += offset; break; case 2: - file->f_pos = eeprom.size - offset; + ret = file->f_pos = eeprom.size - offset; break; default: - return -EINVAL; + ret = -EINVAL; } /* truncate position */ if (file->f_pos < 0) { file->f_pos = 0; - return(-EOVERFLOW); + unlock_kernel(); + ret = -EOVERFLOW; } if (file->f_pos >= eeprom.size) { file->f_pos = eeprom.size - 1; - return(-EOVERFLOW); + ret = -EOVERFLOW; } - return ( file->f_pos ); + return ( ret ); } /* Reads data from eeprom. */ diff --git a/arch/cris/drivers/usb-host.c b/arch/cris/drivers/usb-host.c index 8e4e9e932ae8..24076eec65d3 100644 --- a/arch/cris/drivers/usb-host.c +++ b/arch/cris/drivers/usb-host.c @@ -210,12 +210,12 @@ static int etrax_usb_allocate_epid(void); static void etrax_usb_free_epid(char epid); static void cleanup_sb(USB_SB_Desc_t *sb); -static int etrax_usb_do_ctrl_hw_add(struct urb *urb, char epid, char maxlen); -static int etrax_usb_do_bulk_hw_add(struct urb *urb, char epid, char maxlen); +static int etrax_usb_do_ctrl_hw_add(struct urb *urb, char epid, char maxlen, int mem_flags); +static int etrax_usb_do_bulk_hw_add(struct urb *urb, char epid, char maxlen, int mem_flags); -static int etrax_usb_submit_ctrl_urb(struct urb *urb); +static int etrax_usb_submit_ctrl_urb(struct urb *urb, int mem_flags); -static int etrax_usb_submit_urb(struct urb *urb); +static int etrax_usb_submit_urb(struct urb *urb, int mem_flags); static int etrax_usb_unlink_urb(struct urb *urb); static int etrax_usb_get_frame_number(struct usb_device *usb_dev); static int etrax_usb_allocate_dev(struct usb_device *usb_dev); @@ -512,7 +512,7 @@ void etrax_usb_do_intr_recover(int epid) } while (tmp_ep != first_ep); } -static int etrax_usb_submit_intr_urb(struct urb *urb) +static int etrax_usb_submit_intr_urb(struct urb *urb, mem_flags) { USB_EP_Desc_t *tmp_ep; USB_EP_Desc_t *first_ep; @@ -556,7 +556,7 @@ static int etrax_usb_submit_intr_urb(struct urb *urb) } /* Ok, now we got valid endpoint, lets insert some traffic */ - urb_priv = (etrax_urb_priv_t *)kmalloc(sizeof(etrax_urb_priv_t), GFP_KERNEL); + urb_priv = (etrax_urb_priv_t *)kmalloc(sizeof(etrax_urb_priv_t), mem_flags); urb_priv->first_sb = 0; urb_priv->rx_offset = 0; urb_priv->eot = 0; @@ -591,9 +591,9 @@ static int etrax_usb_submit_intr_urb(struct urb *urb) USB_SB_Desc_t *traffic_sb; traffic_ep = (USB_EP_Desc_t *) - kmem_cache_alloc(usb_desc_cache, GFP_KERNEL); + kmem_cache_alloc(usb_desc_cache, mem_flags); traffic_sb = (USB_SB_Desc_t *) - kmem_cache_alloc(usb_desc_cache, GFP_KERNEL); + kmem_cache_alloc(usb_desc_cache, mem_flags); traffic_ep->hw_len = 0; traffic_ep->command = IO_FIELD(USB_EP_command, epid, epid) | @@ -904,7 +904,7 @@ static int etrax_usb_allocate_epid(void) return -1; } -static int etrax_usb_submit_bulk_urb(struct urb *urb) +static int etrax_usb_submit_bulk_urb(struct urb *urb, int mem_flags) { char epid; char devnum; @@ -954,7 +954,7 @@ static int etrax_usb_submit_bulk_urb(struct urb *urb) /* If this is the first URB, add the URB and do HW add */ URB_List[epid] = urb; restore_flags(flags); - etrax_usb_do_bulk_hw_add(urb, epid, maxlen); + etrax_usb_do_bulk_hw_add(urb, epid, maxlen, mem_flags); } DBFEXIT; @@ -962,7 +962,7 @@ static int etrax_usb_submit_bulk_urb(struct urb *urb) return 0; } -static int etrax_usb_do_bulk_hw_add(struct urb *urb, char epid, char maxlen) +static int etrax_usb_do_bulk_hw_add(struct urb *urb, char epid, char maxlen, int mem_flags) { USB_SB_Desc_t *sb_desc_1; @@ -973,8 +973,8 @@ static int etrax_usb_do_bulk_hw_add(struct urb *urb, char epid, char maxlen) DBFENTER; - urb_priv = kmalloc(sizeof(etrax_urb_priv_t), GFP_KERNEL); - sb_desc_1 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL); + urb_priv = kmalloc(sizeof(etrax_urb_priv_t), mem_flags); + sb_desc_1 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, mem_flags); if (usb_pipeout(urb->pipe)) { @@ -1135,7 +1135,8 @@ static int handle_bulk_transfer_attn(char epid, int status) if (URB_List[epid]) { etrax_usb_do_bulk_hw_add(URB_List[epid], epid, usb_maxpacket(URB_List[epid]->dev, URB_List[epid]->pipe, - usb_pipeout(URB_List[epid]->pipe))); + usb_pipeout(URB_List[epid]->pipe)), + GFP_KERNEL); } #if 1 else { @@ -1159,7 +1160,7 @@ static int handle_bulk_transfer_attn(char epid, int status) /* ---------------------------------------------------------------------------- */ -static int etrax_usb_submit_ctrl_urb(struct urb *urb) +static int etrax_usb_submit_ctrl_urb(struct urb *urb, int mem_flags) { char epid; char devnum; @@ -1209,7 +1210,7 @@ static int etrax_usb_submit_ctrl_urb(struct urb *urb) /* If this is the first URB, add the URB and do HW add */ URB_List[epid] = urb; restore_flags(flags); - etrax_usb_do_ctrl_hw_add(urb, epid, maxlen); + etrax_usb_do_ctrl_hw_add(urb, epid, maxlen, mem_flags); } DBFEXIT; @@ -1217,7 +1218,7 @@ static int etrax_usb_submit_ctrl_urb(struct urb *urb) return 0; } -static int etrax_usb_do_ctrl_hw_add(struct urb *urb, char epid, char maxlen) +static int etrax_usb_do_ctrl_hw_add(struct urb *urb, char epid, char maxlen, int mem_flags) { USB_SB_Desc_t *sb_desc_1; USB_SB_Desc_t *sb_desc_2; @@ -1231,9 +1232,9 @@ static int etrax_usb_do_ctrl_hw_add(struct urb *urb, char epid, char maxlen) DBFENTER; - urb_priv = kmalloc(sizeof(etrax_urb_priv_t), GFP_KERNEL); - sb_desc_1 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL); - sb_desc_2 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL); + urb_priv = kmalloc(sizeof(etrax_urb_priv_t), mem_flags); + sb_desc_1 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, mem_flags); + sb_desc_2 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, mem_flags); if (!(sb_desc_1 && sb_desc_2)) { panic("kmem_cache_alloc in ctrl_hw_add gave NULL pointers !!!\n"); @@ -1257,7 +1258,7 @@ static int etrax_usb_do_ctrl_hw_add(struct urb *urb, char epid, char maxlen) if (urb->transfer_buffer) { dbg_ctrl("This OUT transfer has an extra data stage"); - sb_desc_3 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL); + sb_desc_3 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, mem_flags); sb_desc_1->next = virt_to_phys(sb_desc_3); @@ -1285,7 +1286,7 @@ static int etrax_usb_do_ctrl_hw_add(struct urb *urb, char epid, char maxlen) dbg_ctrl("transfer_buffer_length = %d", urb->transfer_buffer_length); dbg_ctrl("rem is calculated to %d", urb->transfer_buffer_length % maxlen); - sb_desc_3 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL); + sb_desc_3 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, mem_flags); sb_desc_2->sw_len = urb->transfer_buffer_length ? (urb->transfer_buffer_length - 1) / maxlen + 1 : 0; @@ -1358,7 +1359,7 @@ static int etrax_usb_do_ctrl_hw_add(struct urb *urb, char epid, char maxlen) DBFEXIT; } -static int etrax_usb_submit_urb(struct urb *urb) +static int etrax_usb_submit_urb(struct urb *urb, int mem_flags) { etrax_hc_t *hc; int rval = -EINVAL; @@ -1375,10 +1376,10 @@ static int etrax_usb_submit_urb(struct urb *urb) rval = etrax_rh_submit_urb(urb); } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) { - rval = etrax_usb_submit_ctrl_urb(urb); + rval = etrax_usb_submit_ctrl_urb(urb, mem_flags); } else if (usb_pipetype(urb->pipe) == PIPE_BULK) { - rval = etrax_usb_submit_bulk_urb(urb); + rval = etrax_usb_submit_bulk_urb(urb, mem_flags); } else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { int bustime; @@ -1389,7 +1390,7 @@ static int etrax_usb_submit_urb(struct urb *urb) rval = bustime; } else { usb_claim_bandwidth(urb->dev, urb, bustime, 0); - rval = etrax_usb_submit_intr_urb(urb); + rval = etrax_usb_submit_intr_urb(urb, mem_flags); } } @@ -1683,7 +1684,8 @@ static int handle_control_transfer_attn(char epid, int status) if (URB_List[epid]) { etrax_usb_do_ctrl_hw_add(URB_List[epid], epid, usb_maxpacket(URB_List[epid]->dev, URB_List[epid]->pipe, - usb_pipeout(URB_List[epid]->pipe))); + usb_pipeout(URB_List[epid]->pipe)), + GFP_KERNEL); } #if 1 else { diff --git a/arch/cris/kernel/entry.S b/arch/cris/kernel/entry.S index 8512ba94323d..a07f726f3662 100644 --- a/arch/cris/kernel/entry.S +++ b/arch/cris/kernel/entry.S @@ -1015,6 +1015,7 @@ sys_call_table: .long SYMBOL_NAME(sys_ni_syscall) /* Reserved for Security */ .long SYMBOL_NAME(sys_gettid) .long SYMBOL_NAME(sys_readahead) /* 225 */ + .long SYMBOL_NAME(sys_tkill) /* * NOTE!! This doesn't have to be exact - we just have diff --git a/arch/cris/kernel/signal.c b/arch/cris/kernel/signal.c index 4605fc108c7f..ff1c306b8e38 100644 --- a/arch/cris/kernel/signal.c +++ b/arch/cris/kernel/signal.c @@ -679,10 +679,7 @@ int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs) default: lock_kernel(); - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } } diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index 2686bc9bcfd9..0e8e46d76b34 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c @@ -35,6 +35,7 @@ #include <linux/poll.h> #include <linux/smp.h> #include <linux/major.h> +#include <linux/smp_lock.h> #include <asm/processor.h> #include <asm/msr.h> @@ -82,16 +83,24 @@ static inline void do_cpuid(int cpu, u32 reg, u32 *data) static loff_t cpuid_seek(struct file *file, loff_t offset, int orig) { + loff_t ret; + + lock_kernel(); + switch (orig) { case 0: file->f_pos = offset; - return file->f_pos; + ret = file->f_pos; + break; case 1: file->f_pos += offset; - return file->f_pos; + ret = file->f_pos; default: - return -EINVAL; /* SEEK_END not supported */ + ret = -EINVAL; } + + unlock_kernel(); + return ret; } static ssize_t cpuid_read(struct file * file, char * buf, diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 2544f3ddf9b4..27ca507b4ad1 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -667,6 +667,7 @@ ENTRY(sys_call_table) .long SYMBOL_NAME(sys_removexattr) /* 235 */ .long SYMBOL_NAME(sys_lremovexattr) .long SYMBOL_NAME(sys_fremovexattr) + .long SYMBOL_NAME(sys_tkill) .rept NR_syscalls-(.-sys_call_table)/4 .long SYMBOL_NAME(sys_ni_syscall) diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c index 5445ca5ac47b..18560356a40a 100644 --- a/arch/i386/kernel/msr.c +++ b/arch/i386/kernel/msr.c @@ -33,6 +33,7 @@ #include <linux/init.h> #include <linux/poll.h> #include <linux/smp.h> +#include <linux/smp_lock.h> #include <linux/major.h> #include <asm/processor.h> @@ -162,16 +163,19 @@ static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx) static loff_t msr_seek(struct file *file, loff_t offset, int orig) { + loff_t ret = -EINVAL; + lock_kernel(); switch (orig) { case 0: file->f_pos = offset; - return file->f_pos; + ret = file->f_pos; + break; case 1: file->f_pos += offset; - return file->f_pos; - default: - return -EINVAL; /* SEEK_END not supported */ + ret = file->f_pos; } + unlock_kernel(); + return ret; } static ssize_t msr_read(struct file * file, char * buf, diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c index 7cfa09402361..f004ea327689 100644 --- a/arch/i386/kernel/signal.c +++ b/arch/i386/kernel/signal.c @@ -683,10 +683,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) /* FALLTHRU */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } } diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index 4e6d8f3b50cc..e11e8d92b471 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c @@ -171,77 +171,65 @@ sys32_execve (char *filename, unsigned int argv, unsigned int envp, } static inline int -putstat (struct stat32 *ubuf, struct stat *kbuf) +putstat (struct stat32 *ubuf, struct kstat *stat) { int err; + if (stat->size > MAX_NON_LFS) + return -EOVERFLOW; + if (clear_user(ubuf, sizeof(*ubuf))) - return 1; - - err = __put_user(kbuf->st_dev, &ubuf->st_dev); - err |= __put_user(kbuf->st_ino, &ubuf->st_ino); - err |= __put_user(kbuf->st_mode, &ubuf->st_mode); - err |= __put_user(kbuf->st_nlink, &ubuf->st_nlink); - err |= __put_user(kbuf->st_uid, &ubuf->st_uid); - err |= __put_user(kbuf->st_gid, &ubuf->st_gid); - err |= __put_user(kbuf->st_rdev, &ubuf->st_rdev); - err |= __put_user(kbuf->st_size, &ubuf->st_size); - err |= __put_user(kbuf->st_atime, &ubuf->st_atime); - err |= __put_user(kbuf->st_mtime, &ubuf->st_mtime); - err |= __put_user(kbuf->st_ctime, &ubuf->st_ctime); - err |= __put_user(kbuf->st_blksize, &ubuf->st_blksize); - err |= __put_user(kbuf->st_blocks, &ubuf->st_blocks); + return -EFAULT; + + err = __put_user(stat->dev, &ubuf->st_dev); + err |= __put_user(stat->ino, &ubuf->st_ino); + err |= __put_user(stat->mode, &ubuf->st_mode); + err |= __put_user(stat->nlink, &ubuf->st_nlink); + err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid); + err |= __put_user(high2lowgid(stat->gid), &ubuf->st_gid); + err |= __put_user(stat->rdev, &ubuf->st_rdev); + err |= __put_user(stat->size, &ubuf->st_size); + err |= __put_user(stat->atime, &ubuf->st_atime); + err |= __put_user(stat->mtime, &ubuf->st_mtime); + err |= __put_user(stat->ctime, &ubuf->st_ctime); + err |= __put_user(stat->blksize, &ubuf->st_blksize); + err |= __put_user(stat->blocks, &ubuf->st_blocks); return err; } -extern asmlinkage long sys_newstat (char * filename, struct stat * statbuf); - asmlinkage long sys32_newstat (char *filename, struct stat32 *statbuf) { - int ret; - struct stat s; - mm_segment_t old_fs = get_fs(); + struct kstat stat; + int ret = vfs_stat(filename, &stat); + + if (!ret) + ret = putstat(statbuf, &stat); - set_fs(KERNEL_DS); - ret = sys_newstat(filename, &s); - set_fs(old_fs); - if (putstat(statbuf, &s)) - return -EFAULT; return ret; } -extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf); - asmlinkage long sys32_newlstat (char *filename, struct stat32 *statbuf) { - mm_segment_t old_fs = get_fs(); - struct stat s; - int ret; + struct kstat stat; + int ret = vfs_lstat(filename, &stat); + + if (!ret) + ret = putstat(statbuf, &stat); - set_fs(KERNEL_DS); - ret = sys_newlstat(filename, &s); - set_fs(old_fs); - if (putstat(statbuf, &s)) - return -EFAULT; return ret; } -extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf); - asmlinkage long sys32_newfstat (unsigned int fd, struct stat32 *statbuf) { - mm_segment_t old_fs = get_fs(); - struct stat s; - int ret; + struct kstat stat; + int ret = vfs_fstat(fd, &stat); + + if (!ret) + ret = putstat(statbuf, &stat); - set_fs(KERNEL_DS); - ret = sys_newfstat(fd, &s); - set_fs(old_fs); - if (putstat(statbuf, &s)) - return -EFAULT; return ret; } @@ -3529,74 +3517,59 @@ sys32_ftruncate64 (int fd, unsigned int len_lo, unsigned int len_hi) } static int -putstat64 (struct stat64 *ubuf, struct stat *kbuf) +putstat64 (struct stat64 *ubuf, struct kstat *kbuf) { int err; if (clear_user(ubuf, sizeof(*ubuf))) - return 1; - - err = __put_user(kbuf->st_dev, &ubuf->st_dev); - err |= __put_user(kbuf->st_ino, &ubuf->__st_ino); - err |= __put_user(kbuf->st_ino, &ubuf->st_ino_lo); - err |= __put_user(kbuf->st_ino >> 32, &ubuf->st_ino_hi); - err |= __put_user(kbuf->st_mode, &ubuf->st_mode); - err |= __put_user(kbuf->st_nlink, &ubuf->st_nlink); - err |= __put_user(kbuf->st_uid, &ubuf->st_uid); - err |= __put_user(kbuf->st_gid, &ubuf->st_gid); - err |= __put_user(kbuf->st_rdev, &ubuf->st_rdev); - err |= __put_user(kbuf->st_size, &ubuf->st_size_lo); - err |= __put_user((kbuf->st_size >> 32), &ubuf->st_size_hi); - err |= __put_user(kbuf->st_atime, &ubuf->st_atime); - err |= __put_user(kbuf->st_mtime, &ubuf->st_mtime); - err |= __put_user(kbuf->st_ctime, &ubuf->st_ctime); - err |= __put_user(kbuf->st_blksize, &ubuf->st_blksize); - err |= __put_user(kbuf->st_blocks, &ubuf->st_blocks); + return -EFAULT; + + err = __put_user(kbuf->dev, &ubuf->st_dev); + err |= __put_user(kbuf->ino, &ubuf->__st_ino); + err |= __put_user(kbuf->ino, &ubuf->st_ino_lo); + err |= __put_user(kbuf->ino >> 32, &ubuf->st_ino_hi); + err |= __put_user(kbuf->mode, &ubuf->st_mode); + err |= __put_user(kbuf->nlink, &ubuf->st_nlink); + err |= __put_user(kbuf->uid, &ubuf->st_uid); + err |= __put_user(kbuf->gid, &ubuf->st_gid); + err |= __put_user(kbuf->rdev, &ubuf->st_rdev); + err |= __put_user(kbuf->size, &ubuf->st_size_lo); + err |= __put_user((kbuf->size >> 32), &ubuf->st_size_hi); + err |= __put_user(kbuf->atime, &ubuf->st_atime); + err |= __put_user(kbuf->mtime, &ubuf->st_mtime); + err |= __put_user(kbuf->ctime, &ubuf->st_ctime); + err |= __put_user(kbuf->blksize, &ubuf->st_blksize); + err |= __put_user(kbuf->blocks, &ubuf->st_blocks); return err; } asmlinkage long sys32_stat64 (char *filename, struct stat64 *statbuf) { - mm_segment_t old_fs = get_fs(); - struct stat s; - long ret; - - set_fs(KERNEL_DS); - ret = sys_newstat(filename, &s); - set_fs(old_fs); - if (putstat64(statbuf, &s)) - return -EFAULT; + struct kstat s; + long ret = vfs_stat(filename, &s); + if (!ret) + ret = putstat64(statbuf, &s); return ret; } asmlinkage long sys32_lstat64 (char *filename, struct stat64 *statbuf) { - mm_segment_t old_fs = get_fs(); - struct stat s; - long ret; - - set_fs(KERNEL_DS); - ret = sys_newlstat(filename, &s); - set_fs(old_fs); - if (putstat64(statbuf, &s)) - return -EFAULT; + struct kstat s; + long ret = vfs_lstat(filename, &s); + if (!ret) + ret = putstat64(statbuf, &s); return ret; } asmlinkage long sys32_fstat64 (unsigned int fd, struct stat64 *statbuf) { - mm_segment_t old_fs = get_fs(); - struct stat s; - long ret; - - set_fs(KERNEL_DS); - ret = sys_newfstat(fd, &s); - set_fs(old_fs); - if (putstat64(statbuf, &s)) - return -EFAULT; + struct kstat s; + long ret = vfs_fstat(fd, &s); + if (!ret) + ret = putstat64(statbuf, &s); return ret; } diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 4b88d01bb8fc..307b498f7da3 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1130,6 +1130,7 @@ sys_call_table: data8 sys_getdents64 data8 sys_getunwind // 1215 data8 sys_readahead + data8 sys_tkill data8 ia64_ni_syscall data8 ia64_ni_syscall data8 ia64_ni_syscall diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 04a08e56cbc6..1fd947a6f5fa 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -578,10 +578,7 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall) /* FALLTHRU */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } } diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index cc312ad8b18f..8b4512db776b 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c @@ -282,120 +282,64 @@ ia64_create_module (const char *name_user, size_t size, long arg2, long arg3, * call - it will be removed later once everybody migrates to the new * kernel stat structure that matches the glibc one - Jes */ -static __inline__ int -do_revalidate (struct dentry *dentry) -{ - struct inode * inode = dentry->d_inode; - if (inode->i_op && inode->i_op->revalidate) - return inode->i_op->revalidate(dentry); - return 0; -} static int -cp_ia64_old_stat (struct inode *inode, struct ia64_oldstat *statbuf) +cp_ia64_old_stat (struct kstat *stat, struct ia64_oldstat *statbuf) { struct ia64_oldstat tmp; unsigned int blocks, indirect; memset(&tmp, 0, sizeof(tmp)); - tmp.st_dev = kdev_t_to_nr(inode->i_dev); - tmp.st_ino = inode->i_ino; - tmp.st_mode = inode->i_mode; - tmp.st_nlink = inode->i_nlink; - SET_STAT_UID(tmp, inode->i_uid); - SET_STAT_GID(tmp, inode->i_gid); - tmp.st_rdev = kdev_t_to_nr(inode->i_rdev); - tmp.st_size = inode->i_size; - tmp.st_atime = inode->i_atime; - tmp.st_mtime = inode->i_mtime; - tmp.st_ctime = inode->i_ctime; -/* - * st_blocks and st_blksize are approximated with a simple algorithm if - * they aren't supported directly by the filesystem. The minix and msdos - * filesystems don't keep track of blocks, so they would either have to - * be counted explicitly (by delving into the file itself), or by using - * this simple algorithm to get a reasonable (although not 100% accurate) - * value. - */ - -/* - * Use minix fs values for the number of direct and indirect blocks. The - * count is now exact for the minix fs except that it counts zero blocks. - * Everything is in units of BLOCK_SIZE until the assignment to - * tmp.st_blksize. - */ -#define D_B 7 -#define I_B (BLOCK_SIZE / sizeof(unsigned short)) - - if (!inode->i_blksize) { - blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE; - if (blocks > D_B) { - indirect = (blocks - D_B + I_B - 1) / I_B; - blocks += indirect; - if (indirect > 1) { - indirect = (indirect - 1 + I_B - 1) / I_B; - blocks += indirect; - if (indirect > 1) - blocks++; - } - } - tmp.st_blocks = (BLOCK_SIZE / 512) * blocks; - tmp.st_blksize = BLOCK_SIZE; - } else { - tmp.st_blocks = inode->i_blocks; - tmp.st_blksize = inode->i_blksize; - } + tmp.st_dev = stat->dev; + tmp.st_ino = stat->ino; + tmp.st_mode = stat->mode; + tmp.st_nlink = stat->nlink; + SET_STAT_UID(tmp, stat->uid); + SET_STAT_GID(tmp, stat->gid); + tmp.st_rdev = stat->rdev; + tmp.st_size = stat->size; + tmp.st_atime = stat->atime; + tmp.st_mtime = stat->mtime; + tmp.st_ctime = stat->ctime; + tmp.st_blocks = stat->i_blocks; + tmp.st_blksize = stat->i_blksize; return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; } asmlinkage long ia64_oldstat (char *filename, struct ia64_oldstat *statbuf) { - struct nameidata nd; - int error; - - error = user_path_walk(filename, &nd); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_ia64_old_stat(nd.dentry->d_inode, statbuf); - path_release(&nd); - } + struct kstat stat; + int error = vfs_stat(filename, &stat); + + if (!error) + error = cp_ia64_old_stat(&stat, statbuf); + return error; } - asmlinkage long -ia64_oldlstat (char *filename, struct ia64_oldstat *statbuf) { - struct nameidata nd; - int error; - - error = user_path_walk_link(filename, &nd); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_ia64_old_stat(nd.dentry->d_inode, statbuf); - path_release(&nd); - } +ia64_oldlstat (char *filename, struct ia64_oldstat *statbuf) +{ + struct kstat stat; + int error = vfs_lstat(filename, &stat); + + if (!error) + error = cp_ia64_old_stat(&stat, statbuf); + return error; } asmlinkage long ia64_oldfstat (unsigned int fd, struct ia64_oldstat *statbuf) { - struct file * f; - int err = -EBADF; + struct kstat stat; + int error = vfs_fstat(fd, &stat); - f = fget(fd); - if (f) { - struct dentry * dentry = f->f_dentry; + if (!error) + error = cp_ia64_old_stat(&stat, statbuf); - err = do_revalidate(dentry); - if (!err) - err = cp_ia64_old_stat(dentry->d_inode, statbuf); - fput(f); - } - return err; + return error; } #endif diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index fcb7b915c9a5..c519aa25b70d 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -646,6 +646,8 @@ SYMBOL_NAME_LABEL(sys_call_table) .long SYMBOL_NAME(sys_ni_syscall) .long SYMBOL_NAME(sys_ni_syscall) .long SYMBOL_NAME(sys_getdents64) /* 220 */ + .long SYMBOL_NAME(sys_gettid) + .long SYMBOL_NAME(sys_tkill) .rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4 .long SYMBOL_NAME(sys_ni_syscall) diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index e9c41780c84a..aba509a4f9cc 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c @@ -1135,10 +1135,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) /* FALLTHRU */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } } diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 3614fa4aa292..8a02ea63903a 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -661,10 +661,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) /* FALLTHRU */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } } diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h index 9a6795f4e8f3..953186802c1b 100644 --- a/arch/mips/kernel/syscalls.h +++ b/arch/mips/kernel/syscalls.h @@ -235,3 +235,5 @@ SYS(sys_mincore, 3) SYS(sys_madvise, 3) SYS(sys_getdents64, 3) SYS(sys_fcntl64, 3) /* 4220 */ +SYS(sys_gettid, 0) +SYS(sys_tkill, 2) diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index fbd4a2dcc105..9f820f87e25f 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c @@ -1178,7 +1178,7 @@ linux_to_irix_dev_t (dev_t t) return MAJOR (t) << 18 | MINOR (t); } -static inline int irix_xstat32_xlate(struct stat *kb, void *ubuf) +static inline int irix_xstat32_xlate(struct kstat *stat, void *ubuf) { struct xstat32 { u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid; @@ -1191,28 +1191,32 @@ static inline int irix_xstat32_xlate(struct stat *kb, void *ubuf) u32 st_pad4[8]; } ub; - ub.st_dev = linux_to_irix_dev_t (kb->st_dev); - ub.st_ino = kb->st_ino; - ub.st_mode = kb->st_mode; - ub.st_nlink = kb->st_nlink; - ub.st_uid = kb->st_uid; - ub.st_gid = kb->st_gid; - ub.st_rdev = linux_to_irix_dev_t (kb->st_rdev); - ub.st_size = kb->st_size; - ub.st_atime0 = kb->st_atime; + ub.st_dev = linux_to_irix_dev_t(stat->dev); + ub.st_ino = stat->ino; + ub.st_mode = stat->mode; + ub.st_nlink = stat->nlink; + SET_STAT_UID(ub, stat->uid); + SET_STAT_GID(ub, stat->gid); + ub.st_rdev = linux_to_irix_dev_t(stat->rdev); +#if BITS_PER_LONG == 32 + if (stat->size > MAX_NON_LFS) + return -EOVERFLOW; +#endif + ub.st_size = stat->size; + ub.st_atime0 = stat->atime; ub.st_atime1 = 0; - ub.st_mtime0 = kb->st_mtime; + ub.st_mtime0 = stat->mtime; ub.st_mtime1 = 0; - ub.st_ctime0 = kb->st_ctime; + ub.st_ctime0 = stat->ctime; ub.st_ctime1 = 0; - ub.st_blksize = kb->st_blksize; - ub.st_blocks = kb->st_blocks; + ub.st_blksize = stat->blksize; + ub.st_blocks = stat->blocks; strcpy (ub.st_fstype, "efs"); return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0; } -static inline void irix_xstat64_xlate(struct stat *sb) +static inline void irix_xstat64_xlate(struct kstat *stat, void *ubuf) { struct xstat64 { u32 st_dev; s32 st_pad1[3]; @@ -1229,177 +1233,112 @@ static inline void irix_xstat64_xlate(struct stat *sb) s32 st_pad4[8]; } ks; - ks.st_dev = linux_to_irix_dev_t (sb->st_dev); + ks.st_dev = linux_to_irix_dev_t(stat->dev); ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0; - ks.st_ino = (unsigned long long) sb->st_ino; - ks.st_mode = (u32) sb->st_mode; - ks.st_nlink = (u32) sb->st_nlink; - ks.st_uid = (s32) sb->st_uid; - ks.st_gid = (s32) sb->st_gid; - ks.st_rdev = linux_to_irix_dev_t (sb->st_rdev); + ks.st_ino = (unsigned long long) stat->ino; + ks.st_mode = (u32) stat->mode; + ks.st_nlink = (u32) stat->nlink; + ks.st_uid = (s32) stat->uid; + ks.st_gid = (s32) stat->gid; + ks.st_rdev = linux_to_irix_dev_t (stat->rdev); ks.st_pad2[0] = ks.st_pad2[1] = 0; - ks.st_size = (long long) sb->st_size; + ks.st_size = (long long) stat->size; ks.st_pad3 = 0; /* XXX hackety hack... */ - ks.st_atime.tv_sec = (s32) sb->st_atime; ks.st_atime.tv_nsec = 0; - ks.st_mtime.tv_sec = (s32) sb->st_atime; ks.st_mtime.tv_nsec = 0; - ks.st_ctime.tv_sec = (s32) sb->st_atime; ks.st_ctime.tv_nsec = 0; + ks.st_atime.tv_sec = (s32) stat->atime; ks.st_atime.tv_nsec = 0; + ks.st_mtime.tv_sec = (s32) stat->atime; ks.st_mtime.tv_nsec = 0; + ks.st_ctime.tv_sec = (s32) stat->atime; ks.st_ctime.tv_nsec = 0; - ks.st_blksize = (s32) sb->st_blksize; - ks.st_blocks = (long long) sb->st_blocks; + ks.st_blksize = (s32) stat->blksize; + ks.st_blocks = (long long) stat->blocks; memset(ks.st_fstype, 0, 16); ks.st_pad4[0] = ks.st_pad4[1] = ks.st_pad4[2] = ks.st_pad4[3] = 0; ks.st_pad4[4] = ks.st_pad4[5] = ks.st_pad4[6] = ks.st_pad4[7] = 0; /* Now write it all back. */ - copy_to_user(sb, &ks, sizeof(struct xstat64)); + copy_to_user(ubuf, &ks, sizeof(struct xstat64)); } -extern asmlinkage int sys_newstat(char * filename, struct stat * statbuf); - asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf) { int retval; + struct kstat stat; #ifdef DEBUG_XSTAT printk("[%s:%d] Wheee.. irix_xstat(%d,%s,%p) ", current->comm, current->pid, version, filename, statbuf); #endif - switch(version) { - case 2: { - struct stat kb; - mm_segment_t old_fs; - - old_fs = get_fs(); set_fs(get_ds()); - retval = sys_newstat(filename, &kb); - set_fs(old_fs); -#ifdef DEBUG_XSTAT - printk("retval[%d]\n", retval); -#endif - if(retval) - goto out; - retval = irix_xstat32_xlate(&kb, statbuf); - goto out; - } - - case 3: { - retval = sys_newstat(filename, statbuf); -#ifdef DEBUG_XSTAT - printk("retval[%d]\n", retval); -#endif - if(retval) - goto out; - - irix_xstat64_xlate(statbuf); - retval = 0; - break; - } - default: - retval = -EINVAL; - break; + retval = vfs_stat(filename, &stat); + if (!retval) { + switch(version) { + case 2: + retval = irix_xstat32_xlate(&stat, statbuf); + break; + case 3: + irix_xstat64_xlate(&stat, statbuf); + retval = 0; /* Really? */ + break; + default: + retval = -EINVAL; + } } - -out: return retval; } -extern asmlinkage int sys_newlstat(char * filename, struct stat * statbuf); - asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf) { int error; + struct kstat stat; #ifdef DEBUG_XSTAT printk("[%s:%d] Wheee.. irix_lxstat(%d,%s,%p) ", current->comm, current->pid, version, filename, statbuf); #endif - switch(version) { - case 2: { - struct stat kb; - mm_segment_t old_fs; - - old_fs = get_fs(); set_fs(get_ds()); - error = sys_newlstat(filename, &kb); - set_fs(old_fs); -#ifdef DEBUG_XSTAT - printk("error[%d]\n", error); -#endif - if(error) - goto out; - error = irix_xstat32_xlate(&kb, statbuf); - goto out; - } - - case 3: { - error = sys_newlstat(filename, statbuf); -#ifdef DEBUG_XSTAT - printk("error[%d]\n", error); -#endif - if(error) - goto out; - - irix_xstat64_xlate(statbuf); - error = 0; - goto out; - } - default: - error = -EINVAL; - goto out; + error = vfs_lstat(filename, &stat); + + if (!error) { + switch (version) { + case 2: + error = irix_xstat32_xlate(&stat, statbuf); + break; + case 3: + irix_xstat64_xlate(&stat, statbuf); + error = 0; + break; + default: + error = -EINVAL; + } } - -out: return error; } -extern asmlinkage int sys_newfstat(unsigned int fd, struct stat * statbuf); - asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf) { int error; + struct kstat stat; #ifdef DEBUG_XSTAT printk("[%s:%d] Wheee.. irix_fxstat(%d,%d,%p) ", current->comm, current->pid, version, fd, statbuf); #endif - switch(version) { - case 2: { - struct stat kb; - mm_segment_t old_fs; - - old_fs = get_fs(); set_fs(get_ds()); - error = sys_newfstat(fd, &kb); - set_fs(old_fs); -#ifdef DEBUG_XSTAT - printk("error[%d]\n", error); -#endif - if(error) - goto out; - error = irix_xstat32_xlate(&kb, statbuf); - goto out; - } - - case 3: { - error = sys_newfstat(fd, statbuf); -#ifdef DEBUG_XSTAT - printk("error[%d]\n", error); -#endif - if(error) - goto out; - irix_xstat64_xlate(statbuf); - error = 0; - goto out; - } - - default: - error = -EINVAL; - goto out; + error = vfs_fstat(fd, &stat); + if (!error) { + switch (version) { + case 2: + error = irix_xstat32_xlate(&stat, statbuf); + break; + case 3: + irix_xstat64_xlate(&stat, statbuf); + error = 0; + break; + default: + error = -EINVAL; + } } - -out: return error; } diff --git a/arch/mips64/kernel/linux32.c b/arch/mips64/kernel/linux32.c index 5d43147ede34..3ca8a28c1da9 100644 --- a/arch/mips64/kernel/linux32.c +++ b/arch/mips64/kernel/linux32.c @@ -39,125 +39,59 @@ /* * Revalidate the inode. This is required for proper NFS attribute caching. */ -static __inline__ int -do_revalidate(struct dentry *dentry) -{ - struct inode * inode = dentry->d_inode; - - if (inode->i_op && inode->i_op->revalidate) - return inode->i_op->revalidate(dentry); - return 0; -} - -static int cp_new_stat32(struct inode * inode, struct stat32 * statbuf) +static int cp_new_stat32(struct kstat *stat, struct stat32 *statbuf) { struct stat32 tmp; - unsigned int blocks, indirect; memset(&tmp, 0, sizeof(tmp)); - tmp.st_dev = kdev_t_to_nr(inode->i_dev); - tmp.st_ino = inode->i_ino; - tmp.st_mode = inode->i_mode; - tmp.st_nlink = inode->i_nlink; - SET_STAT_UID(tmp, inode->i_uid); - SET_STAT_GID(tmp, inode->i_gid); - tmp.st_rdev = kdev_t_to_nr(inode->i_rdev); - tmp.st_size = inode->i_size; - tmp.st_atime = inode->i_atime; - tmp.st_mtime = inode->i_mtime; - tmp.st_ctime = inode->i_ctime; - - /* - * st_blocks and st_blksize are approximated with a simple algorithm if - * they aren't supported directly by the filesystem. The minix and msdos - * filesystems don't keep track of blocks, so they would either have to - * be counted explicitly (by delving into the file itself), or by using - * this simple algorithm to get a reasonable (although not 100% - * accurate) value. - */ - - /* - * Use minix fs values for the number of direct and indirect blocks. - * The count is now exact for the minix fs except that it counts zero - * blocks. Everything is in units of BLOCK_SIZE until the assignment - * to tmp.st_blksize. - */ -#define D_B 7 -#define I_B (BLOCK_SIZE / sizeof(unsigned short)) - - if (!inode->i_blksize) { - blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE; - if (blocks > D_B) { - indirect = (blocks - D_B + I_B - 1) / I_B; - blocks += indirect; - if (indirect > 1) { - indirect = (indirect - 1 + I_B - 1) / I_B; - blocks += indirect; - if (indirect > 1) - blocks++; - } - } - tmp.st_blocks = (BLOCK_SIZE / 512) * blocks; - tmp.st_blksize = BLOCK_SIZE; - } else { - tmp.st_blocks = inode->i_blocks; - tmp.st_blksize = inode->i_blksize; - } - + tmp.st_dev = stat->dev; + tmp.st_ino = stat->ino; + tmp.st_mode = stat->mode; + tmp.st_nlink = stat->nlink; + SET_STAT_UID(tmp, stat->uid); + SET_STAT_GID(tmp, stat->gid); + tmp.st_rdev = stat->rdev; + tmp.st_size = stat->size; + tmp.st_atime = stat->atime; + tmp.st_mtime = stat->mtime; + tmp.st_ctime = stat->ctime; + tmp.st_blocks = stat->blocks; + tmp.st_blksize = stat->blksize; return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; } asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf) { - struct nameidata nd; - int error; + struct kstat stat; + int error = vfs_stat(filename, &stat); - error = user_path_walk(filename, &nd); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat32(nd.dentry->d_inode, statbuf); - - path_release(&nd); - } + if (!error) + error = cp_new_stat32(&stat, statbuf); return error; } asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf) { - struct nameidata nd; - int error; + struct kstat stat; + int error = vfs_lstat(filename, &stat); - error = user_path_walk_link(filename, &nd); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat32(nd.dentry->d_inode, statbuf); - - path_release(&nd); - } + if (!error) + error = cp_new_stat32(&stat, statbuf); return error; } asmlinkage long sys32_newfstat(unsigned int fd, struct stat32 * statbuf) { - struct file * f; - int err = -EBADF; - - f = fget(fd); - if (f) { - struct dentry * dentry = f->f_dentry; + struct kstat stat; + int error = vfs_fstat(fd, &stat); - err = do_revalidate(dentry); - if (!err) - err = cp_new_stat32(dentry->d_inode, statbuf); - fput(f); - } + if (!error) + error = cp_new_stat32(&stat, statbuf); - return err; + return error; } asmlinkage int sys_mmap2(void) {return 0;} diff --git a/arch/mips64/kernel/scall_64.S b/arch/mips64/kernel/scall_64.S index 70b70cd7caa7..ad270e37658e 100644 --- a/arch/mips64/kernel/scall_64.S +++ b/arch/mips64/kernel/scall_64.S @@ -347,3 +347,5 @@ sys_call_table: PTR sys_mincore PTR sys_madvise PTR sys_getdents64 + PTR sys_gettid + PTR sys_tkill diff --git a/arch/mips64/kernel/scall_o32.S b/arch/mips64/kernel/scall_o32.S index 00a45caa4548..0ee48e317c40 100644 --- a/arch/mips64/kernel/scall_o32.S +++ b/arch/mips64/kernel/scall_o32.S @@ -454,6 +454,8 @@ illegal_syscall: sys sys_madvise 3 sys sys_getdents64 3 sys sys32_fcntl64 3 /* 4220 */ + sys sys32_gettid 0 + sys sys32_tkill 2 .endm .macro sys function, nargs diff --git a/arch/mips64/kernel/signal.c b/arch/mips64/kernel/signal.c index 00f491ec7aa7..43856504587b 100644 --- a/arch/mips64/kernel/signal.c +++ b/arch/mips64/kernel/signal.c @@ -685,10 +685,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) /* FALLTHRU */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } } diff --git a/arch/mips64/kernel/signal32.c b/arch/mips64/kernel/signal32.c index 846f3b9b8cb0..ecd93fee7e40 100644 --- a/arch/mips64/kernel/signal32.c +++ b/arch/mips64/kernel/signal32.c @@ -757,10 +757,7 @@ asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs) /* FALLTHRU */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } } diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c index bbe1a534fd6e..99c06ba7edc1 100644 --- a/arch/parisc/hpux/fs.c +++ b/arch/parisc/hpux/fs.c @@ -83,42 +83,20 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset, i int hpux_getdents(unsigned int fd, struct hpux_dirent *dirent, unsigned int count) { struct file * file; - struct dentry * dentry; - struct inode * inode; struct hpux_dirent * lastdirent; struct getdents_callback buf; - int error; + int error = -EBADF; - lock_kernel(); - error = -EBADF; file = fget(fd); if (!file) goto out; - dentry = file->f_dentry; - if (!dentry) - goto out_putf; - - inode = dentry->d_inode; - if (!inode) - goto out_putf; - buf.current_dir = dirent; buf.previous = NULL; buf.count = count; buf.error = 0; - error = -ENOTDIR; - if (!file->f_op || !file->f_op->readdir) - goto out_putf; - - /* - * Get the inode's semaphore to prevent changes - * to the directory while we read it. - */ - down(&inode->i_sem); - error = file->f_op->readdir(file, &buf, filldir); - up(&inode->i_sem); + error = vfs_readdir(file, &buf, filldir); if (error < 0) goto out_putf; error = buf.error; @@ -131,7 +109,6 @@ int hpux_getdents(unsigned int fd, struct hpux_dirent *dirent, unsigned int coun out_putf: fput(file); out: - unlock_kernel(); return error; } @@ -141,110 +118,56 @@ int hpux_mount(const char *fs, const char *path, int mflag, return -ENOSYS; } -static int cp_hpux_stat(struct inode * inode, struct hpux_stat64 * statbuf) +static int cp_hpux_stat(struct kstat *stat, struct hpux_stat64 *statbuf) { struct hpux_stat64 tmp; - unsigned int blocks, indirect; memset(&tmp, 0, sizeof(tmp)); - tmp.st_dev = kdev_t_to_nr(inode->i_dev); - tmp.st_ino = inode->i_ino; - tmp.st_mode = inode->i_mode; - tmp.st_nlink = inode->i_nlink; - tmp.st_uid = inode->i_uid; - tmp.st_gid = inode->i_gid; - tmp.st_rdev = kdev_t_to_nr(inode->i_rdev); - tmp.st_size = inode->i_size; - tmp.st_atime = inode->i_atime; - tmp.st_mtime = inode->i_mtime; - tmp.st_ctime = inode->i_ctime; - -#define D_B 7 -#define I_B (BLOCK_SIZE / sizeof(unsigned short)) - - if (!inode->i_blksize) { - blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE; - if (blocks > D_B) { - indirect = (blocks - D_B + I_B - 1) / I_B; - blocks += indirect; - if (indirect > 1) { - indirect = (indirect - 1 + I_B - 1) / I_B; - blocks += indirect; - if (indirect > 1) - blocks++; - } - } - tmp.st_blocks = (BLOCK_SIZE / 512) * blocks; - tmp.st_blksize = BLOCK_SIZE; - } else { - tmp.st_blocks = inode->i_blocks; - tmp.st_blksize = inode->i_blksize; - } + tmp.st_dev = stat->dev; + tmp.st_ino = stat->ino; + tmp.st_mode = stat->mode; + tmp.st_nlink = stat->nlink; + tmp.st_uid = stat->uid; + tmp.st_gid = stat->gid; + tmp.st_rdev = stat->rdev; + tmp.st_size = stat->size; + tmp.st_atime = stat->atime; + tmp.st_mtime = stat->mtime; + tmp.st_ctime = stat->ctime; + tmp.st_blocks = stat->blocks; + tmp.st_blksize = stat->blksize; return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; } -/* - * Revalidate the inode. This is required for proper NFS attribute caching. - * Blatently copied wholesale from fs/stat.c - */ -static __inline__ int -do_revalidate(struct dentry *dentry) -{ - struct inode * inode = dentry->d_inode; - if (inode->i_op && inode->i_op->revalidate) - return inode->i_op->revalidate(dentry); - return 0; -} - long hpux_stat64(const char *path, struct hpux_stat64 *buf) { - struct nameidata nd; - int error; + struct kstat stat; + int error = vfs_stat(filename, &stat); + + if (!error) + error = cp_hpux_stat(&stat, statbuf); - lock_kernel(); - error = user_path_walk(path, &nd); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_hpux_stat(nd.dentry->d_inode, buf); - path_release(&nd); - } - unlock_kernel(); return error; } long hpux_fstat64(unsigned int fd, struct hpux_stat64 *statbuf) { - struct file * f; - int err = -EBADF; - - lock_kernel(); - f = fget(fd); - if (f) { - struct dentry * dentry = f->f_dentry; - - err = do_revalidate(dentry); - if (!err) - err = cp_hpux_stat(dentry->d_inode, statbuf); - fput(f); - } - unlock_kernel(); - return err; + struct kstat stat; + int error = vfs_fstat(fd, &stat); + + if (!error) + error = cp_hpux_stat(&stat, statbuf); + + return error; } long hpux_lstat64(char *filename, struct hpux_stat64 *statbuf) { - struct nameidata nd; - int error; + struct kstat stat; + int error = vfs_lstat(filename, &stat); + + if (!error) + error = cp_hpux_stat(&stat, statbuf); - lock_kernel(); - error = user_path_walk_link(filename, &nd); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_hpux_stat(nd.dentry->d_inode, statbuf); - path_release(&nd); - } - unlock_kernel(); return error; } diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index fec670ab8759..f31570d2d18d 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -581,11 +581,7 @@ do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall) /* FALLTHRU */ default: - lock_kernel(); - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } } diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index bfa75747149c..3c70143a07c5 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -552,6 +552,8 @@ sys_call_table: ENTRY_UHOH(shmctl) /* 195 */ ENTRY_SAME(ni_syscall) /* streams1 */ ENTRY_SAME(ni_syscall) /* streams2 */ + ENTRY_SAME(gettid) + ENTRY_SAME(tkill) .end diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 52e7b4e2efc4..376fa23dc4b2 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -1121,6 +1121,7 @@ _GLOBAL(sys_call_table) .long sys_madvise /* 205 */ .long sys_mincore .long sys_gettid + .long sys_tkill .rept NR_syscalls-(.-sys_call_table)/4 .long sys_ni_syscall .endr diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c index 8f054ff4c33c..99661be1e567 100644 --- a/arch/ppc/kernel/ppc_htab.c +++ b/arch/ppc/kernel/ppc_htab.c @@ -21,6 +21,7 @@ #include <linux/sysctl.h> #include <linux/ctype.h> #include <linux/threads.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/bitops.h> @@ -430,18 +431,20 @@ static ssize_t ppc_htab_write(struct file * file, const char * buffer, static long long ppc_htab_lseek(struct file * file, loff_t offset, int orig) { + long long ret = -EINVAL; + + lock_kernel(); switch (orig) { case 0: file->f_pos = offset; - return(file->f_pos); + ret = file->f_pos; + break; case 1: file->f_pos += offset; - return(file->f_pos); - case 2: - return(-EINVAL); - default: - return(-EINVAL); + ret = file->f_pos; } + unlock_kernel(); + return ret; } int proc_dol2crvec(ctl_table *table, int write, struct file *filp, diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c index 99a76902d7d2..58ad86fa0c53 100644 --- a/arch/ppc/kernel/signal.c +++ b/arch/ppc/kernel/signal.c @@ -641,10 +641,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) /* FALLTHRU */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } } diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index ea9541286059..8a1ab082620e 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -602,6 +602,8 @@ sys_call_table: .long sys_ni_syscall /* 224 - reserved for posix_acl */ .rept 255-224 .long sys_ni_syscall + .long sys_gettid /* 226 */ + .long sys_tkill /* 227 */ .endr /* diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 3d2d8f88923d..2028a8340ec8 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -563,10 +563,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) /* FALLTHRU */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } } diff --git a/arch/s390x/kernel/entry.S b/arch/s390x/kernel/entry.S index c4f22df5a322..c761c92bfdff 100644 --- a/arch/s390x/kernel/entry.S +++ b/arch/s390x/kernel/entry.S @@ -635,6 +635,8 @@ sys_call_table: .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for posix_acl */ .rept 255-224 .long SYSCALL(sys_ni_syscall,sys_ni_syscall) + .long SYSCALL(sys_gettid,sys_gettid) + .long SYSCALL(sys_tkill,sys_tkill) .endr /* diff --git a/arch/s390x/kernel/linux32.c b/arch/s390x/kernel/linux32.c index 6f85af23b6c1..0db4c93950bb 100644 --- a/arch/s390x/kernel/linux32.c +++ b/arch/s390x/kernel/linux32.c @@ -1471,140 +1471,62 @@ out_nofds: return ret; } -static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf) -{ - unsigned long ino, blksize, blocks; - kdev_t dev, rdev; - umode_t mode; - nlink_t nlink; - uid_t uid; - gid_t gid; - off_t size; - time_t atime, mtime, ctime; - int err; - - /* Stream the loads of inode data into the load buffer, - * then we push it all into the store buffer below. This - * should give optimal cache performance. - */ - ino = inode->i_ino; - dev = inode->i_dev; - mode = inode->i_mode; - nlink = inode->i_nlink; - uid = inode->i_uid; - gid = inode->i_gid; - rdev = inode->i_rdev; - size = inode->i_size; - atime = inode->i_atime; - mtime = inode->i_mtime; - ctime = inode->i_ctime; - blksize = inode->i_blksize; - blocks = inode->i_blocks; - - err = put_user(kdev_t_to_nr(dev), &statbuf->st_dev); - err |= put_user(ino, &statbuf->st_ino); - err |= put_user(mode, &statbuf->st_mode); - err |= put_user(nlink, &statbuf->st_nlink); - err |= put_user(high2lowuid(uid), &statbuf->st_uid); - err |= put_user(high2lowgid(gid), &statbuf->st_gid); - err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev); - err |= put_user(size, &statbuf->st_size); - err |= put_user(atime, &statbuf->st_atime); +static int cp_new_stat32(struct kstat *stat, struct stat32 *statbuf) +{ + err = put_user(stat->dev, &statbuf->st_dev); + err |= put_user(stat->ino, &statbuf->st_ino); + err |= put_user(stat->mode, &statbuf->st_mode); + err |= put_user(stat->nlink, &statbuf->st_nlink); + err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid); + err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid); + err |= put_user(stat->rdev, &statbuf->st_rdev); + err |= put_user(stat->size, &statbuf->st_size); + err |= put_user(stat->atime, &statbuf->st_atime); err |= put_user(0, &statbuf->__unused1); - err |= put_user(mtime, &statbuf->st_mtime); + err |= put_user(stat->mtime, &statbuf->st_mtime); err |= put_user(0, &statbuf->__unused2); - err |= put_user(ctime, &statbuf->st_ctime); + err |= put_user(stat->ctime, &statbuf->st_ctime); err |= put_user(0, &statbuf->__unused3); - if (blksize) { - err |= put_user(blksize, &statbuf->st_blksize); - err |= put_user(blocks, &statbuf->st_blocks); - } else { - unsigned int tmp_blocks; - -#define D_B 7 -#define I_B (BLOCK_SIZE / sizeof(unsigned short)) - tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE; - if (tmp_blocks > D_B) { - unsigned int indirect; - - indirect = (tmp_blocks - D_B + I_B - 1) / I_B; - tmp_blocks += indirect; - if (indirect > 1) { - indirect = (indirect - 1 + I_B - 1) / I_B; - tmp_blocks += indirect; - if (indirect > 1) - tmp_blocks++; - } - } - err |= put_user(BLOCK_SIZE, &statbuf->st_blksize); - err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks); -#undef D_B -#undef I_B - } + err |= put_user(stat->blksize, &statbuf->st_blksize); + err |= put_user(stat->blocks, &statbuf->st_blocks); /* fixme err |= put_user(0, &statbuf->__unused4[0]); err |= put_user(0, &statbuf->__unused4[1]); */ - return err; } -/* Perhaps this belongs in fs.h or similar. -DaveM */ -static __inline__ int -do_revalidate(struct dentry *dentry) -{ - struct inode * inode = dentry->d_inode; - if (inode->i_op && inode->i_op->revalidate) - return inode->i_op->revalidate(dentry); - return 0; -} - asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf) { - struct nameidata nd; - int error; + struct kstat stat; + int error = vfs_stat(filename, &stat); + + if (!error) + error = cp_new_stat32(&stat, statbuf); - error = user_path_walk(filename, &nd); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat32(nd.dentry->d_inode, statbuf); - path_release(&nd); - } return error; } asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf) { - struct nameidata nd; - int error; + struct kstat stat; + int error = vfs_lstat(filename, &stat); - error = user_path_walk_link(filename, &nd); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat32(nd.dentry->d_inode, statbuf); + if (!error) + error = cp_new_stat32(&stat, statbuf); - path_release(&nd); - } return error; } asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf) { - struct file *f; - int err = -EBADF; + struct kstat stat; + int error = vfs_fstat(fd, &stat); - f = fget(fd); - if (f) { - struct dentry * dentry = f->f_dentry; + if (!error) + error = cp_new_stat32(&stat, statbuf); - err = do_revalidate(dentry); - if (!err) - err = cp_new_stat32(dentry->d_inode, statbuf); - fput(f); - } - return err; + return error; } extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2); diff --git a/arch/s390x/kernel/signal.c b/arch/s390x/kernel/signal.c index 74ec0561ffc9..3b7ab0620845 100644 --- a/arch/s390x/kernel/signal.c +++ b/arch/s390x/kernel/signal.c @@ -569,10 +569,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) /* FALLTHRU */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } } diff --git a/arch/s390x/kernel/signal32.c b/arch/s390x/kernel/signal32.c index 4b44690897a0..4a5dc1e44f05 100644 --- a/arch/s390x/kernel/signal32.c +++ b/arch/s390x/kernel/signal32.c @@ -699,10 +699,7 @@ int do_signal32(struct pt_regs *regs, sigset_t *oldset) /* FALLTHRU */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } } diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S index 620beadcfb6e..7f4042c28a7e 100644 --- a/arch/sh/kernel/entry.S +++ b/arch/sh/kernel/entry.S @@ -1195,6 +1195,8 @@ ENTRY(sys_call_table) .long SYMBOL_NAME(sys_madvise) .long SYMBOL_NAME(sys_getdents64) /* 220 */ .long SYMBOL_NAME(sys_fcntl64) + .long SYMBOL_NAME(sys_gettid) + .long SYMBOL_NAME(sys_tkill) /* * NOTE!! This doesn't have to be exact - we just have diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index 4f4cade82d6c..3e6077c7be83 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c @@ -673,10 +673,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) /* FALLTHRU */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOTREACHED */ } } diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c index 51bfe75ede92..e5bab88cd2d6 100644 --- a/arch/sparc/kernel/signal.c +++ b/arch/sparc/kernel/signal.c @@ -1280,10 +1280,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, #endif /* fall through */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOT REACHED */ } } diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c index 8dd283c38e85..5ea80c32d368 100644 --- a/arch/sparc/kernel/sys_sunos.c +++ b/arch/sparc/kernel/sys_sunos.c @@ -646,7 +646,7 @@ sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr) inode = file->f_dentry->d_inode; - socket = &inode->u.socket_i; + socket = SOCKET_I(inode); local.sin_family = AF_INET; local.sin_addr.s_addr = INADDR_ANY; diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index f77a1ab91d9d..85dd7cf2f037 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -70,7 +70,7 @@ sys_call_table: /*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler /*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep /*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl -/*255*/ .long sys_nis_syscall, sys_nis_syscall +/*255*/ .long sys_nis_syscall, sys_nis_syscall, sys_tkill #ifdef CONFIG_SUNOS_EMUL /* Now the SunOS syscall table. */ diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index 8a67b36fadaf..8745f7e6bd13 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c @@ -807,10 +807,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, #endif /* fall through */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOT REACHED */ } } diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 2058de8bd6bc..7dc93cc8e660 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c @@ -1479,10 +1479,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, #endif /* fall through */ default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(current); - current->flags |= PF_SIGNALED; - do_exit(exit_code); + sig_exit(signr, exit_code, &info); /* NOT REACHED */ } } diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 5ee8df8c502a..53987ffca5dc 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -1459,138 +1459,60 @@ out_nofds: return ret; } -static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf) -{ - unsigned long ino, blksize, blocks; - kdev_t dev, rdev; - umode_t mode; - nlink_t nlink; - uid_t uid; - gid_t gid; - off_t size; - time_t atime, mtime, ctime; - int err; - - /* Stream the loads of inode data into the load buffer, - * then we push it all into the store buffer below. This - * should give optimal cache performance. - */ - ino = inode->i_ino; - dev = inode->i_dev; - mode = inode->i_mode; - nlink = inode->i_nlink; - uid = inode->i_uid; - gid = inode->i_gid; - rdev = inode->i_rdev; - size = inode->i_size; - atime = inode->i_atime; - mtime = inode->i_mtime; - ctime = inode->i_ctime; - blksize = inode->i_blksize; - blocks = inode->i_blocks; - - err = put_user(kdev_t_to_nr(dev), &statbuf->st_dev); - err |= put_user(ino, &statbuf->st_ino); - err |= put_user(mode, &statbuf->st_mode); - err |= put_user(nlink, &statbuf->st_nlink); - err |= put_user(high2lowuid(uid), &statbuf->st_uid); - err |= put_user(high2lowgid(gid), &statbuf->st_gid); - err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev); - err |= put_user(size, &statbuf->st_size); - err |= put_user(atime, &statbuf->st_atime); +static int cp_new_stat32(struct kstat *stat, struct stat32 *statbuf) +{ + err = put_user(stat->dev, &statbuf->st_dev); + err |= put_user(stat->ino, &statbuf->st_ino); + err |= put_user(stat->mode, &statbuf->st_mode); + err |= put_user(stat->nlink, &statbuf->st_nlink); + err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid); + err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid); + err |= put_user(stat->rdev, &statbuf->st_rdev); + err |= put_user(stat->size, &statbuf->st_size); + err |= put_user(stat->atime, &statbuf->st_atime); err |= put_user(0, &statbuf->__unused1); - err |= put_user(mtime, &statbuf->st_mtime); + err |= put_user(stat->mtime, &statbuf->st_mtime); err |= put_user(0, &statbuf->__unused2); - err |= put_user(ctime, &statbuf->st_ctime); + err |= put_user(stat->ctime, &statbuf->st_ctime); err |= put_user(0, &statbuf->__unused3); - if (blksize) { - err |= put_user(blksize, &statbuf->st_blksize); - err |= put_user(blocks, &statbuf->st_blocks); - } else { - unsigned int tmp_blocks; - -#define D_B 7 -#define I_B (BLOCK_SIZE / sizeof(unsigned short)) - tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE; - if (tmp_blocks > D_B) { - unsigned int indirect; - - indirect = (tmp_blocks - D_B + I_B - 1) / I_B; - tmp_blocks += indirect; - if (indirect > 1) { - indirect = (indirect - 1 + I_B - 1) / I_B; - tmp_blocks += indirect; - if (indirect > 1) - tmp_blocks++; - } - } - err |= put_user(BLOCK_SIZE, &statbuf->st_blksize); - err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks); -#undef D_B -#undef I_B - } + err |= put_user(stat->blksize, &statbuf->st_blksize); + err |= put_user(stat->blocks, &statbuf->st_blocks); err |= put_user(0, &statbuf->__unused4[0]); err |= put_user(0, &statbuf->__unused4[1]); - return err; } -/* Perhaps this belongs in fs.h or similar. -DaveM */ -static __inline__ int -do_revalidate(struct dentry *dentry) -{ - struct inode * inode = dentry->d_inode; - if (inode->i_op && inode->i_op->revalidate) - return inode->i_op->revalidate(dentry); - return 0; -} - asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf) { - struct nameidata nd; - int error; + struct kstat stat; + int error = vfs_stat(filename, &stat); + + if (!error) + error = cp_new_stat32(&stat, statbuf); - error = user_path_walk(filename, &nd); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat32(nd.dentry->d_inode, statbuf); - path_release(&nd); - } return error; } asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf) { - struct nameidata nd; - int error; + struct kstat stat; + int error = vfs_lstat(filename, &stat); - error = user_path_walk_link(filename, &nd); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat32(nd.dentry->d_inode, statbuf); + if (!error) + error = cp_new_stat32(&stat, statbuf); - path_release(&nd); - } return error; } asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf) { - struct file *f; - int err = -EBADF; + struct kstat stat; + int error = vfs_fstat(fd, &stat); - f = fget(fd); - if (f) { - struct dentry * dentry = f->f_dentry; + if (!error) + error = cp_new_stat32(&stat, statbuf); - err = do_revalidate(dentry); - if (!err) - err = cp_new_stat32(dentry->d_inode, statbuf); - fput(f); - } - return err; + return error; } extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2); diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index 47e5a445a2a0..526a11af116f 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -612,7 +612,7 @@ sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr) inode = file->f_dentry->d_inode; - socket = &inode->u.socket_i; + socket = SOCKET_I(inode); local.sin_family = AF_INET; local.sin_addr.s_addr = INADDR_ANY; diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 92463d6ff849..d27d7a95d55e 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -70,7 +70,7 @@ sys_call_table32: /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, sys32_nanosleep /*250*/ .word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl - .word sys_aplib + .word sys_aplib, sys_tkill /* Now the 64-bit native Linux syscall table. */ @@ -129,7 +129,7 @@ sys_call_table: /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep /*250*/ .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl - .word sys_aplib + .word sys_aplib, sys_tkill #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ defined(CONFIG_SOLARIS_EMUL_MODULE) diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c index 0ba71673d306..82f941daab28 100644 --- a/arch/sparc64/solaris/fs.c +++ b/arch/sparc64/solaris/fs.c @@ -79,47 +79,49 @@ struct sol_stat64 { #define UFSMAGIC (((unsigned)'u'<<24)||((unsigned)'f'<<16)||((unsigned)'s'<<8)) -static inline int putstat(struct sol_stat *ubuf, struct stat *kbuf) -{ - if (put_user (R4_DEV(kbuf->st_dev), &ubuf->st_dev) || - __put_user (kbuf->st_ino, &ubuf->st_ino) || - __put_user (kbuf->st_mode, &ubuf->st_mode) || - __put_user (kbuf->st_nlink, &ubuf->st_nlink) || - __put_user (kbuf->st_uid, &ubuf->st_uid) || - __put_user (kbuf->st_gid, &ubuf->st_gid) || - __put_user (R4_DEV(kbuf->st_rdev), &ubuf->st_rdev) || - __put_user (kbuf->st_size, &ubuf->st_size) || - __put_user (kbuf->st_atime, &ubuf->st_atime.tv_sec) || +static inline int putstat(struct sol_stat *ubuf, struct kstat *kbuf) +{ + if (kbuf->size > MAX_NON_LFS) + return -EOVERFLOW; + if (put_user (R4_DEV(kbuf->dev), &ubuf->st_dev) || + __put_user (kbuf->ino, &ubuf->st_ino) || + __put_user (kbuf->mode, &ubuf->st_mode) || + __put_user (kbuf->nlink, &ubuf->st_nlink) || + __put_user (kbuf->uid, &ubuf->st_uid) || + __put_user (kbuf->gid, &ubuf->st_gid) || + __put_user (R4_DEV(kbuf->rdev), &ubuf->st_rdev) || + __put_user (kbuf->size, &ubuf->st_size) || + __put_user (kbuf->atime, &ubuf->st_atime.tv_sec) || __put_user (0, &ubuf->st_atime.tv_nsec) || - __put_user (kbuf->st_mtime, &ubuf->st_mtime.tv_sec) || + __put_user (kbuf->mtime, &ubuf->st_mtime.tv_sec) || __put_user (0, &ubuf->st_mtime.tv_nsec) || - __put_user (kbuf->st_ctime, &ubuf->st_ctime.tv_sec) || + __put_user (kbuf->ctime, &ubuf->st_ctime.tv_sec) || __put_user (0, &ubuf->st_ctime.tv_nsec) || - __put_user (kbuf->st_blksize, &ubuf->st_blksize) || - __put_user (kbuf->st_blocks, &ubuf->st_blocks) || + __put_user (kbuf->blksize, &ubuf->st_blksize) || + __put_user (kbuf->blocks, &ubuf->st_blocks) || __put_user (UFSMAGIC, (unsigned *)ubuf->st_fstype)) return -EFAULT; return 0; } -static inline int putstat64(struct sol_stat64 *ubuf, struct stat *kbuf) +static inline int putstat64(struct sol_stat64 *ubuf, struct kstat *kbuf) { - if (put_user (R4_DEV(kbuf->st_dev), &ubuf->st_dev) || - __put_user (kbuf->st_ino, &ubuf->st_ino) || - __put_user (kbuf->st_mode, &ubuf->st_mode) || - __put_user (kbuf->st_nlink, &ubuf->st_nlink) || - __put_user (kbuf->st_uid, &ubuf->st_uid) || - __put_user (kbuf->st_gid, &ubuf->st_gid) || - __put_user (R4_DEV(kbuf->st_rdev), &ubuf->st_rdev) || - __put_user (kbuf->st_size, &ubuf->st_size) || - __put_user (kbuf->st_atime, &ubuf->st_atime.tv_sec) || + if (put_user (R4_DEV(kbuf->dev), &ubuf->st_dev) || + __put_user (kbuf->ino, &ubuf->st_ino) || + __put_user (kbuf->mode, &ubuf->st_mode) || + __put_user (kbuf->nlink, &ubuf->st_nlink) || + __put_user (kbuf->uid, &ubuf->st_uid) || + __put_user (kbuf->gid, &ubuf->st_gid) || + __put_user (R4_DEV(kbuf->rdev), &ubuf->st_rdev) || + __put_user (kbuf->size, &ubuf->st_size) || + __put_user (kbuf->atime, &ubuf->st_atime.tv_sec) || __put_user (0, &ubuf->st_atime.tv_nsec) || - __put_user (kbuf->st_mtime, &ubuf->st_mtime.tv_sec) || + __put_user (kbuf->mtime, &ubuf->st_mtime.tv_sec) || __put_user (0, &ubuf->st_mtime.tv_nsec) || - __put_user (kbuf->st_ctime, &ubuf->st_ctime.tv_sec) || + __put_user (kbuf->ctime, &ubuf->st_ctime.tv_sec) || __put_user (0, &ubuf->st_ctime.tv_nsec) || - __put_user (kbuf->st_blksize, &ubuf->st_blksize) || - __put_user (kbuf->st_blocks, &ubuf->st_blocks) || + __put_user (kbuf->blksize, &ubuf->st_blksize) || + __put_user (kbuf->blocks, &ubuf->st_blocks) || __put_user (UFSMAGIC, (unsigned *)ubuf->st_fstype)) return -EFAULT; return 0; @@ -128,21 +130,18 @@ static inline int putstat64(struct sol_stat64 *ubuf, struct stat *kbuf) asmlinkage int solaris_stat(u32 filename, u32 statbuf) { int ret; - struct stat s; + struct kstat s; char *filenam; mm_segment_t old_fs = get_fs(); - int (*sys_newstat)(char *,struct stat *) = - (int (*)(char *,struct stat *))SYS(stat); filenam = getname ((char *)A(filename)); ret = PTR_ERR(filenam); if (!IS_ERR(filenam)) { set_fs (KERNEL_DS); - ret = sys_newstat(filenam, &s); + ret = vfs_stat(filenam, &s); set_fs (old_fs); putname (filenam); - if (putstat ((struct sol_stat *)A(statbuf), &s)) - return -EFAULT; + return putstat((struct sol_stat *)A(statbuf), &s); } return ret; } @@ -156,21 +155,18 @@ asmlinkage int solaris_xstat(int vers, u32 filename, u32 statbuf) asmlinkage int solaris_stat64(u32 filename, u32 statbuf) { int ret; - struct stat s; + struct kstat s; char *filenam; mm_segment_t old_fs = get_fs(); - int (*sys_newstat)(char *,struct stat *) = - (int (*)(char *,struct stat *))SYS(stat); filenam = getname ((char *)A(filename)); ret = PTR_ERR(filenam); if (!IS_ERR(filenam)) { set_fs (KERNEL_DS); - ret = sys_newstat(filenam, &s); + ret = vfs_stat(filenam, &s); set_fs (old_fs); putname (filenam); - if (putstat64 ((struct sol_stat64 *)A(statbuf), &s)) - return -EFAULT; + return putstat64((struct sol_stat64 *)A(statbuf), &s); } return ret; } @@ -178,21 +174,18 @@ asmlinkage int solaris_stat64(u32 filename, u32 statbuf) asmlinkage int solaris_lstat(u32 filename, u32 statbuf) { int ret; - struct stat s; + struct kstat s; char *filenam; mm_segment_t old_fs = get_fs(); - int (*sys_newlstat)(char *,struct stat *) = - (int (*)(char *,struct stat *))SYS(lstat); filenam = getname ((char *)A(filename)); ret = PTR_ERR(filenam); if (!IS_ERR(filenam)) { set_fs (KERNEL_DS); - ret = sys_newlstat(filenam, &s); + ret = vfs_lstat(filenam, &s); set_fs (old_fs); putname (filenam); - if (putstat ((struct sol_stat *)A(statbuf), &s)) - return -EFAULT; + return putstat((struct sol_stat *)A(statbuf), &s); } return ret; } @@ -205,21 +198,18 @@ asmlinkage int solaris_lxstat(int vers, u32 filename, u32 statbuf) asmlinkage int solaris_lstat64(u32 filename, u32 statbuf) { int ret; - struct stat s; + struct kstat s; char *filenam; mm_segment_t old_fs = get_fs(); - int (*sys_newlstat)(char *,struct stat *) = - (int (*)(char *,struct stat *))SYS(lstat); filenam = getname ((char *)A(filename)); ret = PTR_ERR(filenam); if (!IS_ERR(filenam)) { set_fs (KERNEL_DS); - ret = sys_newlstat(filenam, &s); + ret = vfs_lstat(filenam, &s); set_fs (old_fs); putname (filenam); - if (putstat64 ((struct sol_stat64 *)A(statbuf), &s)) - return -EFAULT; + return putstat64((struct sol_stat64 *)A(statbuf), &s); } return ret; } @@ -227,16 +217,10 @@ asmlinkage int solaris_lstat64(u32 filename, u32 statbuf) asmlinkage int solaris_fstat(unsigned int fd, u32 statbuf) { int ret; - struct stat s; - mm_segment_t old_fs = get_fs(); - int (*sys_newfstat)(unsigned,struct stat *) = - (int (*)(unsigned,struct stat *))SYS(fstat); - - set_fs (KERNEL_DS); - ret = sys_newfstat(fd, &s); - set_fs (old_fs); - if (putstat ((struct sol_stat *)A(statbuf), &s)) - return -EFAULT; + struct kstat s; + ret = vfs_fstat(fd, &s); + if (!ret) + return putstat((struct sol_stat *)A(statbuf), &s); return ret; } @@ -248,16 +232,11 @@ asmlinkage int solaris_fxstat(int vers, u32 fd, u32 statbuf) asmlinkage int solaris_fstat64(unsigned int fd, u32 statbuf) { int ret; - struct stat s; - mm_segment_t old_fs = get_fs(); - int (*sys_newfstat)(unsigned,struct stat *) = - (int (*)(unsigned,struct stat *))SYS(fstat); + struct kstat s; - set_fs (KERNEL_DS); - ret = sys_newfstat(fd, &s); - set_fs (old_fs); - if (putstat64 ((struct sol_stat64 *)A(statbuf), &s)) - return -EFAULT; + ret = vfs_fstat(fd, &s); + if (!ret) + return putstat64((struct sol_stat64 *)A(statbuf), &s); return ret; } diff --git a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c index 72c8f3405b40..a920499e23f4 100644 --- a/arch/sparc64/solaris/ioctl.c +++ b/arch/sparc64/solaris/ioctl.c @@ -308,7 +308,7 @@ static inline int solaris_sockmod(unsigned int fd, unsigned int cmd, u32 arg) case 110: /* SI_GETUDATA */ { int etsdusize, servtype; - switch (ino->u.socket_i.type) { + switch (SOCKET_I(ino)->type) { case SOCK_STREAM: etsdusize = 1; servtype = 2; @@ -326,16 +326,16 @@ static inline int solaris_sockmod(unsigned int fd, unsigned int cmd, u32 arg) __put_user(0, &((struct solaris_si_udata *)A(arg))->so_state) || __put_user(0, &((struct solaris_si_udata *)A(arg))->so_options) || __put_user(16384, &((struct solaris_si_udata *)A(arg))->tsdusize) || - __put_user(ino->u.socket_i.ops->family, &((struct solaris_si_udata *)A(arg))->sockparams.sp_family) || - __put_user(ino->u.socket_i.type, &((struct solaris_si_udata *)A(arg))->sockparams.sp_type) || - __put_user(ino->u.socket_i.ops->family, &((struct solaris_si_udata *)A(arg))->sockparams.sp_protocol)) + __put_user(SOCKET_I(ino)->ops->family, &((struct solaris_si_udata *)A(arg))->sockparams.sp_family) || + __put_user(SOCKET_I(ino)->type, &((struct solaris_si_udata *)A(arg))->sockparams.sp_type) || + __put_user(SOCKET_I(ino)->ops->family, &((struct solaris_si_udata *)A(arg))->sockparams.sp_protocol)) return (EFAULT << 8) | TSYSERR; return 0; } case 101: /* O_SI_GETUDATA */ { int etsdusize, servtype; - switch (ino->u.socket_i.type) { + switch (SOCKET_I(ino)->type) { case SOCK_STREAM: etsdusize = 1; servtype = 2; diff --git a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c index e40b380922c8..6233516951ac 100644 --- a/arch/sparc64/solaris/socket.c +++ b/arch/sparc64/solaris/socket.c @@ -248,12 +248,6 @@ asmlinkage int solaris_getsockname(int fd, struct sockaddr *addr, int *addrlen) 24 for IPv6, about 80 for AX.25 */ -/* XXX These as well... */ -extern __inline__ struct socket *socki_lookup(struct inode *inode) -{ - return &inode->u.socket_i; -} - extern __inline__ struct socket *sockfd_lookup(int fd, int *err) { struct file *file; @@ -265,13 +259,13 @@ extern __inline__ struct socket *sockfd_lookup(int fd, int *err) } inode = file->f_dentry->d_inode; - if (!inode->i_sock || !socki_lookup(inode)) { + if (!inode->i_sock) { *err = -ENOTSOCK; fput(file); return NULL; } - return socki_lookup(inode); + return SOCKET_I(inode); } extern __inline__ void sockfd_put(struct socket *sock) diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c index dd06c16183f8..f6d5fab7c315 100644 --- a/arch/sparc64/solaris/socksys.c +++ b/arch/sparc64/solaris/socksys.c @@ -6,6 +6,13 @@ * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk) */ +/* + * Dave, _please_ give me specifications on this fscking mess so that I + * could at least get it into the state when it wouldn't screw the rest of + * the kernel over. socksys.c and timod.c _stink_ and we are not talking + * H2S here, it's isopropilmercaptan in concentrations way over LD50. -- AV + */ + #include <linux/types.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -86,6 +93,9 @@ static int socksys_open(struct inode * inode, struct file * filp) return fd; /* * N.B. The following operations are not legal! + * + * No shit. WTF is it supposed to do, anyway? + * * Try instead: * d_delete(filp->f_dentry), then d_instantiate with sock inode */ @@ -93,7 +103,7 @@ static int socksys_open(struct inode * inode, struct file * filp) filp->f_dentry = dget(fcheck(fd)->f_dentry); filp->f_dentry->d_inode->i_rdev = inode->i_rdev; filp->f_dentry->d_inode->i_flock = inode->i_flock; - filp->f_dentry->d_inode->u.socket_i.file = filp; + SOCKET_I(filp->f_dentry->d_inode)->file = filp; filp->f_op = &socksys_file_ops; sock = (struct sol_socket_struct*) mykmalloc(sizeof(struct sol_socket_struct), GFP_KERNEL); diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c index d2799895117b..06e9590187ab 100644 --- a/arch/sparc64/solaris/timod.c +++ b/arch/sparc64/solaris/timod.c @@ -149,7 +149,7 @@ static void timod_wake_socket(unsigned int fd) struct socket *sock; SOLD("wakeing socket"); - sock = ¤t->files->fd[fd]->f_dentry->d_inode->u.socket_i; + sock = SOCKET_I(current->files->fd[fd]->f_dentry->d_inode); wake_up_interruptible(&sock->wait); read_lock(&sock->sk->callback_lock); if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags)) @@ -640,7 +640,7 @@ int timod_getmsg(unsigned int fd, char *ctl_buf, int ctl_maxlen, s32 *ctl_len, ino = filp->f_dentry->d_inode; sock = (struct sol_socket_struct *)filp->private_data; SOLDD(("%p %p\n", sock->pfirst, sock->pfirst ? sock->pfirst->next : NULL)); - if ( ctl_maxlen > 0 && !sock->pfirst && ino->u.socket_i.type == SOCK_STREAM + if ( ctl_maxlen > 0 && !sock->pfirst && SOCKET_I(ino)->type == SOCK_STREAM && sock->state == TS_IDLE) { SOLD("calling LISTEN"); args[0] = fd; @@ -730,7 +730,7 @@ int timod_getmsg(unsigned int fd, char *ctl_buf, int ctl_maxlen, s32 *ctl_len, *flags_p = 0; if (ctl_maxlen >= 0) { SOLD("ACCEPT perhaps?"); - if (ino->u.socket_i.type == SOCK_STREAM && sock->state == TS_IDLE) { + if (SOCKET_I(ino)->type == SOCK_STREAM && sock->state == TS_IDLE) { struct T_conn_ind ind; char *buf = getpage(); int len = BUF_SIZE; diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index c58f725576a5..80ce7fd4d72c 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -418,10 +418,13 @@ static int nbd_ioctl(struct inode *inode, struct file *file, file = fget(arg); if (file) { inode = file->f_dentry->d_inode; - /* N.B. Should verify that it's a socket */ - lo->file = file; - lo->sock = &inode->u.socket_i; - error = 0; + if (inode->i_sock) { + lo->file = file; + lo->sock = SOCKET_I(inode); + error = 0; + } else { + fput(file); + } } return error; case NBD_SET_BLKSIZE: diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index 4c511001e25a..d9bfb30183ac 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c @@ -120,11 +120,11 @@ int hci_usb_open(struct hci_dev *hdev) DBG("%s", hdev->name); husb->read_urb->dev = husb->udev; - if ((status = usb_submit_urb(husb->read_urb))) + if ((status = usb_submit_urb(husb->read_urb, GFP_KERNEL))) DBG("read submit failed. %d", status); husb->intr_urb->dev = husb->udev; - if ((status = usb_submit_urb(husb->intr_urb))) + if ((status = usb_submit_urb(husb->intr_urb, GFP_KERNEL))) DBG("interrupt submit failed. %d", status); hdev->flags |= HCI_RUNNING; @@ -428,7 +428,7 @@ static void hci_usb_bulk_read(struct urb *urb) resubmit: husb->read_urb->dev = husb->udev; - if ((status = usb_submit_urb(husb->read_urb))) + if ((status = usb_submit_urb(husb->read_urb, GFP_KERNEL))) DBG("%s read URB submit failed %d", husb->hdev.name, status); DBG("%s read URB re-submited", husb->hdev.name); @@ -453,7 +453,7 @@ static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb) FILL_CONTROL_URB(urb, husb->udev, pipe, (void*)dr, skb->data, skb->len, hci_usb_ctrl, skb); - if ((status = usb_submit_urb(urb))) { + if ((status = usb_submit_urb(urb, GFP_KERNEL))) { DBG("%s control URB submit failed %d", husb->hdev.name, status); return status; } @@ -474,7 +474,7 @@ static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb) hci_usb_bulk_write, skb); urb->transfer_flags |= USB_QUEUE_BULK; - if ((status = usb_submit_urb(urb))) { + if ((status = usb_submit_urb(urb, GFP_KERNEL))) { DBG("%s write URB submit failed %d", husb->hdev.name, status); return status; } diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index dc47bbc87e64..4fe439a995cc 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -221,11 +221,6 @@ static ssize_t hci_vhci_chr_read(struct file * file, char * buf, size_t count, l return ret; } -static loff_t hci_vhci_chr_lseek(struct file * file, loff_t offset, int origin) -{ - return -ESPIPE; -} - static int hci_vhci_chr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { return -EINVAL; @@ -296,7 +291,7 @@ static int hci_vhci_chr_close(struct inode *inode, struct file *file) static struct file_operations hci_vhci_fops = { owner: THIS_MODULE, - llseek: hci_vhci_chr_lseek, + llseek: no_lseek, read: hci_vhci_chr_read, write: hci_vhci_chr_write, poll: hci_vhci_chr_poll, diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 90e1e9956054..9df1b5af4d43 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -21,6 +21,7 @@ #include <linux/raw.h> #include <linux/tty.h> #include <linux/capability.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/io.h> @@ -466,16 +467,23 @@ static loff_t null_lseek(struct file * file, loff_t offset, int orig) */ static loff_t memory_lseek(struct file * file, loff_t offset, int orig) { + int ret; + + lock_kernel(); switch (orig) { case 0: file->f_pos = offset; - return file->f_pos; + ret = file->f_pos; + break; case 1: file->f_pos += offset; - return file->f_pos; + ret = file->f_pos; + break; default: - return -EINVAL; + ret = -EINVAL; } + unlock_kernel(); + return ret; } static int open_port(struct inode * inode, struct file * filp) diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index fae1d0e9490e..e8377d0358c7 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -216,6 +216,7 @@ void nvram_set_checksum( void ) static long long nvram_llseek(struct file *file,loff_t offset, int origin ) { + lock_kernel(); switch( origin ) { case 0: /* nothing to do */ @@ -227,6 +228,7 @@ static long long nvram_llseek(struct file *file,loff_t offset, int origin ) offset += NVRAM_BYTES; break; } + unlock_kernel(); return( (offset >= 0) ? (file->f_pos = offset) : -EINVAL ); } diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c index 58660979a036..5c343f2da4bb 100644 --- a/drivers/char/nwflash.c +++ b/drivers/char/nwflash.c @@ -26,6 +26,7 @@ #include <linux/spinlock.h> #include <linux/rwsem.h> #include <linux/init.h> +#include <linux/smp_lock.h> #include <asm/hardware/dec21285.h> #include <asm/io.h> @@ -301,30 +302,45 @@ static ssize_t flash_write(struct file *file, const char *buf, size_t size, loff */ static long long flash_llseek(struct file *file, long long offset, int orig) { + long long ret; + + lock_kernel(); if (flashdebug) printk(KERN_DEBUG "flash_llseek: offset=0x%X, orig=0x%X.\n", (unsigned int) offset, orig); switch (orig) { case 0: - if (offset < 0) - return -EINVAL; + if (offset < 0) { + ret = -EINVAL; + break; + } - if ((unsigned int) offset > gbFlashSize) - return -EINVAL; + if ((unsigned int) offset > gbFlashSize) { + ret = -EINVAL; + break; + } file->f_pos = (unsigned int) offset; - return file->f_pos; + ret = file->f_pos; + break; case 1: - if ((file->f_pos + offset) > gbFlashSize) - return -EINVAL; - if ((file->f_pos + offset) < 0) - return -EINVAL; + if ((file->f_pos + offset) > gbFlashSize) { + ret = -EINVAL; + break; + } + if ((file->f_pos + offset) < 0) { + ret = -EINVAL; + break; + } file->f_pos += offset; - return file->f_pos; + ret = file->f_pos; + break; default: - return -EINVAL; + ret = -EINVAL; } + unlock_kernel(); + return ret; } diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index 157ac042486f..ce001b8437cd 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c @@ -36,6 +36,7 @@ #include <linux/selection.h> #include <linux/kbd_kern.h> #include <linux/console.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/byteorder.h> #include <asm/unaligned.h> @@ -67,10 +68,13 @@ vcs_size(struct inode *inode) static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) { - int size = vcs_size(file->f_dentry->d_inode); + int size; + lock_kernel(); + size = vcs_size(file->f_dentry->d_inode); switch (orig) { default: + unlock_kernel(); return -EINVAL; case 2: offset += size; @@ -80,9 +84,12 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) case 0: break; } - if (offset < 0 || offset > size) + if (offset < 0 || offset > size) { + unlock_kernel(); return -EINVAL; + } file->f_pos = offset; + unlock_kernel(); return file->f_pos; } diff --git a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c index 1df5e3735adc..27e20390d248 100644 --- a/drivers/hotplug/pci_hotplug_core.c +++ b/drivers/hotplug/pci_hotplug_core.c @@ -362,7 +362,7 @@ static struct super_operations pcihpfs_ops = { put_inode: force_delete, }; -static struct super_block *pcihpfs_read_super (struct super_block *sb, void *data, int silent) +static int pcihpfs_fill_super(struct super_block *sb, void *data, int silent) { struct inode *inode; struct dentry *root; @@ -375,20 +375,31 @@ static struct super_block *pcihpfs_read_super (struct super_block *sb, void *dat if (!inode) { dbg("%s: could not get inode!\n",__FUNCTION__); - return NULL; + return -ENOMEM; } root = d_alloc_root(inode); if (!root) { dbg("%s: could not get root dentry!\n",__FUNCTION__); iput(inode); - return NULL; + return -ENOMEM; } sb->s_root = root; - return sb; + return 0; } -static DECLARE_FSTYPE(pcihpfs_fs_type, "pcihpfs", pcihpfs_read_super, FS_SINGLE | FS_LITTER); +static struct super_block *pcihpfs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_single(fs_type, flags, data, pcihpfs_fill_super); +} + +static struct file_system_type pcihpfs_type = { + owner: THIS_MODULE, + name: "pchihpfs", + get_sb: pcihpfs_get_sb, + fs_flags: FS_LITTER, +}; static int get_mount (void) { diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c index 0e6cebd5641b..2cae730599ec 100644 --- a/drivers/ieee1394/pcilynx.c +++ b/drivers/ieee1394/pcilynx.c @@ -29,6 +29,7 @@ #include <linux/pci.h> #include <linux/fs.h> #include <linux/poll.h> +#include <linux/smp_lock.h> #include <asm/byteorder.h> #include <asm/atomic.h> #include <asm/io.h> @@ -732,8 +733,9 @@ static unsigned int aux_poll(struct file *file, poll_table *pt) loff_t mem_llseek(struct file *file, loff_t offs, int orig) { - loff_t newoffs; + loff_t newoffs = -1; + lock_kernel(); switch (orig) { case 0: newoffs = offs; @@ -743,12 +745,12 @@ loff_t mem_llseek(struct file *file, loff_t offs, int orig) break; case 2: newoffs = PCILYNX_MAX_MEMORY + 1 + offs; - break; - default: - return -EINVAL; } - if (newoffs < 0 || newoffs > PCILYNX_MAX_MEMORY + 1) return -EINVAL; + if (newoffs < 0 || newoffs > PCILYNX_MAX_MEMORY + 1) { + lock_kernel(); + return -EINVAL; + } file->f_pos = newoffs; return newoffs; diff --git a/drivers/input/joystick/iforce.c b/drivers/input/joystick/iforce.c index bc9569fcc4db..f77ec220ba30 100644 --- a/drivers/input/joystick/iforce.c +++ b/drivers/input/joystick/iforce.c @@ -204,7 +204,7 @@ static void send_packet(struct iforce *iforce, u16 cmd, unsigned char* data) set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&iforce->wait, &wait); - if (usb_submit_urb(iforce->out)) { + if (usb_submit_urb(iforce->out, GFP_ATOMIC)) { set_current_state(TASK_RUNNING); remove_wait_queue(&iforce->wait, &wait); return; @@ -289,7 +289,7 @@ static int get_id_packet(struct iforce *iforce, char *packet) set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&iforce->wait, &wait); - if (usb_submit_urb(iforce->ctrl)) { + if (usb_submit_urb(iforce->ctrl, GFP_ATOMIC)) { set_current_state(TASK_RUNNING); remove_wait_queue(&iforce->wait, &wait); return -1; @@ -345,7 +345,7 @@ static int iforce_open(struct input_dev *dev) if (iforce->open++) break; iforce->irq->dev = iforce->usbdev; - if (usb_submit_urb(iforce->irq)) + if (usb_submit_urb(iforce->irq, GFP_KERNEL)) return -EIO; break; #endif diff --git a/drivers/isdn/avmb1/capifs.c b/drivers/isdn/avmb1/capifs.c index 823b3473702e..de29222349f0 100644 --- a/drivers/isdn/avmb1/capifs.c +++ b/drivers/isdn/avmb1/capifs.c @@ -281,17 +281,12 @@ static int capifs_parse_options(char *options, struct capifs_sb_info *sbi) return 0; } -struct super_block *capifs_read_super(struct super_block *s, void *data, - int silent) +static int capifs_fill_super(struct super_block *s, void *data, int silent) { struct inode * root_inode; struct dentry * root; struct capifs_sb_info *sbi; - /* Super block already completed? */ - if (s->s_root) - goto out; - sbi = (struct capifs_sb_info *) kmalloc(sizeof(struct capifs_sb_info), GFP_KERNEL); if ( !sbi ) goto fail; @@ -317,7 +312,6 @@ struct super_block *capifs_read_super(struct super_block *s, void *data, s->s_blocksize_bits = 10; s->s_magic = CAPIFS_SUPER_MAGIC; s->s_op = &capifs_sops; - s->s_root = NULL; /* * Get the root inode and dentry, but defer checking for errors. @@ -332,15 +326,6 @@ struct super_block *capifs_read_super(struct super_block *s, void *data, } root = d_alloc_root(root_inode); - /* - * Check whether somebody else completed the super block. - */ - if (s->s_root) { - if (root) dput(root); - else iput(root_inode); - goto out; - } - if (!root) { printk("capifs: get root dentry failed\n"); /* @@ -352,15 +337,6 @@ struct super_block *capifs_read_super(struct super_block *s, void *data, goto fail; } - /* - * Check whether somebody else completed the super block. - */ - if (s->s_root) - goto out; - - /* - * Success! Install the root dentry now to indicate completion. - */ s->s_root = root; sbi->next = mounts; @@ -368,11 +344,9 @@ struct super_block *capifs_read_super(struct super_block *s, void *data, SBI(sbi->next)->back = &(sbi->next); sbi->back = &mounts; mounts = s; - -out: /* Success ... somebody else completed the super block for us. */ - return s; + return 0; fail: - return NULL; + return -EINVAL; } static int capifs_statfs(struct super_block *sb, struct statfs *buf) @@ -400,7 +374,17 @@ static struct inode *capifs_new_inode(struct super_block *sb) return inode; } -static DECLARE_FSTYPE(capifs_fs_type, "capifs", capifs_read_super, 0); +static struct super_block *capifs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_nodev(fs_type, flags, data, capifs_fill_super); +} + +static struct file_system_type capifs_fs_type = { + owner: THIS_MODULE, + name: "capifs", + get_sb: capifs_get_sb, +}; void capifs_new_ncci(char type, unsigned int num, kdev_t device) { diff --git a/drivers/isdn/hisax/st5481.h b/drivers/isdn/hisax/st5481.h index 3c6e70880408..d5b7ea975088 100644 --- a/drivers/isdn/hisax/st5481.h +++ b/drivers/isdn/hisax/st5481.h @@ -409,10 +409,10 @@ struct st5481_adapter { * Submit an URB with error reporting. This is a macro so * the __FUNCTION__ returns the caller function name. */ -#define SUBMIT_URB(urb) \ +#define SUBMIT_URB(urb, mem_flags) \ ({ \ int status; \ - if ((status = usb_submit_urb(urb)) < 0) { \ + if ((status = usb_submit_urb(urb, mem_flags)) < 0) { \ WARN("usb_submit_urb failed,status=%d", status); \ } \ status; \ diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c index 06670d18003f..22576dfd14f0 100644 --- a/drivers/isdn/hisax/st5481_b.c +++ b/drivers/isdn/hisax/st5481_b.c @@ -115,7 +115,7 @@ static void usb_b_out(struct st5481_bcs *bcs,int buf_nr) DBG_ISO_PACKET(0x200,urb); - SUBMIT_URB(urb); + SUBMIT_URB(urb, GFP_KERNEL); } /* diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c index cd9b0389f491..17f670d864ee 100644 --- a/drivers/isdn/hisax/st5481_d.c +++ b/drivers/isdn/hisax/st5481_d.c @@ -356,10 +356,10 @@ static void usb_d_out(struct st5481_adapter *adapter, int buf_nr) DBG_ISO_PACKET(0x20,urb); - if (usb_submit_urb(urb) < 0) { + if (usb_submit_urb(urb, GFP_KERNEL) < 0) { // There is another URB queued up urb->transfer_flags = USB_ISO_ASAP; - SUBMIT_URB(urb); + SUBMIT_URB(urb, GFP_KERNEL); } } @@ -450,7 +450,7 @@ static void dout_start_xmit(struct FsmInst *fsm, int event, void *arg) urb->transfer_flags = USB_ISO_ASAP; DBG_ISO_PACKET(0x20,urb); - SUBMIT_URB(urb); + SUBMIT_URB(urb, GFP_KERNEL); } static void dout_short_fifo(struct FsmInst *fsm, int event, void *arg) diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c index a3e776f4d3e8..15f8dca9f431 100644 --- a/drivers/isdn/hisax/st5481_usb.c +++ b/drivers/isdn/hisax/st5481_usb.c @@ -48,7 +48,7 @@ static void usb_next_ctrl_msg(struct urb *urb, // Prepare the URB urb->dev = adapter->usb_dev; - SUBMIT_URB(urb); + SUBMIT_URB(urb, GFP_KERNEL); } /* @@ -357,7 +357,7 @@ void __devinit st5481_start(struct st5481_adapter *adapter) adapter->leds = RED_LED; // Start receiving on the interrupt endpoint - SUBMIT_URB(intr->urb); + SUBMIT_URB(intr->urb, GFP_KERNEL); while ((request = init_cmd_table[i++])) { value = init_cmd_table[i++]; @@ -517,7 +517,7 @@ static void usb_in_complete(struct urb *urb) urb->dev = in->adapter->usb_dev; urb->actual_length = 0; - SUBMIT_URB(urb); + SUBMIT_URB(urb, GFP_KERNEL); } int __devinit st5481_setup_in(struct st5481_in *in) @@ -603,10 +603,10 @@ static void st5481_start_rcv(void *context) DBG(4,""); in->urb[0]->dev = adapter->usb_dev; - SUBMIT_URB(in->urb[0]); + SUBMIT_URB(in->urb[0], GFP_KERNEL); in->urb[1]->dev = adapter->usb_dev; - SUBMIT_URB(in->urb[1]); + SUBMIT_URB(in->urb[1], GFP_KERNEL); } void st5481_in_mode(struct st5481_in *in, int mode) diff --git a/drivers/macintosh/nvram.c b/drivers/macintosh/nvram.c index 4e7db7cd310d..049433afeeaf 100644 --- a/drivers/macintosh/nvram.c +++ b/drivers/macintosh/nvram.c @@ -13,6 +13,7 @@ #include <linux/fcntl.h> #include <linux/nvram.h> #include <linux/init.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/nvram.h> @@ -20,6 +21,7 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) { + lock_kernel(); switch (origin) { case 1: offset += file->f_pos; @@ -28,9 +30,12 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) offset += NVRAM_SIZE; break; } - if (offset < 0) + if (offset < 0) { + unlock_kernel(); return -EINVAL; + } file->f_pos = offset; + unlock_kernel(); return file->f_pos; } diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c index 474b05c773ea..c3a1949f732a 100644 --- a/drivers/media/video/cpia_usb.c +++ b/drivers/media/video/cpia_usb.c @@ -246,13 +246,13 @@ static int cpia_usb_open(void *privdata) ucpia->sbuf[1].urb->next = ucpia->sbuf[0].urb; ucpia->sbuf[0].urb->next = ucpia->sbuf[1].urb; - err = usb_submit_urb(ucpia->sbuf[0].urb); + err = usb_submit_urb(ucpia->sbuf[0].urb, GFP_KERNEL); if (err) { printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 0 ret %d\n", err); goto error_urb1; } - err = usb_submit_urb(ucpia->sbuf[1].urb); + err = usb_submit_urb(ucpia->sbuf[1].urb, GFP_KERNEL); if (err) { printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 1 ret %d\n", err); diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index f602eb2b046b..9b30043aea23 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -10,6 +10,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/mtd/mtd.h> +#include <linux/smp_lock.h> #include <linux/slab.h> #ifdef CONFIG_DEVFS_FS @@ -31,6 +32,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) { struct mtd_info *mtd=(struct mtd_info *)file->private_data; + lock_kernel(); switch (orig) { case 0: /* SEEK_SET */ @@ -45,6 +47,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) file->f_pos =mtd->size + offset; break; default: + unlock_kernel(); return -EINVAL; } @@ -53,6 +56,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) else if (file->f_pos >= mtd->size) file->f_pos = mtd->size - 1; + unlock_kernel(); return file->f_pos; } diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 99682aa9a3e7..de87d319237f 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -278,7 +278,7 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) urb->transfer_flags = USB_QUEUE_BULK | USB_ASYNC_UNLINK; urb->timeout = MSECS_TO_JIFFIES(100); - if ((ret = usb_submit_urb(urb))) { + if ((ret = usb_submit_urb(urb, GFP_KERNEL))) { WARNING(__FUNCTION__ "(), failed Speed URB\n"); } spin_unlock_irqrestore(&self->lock, flags); @@ -451,7 +451,7 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) } /* Ask USB to send the packet */ - if ((res = usb_submit_urb(urb))) { + if ((res = usb_submit_urb(urb, GFP_KERNEL))) { WARNING(__FUNCTION__ "(), failed Tx URB\n"); self->stats.tx_errors++; /* Let USB recover : We will catch that in the watchdog */ @@ -730,7 +730,7 @@ static void irda_usb_submit(struct irda_usb_cb *self, struct sk_buff *skb, struc urb->status = 0; urb->next = NULL; /* Don't auto resubmit URBs */ - ret = usb_submit_urb(urb); + ret = usb_submit_urb(urb, GFP_KERNEL); if (ret) { /* If this ever happen, we are in deep s***. * Basically, the Rx path will stop... */ diff --git a/drivers/net/wan/comx.c b/drivers/net/wan/comx.c index 2d673bfda099..96d6f326ceb5 100644 --- a/drivers/net/wan/comx.c +++ b/drivers/net/wan/comx.c @@ -876,7 +876,7 @@ cleanup_dev: static int comx_rmdir(struct inode *dir, struct dentry *dentry) { - struct proc_dir_entry *entry = dentry->d_inode->u.generic_ip; + struct proc_dir_entry *entry = PDE(dentry->d_inode); struct net_device *dev = entry->data; struct comx_channel *ch = dev->priv; int ret; @@ -928,7 +928,7 @@ static struct dentry *comx_lookup(struct inode *dir, struct dentry *dentry) struct proc_dir_entry *de; struct inode *inode = NULL; - if ((de = (struct proc_dir_entry *) dir->u.generic_ip) != NULL) { + if ((de = PDE(dir)) != NULL) { for (de = de->subdir ; de ; de = de->next) { if ((de && de->low_ino) && (de->namelen == dentry->d_name.len) && diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 96448599116c..72f4225836d1 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -2280,7 +2280,7 @@ static ssize_t proc_write( struct file *file, static int proc_status_open( struct inode *inode, struct file *file ) { struct proc_data *data; - struct proc_dir_entry *dp = inode->u.generic_ip; + struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *apriv = (struct airo_info *)dev->priv; CapabilityRid cap_rid; @@ -2289,8 +2289,6 @@ static int proc_status_open( struct inode *inode, struct file *file ) { MOD_INC_USE_COUNT; - dp = inode->u.generic_ip; - if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; memset(file->private_data, 0, sizeof(struct proc_data)); @@ -2364,7 +2362,7 @@ static int proc_stats_rid_open( struct inode *inode, struct file *file, u16 rid ) { struct proc_data *data; - struct proc_dir_entry *dp = inode->u.generic_ip; + struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *apriv = (struct airo_info *)dev->priv; StatsRid stats; @@ -2372,9 +2370,6 @@ static int proc_stats_rid_open( struct inode *inode, int *vals = stats.vals; MOD_INC_USE_COUNT; - - dp = inode->u.generic_ip; - if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; memset(file->private_data, 0, sizeof(struct proc_data)); @@ -2433,7 +2428,7 @@ static void checkThrottle(ConfigRid *config) { static void proc_config_on_close( struct inode *inode, struct file *file ) { struct proc_data *data = file->private_data; - struct proc_dir_entry *dp = inode->u.generic_ip; + struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *ai = (struct airo_info*)dev->priv; ConfigRid config; @@ -2442,7 +2437,6 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) { int need_reset = 0; if ( !data->writelen ) return; - dp = (struct proc_dir_entry *) inode->u.generic_ip; disable_MAC(ai); readConfigRid(ai, &config); @@ -2629,7 +2623,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) { static int proc_config_open( struct inode *inode, struct file *file ) { struct proc_data *data; - struct proc_dir_entry *dp = inode->u.generic_ip; + struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *ai = (struct airo_info*)dev->priv; ConfigRid config; @@ -2637,8 +2631,6 @@ static int proc_config_open( struct inode *inode, struct file *file ) { MOD_INC_USE_COUNT; - dp = (struct proc_dir_entry *) inode->u.generic_ip; - if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; memset(file->private_data, 0, sizeof(struct proc_data)); @@ -2723,7 +2715,7 @@ static int proc_config_open( struct inode *inode, struct file *file ) { static void proc_SSID_on_close( struct inode *inode, struct file *file ) { struct proc_data *data = (struct proc_data *)file->private_data; - struct proc_dir_entry *dp = inode->u.generic_ip; + struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *ai = (struct airo_info*)dev->priv; SsidRid SSID_rid; @@ -2759,7 +2751,7 @@ inline static u8 hexVal(char c) { static void proc_APList_on_close( struct inode *inode, struct file *file ) { struct proc_data *data = (struct proc_data *)file->private_data; - struct proc_dir_entry *dp = inode->u.generic_ip; + struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *ai = (struct airo_info*)dev->priv; APListRid APList_rid; @@ -2852,7 +2844,7 @@ static int set_wep_key(struct airo_info *ai, u16 index, static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { struct proc_data *data; - struct proc_dir_entry *dp = inode->u.generic_ip; + struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *ai = (struct airo_info*)dev->priv; int i; @@ -2862,7 +2854,6 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { memset(key, 0, sizeof(key)); - dp = (struct proc_dir_entry *) inode->u.generic_ip; data = (struct proc_data *)file->private_data; if ( !data->writelen ) return; @@ -2894,7 +2885,7 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { static int proc_wepkey_open( struct inode *inode, struct file *file ) { struct proc_data *data; - struct proc_dir_entry *dp = inode->u.generic_ip; + struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *ai = (struct airo_info*)dev->priv; char *ptr; @@ -2905,8 +2896,6 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) { MOD_INC_USE_COUNT; - dp = (struct proc_dir_entry *) inode->u.generic_ip; - if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; memset(file->private_data, 0, sizeof(struct proc_data)); @@ -2948,7 +2937,7 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) { static int proc_SSID_open( struct inode *inode, struct file *file ) { struct proc_data *data; - struct proc_dir_entry *dp = inode->u.generic_ip; + struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *ai = (struct airo_info*)dev->priv; int i; @@ -2957,8 +2946,6 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) { MOD_INC_USE_COUNT; - dp = (struct proc_dir_entry *) inode->u.generic_ip; - if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; memset(file->private_data, 0, sizeof(struct proc_data)); @@ -2996,7 +2983,7 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) { static int proc_APList_open( struct inode *inode, struct file *file ) { struct proc_data *data; - struct proc_dir_entry *dp = inode->u.generic_ip; + struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *ai = (struct airo_info*)dev->priv; int i; @@ -3005,8 +2992,6 @@ static int proc_APList_open( struct inode *inode, struct file *file ) { MOD_INC_USE_COUNT; - dp = (struct proc_dir_entry *) inode->u.generic_ip; - if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; memset(file->private_data, 0, sizeof(struct proc_data)); @@ -3048,7 +3033,7 @@ static int proc_APList_open( struct inode *inode, struct file *file ) { static int proc_BSSList_open( struct inode *inode, struct file *file ) { struct proc_data *data; - struct proc_dir_entry *dp = inode->u.generic_ip; + struct proc_dir_entry *dp = PDE(inode); struct net_device *dev = dp->data; struct airo_info *ai = (struct airo_info*)dev->priv; char *ptr; @@ -3059,8 +3044,6 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) { MOD_INC_USE_COUNT; - dp = (struct proc_dir_entry *) inode->u.generic_ip; - if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) return -ENOMEM; memset(file->private_data, 0, sizeof(struct proc_data)); diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 81ad8145422d..3bc810d5ae47 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -12,6 +12,7 @@ #include <linux/proc_fs.h> #include <linux/init.h> #include <linux/seq_file.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/byteorder.h> @@ -21,8 +22,9 @@ static loff_t proc_bus_pci_lseek(struct file *file, loff_t off, int whence) { - loff_t new; + loff_t new = -1; + lock_kernel(); switch (whence) { case 0: new = off; @@ -33,9 +35,8 @@ proc_bus_pci_lseek(struct file *file, loff_t off, int whence) case 2: new = PCI_CFG_SPACE_SIZE + off; break; - default: - return -EINVAL; } + unlock_kernel(); if (new < 0 || new > PCI_CFG_SPACE_SIZE) return -EINVAL; return (file->f_pos = new); @@ -45,7 +46,7 @@ static ssize_t proc_bus_pci_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) { const struct inode *ino = file->f_dentry->d_inode; - const struct proc_dir_entry *dp = ino->u.generic_ip; + const struct proc_dir_entry *dp = PDE(ino); struct pci_dev *dev = dp->data; unsigned int pos = *ppos; unsigned int cnt, size; @@ -127,7 +128,7 @@ static ssize_t proc_bus_pci_write(struct file *file, const char *buf, size_t nbytes, loff_t *ppos) { const struct inode *ino = file->f_dentry->d_inode; - const struct proc_dir_entry *dp = ino->u.generic_ip; + const struct proc_dir_entry *dp = PDE(ino); struct pci_dev *dev = dp->data; int pos = *ppos; int cnt; @@ -199,7 +200,7 @@ struct pci_filp_private { static int proc_bus_pci_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - const struct proc_dir_entry *dp = inode->u.generic_ip; + const struct proc_dir_entry *dp = PDE(inode); struct pci_dev *dev = dp->data; #ifdef HAVE_PCI_MMAP struct pci_filp_private *fpriv = file->private_data; @@ -241,7 +242,7 @@ static int proc_bus_pci_ioctl(struct inode *inode, struct file *file, unsigned i static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) { struct inode *inode = file->f_dentry->d_inode; - const struct proc_dir_entry *dp = inode->u.generic_ip; + const struct proc_dir_entry *dp = PDE(inode); struct pci_dev *dev = dp->data; struct pci_filp_private *fpriv = file->private_data; int ret; diff --git a/drivers/pnp/isapnp_proc.c b/drivers/pnp/isapnp_proc.c index 08085e106b13..f359e7539314 100644 --- a/drivers/pnp/isapnp_proc.c +++ b/drivers/pnp/isapnp_proc.c @@ -84,18 +84,26 @@ static void isapnp_devid(char *str, unsigned short vendor, unsigned short device static loff_t isapnp_info_entry_lseek(struct file *file, loff_t offset, int orig) { + loff_t ret; + + lock_kernel(); + switch (orig) { case 0: /* SEEK_SET */ file->f_pos = offset; - return file->f_pos; + ret = file->f_pos; + break; case 1: /* SEEK_CUR */ file->f_pos += offset; - return file->f_pos; + ret = file->f_pos; + break; case 2: /* SEEK_END */ default: - return -EINVAL; + ret = -EINVAL; } - return -ENXIO; + + unlock_kernel(); + return ret; } static ssize_t isapnp_info_entry_read(struct file *file, char *buffer, @@ -211,8 +219,9 @@ static struct file_operations isapnp_info_entry_operations = static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence) { - loff_t new; - + loff_t new = -1; + + lock_kernel(); switch (whence) { case 0: new = off; @@ -223,18 +232,19 @@ static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence) case 2: new = 256 + off; break; - default: - return -EINVAL; } - if (new < 0 || new > 256) + if (new < 0 || new > 256) { + unlock_kernel(); return -EINVAL; + } + unlock_kernel(); return (file->f_pos = new); } static ssize_t isapnp_proc_bus_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) { struct inode *ino = file->f_dentry->d_inode; - struct proc_dir_entry *dp = ino->u.generic_ip; + struct proc_dir_entry *dp = PDE(ino); struct pci_dev *dev = dp->data; int pos = *ppos; int cnt, size = 256; diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index b86a62475ffa..383fa671a3df 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -83,6 +83,7 @@ flash_mmap(struct file *file, struct vm_area_struct *vma) static long long flash_llseek(struct file *file, long long offset, int origin) { + lock_kernel(); switch (origin) { case 0: file->f_pos = offset; @@ -96,8 +97,10 @@ flash_llseek(struct file *file, long long offset, int origin) file->f_pos = flash.read_size; break; default: + unlock_kernel(); return -EINVAL; } + unlock_kernel(); return file->f_pos; } diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c index cc42d1577e34..05b38ff0dc9f 100644 --- a/drivers/sbus/char/jsflash.c +++ b/drivers/sbus/char/jsflash.c @@ -259,16 +259,23 @@ static void jsfd_do_request(request_queue_t *q) */ static loff_t jsf_lseek(struct file * file, loff_t offset, int orig) { + loff_t ret; + + lock_kernel(); switch (orig) { case 0: file->f_pos = offset; - return file->f_pos; + ret = file->f_pos; + break; case 1: file->f_pos += offset; - return file->f_pos; + ret = file->f_pos; + break; default: - return -EINVAL; + ret = -EINVAL; } + unlock_kernel(); + return ret; } /* diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 554dc6b446c4..dd123e96b497 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -87,13 +87,16 @@ static void scsi_dump_status(int level); struct scsi_host_sg_pool { int size; + char *name; kmem_cache_t *slab; mempool_t *pool; }; -static const int scsi_host_sg_pool_sizes[SG_MEMPOOL_NR] = { 8, 16, 32, 64, MAX_PHYS_SEGMENTS }; -struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR]; - +#define SP(x) { x, "sgpool-" #x } +struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR] = { + SP(8), SP(16), SP(32), SP(64), SP(MAX_PHYS_SEGMENTS) +}; +#undef SP /* static const char RCSid[] = "$Header: /vger/u4/cvs/linux/drivers/scsi/scsi.c,v 1.38 1997/01/19 23:07:18 davem Exp $"; */ @@ -2489,7 +2492,6 @@ void scsi_free_sgtable(struct scatterlist *sgl, int index) static int __init init_scsi(void) { struct proc_dir_entry *generic; - char name[16]; int i; printk(KERN_INFO "SCSI subsystem driver " REVISION "\n"); @@ -2499,18 +2501,15 @@ static int __init init_scsi(void) */ for (i = 0; i < SG_MEMPOOL_NR; i++) { struct scsi_host_sg_pool *sgp = scsi_sg_pools + i; - int size = scsi_host_sg_pool_sizes[i] * sizeof(struct scatterlist); + int size = sgp->size * sizeof(struct scatterlist); - snprintf(name, sizeof(name) - 1, "sgpool-%d", scsi_host_sg_pool_sizes[i]); - sgp->slab = kmem_cache_create(name, size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL); + sgp->slab = kmem_cache_create(sgp->name, size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if (!sgp->slab) panic("SCSI: can't init sg slab\n"); sgp->pool = mempool_create(SG_MEMPOOL_SIZE, scsi_pool_alloc, scsi_pool_free, sgp->slab); if (!sgp->pool) panic("SCSI: can't init sg mempool\n"); - - sgp->size = size; } /* diff --git a/drivers/sound/ite8172.c b/drivers/sound/ite8172.c index 22844c9c9037..3534696663de 100644 --- a/drivers/sound/ite8172.c +++ b/drivers/sound/ite8172.c @@ -824,12 +824,6 @@ static void it8172_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* --------------------------------------------------------------------- */ -static loff_t it8172_llseek(struct file *file, loff_t offset, int origin) -{ - return -ESPIPE; -} - - static int it8172_open_mixdev(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); @@ -870,7 +864,7 @@ static int it8172_ioctl_mixdev(struct inode *inode, struct file *file, static /*const*/ struct file_operations it8172_mixer_fops = { owner: THIS_MODULE, - llseek: it8172_llseek, + llseek: no_llseek, ioctl: it8172_ioctl_mixdev, open: it8172_open_mixdev, release: it8172_release_mixdev, @@ -1633,7 +1627,7 @@ static int it8172_release(struct inode *inode, struct file *file) static /*const*/ struct file_operations it8172_audio_fops = { owner: THIS_MODULE, - llseek: it8172_llseek, + llseek: no_llseek, read: it8172_read, write: it8172_write, poll: it8172_poll, diff --git a/drivers/sound/nec_vrc5477.c b/drivers/sound/nec_vrc5477.c index f9589ce8bf8e..2fe779caf9f2 100644 --- a/drivers/sound/nec_vrc5477.c +++ b/drivers/sound/nec_vrc5477.c @@ -805,12 +805,6 @@ static void vrc5477_ac97_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* --------------------------------------------------------------------- */ -static loff_t vrc5477_ac97_llseek(struct file *file, loff_t offset, int origin) -{ - return -ESPIPE; -} - - static int vrc5477_ac97_open_mixdev(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); @@ -852,7 +846,7 @@ static int vrc5477_ac97_ioctl_mixdev(struct inode *inode, struct file *file, static /*const*/ struct file_operations vrc5477_ac97_mixer_fops = { owner: THIS_MODULE, - llseek: vrc5477_ac97_llseek, + llseek: no_llseek, ioctl: vrc5477_ac97_ioctl_mixdev, open: vrc5477_ac97_open_mixdev, release: vrc5477_ac97_release_mixdev, @@ -1618,7 +1612,7 @@ static int vrc5477_ac97_release(struct inode *inode, struct file *file) static /*const*/ struct file_operations vrc5477_ac97_audio_fops = { owner: THIS_MODULE, - llseek: vrc5477_ac97_llseek, + llseek: no_llseek, read: vrc5477_ac97_read, write: vrc5477_ac97_write, poll: vrc5477_ac97_poll, diff --git a/drivers/usb/CDCEther.c b/drivers/usb/CDCEther.c index defae1cd4a72..fc360a9c5337 100644 --- a/drivers/usb/CDCEther.c +++ b/drivers/usb/CDCEther.c @@ -132,7 +132,7 @@ goon: // Give this to the USB subsystem so it can tell us // when more data arrives. - if ( (res = usb_submit_urb(ether_dev->rx_urb)) ) { + if ( (res = usb_submit_urb(ether_dev->rx_urb, GFP_KERNEL)) ) { warn( __FUNCTION__ " failed submint rx_urb %d", res); } @@ -302,7 +302,7 @@ static int CDCEther_start_xmit( struct sk_buff *skb, struct net_device *net ) ether_dev->tx_urb->transfer_buffer_length = count; // Send the URB on its merry way. - if ((res = usb_submit_urb(ether_dev->tx_urb))) { + if ((res = usb_submit_urb(ether_dev->tx_urb, GFP_KERNEL))) { // Hmm... It didn't go. Tell someone... warn("failed tx_urb %d", res); // update some stats... @@ -350,7 +350,7 @@ static int CDCEther_open(struct net_device *net) read_bulk_callback, ether_dev ); // Put it out there so the device can send us stuff - if ( (res = usb_submit_urb(ether_dev->rx_urb)) ) + if ( (res = usb_submit_urb(ether_dev->rx_urb, GFP_KERNEL)) ) { // Hmm... Okay... warn( __FUNCTION__ " failed rx_urb %d", res ); diff --git a/drivers/usb/acm.c b/drivers/usb/acm.c index e8834c190a48..77c42d87f551 100644 --- a/drivers/usb/acm.c +++ b/drivers/usb/acm.c @@ -261,7 +261,7 @@ static void acm_read_bulk(struct urb *urb) urb->actual_length = 0; urb->dev = acm->dev; - if (usb_submit_urb(urb)) + if (usb_submit_urb(urb, GFP_KERNEL)) dbg("failed resubmitting read urb"); } @@ -316,11 +316,11 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) unlock_kernel(); acm->ctrlurb.dev = acm->dev; - if (usb_submit_urb(&acm->ctrlurb)) + if (usb_submit_urb(&acm->ctrlurb, GFP_KERNEL)) dbg("usb_submit_urb(ctrl irq) failed"); acm->readurb.dev = acm->dev; - if (usb_submit_urb(&acm->readurb)) + if (usb_submit_urb(&acm->readurb, GFP_KERNEL)) dbg("usb_submit_urb(read bulk) failed"); acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS); @@ -371,7 +371,7 @@ static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned c acm->writeurb.transfer_buffer_length = count; acm->writeurb.dev = acm->dev; - if (usb_submit_urb(&acm->writeurb)) + if (usb_submit_urb(&acm->writeurb, GFP_KERNEL)) dbg("usb_submit_urb(write bulk) failed"); return count; diff --git a/drivers/usb/audio.c b/drivers/usb/audio.c index a1d11494233e..bad6151b0913 100644 --- a/drivers/usb/audio.c +++ b/drivers/usb/audio.c @@ -917,7 +917,7 @@ static void usbin_completed(struct urb *urb) if (!usbin_retire_desc(u, urb) && u->flags & FLG_RUNNING && !usbin_prepare_desc(u, urb) && - (suret = usb_submit_urb(urb)) == 0) { + (suret = usb_submit_urb(urb, GFP_KERNEL)) == 0) { u->flags |= mask; } else { u->flags &= ~(mask | FLG_RUNNING); @@ -982,7 +982,7 @@ static void usbin_sync_completed(struct urb *urb) if (!usbin_sync_retire_desc(u, urb) && u->flags & FLG_RUNNING && !usbin_sync_prepare_desc(u, urb) && - (suret = usb_submit_urb(urb)) == 0) { + (suret = usb_submit_urb(urb, GFP_KERNEL)) == 0) { u->flags |= mask; } else { u->flags &= ~(mask | FLG_RUNNING); @@ -1055,7 +1055,7 @@ static int usbin_start(struct usb_audiodev *as) urb->number_of_packets = DESCFRAMES; urb->context = as; urb->complete = usbin_completed; - if (!usbin_prepare_desc(u, urb) && !usb_submit_urb(urb)) + if (!usbin_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) u->flags |= FLG_URB0RUNNING; else u->flags &= ~FLG_RUNNING; @@ -1068,7 +1068,7 @@ static int usbin_start(struct usb_audiodev *as) urb->number_of_packets = DESCFRAMES; urb->context = as; urb->complete = usbin_completed; - if (!usbin_prepare_desc(u, urb) && !usb_submit_urb(urb)) + if (!usbin_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) u->flags |= FLG_URB1RUNNING; else u->flags &= ~FLG_RUNNING; @@ -1083,7 +1083,7 @@ static int usbin_start(struct usb_audiodev *as) urb->context = as; urb->complete = usbin_sync_completed; /* stride: u->syncinterval */ - if (!usbin_sync_prepare_desc(u, urb) && !usb_submit_urb(urb)) + if (!usbin_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) u->flags |= FLG_SYNC0RUNNING; else u->flags &= ~FLG_RUNNING; @@ -1097,7 +1097,7 @@ static int usbin_start(struct usb_audiodev *as) urb->context = as; urb->complete = usbin_sync_completed; /* stride: u->syncinterval */ - if (!usbin_sync_prepare_desc(u, urb) && !usb_submit_urb(urb)) + if (!usbin_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) u->flags |= FLG_SYNC1RUNNING; else u->flags &= ~FLG_RUNNING; @@ -1275,7 +1275,7 @@ static void usbout_completed(struct urb *urb) if (!usbout_retire_desc(u, urb) && u->flags & FLG_RUNNING && !usbout_prepare_desc(u, urb) && - (suret = usb_submit_urb(urb)) == 0) { + (suret = usb_submit_urb(urb, GFP_KERNEL)) == 0) { u->flags |= mask; } else { u->flags &= ~(mask | FLG_RUNNING); @@ -1347,7 +1347,7 @@ static void usbout_sync_completed(struct urb *urb) if (!usbout_sync_retire_desc(u, urb) && u->flags & FLG_RUNNING && !usbout_sync_prepare_desc(u, urb) && - (suret = usb_submit_urb(urb)) == 0) { + (suret = usb_submit_urb(urb, GFP_KERNEL)) == 0) { u->flags |= mask; } else { u->flags &= ~(mask | FLG_RUNNING); @@ -1420,7 +1420,7 @@ static int usbout_start(struct usb_audiodev *as) urb->number_of_packets = DESCFRAMES; urb->context = as; urb->complete = usbout_completed; - if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb)) + if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) u->flags |= FLG_URB0RUNNING; else u->flags &= ~FLG_RUNNING; @@ -1433,7 +1433,7 @@ static int usbout_start(struct usb_audiodev *as) urb->number_of_packets = DESCFRAMES; urb->context = as; urb->complete = usbout_completed; - if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb)) + if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) u->flags |= FLG_URB1RUNNING; else u->flags &= ~FLG_RUNNING; @@ -1448,7 +1448,7 @@ static int usbout_start(struct usb_audiodev *as) urb->context = as; urb->complete = usbout_sync_completed; /* stride: u->syncinterval */ - if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb)) + if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) u->flags |= FLG_SYNC0RUNNING; else u->flags &= ~FLG_RUNNING; @@ -1462,7 +1462,7 @@ static int usbout_start(struct usb_audiodev *as) urb->context = as; urb->complete = usbout_sync_completed; /* stride: u->syncinterval */ - if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb)) + if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) u->flags |= FLG_SYNC1RUNNING; else u->flags &= ~FLG_RUNNING; diff --git a/drivers/usb/auerswald.c b/drivers/usb/auerswald.c index 24490c47d408..4c4ef04926a2 100644 --- a/drivers/usb/auerswald.c +++ b/drivers/usb/auerswald.c @@ -49,7 +49,7 @@ do { \ /*-------------------------------------------------------------------*/ /* Version Information */ -#define DRIVER_VERSION "0.9.9" +#define DRIVER_VERSION "0.9.11" #define DRIVER_AUTHOR "Wolfgang Mües <wmues@nexgo.de>" #define DRIVER_DESC "Auerswald PBX/System Telephone usb driver" @@ -191,6 +191,13 @@ typedef struct auerchain struct list_head free_list; /* list of available elements */ } auerchain_t,*pauerchain_t; +/* urb blocking completion helper struct */ +typedef struct +{ + wait_queue_head_t wqh; /* wait for completion */ + unsigned int done; /* completion flag */ +} auerchain_chs_t,*pauerchain_chs_t; + /* ...................................................................*/ /* buffer element */ struct auerbufctl; /* forward */ @@ -330,7 +337,7 @@ static void auerchain_complete (struct urb * urb) urb = acep->urbp; dbg ("auerchain_complete: submitting next urb from chain"); urb->status = 0; /* needed! */ - result = usb_submit_urb( urb); + result = usb_submit_urb(urb, GFP_KERNEL); /* check for submit errors */ if (result) { @@ -408,7 +415,7 @@ static int auerchain_submit_urb_list (pauerchain_t acp, struct urb * urb, int ea if (acep) { dbg("submitting urb immediate"); urb->status = 0; /* needed! */ - result = usb_submit_urb( urb); + result = usb_submit_urb(urb, GFP_KERNEL); /* check for submit errors */ if (result) { urb->status = result; @@ -600,8 +607,10 @@ ac_fail:/* free the elements */ /* completion handler for synchronous chained URBs */ static void auerchain_blocking_completion (struct urb *urb) { - wait_queue_head_t *wakeup = (wait_queue_head_t *)urb->context; - wake_up (wakeup); + pauerchain_chs_t pchs = (pauerchain_chs_t)urb->context; + pchs->done = 1; + wmb(); + wake_up (&pchs->wqh); } @@ -609,36 +618,43 @@ static void auerchain_blocking_completion (struct urb *urb) static int auerchain_start_wait_urb (pauerchain_t acp, struct urb *urb, int timeout, int* actual_length) { DECLARE_WAITQUEUE (wait, current); - DECLARE_WAIT_QUEUE_HEAD (wqh); + auerchain_chs_t chs; int status; dbg ("auerchain_start_wait_urb called"); - init_waitqueue_head (&wqh); - current->state = TASK_INTERRUPTIBLE; - add_wait_queue (&wqh, &wait); - urb->context = &wqh; - status = auerchain_submit_urb ( acp, urb); + init_waitqueue_head (&chs.wqh); + chs.done = 0; + + set_current_state (TASK_UNINTERRUPTIBLE); + add_wait_queue (&chs.wqh, &wait); + urb->context = &chs; + status = auerchain_submit_urb (acp, urb); if (status) { /* something went wrong */ - current->state = TASK_RUNNING; - remove_wait_queue (&wqh, &wait); + set_current_state (TASK_RUNNING); + remove_wait_queue (&chs.wqh, &wait); return status; } - if (urb->status == -EINPROGRESS) { - while (timeout && urb->status == -EINPROGRESS) - status = timeout = schedule_timeout (timeout); - } else - status = 1; + while (timeout && !chs.done) + { + timeout = schedule_timeout (timeout); + set_current_state(TASK_UNINTERRUPTIBLE); + rmb(); + } - current->state = TASK_RUNNING; - remove_wait_queue (&wqh, &wait); + set_current_state (TASK_RUNNING); + remove_wait_queue (&chs.wqh, &wait); - if (!status) { - /* timeout */ - dbg ("auerchain_start_wait_urb: timeout"); - auerchain_unlink_urb (acp, urb); /* remove urb safely */ - status = -ETIMEDOUT; + if (!timeout && !chs.done) { + if (urb->status != -EINPROGRESS) { /* No callback?!! */ + dbg ("auerchain_start_wait_urb: raced timeout"); + status = urb->status; + } else { + dbg ("auerchain_start_wait_urb: timeout"); + auerchain_unlink_urb (acp, urb); /* remove urb safely */ + status = -ETIMEDOUT; + } } else status = urb->status; @@ -932,6 +948,8 @@ static void auerswald_ctrlread_complete (struct urb * urb) /* reuse the buffer */ err ("control read: transmission error %d, can not retry", urb->status); auerbuf_releasebuf (bp); + /* Wake up all processes waiting for a buffer */ + wake_up (&cp->bufferwait); return; } bp->retries++; @@ -1128,7 +1146,7 @@ static int auerswald_int_open (pauerswald_t cp) FILL_INT_URB (cp->inturbp, cp->usbdev, usb_rcvintpipe (cp->usbdev,AU_IRQENDP), cp->intbufp, irqsize, auerswald_int_complete, cp, ep->bInterval); /* start the urb */ cp->inturbp->status = 0; /* needed! */ - ret = usb_submit_urb (cp->inturbp); + ret = usb_submit_urb (cp->inturbp, GFP_KERNEL); intoend: if (ret < 0) { @@ -1376,9 +1394,6 @@ static int auerchar_open (struct inode *inode, struct file *file) } up (&dev_table_mutex); - /* prevent module unloading */ - MOD_INC_USE_COUNT; - /* we have access to the device. Now lets allocate memory */ ccp = (pauerchar_t) kmalloc(sizeof(auerchar_t), GFP_KERNEL); if (ccp == NULL) { @@ -1415,7 +1430,6 @@ static int auerchar_open (struct inode *inode, struct file *file) /* Error exit */ ofail: up (&cp->mutex); auerchar_delete (ccp); - MOD_DEC_USE_COUNT; return ret; } @@ -1553,21 +1567,14 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int return ret; } - -/* Seek is not supported */ -static loff_t auerchar_llseek (struct file *file, loff_t offset, int origin) -{ - dbg ("auerchar_seek"); - return -ESPIPE; -} - - /* Read data from the device */ static ssize_t auerchar_read (struct file *file, char *buf, size_t count, loff_t * ppos) { unsigned long flags; pauerchar_t ccp = (pauerchar_t) file->private_data; pauerbuf_t bp = NULL; + wait_queue_t wait; + dbg ("auerchar_read"); /* Error checking */ @@ -1630,6 +1637,11 @@ doreadbuf: /* a read buffer is not available. Try to get the next data block. */ doreadlist: + /* Preparing for sleep */ + init_waitqueue_entry (&wait, current); + set_current_state (TASK_INTERRUPTIBLE); + add_wait_queue (&ccp->readwait, &wait); + bp = NULL; spin_lock_irqsave (&ccp->bufctl.lock, flags); if (!list_empty (&ccp->bufctl.rec_buff_list)) { @@ -1644,20 +1656,25 @@ doreadlist: if (bp) { ccp->readbuf = bp; ccp->readoffset = AUH_SIZE; /* for headerbyte */ + set_current_state (TASK_RUNNING); + remove_wait_queue (&ccp->readwait, &wait); goto doreadbuf; /* now we can read! */ } /* no data available. Should we wait? */ if (file->f_flags & O_NONBLOCK) { dbg ("No read buffer available, returning -EAGAIN"); + set_current_state (TASK_RUNNING); + remove_wait_queue (&ccp->readwait, &wait); up (&ccp->readmutex); up (&ccp->mutex); - return -EAGAIN; /* nonblocking, no data available */ + return -EAGAIN; /* nonblocking, no data available */ } /* yes, we should wait! */ up (&ccp->mutex); /* allow other operations while we wait */ - interruptible_sleep_on (&ccp->readwait); + schedule(); + remove_wait_queue (&ccp->readwait, &wait); if (signal_pending (current)) { /* waked up by a signal */ up (&ccp->readmutex); @@ -1688,6 +1705,7 @@ static ssize_t auerchar_write (struct file *file, const char *buf, size_t len, l pauerbuf_t bp; unsigned long flags; int ret; + wait_queue_t wait; dbg ("auerchar_write %d bytes", len); @@ -1724,6 +1742,11 @@ write_again: up (&ccp->mutex); return -EIO; } + /* Prepare for sleep */ + init_waitqueue_entry (&wait, current); + set_current_state (TASK_INTERRUPTIBLE); + add_wait_queue (&cp->bufferwait, &wait); + /* Try to get a buffer from the device pool. We can't use a buffer from ccp->bufctl because the write command will last beond a release() */ @@ -1744,16 +1767,22 @@ write_again: /* NONBLOCK: don't wait */ if (file->f_flags & O_NONBLOCK) { + set_current_state (TASK_RUNNING); + remove_wait_queue (&cp->bufferwait, &wait); return -EAGAIN; } /* BLOCKING: wait */ - interruptible_sleep_on (&cp->bufferwait); + schedule(); + remove_wait_queue (&cp->bufferwait, &wait); if (signal_pending (current)) { /* waked up by a signal */ return -ERESTARTSYS; } goto write_again; + } else { + set_current_state (TASK_RUNNING); + remove_wait_queue (&cp->bufferwait, &wait); } /* protect against too big write requests */ @@ -1763,6 +1792,8 @@ write_again: if (copy_from_user ( bp->bufp+AUH_SIZE, buf, len)) { dbg ("copy_from_user failed"); auerbuf_releasebuf (bp); + /* Wake up all processes waiting for a buffer */ + wake_up (&cp->bufferwait); up (&cp->mutex); up (&ccp->mutex); return -EIO; @@ -1787,6 +1818,8 @@ write_again: if (ret) { dbg ("auerchar_write: nonzero result of auerchain_submit_urb %d", ret); auerbuf_releasebuf (bp); + /* Wake up all processes waiting for a buffer */ + wake_up (&cp->bufferwait); up (&ccp->mutex); return -EIO; } @@ -1831,9 +1864,6 @@ static int auerchar_release (struct inode *inode, struct file *file) up (&ccp->mutex); auerchar_delete (ccp); - /* release the module */ - MOD_DEC_USE_COUNT; - return 0; } @@ -1843,7 +1873,7 @@ static int auerchar_release (struct inode *inode, struct file *file) static struct file_operations auerswald_fops = { owner: THIS_MODULE, - llseek: auerchar_llseek, + llseek: no_llseek, read: auerchar_read, write: auerchar_write, ioctl: auerchar_ioctl, @@ -2154,3 +2184,4 @@ module_init (auerswald_init); module_exit (auerswald_cleanup); /* --------------------------------------------------------------------- */ + diff --git a/drivers/usb/bluetooth.c b/drivers/usb/bluetooth.c index 9429d75b9300..56268a5e4560 100644 --- a/drivers/usb/bluetooth.c +++ b/drivers/usb/bluetooth.c @@ -335,7 +335,7 @@ static int bluetooth_ctrl_msg (struct usb_bluetooth *bluetooth, int request, int (unsigned char*)dr, urb->transfer_buffer, len, bluetooth_ctrl_callback, bluetooth); /* send it down the pipe */ - status = usb_submit_urb(urb); + status = usb_submit_urb(urb, GFP_KERNEL); if (status) dbg(__FUNCTION__ " - usb_submit_urb(control) failed with status = %d", status); @@ -390,7 +390,7 @@ static int bluetooth_open (struct tty_struct *tty, struct file * filp) bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, bluetooth_read_bulk_callback, bluetooth); - result = usb_submit_urb(bluetooth->read_urb); + result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL); if (result) dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed with status %d", result); #endif @@ -400,7 +400,7 @@ static int bluetooth_open (struct tty_struct *tty, struct file * filp) bluetooth->interrupt_in_buffer_size, bluetooth_int_callback, bluetooth, bluetooth->interrupt_in_interval); - result = usb_submit_urb(bluetooth->interrupt_in_urb); + result = usb_submit_urb(bluetooth->interrupt_in_urb, GFP_KERNEL); if (result) dbg(__FUNCTION__ " - usb_submit_urb(interrupt in) failed with status %d", result); } @@ -540,7 +540,7 @@ static int bluetooth_write (struct tty_struct * tty, int from_user, const unsign urb->transfer_flags |= USB_QUEUE_BULK; /* send it down the pipe */ - retval = usb_submit_urb(urb); + retval = usb_submit_urb(urb, GFP_KERNEL); if (retval) { dbg(__FUNCTION__ " - usb_submit_urb(write bulk) failed with error = %d", retval); goto exit; @@ -730,7 +730,7 @@ void btusb_enable_bulk_read(struct tty_struct *tty){ usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, bluetooth_read_bulk_callback, bluetooth); - result = usb_submit_urb(bluetooth->read_urb); + result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL); if (result) err (__FUNCTION__ " - failed submitting read urb, error %d", result); } @@ -921,7 +921,7 @@ static void bluetooth_read_bulk_callback (struct urb *urb) usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, bluetooth_read_bulk_callback, bluetooth); - result = usb_submit_urb(bluetooth->read_urb); + result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL); if (result) err (__FUNCTION__ " - failed resubmitting read urb, error %d", result); @@ -982,7 +982,7 @@ exit: usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, bluetooth_read_bulk_callback, bluetooth); - result = usb_submit_urb(bluetooth->read_urb); + result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL); if (result) err (__FUNCTION__ " - failed resubmitting read urb, error %d", result); diff --git a/drivers/usb/catc.c b/drivers/usb/catc.c index 0667997ff89a..fdfad40b85f6 100644 --- a/drivers/usb/catc.c +++ b/drivers/usb/catc.c @@ -257,7 +257,7 @@ static void catc_irq_done(struct urb *urb) if ((data[1] & 0x80) && !test_and_set_bit(RX_RUNNING, &catc->flags)) { catc->rx_urb->dev = catc->usbdev; - if ((status = usb_submit_urb(catc->rx_urb)) < 0) { + if ((status = usb_submit_urb(catc->rx_urb, GFP_KERNEL)) < 0) { err("submit(rx_urb) status %d", status); return; } @@ -286,7 +286,7 @@ static void catc_tx_run(struct catc *catc) catc->tx_urb->transfer_buffer = catc->tx_buf[catc->tx_idx]; catc->tx_urb->dev = catc->usbdev; - if ((status = usb_submit_urb(catc->tx_urb)) < 0) + if ((status = usb_submit_urb(catc->tx_urb, GFP_KERNEL)) < 0) err("submit(tx_urb), status %d", status); catc->tx_idx = !catc->tx_idx; @@ -402,7 +402,7 @@ static void catc_ctrl_run(struct catc *catc) if (!q->dir && q->buf && q->len) memcpy(catc->ctrl_buf, q->buf, q->len); - if ((status = usb_submit_urb(catc->ctrl_urb))) + if ((status = usb_submit_urb(catc->ctrl_urb, GFP_KERNEL))) err("submit(ctrl_urb) status %d", status); } @@ -625,7 +625,7 @@ static int catc_open(struct net_device *netdev) int status; catc->irq_urb->dev = catc->usbdev; - if ((status = usb_submit_urb(catc->irq_urb)) < 0) { + if ((status = usb_submit_urb(catc->irq_urb, GFP_KERNEL)) < 0) { err("submit(irq_urb) status %d", status); return -1; } diff --git a/drivers/usb/dabusb.c b/drivers/usb/dabusb.c index 40ba92fedcfa..02833f56f92b 100644 --- a/drivers/usb/dabusb.c +++ b/drivers/usb/dabusb.c @@ -458,7 +458,7 @@ static int dabusb_startrek (pdabusb_t s) end = list_entry (s->rec_buff_list.prev, buff_t, buff_list); - ret = usb_submit_urb (end->purb); + ret = usb_submit_urb (end->purb, GFP_KERNEL); if (ret) { err("usb_submit_urb returned:%d", ret); if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list)) diff --git a/drivers/usb/devices.c b/drivers/usb/devices.c index c732e45be986..3e8b1d79b270 100644 --- a/drivers/usb/devices.c +++ b/drivers/usb/devices.c @@ -554,21 +554,26 @@ static int usb_device_release(struct inode *inode, struct file *file) static loff_t usb_device_lseek(struct file * file, loff_t offset, int orig) { + loff_t ret; + + lock_kernel(); + switch (orig) { case 0: file->f_pos = offset; - return file->f_pos; - + ret = file->f_pos; + break; case 1: file->f_pos += offset; - return file->f_pos; - + ret = file->f_pos; + break; case 2: - return -EINVAL; - default: - return -EINVAL; + ret = -EINVAL; } + + unlock_kernel(); + return ret; } struct file_operations usbdevfs_devices_fops = { diff --git a/drivers/usb/devio.c b/drivers/usb/devio.c index c7883b376139..eeb86671eef1 100644 --- a/drivers/usb/devio.c +++ b/drivers/usb/devio.c @@ -58,21 +58,26 @@ struct async { static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig) { + loff_t ret; + + lock_kernel(); + switch (orig) { case 0: file->f_pos = offset; - return file->f_pos; - + ret = file->f_pos; + break; case 1: file->f_pos += offset; - return file->f_pos; - + ret = file->f_pos; + break; case 2: - return -EINVAL; - default: - return -EINVAL; + ret = -EINVAL; } + + unlock_kernel(); + return ret; } static ssize_t usbdev_read(struct file *file, char * buf, size_t nbytes, loff_t *ppos) @@ -364,7 +369,7 @@ static int checkintf(struct dev_state *ps, unsigned int intf) if (test_bit(intf, &ps->ifclaimed)) return 0; /* if not yet claimed, claim it for the driver */ - printk(KERN_WARNING "usbdevfs: process %d (%s) did not claim interface %u before use\n", + printk(KERN_WARNING "usbfs: process %d (%s) did not claim interface %u before use\n", current->pid, current->comm, intf); return claimintf(ps, intf); } @@ -563,7 +568,7 @@ static int proc_control(struct dev_state *ps, void *arg) } free_page((unsigned long)tbuf); if (i<0) { - printk(KERN_DEBUG "usbdevfs: USBDEVFS_CONTROL failed dev %d rqt %u rq %u len %u ret %d\n", + printk(KERN_DEBUG "usbfs: USBDEVFS_CONTROL failed dev %d rqt %u rq %u len %u ret %d\n", dev->devnum, ctrl.bRequestType, ctrl.bRequest, ctrl.wLength, i); } return i; @@ -619,7 +624,7 @@ static int proc_bulk(struct dev_state *ps, void *arg) } free_page((unsigned long)tbuf); if (i < 0) { - printk(KERN_WARNING "usbdevfs: USBDEVFS_BULK failed dev %d ep 0x%x len %u ret %d\n", + printk(KERN_WARNING "usbfs: USBDEVFS_BULK failed dev %d ep 0x%x len %u ret %d\n", dev->devnum, bulk.ep, bulk.len, i); return i; } @@ -906,8 +911,8 @@ static int proc_submiturb(struct dev_state *ps, void *arg) } } async_newpending(as); - if ((ret = usb_submit_urb(as->urb))) { - printk(KERN_DEBUG "usbdevfs: usb_submit_urb returned %d\n", ret); + if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) { + printk(KERN_DEBUG "usbfs: usb_submit_urb returned %d\n", ret); async_removepending(as); free_async(as); return ret; diff --git a/drivers/usb/drivers.c b/drivers/usb/drivers.c index 28589b1e6da5..ae96757ef9f6 100644 --- a/drivers/usb/drivers.c +++ b/drivers/usb/drivers.c @@ -38,6 +38,7 @@ #include <linux/mm.h> #include <linux/usb.h> #include <linux/usbdevice_fs.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> /*****************************************************************/ @@ -96,21 +97,24 @@ static ssize_t usb_driver_read(struct file *file, char *buf, size_t nbytes, loff static loff_t usb_driver_lseek(struct file * file, loff_t offset, int orig) { + loff_t ret; + + lock_kernel(); switch (orig) { case 0: file->f_pos = offset; - return file->f_pos; - + ret = file->f_pos; + break; case 1: file->f_pos += offset; - return file->f_pos; - + ret = file->f_pos; + break; case 2: - return -EINVAL; - default: - return -EINVAL; + ret = -EINVAL; } + unlock_kernel(); + return ret; } struct file_operations usbdevfs_drivers_fops = { diff --git a/drivers/usb/hcd.c b/drivers/usb/hcd.c index f6095f2f8c48..2f97c96bd105 100644 --- a/drivers/usb/hcd.c +++ b/drivers/usb/hcd.c @@ -916,14 +916,13 @@ static void hc_died (struct usb_hcd *hcd) /* may be called in any context with a valid urb->dev usecount */ /* caller surrenders "ownership" of urb (and chain at urb->next). */ -static int hcd_submit_urb (struct urb *urb) +static int hcd_submit_urb (struct urb *urb, int mem_flags) { int status; struct usb_hcd *hcd; struct hcd_dev *dev; unsigned long flags; int pipe; - int mem_flags; if (!urb || urb->hcpriv || !urb->complete) return -EINVAL; @@ -947,11 +946,6 @@ static int hcd_submit_urb (struct urb *urb) usb_pipeout (pipe))) return -EPIPE; - // FIXME paging/swapping requests over USB should not use GFP_KERNEL - // and might even need to use GFP_NOIO ... that flag actually needs - // to be passed from the higher level. - mem_flags = in_interrupt () ? GFP_ATOMIC : GFP_KERNEL; - #ifdef DEBUG { unsigned int orig_flags = urb->transfer_flags; @@ -1316,7 +1310,7 @@ void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb) else if (urb->next) { int status; - status = usb_submit_urb (urb->next); + status = usb_submit_urb (urb->next, GFP_ATOMIC); if (status) { dbg ("urb %p chain fail, %d", urb->next, status); urb->next->status = -ENOTCONN; diff --git a/drivers/usb/hid-core.c b/drivers/usb/hid-core.c index 1129deb66a2a..f9ebfa1f8687 100644 --- a/drivers/usb/hid-core.c +++ b/drivers/usb/hid-core.c @@ -992,7 +992,7 @@ static int hid_submit_out(struct hid_device *hid) hid->urbout.setup_packet = (void *) &(hid->out[hid->outtail].dr); hid->urbout.dev = hid->dev; - if (usb_submit_urb(&hid->urbout)) { + if (usb_submit_urb(&hid->urbout, GFP_KERNEL)) { err("usb_submit_urb(out) failed"); return -1; } @@ -1036,7 +1036,7 @@ int hid_open(struct hid_device *hid) hid->urb.dev = hid->dev; - if (usb_submit_urb(&hid->urb)) + if (usb_submit_urb(&hid->urb, GFP_KERNEL)) return -EIO; return 0; diff --git a/drivers/usb/hpusbscsi.c b/drivers/usb/hpusbscsi.c index 71e60ef6aeeb..c9153fedea7f 100644 --- a/drivers/usb/hpusbscsi.c +++ b/drivers/usb/hpusbscsi.c @@ -245,7 +245,7 @@ hpusbscsi_scsi_detect (struct SHT *sht) desc->interrupt_interval ); - if ( 0 > usb_submit_urb(desc->controlurb)) { + if ( 0 > usb_submit_urb(desc->controlurb, GFP_KERNEL)) { kfree(sht->proc_name); return 0; } @@ -321,7 +321,7 @@ static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback) hpusbscsi->scallback = callback; hpusbscsi->srb = srb; - res = usb_submit_urb(hpusbscsi->dataurb); + res = usb_submit_urb(hpusbscsi->dataurb, GFP_ATOMIC); if (unlikely(res)) { hpusbscsi->state = HP_STATE_FREE; TRACE_STATE; @@ -461,7 +461,7 @@ static void scatter_gather_callback(struct urb *u) hpusbscsi ); - res = usb_submit_urb(u); + res = usb_submit_urb(u, GFP_ATOMIC); if (unlikely(res)) hpusbscsi->state = HP_STATE_ERROR; TRACE_STATE; @@ -510,7 +510,7 @@ static void simple_payload_callback (struct urb *u) hpusbscsi ); - res = usb_submit_urb(u); + res = usb_submit_urb(u, GFP_ATOMIC); if (unlikely(res)) { handle_usb_error(hpusbscsi); return; diff --git a/drivers/usb/hub.c b/drivers/usb/hub.c index f741f808a244..23eb747a727e 100644 --- a/drivers/usb/hub.c +++ b/drivers/usb/hub.c @@ -312,7 +312,7 @@ static int usb_hub_configure(struct usb_hub *hub, FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq, hub, endpoint->bInterval); - ret = usb_submit_urb(hub->urb); + ret = usb_submit_urb(hub->urb, GFP_KERNEL); if (ret) { err("usb_submit_urb failed (%d)", ret); kfree(hub->descriptor); @@ -498,7 +498,7 @@ static int usb_hub_reset(struct usb_hub *hub) return -1; hub->urb->dev = dev; - if (usb_submit_urb(hub->urb)) + if (usb_submit_urb(hub->urb, GFP_KERNEL)) return -1; usb_hub_power_on(hub); diff --git a/drivers/usb/ibmcam.c b/drivers/usb/ibmcam.c index c3061157e204..f8c3ea116b82 100644 --- a/drivers/usb/ibmcam.c +++ b/drivers/usb/ibmcam.c @@ -1,7 +1,8 @@ /* * USB IBM C-It Video Camera driver * - * Supports IBM C-It Video Camera. + * Supports Xirlink C-It Video Camera, IBM PC Camera, + * IBM NetCamera and Veo Stingray. * * This driver is based on earlier work of: * @@ -33,9 +34,11 @@ #include "usbvideo.h" -#define IBMCAM_VENDOR_ID 0x0545 -#define IBMCAM_PRODUCT_ID 0x8080 +#define IBMCAM_VENDOR_ID 0x0545 +#define IBMCAM_PRODUCT_ID 0x8080 #define NETCAM_PRODUCT_ID 0x8002 /* IBM NetCamera, close to model 2 */ +#define VEO_800C_PRODUCT_ID 0x800C /* Veo Stingray, repackaged Model 2 */ +#define VEO_800D_PRODUCT_ID 0x800D /* Veo Stingray, repackaged Model 4 */ #define MAX_IBMCAM 4 /* How many devices we allow to connect */ #define USES_IBMCAM_PUTPIXEL 0 /* 0=Fast/oops 1=Slow/secure */ @@ -3671,6 +3674,8 @@ static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const stru if (dev->descriptor.idVendor != IBMCAM_VENDOR_ID) return NULL; if ((dev->descriptor.idProduct != IBMCAM_PRODUCT_ID) && + (dev->descriptor.idProduct != VEO_800C_PRODUCT_ID) && + (dev->descriptor.idProduct != VEO_800D_PRODUCT_ID) && (dev->descriptor.idProduct != NETCAM_PRODUCT_ID)) return NULL; @@ -3684,7 +3689,8 @@ static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const stru case 0x030A: if (ifnum != 0) return NULL; - if (dev->descriptor.idProduct == NETCAM_PRODUCT_ID) + if ((dev->descriptor.idProduct == NETCAM_PRODUCT_ID) || + (dev->descriptor.idProduct == VEO_800D_PRODUCT_ID)) model = IBMCAM_MODEL_4; else model = IBMCAM_MODEL_2; @@ -3699,8 +3705,28 @@ static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const stru dev->descriptor.bcdDevice); return NULL; } - info("IBM USB camera found (model %d, rev. 0x%04x)", - model, dev->descriptor.bcdDevice); + + /* Print detailed info on what we found so far */ + do { + char *brand = NULL; + switch (dev->descriptor.idProduct) { + case NETCAM_PRODUCT_ID: + brand = "IBM NetCamera"; + break; + case VEO_800C_PRODUCT_ID: + brand = "Veo Stingray [800C]"; + break; + case VEO_800D_PRODUCT_ID: + brand = "Veo Stingray [800D]"; + break; + case IBMCAM_PRODUCT_ID: + default: + brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */ + break; + } + info("%s USB camera found (model %d, rev. 0x%04x)", + brand, model, dev->descriptor.bcdDevice); + } while (0); /* Validate found interface: must have one ISO endpoint */ nas = dev->actconfig->interface[ifnum].num_altsetting; @@ -3908,18 +3934,16 @@ static void __exit ibmcam_cleanup(void) usbvideo_Deregister(&cams); } -#if defined(usb_device_id_ver) - static __devinitdata struct usb_device_id id_table[] = { { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0002, 0x0002) }, /* Model 1 */ { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */ { USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0301, 0x0301) }, /* Model 3 */ { USB_DEVICE_VER(IBMCAM_VENDOR_ID, NETCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */ + { USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800C_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */ + { USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800D_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, id_table); -#endif /* defined(usb_device_id_ver) */ - module_init(ibmcam_init); module_exit(ibmcam_cleanup); diff --git a/drivers/usb/ibmcam.h b/drivers/usb/ibmcam.h deleted file mode 100644 index 6a5e1cd02980..000000000000 --- a/drivers/usb/ibmcam.h +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Header file for USB IBM C-It Video Camera driver. - * - * Supports IBM C-It Video Camera. - * - * This driver is based on earlier work of: - * - * (C) Copyright 1999 Johannes Erdfelt - * (C) Copyright 1999 Randy Dunlap - */ - -#ifndef __LINUX_IBMCAM_H -#define __LINUX_IBMCAM_H - -#include <linux/list.h> - -#define USES_IBMCAM_PUTPIXEL 0 /* 0=Fast/oops 1=Slow/secure */ - -/* Video Size 384 x 288 x 3 bytes for RGB */ -/* 384 because xawtv tries to grab 384 even though we tell it 352 is our max */ -#define V4L_FRAME_WIDTH 384 -#define V4L_FRAME_WIDTH_USED 352 -#define V4L_FRAME_HEIGHT 288 -#define V4L_BYTES_PER_PIXEL 3 -#define MAX_FRAME_SIZE (V4L_FRAME_WIDTH * V4L_FRAME_HEIGHT * V4L_BYTES_PER_PIXEL) - -/* Camera capabilities (maximum) */ -#define CAMERA_IMAGE_WIDTH 352 -#define CAMERA_IMAGE_HEIGHT 288 -#define CAMERA_IMAGE_LINE_SZ ((CAMERA_IMAGE_WIDTH * 3) / 2) /* Bytes */ -#define CAMERA_URB_FRAMES 32 -#define CAMERA_MAX_ISO_PACKET 1023 /* 1022 actually sent by camera */ - -#define IBMCAM_NUMFRAMES 2 -#define IBMCAM_NUMSBUF 2 - -#define FRAMES_PER_DESC (CAMERA_URB_FRAMES) -#define FRAME_SIZE_PER_DESC (CAMERA_MAX_ISO_PACKET) - -/* This macro restricts an int variable to an inclusive range */ -#define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); } - -/* - * This macro performs bounds checking - use it when working with - * new formats, or else you may get oopses all over the place. - * If pixel falls out of bounds then it gets shoved back (as close - * to place of offence as possible) and is painted bright red. - */ -#define IBMCAM_PUTPIXEL(fr, ix, iy, vr, vg, vb) { \ - register unsigned char *pf; \ - int limiter = 0, mx, my; \ - mx = ix; \ - my = iy; \ - if (mx < 0) { \ - mx=0; \ - limiter++; \ - } else if (mx >= 352) { \ - mx=351; \ - limiter++; \ - } \ - if (my < 0) { \ - my = 0; \ - limiter++; \ - } else if (my >= V4L_FRAME_HEIGHT) { \ - my = V4L_FRAME_HEIGHT - 1; \ - limiter++; \ - } \ - pf = (fr)->data + V4L_BYTES_PER_PIXEL*((iy)*352 + (ix)); \ - if (limiter) { \ - *pf++ = 0; \ - *pf++ = 0; \ - *pf++ = 0xFF; \ - } else { \ - *pf++ = (vb); \ - *pf++ = (vg); \ - *pf++ = (vr); \ - } \ -} - -/* - * We use macros to do YUV -> RGB conversion because this is - * very important for speed and totally unimportant for size. - * - * YUV -> RGB Conversion - * --------------------- - * - * B = 1.164*(Y-16) + 2.018*(V-128) - * G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128) - * R = 1.164*(Y-16) + 1.596*(U-128) - * - * If you fancy integer arithmetics (as you should), hear this: - * - * 65536*B = 76284*(Y-16) + 132252*(V-128) - * 65536*G = 76284*(Y-16) - 53281*(U-128) - 25625*(V-128) - * 65536*R = 76284*(Y-16) + 104595*(U-128) - * - * Make sure the output values are within [0..255] range. - */ -#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x))) -#define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \ - int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \ - mm_y = (my) - 16; \ - mm_u = (mu) - 128; \ - mm_v = (mv) - 128; \ - mm_yc= mm_y * 76284; \ - mm_b = (mm_yc + 132252*mm_v ) >> 16; \ - mm_g = (mm_yc - 53281*mm_u - 25625*mm_v ) >> 16; \ - mm_r = (mm_yc + 104595*mm_u ) >> 16; \ - mb = LIMIT_RGB(mm_b); \ - mg = LIMIT_RGB(mm_g); \ - mr = LIMIT_RGB(mm_r); \ -} - -/* Debugging aid */ -#define IBMCAM_SAY_AND_WAIT(what) { \ - wait_queue_head_t wq; \ - init_waitqueue_head(&wq); \ - printk(KERN_INFO "Say: %s\n", what); \ - interruptible_sleep_on_timeout (&wq, HZ*3); \ -} - -/* - * This macro checks if ibmcam is still operational. The 'ibmcam' - * pointer must be valid, ibmcam->dev must be valid, we are not - * removing the device and the device has not erred on us. - */ -#define IBMCAM_IS_OPERATIONAL(ibm_cam) (\ - (ibm_cam != NULL) && \ - ((ibm_cam)->dev != NULL) && \ - ((ibm_cam)->last_error == 0) && \ - (!(ibm_cam)->remove_pending)) - -enum { - STATE_SCANNING, /* Scanning for header */ - STATE_LINES, /* Parsing lines */ -}; - -enum { - FRAME_UNUSED, /* Unused (no MCAPTURE) */ - FRAME_READY, /* Ready to start grabbing */ - FRAME_GRABBING, /* In the process of being grabbed into */ - FRAME_DONE, /* Finished grabbing, but not been synced yet */ - FRAME_ERROR, /* Something bad happened while processing */ -}; - -struct usb_device; - -struct ibmcam_sbuf { - char *data; - struct urb *urb; -}; - -struct ibmcam_frame { - char *data; /* Frame buffer */ - int order_uv; /* True=UV False=VU */ - int order_yc; /* True=Yc False=cY ('c'=either U or V) */ - unsigned char hdr_sig; /* "00 FF 00 ??" where 'hdr_sig' is '??' */ - - int width; /* Width application is expecting */ - int height; /* Height */ - - int frmwidth; /* Width the frame actually is */ - int frmheight; /* Height */ - - volatile int grabstate; /* State of grabbing */ - int scanstate; /* State of scanning */ - - int curline; /* Line of frame we're working on */ - - long scanlength; /* uncompressed, raw data length of frame */ - long bytes_read; /* amount of scanlength that has been read from *data */ - - wait_queue_head_t wq; /* Processes waiting */ -}; - -#define IBMCAM_MODEL_1 1 /* XVP-501, 3 interfaces, rev. 0.02 */ -#define IBMCAM_MODEL_2 2 /* KSX-X9903, 2 interfaces, rev. 3.0a */ - -struct usb_ibmcam { - struct video_device vdev; - - /* Device structure */ - struct usb_device *dev; - - unsigned char iface; /* Video interface number */ - unsigned char ifaceAltActive, ifaceAltInactive; /* Alt settings */ - - struct semaphore lock; - int user; /* user count for exclusive use */ - - int ibmcam_used; /* Is this structure in use? */ - int initialized; /* Had we already sent init sequence? */ - int camera_model; /* What type of IBM camera we got? */ - int streaming; /* Are we streaming Isochronous? */ - int grabbing; /* Are we grabbing? */ - int last_error; /* What calamity struck us? */ - - int compress; /* Should the next frame be compressed? */ - - char *fbuf; /* Videodev buffer area */ - int fbuf_size; /* Videodev buffer size */ - - int curframe; - struct ibmcam_frame frame[IBMCAM_NUMFRAMES]; /* Double buffering */ - - int cursbuf; /* Current receiving sbuf */ - struct ibmcam_sbuf sbuf[IBMCAM_NUMSBUF]; /* Double buffering */ - volatile int remove_pending; /* If set then about to exit */ - - /* - * Scratch space from the Isochronous pipe. - * Scratch buffer should contain at least one pair of lines - * (CAMERA_IMAGE_LINE_SZ). We set it to two pairs here. - * This will be approximately 2 KB. HOWEVER in reality this - * buffer must be as large as hundred of KB because otherwise - * you'll get lots of overflows because V4L client may request - * frames not as uniformly as USB sources them. - */ - unsigned char *scratch; - int scratchlen; - - struct video_picture vpic, vpic_old; /* Picture settings */ - struct video_capability vcap; /* Video capabilities */ - struct video_channel vchan; /* May be used for tuner support */ - unsigned char video_endp; /* 0x82 for IBM camera */ - int has_hdr; - int frame_num; - int iso_packet_len; /* Videomode-dependent, saves bus bandwidth */ - - /* Statistics that can be overlayed on screen */ - unsigned long urb_count; /* How many URBs we received so far */ - unsigned long urb_length; /* Length of last URB */ - unsigned long data_count; /* How many bytes we received */ - unsigned long header_count; /* How many frame headers we found */ - unsigned long scratch_ovf_count;/* How many times we overflowed scratch */ - unsigned long iso_skip_count; /* How many empty ISO packets received */ - unsigned long iso_err_count; /* How many bad ISO packets received */ -}; - -#endif /* __LINUX_IBMCAM_H */ diff --git a/drivers/usb/inode.c b/drivers/usb/inode.c index 53716ae850e5..4166d45f8fe3 100644 --- a/drivers/usb/inode.c +++ b/drivers/usb/inode.c @@ -36,7 +36,7 @@ #include <linux/proc_fs.h> #include <linux/usb.h> #include <linux/usbdevice_fs.h> - +#include <linux/smp_lock.h> static struct super_operations usbfs_ops; static struct address_space_operations usbfs_aops; @@ -295,6 +295,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig) { loff_t retval = -EINVAL; + lock_kernel(); switch(orig) { case 0: if (offset > 0) { @@ -311,6 +312,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig) default: break; } + unlock_kernel(); return retval; } @@ -362,15 +364,14 @@ static struct super_operations usbfs_ops = { put_inode: force_delete, }; -static struct super_block *usbfs_read_super (struct super_block *sb, void *data, - int silent) +static int usbfs_fill_super(struct super_block *sb, void *data, int silent) { struct inode *inode; struct dentry *root; if (parse_options(sb, data)) { warn("usbfs: mount parameter error:"); - return NULL; + return -EINVAL; } sb->s_blocksize = PAGE_CACHE_SIZE; @@ -381,17 +382,17 @@ static struct super_block *usbfs_read_super (struct super_block *sb, void *data, if (!inode) { dbg("%s: could not get inode!\n",__FUNCTION__); - return NULL; + return -ENOMEM; } root = d_alloc_root(inode); if (!root) { dbg("%s: could not get root dentry!\n",__FUNCTION__); iput(inode); - return NULL; + return -ENOMEM; } sb->s_root = root; - return sb; + return 0; } /** @@ -520,8 +521,24 @@ static void fs_remove_file (struct dentry *dentry) * It will be removed when the 2.7.x development cycle is started. * You have been warned :) */ -static DECLARE_FSTYPE(usbdevice_fs_type, "usbdevfs", usbfs_read_super, FS_SINGLE); -static DECLARE_FSTYPE(usb_fs_type, "usbfs", usbfs_read_super, FS_SINGLE); + +static struct super_block *usb_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_single(fs_type, flags, data, usb_fill_super); +} + +static struct file_system_type usbdevice_fs_type = { + owner: THIS_MODULE, + name: "usbdevfs", + get_sb: usb_get_sb, +}; + +static struct file_system_type usb_fs_type = { + owner: THIS_MODULE, + name: "usbfs", + get_sb: usb_get_sb, +}; /* --------------------------------------------------------------------- */ static int get_mount (void) diff --git a/drivers/usb/kaweth.c b/drivers/usb/kaweth.c index 8d89ba87cf30..65cb2b123841 100644 --- a/drivers/usb/kaweth.c +++ b/drivers/usb/kaweth.c @@ -447,7 +447,8 @@ static void kaweth_usb_receive(struct urb *); /**************************************************************** * kaweth_resubmit_rx_urb ****************************************************************/ -static inline void kaweth_resubmit_rx_urb(struct kaweth_device *kaweth) +static inline void kaweth_resubmit_rx_urb(struct kaweth_device *kaweth, + int mem_flags) { int result; @@ -461,7 +462,7 @@ static inline void kaweth_resubmit_rx_urb(struct kaweth_device *kaweth) kaweth_usb_receive, kaweth); - if((result = usb_submit_urb(kaweth->rx_urb))) { + if((result = usb_submit_urb(kaweth->rx_urb, mem_flags))) { kaweth_err("resubmitting rx_urb %d failed", result); } } @@ -493,7 +494,7 @@ static void kaweth_usb_receive(struct urb *urb) urb->status, count, (int)pkt_len); - kaweth_resubmit_rx_urb(kaweth); + kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC); return; } @@ -502,12 +503,12 @@ static void kaweth_usb_receive(struct urb *urb) kaweth_err("Packet length too long for USB frame (pkt_len: %x, count: %x)",pkt_len, count); kaweth_err("Packet len & 2047: %x", pkt_len & 2047); kaweth_err("Count 2: %x", count2); - kaweth_resubmit_rx_urb(kaweth); + kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC); return; } if(!(skb = dev_alloc_skb(pkt_len+2))) { - kaweth_resubmit_rx_urb(kaweth); + kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC); return; } @@ -525,7 +526,7 @@ static void kaweth_usb_receive(struct urb *urb) kaweth->stats.rx_bytes += pkt_len; } - kaweth_resubmit_rx_urb(kaweth); + kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC); } /**************************************************************** @@ -539,11 +540,11 @@ static int kaweth_open(struct net_device *net) kaweth_dbg("Opening network device."); - kaweth_resubmit_rx_urb(kaweth); + MOD_INC_USE_COUNT; - netif_start_queue(net); + kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL); - MOD_INC_USE_COUNT; + netif_start_queue(net); kaweth_async_set_rx_mode(kaweth); return 0; @@ -621,7 +622,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net) kaweth_usb_transmit_complete, kaweth); - if((res = usb_submit_urb(kaweth->tx_urb))) + if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC))) { kaweth_warn("kaweth failed tx_urb %d", res); kaweth->stats.tx_errors++; @@ -975,7 +976,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length) set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&awd.wqh, &wait); urb->context = &awd; - status = usb_submit_urb(urb); + status = usb_submit_urb(urb, GFP_KERNEL); if (status) { // something went wrong usb_free_urb(urb); diff --git a/drivers/usb/mdc800.c b/drivers/usb/mdc800.c index a6b2e0c549e8..eb3d1df911cb 100644 --- a/drivers/usb/mdc800.c +++ b/drivers/usb/mdc800.c @@ -605,7 +605,7 @@ static int mdc800_device_open (struct inode* inode, struct file *file) retval=0; mdc800->irq_urb->dev = mdc800->dev; - if (usb_submit_urb (mdc800->irq_urb)) + if (usb_submit_urb (mdc800->irq_urb, GFP_KERNEL)) { err ("request USB irq fails (submit_retval=%i urb_status=%i).",retval, mdc800->irq_urb->status); errn = -EIO; @@ -694,7 +694,7 @@ static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, lof /* Download -> Request new bytes */ mdc800->download_urb->dev = mdc800->dev; - if (usb_submit_urb (mdc800->download_urb)) + if (usb_submit_urb (mdc800->download_urb, GFP_KERNEL)) { err ("Can't submit download urb (status=%i)",mdc800->download_urb->status); up (&mdc800->io_lock); @@ -808,7 +808,7 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t l mdc800->state=WORKING; memcpy (mdc800->write_urb->transfer_buffer, mdc800->in,8); mdc800->write_urb->dev = mdc800->dev; - if (usb_submit_urb (mdc800->write_urb)) + if (usb_submit_urb (mdc800->write_urb, GFP_KERNEL)) { err ("submitting write urb fails (status=%i)", mdc800->write_urb->status); up (&mdc800->io_lock); diff --git a/drivers/usb/microtek.c b/drivers/usb/microtek.c index ff190dcd76ba..9d68144aa179 100644 --- a/drivers/usb/microtek.c +++ b/drivers/usb/microtek.c @@ -499,7 +499,7 @@ void mts_int_submit_urb (struct urb* transfer, transfer->status = 0; - res = usb_submit_urb( transfer ); + res = usb_submit_urb( transfer, GFP_ATOMIC ); if ( unlikely(res) ) { MTS_INT_ERROR( "could not submit URB! Error was %d\n",(int)res ); context->srb->result = DID_ERROR << 16; @@ -720,7 +720,8 @@ int mts_scsi_queuecommand( Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback ) mts_build_transfer_context( srb, desc ); desc->context.final_callback = callback; - res=usb_submit_urb(desc->urb); + /* here we need ATOMIC as we are called with the iolock */ + res=usb_submit_urb(desc->urb, GFP_ATOMIC); if(unlikely(res)){ MTS_ERROR("error %d submitting URB\n",(int)res); diff --git a/drivers/usb/ov511.c b/drivers/usb/ov511.c index c84a6691aec8..f8d788eb4416 100644 --- a/drivers/usb/ov511.c +++ b/drivers/usb/ov511.c @@ -4457,7 +4457,7 @@ ov511_init_isoc(struct usb_ov511 *ov511) for (n = 0; n < OV511_NUMSBUF; n++) { ov511->sbuf[n].urb->dev = ov511->dev; - err = usb_submit_urb(ov511->sbuf[n].urb); + err = usb_submit_urb(ov511->sbuf[n].urb, GFP_KERNEL); if (err) err("init isoc: usb_submit_urb(%d) ret %d", n, err); } @@ -5618,7 +5618,7 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg = (void *) ularg; int rc; - pde = (struct proc_dir_entry *) inode->u.generic_ip; + pde = PDE(inode); if (!pde) return -ENOENT; diff --git a/drivers/usb/pegasus.c b/drivers/usb/pegasus.c index 96e28260c8b8..02e1a8e84f27 100644 --- a/drivers/usb/pegasus.c +++ b/drivers/usb/pegasus.c @@ -157,7 +157,8 @@ static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) add_wait_queue( &pegasus->ctrl_wait, &wait ); set_current_state( TASK_UNINTERRUPTIBLE ); - if ( (ret = usb_submit_urb( pegasus->ctrl_urb )) ) { + /* using ATOMIC, we'd never wake up if we slept */ + if ( (ret = usb_submit_urb( pegasus->ctrl_urb, GFP_ATOMIC )) ) { err("%s: BAD CTRLs %d", __FUNCTION__, ret); goto out; } @@ -207,7 +208,7 @@ static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) add_wait_queue( &pegasus->ctrl_wait, &wait ); set_current_state( TASK_UNINTERRUPTIBLE ); - if ( (ret = usb_submit_urb( pegasus->ctrl_urb )) ) { + if ( (ret = usb_submit_urb( pegasus->ctrl_urb, GFP_ATOMIC )) ) { err("%s: BAD CTRL %d", __FUNCTION__, ret); goto out; } @@ -257,7 +258,7 @@ static int set_register( pegasus_t *pegasus, __u16 indx, __u8 data ) add_wait_queue( &pegasus->ctrl_wait, &wait ); set_current_state( TASK_UNINTERRUPTIBLE ); - if ( (ret = usb_submit_urb( pegasus->ctrl_urb )) ) { + if ( (ret = usb_submit_urb( pegasus->ctrl_urb, GFP_ATOMIC )) ) { err("%s: BAD CTRL %d", __FUNCTION__, ret); goto out; } @@ -287,7 +288,7 @@ static int update_eth_regs_async( pegasus_t *pegasus ) (char *)&pegasus->dr, pegasus->eth_regs, 3, ctrl_callback, pegasus ); - if ( (ret = usb_submit_urb( pegasus->ctrl_urb )) ) + if ( (ret = usb_submit_urb( pegasus->ctrl_urb, GFP_ATOMIC )) ) err("%s: BAD CTRL %d, flgs %x",__FUNCTION__,ret,pegasus->flags); return ret; @@ -573,7 +574,7 @@ goon: usb_rcvbulkpipe(pegasus->usb, 1), pegasus->rx_buff, PEGASUS_MAX_MTU, read_bulk_callback, pegasus ); - if ( (res = usb_submit_urb(pegasus->rx_urb)) ) + if ( (res = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) ) warn("%s: failed submint rx_urb %d", __FUNCTION__, res); pegasus->flags &= ~PEGASUS_RX_BUSY; } @@ -661,7 +662,7 @@ static int pegasus_start_xmit( struct sk_buff *skb, struct net_device *net ) pegasus->tx_buff, PEGASUS_MAX_MTU, write_bulk_callback, pegasus ); pegasus->tx_urb->transfer_buffer_length = count; - if ((res = usb_submit_urb(pegasus->tx_urb))) { + if ((res = usb_submit_urb(pegasus->tx_urb, GFP_ATOMIC))) { warn("failed tx_urb %d", res); pegasus->stats.tx_errors++; netif_start_queue( net ); @@ -721,14 +722,14 @@ static int pegasus_open(struct net_device *net) usb_rcvbulkpipe(pegasus->usb, 1), pegasus->rx_buff, PEGASUS_MAX_MTU, read_bulk_callback, pegasus ); - if ( (res = usb_submit_urb(pegasus->rx_urb)) ) + if ( (res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL)) ) warn("%s: failed rx_urb %d", __FUNCTION__, res); #ifdef PEGASUS_USE_INTR FILL_INT_URB( pegasus->intr_urb, pegasus->usb, usb_rcvintpipe(pegasus->usb, 3), pegasus->intr_buff, sizeof(pegasus->intr_buff), intr_callback, pegasus, pegasus->intr_interval ); - if ( (res = usb_submit_urb(pegasus->intr_urb)) ) + if ( (res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL)) ) warn("%s: failed intr_urb %d", __FUNCTION__, res); #endif netif_start_queue( net ); diff --git a/drivers/usb/printer.c b/drivers/usb/printer.c index a77f41a109b6..b67fe4805ce3 100644 --- a/drivers/usb/printer.c +++ b/drivers/usb/printer.c @@ -261,7 +261,7 @@ static int usblp_open(struct inode *inode, struct file *file) if (usblp->bidir) { usblp->readcount = 0; usblp->readurb.dev = usblp->dev; - if (usb_submit_urb(&usblp->readurb) < 0) { + if (usb_submit_urb(&usblp->readurb, GFP_KERNEL) < 0) { retval = -EIO; usblp->used = 0; file->private_data = NULL; @@ -456,7 +456,7 @@ static ssize_t usblp_write(struct file *file, const char *buffer, size_t count, usblp->writeurb.dev = usblp->dev; usblp->wcomplete = 0; - if (usb_submit_urb(&usblp->writeurb)) { + if (usb_submit_urb(&usblp->writeurb, GFP_KERNEL)) { count = -EIO; up (&usblp->sem); break; @@ -521,7 +521,7 @@ static ssize_t usblp_read(struct file *file, char *buffer, size_t count, loff_t usblp->minor, usblp->readurb.status); usblp->readurb.dev = usblp->dev; usblp->readcount = 0; - usb_submit_urb(&usblp->readurb); + usb_submit_urb(&usblp->readurb, GFP_KERNEL); count = -EIO; goto done; } @@ -538,7 +538,7 @@ static ssize_t usblp_read(struct file *file, char *buffer, size_t count, loff_t usblp->readcount = 0; usblp->readurb.dev = usblp->dev; usblp->rcomplete = 0; - if (usb_submit_urb(&usblp->readurb)) { + if (usb_submit_urb(&usblp->readurb, GFP_KERNEL)) { count = -EIO; goto done; } diff --git a/drivers/usb/pwc-if.c b/drivers/usb/pwc-if.c index bac4b10b4aa5..ba5f74019952 100644 --- a/drivers/usb/pwc-if.c +++ b/drivers/usb/pwc-if.c @@ -869,7 +869,7 @@ static int pwc_isoc_init(struct pwc_device *pdev) /* link */ for (i = 0; i < MAX_ISO_BUFS; i++) { - ret = usb_submit_urb(pdev->sbuf[i].urb); + ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL); if (ret) Err("isoc_init() submit_urb %d failed with error %d\n", i, ret); else diff --git a/drivers/usb/scanner.c b/drivers/usb/scanner.c index 8dac42ff26c5..8b262b83c275 100644 --- a/drivers/usb/scanner.c +++ b/drivers/usb/scanner.c @@ -992,7 +992,7 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum, // endpoint[(int)have_intr].bInterval); 250); - if (usb_submit_urb(scn->scn_irq)) { + if (usb_submit_urb(scn->scn_irq, GFP_KERNEL)) { err("probe_scanner(%d): Unable to allocate INT URB.", scn_minor); kfree(scn); up(&scn_mutex); diff --git a/drivers/usb/se401.c b/drivers/usb/se401.c index 7029693e2d73..8cdd85e09011 100644 --- a/drivers/usb/se401.c +++ b/drivers/usb/se401.c @@ -556,7 +556,7 @@ static void se401_video_irq(struct urb *urb) /* Resubmit urb for new data */ urb->status=0; urb->dev=se401->dev; - if(usb_submit_urb(urb)) + if(usb_submit_urb(urb, GFP_KERNEL)) info("urb burned down"); return; } @@ -657,7 +657,7 @@ static int se401_start_stream(struct usb_se401 *se401) se401->urb[i]=urb; - err=usb_submit_urb(se401->urb[i]); + err=usb_submit_urb(se401->urb[i], GFP_KERNEL); if(err) err("urb burned down"); } @@ -1477,7 +1477,7 @@ static int se401_init(struct usb_se401 *se401) se401, HZ/10 ); - if (usb_submit_urb(se401->inturb)) { + if (usb_submit_urb(se401->inturb, GFP_KERNEL)) { info("int urb burned down"); return 1; } diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 0f20382baf0c..8b3f1ecf9198 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -217,14 +217,14 @@ static int belkin_sa_open (struct usb_serial_port *port, struct file *filp) * enhance buffering. Win trace shows 16 initial read URBs. */ port->read_urb->dev = port->serial->dev; - retval = usb_submit_urb(port->read_urb); + retval = usb_submit_urb(port->read_urb, GFP_KERNEL); if (retval) { err("usb_submit_urb(read bulk) failed"); goto exit; } port->interrupt_in_urb->dev = port->serial->dev; - retval = usb_submit_urb(port->interrupt_in_urb); + retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (retval) err(" usb_submit_urb(read int) failed"); } diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index fcdb59e741d1..e2c0536d6a7d 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -173,7 +173,7 @@ static int cyberjack_open (struct usb_serial_port *port, struct file *filp) usb_unlink_urb (port->interrupt_in_urb); port->interrupt_in_urb->dev = port->serial->dev; - result = usb_submit_urb(port->interrupt_in_urb); + result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (result) err(" usb_submit_urb(read int) failed"); dbg(__FUNCTION__ " - usb_submit_urb(int urb)"); @@ -271,7 +271,7 @@ static int cyberjack_write (struct usb_serial_port *port, int from_user, const u port); /* send the data out the bulk port */ - result = usb_submit_urb(port->write_urb); + result = usb_submit_urb(port->write_urb, GFP_KERNEL); if (result) { err(__FUNCTION__ " - failed submitting write urb, error %d", result); /* Throw away data. No better idea what to do with it. */ @@ -342,7 +342,7 @@ static void cyberjack_read_int_callback( struct urb *urb ) if( !old_rdtodo ) { port->read_urb->dev = port->serial->dev; - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if( result ) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); dbg(__FUNCTION__ " - usb_submit_urb(read urb)"); @@ -398,7 +398,7 @@ static void cyberjack_read_bulk_callback (struct urb *urb) /* Continue to read if we have still urbs to do. */ if( priv->rdtodo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/ ) { port->read_urb->dev = port->serial->dev; - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); dbg(__FUNCTION__ " - usb_submit_urb(read urb)"); @@ -453,7 +453,7 @@ static void cyberjack_write_bulk_callback (struct urb *urb) port); /* send the data out the bulk port */ - result = usb_submit_urb(port->write_urb); + result = usb_submit_urb(port->write_urb, GFP_KERNEL); if (result) { err(__FUNCTION__ " - failed submitting write urb, error %d", result); /* Throw away data. No better idea what to do with it. */ diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 4edf3c7a38af..2ee1abbd10bc 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -676,7 +676,7 @@ dbg( "digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, co oob_port->write_urb->transfer_buffer_length = len; oob_port->write_urb->dev = port->serial->dev; - if( (ret=usb_submit_urb(oob_port->write_urb)) == 0 ) { + if( (ret=usb_submit_urb(oob_port->write_urb, GFP_KERNEL)) == 0 ) { oob_priv->dp_write_urb_in_use = 1; count -= len; buf += len; @@ -764,7 +764,7 @@ count ); } port->write_urb->dev = port->serial->dev; - if( (ret=usb_submit_urb(port->write_urb)) == 0 ) { + if( (ret=usb_submit_urb(port->write_urb, GFP_KERNEL)) == 0 ) { priv->dp_write_urb_in_use = 1; priv->dp_out_buf_len = 0; count -= len; @@ -841,7 +841,7 @@ port_priv->dp_port_num, modem_signals ); oob_port->write_urb->transfer_buffer_length = 8; oob_port->write_urb->dev = port->serial->dev; - if( (ret=usb_submit_urb(oob_port->write_urb)) == 0 ) { + if( (ret=usb_submit_urb(oob_port->write_urb, GFP_KERNEL)) == 0 ) { oob_priv->dp_write_urb_in_use = 1; port_priv->dp_modem_signals = (port_priv->dp_modem_signals&~(TIOCM_DTR|TIOCM_RTS)) @@ -962,7 +962,7 @@ dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num ); /* restart read chain */ if( priv->dp_throttle_restart ) { port->read_urb->dev = port->serial->dev; - ret = usb_submit_urb( port->read_urb ); + ret = usb_submit_urb( port->read_urb, GFP_KERNEL ); } /* turn throttle off */ @@ -1323,7 +1323,7 @@ priv->dp_port_num, count, from_user, in_interrupt() ); /* copy in new data */ memcpy( data, from_user ? user_buf : buf, new_len ); - if( (ret=usb_submit_urb(port->write_urb)) == 0 ) { + if( (ret=usb_submit_urb(port->write_urb, GFP_KERNEL)) == 0 ) { priv->dp_write_urb_in_use = 1; ret = new_len; priv->dp_out_buf_len = 0; @@ -1399,7 +1399,7 @@ dbg( "digi_write_bulk_callback: TOP, urb->status=%d", urb->status ); memcpy( port->write_urb->transfer_buffer+2, priv->dp_out_buf, priv->dp_out_buf_len ); - if( (ret=usb_submit_urb(port->write_urb)) == 0 ) { + if( (ret=usb_submit_urb(port->write_urb, GFP_KERNEL)) == 0 ) { priv->dp_write_urb_in_use = 1; priv->dp_out_buf_len = 0; } @@ -1677,7 +1677,7 @@ static int digi_startup_device( struct usb_serial *serial ) port->write_urb->dev = port->serial->dev; - if( (ret=usb_submit_urb(port->read_urb)) != 0 ) { + if( (ret=usb_submit_urb(port->read_urb, GFP_KERNEL)) != 0 ) { err( __FUNCTION__ ": usb_submit_urb failed, ret=%d, port=%d", ret, i ); @@ -1837,7 +1837,7 @@ dbg( "digi_read_bulk_callback: TOP" ); /* continue read */ urb->dev = port->serial->dev; - if( (ret=usb_submit_urb(urb)) != 0 ) { + if( (ret=usb_submit_urb(urb, GFP_KERNEL)) != 0 ) { err( __FUNCTION__ ": failed resubmitting urb, ret=%d, port=%d", ret, priv->dp_port_num ); } diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 49e00fc8bb61..ecabfa0b502e 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c @@ -182,7 +182,7 @@ static int empeg_open (struct usb_serial_port *port, struct file *filp) port->read_urb->transfer_flags |= USB_QUEUE_BULK; - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed submitting read urb, error %d", result); @@ -296,7 +296,7 @@ static int empeg_write (struct usb_serial_port *port, int from_user, const unsig urb->transfer_flags |= USB_QUEUE_BULK; /* send it down the pipe */ - status = usb_submit_urb(urb); + status = usb_submit_urb(urb, GFP_KERNEL); if (status) { err(__FUNCTION__ " - usb_submit_urb(write bulk) failed with status = %d", status); bytes_sent = status; @@ -449,7 +449,7 @@ static void empeg_read_bulk_callback (struct urb *urb) port->read_urb->transfer_flags |= USB_QUEUE_BULK; - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); @@ -484,7 +484,7 @@ static void empeg_unthrottle (struct usb_serial_port *port) port->read_urb->dev = port->serial->dev; - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed submitting read urb, error %d", result); diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index d323a742f7ef..29faf65b73a0 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -356,7 +356,7 @@ static int ftdi_sio_open (struct usb_serial_port *port, struct file *filp) usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, ftdi_sio_read_bulk_callback, port); - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed submitting read urb, error %d", result); } @@ -479,7 +479,7 @@ static int ftdi_sio_write (struct usb_serial_port *port, int from_user, port->write_urb->transfer_buffer, count, ftdi_sio_write_bulk_callback, port); - result = usb_submit_urb(port->write_urb); + result = usb_submit_urb(port->write_urb, GFP_KERNEL); if (result) { err(__FUNCTION__ " - failed submitting write urb, error %d", result); up (&port->sem); @@ -644,7 +644,7 @@ static void ftdi_sio_read_bulk_callback (struct urb *urb) port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, ftdi_sio_read_bulk_callback, port); - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index de7463529c3e..42b8e39cdc44 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -787,7 +787,7 @@ static void edge_interrupt_callback (struct urb *urb) /* we have pending bytes on the bulk in pipe, send a request */ edge_serial->read_urb->dev = edge_serial->serial->dev; - result = usb_submit_urb(edge_serial->read_urb); + result = usb_submit_urb(edge_serial->read_urb, GFP_KERNEL); if (result) { dbg(__FUNCTION__" - usb_submit_urb(read bulk) failed with result = %d", result); } @@ -864,7 +864,7 @@ static void edge_bulk_in_callback (struct urb *urb) /* there is, so resubmit our urb */ edge_serial->read_urb->dev = edge_serial->serial->dev; - status = usb_submit_urb(edge_serial->read_urb); + status = usb_submit_urb(edge_serial->read_urb, GFP_KERNEL); if (status) { err(__FUNCTION__" - usb_submit_urb(read bulk) failed, status = %d", status); } @@ -1031,7 +1031,7 @@ static int edge_open (struct usb_serial_port *port, struct file * filp) /* start interrupt read for this edgeport * this interrupt will continue as long as the edgeport is connected */ - response = usb_submit_urb (edge_serial->interrupt_read_urb); + response = usb_submit_urb (edge_serial->interrupt_read_urb, GFP_KERNEL); if (response) { err(__FUNCTION__" - Error %d submitting control urb", response); } @@ -1471,7 +1471,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, struct edge urb->transfer_flags |= USB_QUEUE_BULK; urb->dev = edge_serial->serial->dev; - status = usb_submit_urb(urb); + status = usb_submit_urb(urb, GFP_KERNEL); if (status) { /* something went wrong */ dbg(__FUNCTION__" - usb_submit_urb(write bulk) failed"); @@ -2477,7 +2477,7 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer urb->transfer_flags |= USB_QUEUE_BULK; edge_port->commandPending = TRUE; - status = usb_submit_urb(urb); + status = usb_submit_urb(urb, GFP_KERNEL); if (status) { /* something went wrong */ diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 6966bd9d50f7..9167717f7e10 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -171,7 +171,7 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp) usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, ipaq_read_bulk_callback, port); - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) { err(__FUNCTION__ " - failed submitting read urb, error %d", result); } @@ -288,7 +288,7 @@ static void ipaq_read_bulk_callback(struct urb *urb) usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, ipaq_read_bulk_callback, port); - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); return; @@ -403,7 +403,7 @@ static int ipaq_write_flush(struct usb_serial_port *port) usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer, count, ipaq_write_bulk_callback, port); - result = usb_submit_urb(urb); + result = usb_submit_urb(urb, GFP_KERNEL); if (result) { err(__FUNCTION__ " - failed submitting write urb, error %d", result); } diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 7672fc1c5558..69a572b6d8ac 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -289,7 +289,7 @@ static int ir_open (struct usb_serial_port *port, struct file *filp) ir_read_bulk_callback, port); port->read_urb->transfer_flags = USB_QUEUE_BULK; - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err("%s - failed submitting read urb, error %d", __FUNCTION__, result); } @@ -382,7 +382,7 @@ static int ir_write (struct usb_serial_port *port, int from_user, const unsigned = USB_QUEUE_BULK | USB_ZERO_PACKET; - result = usb_submit_urb (port->write_urb); + result = usb_submit_urb (port->write_urb, GFP_KERNEL); if (result) err("%s - failed submitting write urb, error %d", __FUNCTION__, result); else @@ -492,7 +492,7 @@ static void ir_read_bulk_callback (struct urb *urb) port->read_urb->transfer_flags = USB_QUEUE_BULK; - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err("%s - failed resubmitting read urb, error %d", @@ -591,7 +591,7 @@ static void ir_set_termios (struct usb_serial_port *port, struct termios *old_te = USB_QUEUE_BULK | USB_ZERO_PACKET; - result = usb_submit_urb (port->write_urb); + result = usb_submit_urb (port->write_urb, GFP_KERNEL); if (result) err("%s - failed submitting write urb, error %d", __FUNCTION__, result); } diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 43bc791c6cde..ffb356043fa6 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -378,7 +378,7 @@ static int keyspan_write(struct usb_serial_port *port, int from_user, this_urb->transfer_flags &= ~USB_ASYNC_UNLINK; this_urb->dev = port->serial->dev; - if ((err = usb_submit_urb(this_urb)) != 0) { + if ((err = usb_submit_urb(this_urb, GFP_KERNEL)) != 0) { dbg("usb_submit_urb(write bulk) failed (%d)\n", err); } p_priv->tx_start_time[flip] = jiffies; @@ -436,7 +436,7 @@ static void usa26_indat_callback(struct urb *urb) /* Resubmit urb so we continue receiving */ urb->dev = port->serial->dev; - if ((err = usb_submit_urb(urb)) != 0) { + if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) { dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err); } return; @@ -535,7 +535,7 @@ static void usa26_instat_callback(struct urb *urb) exit: /* Resubmit urb so we continue receiving */ urb->dev = serial->dev; - if ((err = usb_submit_urb(urb)) != 0) { + if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) { dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err); } } @@ -586,7 +586,7 @@ static void usa28_indat_callback(struct urb *urb) /* Resubmit urb so we continue receiving */ urb->dev = port->serial->dev; - if ((err = usb_submit_urb(urb)) != 0) { + if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) { dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err); } @@ -671,7 +671,7 @@ static void usa28_instat_callback(struct urb *urb) exit: /* Resubmit urb so we continue receiving */ urb->dev = serial->dev; - if ((err = usb_submit_urb(urb)) != 0) { + if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) { dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err); } } @@ -764,7 +764,7 @@ exit: /* Resubmit urb so we continue receiving */ urb->dev = serial->dev; - if ((err = usb_submit_urb(urb)) != 0) { + if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) { dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err); } } @@ -819,7 +819,7 @@ static void usa49_indat_callback(struct urb *urb) /* Resubmit urb so we continue receiving */ urb->dev = port->serial->dev; - if ((err = usb_submit_urb(urb)) != 0) { + if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) { dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err); } } @@ -880,7 +880,7 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp) if ((urb = p_priv->in_urbs[i]) == NULL) continue; urb->dev = serial->dev; - if ((err = usb_submit_urb(urb)) != 0) { + if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) { dbg(__FUNCTION__ " submit urb %d failed (%d)\n", i, err); } } @@ -1408,7 +1408,7 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial, this_urb->transfer_buffer_length = sizeof(msg); this_urb->dev = serial->dev; - if ((err = usb_submit_urb(this_urb)) != 0) { + if ((err = usb_submit_urb(this_urb, GFP_KERNEL)) != 0) { dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)\n", err); } #if 0 @@ -1494,7 +1494,7 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial, this_urb->transfer_buffer_length = sizeof(msg); this_urb->dev = serial->dev; - if ((err = usb_submit_urb(this_urb)) != 0) { + if ((err = usb_submit_urb(this_urb, GFP_KERNEL)) != 0) { dbg(__FUNCTION__ " usb_submit_urb(setup) failed\n"); } #if 0 @@ -1622,7 +1622,7 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial, this_urb->transfer_buffer_length = sizeof(msg); this_urb->dev = serial->dev; - if ((err = usb_submit_urb(this_urb)) != 0) { + if ((err = usb_submit_urb(this_urb, GFP_KERNEL)) != 0) { dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)\n", err); } #if 0 @@ -1708,7 +1708,7 @@ static int keyspan_startup (struct usb_serial *serial) keyspan_setup_urbs(serial); s_priv->instat_urb->dev = serial->dev; - if ((err = usb_submit_urb(s_priv->instat_urb)) != 0) { + if ((err = usb_submit_urb(s_priv->instat_urb, GFP_KERNEL)) != 0) { dbg(__FUNCTION__ " submit instat urb failed %d\n", err); } diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index a45751e5219a..e17f1b3bee84 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -292,7 +292,7 @@ static void keyspan_pda_rx_unthrottle (struct usb_serial_port *port) /* just restart the receive interrupt URB */ dbg("keyspan_pda_rx_unthrottle port %d", port->number); port->interrupt_in_urb->dev = port->serial->dev; - if (usb_submit_urb(port->interrupt_in_urb)) + if (usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL)) dbg(" usb_submit_urb(read urb) failed"); return; } @@ -584,7 +584,7 @@ static int keyspan_pda_write(struct usb_serial_port *port, int from_user, priv->tx_room -= count; port->write_urb->dev = port->serial->dev; - rc = usb_submit_urb(port->write_urb); + rc = usb_submit_urb(port->write_urb, GFP_KERNEL); if (rc) { dbg(" usb_submit_urb(write bulk) failed"); goto exit; @@ -699,7 +699,7 @@ static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp) /*Start reading from the device*/ port->interrupt_in_urb->dev = serial->dev; - rc = usb_submit_urb(port->interrupt_in_urb); + rc = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (rc) { dbg(__FUNCTION__" - usb_submit_urb(read int) failed"); goto error; diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 4278bcb58a1b..533c83271f10 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -404,7 +404,7 @@ static int klsi_105_open (struct usb_serial_port *port, struct file *filp) port); port->read_urb->transfer_flags |= USB_QUEUE_BULK; - rc = usb_submit_urb(port->read_urb); + rc = usb_submit_urb(port->read_urb, GFP_KERNEL); if (rc) { err(__FUNCTION__ " - failed submitting read urb, error %d", rc); @@ -567,7 +567,7 @@ static int klsi_105_write (struct usb_serial_port *port, int from_user, /* send the data out the bulk port */ - result = usb_submit_urb(urb); + result = usb_submit_urb(urb, GFP_KERNEL); if (result) { err(__FUNCTION__ " - failed submitting write urb, error %d", result); @@ -734,7 +734,7 @@ static void klsi_105_read_bulk_callback (struct urb *urb) port->read_urb->transfer_buffer_length, klsi_105_read_bulk_callback, port); - rc = usb_submit_urb(port->read_urb); + rc = usb_submit_urb(port->read_urb, GFP_KERNEL); if (rc) err(__FUNCTION__ " - failed resubmitting read urb, error %d", rc); @@ -1041,7 +1041,7 @@ static void klsi_105_unthrottle (struct usb_serial_port *port) down (&port->sem); port->read_urb->dev = port->serial->dev; - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed submitting read urb, error %d", result); diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 90d296ee3850..16f32e65f490 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -384,14 +384,14 @@ static int mct_u232_open (struct usb_serial_port *port, struct file *filp) } port->read_urb->dev = port->serial->dev; - retval = usb_submit_urb(port->read_urb); + retval = usb_submit_urb(port->read_urb, GFP_KERNEL); if (retval) { err("usb_submit_urb(read bulk) failed"); goto exit; } port->interrupt_in_urb->dev = port->serial->dev; - retval = usb_submit_urb(port->interrupt_in_urb); + retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (retval) err(" usb_submit_urb(read int) failed"); @@ -482,7 +482,7 @@ static int mct_u232_write (struct usb_serial_port *port, int from_user, port); /* send the data out the bulk port */ - result = usb_submit_urb(port->write_urb); + result = usb_submit_urb(port->write_urb, GFP_KERNEL); if (result) { err(__FUNCTION__ " - failed submitting write urb, error %d", result); diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 56cba64d9b5a..9a778fc3cd41 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -179,7 +179,7 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp) usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, omninet_read_bulk_callback, port); - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed submitting read urb, error %d", result); } @@ -274,7 +274,7 @@ static void omninet_read_bulk_callback (struct urb *urb) usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), urb->transfer_buffer, urb->transfer_buffer_length, omninet_read_bulk_callback, port); - result = usb_submit_urb(urb); + result = usb_submit_urb(urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); @@ -325,7 +325,7 @@ static int omninet_write (struct usb_serial_port *port, int from_user, const uns wport->write_urb->transfer_buffer_length = 64; wport->write_urb->dev = serial->dev; - result = usb_submit_urb(wport->write_urb); + result = usb_submit_urb(wport->write_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed submitting write urb, error %d", result); else diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 4e667199590b..f6f14f60b6cb 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -195,7 +195,7 @@ static int pl2303_write (struct usb_serial_port *port, int from_user, const uns port->write_urb->transfer_buffer_length = count; port->write_urb->dev = port->serial->dev; - result = usb_submit_urb (port->write_urb); + result = usb_submit_urb (port->write_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed submitting write urb, error %d", result); else @@ -404,7 +404,7 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp) dbg (__FUNCTION__ " - submitting read urb"); port->read_urb->dev = serial->dev; - result = usb_submit_urb (port->read_urb); + result = usb_submit_urb (port->read_urb, GFP_KERNEL); if (result) { err(__FUNCTION__ " - failed submitting read urb, error %d", result); up (&port->sem); @@ -414,7 +414,7 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp) dbg (__FUNCTION__ " - submitting interrupt urb"); port->interrupt_in_urb->dev = serial->dev; - result = usb_submit_urb (port->interrupt_in_urb); + result = usb_submit_urb (port->interrupt_in_urb, GFP_KERNEL); if (result) { err(__FUNCTION__ " - failed submitting interrupt urb, error %d", result); up (&port->sem); @@ -652,7 +652,7 @@ static void pl2303_read_bulk_callback (struct urb *urb) dbg (__FUNCTION__ " - caught -EPROTO, resubmitting the urb"); urb->status = 0; urb->dev = serial->dev; - result = usb_submit_urb(urb); + result = usb_submit_urb(urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); return; @@ -677,7 +677,7 @@ static void pl2303_read_bulk_callback (struct urb *urb) /* Schedule the next read _if_ we are still open */ if (port->open_count) { urb->dev = serial->dev; - result = usb_submit_urb(urb); + result = usb_submit_urb(urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); } @@ -706,7 +706,7 @@ static void pl2303_write_bulk_callback (struct urb *urb) dbg (__FUNCTION__ " - nonzero write bulk status received: %d", urb->status); port->write_urb->transfer_buffer_length = 1; port->write_urb->dev = port->serial->dev; - result = usb_submit_urb (port->write_urb); + result = usb_submit_urb (port->write_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed resubmitting write urb, error %d", result); diff --git a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c index 808c82985cab..7dcbb92890e9 100644 --- a/drivers/usb/serial/usbserial.c +++ b/drivers/usb/serial/usbserial.c @@ -813,7 +813,7 @@ static int generic_open (struct usb_serial_port *port, struct file *filp) serial->type->read_bulk_callback : generic_read_bulk_callback), port); - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); } @@ -894,7 +894,7 @@ static int generic_write (struct usb_serial_port *port, int from_user, const uns generic_write_bulk_callback), port); /* send the data out the bulk port */ - result = usb_submit_urb(port->write_urb); + result = usb_submit_urb(port->write_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed submitting write urb, error %d", result); else @@ -987,7 +987,7 @@ static void generic_read_bulk_callback (struct urb *urb) ((serial->type->read_bulk_callback) ? serial->type->read_bulk_callback : generic_read_bulk_callback), port); - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); } diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index ce34eb15a8d6..9b4e8bcc423e 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -274,7 +274,7 @@ static int visor_open (struct usb_serial_port *port, struct file *filp) port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, visor_read_bulk_callback, port); - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed submitting read urb, error %d", result); } @@ -388,7 +388,7 @@ static int visor_write (struct usb_serial_port *port, int from_user, const unsig urb->transfer_flags |= USB_QUEUE_BULK; /* send it down the pipe */ - status = usb_submit_urb(urb); + status = usb_submit_urb(urb, GFP_KERNEL); if (status) { err(__FUNCTION__ " - usb_submit_urb(write bulk) failed with status = %d", status); bytes_sent = status; @@ -520,7 +520,7 @@ static void visor_read_bulk_callback (struct urb *urb) port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, visor_read_bulk_callback, port); - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); return; @@ -551,7 +551,7 @@ static void visor_unthrottle (struct usb_serial_port *port) down (&port->sem); port->read_urb->dev = port->serial->dev; - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) err(__FUNCTION__ " - failed submitting read urb, error %d", result); diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index dc10e752f86c..e90ea4a33b8e 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -240,7 +240,7 @@ static void command_port_read_callback (struct urb *urb) usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, command_port_read_callback, port); - result = usb_submit_urb(port->read_urb); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); if (result) dbg(__FUNCTION__ " - failed resubmitting read urb, error %d", result); } @@ -265,7 +265,7 @@ static int whiteheat_send_cmd (struct usb_serial *serial, __u8 command, __u8 *da memcpy (&transfer_buffer[1], data, datasize); port->write_urb->transfer_buffer_length = datasize + 1; port->write_urb->dev = serial->dev; - retval = usb_submit_urb (port->write_urb); + retval = usb_submit_urb (port->write_urb, GFP_KERNEL); if (retval) { dbg (__FUNCTION__" - submit urb failed"); goto exit; @@ -327,7 +327,7 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp) command_port->read_urb->complete = command_port_read_callback; command_port->read_urb->dev = port->serial->dev; command_port->tty = port->tty; /* need this to "fake" our our sanity check macros */ - retval = usb_submit_urb (command_port->read_urb); + retval = usb_submit_urb (command_port->read_urb, GFP_KERNEL); if (retval) { err(__FUNCTION__ " - failed submitting read urb, error %d", retval); goto error_exit; @@ -336,7 +336,7 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp) /* Start reading from the device */ port->read_urb->dev = port->serial->dev; - retval = usb_submit_urb(port->read_urb); + retval = usb_submit_urb(port->read_urb, GFP_KERNEL); if (retval) { err(__FUNCTION__ " - failed submitting read urb, error %d", retval); goto error_exit; diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 8611a366d937..596aa799adf1 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -278,7 +278,7 @@ static int bus_reset( Scsi_Cmnd *srb ) if (us->protocol == US_PR_CBI) { down(&(us->irq_urb_sem)); us->irq_urb->dev = us->pusb_dev; - result = usb_submit_urb(us->irq_urb); + result = usb_submit_urb(us->irq_urb, GFP_NOIO); US_DEBUGP("usb_submit_urb() returns %d\n", result); up(&(us->irq_urb_sem)); } diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 7b40983c7a99..f5f3d5ee70a9 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -414,7 +414,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe, us->current_urb->transfer_flags = USB_ASYNC_UNLINK; /* submit the URB */ - status = usb_submit_urb(us->current_urb); + status = usb_submit_urb(us->current_urb, GFP_NOIO); if (status) { /* something went wrong */ up(&(us->current_urb_sem)); @@ -461,7 +461,7 @@ int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe, us->current_urb->transfer_flags = USB_ASYNC_UNLINK; /* submit the URB */ - status = usb_submit_urb(us->current_urb); + status = usb_submit_urb(us->current_urb, GFP_NOIO); if (status) { /* something went wrong */ up(&(us->current_urb_sem)); diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 0932c1b27119..ee8c4c5fc880 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -534,7 +534,7 @@ static int usb_stor_allocate_irq(struct us_data *ss) usb_stor_CBI_irq, ss, ss->ep_int->bInterval); /* submit the URB for processing */ - result = usb_submit_urb(ss->irq_urb); + result = usb_submit_urb(ss->irq_urb, GFP_KERNEL); US_DEBUGP("usb_submit_urb() returns %d\n", result); if (result) { usb_free_urb(ss->irq_urb); diff --git a/drivers/usb/stv680.c b/drivers/usb/stv680.c index e5f89a3de975..442f31139787 100644 --- a/drivers/usb/stv680.c +++ b/drivers/usb/stv680.c @@ -765,7 +765,7 @@ static void stv680_video_irq (struct urb *urb) /* Resubmit urb for new data */ urb->status = 0; urb->dev = stv680->udev; - if (usb_submit_urb (urb)) + if (usb_submit_urb (urb, GFP_KERNEL)) PDEBUG (0, "STV(e): urb burned down in video irq"); return; } /* _video_irq */ @@ -816,7 +816,7 @@ static int stv680_start_stream (struct usb_stv *stv680) urb->timeout = PENCAM_TIMEOUT * 2; urb->transfer_flags |= USB_QUEUE_BULK; stv680->urb[i] = urb; - err = usb_submit_urb (stv680->urb[i]); + err = usb_submit_urb (stv680->urb[i], GFP_KERNEL); if (err) PDEBUG (0, "STV(e): urb burned down in start stream"); } /* i STV680_NUMSBUF */ diff --git a/drivers/usb/uhci-debug.h b/drivers/usb/uhci-debug.h index 5ff42d2393d6..3206bcdff954 100644 --- a/drivers/usb/uhci-debug.h +++ b/drivers/usb/uhci-debug.h @@ -12,6 +12,7 @@ #include <linux/config.h> #include <linux/kernel.h> #include <linux/proc_fs.h> +#include <linux/smp_lock.h> #include <asm/io.h> #include "uhci.h" @@ -476,7 +477,7 @@ struct uhci_proc { static int uhci_proc_open(struct inode *inode, struct file *file) { - const struct proc_dir_entry *dp = inode->u.generic_ip; + const struct proc_dir_entry *dp = PDE(inode); struct uhci *uhci = dp->data; struct uhci_proc *up; unsigned long flags; @@ -507,8 +508,11 @@ out: static loff_t uhci_proc_lseek(struct file *file, loff_t off, int whence) { - struct uhci_proc *up = file->private_data; - loff_t new; + struct uhci_proc *up; + loff_t new = -1; + + lock_kernel(); + up = file->private_data; switch (whence) { case 0: @@ -517,12 +521,12 @@ static loff_t uhci_proc_lseek(struct file *file, loff_t off, int whence) case 1: new = file->f_pos + off; break; - case 2: - default: - return -EINVAL; } - if (new < 0 || new > up->size) + if (new < 0 || new > up->size) { + unlock_kernel(); return -EINVAL; + } + unlock_kernel(); return (file->f_pos = new); } diff --git a/drivers/usb/uhci.c b/drivers/usb/uhci.c index f34ffcdd6e50..de765d9dc79a 100644 --- a/drivers/usb/uhci.c +++ b/drivers/usb/uhci.c @@ -1476,7 +1476,7 @@ out: return u; } -static int uhci_submit_urb(struct urb *urb) +static int uhci_submit_urb(struct urb *urb, int mem_flags) { int ret = -EINVAL; struct uhci *uhci; @@ -1823,11 +1823,11 @@ static int uhci_get_current_frame_number(struct usb_device *dev) } struct usb_operations uhci_device_operations = { - uhci_alloc_dev, - uhci_free_dev, - uhci_get_current_frame_number, - uhci_submit_urb, - uhci_unlink_urb + allocate: uhci_alloc_dev, + deallocate: uhci_free_dev, + get_frame_number: uhci_get_current_frame_number, + submit_urb: uhci_submit_urb, + unlink_urb: uhci_unlink_urb, }; /* Virtual Root Hub */ @@ -2294,7 +2294,7 @@ static void uhci_call_completion(struct urb *urb) } else { if (is_ring && !killed) { urb->dev = dev; - uhci_submit_urb(urb); + uhci_submit_urb(urb, GFP_KERNEL); } else { /* We decrement the usage count after we're done */ /* with everything */ diff --git a/drivers/usb/usb-ohci.c b/drivers/usb/usb-ohci.c index a33ffebb6c2f..94f84edfc94f 100644 --- a/drivers/usb/usb-ohci.c +++ b/drivers/usb/usb-ohci.c @@ -532,7 +532,7 @@ static int sohci_return_urb (struct ohci *hc, struct urb * urb) /* get a transfer request */ -static int sohci_submit_urb (struct urb * urb) +static int sohci_submit_urb (struct urb * urb, int mem_flags) { ohci_t * ohci; ed_t * ed; @@ -542,7 +542,6 @@ static int sohci_submit_urb (struct urb * urb) int i, size = 0; unsigned long flags; int bustime = 0; - int mem_flags = ALLOC_FLAGS; if (!urb->dev || !urb->dev->bus) return -ENODEV; @@ -612,8 +611,7 @@ static int sohci_submit_urb (struct urb * urb) } /* allocate the private part of the URB */ - urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), mem_flags); if (!urb_priv) { usb_dec_dev_use (urb->dev); return -ENOMEM; @@ -919,11 +917,11 @@ static int sohci_get_current_frame_number (struct usb_device *usb_dev) /*-------------------------------------------------------------------------*/ struct usb_operations sohci_device_operations = { - sohci_alloc_dev, - sohci_free_dev, - sohci_get_current_frame_number, - sohci_submit_urb, - sohci_unlink_urb + allocate: sohci_alloc_dev, + deallocate: sohci_free_dev, + get_frame_number: sohci_get_current_frame_number, + submit_urb: sohci_submit_urb, + unlink_urb: sohci_unlink_urb, }; /*-------------------------------------------------------------------------* diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 4abfb6559aa7..247cfc7aa622 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -431,7 +431,9 @@ static ssize_t skel_write (struct file *file, const char *buffer, size_t count, skel_write_bulk_callback, dev); /* send the data out the bulk port */ - retval = usb_submit_urb(dev->write_urb); + /* a character device write uses GFP_KERNEL, + unless a spinlock is held */ + retval = usb_submit_urb(dev->write_urb, GFP_KERNEL); if (retval) { err(__FUNCTION__ " - failed submitting write urb, error %d", retval); diff --git a/drivers/usb/usb-uhci.c b/drivers/usb/usb-uhci.c index 3c89ed98235c..83d38a9ec4b2 100644 --- a/drivers/usb/usb-uhci.c +++ b/drivers/usb/usb-uhci.c @@ -87,7 +87,6 @@ #endif #define SLAB_FLAG (in_interrupt ()? SLAB_ATOMIC : SLAB_KERNEL) -#define KMALLOC_FLAG (in_interrupt ()? GFP_ATOMIC : GFP_KERNEL) /* CONFIG_USB_UHCI_HIGH_BANDWITH turns on Full Speed Bandwidth * Reclamation: feature that puts loop on descriptor loop when @@ -1499,7 +1498,7 @@ _static int uhci_submit_int_urb (struct urb *urb) return 0; } /*-------------------------------------------------------------------*/ -_static int uhci_submit_iso_urb (struct urb *urb) +_static int uhci_submit_iso_urb (struct urb *urb, int mem_flags) { uhci_t *s = (uhci_t*) urb->dev->bus->hcpriv; urb_priv_t *urb_priv = urb->hcpriv; @@ -1519,7 +1518,7 @@ _static int uhci_submit_iso_urb (struct urb *urb) if (ret) goto err; - tdm = (uhci_desc_t **) kmalloc (urb->number_of_packets * sizeof (uhci_desc_t*), KMALLOC_FLAG); + tdm = (uhci_desc_t **) kmalloc (urb->number_of_packets * sizeof (uhci_desc_t*), mem_flags); if (!tdm) { ret = -ENOMEM; @@ -1616,7 +1615,7 @@ _static struct urb* search_dev_ep (uhci_t *s, struct urb *urb) return 0; } /*-------------------------------------------------------------------*/ -_static int uhci_submit_urb (struct urb *urb) +_static int uhci_submit_urb (struct urb *urb, int mem_flags) { uhci_t *s; urb_priv_t *urb_priv; @@ -1673,7 +1672,7 @@ _static int uhci_submit_urb (struct urb *urb) #ifdef DEBUG_SLAB urb_priv = kmem_cache_alloc(urb_priv_kmem, SLAB_FLAG); #else - urb_priv = kmalloc (sizeof (urb_priv_t), KMALLOC_FLAG); + urb_priv = kmalloc (sizeof (urb_priv_t), mem_flags); #endif if (!urb_priv) { usb_dec_dev_use (urb->dev); @@ -1726,12 +1725,12 @@ _static int uhci_submit_urb (struct urb *urb) if (bustime < 0) ret = bustime; else { - ret = uhci_submit_iso_urb(urb); + ret = uhci_submit_iso_urb(urb, mem_flags); if (ret == 0) usb_claim_bandwidth (urb->dev, urb, bustime, 1); } } else { /* bandwidth is already set */ - ret = uhci_submit_iso_urb(urb); + ret = uhci_submit_iso_urb(urb, mem_flags); } break; case PIPE_INTERRUPT: @@ -2276,11 +2275,11 @@ _static int uhci_get_current_frame_number (struct usb_device *usb_dev) struct usb_operations uhci_device_operations = { - uhci_alloc_dev, - uhci_free_dev, - uhci_get_current_frame_number, - uhci_submit_urb, - uhci_unlink_urb + allocate: uhci_alloc_dev, + deallocate: uhci_free_dev, + get_frame_number: uhci_get_current_frame_number, + submit_urb: uhci_submit_urb, + unlink_urb: uhci_unlink_urb, }; _static void correct_data_toggles(struct urb *urb) @@ -2694,7 +2693,10 @@ _static int process_urb (uhci_t *s, struct list_head *p) spin_unlock(&s->urb_list_lock); - ret_submit=uhci_submit_urb(next_urb); + // FIXME!!! + // We need to know the real state, so + // GFP_ATOMIC is probably not correct + ret_submit=uhci_submit_urb(next_urb, GFP_ATOMIC); spin_lock(&s->urb_list_lock); if (ret_submit) @@ -2718,7 +2720,10 @@ _static int process_urb (uhci_t *s, struct list_head *p) // Re-submit the URB if ring-linked if (is_ring && !was_unlinked && !contains_killed) { urb->dev=usb_dev; - uhci_submit_urb (urb); + // FIXME!!! + // We need to know the real state, so + // GFP_ATOMIC is probably not correct + uhci_submit_urb (urb, GFP_ATOMIC); } spin_lock(&s->urb_list_lock); } diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c index 06b8c6623c43..e94daf9e1e89 100644 --- a/drivers/usb/usb.c +++ b/drivers/usb/usb.c @@ -1148,6 +1148,7 @@ struct urb * usb_get_urb(struct urb *urb) /** * usb_submit_urb - asynchronously issue a transfer request for an endpoint * @urb: pointer to the urb describing the request + * @mem_flags: the type of memory to allocate, see kmalloc() for a list of valid options for this. * * This submits a transfer request, and transfers control of the URB * describing that request to the USB subsystem. Request completion will @@ -1197,12 +1198,49 @@ struct urb * usb_get_urb(struct urb *urb) * * If the USB subsystem can't reserve sufficient bandwidth to perform * the periodic request, and bandwidth reservation is being done for - * this controller, submitting such a periodic request will fail. + * this controller, submitting such a periodic request will fail. + * + * Memory Flags: + * + * General rules for how to decide which mem_flags to use: + * + * Basically the rules are the same as for kmalloc. There are four + * different possible values; GFP_KERNEL, GFP_NOFS, GFP_NOIO and + * GFP_ATOMIC. + * + * GFP_NOFS is not ever used, as it has not been implemented yet. + * + * There are three situations you must use GFP_ATOMIC. + * a) you are inside a completion handler, an interrupt, bottom half, + * tasklet or timer. + * b) you are holding a spinlock or rwlock (does not apply to + * semaphores) + * c) current->state != TASK_RUNNING, this is the case only after + * you've changed it. + * + * GFP_NOIO is used in the block io path and error handling of storage + * devices. + * + * All other situations use GFP_KERNEL. + * + * Specfic rules for how to decide which mem_flags to use: + * + * - start_xmit, timeout, and receive methods of network drivers must + * use GFP_ATOMIC (spinlock) + * - queuecommand methods of scsi drivers must use GFP_ATOMIC (spinlock) + * - If you use a kernel thread with a network driver you must use + * GFP_NOIO, unless b) or c) apply + * - After you have done a down() you use GFP_KERNEL, unless b) or c) + * apply or your are in a storage driver's block io path + * - probe and disconnect use GFP_KERNEL unless b) or c) apply + * - Changing firmware on a running storage or net device uses + * GFP_NOIO, unless b) or c) apply + * */ -int usb_submit_urb(struct urb *urb) +int usb_submit_urb(struct urb *urb, int mem_flags) { if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op) - return urb->dev->bus->op->submit_urb(urb); + return urb->dev->bus->op->submit_urb(urb, mem_flags); else return -ENODEV; } @@ -1272,7 +1310,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length) add_wait_queue(&awd.wqh, &wait); urb->context = &awd; - status = usb_submit_urb(urb); + status = usb_submit_urb(urb, GFP_KERNEL); if (status) { // something went wrong usb_free_urb(urb); diff --git a/drivers/usb/usbkbd.c b/drivers/usb/usbkbd.c index 9d57df368e35..156c7878efd0 100644 --- a/drivers/usb/usbkbd.c +++ b/drivers/usb/usbkbd.c @@ -129,7 +129,7 @@ int usb_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, i kbd->leds = kbd->newleds; kbd->led->dev = kbd->usbdev; - if (usb_submit_urb(kbd->led)) + if (usb_submit_urb(kbd->led, GFP_KERNEL)) err("usb_submit_urb(leds) failed"); return 0; @@ -147,7 +147,7 @@ static void usb_kbd_led(struct urb *urb) kbd->leds = kbd->newleds; kbd->led->dev = kbd->usbdev; - if (usb_submit_urb(kbd->led)) + if (usb_submit_urb(kbd->led, GFP_KERNEL)) err("usb_submit_urb(leds) failed"); } @@ -159,7 +159,7 @@ static int usb_kbd_open(struct input_dev *dev) return 0; kbd->irq->dev = kbd->usbdev; - if (usb_submit_urb(kbd->irq)) + if (usb_submit_urb(kbd->irq, GFP_KERNEL)) return -EIO; return 0; diff --git a/drivers/usb/usbmouse.c b/drivers/usb/usbmouse.c index db2e61f8290b..9a1994b79197 100644 --- a/drivers/usb/usbmouse.c +++ b/drivers/usb/usbmouse.c @@ -85,7 +85,7 @@ static int usb_mouse_open(struct input_dev *dev) return 0; mouse->irq->dev = mouse->usbdev; - if (usb_submit_urb(mouse->irq)) + if (usb_submit_urb(mouse->irq, GFP_KERNEL)) return -EIO; return 0; diff --git a/drivers/usb/usbnet.c b/drivers/usb/usbnet.c index 70bcf013f00c..772ca2f56df3 100644 --- a/drivers/usb/usbnet.c +++ b/drivers/usb/usbnet.c @@ -373,7 +373,7 @@ static int gl_interrupt_read (struct usbnet *dev) // issue usb interrupt read if (priv && priv->irq_urb) { // submit urb - if ((retval = usb_submit_urb (priv->irq_urb)) != 0) + if ((retval = usb_submit_urb (priv->irq_urb, GFP_KERNEL)) != 0) dbg ("gl_interrupt_read: submit fail - %X...", retval); else dbg ("gl_interrupt_read: submit success..."); @@ -1281,7 +1281,7 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, int flags) spin_lock_irqsave (&dev->rxq.lock, lockflags); if (netif_running (&dev->net)) { - if ((retval = usb_submit_urb (urb)) != 0) { + if ((retval = usb_submit_urb (urb, GFP_ATOMIC)) != 0) { dbg ("%s rx submit, %d", dev->net.name, retval); tasklet_schedule (&dev->bh); } else { @@ -1642,7 +1642,7 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) #endif /* CONFIG_USB_NET1080 */ netif_stop_queue (net); - if ((retval = usb_submit_urb (urb)) != 0) { + if ((retval = usb_submit_urb (urb, GFP_ATOMIC)) != 0) { netif_start_queue (net); dbg ("%s tx: submit urb err %d", net->name, retval); } else { diff --git a/drivers/usb/usbvideo.c b/drivers/usb/usbvideo.c index c5c30d3d1e8d..a7a5fc1052af 100644 --- a/drivers/usb/usbvideo.c +++ b/drivers/usb/usbvideo.c @@ -1916,7 +1916,7 @@ int usbvideo_StartDataPump(uvd_t *uvd) /* Submit all URBs */ for (i=0; i < USBVIDEO_NUMSBUF; i++) { - errFlag = usb_submit_urb(uvd->sbuf[i].urb); + errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL); if (errFlag) err("%s: usb_submit_isoc(%d) ret %d", proc, i, errFlag); } diff --git a/drivers/usb/vicam.c b/drivers/usb/vicam.c index d7dc679d5461..ef02499ae99d 100644 --- a/drivers/usb/vicam.c +++ b/drivers/usb/vicam.c @@ -350,7 +350,7 @@ static void params_changed(struct usb_vicam *vicam) synchronize(vicam); mdelay(10); vicam_parameters(vicam); - printk("Submiting urb: %d\n", usb_submit_urb(vicam->readurb)); + printk(KERN_DEBUG "Submiting urb: %d\n", usb_submit_urb(vicam->readurb, GFP_KERNEL)); #endif } @@ -765,7 +765,7 @@ static void vicam_bulk(struct urb *urb) memcpy(vicam->fbuf, buf+64, 0x1e480); if (!change_pending) { - if (usb_submit_urb(urb)) + if (usb_submit_urb(urb, GFP_ATOMIC)) dbg("failed resubmitting read urb"); } else { change_pending = 0; @@ -849,7 +849,7 @@ static int vicam_init(struct usb_vicam *vicam) FILL_BULK_URB(vicam->readurb, vicam->udev, usb_rcvbulkpipe(vicam->udev, 0x81), buf, 0x1e480, vicam_bulk, vicam); - printk("Submiting urb: %d\n", usb_submit_urb(vicam->readurb)); + printk(KERN_DEBUG "Submiting urb: %d\n", usb_submit_urb(vicam->readurb, GFP_KERNEL)); return 0; error: diff --git a/drivers/usb/wacom.c b/drivers/usb/wacom.c index 9f3433a8aa64..638804196ff5 100644 --- a/drivers/usb/wacom.c +++ b/drivers/usb/wacom.c @@ -336,7 +336,7 @@ static int wacom_open(struct input_dev *dev) return 0; wacom->irq->dev = wacom->usbdev; - if (usb_submit_urb(wacom->irq)) + if (usb_submit_urb(wacom->irq, GFP_KERNEL)) return -EIO; return 0; diff --git a/drivers/zorro/proc.c b/drivers/zorro/proc.c index 28b7c4272dd8..07a3ae80edd9 100644 --- a/drivers/zorro/proc.c +++ b/drivers/zorro/proc.c @@ -14,6 +14,7 @@ #include <linux/zorro.h> #include <linux/proc_fs.h> #include <linux/init.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/amigahw.h> #include <asm/setup.h> @@ -21,7 +22,7 @@ static loff_t proc_bus_zorro_lseek(struct file *file, loff_t off, int whence) { - loff_t new; + loff_t new = -1; switch (whence) { case 0: @@ -33,11 +34,12 @@ proc_bus_zorro_lseek(struct file *file, loff_t off, int whence) case 2: new = sizeof(struct ConfigDev) + off; break; - default: - return -EINVAL; } - if (new < 0 || new > sizeof(struct ConfigDev)) + if (new < 0 || new > sizeof(struct ConfigDev)) { + unlock_kernel(); return -EINVAL; + } + unlock_kernel(); return (file->f_pos = new); } @@ -45,7 +47,7 @@ static ssize_t proc_bus_zorro_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) { struct inode *ino = file->f_dentry->d_inode; - struct proc_dir_entry *dp = ino->u.generic_ip; + struct proc_dir_entry *dp = PDE(ino); struct zorro_dev *dev = dp->data; struct ConfigDev cd; int pos = *ppos; diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h index 6d6a334b3717..354af8325576 100644 --- a/fs/autofs/autofs_i.h +++ b/fs/autofs/autofs_i.h @@ -145,7 +145,7 @@ extern struct file_operations autofs_dir_operations; /* Initializing function */ -struct super_block *autofs_read_super(struct super_block *, void *,int); +int autofs_fill_super(struct super_block *, void *, int); /* Queue management functions */ diff --git a/fs/autofs/init.c b/fs/autofs/init.c index 0e7fff94f254..b73fec09f7c2 100644 --- a/fs/autofs/init.c +++ b/fs/autofs/init.c @@ -14,7 +14,17 @@ #include <linux/init.h> #include "autofs_i.h" -static DECLARE_FSTYPE(autofs_fs_type, "autofs", autofs_read_super, 0); +static struct super_block *autofs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_nodev(fs_type, flags, data, autofs_fill_super); +} + +static struct file_system_type autofs_fs_type = { + owner: THIS_MODULE, + name: "autofs", + get_sb: autofs_get_sb, +}; static int __init init_autofs_fs(void) { diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c index d275c5f81e57..8a0f463dfaf6 100644 --- a/fs/autofs/inode.c +++ b/fs/autofs/inode.c @@ -111,8 +111,7 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, pid return (*pipefd < 0); } -struct super_block *autofs_read_super(struct super_block *s, void *data, - int silent) +int autofs_fill_super(struct super_block *s, void *data, int silent) { struct inode * root_inode; struct dentry * root; @@ -175,7 +174,7 @@ struct super_block *autofs_read_super(struct super_block *s, void *data, * Success! Install the root dentry now to indicate completion. */ s->s_root = root; - return s; + return 0; fail_fput: printk("autofs: pipe file descriptor does not contain proper ops\n"); @@ -189,7 +188,7 @@ fail_iput: fail_free: kfree(sbi); fail_unlock: - return NULL; + return -EINVAL; } static int autofs_statfs(struct super_block *sb, struct statfs *buf) diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index 4dcdcaafcca9..7e43620bca87 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h @@ -144,7 +144,7 @@ extern struct file_operations autofs4_root_operations; /* Initializing function */ -struct super_block *autofs4_read_super(struct super_block *, void *,int); +int autofs4_fill_super(struct super_block *, void *, int); struct autofs_info *autofs4_init_ino(struct autofs_info *, struct autofs_sb_info *sbi, mode_t mode); /* Queue management functions */ diff --git a/fs/autofs4/init.c b/fs/autofs4/init.c index dbb3e5385ded..fdce6b04367c 100644 --- a/fs/autofs4/init.c +++ b/fs/autofs4/init.c @@ -14,7 +14,17 @@ #include <linux/init.h> #include "autofs_i.h" -static DECLARE_FSTYPE(autofs_fs_type, "autofs", autofs4_read_super, 0); +static struct super_block *autofs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_nodev(fs_type, flags, data, autofs4_fill_super); +} + +static struct file_system_type autofs_fs_type = { + owner: THIS_MODULE, + name: "autofs", + get_sb: autofs_get_sb, +}; static int __init init_autofs4_fs(void) { diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index 1f2d29f6d0cd..a7331fd67fa9 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c @@ -173,8 +173,7 @@ static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi) return ino; } -struct super_block *autofs4_read_super(struct super_block *s, void *data, - int silent) +int autofs4_fill_super(struct super_block *s, void *data, int silent) { struct inode * root_inode; struct dentry * root; @@ -251,7 +250,7 @@ struct super_block *autofs4_read_super(struct super_block *s, void *data, * Success! Install the root dentry now to indicate completion. */ s->s_root = root; - return s; + return 0; /* * Failure ... clean up. @@ -278,7 +277,7 @@ fail_iput: fail_free: kfree(sbi); fail_unlock: - return NULL; + return -EINVAL; } static int autofs4_statfs(struct super_block *sb, struct statfs *buf) diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index dcbc3a688ae7..7f371ea86066 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -656,7 +656,7 @@ static struct super_operations s_ops = { clear_inode: bm_clear_inode, }; -static struct super_block *bm_read_super(struct super_block * sb, void * data, int silent) +static int bm_fill_super(struct super_block * sb, void * data, int silent) { struct qstr names[2] = {{name:"status"}, {name:"register"}}; struct inode * inode; @@ -675,13 +675,13 @@ static struct super_block *bm_read_super(struct super_block * sb, void * data, i inode = bm_get_inode(sb, S_IFDIR | 0755); if (!inode) - return NULL; + return -ENOMEM; inode->i_op = &bm_dir_inode_operations; inode->i_fop = &bm_dir_operations; dentry[0] = d_alloc_root(inode); if (!dentry[0]) { iput(inode); - return NULL; + return -ENOMEM; } dentry[1] = d_alloc(dentry[0], &names[0]); if (!dentry[1]) @@ -701,7 +701,7 @@ static struct super_block *bm_read_super(struct super_block * sb, void * data, i d_add(dentry[2], inode); sb->s_root = dentry[0]; - return sb; + return 0; out3: dput(dentry[2]); @@ -709,14 +709,26 @@ out2: dput(dentry[1]); out1: dput(dentry[0]); - return NULL; + return -ENOMEM; +} + +static struct super_block *bm_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_single(fs_type, flags, data, bm_fill_super); } static struct linux_binfmt misc_format = { - NULL, THIS_MODULE, load_misc_binary, NULL, NULL, 0 + module: THIS_MODULE, + load_binary: load_misc_binary, }; -static DECLARE_FSTYPE(bm_fs_type, "binfmt_misc", bm_read_super, FS_SINGLE|FS_LITTER); +static struct file_system_type bm_fs_type = { + owner: THIS_MODULE, + name: "binfmt_misc", + get_sb: bm_get_sb, + fs_flags: FS_LITTER, +}; static int __init init_misc_binfmt(void) { @@ -33,20 +33,24 @@ static kmem_cache_t *bio_slab; struct biovec_pool { int size; + char *name; kmem_cache_t *slab; mempool_t *pool; }; -static struct biovec_pool bvec_array[BIOVEC_NR_POOLS]; - /* * if you change this list, also change bvec_alloc or things will * break badly! cannot be bigger than what you can fit into an * unsigned short */ -static const int bvec_pool_sizes[BIOVEC_NR_POOLS] = { 1, 4, 16, 64, 128, 256 }; -#define BIO_MAX_PAGES (bvec_pool_sizes[BIOVEC_NR_POOLS - 1]) +#define BV(x) { x, "biovec-" #x } +static struct biovec_pool bvec_array[BIOVEC_NR_POOLS] = { + BV(1), BV(4), BV(16), BV(64), BV(128), BV(256) +}; +#undef BV + +#define BIO_MAX_PAGES (bvec_array[BIOVEC_NR_POOLS - 1].size) static void *slab_pool_alloc(int gfp_mask, void *data) { @@ -64,7 +68,7 @@ static inline struct bio_vec *bvec_alloc(int gfp_mask, int nr, int *idx) struct bio_vec *bvl; /* - * see comment near bvec_pool_sizes define! + * see comment near bvec_array define! */ switch (nr) { case 1 : *idx = 0; break; @@ -452,21 +456,17 @@ int bio_endio(struct bio *bio, int uptodate, int nr_sectors) static void __init biovec_init_pool(void) { - char name[16]; int i, size; - memset(&bvec_array, 0, sizeof(bvec_array)); - for (i = 0; i < BIOVEC_NR_POOLS; i++) { struct biovec_pool *bp = bvec_array + i; - size = bvec_pool_sizes[i] * sizeof(struct bio_vec); + size = bp->size * sizeof(struct bio_vec); printk("biovec: init pool %d, %d entries, %d bytes\n", i, - bvec_pool_sizes[i], size); + bp->size, size); - snprintf(name, sizeof(name) - 1,"biovec-%d",bvec_pool_sizes[i]); - bp->slab = kmem_cache_create(name, size, 0, + bp->slab = kmem_cache_create(bp->name, size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if (!bp->slab) panic("biovec: can't init slab cache\n"); @@ -474,7 +474,7 @@ static void __init biovec_init_pool(void) slab_pool_free, bp->slab); if (!bp->pool) panic("biovec: can't init mempool\n"); - bp->size = size; + bp->size = size; } } diff --git a/fs/block_dev.c b/fs/block_dev.c index ef9fb9f89aa2..5bdffee5760e 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -220,7 +220,7 @@ static int block_fsync(struct file *filp, struct dentry *dentry, int datasync) * pseudo-fs */ -static struct super_block *bd_read_super(struct super_block *sb, void *data, int silent) +static int bd_fill_super(struct super_block *sb, void *data, int silent) { static struct super_operations sops = {}; struct inode *root; @@ -232,22 +232,32 @@ static struct super_block *bd_read_super(struct super_block *sb, void *data, int sb->s_op = &sops; root = new_inode(sb); if (!root) - return NULL; + return -ENOMEM; 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_root = d_alloc(NULL, &(const struct qstr) { "bdev:", 5, 0 }); if (!sb->s_root) { iput(root); - return NULL; + return -ENOMEM; } sb->s_root->d_sb = sb; sb->s_root->d_parent = sb->s_root; d_instantiate(sb->s_root, root); - return sb; + return 0; } -static DECLARE_FSTYPE(bd_type, "bdev", bd_read_super, FS_NOMOUNT); +static struct super_block *bd_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_nodev(fs_type, flags, data, bd_fill_super); +} + +static struct file_system_type bd_type = { + name: "bdev", + get_sb: bd_get_sb, + fs_flags: FS_NOMOUNT, +}; static struct vfsmount *bd_mnt; diff --git a/fs/dcache.c b/fs/dcache.c index 7246506fff37..a421788191fb 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1283,6 +1283,7 @@ void __init vfs_caches_init(unsigned long mempages) dcache_init(mempages); inode_init(mempages); + files_init(mempages); mnt_init(mempages); bdev_cache_init(); cdev_cache_init(); diff --git a/fs/devfs/base.c b/fs/devfs/base.c index 89a698a63ea6..6372557356d9 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c @@ -3218,8 +3218,7 @@ static struct inode_operations devfs_symlink_iops = setattr: devfs_notify_change, }; -static struct super_block *devfs_read_super (struct super_block *sb, - void *data, int silent) +static int devfs_fill_super (struct super_block *sb, void *data, int silent) { struct inode *root_inode = NULL; @@ -3238,17 +3237,24 @@ static struct super_block *devfs_read_super (struct super_block *sb, sb->s_root = d_alloc_root (root_inode); if (!sb->s_root) goto out_no_root; DPRINTK (DEBUG_S_READ, "(): made devfs ptr: %p\n", sb->u.generic_sbp); - return sb; + return 0; out_no_root: PRINTK ("(): get root inode failed\n"); if (root_inode) iput (root_inode); - return NULL; + return -EINVAL; } /* End Function devfs_read_super */ +static struct super_block *devfs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_single(fs_type, flags, data, devfs_fill_super); +} -static DECLARE_FSTYPE (devfs_fs_type, DEVFS_NAME, devfs_read_super, FS_SINGLE); - +static struct file_system_type devfs_fs_type = { + name: DEVFS_NAME, + get_sb: devfs_get_sb, +}; /* File operations for devfsd follow */ diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 393ca3ececc6..1816bd4137c7 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -118,9 +118,9 @@ static int devpts_remount(struct super_block * sb, int * flags, char * data) return 0; } -struct super_block *devpts_read_super(struct super_block *s, void *data, - int silent) +static int devpts_fill_super(struct super_block *s, void *data, int silent) { + int error = -ENOMEM; struct inode * inode; struct devpts_sb_info *sbi; @@ -136,6 +136,7 @@ struct super_block *devpts_read_super(struct super_block *s, void *data, memset(sbi->inodes, 0, sizeof(struct inode *) * sbi->max_ptys); if ( devpts_parse_options(data,sbi) && !silent) { + error = -EINVAL; printk("devpts: called with bogus options\n"); goto fail_free; } @@ -160,14 +161,14 @@ struct super_block *devpts_read_super(struct super_block *s, void *data, s->s_root = d_alloc_root(inode); if (s->s_root) - return s; + return 0; printk("devpts: get root dentry failed\n"); iput(inode); fail_free: kfree(sbi); fail: - return NULL; + return error; } static int devpts_statfs(struct super_block *sb, struct statfs *buf) @@ -178,7 +179,17 @@ static int devpts_statfs(struct super_block *sb, struct statfs *buf) return 0; } -static DECLARE_FSTYPE(devpts_fs_type, "devpts", devpts_read_super, FS_SINGLE); +static struct super_block *devpts_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_single(fs_type, flags, data, devpts_fill_super); +} + +static struct file_system_type devpts_fs_type = { + owner: THIS_MODULE, + name: "devpts", + get_sb: devpts_get_sb, +}; void devpts_pty_new(int number, kdev_t device) { diff --git a/fs/driverfs/inode.c b/fs/driverfs/inode.c index 802d5f8597f9..54e35bce866d 100644 --- a/fs/driverfs/inode.c +++ b/fs/driverfs/inode.c @@ -32,6 +32,7 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/device.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> @@ -341,6 +342,7 @@ driverfs_file_lseek(struct file *file, loff_t offset, int orig) { loff_t retval = -EINVAL; + lock_kernel(); switch(orig) { case 0: if (offset > 0) { @@ -357,6 +359,7 @@ driverfs_file_lseek(struct file *file, loff_t offset, int orig) default: break; } + unlock_kernel(); return retval; } @@ -446,8 +449,7 @@ static struct super_operations driverfs_ops = { put_inode: force_delete, }; -static struct super_block* -driverfs_read_super(struct super_block *sb, void *data, int silent) +static int driverfs_fill_super(struct super_block *sb, void *data, int silent) { struct inode *inode; struct dentry *root; @@ -460,20 +462,31 @@ driverfs_read_super(struct super_block *sb, void *data, int silent) if (!inode) { DBG("%s: could not get inode!\n",__FUNCTION__); - return NULL; + return -ENOMEM; } root = d_alloc_root(inode); if (!root) { DBG("%s: could not get root dentry!\n",__FUNCTION__); iput(inode); - return NULL; + return -ENOMEM; } sb->s_root = root; - return sb; + return 0; } -static DECLARE_FSTYPE(driverfs_fs_type, "driverfs", driverfs_read_super, FS_SINGLE | FS_LITTER); +static struct super_block *driverfs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_single(fs_type, flags, data, driverfs_fill_super); +} + +static struct file_system_type driverfs_fs_type = { + owner: THIS_MODULE, + name: "driverfs", + get_sb: driverfs_get_sb, + fs_flags: FS_LITTER, +}; static int get_mount(void) { diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 09d13d60ef31..b6ffc9337824 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h @@ -96,7 +96,6 @@ extern void ext2_update_dynamic_rev (struct super_block *sb); extern void ext2_put_super (struct super_block *); extern void ext2_write_super (struct super_block *); extern int ext2_remount (struct super_block *, int *, char *); -extern struct super_block * ext2_read_super (struct super_block *,void *,int); extern int ext2_statfs (struct super_block *, struct statfs *); /* diff --git a/fs/ext2/super.c b/fs/ext2/super.c index bb14991cf85f..d46639635c61 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -441,8 +441,7 @@ static loff_t ext2_max_size(int bits) return res; } -struct super_block * ext2_read_super (struct super_block * sb, void * data, - int silent) +static int ext2_fill_super(struct super_block *sb, void *data, int silent) { struct buffer_head * bh; struct ext2_super_block * es; @@ -465,14 +464,13 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, sb->u.ext2_sb.s_mount_opt = 0; if (!parse_options ((char *) data, &sb_block, &resuid, &resgid, - &sb->u.ext2_sb.s_mount_opt)) { - return NULL; - } + &sb->u.ext2_sb.s_mount_opt)) + return -EINVAL; blocksize = sb_min_blocksize(sb, BLOCK_SIZE); if (!blocksize) { printk ("EXT2-fs: unable to set blocksize\n"); - return NULL; + return -EINVAL; } /* @@ -487,7 +485,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, if (!(bh = sb_bread(sb, logic_sb_block))) { printk ("EXT2-fs: unable to read superblock\n"); - return NULL; + return -EINVAL; } /* * Note: s_es must be initialized as soon as possible because @@ -533,7 +531,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, if (!sb_set_blocksize(sb, blocksize)) { printk(KERN_ERR "EXT2-fs: blocksize too small for device.\n"); - return NULL; + return -EINVAL; } logic_sb_block = (sb_block*BLOCK_SIZE) / blocksize; @@ -684,14 +682,14 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, goto failed_mount2; } ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY); - return sb; + return 0; failed_mount2: for (i = 0; i < db_count; i++) brelse(sb->u.ext2_sb.s_group_desc[i]); kfree(sb->u.ext2_sb.s_group_desc); failed_mount: brelse(bh); - return NULL; + return -EINVAL; } static void ext2_commit_super (struct super_block * sb, @@ -843,7 +841,18 @@ int ext2_statfs (struct super_block * sb, struct statfs * buf) return 0; } -static DECLARE_FSTYPE_DEV(ext2_fs_type, "ext2", ext2_read_super); +static struct super_block *ext2_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super); +} + +static struct file_system_type ext2_fs_type = { + owner: THIS_MODULE, + name: "ext2", + get_sb: ext2_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_ext2_fs(void) { diff --git a/fs/fat/fatfs_syms.c b/fs/fat/fatfs_syms.c index 1ebb2731f60f..8b7152af25ae 100644 --- a/fs/fat/fatfs_syms.c +++ b/fs/fat/fatfs_syms.c @@ -47,5 +47,10 @@ static int __init init_fat_fs(void) return fat_init_inodecache(); } +static void __exit exit_fat_fs(void) +{ + fat_destroy_inodecache(); +} + module_init(init_fat_fs) -module_exit(fat_destroy_inodecache) +module_exit(exit_fat_fs) diff --git a/fs/file_table.c b/fs/file_table.c index 27713eb016fc..e7248739e3d4 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -186,3 +186,17 @@ too_bad: file_list_unlock(); return 0; } + +void __init files_init(unsigned long mempages) +{ + int n; + /* One file with associated inode and dcache is very roughly 1K. + * Per default don't use more than 10% of our memory for files. + */ + + n = (mempages * (PAGE_SIZE / 1024)) / 10; + files_stat.max_files = n; + if (files_stat.max_files < NR_FILE) + files_stat.max_files = NR_FILE; +} + diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c index 3bcdaae4e024..a82753c462d9 100644 --- a/fs/hfs/catalog.c +++ b/fs/hfs/catalog.c @@ -1346,13 +1346,6 @@ int hfs_cat_move(struct hfs_cat_entry *old_dir, struct hfs_cat_entry *new_dir, return -EINVAL; } - while (mdb->rename_lock) { - hfs_sleep_on(&mdb->rename_wait); - } - spin_lock(&entry_lock); - mdb->rename_lock = 1; /* XXX: should be atomic_inc */ - spin_unlock(&entry_lock); - /* keep readers from getting confused by changing dir size */ start_write(new_dir); if (old_dir != new_dir) { @@ -1567,11 +1560,6 @@ done: end_write(old_dir); } end_write(new_dir); - spin_lock(&entry_lock); - mdb->rename_lock = 0; /* XXX: should use atomic_dec */ - hfs_wake_up(&mdb->rename_wait); - spin_unlock(&entry_lock); - return error; } diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c index 5df23375add4..4b7d36f5f2fb 100644 --- a/fs/hfs/extent.c +++ b/fs/hfs/extent.c @@ -48,10 +48,7 @@ static inline void build_key(struct hfs_ext_key *key, * Get an exclusive lock on the B-tree bitmap. */ static inline void lock_bitmap(struct hfs_mdb *mdb) { - while (mdb->bitmap_lock) { - hfs_sleep_on(&mdb->bitmap_wait); - } - mdb->bitmap_lock = 1; + down(&mdb->bitmap_sem); } /* @@ -60,8 +57,7 @@ static inline void lock_bitmap(struct hfs_mdb *mdb) { * Relinquish an exclusive lock on the B-tree bitmap. */ static inline void unlock_bitmap(struct hfs_mdb *mdb) { - mdb->bitmap_lock = 0; - hfs_wake_up(&mdb->bitmap_wait); + up(&mdb->bitmap_sem); } /* diff --git a/fs/hfs/file_cap.c b/fs/hfs/file_cap.c index 494d43249c44..7a02ebaa6154 100644 --- a/fs/hfs/file_cap.c +++ b/fs/hfs/file_cap.c @@ -24,6 +24,7 @@ #include <linux/hfs_fs_sb.h> #include <linux/hfs_fs_i.h> #include <linux/hfs_fs.h> +#include <linux/smp_lock.h> /*================ Forward declarations ================*/ static loff_t cap_info_llseek(struct file *, loff_t, diff --git a/fs/hfs/file_hdr.c b/fs/hfs/file_hdr.c index 2ac3182437a7..8dad9e76d20b 100644 --- a/fs/hfs/file_hdr.c +++ b/fs/hfs/file_hdr.c @@ -29,6 +29,7 @@ #include <linux/hfs_fs_sb.h> #include <linux/hfs_fs_i.h> #include <linux/hfs_fs.h> +#include <linux/smp_lock.h> /* prodos types */ #define PRODOSI_FTYPE_DIR 0x0F diff --git a/fs/hfs/hfs.h b/fs/hfs/hfs.h index e328a14aeed7..ad9f70d74294 100644 --- a/fs/hfs/hfs.h +++ b/fs/hfs/hfs.h @@ -271,10 +271,7 @@ struct hfs_mdb { 512-byte blocks per "allocation block" */ hfs_u16 attrib; /* Attribute word */ - hfs_wait_queue rename_wait; - int rename_lock; - hfs_wait_queue bitmap_wait; - int bitmap_lock; + struct semaphore bitmap_sem; struct list_head entry_dirty; }; diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c index d907a632dad9..b3f8477f58cb 100644 --- a/fs/hfs/mdb.c +++ b/fs/hfs/mdb.c @@ -100,8 +100,7 @@ struct hfs_mdb *hfs_mdb_get(hfs_sysmdb sys_mdb, int readonly, mdb->magic = HFS_MDB_MAGIC; mdb->sys_mdb = sys_mdb; INIT_LIST_HEAD(&mdb->entry_dirty); - hfs_init_waitqueue(&mdb->rename_wait); - hfs_init_waitqueue(&mdb->bitmap_wait); + init_MUTEX(&mdb->bitmap_sem); /* See if this is an HFS filesystem */ buf = hfs_buffer_get(sys_mdb, part_start + HFS_MDB_BLK, 1); diff --git a/fs/hpfs/buffer.c b/fs/hpfs/buffer.c index 0049e5ee48fa..94b663656ac4 100644 --- a/fs/hpfs/buffer.c +++ b/fs/hpfs/buffer.c @@ -14,8 +14,7 @@ void hpfs_lock_creation(struct super_block *s) #ifdef DEBUG_LOCKS printk("lock creation\n"); #endif - while (s->s_hpfs_creation_de_lock) sleep_on(&s->s_hpfs_creation_de); - s->s_hpfs_creation_de_lock = 1; + down(&s->u.hpfs_sb.hpfs_creation_de); } void hpfs_unlock_creation(struct super_block *s) @@ -23,8 +22,7 @@ void hpfs_unlock_creation(struct super_block *s) #ifdef DEBUG_LOCKS printk("unlock creation\n"); #endif - s->s_hpfs_creation_de_lock = 0; - wake_up(&s->s_hpfs_creation_de); + up(&s->u.hpfs_sb.hpfs_creation_de); } void hpfs_lock_iget(struct super_block *s, int mode) diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index 2483e920b597..3d59f27c82b8 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c @@ -427,8 +427,8 @@ struct super_block *hpfs_read_super(struct super_block *s, void *options, s->s_hpfs_bmp_dir = NULL; s->s_hpfs_cp_table = NULL; - s->s_hpfs_creation_de_lock = s->s_hpfs_rd_inode = 0; - init_waitqueue_head(&s->s_hpfs_creation_de); + s->s_hpfs_rd_inode = 0; + init_MUTEX(&s->u.hpfs_sb.hpfs_creation_de); init_waitqueue_head(&s->s_hpfs_iget_q); uid = current->uid; diff --git a/fs/namespace.c b/fs/namespace.c index fdcc369fbe38..1419b179c74c 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1048,15 +1048,9 @@ void __init mnt_init(unsigned long mempages) if (!mnt_cache) panic("Cannot create vfsmount cache"); - mempages >>= (16 - PAGE_SHIFT); - mempages *= sizeof(struct list_head); - for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++) - ; - - do { - mount_hashtable = (struct list_head *) - __get_free_pages(GFP_ATOMIC, order); - } while (mount_hashtable == NULL && --order >= 0); + order = 0; + mount_hashtable = (struct list_head *) + __get_free_pages(GFP_ATOMIC, order); if (!mount_hashtable) panic("Failed to allocate mount hash table\n"); diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index 1f70ec451ce7..bc7b38e5530c 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c @@ -18,6 +18,7 @@ #include <linux/locks.h> #include <linux/slab.h> #include <linux/vmalloc.h> +#include <linux/smp_lock.h> #include <linux/ncp_fs.h> #include "ncplib_kernel.h" @@ -281,7 +282,7 @@ static int ncp_release(struct inode *inode, struct file *file) { struct file_operations ncp_file_operations = { - llseek: generic_file_llseek, + llseek: remote_llseek, read: ncp_file_read, write: ncp_file_write, ioctl: ncp_ioctl, diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 32e089bd5ec0..e4ed0426d766 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -365,7 +365,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent) sock_inode = ncp_filp->f_dentry->d_inode; if (!S_ISSOCK(sock_inode->i_mode)) goto out_bad_file2; - sock = &sock_inode->u.socket_i; + sock = SOCKET_I(sock_inode); if (!sock) goto out_bad_file2; diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c index 470ea5e96ae3..095498a2b5b8 100644 --- a/fs/ncpfs/sock.c +++ b/fs/ncpfs/sock.c @@ -101,7 +101,7 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size, struct ncp_reply_header reply; file = server->ncp_filp; - sock = &file->f_dentry->d_inode->u.socket_i; + sock = SOCKET_I(file->f_dentry->d_inode); init_timeout = server->m.time_out; max_timeout = NCP_MAX_RPC_TIMEOUT; @@ -269,7 +269,7 @@ static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len) { int result = 0; file = server->ncp_filp; - sock = &file->f_dentry->d_inode->u.socket_i; + sock = SOCKET_I(file->f_dentry->d_inode); dataread = 0; @@ -348,7 +348,7 @@ static int do_ncp_tcp_rpc_call(struct ncp_server *server, int size, *((struct ncp_request_header *) (server->packet)); file = server->ncp_filp; - sock = &file->f_dentry->d_inode->u.socket_i; + sock = SOCKET_I(file->f_dentry->d_inode); ncptcp_xmit_hdr[0] = htonl(NCP_TCP_XMIT_MAGIC); ncptcp_xmit_hdr[1] = htonl(size + 16); @@ -444,7 +444,7 @@ static int ncp_do_request(struct ncp_server *server, int size, } #endif /* CONFIG_NCPFS_PACKET_SIGNING */ file = server->ncp_filp; - sock = &file->f_dentry->d_inode->u.socket_i; + sock = SOCKET_I(file->f_dentry->d_inode); /* N.B. this isn't needed ... check socket type? */ if (!sock) { printk(KERN_ERR "ncp_rpc_call: socki_lookup failed\n"); diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 1d5e7dbde28a..d25cb4968931 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -41,7 +41,7 @@ static int nfs_file_flush(struct file *); static int nfs_fsync(struct file *, struct dentry *dentry, int datasync); struct file_operations nfs_file_operations = { - llseek: generic_file_llseek, + llseek: remote_llseek, read: nfs_file_read, write: nfs_file_write, mmap: nfs_file_mmap, diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 261cadb58635..28d57bf19bad 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -245,8 +245,7 @@ nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh) * and the root file handle obtained from the server's mount * daemon. We stash these away in the private superblock fields. */ -struct super_block * -nfs_read_super(struct super_block *sb, void *raw_data, int silent) +int nfs_fill_super(struct super_block *sb, void *raw_data, int silent) { struct nfs_mount_data *data = (struct nfs_mount_data *) raw_data; struct nfs_server *server; @@ -455,6 +454,8 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent) server->namelen = maxlen; sb->s_maxbytes = fsinfo.maxfilesize; + if (sb->s_maxbytes > MAX_LFS_FILESIZE) + sb->s_maxbytes = MAX_LFS_FILESIZE; /* Fire up the writeback cache */ if (nfs_reqlist_alloc(server) < 0) { @@ -467,7 +468,7 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent) /* Check whether to start the lockd process */ if (!(server->flags & NFS_MOUNT_NONLM)) lockd_up(); - return sb; + return 0; /* Yargs. It didn't work out. */ failure_kill_reqlist: @@ -506,7 +507,7 @@ out_miss_args: printk("nfs_read_super: missing data argument\n"); out_fail: - return NULL; + return -EINVAL; } static int @@ -1137,7 +1138,25 @@ __nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) /* * File system information */ -static DECLARE_FSTYPE(nfs_fs_type, "nfs", nfs_read_super, FS_ODD_RENAME); + +/* + * Right now we are using get_sb_nodev, but we ought to switch to + * get_anon_super() with appropriate comparison function. The only + * question being, when two NFS mounts are the same? Identical IP + * of server + identical root fhandle? Trond? + */ +static struct super_block *nfs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_nodev(fs_type, flags, data, nfs_fill_super); +} + +static struct file_system_type nfs_fs_type = { + owner: THIS_MODULE, + name: "nfs", + get_sb: nfs_get_sb, + fs_flags: FS_ODD_RENAME, +}; extern int nfs_init_nfspagecache(void); extern void nfs_destroy_nfspagecache(void); diff --git a/fs/ntfs/fs.c b/fs/ntfs/fs.c index 4fa8e2f018e4..d28ea94084a9 100644 --- a/fs/ntfs/fs.c +++ b/fs/ntfs/fs.c @@ -1130,7 +1130,7 @@ struct super_block *ntfs_read_super(struct super_block *sb, void *options, /* Inform the kernel about which super operations are available. */ sb->s_op = &ntfs_super_operations; sb->s_magic = NTFS_SUPER_MAGIC; - sb->s_maxbytes = ~0ULL >> 1; + sb->s_maxbytes = MAX_LFS_FILESIZE; ntfs_debug(DEBUG_OTHER, "Reading special files\n"); if (ntfs_load_special_files(vol)) { ntfs_error("Error loading special files\n"); diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c index 61c8b2b73111..fb86cd505779 100644 --- a/fs/openpromfs/inode.c +++ b/fs/openpromfs/inode.c @@ -998,8 +998,7 @@ static struct super_operations openprom_sops = { statfs: openprom_statfs, }; -struct super_block *openprom_read_super(struct super_block *s,void *data, - int silent) +static int openprom_fill_super(struct super_block *s, void *data, int silent) { struct inode * root_inode; @@ -1013,15 +1012,25 @@ struct super_block *openprom_read_super(struct super_block *s,void *data, s->s_root = d_alloc_root(root_inode); if (!s->s_root) goto out_no_root; - return s; + return 0; out_no_root: - printk("openprom_read_super: get root inode failed\n"); + printk("openprom_fill_super: get root inode failed\n"); iput(root_inode); - return NULL; + return -ENOMEM; +} + +static struct super_block *openprom_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_single(fs_type, flags, data, openprom_fill_super); } -static DECLARE_FSTYPE(openprom_fs_type, "openpromfs", openprom_read_super, 0); +static struct file_system_type openprom_fs_type = { + owner: THIS_MODULE, + name: "openpromfs", + get_sb: openprom_get_sb, +}; static int __init init_openprom_fs(void) { diff --git a/fs/pipe.c b/fs/pipe.c index 5910c168288f..90734730ca62 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -246,12 +246,6 @@ sigpipe: return -EPIPE; } -static loff_t -pipe_lseek(struct file *file, loff_t offset, int orig) -{ - return -ESPIPE; -} - static ssize_t bad_pipe_r(struct file *filp, char *buf, size_t count, loff_t *ppos) { @@ -381,7 +375,7 @@ pipe_rdwr_open(struct inode *inode, struct file *filp) * are also used in linux/fs/fifo.c to do operations on FIFOs. */ struct file_operations read_fifo_fops = { - llseek: pipe_lseek, + llseek: no_llseek, read: pipe_read, write: bad_pipe_w, poll: fifo_poll, @@ -391,7 +385,7 @@ struct file_operations read_fifo_fops = { }; struct file_operations write_fifo_fops = { - llseek: pipe_lseek, + llseek: no_llseek, read: bad_pipe_r, write: pipe_write, poll: fifo_poll, @@ -401,7 +395,7 @@ struct file_operations write_fifo_fops = { }; struct file_operations rdwr_fifo_fops = { - llseek: pipe_lseek, + llseek: no_llseek, read: pipe_read, write: pipe_write, poll: fifo_poll, @@ -411,7 +405,7 @@ struct file_operations rdwr_fifo_fops = { }; struct file_operations read_pipe_fops = { - llseek: pipe_lseek, + llseek: no_llseek, read: pipe_read, write: bad_pipe_w, poll: pipe_poll, @@ -421,7 +415,7 @@ struct file_operations read_pipe_fops = { }; struct file_operations write_pipe_fops = { - llseek: pipe_lseek, + llseek: no_llseek, read: bad_pipe_r, write: pipe_write, poll: pipe_poll, @@ -431,7 +425,7 @@ struct file_operations write_pipe_fops = { }; struct file_operations rdwr_pipe_fops = { - llseek: pipe_lseek, + llseek: no_llseek, read: pipe_read, write: pipe_write, poll: pipe_poll, @@ -606,7 +600,7 @@ static struct super_operations pipefs_ops = { statfs: pipefs_statfs, }; -static struct super_block * pipefs_read_super(struct super_block *sb, void *data, int silent) +static int pipefs_fill_super(struct super_block *sb, void *data, int silent) { struct inode *root; @@ -616,22 +610,32 @@ static struct super_block * pipefs_read_super(struct super_block *sb, void *data sb->s_op = &pipefs_ops; root = new_inode(sb); if (!root) - return NULL; + return -ENOMEM; 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_root = d_alloc(NULL, &(const struct qstr) { "pipe:", 5, 0 }); if (!sb->s_root) { iput(root); - return NULL; + return -ENOMEM; } sb->s_root->d_sb = sb; sb->s_root->d_parent = sb->s_root; d_instantiate(sb->s_root, root); - return sb; + return 0; } -static DECLARE_FSTYPE(pipe_fs_type, "pipefs", pipefs_read_super, FS_NOMOUNT); +static struct super_block *pipefs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_nodev(fs_type, flags, data, pipefs_fill_super); +} + +static struct file_system_type pipe_fs_type = { + name: "pipefs", + get_sb: pipefs_get_sb, + fs_flags: FS_NOMOUNT, +}; static int __init init_pipe_fs(void) { diff --git a/fs/proc/base.c b/fs/proc/base.c index ed0da13a0e91..e472c395cccd 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -37,6 +37,11 @@ #define fake_ino(pid,ino) (((pid)<<16)|(ino)) +static inline struct task_struct *proc_task(struct inode *inode) +{ + return PROC_I(inode)->task; +} + ssize_t proc_pid_read_maps(struct task_struct*,struct file*,char*,size_t,loff_t*); int proc_pid_stat(struct task_struct*,char*); int proc_pid_status(struct task_struct*,char*); @@ -45,9 +50,10 @@ int proc_pid_cpu(struct task_struct*,char*); static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) { - if (inode->u.proc_i.file) { - *mnt = mntget(inode->u.proc_i.file->f_vfsmnt); - *dentry = dget(inode->u.proc_i.file->f_dentry); + struct file *file = PROC_I(inode)->file; + if (file) { + *mnt = mntget(file->f_vfsmnt); + *dentry = dget(file->f_dentry); return 0; } return -ENOENT; @@ -58,7 +64,7 @@ static int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfs struct mm_struct * mm; struct vm_area_struct * vma; int result = -ENOENT; - struct task_struct *task = inode->u.proc_i.task; + struct task_struct *task = proc_task(inode); task_lock(task); mm = task->mm; @@ -89,11 +95,11 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs { struct fs_struct *fs; int result = -ENOENT; - task_lock(inode->u.proc_i.task); - fs = inode->u.proc_i.task->fs; + task_lock(proc_task(inode)); + fs = proc_task(inode)->fs; if(fs) atomic_inc(&fs->count); - task_unlock(inode->u.proc_i.task); + task_unlock(proc_task(inode)); if (fs) { read_lock(&fs->lock); *mnt = mntget(fs->pwdmnt); @@ -109,11 +115,11 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf { struct fs_struct *fs; int result = -ENOENT; - task_lock(inode->u.proc_i.task); - fs = inode->u.proc_i.task->fs; + task_lock(proc_task(inode)); + fs = proc_task(inode)->fs; if(fs) atomic_inc(&fs->count); - task_unlock(inode->u.proc_i.task); + task_unlock(proc_task(inode)); if (fs) { read_lock(&fs->lock); *mnt = mntget(fs->rootmnt); @@ -238,7 +244,7 @@ static ssize_t pid_maps_read(struct file * file, char * buf, size_t count, loff_t *ppos) { struct inode * inode = file->f_dentry->d_inode; - struct task_struct *task = inode->u.proc_i.task; + struct task_struct *task = proc_task(inode); ssize_t res; res = proc_pid_read_maps(task, file, buf, count, ppos); @@ -252,7 +258,7 @@ static struct file_operations proc_maps_operations = { extern struct seq_operations mounts_op; static int mounts_open(struct inode *inode, struct file *file) { - struct task_struct *task = inode->u.proc_i.task; + struct task_struct *task = proc_task(inode); int ret = seq_open(file, &mounts_op); if (!ret) { @@ -298,14 +304,14 @@ static ssize_t proc_info_read(struct file * file, char * buf, unsigned long page; ssize_t length; ssize_t end; - struct task_struct *task = inode->u.proc_i.task; + struct task_struct *task = proc_task(inode); if (count > PROC_BLOCK_SIZE) count = PROC_BLOCK_SIZE; if (!(page = __get_free_page(GFP_KERNEL))) return -ENOMEM; - length = inode->u.proc_i.op.proc_read(task, (char*)page); + length = PROC_I(inode)->op.proc_read(task, (char*)page); if (length < 0) { free_page(page); @@ -342,7 +348,7 @@ static int mem_open(struct inode* inode, struct file* file) static ssize_t mem_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - struct task_struct *task = file->f_dentry->d_inode->u.proc_i.task; + struct task_struct *task = proc_task(file->f_dentry->d_inode); char *page; unsigned long src = *ppos; int copied = 0; @@ -404,7 +410,7 @@ static ssize_t mem_write(struct file * file, const char * buf, { int copied = 0; char *page; - struct task_struct *task = file->f_dentry->d_inode->u.proc_i.task; + struct task_struct *task = proc_task(file->f_dentry->d_inode); unsigned long dst = *ppos; if (!MAY_PTRACE(task)) @@ -463,7 +469,7 @@ static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) if (error) goto out; - error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt); + error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt); nd->last_type = LAST_BIND; out: return error; @@ -503,7 +509,7 @@ static int proc_pid_readlink(struct dentry * dentry, char * buffer, int buflen) if (error) goto out; - error = inode->u.proc_i.op.proc_get_link(inode, &de, &mnt); + error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt); if (error) goto out; @@ -570,7 +576,7 @@ static struct pid_entry base_stuff[] = { static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) { struct inode *inode = filp->f_dentry->d_inode; - struct task_struct *p = inode->u.proc_i.task; + struct task_struct *p = proc_task(inode); unsigned int fd, pid, ino; int retval; char buf[NUMBUF]; @@ -598,6 +604,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) task_unlock(p); if (!files) goto out; + read_lock(&files->file_lock); for (fd = filp->f_pos-2; fd < files->max_fds; fd++, filp->f_pos++) { @@ -605,6 +612,7 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) if (!fcheck_files(files, fd)) continue; + read_unlock(&files->file_lock); j = NUMBUF; i = fd; @@ -617,7 +625,9 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) ino = fake_ino(pid, PROC_PID_FD_DIR + fd); if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0) break; + read_lock(&files->file_lock); } + read_unlock(&files->file_lock); put_files_struct(files); } out: @@ -632,7 +642,7 @@ static int proc_base_readdir(struct file * filp, struct inode *inode = filp->f_dentry->d_inode; struct pid_entry *p; - pid = inode->u.proc_i.task->pid; + pid = proc_task(inode)->pid; if (!pid) return -ENOENT; i = filp->f_pos; @@ -684,6 +694,7 @@ static int task_dumpable(struct task_struct *task) static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task, int ino) { struct inode * inode; + struct proc_inode *ei; /* We need a new inode */ @@ -692,7 +703,9 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st goto out; /* Common stuff */ - + ei = PROC_I(inode); + ei->task = NULL; + ei->file = NULL; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_ino = fake_ino(task->pid, ino); @@ -703,7 +716,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st * grab the reference to task. */ get_task_struct(task); - inode->u.proc_i.task = task; + ei->task = task; inode->i_uid = 0; inode->i_gid = 0; if (ino == PROC_PID_INO || task_dumpable(task)) { @@ -733,7 +746,7 @@ static int pid_fd_revalidate(struct dentry * dentry, int flags) */ static int pid_base_revalidate(struct dentry * dentry, int flags) { - if (dentry->d_inode->u.proc_i.task->pid) + if (proc_task(dentry->d_inode)->pid) return 1; d_drop(dentry); return 0; @@ -767,10 +780,11 @@ static struct dentry_operations pid_base_dentry_operations = static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry) { unsigned int fd, c; - struct task_struct *task = dir->u.proc_i.task; + struct task_struct *task = proc_task(dir); struct file * file; struct files_struct * files; struct inode *inode; + struct proc_inode *ei; const char *name; int len; @@ -792,6 +806,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry) inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_FD_DIR+fd); if (!inode) goto out; + ei = PROC_I(inode); task_lock(task); files = task->files; if (files) @@ -800,7 +815,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry) if (!files) goto out_unlock; read_lock(&files->file_lock); - file = inode->u.proc_i.file = fcheck_files(files, fd); + file = ei->file = fcheck_files(files, fd); if (!file) goto out_unlock2; get_file(file); @@ -809,7 +824,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry) inode->i_op = &proc_pid_link_inode_operations; inode->i_size = 64; inode->i_mode = S_IFLNK; - inode->u.proc_i.op.proc_get_link = proc_fd_link; + ei->op.proc_get_link = proc_fd_link; if (file->f_mode & 1) inode->i_mode |= S_IRUSR | S_IXUSR; if (file->f_mode & 2) @@ -844,8 +859,9 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) { struct inode *inode; int error; - struct task_struct *task = dir->u.proc_i.task; + struct task_struct *task = proc_task(dir); struct pid_entry *p; + struct proc_inode *ei; error = -ENOENT; inode = NULL; @@ -864,6 +880,7 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) if (!inode) goto out; + ei = PROC_I(inode); inode->i_mode = p->mode; /* * Yes, it does not scale. And it should not. Don't add @@ -877,35 +894,35 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) break; case PROC_PID_EXE: inode->i_op = &proc_pid_link_inode_operations; - inode->u.proc_i.op.proc_get_link = proc_exe_link; + ei->op.proc_get_link = proc_exe_link; break; case PROC_PID_CWD: inode->i_op = &proc_pid_link_inode_operations; - inode->u.proc_i.op.proc_get_link = proc_cwd_link; + ei->op.proc_get_link = proc_cwd_link; break; case PROC_PID_ROOT: inode->i_op = &proc_pid_link_inode_operations; - inode->u.proc_i.op.proc_get_link = proc_root_link; + ei->op.proc_get_link = proc_root_link; break; case PROC_PID_ENVIRON: inode->i_fop = &proc_info_file_operations; - inode->u.proc_i.op.proc_read = proc_pid_environ; + ei->op.proc_read = proc_pid_environ; break; case PROC_PID_STATUS: inode->i_fop = &proc_info_file_operations; - inode->u.proc_i.op.proc_read = proc_pid_status; + ei->op.proc_read = proc_pid_status; break; case PROC_PID_STAT: inode->i_fop = &proc_info_file_operations; - inode->u.proc_i.op.proc_read = proc_pid_stat; + ei->op.proc_read = proc_pid_stat; break; case PROC_PID_CMDLINE: inode->i_fop = &proc_info_file_operations; - inode->u.proc_i.op.proc_read = proc_pid_cmdline; + ei->op.proc_read = proc_pid_cmdline; break; case PROC_PID_STATM: inode->i_fop = &proc_info_file_operations; - inode->u.proc_i.op.proc_read = proc_pid_statm; + ei->op.proc_read = proc_pid_statm; break; case PROC_PID_MAPS: inode->i_fop = &proc_maps_operations; @@ -913,7 +930,7 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) #ifdef CONFIG_SMP case PROC_PID_CPU: inode->i_fop = &proc_info_file_operations; - inode->u.proc_i.op.proc_read = proc_pid_cpu; + ei->op.proc_read = proc_pid_cpu; break; #endif case PROC_PID_MEM: @@ -973,6 +990,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry) struct task_struct *task; const char *name; struct inode *inode; + struct proc_inode *ei; int len; pid = 0; @@ -982,10 +1000,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry) inode = new_inode(dir->i_sb); if (!inode) return ERR_PTR(-ENOMEM); + ei = PROC_I(inode); inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_ino = fake_ino(0, PROC_PID_INO); - inode->u.proc_i.file = NULL; - inode->u.proc_i.task = NULL; + ei->file = NULL; + ei->task = NULL; inode->i_mode = S_IFLNK|S_IRWXUGO; inode->i_uid = inode->i_gid = 0; inode->i_size = 64; @@ -1035,10 +1054,10 @@ out: void proc_pid_delete_inode(struct inode *inode) { - if (inode->u.proc_i.file) - fput(inode->u.proc_i.file); - if (inode->u.proc_i.task) - free_task_struct(inode->u.proc_i.task); + if (PROC_I(inode)->file) + fput(PROC_I(inode)->file); + if (proc_task(inode)) + free_task_struct(proc_task(inode)); } #define PROC_NUMBUF 10 diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 3e31f65e266b..f50b13026f27 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -58,7 +58,7 @@ proc_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos) char *start; struct proc_dir_entry * dp; - dp = (struct proc_dir_entry *) inode->u.generic_ip; + dp = PDE(inode); if (!(page = (char*) __get_free_page(GFP_KERNEL))) return -ENOMEM; @@ -128,7 +128,7 @@ proc_file_write(struct file * file, const char * buffer, struct inode *inode = file->f_dentry->d_inode; struct proc_dir_entry * dp; - dp = (struct proc_dir_entry *) inode->u.generic_ip; + dp = PDE(inode); if (!dp->write_proc) return -EIO; @@ -221,13 +221,13 @@ out: static int proc_readlink(struct dentry *dentry, char *buffer, int buflen) { - char *s=((struct proc_dir_entry *)dentry->d_inode->u.generic_ip)->data; + char *s=PDE(dentry->d_inode)->data; return vfs_readlink(dentry, buffer, buflen, s); } static int proc_follow_link(struct dentry *dentry, struct nameidata *nd) { - char *s=((struct proc_dir_entry *)dentry->d_inode->u.generic_ip)->data; + char *s=PDE(dentry->d_inode)->data; return vfs_follow_link(nd, s); } @@ -264,7 +264,7 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry) error = -ENOENT; inode = NULL; - de = (struct proc_dir_entry *) dir->u.generic_ip; + de = PDE(dir); if (de) { for (de = de->subdir; de ; de = de->next) { if (!de || !de->low_ino) @@ -306,7 +306,7 @@ int proc_readdir(struct file * filp, struct inode *inode = filp->f_dentry->d_inode; ino = inode->i_ino; - de = (struct proc_dir_entry *) inode->u.generic_ip; + de = PDE(inode); if (!de) return -EINVAL; i = filp->f_pos; @@ -413,7 +413,7 @@ static void proc_kill_inodes(struct proc_dir_entry *de) if (dentry->d_op != &proc_dentry_operations) continue; inode = dentry->d_inode; - if (inode->u.generic_ip != de) + if (PDE(inode) != de) continue; fops = filp->f_op; filp->f_op = NULL; diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 8af8a6868e92..c96bde47f090 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -58,7 +58,7 @@ void de_put(struct proc_dir_entry *de) */ static void proc_delete_inode(struct inode *inode) { - struct proc_dir_entry *de = inode->u.generic_ip; + struct proc_dir_entry *de = PDE(inode); inode->i_state = I_CLEAR; @@ -91,14 +91,51 @@ static int proc_statfs(struct super_block *sb, struct statfs *buf) return 0; } +static kmem_cache_t * proc_inode_cachep; + +static struct inode *proc_alloc_inode(struct super_block *sb) +{ + struct proc_inode *ei; + ei = (struct proc_inode *)kmem_cache_alloc(proc_inode_cachep, SLAB_KERNEL); + if (!ei) + return NULL; + return &ei->vfs_inode; +} + +static void proc_destroy_inode(struct inode *inode) +{ + kmem_cache_free(proc_inode_cachep, PROC_I(inode)); +} + +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +{ + struct proc_inode *ei = (struct proc_inode *) foo; + + if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == + SLAB_CTOR_CONSTRUCTOR) + inode_init_once(&ei->vfs_inode); +} + +int __init proc_init_inodecache(void) +{ + proc_inode_cachep = kmem_cache_create("proc_inode_cache", + sizeof(struct proc_inode), + 0, SLAB_HWCACHE_ALIGN, + init_once, NULL); + if (proc_inode_cachep == NULL) + return -ENOMEM; + return 0; +} + static struct super_operations proc_sops = { + alloc_inode: proc_alloc_inode, + destroy_inode: proc_destroy_inode, read_inode: proc_read_inode, put_inode: force_delete, delete_inode: proc_delete_inode, statfs: proc_statfs, }; - static int parse_options(char *options,uid_t *uid,gid_t *gid) { char *this_char,*value; @@ -147,7 +184,7 @@ printk("proc_iget: using deleted entry %s, count=%d\n", de->name, atomic_read(&d if (!inode) goto out_fail; - inode->u.generic_ip = (void *) de; + PROC_I(inode)->pde = de; if (de) { if (de->mode) { inode->i_mode = de->mode; @@ -176,8 +213,7 @@ out_fail: goto out; } -struct super_block *proc_read_super(struct super_block *s,void *data, - int silent) +int proc_fill_super(struct super_block *s, void *data, int silent) { struct inode * root_inode; struct task_struct *p; @@ -200,11 +236,11 @@ struct super_block *proc_read_super(struct super_block *s,void *data, if (!s->s_root) goto out_no_root; parse_options(data, &root_inode->i_uid, &root_inode->i_gid); - return s; + return 0; out_no_root: printk("proc_read_super: get root inode failed\n"); iput(root_inode); - return NULL; + return -ENOMEM; } MODULE_LICENSE("GPL"); diff --git a/fs/proc/root.c b/fs/proc/root.c index 3db40a53bc0f..666166bfcf57 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -23,11 +23,24 @@ struct proc_dir_entry *proc_net, *proc_bus, *proc_root_fs, *proc_root_driver; struct proc_dir_entry *proc_sys_root; #endif -static DECLARE_FSTYPE(proc_fs_type, "proc", proc_read_super, FS_SINGLE); +static struct super_block *proc_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_single(fs_type, flags, data, proc_fill_super); +} + +static struct file_system_type proc_fs_type = { + name: "proc", + get_sb: proc_get_sb, +}; +extern int __init proc_init_inodecache(void); void __init proc_root_init(void) { - int err = register_filesystem(&proc_fs_type); + int err = proc_init_inodecache(); + if (err) + return; + err = register_filesystem(&proc_fs_type); if (err) return; proc_mnt = kern_mount(&proc_fs_type); diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index b8994583f13a..3bed425ec3b8 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -302,7 +302,7 @@ static struct super_operations ramfs_ops = { put_inode: force_delete, }; -static struct super_block *ramfs_read_super(struct super_block * sb, void * data, int silent) +static int ramfs_fill_super(struct super_block * sb, void * data, int silent) { struct inode * inode; struct dentry * root; @@ -313,19 +313,33 @@ static struct super_block *ramfs_read_super(struct super_block * sb, void * data sb->s_op = &ramfs_ops; inode = ramfs_get_inode(sb, S_IFDIR | 0755, 0); if (!inode) - return NULL; + return -ENOMEM; root = d_alloc_root(inode); if (!root) { iput(inode); - return NULL; + return -ENOMEM; } sb->s_root = root; - return sb; + return 0; +} + +static struct super_block *ramfs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_nodev(fs_type, flags, data, ramfs_fill_super); } -static DECLARE_FSTYPE(ramfs_fs_type, "ramfs", ramfs_read_super, FS_LITTER); -static DECLARE_FSTYPE(rootfs_fs_type, "rootfs", ramfs_read_super, FS_NOMOUNT|FS_LITTER); +static struct file_system_type ramfs_fs_type = { + name: "ramfs", + get_sb: ramfs_get_sb, + fs_flags: FS_LITTER, +}; +static struct file_system_type rootfs_fs_type = { + name: "rootfs", + get_sb: ramfs_get_sb, + fs_flags: FS_NOMOUNT|FS_LITTER, +}; static int __init init_ramfs_fs(void) { diff --git a/fs/read_write.c b/fs/read_write.c index 31cee2a6aa4e..ce5230669579 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -51,6 +51,31 @@ loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) return retval; } +loff_t remote_llseek(struct file *file, loff_t offset, int origin) +{ + long long retval; + + lock_kernel(); + switch (origin) { + case 2: + offset += file->f_dentry->d_inode->i_size; + break; + case 1: + offset += file->f_pos; + } + retval = -EINVAL; + if (offset>=0 && offset<=file->f_dentry->d_inode->i_sb->s_maxbytes) { + if (offset != file->f_pos) { + file->f_pos = offset; + file->f_reada = 0; + file->f_version = ++event; + } + retval = offset; + } + unlock_kernel(); + return retval; +} + loff_t no_llseek(struct file *file, loff_t offset, int origin) { return -ESPIPE; diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 4fe8843c5899..c35cb51a9a48 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -890,6 +890,13 @@ static void init_inode (struct inode * inode, struct path * path) inode->i_blksize = PAGE_SIZE; INIT_LIST_HEAD(&(REISERFS_I(inode)->i_prealloc_list )); + REISERFS_I(inode)->i_flags = 0; + REISERFS_I(inode)->i_prealloc_block = 0; + REISERFS_I(inode)->i_prealloc_count = 0; + REISERFS_I(inode)->i_trans_id = 0; + REISERFS_I(inode)->i_trans_index = 0; + /* nopack = 0, by default */ + REISERFS_I(inode)->i_flags &= ~i_nopack_mask; if (stat_data_v1 (ih)) { struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih); @@ -950,13 +957,6 @@ static void init_inode (struct inode * inode, struct path * path) set_inode_item_key_version (inode, KEY_FORMAT_3_6); REISERFS_I(inode)->i_first_direct_byte = 0; } - REISERFS_I(inode)->i_flags = 0; - REISERFS_I(inode)->i_prealloc_block = 0; - REISERFS_I(inode)->i_prealloc_count = 0; - REISERFS_I(inode)->i_trans_id = 0; - REISERFS_I(inode)->i_trans_index = 0; - /* nopack = 0, by default */ - REISERFS_I(inode)->i_flags &= ~i_nopack_mask; pathrelse (path); if (S_ISREG (inode->i_mode)) { diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index b3feaa56924a..39badd71692f 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c @@ -381,7 +381,7 @@ smb_file_permission(struct inode *inode, int mask) struct file_operations smb_file_operations = { - llseek: generic_file_llseek, + llseek: remote_llseek, read: smb_file_read, write: smb_file_write, ioctl: smb_ioctl, diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c index 46313b623c7b..8c66f4c5e655 100644 --- a/fs/smbfs/sock.c +++ b/fs/smbfs/sock.c @@ -176,7 +176,7 @@ int smb_valid_socket(struct inode * inode) { return (inode && S_ISSOCK(inode->i_mode) && - inode->u.socket_i.type == SOCK_STREAM); + SOCKET_I(inode)->type == SOCK_STREAM); } static struct socket * @@ -190,7 +190,7 @@ server_sock(struct smb_sb_info *server) if (!smb_valid_socket(file->f_dentry->d_inode)) PARANOIA("bad socket!\n"); #endif - return &file->f_dentry->d_inode->u.socket_i; + return SOCKET_I(file->f_dentry->d_inode); } return NULL; } diff --git a/fs/stat.c b/fs/stat.c index d7ed42c77f59..20bd373580c5 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -25,68 +25,28 @@ do_revalidate(struct dentry *dentry) return 0; } - -#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) - -/* - * For backward compatibility? Maybe this should be moved - * into arch/i386 instead? - */ -static int cp_old_stat(struct inode * inode, struct __old_kernel_stat * statbuf) +static int do_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { - static int warncount = 5; - struct __old_kernel_stat tmp; - - if (warncount > 0) { - warncount--; - printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n", - current->comm); - } else if (warncount < 0) { - /* it's laughable, but... */ - warncount = 0; - } - - tmp.st_dev = kdev_t_to_nr(inode->i_dev); - tmp.st_ino = inode->i_ino; - tmp.st_mode = inode->i_mode; - tmp.st_nlink = inode->i_nlink; - SET_OLDSTAT_UID(tmp, inode->i_uid); - SET_OLDSTAT_GID(tmp, inode->i_gid); - tmp.st_rdev = kdev_t_to_nr(inode->i_rdev); -#if BITS_PER_LONG == 32 - if (inode->i_size > MAX_NON_LFS) - return -EOVERFLOW; -#endif - tmp.st_size = inode->i_size; - tmp.st_atime = inode->i_atime; - tmp.st_mtime = inode->i_mtime; - tmp.st_ctime = inode->i_ctime; - return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; -} - -#endif - -static int cp_new_stat(struct inode * inode, struct stat * statbuf) -{ - struct stat tmp; + int res = 0; unsigned int blocks, indirect; - - memset(&tmp, 0, sizeof(tmp)); - tmp.st_dev = kdev_t_to_nr(inode->i_dev); - tmp.st_ino = inode->i_ino; - tmp.st_mode = inode->i_mode; - tmp.st_nlink = inode->i_nlink; - SET_STAT_UID(tmp, inode->i_uid); - SET_STAT_GID(tmp, inode->i_gid); - tmp.st_rdev = kdev_t_to_nr(inode->i_rdev); -#if BITS_PER_LONG == 32 - if (inode->i_size > MAX_NON_LFS) - return -EOVERFLOW; -#endif - tmp.st_size = inode->i_size; - tmp.st_atime = inode->i_atime; - tmp.st_mtime = inode->i_mtime; - tmp.st_ctime = inode->i_ctime; + struct inode *inode = dentry->d_inode; + + res = do_revalidate(dentry); + if (res) + return res; + + stat->dev = kdev_t_to_nr(inode->i_dev); + stat->ino = inode->i_ino; + stat->mode = inode->i_mode; + stat->nlink = inode->i_nlink; + stat->uid = inode->i_uid; + stat->gid = inode->i_gid; + stat->rdev = kdev_t_to_nr(inode->i_rdev); + stat->atime = inode->i_atime; + stat->mtime = inode->i_mtime; + stat->ctime = inode->i_ctime; + stat->ctime = inode->i_ctime; + stat->size = inode->i_size; /* * st_blocks and st_blksize are approximated with a simple algorithm if * they aren't supported directly by the filesystem. The minix and msdos @@ -106,7 +66,7 @@ static int cp_new_stat(struct inode * inode, struct stat * statbuf) #define I_B (BLOCK_SIZE / sizeof(unsigned short)) if (!inode->i_blksize) { - blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE; + blocks = (stat->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS; if (blocks > D_B) { indirect = (blocks - D_B + I_B - 1) / I_B; blocks += indirect; @@ -117,130 +77,178 @@ static int cp_new_stat(struct inode * inode, struct stat * statbuf) blocks++; } } - tmp.st_blocks = (BLOCK_SIZE / 512) * blocks; - tmp.st_blksize = BLOCK_SIZE; + stat->blocks = (BLOCK_SIZE / 512) * blocks; + stat->blksize = BLOCK_SIZE; } else { - tmp.st_blocks = inode->i_blocks; - tmp.st_blksize = inode->i_blksize; + stat->blocks = inode->i_blocks; + stat->blksize = inode->i_blksize; } - return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; + return 0; } - -#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) -/* - * For backward compatibility? Maybe this should be moved - * into arch/i386 instead? - */ -asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf) +int vfs_stat(char *name, struct kstat *stat) { struct nameidata nd; int error; - error = user_path_walk(filename, &nd); + error = user_path_walk(name, &nd); if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); + error = do_getattr(nd.mnt, nd.dentry, stat); path_release(&nd); } return error; } -#endif -asmlinkage long sys_newstat(char * filename, struct stat * statbuf) +int vfs_lstat(char *name, struct kstat *stat) { struct nameidata nd; int error; - error = user_path_walk(filename, &nd); + error = user_path_walk_link(name, &nd); if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); + error = do_getattr(nd.mnt, nd.dentry, stat); path_release(&nd); } return error; } +int vfs_fstat(unsigned int fd, struct kstat *stat) +{ + struct file *f = fget(fd); + int error = -EBADF; + + if (f) { + error = do_getattr(f->f_vfsmnt, f->f_dentry, stat); + fput(f); + } + return error; +} + #if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) /* * For backward compatibility? Maybe this should be moved * into arch/i386 instead? */ -asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf) +static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat * statbuf) { - struct nameidata nd; - int error; + static int warncount = 5; + struct __old_kernel_stat tmp; - error = user_path_walk_link(filename, &nd); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); - path_release(&nd); + if (warncount > 0) { + warncount--; + printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n", + current->comm); + } else if (warncount < 0) { + /* it's laughable, but... */ + warncount = 0; } - return error; -} -#endif + tmp.st_dev = stat->dev; + tmp.st_ino = stat->ino; + tmp.st_mode = stat->mode; + tmp.st_nlink = stat->nlink; + SET_OLDSTAT_UID(tmp, stat->uid); + SET_OLDSTAT_GID(tmp, stat->gid); + tmp.st_rdev = stat->rdev; +#if BITS_PER_LONG == 32 + if (stat->size > MAX_NON_LFS) + return -EOVERFLOW; +#endif + tmp.st_size = stat->size; + tmp.st_atime = stat->atime; + tmp.st_mtime = stat->mtime; + tmp.st_ctime = stat->ctime; + return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; +} -asmlinkage long sys_newlstat(char * filename, struct stat * statbuf) +asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf) { - struct nameidata nd; - int error; + struct kstat stat; + int error = vfs_stat(filename, &stat); + + if (!error) + error = cp_old_stat(&stat, statbuf); - error = user_path_walk_link(filename, &nd); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); - path_release(&nd); - } return error; } +asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf) +{ + struct kstat stat; + int error = vfs_lstat(filename, &stat); -#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) + if (!error) + error = cp_old_stat(&stat, statbuf); -/* - * For backward compatibility? Maybe this should be moved - * into arch/i386 instead? - */ + return error; +} asmlinkage long sys_fstat(unsigned int fd, struct __old_kernel_stat * statbuf) { - struct file * f; - int err = -EBADF; + struct kstat stat; + int error = vfs_fstat(fd, &stat); - f = fget(fd); - if (f) { - struct dentry * dentry = f->f_dentry; + if (!error) + error = cp_old_stat(&stat, statbuf); - err = do_revalidate(dentry); - if (!err) - err = cp_old_stat(dentry->d_inode, statbuf); - fput(f); - } - return err; + return error; } #endif +static int cp_new_stat(struct kstat *stat, struct stat *statbuf) +{ + struct stat tmp; + + memset(&tmp, 0, sizeof(tmp)); + tmp.st_dev = stat->dev; + tmp.st_ino = stat->ino; + tmp.st_mode = stat->mode; + tmp.st_nlink = stat->nlink; + SET_STAT_UID(tmp, stat->uid); + SET_STAT_GID(tmp, stat->gid); + tmp.st_rdev = stat->rdev; +#if BITS_PER_LONG == 32 + if (stat->size > MAX_NON_LFS) + return -EOVERFLOW; +#endif + tmp.st_size = stat->size; + tmp.st_atime = stat->atime; + tmp.st_mtime = stat->mtime; + tmp.st_ctime = stat->ctime; + tmp.st_blocks = stat->blocks; + tmp.st_blksize = stat->blksize; + return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; +} + +asmlinkage long sys_newstat(char * filename, struct stat * statbuf) +{ + struct kstat stat; + int error = vfs_stat(filename, &stat); + + if (!error) + error = cp_new_stat(&stat, statbuf); + + return error; +} +asmlinkage long sys_newlstat(char * filename, struct stat * statbuf) +{ + struct kstat stat; + int error = vfs_lstat(filename, &stat); + + if (!error) + error = cp_new_stat(&stat, statbuf); + + return error; +} asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf) { - struct file * f; - int err = -EBADF; + struct kstat stat; + int error = vfs_fstat(fd, &stat); - f = fget(fd); - if (f) { - struct dentry * dentry = f->f_dentry; + if (!error) + error = cp_new_stat(&stat, statbuf); - err = do_revalidate(dentry); - if (!err) - err = cp_new_stat(dentry->d_inode, statbuf); - fput(f); - } - return err; + return error; } asmlinkage long sys_readlink(const char * path, char * buf, int bufsiz) @@ -270,110 +278,59 @@ asmlinkage long sys_readlink(const char * path, char * buf, int bufsiz) /* ---------- LFS-64 ----------- */ #if !defined(__alpha__) && !defined(__ia64__) && !defined(__mips64) && !defined(__x86_64__) && !defined(CONFIG_ARCH_S390X) -static long cp_new_stat64(struct inode * inode, struct stat64 * statbuf) +static long cp_new_stat64(struct kstat *stat, struct stat64 *statbuf) { struct stat64 tmp; - unsigned int blocks, indirect; memset(&tmp, 0, sizeof(tmp)); - tmp.st_dev = kdev_t_to_nr(inode->i_dev); - tmp.st_ino = inode->i_ino; + tmp.st_dev = stat->dev; + tmp.st_ino = stat->ino; #ifdef STAT64_HAS_BROKEN_ST_INO - tmp.__st_ino = inode->i_ino; + tmp.__st_ino = stat->ino; #endif - tmp.st_mode = inode->i_mode; - tmp.st_nlink = inode->i_nlink; - tmp.st_uid = inode->i_uid; - tmp.st_gid = inode->i_gid; - tmp.st_rdev = kdev_t_to_nr(inode->i_rdev); - tmp.st_atime = inode->i_atime; - tmp.st_mtime = inode->i_mtime; - tmp.st_ctime = inode->i_ctime; - tmp.st_size = inode->i_size; -/* - * st_blocks and st_blksize are approximated with a simple algorithm if - * they aren't supported directly by the filesystem. The minix and msdos - * filesystems don't keep track of blocks, so they would either have to - * be counted explicitly (by delving into the file itself), or by using - * this simple algorithm to get a reasonable (although not 100% accurate) - * value. - */ - -/* - * Use minix fs values for the number of direct and indirect blocks. The - * count is now exact for the minix fs except that it counts zero blocks. - * Everything is in units of BLOCK_SIZE until the assignment to - * tmp.st_blksize. - */ -#define D_B 7 -#define I_B (BLOCK_SIZE / sizeof(unsigned short)) - - if (!inode->i_blksize) { - blocks = (tmp.st_size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS; - if (blocks > D_B) { - indirect = (blocks - D_B + I_B - 1) / I_B; - blocks += indirect; - if (indirect > 1) { - indirect = (indirect - 1 + I_B - 1) / I_B; - blocks += indirect; - if (indirect > 1) - blocks++; - } - } - tmp.st_blocks = (BLOCK_SIZE / 512) * blocks; - tmp.st_blksize = BLOCK_SIZE; - } else { - tmp.st_blocks = inode->i_blocks; - tmp.st_blksize = inode->i_blksize; - } + tmp.st_mode = stat->mode; + tmp.st_nlink = stat->nlink; + tmp.st_uid = stat->uid; + tmp.st_gid = stat->gid; + tmp.st_rdev = stat->rdev; + tmp.st_atime = stat->atime; + tmp.st_mtime = stat->mtime; + tmp.st_ctime = stat->ctime; + tmp.st_size = stat->size; + tmp.st_blocks = stat->blocks; + tmp.st_blksize = stat->blksize; return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; } asmlinkage long sys_stat64(char * filename, struct stat64 * statbuf, long flags) { - struct nameidata nd; - int error; + struct kstat stat; + int error = vfs_stat(filename, &stat); + + if (!error) + error = cp_new_stat64(&stat, statbuf); - error = user_path_walk(filename, &nd); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); - path_release(&nd); - } return error; } - asmlinkage long sys_lstat64(char * filename, struct stat64 * statbuf, long flags) { - struct nameidata nd; - int error; + struct kstat stat; + int error = vfs_lstat(filename, &stat); + + if (!error) + error = cp_new_stat64(&stat, statbuf); - error = user_path_walk_link(filename, &nd); - if (!error) { - error = do_revalidate(nd.dentry); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); - path_release(&nd); - } return error; } - asmlinkage long sys_fstat64(unsigned long fd, struct stat64 * statbuf, long flags) { - struct file * f; - int err = -EBADF; + struct kstat stat; + int error = vfs_fstat(fd, &stat); - f = fget(fd); - if (f) { - struct dentry * dentry = f->f_dentry; + if (!error) + error = cp_new_stat64(&stat, statbuf); - err = do_revalidate(dentry); - if (!err) - err = cp_new_stat64(dentry->d_inode, statbuf); - fput(f); - } - return err; + return error; } #endif /* LFS-64 */ diff --git a/fs/super.c b/fs/super.c index fb70602790ae..f9f6a9802ad4 100644 --- a/fs/super.c +++ b/fs/super.c @@ -641,8 +641,9 @@ retry: return s; } -static struct super_block *get_sb_bdev(struct file_system_type *fs_type, - int flags, char *dev_name, void * data) +struct super_block *get_sb_bdev(struct file_system_type *fs_type, + int flags, char *dev_name, void * data, + int (*fill_super)(struct super_block *, void *, int)) { struct inode *inode; struct block_device *bdev; @@ -698,7 +699,7 @@ restart: list_for_each(p, &super_blocks) { struct super_block *old = sb_entry(p); - if (!kdev_same(old->s_dev, dev)) + if (old->s_bdev != bdev) continue; if (old->s_type != fs_type || ((flags ^ old->s_flags) & MS_RDONLY)) { @@ -718,8 +719,8 @@ restart: s->s_flags = flags; insert_super(s, fs_type); strncpy(s->s_id, bdevname(dev), sizeof(s->s_id)); - error = -EINVAL; - if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) + error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); + if (error) goto failed; s->s_flags |= MS_ACTIVE; path_release(&nd); @@ -736,19 +737,23 @@ out: return ERR_PTR(error); } -static struct super_block *get_sb_nodev(struct file_system_type *fs_type, - int flags, char *dev_name, void *data) +struct super_block *get_sb_nodev(struct file_system_type *fs_type, + int flags, void *data, + int (*fill_super)(struct super_block *, void *, int)) { + int error; struct super_block *s = get_anon_super(fs_type, NULL, NULL); if (IS_ERR(s)) return s; s->s_flags = flags; - if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) { + + error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); + if (error) { deactivate_super(s); remove_super(s); - return ERR_PTR(-EINVAL); + return ERR_PTR(error); } s->s_flags |= MS_ACTIVE; return s; @@ -759,19 +764,22 @@ static int compare_single(struct super_block *s, void *p) return 1; } -static struct super_block *get_sb_single(struct file_system_type *fs_type, - int flags, char *dev_name, void *data) +struct super_block *get_sb_single(struct file_system_type *fs_type, + int flags, void *data, + int (*fill_super)(struct super_block *, void *, int)) { + int error; struct super_block *s = get_anon_super(fs_type, compare_single, NULL); if (IS_ERR(s)) return s; if (!s->s_root) { s->s_flags = flags; - if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) { + error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0); + if (error) { deactivate_super(s); remove_super(s); - return ERR_PTR(-EINVAL); + return ERR_PTR(error); } s->s_flags |= MS_ACTIVE; } @@ -779,6 +787,22 @@ static struct super_block *get_sb_single(struct file_system_type *fs_type, return s; } +/* Will go away */ +static int fill_super(struct super_block *sb, void *data, int verbose) +{ + return sb->s_type->read_super(sb, data, verbose) ? 0 : -EINVAL; +} +static struct super_block *__get_sb_bdev(struct file_system_type *fs_type, + int flags, char *dev_name, void * data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, fill_super); +} +static struct super_block *__get_sb_nodev(struct file_system_type *fs_type, + int flags, char *dev_name, void * data) +{ + return get_sb_nodev(fs_type, flags, data, fill_super); +} + struct vfsmount * do_kern_mount(const char *fstype, int flags, char *name, void *data) { @@ -792,12 +816,12 @@ do_kern_mount(const char *fstype, int flags, char *name, void *data) mnt = alloc_vfsmnt(name); if (!mnt) goto out; - if (type->fs_flags & FS_REQUIRES_DEV) - sb = get_sb_bdev(type, flags, name, data); - else if (type->fs_flags & FS_SINGLE) - sb = get_sb_single(type, flags, name, data); + if (type->get_sb) + sb = type->get_sb(type, flags, name, data); + else if (type->fs_flags & FS_REQUIRES_DEV) + sb = __get_sb_bdev(type, flags, name, data); else - sb = get_sb_nodev(type, flags, name, data); + sb = __get_sb_nodev(type, flags, name, data); if (IS_ERR(sb)) goto out_mnt; if (type->fs_flags & FS_NOMOUNT) diff --git a/fs/udf/super.c b/fs/udf/super.c index a4984734a384..cf78cf53cc76 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1544,7 +1544,7 @@ udf_read_super(struct super_block *sb, void *options, int silent) iput(inode); goto error_out; } - sb->s_maxbytes = ~0ULL; + sb->s_maxbytes = MAX_LFS_FILESIZE; return sb; error_out: diff --git a/fs/ufs/file.c b/fs/ufs/file.c index 7af092555ad0..819e6945b112 100644 --- a/fs/ufs/file.c +++ b/fs/ufs/file.c @@ -38,46 +38,12 @@ #include <linux/smp_lock.h> /* - * Make sure the offset never goes beyond the 32-bit mark.. - */ -static long long ufs_file_lseek( - struct file *file, - long long offset, - int origin ) -{ - long long retval; - struct inode *inode = file->f_dentry->d_inode; - - lock_kernel(); - - switch (origin) { - case 2: - offset += inode->i_size; - break; - case 1: - offset += file->f_pos; - } - retval = -EINVAL; - /* make sure the offset fits in 32 bits */ - if (((unsigned long long) offset >> 32) == 0) { - if (offset != file->f_pos) { - file->f_pos = offset; - file->f_reada = 0; - file->f_version = ++event; - } - retval = offset; - } - unlock_kernel(); - return retval; -} - -/* * We have mostly NULL's here: the current defaults are ok for * the ufs filesystem. */ struct file_operations ufs_file_operations = { - llseek: ufs_file_lseek, + llseek: generic_file_llseek, read: generic_file_read, write: generic_file_write, mmap: generic_file_mmap, diff --git a/include/asm-alpha/siginfo.h b/include/asm-alpha/siginfo.h index 88470336ef6e..b5a899bd13d8 100644 --- a/include/asm-alpha/siginfo.h +++ b/include/asm-alpha/siginfo.h @@ -107,6 +107,7 @@ typedef struct siginfo { #define SI_MESGQ -3 /* sent by real time mesq state change */ #define SI_ASYNCIO -4 /* sent by AIO completion */ #define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h index b16c49d2e9d7..b94be13a7254 100644 --- a/include/asm-alpha/unistd.h +++ b/include/asm-alpha/unistd.h @@ -318,6 +318,7 @@ #define __NR_gettid 378 #define __NR_readahead 379 #define __NR_security 380 /* syscall for security modules */ +#define __NR_tkill 381 #if defined(__GNUC__) diff --git a/include/asm-arm/siginfo.h b/include/asm-arm/siginfo.h index 2591a6fdc963..354b4e23b306 100644 --- a/include/asm-arm/siginfo.h +++ b/include/asm-arm/siginfo.h @@ -107,6 +107,7 @@ typedef struct siginfo { #define SI_MESGQ -3 /* sent by real time mesq state change */ #define SI_ASYNCIO -4 /* sent by AIO completion */ #define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) diff --git a/include/asm-cris/siginfo.h b/include/asm-cris/siginfo.h index ce26ee48e94f..d843ace9c962 100644 --- a/include/asm-cris/siginfo.h +++ b/include/asm-cris/siginfo.h @@ -107,6 +107,7 @@ typedef struct siginfo { #define SI_MESGQ -3 /* sent by real time mesq state change */ #define SI_ASYNCIO -4 /* sent by AIO completion */ #define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h index 9fe719c8089e..80a36c1369ce 100644 --- a/include/asm-cris/unistd.h +++ b/include/asm-cris/unistd.h @@ -230,6 +230,7 @@ #define __NR_security 223 /* syscall for security modules */ #define __NR_gettid 224 #define __NR_readahead 225 +#define __NR_tkill 226 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ #define _syscall0(type,name) \ diff --git a/include/asm-i386/siginfo.h b/include/asm-i386/siginfo.h index 9abf5427a9dc..d2686eda126d 100644 --- a/include/asm-i386/siginfo.h +++ b/include/asm-i386/siginfo.h @@ -107,6 +107,7 @@ typedef struct siginfo { #define SI_MESGQ -3 /* sent by real time mesq state change */ #define SI_ASYNCIO -4 /* sent by AIO completion */ #define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index d89e8453241b..9be3827028c6 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h @@ -242,6 +242,7 @@ #define __NR_removexattr 235 #define __NR_lremovexattr 236 #define __NR_fremovexattr 237 +#define __NR_tkill 238 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */ diff --git a/include/asm-ia64/siginfo.h b/include/asm-ia64/siginfo.h index dc801e5ab8f2..c04493693a80 100644 --- a/include/asm-ia64/siginfo.h +++ b/include/asm-ia64/siginfo.h @@ -124,6 +124,7 @@ typedef struct siginfo { #define SI_MESGQ -3 /* sent by real time mesq state change */ #define SI_ASYNCIO -4 /* sent by AIO completion */ #define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h index 4ca8ff0fd67c..f594a382db4e 100644 --- a/include/asm-ia64/unistd.h +++ b/include/asm-ia64/unistd.h @@ -206,6 +206,7 @@ #define __NR_getdents64 1214 #define __NR_getunwind 1215 #define __NR_readahead 1216 +#define __NR_tkill 1217 #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER) diff --git a/include/asm-m68k/siginfo.h b/include/asm-m68k/siginfo.h index 6b48063af642..d84552d56802 100644 --- a/include/asm-m68k/siginfo.h +++ b/include/asm-m68k/siginfo.h @@ -117,6 +117,7 @@ typedef struct siginfo { #define SI_MESGQ -3 /* sent by real time mesq state change */ #define SI_ASYNCIO -4 /* sent by AIO completion */ #define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h index e8bdf18a190e..c3cf1133d832 100644 --- a/include/asm-m68k/unistd.h +++ b/include/asm-m68k/unistd.h @@ -222,6 +222,8 @@ #define __NR_setfsuid32 215 #define __NR_setfsgid32 216 #define __NR_getdents64 220 +#define __NR_gettid 221 +#define __NR_tkill 222 /* user-visible error numbers are in the range -1 - -122: see <asm-m68k/errno.h> */ diff --git a/include/asm-mips/siginfo.h b/include/asm-mips/siginfo.h index aecf13381414..aeb6f5e40122 100644 --- a/include/asm-mips/siginfo.h +++ b/include/asm-mips/siginfo.h @@ -127,6 +127,7 @@ typedef struct siginfo { #define SI_TIMER __SI_CODE(__SI_TIMER,-3) /* sent by timer expiration */ #define SI_MESGQ -4 /* sent by real time mesq state change */ #define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 97d031618666..283831f78768 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -233,6 +233,8 @@ #define __NR_madvise (__NR_Linux + 218) #define __NR_getdents64 (__NR_Linux + 219) #define __NR_fcntl64 (__NR_Linux + 220) +#define __NR_gettid (__NR_Linux + 221) +#define __NR_tkill (__NR_Linux + 222) /* * Offset of the last Linux flavoured syscall diff --git a/include/asm-mips64/siginfo.h b/include/asm-mips64/siginfo.h index 7ceb380906f9..0a10716d6ab9 100644 --- a/include/asm-mips64/siginfo.h +++ b/include/asm-mips64/siginfo.h @@ -127,6 +127,7 @@ typedef struct siginfo { #define SI_TIMER __SI_CODE(__SI_TIMER,-3) /* sent by timer expiration */ #define SI_MESGQ -4 /* sent by real time mesq state change */ #define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) diff --git a/include/asm-mips64/unistd.h b/include/asm-mips64/unistd.h index 2c9fef61786e..5d56eadb3450 100644 --- a/include/asm-mips64/unistd.h +++ b/include/asm-mips64/unistd.h @@ -461,11 +461,13 @@ #define __NR_mincore (__NR_Linux + 211) #define __NR_madvise (__NR_Linux + 212) #define __NR_getdents64 (__NR_Linux + 213) +#define __NR_gettid (__NR_Linux + 214) +#define __NR_tkill (__NR_Linux + 215) /* * Offset of the last Linux flavoured syscall */ -#define __NR_Linux_syscalls 213 +#define __NR_Linux_syscalls 215 #ifndef _LANGUAGE_ASSEMBLY diff --git a/include/asm-parisc/siginfo.h b/include/asm-parisc/siginfo.h index 143fe7eef2ba..349b614eca38 100644 --- a/include/asm-parisc/siginfo.h +++ b/include/asm-parisc/siginfo.h @@ -107,6 +107,7 @@ typedef struct siginfo { #define SI_MESGQ -3 /* sent by real time mesq state change */ #define SI_ASYNCIO -4 /* sent by AIO completion */ #define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h index ea0542a35fb4..f84502172fa7 100644 --- a/include/asm-parisc/unistd.h +++ b/include/asm-parisc/unistd.h @@ -689,8 +689,10 @@ #define __NR_getpmsg (__NR_Linux + 196) /* some people actually want streams */ #define __NR_putpmsg (__NR_Linux + 197) /* some people actually want streams */ +#define __NR_gettid (__NR_Linux + 198) +#define __NR_tkill (__NR_Linux + 199) -#define __NR_Linux_syscalls 197 +#define __NR_Linux_syscalls 199 #define HPUX_GATEWAY_ADDR 0xC0000004 #define LINUX_GATEWAY_ADDR 0x100 diff --git a/include/asm-ppc/siginfo.h b/include/asm-ppc/siginfo.h index 6699c3accac1..684ad91eb8d7 100644 --- a/include/asm-ppc/siginfo.h +++ b/include/asm-ppc/siginfo.h @@ -108,6 +108,7 @@ typedef struct siginfo { #define SI_MESGQ -3 /* sent by real time mesq state change */ #define SI_ASYNCIO -4 /* sent by AIO completion */ #define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h index e707c1a5589a..c2d1e8edd5d8 100644 --- a/include/asm-ppc/unistd.h +++ b/include/asm-ppc/unistd.h @@ -215,6 +215,7 @@ #define __NR_madvise 205 #define __NR_mincore 206 #define __NR_gettid 207 +#define __NR_tkill 208 #define __NR(n) #n diff --git a/include/asm-s390/siginfo.h b/include/asm-s390/siginfo.h index 876e8baaec0a..1a6401075e81 100644 --- a/include/asm-s390/siginfo.h +++ b/include/asm-s390/siginfo.h @@ -115,6 +115,7 @@ typedef struct siginfo { #define SI_MESGQ -3 /* sent by real time mesq state change */ #define SI_ASYNCIO -4 /* sent by AIO completion */ #define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h index 2c5a01426b1f..77ff9ccfb2fd 100644 --- a/include/asm-s390/unistd.h +++ b/include/asm-s390/unistd.h @@ -211,6 +211,8 @@ #define __NR_mincore 218 #define __NR_madvise 219 #define __NR_getdents64 220 +#define __NR_gettid 226 +#define __NR_tkill 227 /* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */ diff --git a/include/asm-s390x/siginfo.h b/include/asm-s390x/siginfo.h index 876e8baaec0a..1a6401075e81 100644 --- a/include/asm-s390x/siginfo.h +++ b/include/asm-s390x/siginfo.h @@ -115,6 +115,7 @@ typedef struct siginfo { #define SI_MESGQ -3 /* sent by real time mesq state change */ #define SI_ASYNCIO -4 /* sent by AIO completion */ #define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) diff --git a/include/asm-s390x/unistd.h b/include/asm-s390x/unistd.h index eeec47819b0b..603864584386 100644 --- a/include/asm-s390x/unistd.h +++ b/include/asm-s390x/unistd.h @@ -181,6 +181,8 @@ #define __NR_mincore 218 #define __NR_madvise 219 #define __NR_getdents64 220 +#define __NR_gettid 226 +#define __NR_tkill 227 /* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */ diff --git a/include/asm-sh/siginfo.h b/include/asm-sh/siginfo.h index aa6a1c46f307..e93ed1a89a4a 100644 --- a/include/asm-sh/siginfo.h +++ b/include/asm-sh/siginfo.h @@ -107,6 +107,7 @@ typedef struct siginfo { #define SI_MESGQ -3 /* sent by real time mesq state change */ #define SI_ASYNCIO -4 /* sent by AIO completion */ #define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h index e5896abec545..a22a81fb3e3c 100644 --- a/include/asm-sh/unistd.h +++ b/include/asm-sh/unistd.h @@ -231,6 +231,8 @@ #define __NR_madvise 219 #define __NR_getdents64 220 #define __NR_fcntl64 221 +#define __NR_gettid 222 +#define __NR_tkill 223 /* user-visible error numbers are in the range -1 - -125: see <asm-sh/errno.h> */ diff --git a/include/asm-sparc/siginfo.h b/include/asm-sparc/siginfo.h index 61e4ef22fc94..816a08a67275 100644 --- a/include/asm-sparc/siginfo.h +++ b/include/asm-sparc/siginfo.h @@ -112,6 +112,7 @@ typedef struct siginfo { #define SI_MESGQ -3 /* sent by real time mesq state change */ #define SI_ASYNCIO -4 /* sent by AIO completion */ #define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index 040ca14cb15e..cbed9be281d4 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h @@ -271,6 +271,7 @@ #define __NR_fdatasync 253 #define __NR_nfsservctl 254 #define __NR_aplib 255 +#define __NR_tkill 257 #define _syscall0(type,name) \ type name(void) \ diff --git a/include/asm-sparc64/siginfo.h b/include/asm-sparc64/siginfo.h index 93f849e8a336..b90c84dc86d3 100644 --- a/include/asm-sparc64/siginfo.h +++ b/include/asm-sparc64/siginfo.h @@ -172,6 +172,7 @@ typedef struct siginfo32 { #define SI_MESGQ -3 /* sent by real time mesq state change */ #define SI_ASYNCIO -4 /* sent by AIO completion */ #define SI_SIGIO -5 /* sent by queued SIGIO */ +#define SI_TKILL -6 /* sent by tkill system call */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) #define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0) diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index 135eb2936520..1b325812c8c7 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h @@ -273,6 +273,7 @@ #define __NR_fdatasync 253 #define __NR_nfsservctl 254 #define __NR_aplib 255 +#define __NR_tkill 256 #define _syscall0(type,name) \ type name(void) \ diff --git a/include/linux/fs.h b/include/linux/fs.h index cdfaac0cdc0e..8e3ce34f39da 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -91,7 +91,6 @@ extern int leases_enable, dir_notify_enable, lease_break_time; #define FS_NO_PRELIM 4 /* prevent preloading of dentries, even if * FS_NO_DCACHE is not set. */ -#define FS_SINGLE 8 /* Filesystem that can have only one superblock */ #define FS_NOMOUNT 16 /* Never mount from userland */ #define FS_LITTER 32 /* Keeps the tree in dcache */ #define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon @@ -208,6 +207,7 @@ extern void update_atime (struct inode *); extern void buffer_init(unsigned long); extern void inode_init(unsigned long); extern void mnt_init(unsigned long); +extern void files_init(unsigned long); /* bh state bits */ enum bh_state_bits { @@ -289,7 +289,6 @@ extern void set_bh_page(struct buffer_head *bh, struct page *page, unsigned long #include <linux/pipe_fs_i.h> /* #include <linux/umsdos_fs_i.h> */ #include <linux/romfs_fs_i.h> -#include <linux/proc_fs_i.h> #include <linux/cramfs_fs_sb.h> /* @@ -455,12 +454,25 @@ struct inode { union { /* struct umsdos_inode_info umsdos_i; */ struct romfs_inode_info romfs_i; - struct proc_inode_info proc_i; - struct socket socket_i; void *generic_ip; } u; }; +struct socket_alloc { + struct socket socket; + struct inode vfs_inode; +}; + +static inline struct socket *SOCKET_I(struct inode *inode) +{ + return &list_entry(inode, struct socket_alloc, vfs_inode)->socket; +} + +static inline struct inode *SOCK_INODE(struct socket *socket) +{ + return &list_entry(socket, struct socket_alloc, socket)->vfs_inode; +} + #include <linux/shmem_fs.h> /* will die */ #include <linux/coda_fs_i.h> @@ -507,6 +519,14 @@ extern int init_private_file(struct file *, struct dentry *, int); #define MAX_NON_LFS ((1UL<<31) - 1) +/* Page cache limit. The filesystems should put that into their s_maxbytes + limits, otherwise bad things can happen in VM. */ +#if BITS_PER_LONG==32 +#define MAX_LFS_FILESIZE (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) +#elif BITS_PER_LONG==64 +#define MAX_LFS_FILESIZE 0x7fffffffffffffff +#endif + #define FL_POSIX 1 #define FL_FLOCK 2 #define FL_BROKEN 4 /* broken flock() emulation */ @@ -914,15 +934,36 @@ struct dquot_operations { int (*transfer) (struct inode *, struct iattr *); }; +/* + * NOTE NOTE NOTE + * + * ->read_super() is going to die. New method (->get_sb) should replace + * it. The only reason why ->read_super() is left for _SHORT_ transition + * period is to avoid a single patch touching every fs. They will be + * converted one-by-one and ONCE THAT IS DONE OR TWO WEEKS HAD PASSED + * (whatever sooner) ->read_super() WILL DISAPPEAR. + */ + struct file_system_type { const char *name; int fs_flags; + struct super_block *(*get_sb) (struct file_system_type *, int, char *, void *); struct super_block *(*read_super) (struct super_block *, void *, int); struct module *owner; struct file_system_type * next; struct list_head fs_supers; }; +struct super_block *get_sb_bdev(struct file_system_type *fs_type, + int flags, char *dev_name, void * data, + int (*fill_super)(struct super_block *, void *, int)); +struct super_block *get_sb_single(struct file_system_type *fs_type, + int flags, void *data, + int (*fill_super)(struct super_block *, void *, int)); +struct super_block *get_sb_nodev(struct file_system_type *fs_type, + int flags, void *data, + int (*fill_super)(struct super_block *, void *, int)); + #define DECLARE_FSTYPE(var,type,read,flags) \ struct file_system_type var = { \ name: type, \ @@ -1449,6 +1490,7 @@ extern ssize_t generic_file_write(struct file *, const char *, size_t, loff_t *) extern void do_generic_file_read(struct file *, loff_t *, read_descriptor_t *, read_actor_t); extern loff_t no_llseek(struct file *file, loff_t offset, int origin); extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin); +extern loff_t remote_llseek(struct file *file, loff_t offset, int origin); extern ssize_t generic_read_dir(struct file *, char *, size_t, loff_t *); extern int generic_file_open(struct inode * inode, struct file * filp); @@ -1463,6 +1505,10 @@ extern struct inode_operations page_symlink_inode_operations; extern int vfs_readdir(struct file *, filldir_t, void *); extern int dcache_readdir(struct file *, void *, filldir_t); +extern int vfs_stat(char *, struct kstat *); +extern int vfs_lstat(char *, struct kstat *); +extern int vfs_fstat(unsigned int, struct kstat *); + extern struct file_system_type *get_fs_type(const char *name); extern struct super_block *get_super(kdev_t); extern void drop_super(struct super_block *sb); @@ -1475,8 +1521,6 @@ static inline int is_mounted(kdev_t dev) } return 0; } -unsigned long generate_cluster(kdev_t, int b[], int); -unsigned long generate_cluster_swab32(kdev_t, int b[], int); extern kdev_t ROOT_DEV; extern char root_device_name[]; diff --git a/include/linux/hpfs_fs_sb.h b/include/linux/hpfs_fs_sb.h index 9059054cf82d..068035e9a4bd 100644 --- a/include/linux/hpfs_fs_sb.h +++ b/include/linux/hpfs_fs_sb.h @@ -30,9 +30,8 @@ struct hpfs_sb_info { /* 128 bytes lowercasing table */ unsigned *sb_bmp_dir; /* main bitmap directory */ unsigned sb_c_bitmap; /* current bitmap */ - wait_queue_head_t sb_creation_de;/* when creating dirents, nobody else + struct semaphore hpfs_creation_de; /* when creating dirents, nobody else can alloc blocks */ - unsigned sb_creation_de_lock : 1; /*unsigned sb_mounting : 1;*/ int sb_timeshift; }; @@ -60,8 +59,6 @@ struct hpfs_sb_info { #define s_hpfs_cp_table u.hpfs_sb.sb_cp_table #define s_hpfs_bmp_dir u.hpfs_sb.sb_bmp_dir #define s_hpfs_c_bitmap u.hpfs_sb.sb_c_bitmap -#define s_hpfs_creation_de u.hpfs_sb.sb_creation_de -#define s_hpfs_creation_de_lock u.hpfs_sb.sb_creation_de_lock #define s_hpfs_iget_q u.hpfs_sb.sb_iget_q /*#define s_hpfs_mounting u.hpfs_sb.sb_mounting*/ #define s_hpfs_timeshift u.hpfs_sb.sb_timeshift diff --git a/include/linux/net.h b/include/linux/net.h index 39493fc2e265..8cd440ce36d6 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -23,6 +23,7 @@ #include <linux/wait.h> struct poll_table_struct; +struct inode; #define NPROTO 32 /* should be enough for now.. */ @@ -68,7 +69,6 @@ struct socket unsigned long flags; struct proto_ops *ops; - struct inode *inode; struct fasync_struct *fasync_list; /* Asynchronous wake up list */ struct file *file; /* File back pointer for gc */ struct sock *sk; @@ -78,8 +78,6 @@ struct socket unsigned char passcred; }; -#define SOCK_INODE(S) ((S)->inode) - struct scm_cookie; struct vm_area_struct; struct page; diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index eda80eca898e..e95a085a2fdd 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -226,7 +226,6 @@ unsigned long page_index(struct page *page) /* * linux/fs/nfs/inode.c */ -extern struct super_block *nfs_read_super(struct super_block *, void *, int); extern void nfs_zap_caches(struct inode *); extern int nfs_inode_is_stale(struct inode *, struct nfs_fh *, struct nfs_fattr *); diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 4688c8c90ede..5c0a4642fd69 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -97,7 +97,7 @@ extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent); extern struct vfsmount *proc_mnt; -extern struct super_block *proc_read_super(struct super_block *,void *,int); +extern int proc_fill_super(struct super_block *,void *,int); extern struct inode * proc_get_inode(struct super_block *, int, struct proc_dir_entry *); extern int proc_match(int, const char *,struct proc_dir_entry *); @@ -205,4 +205,26 @@ extern struct proc_dir_entry proc_root; #endif /* CONFIG_PROC_FS */ +struct proc_inode { + struct task_struct *task; + int type; + union { + int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **); + int (*proc_read)(struct task_struct *task, char *page); + } op; + struct file *file; + struct proc_dir_entry *pde; + struct inode vfs_inode; +}; + +static inline struct proc_inode *PROC_I(struct inode *inode) +{ + return list_entry(inode, struct proc_inode, vfs_inode); +} + +static inline struct proc_dir_entry *PDE(struct inode *inode) +{ + return PROC_I(inode)->pde; +} + #endif /* _LINUX_PROC_FS_H */ diff --git a/include/linux/proc_fs_i.h b/include/linux/proc_fs_i.h deleted file mode 100644 index d4bde0989084..000000000000 --- a/include/linux/proc_fs_i.h +++ /dev/null @@ -1,9 +0,0 @@ -struct proc_inode_info { - struct task_struct *task; - int type; - union { - int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **); - int (*proc_read)(struct task_struct *task, char *page); - } op; - struct file *file; -}; diff --git a/include/linux/sched.h b/include/linux/sched.h index 6805d6ae39df..5d3f7b02ce08 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -564,6 +564,7 @@ extern int in_egroup_p(gid_t); extern void proc_caches_init(void); extern void flush_signals(struct task_struct *); extern void flush_signal_handlers(struct task_struct *); +extern void sig_exit(int, int, struct siginfo *); extern int dequeue_signal(sigset_t *, siginfo_t *); extern void block_all_signals(int (*notifier)(void *priv), void *priv, sigset_t *mask); @@ -839,9 +840,14 @@ do { \ #define for_each_task(p) \ for (p = &init_task ; (p = p->next_task) != &init_task ; ) +#define for_each_thread(task) \ + for (task = next_thread(current) ; task != current ; task = next_thread(task)) + #define next_thread(p) \ list_entry((p)->thread_group.next, struct task_struct, thread_group) +#define thread_group_leader(p) (p->pid == p->tgid) + static inline void unhash_process(struct task_struct *p) { write_lock_irq(&tasklist_lock); diff --git a/include/linux/stat.h b/include/linux/stat.h index e43e241f31cb..d78a416a3a39 100644 --- a/include/linux/stat.h +++ b/include/linux/stat.h @@ -52,6 +52,25 @@ #define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH) #define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH) #define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH) + +#include <linux/types.h> + +struct kstat { + unsigned long ino; + dev_t dev; + umode_t mode; + nlink_t nlink; + uid_t uid; + gid_t gid; + dev_t rdev; + loff_t size; + time_t atime; + time_t mtime; + time_t ctime; + unsigned long blksize; + unsigned long blocks; +}; + #endif #endif diff --git a/include/linux/usb.h b/include/linux/usb.h index 4c5837e684cd..d598c720ad2d 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -857,7 +857,7 @@ extern struct urb *usb_alloc_urb(int iso_packets); extern void usb_free_urb(struct urb *urb); #define usb_put_urb usb_free_urb extern struct urb *usb_get_urb(struct urb *urb); -extern int usb_submit_urb(struct urb *urb); +extern int usb_submit_urb(struct urb *urb, int mem_flags); extern int usb_unlink_urb(struct urb *urb); /*-------------------------------------------------------------------* @@ -906,7 +906,7 @@ struct usb_operations { int (*allocate)(struct usb_device *); int (*deallocate)(struct usb_device *); int (*get_frame_number) (struct usb_device *usb_dev); - int (*submit_urb) (struct urb *urb); + int (*submit_urb) (struct urb *urb, int mem_flags); int (*unlink_urb) (struct urb *urb); }; diff --git a/linux/zconf.h b/include/linux/zconf.h index 0b5ec883812b..0b5ec883812b 100644 --- a/linux/zconf.h +++ b/include/linux/zconf.h diff --git a/linux/zutil.h b/include/linux/zutil.h index a4a4d8d75f1e..a4a4d8d75f1e 100644 --- a/linux/zutil.h +++ b/include/linux/zutil.h diff --git a/include/net/sock.h b/include/net/sock.h index e4b723ca4545..c5e1646d8f75 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1022,7 +1022,7 @@ static inline int sock_i_uid(struct sock *sk) int uid; read_lock(&sk->callback_lock); - uid = sk->socket ? sk->socket->inode->i_uid : 0; + uid = sk->socket ? SOCK_INODE(sk->socket)->i_uid : 0; read_unlock(&sk->callback_lock); return uid; } @@ -1032,7 +1032,7 @@ static inline unsigned long sock_i_ino(struct sock *sk) unsigned long ino; read_lock(&sk->callback_lock); - ino = sk->socket ? sk->socket->inode->i_ino : 0; + ino = sk->socket ? SOCK_INODE(sk->socket)->i_ino : 0; read_unlock(&sk->callback_lock); return ino; } diff --git a/kernel/fork.c b/kernel/fork.c index 8c10cad0e021..bfbae1b15439 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -724,10 +724,10 @@ int do_fork(unsigned long clone_flags, unsigned long stack_start, /* Need tasklist lock for parent etc handling! */ write_lock_irq(&tasklist_lock); - /* CLONE_PARENT and CLONE_THREAD re-use the old parent */ + /* CLONE_PARENT re-uses the old parent */ p->p_opptr = current->p_opptr; p->p_pptr = current->p_pptr; - if (!(clone_flags & (CLONE_PARENT | CLONE_THREAD))) { + if (!(clone_flags & CLONE_PARENT)) { p->p_opptr = current; if (!(p->ptrace & PT_PTRACED)) p->p_pptr = current; diff --git a/kernel/ksyms.c b/kernel/ksyms.c index c271a8e6f6fc..42ebfe7f746c 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -251,6 +251,7 @@ EXPORT_SYMBOL(vfs_rename); EXPORT_SYMBOL(vfs_statfs); EXPORT_SYMBOL(generic_read_dir); EXPORT_SYMBOL(generic_file_llseek); +EXPORT_SYMBOL(remote_llseek); EXPORT_SYMBOL(no_llseek); EXPORT_SYMBOL(__pollwait); EXPORT_SYMBOL(poll_freewait); @@ -274,6 +275,9 @@ EXPORT_SYMBOL(lock_may_write); EXPORT_SYMBOL(dcache_readdir); EXPORT_SYMBOL(fd_install); EXPORT_SYMBOL(put_unused_fd); +EXPORT_SYMBOL(get_sb_bdev); +EXPORT_SYMBOL(get_sb_nodev); +EXPORT_SYMBOL(get_sb_single); /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ EXPORT_SYMBOL(default_llseek); diff --git a/kernel/signal.c b/kernel/signal.c index 3741c8a4a6ac..d648cff08eb6 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -142,6 +142,35 @@ flush_signal_handlers(struct task_struct *t) } } +/* + * sig_exit - cause the current task to exit due to a signal. + */ + +void +sig_exit(int sig, int exit_code, struct siginfo *info) +{ + struct task_struct *t; + + sigaddset(¤t->pending.signal, sig); + recalc_sigpending(current); + current->flags |= PF_SIGNALED; + + /* Propagate the signal to all the tasks in + * our thread group + */ + if (info && (unsigned long)info != 1 + && info->si_code != SI_TKILL) { + read_lock(&tasklist_lock); + for_each_thread(t) { + force_sig_info(sig, info, t); + } + read_unlock(&tasklist_lock); + } + + do_exit(exit_code); + /* NOTREACHED */ +} + /* Notify the system that a driver wants to block all signals for this * process, and wants to be notified if any signals at all were to be * sent/acted upon. If the notifier routine returns non-zero, then the @@ -589,7 +618,7 @@ kill_pg_info(int sig, struct siginfo *info, pid_t pgrp) retval = -ESRCH; read_lock(&tasklist_lock); for_each_task(p) { - if (p->pgrp == pgrp) { + if (p->pgrp == pgrp && thread_group_leader(p)) { int err = send_sig_info(sig, info, p); if (retval) retval = err; @@ -636,8 +665,15 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid) read_lock(&tasklist_lock); p = find_task_by_pid(pid); error = -ESRCH; - if (p) + if (p) { + if (!thread_group_leader(p)) { + struct task_struct *tg; + tg = find_task_by_pid(p->tgid); + if (tg) + p = tg; + } error = send_sig_info(sig, info, p); + } read_unlock(&tasklist_lock); return error; } @@ -660,7 +696,7 @@ static int kill_something_info(int sig, struct siginfo *info, int pid) read_lock(&tasklist_lock); for_each_task(p) { - if (p->pid > 1 && p != current) { + if (p->pid > 1 && p != current && thread_group_leader(p)) { int err = send_sig_info(sig, info, p); ++count; if (err != -EPERM) @@ -985,6 +1021,36 @@ sys_kill(int pid, int sig) return kill_something_info(sig, &info, pid); } +/* + * Kill only one task, even if it's a CLONE_THREAD task. + */ +asmlinkage long +sys_tkill(int pid, int sig) +{ + struct siginfo info; + int error; + struct task_struct *p; + + /* This is only valid for single tasks */ + if (pid <= 0) + return -EINVAL; + + info.si_signo = sig; + info.si_errno = 0; + info.si_code = SI_TKILL; + info.si_pid = current->pid; + info.si_uid = current->uid; + + read_lock(&tasklist_lock); + p = find_task_by_pid(pid); + error = -ESRCH; + if (p) { + error = send_sig_info(sig, &info, p); + } + read_unlock(&tasklist_lock); + return error; +} + asmlinkage long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo) { diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 9035ae798d0e..21a5c8fe6543 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -677,7 +677,7 @@ static ssize_t do_rw_proc(int write, struct file * file, char * buf, size_t res; ssize_t error; - de = (struct proc_dir_entry*) file->f_dentry->d_inode->u.generic_ip; + de = PDE(file->f_dentry->d_inode); if (!de || !de->data) return -ENOTDIR; table = (struct ctl_table *) de->data; diff --git a/mm/bootmem.c b/mm/bootmem.c index 3b0420d653cb..5027b2892471 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -247,19 +247,30 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat) bootmem_data_t *bdata = pgdat->bdata; unsigned long i, count, total = 0; unsigned long idx; + unsigned long *map; if (!bdata->node_bootmem_map) BUG(); count = 0; idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT); - for (i = 0; i < idx; i++, page++) { - if (!test_bit(i, bdata->node_bootmem_map)) { + map = bdata->node_bootmem_map; + for (i = 0; i < idx; ) { + unsigned long v = ~map[i / BITS_PER_LONG]; + if (v) { + unsigned long m; + for (m = 1; m && i < idx; m<<=1, page++, i++) { + if (v & m) { count++; ClearPageReserved(page); set_page_count(page, 1); __free_page(page); } } + } else { + i+=BITS_PER_LONG; + page+=BITS_PER_LONG; + } + } total += count; /* diff --git a/mm/shmem.c b/mm/shmem.c index a32676791b05..ac105cc17d04 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1267,7 +1267,7 @@ int shmem_sync_file(struct file * file, struct dentry *dentry, int datasync) } #endif -static struct super_block *shmem_read_super(struct super_block * sb, void * data, int silent) +static int shmem_fill_super(struct super_block * sb, void * data, int silent) { struct inode * inode; struct dentry * root; @@ -1286,7 +1286,7 @@ static struct super_block *shmem_read_super(struct super_block * sb, void * data #ifdef CONFIG_TMPFS if (shmem_parse_options (data, &mode, &blocks, &inodes)) { printk(KERN_ERR "tmpfs invalid option\n"); - return NULL; + return -EINVAL; } #endif @@ -1302,15 +1302,15 @@ static struct super_block *shmem_read_super(struct super_block * sb, void * data sb->s_op = &shmem_ops; inode = shmem_get_inode(sb, S_IFDIR | mode, 0); if (!inode) - return NULL; + return -ENOMEM; root = d_alloc_root(inode); if (!root) { iput(inode); - return NULL; + return -ENOMEM; } sb->s_root = root; - return sb; + return 0; } static kmem_cache_t * shmem_inode_cachep; @@ -1410,12 +1410,33 @@ static struct vm_operations_struct shmem_vm_ops = { nopage: shmem_nopage, }; +static struct super_block *shmem_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_nodev(fs_type, flags, data, shmem_fill_super); +} + #ifdef CONFIG_TMPFS /* type "shm" will be tagged obsolete in 2.5 */ -static DECLARE_FSTYPE(shmem_fs_type, "shm", shmem_read_super, FS_LITTER); -static DECLARE_FSTYPE(tmpfs_fs_type, "tmpfs", shmem_read_super, FS_LITTER); +static struct file_system_type shmem_fs_type = { + owner: THIS_MODULE, + name: "shmem", + get_sb: shmem_get_sb, + fs_flags: FS_LITTER, +}; +static struct file_system_type tmpfs_fs_type = { + owner: THIS_MODULE, + name: "tmpfs", + get_sb: shmem_get_sb, + fs_flags: FS_LITTER, +}; #else -static DECLARE_FSTYPE(tmpfs_fs_type, "tmpfs", shmem_read_super, FS_LITTER|FS_NOMOUNT); +static struct file_system_type tmpfs_fs_type = { + owner: THIS_MODULE, + name: "tmpfs", + get_sb: shmem_get_sb, + fs_flags: FS_LITTER|FS_NOMOUNT, +}; #endif static struct vfsmount *shm_mnt; diff --git a/mm/slab.c b/mm/slab.c index 8219181090a4..9835c232b066 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -186,8 +186,6 @@ typedef struct cpucache_s { * manages a cache. */ -#define CACHE_NAMELEN 20 /* max name length for a slab cache */ - struct kmem_cache_s { /* 1) each alloc & free */ /* full, partial first, then free */ @@ -225,7 +223,7 @@ struct kmem_cache_s { unsigned long failures; /* 3) cache creation/removal */ - char name[CACHE_NAMELEN]; + const char *name; struct list_head next; #ifdef CONFIG_SMP /* 4) per-cpu data */ @@ -335,6 +333,7 @@ typedef struct cache_sizes { kmem_cache_t *cs_dmacachep; } cache_sizes_t; +/* These are the default caches for kmalloc. Custom caches can have other sizes. */ static cache_sizes_t cache_sizes[] = { #if PAGE_SIZE == 4096 { 32, NULL, NULL}, @@ -353,6 +352,29 @@ static cache_sizes_t cache_sizes[] = { {131072, NULL, NULL}, { 0, NULL, NULL} }; +/* Must match cache_sizes above. Out of line to keep cache footprint low. */ +#define CN(x) { x, x " (DMA)" } +static struct { + char *name; + char *name_dma; +} cache_names[] = { +#if PAGE_SIZE == 4096 + CN("size-32"), +#endif + CN("size-64"), + CN("size-128"), + CN("size-256"), + CN("size-512"), + CN("size-1024"), + CN("size-2048"), + CN("size-4096"), + CN("size-8192"), + CN("size-16384"), + CN("size-32768"), + CN("size-65536"), + CN("size-131072") +}; +#undef CN /* internal cache of cache description objs */ static kmem_cache_t cache_cache = { @@ -437,7 +459,6 @@ void __init kmem_cache_init(void) void __init kmem_cache_sizes_init(void) { cache_sizes_t *sizes = cache_sizes; - char name[20]; /* * Fragmentation resistance on low memory - only use bigger * page orders on machines with more than 32MB of memory. @@ -450,9 +471,9 @@ void __init kmem_cache_sizes_init(void) * eliminates "false sharing". * Note for systems short on memory removing the alignment will * allow tighter packing of the smaller caches. */ - sprintf(name,"size-%Zd",sizes->cs_size); if (!(sizes->cs_cachep = - kmem_cache_create(name, sizes->cs_size, + kmem_cache_create(cache_names[sizes-cache_sizes].name, + sizes->cs_size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL))) { BUG(); } @@ -462,9 +483,10 @@ void __init kmem_cache_sizes_init(void) offslab_limit = sizes->cs_size-sizeof(slab_t); offslab_limit /= 2; } - sprintf(name, "size-%Zd(DMA)",sizes->cs_size); - sizes->cs_dmacachep = kmem_cache_create(name, sizes->cs_size, 0, - SLAB_CACHE_DMA|SLAB_HWCACHE_ALIGN, NULL, NULL); + sizes->cs_dmacachep = kmem_cache_create( + cache_names[sizes-cache_sizes].name_dma, + sizes->cs_size, 0, + SLAB_CACHE_DMA|SLAB_HWCACHE_ALIGN, NULL, NULL); if (!sizes->cs_dmacachep) BUG(); sizes++; @@ -604,6 +626,11 @@ static void kmem_slab_destroy (kmem_cache_t *cachep, slab_t *slabp) * Cannot be called within a int, but can be interrupted. * The @ctor is run when new pages are allocated by the cache * and the @dtor is run before the pages are handed back. + * + * @name must be valid until the cache is destroyed. This implies that + * the module calling this has to destroy the cache before getting + * unloaded. + * * The flags are * * %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5) @@ -632,7 +659,6 @@ kmem_cache_create (const char *name, size_t size, size_t offset, * Sanity checks... these are all serious usage bugs. */ if ((!name) || - ((strlen(name) >= CACHE_NAMELEN - 1)) || in_interrupt() || (size < BYTES_PER_WORD) || (size > (1<<MAX_OBJ_ORDER)*PAGE_SIZE) || @@ -797,8 +823,7 @@ next: cachep->slabp_cache = kmem_find_general_cachep(slab_size,0); cachep->ctor = ctor; cachep->dtor = dtor; - /* Copy name over so we don't have problems with unloaded modules */ - strcpy(cachep->name, name); + cachep->name = name; #ifdef CONFIG_SMP if (g_cpucache_up) @@ -811,10 +836,20 @@ next: list_for_each(p, &cache_chain) { kmem_cache_t *pc = list_entry(p, kmem_cache_t, next); - - /* The name field is constant - no lock needed. */ - if (!strcmp(pc->name, name)) - BUG(); + char tmp; + /* This happens when the module gets unloaded and doesn't + destroy its slab cache and noone else reuses the vmalloc + area of the module. Print a warning. */ + if (__get_user(tmp,pc->name)) { + printk("SLAB: cache with size %d has lost its name\n", + pc->objsize); + continue; + } + if (!strcmp(pc->name,name)) { + printk("kmem_cache_create: duplicate cache %s\n",name); + up(&cache_chain_sem); + BUG(); + } } } @@ -1878,6 +1913,7 @@ static int proc_getdata (char*page, char**start, off_t off, int count) unsigned long num_objs; unsigned long active_slabs = 0; unsigned long num_slabs; + const char *name; cachep = list_entry(p, kmem_cache_t, next); spin_lock_irq(&cachep->spinlock); @@ -1906,8 +1942,15 @@ static int proc_getdata (char*page, char**start, off_t off, int count) num_slabs+=active_slabs; num_objs = num_slabs*cachep->num; + name = cachep->name; + { + char tmp; + if (__get_user(tmp, name)) + name = "broken"; + } + len += sprintf(page+len, "%-17s %6lu %6lu %6u %4lu %4lu %4u", - cachep->name, active_objs, num_objs, cachep->objsize, + name, active_objs, num_objs, cachep->objsize, active_slabs, num_slabs, (1<<cachep->gfporder)); #if STATS diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index 5c994e1a1257..c8482f9ab40f 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c @@ -236,7 +236,7 @@ static ssize_t vlan_proc_read(struct file *file, char *buf, if (count <= 0) return 0; - dent = inode->u.generic_ip; + dent = PDE(inode); if ((dent == NULL) || (dent->get_info == NULL)) return 0; diff --git a/net/atm/proc.c b/net/atm/proc.c index 3fdd52372ea0..e19a6a69a0a4 100644 --- a/net/atm/proc.c +++ b/net/atm/proc.c @@ -498,8 +498,7 @@ static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count, if (count == 0) return 0; page = get_free_page(GFP_KERNEL); if (!page) return -ENOMEM; - dev = ((struct proc_dir_entry *) file->f_dentry->d_inode->u.generic_ip) - ->data; + dev = PDE(file->f_dentry->d_inode)->data; if (!dev->ops->proc_read) length = -EINVAL; else { @@ -521,8 +520,7 @@ static ssize_t proc_spec_atm_read(struct file *file,char *buf,size_t count, unsigned long page; int length; int (*info)(loff_t,char *); - info = ((struct proc_dir_entry *) file->f_dentry->d_inode->u.generic_ip) - ->data; + info = PDE(file->f_dentry->d_inode)->data; if (count == 0) return 0; page = get_free_page(GFP_KERNEL); diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 59e1cf120b58..7b7374c9d81f 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -1756,7 +1756,7 @@ static int ax25_get_info(char *buffer, char **start, off_t offset, int length) len += sprintf(buffer + len, " %d %d %ld\n", atomic_read(&ax25->sk->wmem_alloc), atomic_read(&ax25->sk->rmem_alloc), - ax25->sk->socket != NULL ? ax25->sk->socket->inode->i_ino : 0L); + ax25->sk->socket != NULL ? SOCK_INODE(ax25->sk->socket)->i_ino : 0L); } else { len += sprintf(buffer + len, " * * *\n"); } diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index d0ddcde24ce9..97bfcda70b3f 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -637,21 +637,11 @@ int __init icmpv6_init(struct net_proto_family *ops) struct sock *sk; int err; - icmpv6_socket = sock_alloc(); - if (icmpv6_socket == NULL) { - printk(KERN_ERR - "Failed to create the ICMP6 control socket.\n"); - return -1; - } - icmpv6_socket->inode->i_uid = 0; - icmpv6_socket->inode->i_gid = 0; - icmpv6_socket->type = SOCK_RAW; - - if ((err = ops->create(icmpv6_socket, IPPROTO_ICMPV6)) < 0) { + err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &icmpv6_socket); + if (err < 0) { printk(KERN_ERR "Failed to initialize the ICMP6 control socket (err %d).\n", err); - sock_release(icmpv6_socket); icmpv6_socket = NULL; /* for safety */ return err; } diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 3d243fabd47a..6dcfb30fadda 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -751,21 +751,11 @@ int __init igmp6_init(struct net_proto_family *ops) struct sock *sk; int err; - igmp6_socket = sock_alloc(); - if (igmp6_socket == NULL) { + err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &igmp6_socket); + if (err < 0) { printk(KERN_ERR - "Failed to create the IGMP6 control socket.\n"); - return -1; - } - igmp6_socket->inode->i_uid = 0; - igmp6_socket->inode->i_gid = 0; - igmp6_socket->type = SOCK_RAW; - - if((err = ops->create(igmp6_socket, IPPROTO_ICMPV6)) < 0) { - printk(KERN_DEBUG "Failed to initialize the IGMP6 control socket (err %d).\n", err); - sock_release(igmp6_socket); igmp6_socket = NULL; /* For safety. */ return err; } diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 838f7eebc396..658f559e6ac7 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1214,21 +1214,11 @@ int __init ndisc_init(struct net_proto_family *ops) struct sock *sk; int err; - ndisc_socket = sock_alloc(); - if (ndisc_socket == NULL) { + err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &ndisc_socket); + if (err < 0) { printk(KERN_ERR - "Failed to create the NDISC control socket.\n"); - return -1; - } - ndisc_socket->inode->i_uid = 0; - ndisc_socket->inode->i_gid = 0; - ndisc_socket->type = SOCK_RAW; - - if((err = ops->create(ndisc_socket, IPPROTO_ICMPV6)) < 0) { - printk(KERN_DEBUG "Failed to initialize the NDISC control socket (err %d).\n", err); - sock_release(ndisc_socket); ndisc_socket = NULL; /* For safety. */ return err; } diff --git a/net/netlink/netlink_dev.c b/net/netlink/netlink_dev.c index 8c13461ed29a..a5bb25ab5089 100644 --- a/net/netlink/netlink_dev.c +++ b/net/netlink/netlink_dev.c @@ -98,11 +98,6 @@ static ssize_t netlink_read(struct file * file, char * buf, return sock_recvmsg(sock, &msg, count, msg.msg_flags); } -static loff_t netlink_lseek(struct file * file, loff_t offset, int origin) -{ - return -ESPIPE; -} - static int netlink_open(struct inode * inode, struct file * file) { unsigned int minor = minor(inode->i_rdev); @@ -166,7 +161,7 @@ static int netlink_ioctl(struct inode *inode, struct file *file, static struct file_operations netlink_fops = { owner: THIS_MODULE, - llseek: netlink_lseek, + llseek: no_llseek, read: netlink_read, write: netlink_write, poll: netlink_poll, diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index f37bb2433e26..3c6f247a5305 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -1204,7 +1204,7 @@ static int nr_get_info(char *buffer, char **start, off_t offset, int length) s->protinfo.nr->window, atomic_read(&s->wmem_alloc), atomic_read(&s->rmem_alloc), - s->socket != NULL ? s->socket->inode->i_ino : 0L); + s->socket != NULL ? SOCK_INODE(s->socket)->i_ino : 0L); pos = begin + len; diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index a0ae47666a30..272d42608490 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1575,7 +1575,7 @@ static void packet_mm_open(struct vm_area_struct *vma) { struct file *file = vma->vm_file; struct inode *inode = file->f_dentry->d_inode; - struct socket * sock = &inode->u.socket_i; + struct socket * sock = SOCKET_I(inode); struct sock *sk = sock->sk; if (sk) @@ -1586,7 +1586,7 @@ static void packet_mm_close(struct vm_area_struct *vma) { struct file *file = vma->vm_file; struct inode *inode = file->f_dentry->d_inode; - struct socket * sock = &inode->u.socket_i; + struct socket * sock = SOCKET_I(inode); struct sock *sk = sock->sk; if (sk) diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index d721721e8d8e..957315f805c4 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -1370,7 +1370,7 @@ static int rose_get_info(char *buffer, char **start, off_t offset, int length) s->protinfo.rose->idle / (60 * HZ), atomic_read(&s->wmem_alloc), atomic_read(&s->rmem_alloc), - s->socket != NULL ? s->socket->inode->i_ino : 0L); + s->socket != NULL ? SOCK_INODE(s->socket)->i_ino : 0L); pos = begin + len; diff --git a/net/socket.c b/net/socket.c index 0be746b10e8a..2965aa8d0f49 100644 --- a/net/socket.c +++ b/net/socket.c @@ -86,7 +86,6 @@ #include <linux/netfilter.h> static int sock_no_open(struct inode *irrelevant, struct file *dontcare); -static loff_t sock_lseek(struct file *file, loff_t offset, int whence); static ssize_t sock_read(struct file *file, char *buf, size_t size, loff_t *ppos); static ssize_t sock_write(struct file *file, const char *buf, @@ -113,7 +112,7 @@ static ssize_t sock_sendpage(struct file *file, struct page *page, */ static struct file_operations socket_file_ops = { - llseek: sock_lseek, + llseek: no_llseek, read: sock_read, write: sock_write, poll: sock_poll, @@ -272,36 +271,87 @@ static int sockfs_statfs(struct super_block *sb, struct statfs *buf) return 0; } +static kmem_cache_t * sock_inode_cachep; + +static struct inode *sock_alloc_inode(struct super_block *sb) +{ + struct socket_alloc *ei; + ei = (struct socket_alloc *)kmem_cache_alloc(sock_inode_cachep, SLAB_KERNEL); + if (!ei) + return NULL; + init_waitqueue_head(&ei->socket.wait); + return &ei->vfs_inode; +} + +static void sock_destroy_inode(struct inode *inode) +{ + kmem_cache_free(sock_inode_cachep, + list_entry(inode, struct socket_alloc, vfs_inode)); +} + +static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +{ + struct socket_alloc *ei = (struct socket_alloc *) foo; + + if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == + SLAB_CTOR_CONSTRUCTOR) + inode_init_once(&ei->vfs_inode); +} + +static int init_inodecache(void) +{ + sock_inode_cachep = kmem_cache_create("sock_inode_cache", + sizeof(struct socket_alloc), + 0, SLAB_HWCACHE_ALIGN, + init_once, NULL); + if (sock_inode_cachep == NULL) + return -ENOMEM; + return 0; +} + static struct super_operations sockfs_ops = { + alloc_inode: sock_alloc_inode, + destroy_inode: sock_destroy_inode, statfs: sockfs_statfs, }; -static struct super_block * sockfs_read_super(struct super_block *sb, void *data, int silent) +static int sockfs_fill_super(struct super_block *sb, void *data, int silent) { struct inode *root; sb->s_blocksize = 1024; sb->s_blocksize_bits = 10; sb->s_magic = SOCKFS_MAGIC; - sb->s_op = &sockfs_ops; + sb->s_op = &sockfs_ops; root = new_inode(sb); if (!root) - return NULL; + return -ENOMEM; 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_root = d_alloc(NULL, &(const struct qstr) { "socket:", 7, 0 }); if (!sb->s_root) { iput(root); - return NULL; + return -ENOMEM; } sb->s_root->d_sb = sb; sb->s_root->d_parent = sb->s_root; d_instantiate(sb->s_root, root); - return sb; + return 0; +} + +static struct super_block *sockfs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_nodev(fs_type, flags, data, sockfs_fill_super); } static struct vfsmount *sock_mnt; -static DECLARE_FSTYPE(sock_fs_type, "sockfs", sockfs_read_super, FS_NOMOUNT); + +static struct file_system_type sock_fs_type = { + name: "sockfs", + get_sb: sockfs_get_sb, + fs_flags: FS_NOMOUNT, +}; static int sockfs_delete_dentry(struct dentry *dentry) { return 1; @@ -347,10 +397,10 @@ static int sock_map_fd(struct socket *sock) goto out; } - sprintf(name, "[%lu]", sock->inode->i_ino); + sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino); this.name = name; this.len = strlen(name); - this.hash = sock->inode->i_ino; + this.hash = SOCK_INODE(sock)->i_ino; file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this); if (!file->f_dentry) { @@ -360,11 +410,11 @@ static int sock_map_fd(struct socket *sock) goto out; } file->f_dentry->d_op = &sockfs_dentry_operations; - d_add(file->f_dentry, sock->inode); + d_add(file->f_dentry, SOCK_INODE(sock)); file->f_vfsmnt = mntget(sock_mnt); sock->file = file; - file->f_op = sock->inode->i_fop = &socket_file_ops; + file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops; file->f_mode = 3; file->f_flags = O_RDWR; file->f_pos = 0; @@ -375,11 +425,6 @@ out: return fd; } -extern __inline__ struct socket *socki_lookup(struct inode *inode) -{ - return &inode->u.socket_i; -} - /** * sockfd_lookup - Go from a file number to its socket slot * @fd: file handle @@ -406,7 +451,7 @@ struct socket *sockfd_lookup(int fd, int *err) } inode = file->f_dentry->d_inode; - if (!inode->i_sock || !(sock = socki_lookup(inode))) + if (!inode->i_sock || !(sock = SOCKET_I(inode))) { *err = -ENOTSOCK; fput(file); @@ -443,15 +488,13 @@ struct socket *sock_alloc(void) return NULL; inode->i_dev = NODEV; - sock = socki_lookup(inode); + sock = SOCKET_I(inode); inode->i_mode = S_IFSOCK|S_IRWXUGO; inode->i_sock = 1; inode->i_uid = current->fsuid; inode->i_gid = current->fsgid; - sock->inode = inode; - init_waitqueue_head(&sock->wait); sock->fasync_list = NULL; sock->state = SS_UNCONNECTED; sock->flags = 0; @@ -493,7 +536,7 @@ void sock_release(struct socket *sock) sockets_in_use[smp_processor_id()].counter--; if (!sock->file) { - iput(sock->inode); + iput(SOCK_INODE(sock)); return; } sock->file=NULL; @@ -527,15 +570,6 @@ int sock_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags) /* - * Sockets are not seekable. - */ - -static loff_t sock_lseek(struct file *file, loff_t offset, int whence) -{ - return -ESPIPE; -} - -/* * Read data from a socket. ubuf is a user mode pointer. We make sure the user * area ubuf...ubuf+size-1 is writable before asking the protocol. */ @@ -553,7 +587,7 @@ static ssize_t sock_read(struct file *file, char *ubuf, if (size==0) /* Match SYS5 behaviour */ return 0; - sock = socki_lookup(file->f_dentry->d_inode); + sock = SOCKET_I(file->f_dentry->d_inode); msg.msg_name=NULL; msg.msg_namelen=0; @@ -586,7 +620,7 @@ static ssize_t sock_write(struct file *file, const char *ubuf, if(size==0) /* Match SYS5 behaviour */ return 0; - sock = socki_lookup(file->f_dentry->d_inode); + sock = SOCKET_I(file->f_dentry->d_inode); msg.msg_name=NULL; msg.msg_namelen=0; @@ -612,7 +646,7 @@ ssize_t sock_sendpage(struct file *file, struct page *page, if (ppos != &file->f_pos) return -ESPIPE; - sock = socki_lookup(file->f_dentry->d_inode); + sock = SOCKET_I(file->f_dentry->d_inode); flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT; if (more) @@ -627,7 +661,7 @@ int sock_readv_writev(int type, struct inode * inode, struct file * file, struct msghdr msg; struct socket *sock; - sock = socki_lookup(inode); + sock = SOCKET_I(inode); msg.msg_name = NULL; msg.msg_namelen = 0; @@ -681,7 +715,7 @@ int sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd, int err; unlock_kernel(); - sock = socki_lookup(inode); + sock = SOCKET_I(inode); err = sock->ops->ioctl(sock, cmd, arg); lock_kernel(); @@ -697,13 +731,13 @@ static unsigned int sock_poll(struct file *file, poll_table * wait) /* * We can't return errors to poll, so it's either yes or no. */ - sock = socki_lookup(file->f_dentry->d_inode); + sock = SOCKET_I(file->f_dentry->d_inode); return sock->ops->poll(file, sock, wait); } static int sock_mmap(struct file * file, struct vm_area_struct * vma) { - struct socket *sock = socki_lookup(file->f_dentry->d_inode); + struct socket *sock = SOCKET_I(file->f_dentry->d_inode); return sock->ops->mmap(file, sock, vma); } @@ -721,7 +755,7 @@ int sock_close(struct inode *inode, struct file *filp) return 0; } sock_fasync(-1, filp, 0); - sock_release(socki_lookup(inode)); + sock_release(SOCKET_I(inode)); return 0; } @@ -754,7 +788,7 @@ static int sock_fasync(int fd, struct file *filp, int on) } - sock = socki_lookup(filp->f_dentry->d_inode); + sock = SOCKET_I(filp->f_dentry->d_inode); if ((sk=sock->sk) == NULL) return -EINVAL; @@ -1521,7 +1555,7 @@ int sock_fcntl(struct file *filp, unsigned int cmd, unsigned long arg) { struct socket *sock; - sock = socki_lookup (filp->f_dentry->d_inode); + sock = SOCKET_I (filp->f_dentry->d_inode); if (sock && sock->ops) return sock_no_fcntl(sock, cmd, arg); return(-EINVAL); @@ -1711,6 +1745,7 @@ void __init sock_init(void) * Initialize the protocols module. */ + init_inodecache(); register_filesystem(&sock_fs_type); sock_mnt = kern_mount(&sock_fs_type); /* The real protocol initialization is performed when diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 77a034a364ac..2cba30f76eca 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -711,7 +711,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) /* * All right, let's create it. */ - mode = S_IFSOCK | (sock->inode->i_mode & ~current->fs->umask); + mode = S_IFSOCK | (SOCK_INODE(sock)->i_mode & ~current->fs->umask); err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); if (err) goto out_mknod_dput; diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 457515db9b18..8581b06c94ae 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -101,7 +101,7 @@ extern inline unix_socket *unix_get_socket(struct file *filp) * Socket ? */ if (inode->i_sock) { - struct socket * sock = &inode->u.socket_i; + struct socket * sock = SOCKET_I(inode); struct sock * s = sock->sk; /* diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c index b58338f52f06..38838887c22d 100644 --- a/net/wanrouter/wanmain.c +++ b/net/wanrouter/wanmain.c @@ -500,7 +500,7 @@ int wanrouter_ioctl(struct inode *inode, struct file *file, if ((cmd >> 8) != ROUTER_IOCTL) return -EINVAL; - dent = inode->u.generic_ip; + dent = PDE(inode); if ((dent == NULL) || (dent->data == NULL)) return -EINVAL; diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c index 14cf0257f28c..51b0f8b18c9b 100644 --- a/net/wanrouter/wanproc.c +++ b/net/wanrouter/wanproc.c @@ -248,7 +248,7 @@ typedef struct wan_stat_entry if (count <= 0) return 0; - dent = inode->u.generic_ip; + dent = PDE(inode); if ((dent == NULL) || (dent->get_info == NULL)) return 0; @@ -794,7 +794,7 @@ typedef struct wan_stat_entry if (count <= 0) return 0; - dent = inode->u.generic_ip; + dent = PDE(inode); if ((dent == NULL) || (dent->get_info == NULL)) return 0; @@ -828,7 +828,7 @@ typedef struct wan_stat_entry if (count <= 0) return 0; - dent = inode->u.generic_ip; + dent = PDE(inode); if ((dent == NULL) || (dent->get_info == NULL)) return -ENODATA; err = verify_area(VERIFY_WRITE, buf, count); @@ -1068,7 +1068,7 @@ static int device_write( if (err) return err; - dent = inode->u.generic_ip; + dent = PDE(inode); if ((dent == NULL) || (dent->data == NULL)) return -ENODATA; diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index cbd52721c9b3..b8ea06165822 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1239,7 +1239,7 @@ static int x25_get_info(char *buffer, char **start, off_t offset, int length) s->protinfo.x25->t23 / HZ, atomic_read(&s->wmem_alloc), atomic_read(&s->rmem_alloc), - s->socket != NULL ? s->socket->inode->i_ino : 0L); + s->socket != NULL ? SOCK_INODE(s->socket)->i_ino : 0L); pos = begin + len; |
