Commit 771a7305 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/net-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents e0f4c5ce fd4615c9
......@@ -15,9 +15,10 @@
* 04-Jan-2005 BJD New uart initialisation
* 10-Jan-2005 BJD Moved generic init here, specific to cpu headers
* 14-Jan-2005 BJD Added s3c24xx_init_clocks() call
* 10-Mar-2005 LCVR Changed S3C2410_{VA,SZ} to S3C24XX_{VA,SZ} on IODESC_ENT
*/
#define IODESC_ENT(x) { S3C2410_VA_##x, S3C2410_PA_##x, S3C2410_SZ_##x, MT_DEVICE }
#define IODESC_ENT(x) { S3C24XX_VA_##x, S3C2410_PA_##x, S3C24XX_SZ_##x, MT_DEVICE }
#ifndef MHZ
#define MHZ (1000*1000)
......
......@@ -10,6 +10,7 @@
* published by the Free Software Foundation.
*
* Modifications:
* 10-Mar-2005 LCVR Changed S3C2410_{VA,SZ} to S3C24XX_{VA,SZ}
* 10-Feb-2005 BJD Added camera from guillaume.gourat@nexvision.tv
* 29-Aug-2004 BJD Added timers 0 through 3
* 29-Aug-2004 BJD Changed index of devices we only have one of to -1
......@@ -46,7 +47,7 @@ struct platform_device *s3c24xx_uart_devs[3];
static struct resource s3c_usb_resource[] = {
[0] = {
.start = S3C2410_PA_USBHOST,
.end = S3C2410_PA_USBHOST + S3C2410_SZ_USBHOST,
.end = S3C2410_PA_USBHOST + S3C24XX_SZ_USBHOST,
.flags = IORESOURCE_MEM,
},
[1] = {
......@@ -76,7 +77,7 @@ EXPORT_SYMBOL(s3c_device_usb);
static struct resource s3c_lcd_resource[] = {
[0] = {
.start = S3C2410_PA_LCD,
.end = S3C2410_PA_LCD + S3C2410_SZ_LCD,
.end = S3C2410_PA_LCD + S3C24XX_SZ_LCD,
.flags = IORESOURCE_MEM,
},
[1] = {
......@@ -107,7 +108,7 @@ EXPORT_SYMBOL(s3c_device_lcd);
static struct resource s3c_nand_resource[] = {
[0] = {
.start = S3C2410_PA_NAND,
.end = S3C2410_PA_NAND + S3C2410_SZ_NAND,
.end = S3C2410_PA_NAND + S3C24XX_SZ_NAND,
.flags = IORESOURCE_MEM,
}
};
......@@ -126,7 +127,7 @@ EXPORT_SYMBOL(s3c_device_nand);
static struct resource s3c_usbgadget_resource[] = {
[0] = {
.start = S3C2410_PA_USBDEV,
.end = S3C2410_PA_USBDEV + S3C2410_SZ_USBDEV,
.end = S3C2410_PA_USBDEV + S3C24XX_SZ_USBDEV,
.flags = IORESOURCE_MEM,
},
[1] = {
......@@ -151,7 +152,7 @@ EXPORT_SYMBOL(s3c_device_usbgadget);
static struct resource s3c_wdt_resource[] = {
[0] = {
.start = S3C2410_PA_WATCHDOG,
.end = S3C2410_PA_WATCHDOG + S3C2410_SZ_WATCHDOG,
.end = S3C2410_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG,
.flags = IORESOURCE_MEM,
},
[1] = {
......@@ -176,7 +177,7 @@ EXPORT_SYMBOL(s3c_device_wdt);
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C2410_PA_IIC,
.end = S3C2410_PA_IIC + S3C2410_SZ_IIC,
.end = S3C2410_PA_IIC + S3C24XX_SZ_IIC,
.flags = IORESOURCE_MEM,
},
[1] = {
......@@ -201,7 +202,7 @@ EXPORT_SYMBOL(s3c_device_i2c);
static struct resource s3c_iis_resource[] = {
[0] = {
.start = S3C2410_PA_IIS,
.end = S3C2410_PA_IIS + S3C2410_SZ_IIS,
.end = S3C2410_PA_IIS + S3C24XX_SZ_IIS,
.flags = IORESOURCE_MEM,
}
};
......@@ -255,7 +256,7 @@ EXPORT_SYMBOL(s3c_device_rtc);
static struct resource s3c_adc_resource[] = {
[0] = {
.start = S3C2410_PA_ADC,
.end = S3C2410_PA_ADC + S3C2410_SZ_ADC,
.end = S3C2410_PA_ADC + S3C24XX_SZ_ADC,
.flags = IORESOURCE_MEM,
},
[1] = {
......@@ -278,7 +279,7 @@ struct platform_device s3c_device_adc = {
static struct resource s3c_sdi_resource[] = {
[0] = {
.start = S3C2410_PA_SDI,
.end = S3C2410_PA_SDI + S3C2410_SZ_SDI,
.end = S3C2410_PA_SDI + S3C24XX_SZ_SDI,
.flags = IORESOURCE_MEM,
},
[1] = {
......
......@@ -24,6 +24,7 @@
* 10-Jan-2005 BJD Removed include of s3c2410.h
* 14-Jan-2005 BJD Add support for muitlple NAND devices
* 03-Mar-2005 BJD Ensured that bast-cpld.h is included
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/
#include <linux/kernel.h>
......@@ -82,8 +83,8 @@
static struct map_desc bast_iodesc[] __initdata = {
/* ISA IO areas */
{ S3C2410_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ S3C2410_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ S3C24XX_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ S3C24XX_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
/* we could possibly compress the next set down into a set of smaller tables
* pagetables, but that would mean using an L2 section, and it still means
......@@ -409,7 +410,7 @@ static __init void bast_init_machine(void)
MACHINE_START(BAST, "Simtec-BAST")
MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C24XX_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(bast_map_io)
INITIRQ(bast_init_irq)
......
......@@ -23,6 +23,7 @@
* 04-Jan-2005 BJD Updated uart init call
* 10-Jan-2005 BJD Removed include of s3c2410.h
* 14-Jan-2005 BJD Added clock init
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/
#include <linux/kernel.h>
......@@ -117,7 +118,7 @@ void __init h1940_init_irq(void)
MACHINE_START(H1940, "IPAQ-H1940")
MAINTAINER("Ben Dooks <ben@fluff.org>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C24XX_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(h1940_map_io)
INITIRQ(h1940_init_irq)
......
......@@ -11,6 +11,9 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Modifications:
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/
#include <linux/kernel.h>
......@@ -138,7 +141,7 @@ void __init n30_init(void)
MACHINE_START(N30, "Acer-N30")
MAINTAINER("Christer Weinigel <christer@weinigel.se>, Ben Dooks <ben-linux@fluff.org>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C24XX_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
.timer = &s3c24xx_timer,
......
......@@ -10,10 +10,11 @@
* published by the Free Software Foundation.
*
* Modifications:
* 16-Sep-2004 BJD Copied from mach-h1940.c
* 25-Oct-2004 BJD Updates for 2.6.10-rc1
* 10-Jan-2005 BJD Removed include of s3c2410.h s3c2440.h
* 14-Jan-2005 BJD Added new clock init
* 16-Sep-2004 BJD Copied from mach-h1940.c
* 25-Oct-2004 BJD Updates for 2.6.10-rc1
* 10-Jan-2005 BJD Removed include of s3c2410.h s3c2440.h
* 14-Jan-2005 BJD Added new clock init
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/
#include <linux/kernel.h>
......@@ -48,8 +49,8 @@
static struct map_desc rx3715_iodesc[] __initdata = {
/* dump ISA space somewhere unused */
{ S3C2410_VA_ISA_WORD, S3C2410_CS3, SZ_16M, MT_DEVICE },
{ S3C2410_VA_ISA_BYTE, S3C2410_CS3, SZ_16M, MT_DEVICE },
{ S3C24XX_VA_ISA_WORD, S3C2410_CS3, SZ_16M, MT_DEVICE },
{ S3C24XX_VA_ISA_BYTE, S3C2410_CS3, SZ_16M, MT_DEVICE },
};
static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
......@@ -114,7 +115,7 @@ static void __init rx3715_init_machine(void)
MACHINE_START(RX3715, "IPAQ-RX3715")
MAINTAINER("Ben Dooks <ben@fluff.org>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C24XX_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(rx3715_map_io)
INITIRQ(rx3715_init_irq)
......
......@@ -26,6 +26,9 @@
* @History:
* derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by
* Ben Dooks <ben@simtec.co.uk>
*
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*
***********************************************************************/
#include <linux/kernel.h>
......@@ -110,7 +113,7 @@ void __init smdk2410_init_irq(void)
MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
* to SMDK2410 */
MAINTAINER("Jonas Dietsche")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C24XX_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(smdk2410_map_io)
INITIRQ(smdk2410_init_irq)
......
......@@ -12,10 +12,11 @@
* published by the Free Software Foundation.
*
* Modifications:
* 01-Nov-2004 BJD Initial version
* 12-Nov-2004 BJD Updated for release
* 04-Jan-2005 BJD Fixes for pre-release
* 22-Feb-2005 BJD Updated for 2.6.11-rc5 relesa
* 01-Nov-2004 BJD Initial version
* 12-Nov-2004 BJD Updated for release
* 04-Jan-2005 BJD Fixes for pre-release
* 22-Feb-2005 BJD Updated for 2.6.11-rc5 relesa
* 10-Mar-2005 LCVR Replaced S3C2410_VA by S3C24XX_VA
*/
#include <linux/kernel.h>
......@@ -50,8 +51,8 @@
static struct map_desc smdk2440_iodesc[] __initdata = {
/* ISA IO Space map (memory space selected by A24) */
{ S3C2410_VA_ISA_WORD, S3C2410_CS2, SZ_16M, MT_DEVICE },
{ S3C2410_VA_ISA_BYTE, S3C2410_CS2, SZ_16M, MT_DEVICE },
{ S3C24XX_VA_ISA_WORD, S3C2410_CS2, SZ_16M, MT_DEVICE },
{ S3C24XX_VA_ISA_BYTE, S3C2410_CS2, SZ_16M, MT_DEVICE },
};
#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
......@@ -123,7 +124,7 @@ void __init smdk2440_machine_init(void)
MACHINE_START(S3C2440, "SMDK2440")
MAINTAINER("Ben Dooks <ben@fluff.org>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C24XX_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
.init_irq = s3c24xx_init_irq,
......
......@@ -25,6 +25,7 @@
* 15-Jan-2005 BJD Add serial port device definition
* 20-Jan-2005 BJD Use UPF_IOREMAP for ports
* 10-Feb-2005 BJD Added power-off capability
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/
#include <linux/kernel.h>
......@@ -77,8 +78,8 @@
static struct map_desc vr1000_iodesc[] __initdata = {
/* ISA IO areas */
{ S3C2410_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ S3C2410_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ S3C24XX_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ S3C24XX_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
/* we could possibly compress the next set down into a set of smaller tables
* pagetables, but that would mean using an L2 section, and it still means
......@@ -307,7 +308,7 @@ void __init vr1000_init_irq(void)
MACHINE_START(VR1000, "Thorcom-VR1000")
MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C24XX_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(vr1000_map_io)
INITIRQ(vr1000_init_irq)
......
......@@ -24,6 +24,9 @@
* Parts based on arch/arm/mach-pxa/pm.c
*
* Thanks to Dimitry Andric for debugging
*
* Modifications:
* 10-Mar-2005 LCVR Changed S3C2410_VA_UART to S3C24XX_VA_UART
*/
#include <linux/config.h>
......@@ -144,9 +147,11 @@ static struct sleep_save gpio_save[] = {
SAVE_ITEM((va) + S3C2410_UBRDIV)
static struct sleep_save uart_save[] = {
SAVE_UART(S3C2410_VA_UART0),
SAVE_UART(S3C2410_VA_UART1),
SAVE_UART(S3C2410_VA_UART2),
SAVE_UART(S3C24XX_VA_UART0),
SAVE_UART(S3C24XX_VA_UART1),
#ifndef CONFIG_CPU_S3C2400
SAVE_UART(S3C24XX_VA_UART2),
#endif
};
/* debug
......
......@@ -17,10 +17,15 @@ static int cmp_ex(const void *a, const void *b)
u64 lip = (u64) &l->addr + l->addr;
u64 rip = (u64) &r->addr + r->addr;
return lip - rip;
/* avoid overflow */
if (lip > rip)
return 1;
if (lip < rip)
return -1;
return 0;
}
static void swap_ex(void *a, void *b)
static void swap_ex(void *a, void *b, int size)
{
struct exception_table_entry *l = a, *r = b, tmp;
u64 delta = (u64) r - (u64) l;
......
config AGP
tristate "/dev/agpgart (AGP Support)" if !GART_IOMMU
depends on ALPHA || IA64 || PPC32 || X86
depends on ALPHA || IA64 || PPC || X86
default y if GART_IOMMU
---help---
AGP (Accelerated Graphics Port) is a bus system mainly used to
......@@ -146,11 +146,11 @@ config AGP_ALPHA_CORE
default AGP
config AGP_UNINORTH
tristate "Apple UniNorth AGP support"
tristate "Apple UniNorth & U3 AGP support"
depends on AGP && PPC_PMAC
help
This option gives you AGP support for Apple machines with a
UniNorth bridge.
UniNorth or U3 (Apple G5) bridge.
config AGP_EFFICEON
tristate "Transmeta Efficeon support"
......
......@@ -322,7 +322,7 @@ extern int agp_try_unsupported_boot;
#define AGPCTRL_GTLBEN (1<<7)
#define AGP2_RESERVED_MASK 0x00fffcc8
#define AGP3_RESERVED_MASK 0x00ff00cc
#define AGP3_RESERVED_MASK 0x00ff00c4
#define AGP_ERRATA_FASTWRITES 1<<0
#define AGP_ERRATA_SBA 1<<1
......
......@@ -515,13 +515,9 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
printk (KERN_INFO PFX "%s tried to set rate=x0. Setting to AGP3 x4 mode.\n", current->comm);
*requested_mode |= AGPSTAT3_4X;
}
if (tmp == 3) {
printk (KERN_INFO PFX "%s tried to set rate=x3. Setting to AGP3 x4 mode.\n", current->comm);
*requested_mode |= AGPSTAT3_4X;
}
if (tmp >3) {
printk (KERN_INFO PFX "%s tried to set rate=x%d. Setting to AGP3 x8 mode.\n", current->comm, tmp);
*requested_mode |= AGPSTAT3_8X;
if (tmp >= 3) {
printk (KERN_INFO PFX "%s tried to set rate=x%d. Setting to AGP3 x8 mode.\n", current->comm, tmp * 4);
*requested_mode = (*requested_mode & ~7) | AGPSTAT3_8X;
}
/* ARQSZ - Set the value to the maximum one.
......@@ -632,26 +628,18 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 requested_mode, u32 bridge_agpstat)
{
struct pci_dev *device = NULL;
u8 cap_ptr = 0;
u32 vga_agpstat;
u8 cap_ptr;
while (!cap_ptr) {
for (;;) {
device = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, device);
if (!device) {
printk (KERN_INFO PFX "Couldn't find an AGP VGA controller.\n");
return 0;
}
cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
if (!cap_ptr) {
pci_dev_put(device);
continue;
}
if ((device->bus->self->vendor != bridge->dev->vendor) &&
(device->bus->self->device != bridge->dev->device)) {
pci_dev_put(device);
cap_ptr = 0;
continue;
}
if (cap_ptr)
break;
}
/*
......
This diff is collapsed.
......@@ -13,6 +13,7 @@
* 08-Nov-2004 BJD Initial creation
* 12-Nov-2004 BJD Added periodic IRQ and PM code
* 22-Nov-2004 BJD Sign-test on alarm code to check for <0
* 10-Mar-2005 LCVR Changed S3C2410_VA_RTC to S3C24XX_VA_RTC
*/
#include <linux/module.h>
......@@ -38,8 +39,8 @@
/* need this for the RTC_AF definitions */
#include <linux/mc146818rtc.h>
#undef S3C2410_VA_RTC
#define S3C2410_VA_RTC s3c2410_rtc_base
#undef S3C24XX_VA_RTC
#define S3C24XX_VA_RTC s3c2410_rtc_base
static struct resource *s3c2410_rtc_mem;
......
......@@ -26,6 +26,8 @@
* 05-Oct-2004 BJD Added semaphore init to stop crashes on open
* Fixed tmr_count / wdt_count confusion
* Added configurable debug
*
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/
#include <linux/module.h>
......@@ -48,8 +50,8 @@
#include <asm/arch/map.h>
#include <asm/hardware/clock.h>
#undef S3C2410_VA_WATCHDOG
#define S3C2410_VA_WATCHDOG (0)
#undef S3C24XX_VA_WATCHDOG
#define S3C24XX_VA_WATCHDOG (0)
#include <asm/arch/regs-watchdog.h>
......
......@@ -29,6 +29,8 @@
* 06-Mar-2005 BJD Add s3c2440 fclk clock source
*
* 09-Mar-2005 BJD Add s3c2400 support
*
* 10-Mar-2005 LCVR Changed S3C2410_VA_UART to S3C24XX_VA_UART
*/
/* Note on 2440 fclk clock source handling
......@@ -1093,7 +1095,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
port->mapbase = res->start;
port->membase = (void __iomem *)(res->start - S3C2410_PA_UART);
port->membase += S3C2410_VA_UART;
port->membase += S3C24XX_VA_UART;
port->irq = platform_get_irq(platdev, 0);
ourport->clk = clk_get(&platdev->dev, "uart");
......@@ -1441,9 +1443,9 @@ static int s3c2440_serial_getsource(struct uart_port *port,
/* the fun of calculating the uart divisors on
* the s3c2440 */
ucon0 = __raw_readl(S3C2410_VA_UART0 + S3C2410_UCON);
ucon1 = __raw_readl(S3C2410_VA_UART1 + S3C2410_UCON);
ucon2 = __raw_readl(S3C2410_VA_UART2 + S3C2410_UCON);
ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
printk("ucons: %08lx, %08lx, %08lx\n", ucon0, ucon1, ucon2);
......
......@@ -322,14 +322,13 @@ static int nlm_wait_on_grace(wait_queue_head_t *queue)
/*
* Generic NLM call
*/
int
static int
nlmclnt_call(struct nlm_rqst *req, u32 proc)
{
struct nlm_host *host = req->a_host;
struct rpc_clnt *clnt;
struct nlm_args *argp = &req->a_args;
struct nlm_res *resp = &req->a_res;
struct file *filp = argp->lock.fl.fl_file;
struct rpc_message msg = {
.rpc_argp = argp,
.rpc_resp = resp,
......@@ -339,9 +338,6 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc)
dprintk("lockd: call procedure %d on %s\n",
(int)proc, host->h_name);
if (filp)
msg.rpc_cred = nfs_file_cred(filp);
do {
if (host->h_reclaiming && !argp->reclaim)
goto in_grace_period;
......@@ -428,14 +424,13 @@ nlmsvc_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback)
return status;
}
int
static int
nlmclnt_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback)
{
struct nlm_host *host = req->a_host;
struct rpc_clnt *clnt;
struct nlm_args *argp = &req->a_args;
struct nlm_res *resp = &req->a_res;
struct file *file = argp->lock.fl.fl_file;
struct rpc_message msg = {
.rpc_argp = argp,
.rpc_resp = resp,
......@@ -450,11 +445,9 @@ nlmclnt_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback)
return -ENOLCK;
msg.rpc_proc = &clnt->cl_procinfo[proc];
/* bootstrap and kick off the async RPC call */
if (file)
msg.rpc_cred = nfs_file_cred(file);
/* Increment host refcount */
nlm_get_host(host);
/* bootstrap and kick off the async RPC call */
status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, callback, req);
if (status < 0)
nlm_release_host(host);
......@@ -516,6 +509,24 @@ static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *ho
fl->fl_ops = &nlmclnt_lock_ops;
}
static void do_vfs_lock(struct file_lock *fl)
{
int res = 0;
switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) {
case FL_POSIX:
res = posix_lock_file_wait(fl->fl_file, fl);
break;
case FL_FLOCK:
res = flock_lock_file_wait(fl->fl_file, fl);
break;
default:
BUG();
}
if (res < 0)
printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n",
__FUNCTION__);
}
/*
* LOCK: Try to create a lock
*
......@@ -564,9 +575,7 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
fl->fl_u.nfs_fl.state = host->h_state;
fl->fl_u.nfs_fl.flags |= NFS_LCK_GRANTED;
fl->fl_flags |= FL_SLEEP;
if (posix_lock_file_wait(fl->fl_file, fl) < 0)
printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n",
__FUNCTION__);
do_vfs_lock(fl);
}
status = nlm_stat_to_errno(resp->status);
out:
......@@ -635,7 +644,7 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
nlmclnt_unlock_callback);
/* Hrmf... Do the unlock early since locks_remove_posix()
* really expects us to free the lock synchronously */
posix_lock_file(fl->fl_file, fl);
do_vfs_lock(fl);
if (status < 0) {
nlmclnt_release_lockargs(req);
kfree(req);
......@@ -648,7 +657,7 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
if (status < 0)
return status;
posix_lock_file(fl->fl_file, fl);
do_vfs_lock(fl);
if (resp->status == NLM_LCK_GRANTED)
return 0;
......
......@@ -110,7 +110,6 @@ nlm_lookup_host(int server, struct sockaddr_in *sin,
host->h_addr.sin_port = 0; /* ouch! */
host->h_version = version;
host->h_proto = proto;
host->h_authflavor = RPC_AUTH_UNIX;
host->h_rpcclnt = NULL;
init_MUTEX(&host->h_sema);
host->h_nextrebind = jiffies + NLM_HOST_REBIND;
......@@ -191,8 +190,9 @@ nlm_bind_host(struct nlm_host *host)
xprt_set_timeout(&xprt->timeout, 5, nlmsvc_timeout);
/* Existing NLM servers accept AUTH_UNIX only */
clnt = rpc_create_client(xprt, host->h_name, &nlm_program,
host->h_version, host->h_authflavor);
host->h_version, RPC_AUTH_UNIX);
if (IS_ERR(clnt)) {
xprt_destroy(xprt);
goto forgetit;
......
......@@ -1865,8 +1865,13 @@ void locks_remove_flock(struct file *filp)
return;
if (filp->f_op && filp->f_op->flock) {
struct file_lock fl = { .fl_flags = FL_FLOCK,
.fl_type = F_UNLCK };
struct file_lock fl = {
.fl_pid = current->tgid,
.fl_file = filp,
.fl_flags = FL_FLOCK,
.fl_type = F_UNLCK,
.fl_end = OFFSET_MAX,
};
filp->f_op->flock(filp, F_SETLKW, &fl);
}
......
......@@ -681,7 +681,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
*
* We expect 'base' to be positive and a directory.
*/
int fastcall link_path_walk(const char * name, struct nameidata *nd)
static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
{
struct path next;
struct inode *inode;
......@@ -881,6 +881,37 @@ int fastcall link_path_walk(const char * name, struct nameidata *nd)
return err;
}
/*
* Wrapper to retry pathname resolution whenever the underlying
* file system returns an ESTALE.
*
* Retry the whole path once, forcing real lookup requests
* instead of relying on the dcache.
*/
int fastcall link_path_walk(const char *name, struct nameidata *nd)
{
struct nameidata save = *nd;
int result;
/* make sure the stuff we saved doesn't go away */
dget(save.dentry);
mntget(save.mnt);
result = __link_path_walk(name, nd);
if (result == -ESTALE) {
*nd = save;
dget(nd->dentry);
mntget(nd->mnt);
nd->flags |= LOOKUP_REVAL;
result = __link_path_walk(name, nd);
}
dput(save.dentry);
mntput(save.mnt);
return result;
}
int fastcall path_walk(const char * name, struct nameidata *nd)
{
current->total_link_count = 0;
......
......@@ -529,13 +529,24 @@ static inline void nfs_renew_times(struct dentry * dentry)
}
static inline
int nfs_lookup_verify_inode(struct inode *inode, int isopen)
int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd)
{
struct nfs_server *server = NFS_SERVER(inode);
if (isopen && !(server->flags & NFS_MOUNT_NOCTO))
return __nfs_revalidate_inode(server, inode);
if (nd != NULL) {
int ndflags = nd->flags;
/* VFS wants an on-the-wire revalidation */
if (ndflags & LOOKUP_REVAL)
goto out_force;
/* This is an open(2) */
if ((ndflags & LOOKUP_OPEN) &&
!(ndflags & LOOKUP_CONTINUE) &&
!(server->flags & NFS_MOUNT_NOCTO))
goto out_force;
}
return nfs_revalidate_inode(server, inode);
out_force:
return __nfs_revalidate_inode(server, inode);
}
/*
......@@ -579,16 +590,12 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
struct nfs_fh fhandle;
struct nfs_fattr fattr;
unsigned long verifier;
int isopen = 0;
parent = dget_parent(dentry);
lock_kernel();
dir = parent->d_inode;
inode = dentry->d_inode;
if (nd && !(nd->flags & LOOKUP_CONTINUE) && (nd->flags & LOOKUP_OPEN))
isopen = 1;
if (!inode) {
if (nfs_neg_need_reval(dir, dentry, nd))
goto out_bad;
......@@ -602,11 +609,12 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
}
/* Revalidate parent directory attribute cache */
nfs_revalidate_inode(NFS_SERVER(dir), dir);
if (nfs_revalidate_inode(NFS_SERVER(dir), dir) < 0)
goto out_zap_parent;
/* Force a full look up iff the parent directory has changed */
if (nfs_check_verifier(dir, dentry)) {
if (nfs_lookup_verify_inode(inode, isopen))
if (nfs_lookup_verify_inode(inode, nd))
goto out_zap_parent;
goto out_valid;
}
......@@ -722,7 +730,11 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
lock_kernel();
/* Revalidate parent directory attribute cache */
nfs_revalidate_inode(NFS_SERVER(dir), dir);
error = nfs_revalidate_inode(NFS_SERVER(dir), dir);
if (error < 0) {
res = ERR_PTR(error);
goto out_unlock;
}
/* If we're doing an exclusive create, optimize away the lookup */
if (nfs_is_exclusive_create(dir, nd))
......@@ -780,6 +792,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
{
struct dentry *res = NULL;
struct inode *inode = NULL;
int error;
/* Check that we are indeed trying to open this file */
if (!is_atomic_open(dir, nd))
......@@ -798,7 +811,11 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
/* Open the file on the server */
lock_kernel();
/* Revalidate parent directory attribute cache */
nfs_revalidate_inode(NFS_SERVER(dir), dir);
error = nfs_revalidate_inode(NFS_SERVER(dir), dir);
if (error < 0) {
res = ERR_PTR(error);
goto out;
}
if (nd->intent.open.flags & O_CREAT) {
nfs_begin_data_update(dir);
......@@ -808,7 +825,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
inode = nfs4_atomic_open(dir, dentry, nd);
unlock_kernel();
if (IS_ERR(inode)) {
int error = PTR_ERR(inode);
error = PTR_ERR(inode);
switch (error) {
/* Make a negative dentry */
case -ENOENT:
......@@ -938,7 +955,7 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
/*
* Code common to create, mkdir, and mknod.
*/
static int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
struct nfs_fattr *fattr)
{
struct inode *inode;
......@@ -959,14 +976,12 @@ static int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
if (error < 0)
goto out_err;
}
inode = nfs_fhget(dentry->d_sb, fhandle, fattr);
if (inode) {
d_instantiate(dentry, inode);
nfs_renew_times(dentry);
nfs_set_verifier(dentry, nfs_save_change_attribute(dentry->d_parent->d_inode));
return 0;
}
error = -ENOMEM;
inode = nfs_fhget(dentry->d_sb, fhandle, fattr);
if (inode == NULL)
goto out_err;
d_instantiate(dentry, inode);
return 0;
out_err:
d_drop(dentry);
return error;
......@@ -982,7 +997,6 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
struct nameidata *nd)
{
struct iattr attr;
struct inode *inode;
int error;
int open_flags = 0;
......@@ -997,18 +1011,17 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
lock_kernel();
nfs_begin_data_update(dir);
inode = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
nfs_end_data_update(dir);
if (!IS_ERR(inode)) {
d_instantiate(dentry, inode);
nfs_renew_times(dentry);
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
error = 0;
} else {
error = PTR_ERR(inode);
d_drop(dentry);
}
if (error != 0)
goto out_err;
nfs_renew_times(dentry);
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
unlock_kernel();
return 0;
out_err:
unlock_kernel();
d_drop(dentry);
return error;
}
......@@ -1019,9 +1032,7 @@ static int
nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
{
struct iattr attr;
struct nfs_fattr fattr;
struct nfs_fh fhandle;
int error;
int status;
dfprintk(VFS, "NFS: mknod(%s/%ld, %s\n", dir->i_sb->s_id,
dir->i_ino, dentry->d_name.name);
......@@ -1034,15 +1045,18 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
lock_kernel();
nfs_begin_data_update(dir);
error = NFS_PROTO(dir)->mknod(dir, &dentry->d_name, &attr, rdev,
&fhandle, &fattr);
status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev);
nfs_end_data_update(dir);
if (!error)
error = nfs_instantiate(dentry, &fhandle, &fattr);
else
d_drop(dentry);
if (status != 0)
goto out_err;
nfs_renew_times(dentry);
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
unlock_kernel();
return error;
return 0;
out_err:
unlock_kernel();
d_drop(dentry);
return status;
}
/*
......@@ -1051,8 +1065,6 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
struct iattr attr;
struct nfs_fattr fattr;
struct nfs_fh fhandle;
int error;
dfprintk(VFS, "NFS: mkdir(%s/%ld, %s\n", dir->i_sb->s_id,
......@@ -1062,23 +1074,17 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
attr.ia_mode = mode | S_IFDIR;
lock_kernel();
#if 0
/*
* Always drop the dentry, we can't always depend on
* the fattr returned by the server (AIX seems to be
* broken). We're better off doing another lookup than
* depending on potentially bogus information.
*/
d_drop(dentry);
#endif
nfs_begin_data_update(dir);
error = NFS_PROTO(dir)->mkdir(dir, &dentry->d_name, &attr, &fhandle,
&fattr);
error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr);
nfs_end_data_update(dir);
if (!error)
error = nfs_instantiate(dentry, &fhandle, &fattr);
else
d_drop(dentry);
if (error != 0)
goto out_err;
nfs_renew_times(dentry);
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
unlock_kernel();
return 0;
out_err:
d_drop(dentry);
unlock_kernel();
return error;
}
......@@ -1107,7 +1113,7 @@ static int nfs_sillyrename(struct inode *dir, struct dentry *dentry)
static unsigned int sillycounter;
const int i_inosize = sizeof(dir->i_ino)*2;
const int countersize = sizeof(sillycounter)*2;
const int slen = strlen(".nfs") + i_inosize + countersize;
const int slen = sizeof(".nfs") + i_inosize + countersize - 1;
char silly[slen+1];
struct qstr qsilly;
struct dentry *sdentry;
......@@ -1498,34 +1504,52 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
int nfs_permission(struct inode *inode, int mask, struct nameidata *nd)
{
struct rpc_cred *cred;
int res;
int res = 0;
if (mask == 0)
return 0;
goto out;
/* Is this sys_access() ? */
if (nd != NULL && (nd->flags & LOOKUP_ACCESS))
goto force_lookup;
/* Are we checking permissions on anything other than lookup/execute? */
if ((mask & MAY_EXEC) == 0) {
/* We only need to check permissions on file open() and access() */
if (!nd || !(nd->flags & (LOOKUP_OPEN|LOOKUP_ACCESS)))
return 0;
/* NFSv4 has atomic_open... */
if (NFS_PROTO(inode)->version > 3 && (nd->flags & LOOKUP_OPEN))
return 0;
switch (inode->i_mode & S_IFMT) {
case S_IFLNK:
goto out;
case S_IFREG:
/* NFSv4 has atomic_open... */
if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN)
&& nd != NULL
&& (nd->flags & LOOKUP_OPEN))
goto out;
break;
case S_IFDIR:
/*
* Optimize away all write operations, since the server
* will check permissions when we perform the op.
*/
if ((mask & MAY_WRITE) && !(mask & MAY_READ))
goto out;
}
force_lookup:
lock_kernel();
if (!NFS_PROTO(inode)->access)
goto out_notsup;
cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0);
res = nfs_do_access(inode, cred, mask);
put_rpccred(cred);
if (!IS_ERR(cred)) {
res = nfs_do_access(inode, cred, mask);
put_rpccred(cred);
} else
res = PTR_ERR(cred);
unlock_kernel();
out:
return res;
out_notsup:
nfs_revalidate_inode(NFS_SERVER(inode), inode);
res = generic_permission(inode, mask, NULL);
res = nfs_revalidate_inode(NFS_SERVER(inode), inode);
if (res == 0)
res = generic_permission(inode, mask, NULL);
unlock_kernel();
return res;
}
......
......@@ -44,6 +44,8 @@ static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_
static int nfs_file_flush(struct file *);
static int nfs_fsync(struct file *, struct dentry *dentry, int datasync);
static int nfs_check_flags(int flags);
static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
struct file_operations nfs_file_operations = {
.llseek = remote_llseek,
......@@ -57,6 +59,7 @@ struct file_operations nfs_file_operations = {
.release = nfs_file_release,
.fsync = nfs_fsync,
.lock = nfs_lock,
.flock = nfs_flock,
.sendfile = nfs_file_sendfile,
.check_flags = nfs_check_flags,
};
......@@ -312,6 +315,25 @@ static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
return status;
}
static int do_vfs_lock(struct file *file, struct file_lock *fl)
{
int res = 0;
switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) {
case FL_POSIX:
res = posix_lock_file_wait(file, fl);
break;
case FL_FLOCK:
res = flock_lock_file_wait(file, fl);
break;
default:
BUG();
}
if (res < 0)
printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n",
__FUNCTION__);
return res;
}
static int do_unlk(struct file *filp, int cmd, struct file_lock *fl)
{
struct inode *inode = filp->f_mapping->host;
......@@ -338,7 +360,7 @@ static int do_unlk(struct file *filp, int cmd, struct file_lock *fl)
if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM))
status = NFS_PROTO(inode)->lock(filp, cmd, fl);
else
status = posix_lock_file_wait(filp, fl);
status = do_vfs_lock(filp, fl);
unlock_kernel();
rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset);
return status;
......@@ -377,9 +399,9 @@ static int do_setlk(struct file *filp, int cmd, struct file_lock *fl)
* the process exits.
*/
if (status == -EINTR || status == -ERESTARTSYS)
posix_lock_file_wait(filp, fl);
do_vfs_lock(filp, fl);
} else
status = posix_lock_file_wait(filp, fl);
status = do_vfs_lock(filp, fl);
unlock_kernel();
if (status < 0)
goto out;
......@@ -401,8 +423,7 @@ static int do_setlk(struct file *filp, int cmd, struct file_lock *fl)
/*
* Lock a (portion of) a file
*/
int
nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
{
struct inode * inode = filp->f_mapping->host;
......@@ -418,6 +439,27 @@ nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
return -ENOLCK;
if (IS_GETLK(cmd))
return do_getlk(filp, cmd, fl);
if (fl->fl_type == F_UNLCK)
return do_unlk(filp, cmd, fl);
return do_setlk(filp, cmd, fl);
}
/*
* Lock a (portion of) a file
*/
static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
{
struct inode * inode = filp->f_mapping->host;
dprintk("NFS: nfs_flock(f=%s/%ld, t=%x, fl=%x)\n",
inode->i_sb->s_id, inode->i_ino,
fl->fl_type, fl->fl_flags);
if (!inode)
return -EINVAL;
/*
* No BSD flocks over NFS allowed.
* Note: we could try to fake a POSIX lock request here by
......@@ -425,11 +467,14 @@ nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
* Not sure whether that would be unique, though, or whether
* that would break in other places.
*/
if (!fl->fl_owner || !(fl->fl_flags & FL_POSIX))
if (!(fl->fl_flags & FL_FLOCK))
return -ENOLCK;
if (IS_GETLK(cmd))
return do_getlk(filp, cmd, fl);
/* We're simulating flock() locks using posix locks on the server */
fl->fl_owner = (fl_owner_t)filp;
fl->fl_start = 0;
fl->fl_end = OFFSET_MAX;
if (fl->fl_type == F_UNLCK)
return do_unlk(filp, cmd, fl);
return do_setlk(filp, cmd, fl);
......
......@@ -64,6 +64,8 @@ static void nfs_umount_begin(struct super_block *);
static int nfs_statfs(struct super_block *, struct kstatfs *);
static int nfs_show_options(struct seq_file *, struct vfsmount *);
static struct rpc_program nfs_program;
static struct super_operations nfs_sops = {
.alloc_inode = nfs_alloc_inode,
.destroy_inode = nfs_destroy_inode,
......@@ -78,7 +80,7 @@ static struct super_operations nfs_sops = {
/*
* RPC cruft for NFS
*/
struct rpc_stat nfs_rpcstat = {
static struct rpc_stat nfs_rpcstat = {
.program = &nfs_program
};
static struct rpc_version * nfs_version[] = {
......@@ -95,7 +97,7 @@ static struct rpc_version * nfs_version[] = {
#endif
};
struct rpc_program nfs_program = {
static struct rpc_program nfs_program = {
.name = "nfs",
.number = NFS_PROGRAM,
.nrvers = sizeof(nfs_version) / sizeof(nfs_version[0]),
......@@ -247,6 +249,7 @@ nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor)
.fattr = &fattr,
};
int no_root_error = 0;
unsigned long max_rpc_payload;
/* We probably want something more informative here */
snprintf(sb->s_id, sizeof(sb->s_id), "%x:%x", MAJOR(sb->s_dev), MINOR(sb->s_dev));
......@@ -283,6 +286,12 @@ nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor)
if (fsinfo.wtmax >= 512 && server->wsize > fsinfo.wtmax)
server->wsize = nfs_block_size(fsinfo.wtmax, NULL);
max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL);
if (server->rsize > max_rpc_payload)
server->rsize = max_rpc_payload;
if (server->wsize > max_rpc_payload)
server->wsize = max_rpc_payload;
server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
if (server->rpages > NFS_READ_MAXIOV) {
server->rpages = NFS_READ_MAXIOV;
......@@ -317,6 +326,9 @@ nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor)
if (sb->s_maxbytes > MAX_LFS_FILESIZE)
sb->s_maxbytes = MAX_LFS_FILESIZE;
server->client->cl_intr = (server->flags & NFS_MOUNT_INTR) ? 1 : 0;
server->client->cl_softrtry = (server->flags & NFS_MOUNT_SOFT) ? 1 : 0;
/* We're airborne Set socket buffersize */
rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
return 0;
......@@ -364,9 +376,8 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
goto out_fail;
}
clnt->cl_intr = (server->flags & NFS_MOUNT_INTR) ? 1 : 0;
clnt->cl_softrtry = (server->flags & NFS_MOUNT_SOFT) ? 1 : 0;
clnt->cl_droppriv = (server->flags & NFS_MOUNT_BROKEN_SUID) ? 1 : 0;
clnt->cl_intr = 1;
clnt->cl_softrtry = 1;
clnt->cl_chatty = 1;
return clnt;
......@@ -538,7 +549,6 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
{ NFS_MOUNT_NOCTO, ",nocto", "" },
{ NFS_MOUNT_NOAC, ",noac", "" },
{ NFS_MOUNT_NONLM, ",nolock", ",lock" },
{ NFS_MOUNT_BROKEN_SUID, ",broken_suid", "" },
{ 0, NULL, NULL }
};
struct proc_nfs_info *nfs_infop;
......@@ -792,7 +802,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
* Wait for the inode to get unlocked.
* (Used for NFS_INO_LOCKED and NFS_INO_REVALIDATING).
*/
int
static int
nfs_wait_on_inode(struct inode *inode, int flag)
{
struct rpc_clnt *clnt = NFS_CLIENT(inode);
......@@ -856,6 +866,12 @@ struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
void put_nfs_open_context(struct nfs_open_context *ctx)
{
if (atomic_dec_and_test(&ctx->count)) {
if (!list_empty(&ctx->list)) {
struct inode *inode = ctx->dentry->d_inode;
spin_lock(&inode->i_lock);
list_del(&ctx->list);
spin_unlock(&inode->i_lock);
}
if (ctx->state != NULL)
nfs4_close_state(ctx->state, ctx->mode);
if (ctx->cred != NULL)
......@@ -904,7 +920,7 @@ void nfs_file_clear_open_context(struct file *filp)
if (ctx) {
filp->private_data = NULL;
spin_lock(&inode->i_lock);
list_del(&ctx->list);
list_move_tail(&ctx->list, &NFS_I(inode)->open_files);
spin_unlock(&inode->i_lock);
put_nfs_open_context(ctx);
}
......@@ -918,8 +934,9 @@ int nfs_open(struct inode *inode, struct file *filp)
struct nfs_open_context *ctx;
struct rpc_cred *cred;
if ((cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0)) == NULL)
return -ENOMEM;
cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0);
if (IS_ERR(cred))
return PTR_ERR(cred);
ctx = alloc_nfs_open_context(filp->f_dentry, cred);
put_rpccred(cred);
if (ctx == NULL)
......@@ -1542,6 +1559,7 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
if (data->wsize != 0)
server->wsize = nfs_block_size(data->wsize, NULL);
server->flags = data->flags & NFS_MOUNT_FLAGMASK;
server->caps = NFS_CAP_ATOMIC_OPEN;
server->acregmin = data->acregmin*HZ;
server->acregmax = data->acregmax*HZ;
......@@ -1609,9 +1627,17 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
err = PTR_ERR(clnt);
goto out_fail;
}
clnt->cl_intr = 1;
clnt->cl_softrtry = 1;
clnt->cl_chatty = 1;
clp->cl_rpcclient = clnt;
clp->cl_cred = rpcauth_lookupcred(clnt->cl_auth, 0);
if (IS_ERR(clp->cl_cred)) {
up_write(&clp->cl_sem);
err = PTR_ERR(clp->cl_cred);
clp->cl_cred = NULL;
goto out_fail;
}
memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr));
nfs_idmap_new(clp);
}
......@@ -1634,8 +1660,6 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
return PTR_ERR(clnt);
}
clnt->cl_intr = (server->flags & NFS4_MOUNT_INTR) ? 1 : 0;
clnt->cl_softrtry = (server->flags & NFS4_MOUNT_SOFT) ? 1 : 0;
server->client = clnt;
if (server->nfs4_state->cl_idmap == NULL) {
......
......@@ -31,7 +31,7 @@
static struct rpc_clnt * mnt_create(char *, struct sockaddr_in *,
int, int);
struct rpc_program mnt_program;
static struct rpc_program mnt_program;
struct mnt_fhstatus {
unsigned int status;
......@@ -174,7 +174,7 @@ static struct rpc_version * mnt_version[] = {
static struct rpc_stat mnt_stats;
struct rpc_program mnt_program = {
static struct rpc_program mnt_program = {
.name = "mount",
.number = NFS_MNT_PROGRAM,
.nrvers = sizeof(mnt_version)/sizeof(mnt_version[0]),
......
......@@ -295,7 +295,7 @@ static int nfs3_proc_commit(struct nfs_write_data *cdata)
* Create a regular file.
* For now, we don't implement O_EXCL.
*/
static struct inode *
static int
nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
int flags)
{
......@@ -342,29 +342,19 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
break;
case NFS3_CREATE_UNCHECKED:
goto exit;
goto out;
}
goto again;
}
exit:
dprintk("NFS reply create: %d\n", status);
if (status == 0)
status = nfs_instantiate(dentry, &fhandle, &fattr);
if (status != 0)
goto out;
if (fhandle.size == 0 || !(fattr.valid & NFS_ATTR_FATTR)) {
status = nfs3_proc_lookup(dir, &dentry->d_name, &fhandle, &fattr);
if (status != 0)
goto out;
}
/* When we created the file with exclusive semantics, make
* sure we set the attributes afterwards. */
if (arg.createmode == NFS3_CREATE_EXCLUSIVE) {
struct nfs3_sattrargs arg = {
.fh = &fhandle,
.sattr = sattr,
};
dprintk("NFS call setattr (post-create)\n");
if (!(sattr->ia_valid & ATTR_ATIME_SET))
......@@ -375,20 +365,13 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
/* Note: we could use a guarded setattr here, but I'm
* not sure this buys us anything (and I'd have
* to revamp the NFSv3 XDR code) */
fattr.valid = 0;
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_SETATTR,
&arg, &fattr, 0);
status = nfs3_proc_setattr(dentry, &fattr, sattr);
nfs_refresh_inode(dentry->d_inode, &fattr);
dprintk("NFS reply setattr (post-create): %d\n", status);
}
if (status == 0) {
struct inode *inode;
inode = nfs_fhget(dir->i_sb, &fhandle, &fattr);
if (inode)
return inode;
status = -ENOMEM;
}
out:
return ERR_PTR(status);
dprintk("NFS reply create: %d\n", status);
return status;
}
static int
......@@ -540,28 +523,30 @@ nfs3_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
}
static int
nfs3_proc_mkdir(struct inode *dir, struct qstr *name, struct iattr *sattr,
struct nfs_fh *fhandle, struct nfs_fattr *fattr)
nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
{
struct nfs_fattr dir_attr;
struct nfs_fh fhandle;
struct nfs_fattr fattr, dir_attr;
struct nfs3_mkdirargs arg = {
.fh = NFS_FH(dir),
.name = name->name,
.len = name->len,
.name = dentry->d_name.name,
.len = dentry->d_name.len,
.sattr = sattr
};
struct nfs3_diropres res = {
.dir_attr = &dir_attr,
.fh = fhandle,
.fattr = fattr
.fh = &fhandle,
.fattr = &fattr
};
int status;
dprintk("NFS call mkdir %s\n", name->name);
dprintk("NFS call mkdir %s\n", dentry->d_name.name);
dir_attr.valid = 0;
fattr->valid = 0;
fattr.valid = 0;
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0);
nfs_refresh_inode(dir, &dir_attr);
if (status == 0)
status = nfs_instantiate(dentry, &fhandle, &fattr);
dprintk("NFS reply mkdir: %d\n", status);
return status;
}
......@@ -639,23 +624,24 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
}
static int
nfs3_proc_mknod(struct inode *dir, struct qstr *name, struct iattr *sattr,
dev_t rdev, struct nfs_fh *fh, struct nfs_fattr *fattr)
nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
dev_t rdev)
{
struct nfs_fattr dir_attr;
struct nfs_fh fh;
struct nfs_fattr fattr, dir_attr;
struct nfs3_mknodargs arg = {
.fh = NFS_FH(dir),
.name = name->name,
.len = name->len,
.name = dentry->d_name.name,
.len = dentry->d_name.len,
.sattr = sattr,
.rdev = rdev
};
struct nfs3_diropres res = {
.dir_attr = &dir_attr,
.fh = fh,
.fattr = fattr
.fh = &fh,
.fattr = &fattr
};
int status;
int status;
switch (sattr->ia_mode & S_IFMT) {
case S_IFBLK: arg.type = NF3BLK; break;
......@@ -665,12 +651,14 @@ nfs3_proc_mknod(struct inode *dir, struct qstr *name, struct iattr *sattr,
default: return -EINVAL;
}
dprintk("NFS call mknod %s %u:%u\n", name->name,
dprintk("NFS call mknod %s %u:%u\n", dentry->d_name.name,
MAJOR(rdev), MINOR(rdev));
dir_attr.valid = 0;
fattr->valid = 0;
fattr.valid = 0;
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0);
nfs_refresh_inode(dir, &dir_attr);
if (status == 0)
status = nfs_instantiate(dentry, &fh, &fattr);
dprintk("NFS reply mknod: %d\n", status);
return status;
}
......
This diff is collapsed.
......@@ -116,6 +116,7 @@ nfs4_alloc_client(struct in_addr *addr)
INIT_LIST_HEAD(&clp->cl_superblocks);
init_waitqueue_head(&clp->cl_waitq);
rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client");
clp->cl_boot_time = CURRENT_TIME;
clp->cl_state = 1 << NFS4CLNT_OK;
return clp;
}
......@@ -205,7 +206,7 @@ nfs4_put_client(struct nfs4_client *clp)
nfs4_free_client(clp);
}
int nfs4_init_client(struct nfs4_client *clp)
static int __nfs4_init_client(struct nfs4_client *clp)
{
int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, nfs_callback_tcpport);
if (status == 0)
......@@ -215,6 +216,11 @@ int nfs4_init_client(struct nfs4_client *clp)
return status;
}
int nfs4_init_client(struct nfs4_client *clp)
{
return nfs4_map_errors(__nfs4_init_client(clp));
}
u32
nfs4_alloc_lockowner_id(struct nfs4_client *clp)
{
......@@ -274,8 +280,8 @@ nfs4_alloc_state_owner(void)
return sp;
}
static void
nfs4_unhash_state_owner(struct nfs4_state_owner *sp)
void
nfs4_drop_state_owner(struct nfs4_state_owner *sp)
{
struct nfs4_client *clp = sp->so_client;
spin_lock(&clp->cl_lock);
......@@ -441,7 +447,9 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner)
if (state == NULL && new != NULL) {
state = new;
/* Caller *must* be holding owner->so_sem */
list_add(&state->open_states, &owner->so_states);
/* Note: The reclaim code dictates that we add stateless
* and read-only stateids to the end of the list */
list_add_tail(&state->open_states, &owner->so_states);
state->owner = owner;
atomic_inc(&owner->so_count);
list_add(&state->inode_states, &nfsi->open_states);
......@@ -497,8 +505,12 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode)
state->nreaders--;
if (mode & FMODE_WRITE)
state->nwriters--;
if (state->nwriters == 0 && state->nreaders == 0)
list_del_init(&state->inode_states);
if (state->nwriters == 0) {
if (state->nreaders == 0)
list_del_init(&state->inode_states);
/* See reclaim code */
list_move_tail(&state->open_states, &owner->so_states);
}
spin_unlock(&inode->i_lock);
newstate = 0;
if (state->state != 0) {
......@@ -708,7 +720,7 @@ void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp)
sp->so_seqid++;
/* If the server returns BAD_SEQID, unhash state_owner here */
if (status == -NFS4ERR_BAD_SEQID)
nfs4_unhash_state_owner(sp);
nfs4_drop_state_owner(sp);
}
static int reclaimer(void *);
......@@ -753,7 +765,7 @@ nfs4_schedule_state_recovery(struct nfs4_client *clp)
schedule_work(&clp->cl_recoverd);
}
static int nfs4_reclaim_locks(struct nfs4_state *state)
static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_state *state)
{
struct inode *inode = state->inode;
struct file_lock *fl;
......@@ -764,7 +776,7 @@ static int nfs4_reclaim_locks(struct nfs4_state *state)
continue;
if (((struct nfs_open_context *)fl->fl_file->private_data)->state != state)
continue;
status = nfs4_lock_reclaim(state, fl);
status = ops->recover_lock(state, fl);
if (status >= 0)
continue;
switch (status) {
......@@ -786,20 +798,28 @@ static int nfs4_reclaim_locks(struct nfs4_state *state)
return status;
}
static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp)
static int nfs4_reclaim_open_state(struct nfs4_state_recovery_ops *ops, struct nfs4_state_owner *sp)
{
struct nfs4_state *state;
struct nfs4_lock_state *lock;
int status = 0;
/* Note: we rely on the sp->so_states list being ordered
* so that we always reclaim open(O_RDWR) and/or open(O_WRITE)
* states first.
* This is needed to ensure that the server won't give us any
* read delegations that we have to return if, say, we are
* recovering after a network partition or a reboot from a
* server that doesn't support a grace period.
*/
list_for_each_entry(state, &sp->so_states, open_states) {
if (state->state == 0)
continue;
status = nfs4_open_reclaim(sp, state);
status = ops->recover_open(sp, state);
list_for_each_entry(lock, &state->lock_states, ls_locks)
lock->ls_flags &= ~NFS_LOCK_INITIALIZED;
if (status >= 0) {
status = nfs4_reclaim_locks(state);
status = nfs4_reclaim_locks(ops, state);
if (status < 0)
goto out_err;
list_for_each_entry(lock, &state->lock_states, ls_locks) {
......@@ -813,8 +833,7 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp)
default:
printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n",
__FUNCTION__, status);
case -NFS4ERR_EXPIRED:
case -NFS4ERR_NO_GRACE:
case -ENOENT:
case -NFS4ERR_RECLAIM_BAD:
case -NFS4ERR_RECLAIM_CONFLICT:
/*
......@@ -826,6 +845,8 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp)
/* Mark the file as being 'closed' */
state->state = 0;
break;
case -NFS4ERR_EXPIRED:
case -NFS4ERR_NO_GRACE:
case -NFS4ERR_STALE_CLIENTID:
goto out_err;
}
......@@ -840,6 +861,7 @@ static int reclaimer(void *ptr)
struct reclaimer_args *args = (struct reclaimer_args *)ptr;
struct nfs4_client *clp = args->clp;
struct nfs4_state_owner *sp;
struct nfs4_state_recovery_ops *ops;
int status = 0;
daemonize("%u.%u.%u.%u-reclaim", NIPQUAD(clp->cl_addr));
......@@ -856,20 +878,34 @@ static int reclaimer(void *ptr)
goto out;
restart_loop:
status = nfs4_proc_renew(clp);
if (status == 0 || status == -NFS4ERR_CB_PATH_DOWN)
goto out;
status = nfs4_init_client(clp);
switch (status) {
case 0:
case -NFS4ERR_CB_PATH_DOWN:
goto out;
case -NFS4ERR_STALE_CLIENTID:
case -NFS4ERR_LEASE_MOVED:
ops = &nfs4_reboot_recovery_ops;
break;
default:
ops = &nfs4_network_partition_recovery_ops;
};
status = __nfs4_init_client(clp);
if (status)
goto out_error;
/* Mark all delagations for reclaim */
/* Mark all delegations for reclaim */
nfs_delegation_mark_reclaim(clp);
/* Note: list is protected by exclusive lock on cl->cl_sem */
list_for_each_entry(sp, &clp->cl_state_owners, so_list) {
status = nfs4_reclaim_open_state(sp);
status = nfs4_reclaim_open_state(ops, sp);
if (status < 0) {
if (status == -NFS4ERR_NO_GRACE) {
ops = &nfs4_network_partition_recovery_ops;
status = nfs4_reclaim_open_state(ops, sp);
}
if (status == -NFS4ERR_STALE_CLIENTID)
goto restart_loop;
goto out_error;
if (status == -NFS4ERR_EXPIRED)
goto restart_loop;
}
}
nfs_delegation_reap_unclaimed(clp);
......
......@@ -1010,8 +1010,13 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
WRITE32(readdir->count >> 1); /* We're not doing readdirplus */
WRITE32(readdir->count);
WRITE32(2);
WRITE32(FATTR4_WORD0_FILEID);
WRITE32(0);
if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) {
WRITE32(0);
WRITE32(FATTR4_WORD1_MOUNTED_ON_FILEID);
} else {
WRITE32(FATTR4_WORD0_FILEID);
WRITE32(0);
}
/* set up reply kvec
* toplevel_status + taglen + rescount + OP_PUTFH + status
......@@ -3175,7 +3180,7 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_client *clp)
READ_BUF(4);
READ32(len);
READ_BUF(len);
return -EEXIST;
return -NFSERR_CLID_INUSE;
} else
return -nfs_stat_to_errno(nfserr);
......@@ -3857,7 +3862,7 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, void *d
uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
{
uint32_t bitmap[1] = {0};
uint32_t bitmap[2] = {0};
uint32_t len;
if (!*p++) {
......@@ -3881,13 +3886,18 @@ uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
entry->ino = 1;
len = ntohl(*p++); /* bitmap length */
if (len > 0) {
bitmap[0] = ntohl(*p);
p += len;
if (len-- > 0) {
bitmap[0] = ntohl(*p++);
if (len-- > 0) {
bitmap[1] = ntohl(*p++);
p += len;
}
}
len = XDR_QUADLEN(ntohl(*p++)); /* attribute buffer length */
if (len > 0) {
if (bitmap[0] == FATTR4_WORD0_FILEID)
if (bitmap[0] == 0 && bitmap[1] == FATTR4_WORD1_MOUNTED_ON_FILEID)
xdr_decode_hyper(p, &entry->ino);
else if (bitmap[0] == FATTR4_WORD0_FILEID)
xdr_decode_hyper(p, &entry->ino);
p += len;
}
......
......@@ -124,7 +124,6 @@ enum {
Opt_soft, Opt_hard, Opt_intr,
Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac,
Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp,
Opt_broken_suid,
/* Error token */
Opt_err
};
......@@ -159,7 +158,6 @@ static match_table_t __initdata tokens = {
{Opt_udp, "udp"},
{Opt_tcp, "proto=tcp"},
{Opt_tcp, "tcp"},
{Opt_broken_suid, "broken_suid"},
{Opt_err, NULL}
};
......@@ -268,9 +266,6 @@ static int __init root_nfs_parse(char *name, char *buf)
case Opt_tcp:
nfs_data.flags |= NFS_MOUNT_TCP;
break;
case Opt_broken_suid:
nfs_data.flags |= NFS_MOUNT_BROKEN_SUID;
break;
default :
return 0;
}
......@@ -351,7 +346,7 @@ static void __init root_nfs_print(void)
#endif
int __init root_nfs_init(void)
static int __init root_nfs_init(void)
{
#ifdef NFSROOT_DEBUG
nfs_debug |= NFSDBG_ROOT;
......@@ -379,15 +374,15 @@ int __init root_nfs_init(void)
* Parse NFS server and directory information passed on the kernel
* command line.
*/
int __init nfs_root_setup(char *line)
static int __init nfs_root_setup(char *line)
{
ROOT_DEV = Root_NFS;
if (line[0] == '/' || line[0] == ',' || (line[0] >= '0' && line[0] <= '9')) {
strlcpy(nfs_root_name, line, sizeof(nfs_root_name));
} else {
int n = strlen(line) + strlen(NFS_ROOT);
int n = strlen(line) + sizeof(NFS_ROOT) - 1;
if (n >= sizeof(nfs_root_name))
line[sizeof(nfs_root_name) - strlen(NFS_ROOT) - 1] = '\0';
line[sizeof(nfs_root_name) - sizeof(NFS_ROOT) - 2] = '\0';
sprintf(nfs_root_name, NFS_ROOT, line);
}
root_server_addr = root_nfs_parse_addr(nfs_root_name);
......
......@@ -212,7 +212,7 @@ static int nfs_proc_write(struct nfs_write_data *wdata)
return status < 0? status : wdata->res.count;
}
static struct inode *
static int
nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
int flags)
{
......@@ -233,37 +233,34 @@ nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
fattr.valid = 0;
dprintk("NFS call create %s\n", dentry->d_name.name);
status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
if (status == 0)
status = nfs_instantiate(dentry, &fhandle, &fattr);
dprintk("NFS reply create: %d\n", status);
if (status == 0) {
struct inode *inode;
inode = nfs_fhget(dir->i_sb, &fhandle, &fattr);
if (inode)
return inode;
status = -ENOMEM;
}
return ERR_PTR(status);
return status;
}
/*
* In NFSv2, mknod is grafted onto the create call.
*/
static int
nfs_proc_mknod(struct inode *dir, struct qstr *name, struct iattr *sattr,
dev_t rdev, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
dev_t rdev)
{
struct nfs_fh fhandle;
struct nfs_fattr fattr;
struct nfs_createargs arg = {
.fh = NFS_FH(dir),
.name = name->name,
.len = name->len,
.name = dentry->d_name.name,
.len = dentry->d_name.len,
.sattr = sattr
};
struct nfs_diropok res = {
.fh = fhandle,
.fattr = fattr
.fh = &fhandle,
.fattr = &fattr
};
int status, mode;
int status, mode;
dprintk("NFS call mknod %s\n", name->name);
dprintk("NFS call mknod %s\n", dentry->d_name.name);
mode = sattr->ia_mode;
if (S_ISFIFO(mode)) {
......@@ -274,14 +271,16 @@ nfs_proc_mknod(struct inode *dir, struct qstr *name, struct iattr *sattr,
sattr->ia_size = new_encode_dev(rdev);/* get out your barf bag */
}
fattr->valid = 0;
fattr.valid = 0;
status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
if (status == -EINVAL && S_ISFIFO(mode)) {
sattr->ia_mode = mode;
fattr->valid = 0;
fattr.valid = 0;
status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
}
if (status == 0)
status = nfs_instantiate(dentry, &fhandle, &fattr);
dprintk("NFS reply mknod: %d\n", status);
return status;
}
......@@ -398,24 +397,27 @@ nfs_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
}
static int
nfs_proc_mkdir(struct inode *dir, struct qstr *name, struct iattr *sattr,
struct nfs_fh *fhandle, struct nfs_fattr *fattr)
nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
{
struct nfs_fh fhandle;
struct nfs_fattr fattr;
struct nfs_createargs arg = {
.fh = NFS_FH(dir),
.name = name->name,
.len = name->len,
.name = dentry->d_name.name,
.len = dentry->d_name.len,
.sattr = sattr
};
struct nfs_diropok res = {
.fh = fhandle,
.fattr = fattr
.fh = &fhandle,
.fattr = &fattr
};
int status;
dprintk("NFS call mkdir %s\n", name->name);
fattr->valid = 0;
dprintk("NFS call mkdir %s\n", dentry->d_name.name);
fattr.valid = 0;
status = rpc_call(NFS_CLIENT(dir), NFSPROC_MKDIR, &arg, &res, 0);
if (status == 0)
status = nfs_instantiate(dentry, &fhandle, &fattr);
dprintk("NFS reply mkdir: %d\n", status);
return status;
}
......
......@@ -370,7 +370,7 @@ static int nfs_pagein_one(struct list_head *head, struct inode *inode)
return -ENOMEM;
}
int
static int
nfs_pagein_list(struct list_head *head, int rpages)
{
LIST_HEAD(one_request);
......
......@@ -167,6 +167,11 @@ nfs_async_unlink(struct dentry *dentry)
goto out;
memset(data, 0, sizeof(*data));
data->cred = rpcauth_lookupcred(clnt->cl_auth, 0);
if (IS_ERR(data->cred)) {
status = PTR_ERR(data->cred);
goto out_free;
}
data->dir = dget(dir);
data->dentry = dentry;
......@@ -183,12 +188,14 @@ nfs_async_unlink(struct dentry *dentry)
spin_lock(&dentry->d_lock);
dentry->d_flags |= DCACHE_NFSFS_RENAMED;
spin_unlock(&dentry->d_lock);
data->cred = rpcauth_lookupcred(clnt->cl_auth, 0);
rpc_sleep_on(&nfs_delete_queue, task, NULL, NULL);
status = 0;
out:
return status;
out_free:
kfree(data);
return status;
}
/**
......
......@@ -80,14 +80,31 @@ static void nfs_writeback_done_partial(struct nfs_write_data *, int);
static void nfs_writeback_done_full(struct nfs_write_data *, int);
static int nfs_wait_on_write_congestion(struct address_space *, int);
static int nfs_wait_on_requests(struct inode *, unsigned long, unsigned int);
static int nfs_flush_inode(struct inode *inode, unsigned long idx_start,
unsigned int npages, int how);
static kmem_cache_t *nfs_wdata_cachep;
mempool_t *nfs_wdata_mempool;
mempool_t *nfs_commit_mempool;
static mempool_t *nfs_commit_mempool;
static DECLARE_WAIT_QUEUE_HEAD(nfs_write_congestion);
void nfs_writedata_release(struct rpc_task *task)
static inline struct nfs_write_data *nfs_commit_alloc(void)
{
struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, SLAB_NOFS);
if (p) {
memset(p, 0, sizeof(*p));
INIT_LIST_HEAD(&p->pages);
}
return p;
}
static inline void nfs_commit_free(struct nfs_write_data *p)
{
mempool_free(p, nfs_commit_mempool);
}
static void nfs_writedata_release(struct rpc_task *task)
{
struct nfs_write_data *wdata = (struct nfs_write_data *)task->tk_calldata;
nfs_writedata_free(wdata);
......@@ -990,7 +1007,7 @@ static int nfs_flush_one(struct list_head *head, struct inode *inode, int how)
return -ENOMEM;
}
int
static int
nfs_flush_list(struct list_head *head, int wpages, int how)
{
LIST_HEAD(one_request);
......@@ -1240,7 +1257,7 @@ static void nfs_commit_rpcsetup(struct list_head *head,
/*
* Commit dirty pages
*/
int
static int
nfs_commit_list(struct list_head *head, int how)
{
struct nfs_write_data *data;
......@@ -1314,8 +1331,8 @@ nfs_commit_done(struct rpc_task *task)
}
#endif
int nfs_flush_inode(struct inode *inode, unsigned long idx_start,
unsigned int npages, int how)
static int nfs_flush_inode(struct inode *inode, unsigned long idx_start,
unsigned int npages, int how)
{
struct nfs_inode *nfsi = NFS_I(inode);
LIST_HEAD(head);
......
......@@ -446,7 +446,7 @@ nfsd4_probe_callback(struct nfs4_client *clp)
atomic_inc(&clp->cl_count);
msg.rpc_cred = nfsd4_lookupcred(clp,0);
if (msg.rpc_cred == NULL)
if (IS_ERR(msg.rpc_cred))
goto out_rpciod;
status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, nfs4_cb_null, NULL);
put_rpccred(msg.rpc_cred);
......@@ -512,7 +512,7 @@ nfsd4_cb_recall(struct nfs4_delegation *dp)
return;
msg.rpc_cred = nfsd4_lookupcred(clp, 0);
if (msg.rpc_cred == NULL)
if (IS_ERR(msg.rpc_cred))
goto out;
cbr->cbr_trunc = 0; /* XXX need to implement truncate optimization */
......
......@@ -11,6 +11,8 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Modifications:
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/
#include <asm/arch/map.h>
......@@ -24,7 +26,7 @@
mrc p15, 0, \rx, c1, c0
tst \rx, #1
ldreq \rx, = S3C2410_PA_UART
ldrne \rx, = S3C2410_VA_UART
ldrne \rx, = S3C24XX_VA_UART
#if CONFIG_DEBUG_S3C2410_UART != 0
add \rx, \rx, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C2410_UART)
#endif
......@@ -43,7 +45,7 @@
mrc p15, 0, \rd, c1, c0
tst \rd, #1
addeq \rd, \rx, #(S3C2410_PA_GPIO - S3C2410_PA_UART)
addne \rd, \rx, #(S3C2410_VA_GPIO - S3C2410_VA_UART)
addne \rd, \rx, #(S3C24XX_VA_GPIO - S3C24XX_VA_UART)
bic \rd, \rd, #0xff000
ldr \rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ]
and \rd, \rd, #0x00ff0000
......@@ -74,7 +76,7 @@
mrc p15, 0, \rd, c1, c0
tst \rd, #1
addeq \rd, \rx, #(S3C2410_PA_GPIO - S3C2410_PA_UART)
addne \rd, \rx, #(S3C2410_VA_GPIO - S3C2410_VA_UART)
addne \rd, \rx, #(S3C24XX_VA_GPIO - S3C24XX_VA_UART)
bic \rd, \rd, #0xff000
ldr \rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ]
and \rd, \rd, #0x00ff0000
......
......@@ -6,12 +6,15 @@
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
* Modifications:
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov \tmp, #S3C2410_VA_IRQ
mov \tmp, #S3C24XX_VA_IRQ
ldr \irqnr, [ \tmp, #0x14 ] @ get irq no
30000:
teq \irqnr, #4
......@@ -45,7 +48,7 @@
.align 4
20004:
mov r1, #1
mov \tmp, #S3C2410_VA_IRQ
mov \tmp, #S3C24XX_VA_IRQ
ldmfd r13!, { r0 - r4 , r8-r12, r14 }
#endif
......@@ -83,7 +86,7 @@
@ we get here from no main or external interrupts pending
1002:
add \tmp, \tmp, #S3C2410_VA_GPIO - S3C2410_VA_IRQ
add \tmp, \tmp, #S3C24XX_VA_GPIO - S3C24XX_VA_IRQ
ldr \irqstat, [ \tmp, # 0xa8 ] @ EXTINTPEND
ldr \irqnr, [ \tmp, # 0xa4 ] @ EXTINTMASK
......
......@@ -8,6 +8,7 @@
* Modifications:
* 06-Dec-1997 RMK Created.
* 02-Sep-2003 BJD Modified for S3C2410
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*
*/
......@@ -26,10 +27,10 @@
#define __PORT_PCIO(x) ((x) < (1<<28))
#define PCIO_BASE (S3C2410_VA_ISA_WORD)
#define PCIO_BASE_b (S3C2410_VA_ISA_BYTE)
#define PCIO_BASE_w (S3C2410_VA_ISA_WORD)
#define PCIO_BASE_l (S3C2410_VA_ISA_WORD)
#define PCIO_BASE (S3C24XX_VA_ISA_WORD)
#define PCIO_BASE_b (S3C24XX_VA_ISA_BYTE)
#define PCIO_BASE_w (S3C24XX_VA_ISA_WORD)
#define PCIO_BASE_l (S3C24XX_VA_ISA_WORD)
/*
* Dynamic IO functions - let the compiler
* optimize the expressions
......
......@@ -10,9 +10,10 @@
* published by the Free Software Foundation.
*
* Changelog:
* 12-May-2003 BJD Created file
* 06-Jan-2003 BJD Linux 2.6.0 version, moved bast specifics out
* 10-Feb-2005 BJD Added CAMIF definition from guillaume.gourat@nexvision.tv
* 12-May-2003 BJD Created file
* 06-Jan-2003 BJD Linux 2.6.0 version, moved bast specifics out
* 10-Feb-2005 BJD Added CAMIF definition from guillaume.gourat@nexvision.tv
* 10-Mar-2005 LCVR Added support to S3C2400, changed {VA,SZ} names
*/
#ifndef __ASM_ARCH_MAP_H
......@@ -30,100 +31,122 @@
*/
#define S3C2410_ADDR(x) (0xF0000000 + (x))
#define S3C2400_ADDR(x) S3C2410_ADDR(x)
/* interrupt controller is the first thing we put in, to make
* the assembly code for the irq detection easier
*/
#define S3C2410_VA_IRQ S3C2410_ADDR(0x00000000)
#define S3C24XX_VA_IRQ S3C2410_ADDR(0x00000000)
#define S3C2400_PA_IRQ (0x14400000)
#define S3C2410_PA_IRQ (0x4A000000)
#define S3C2410_SZ_IRQ SZ_1M
#define S3C24XX_SZ_IRQ SZ_1M
/* memory controller registers */
#define S3C2410_VA_MEMCTRL S3C2410_ADDR(0x00100000)
#define S3C24XX_VA_MEMCTRL S3C2410_ADDR(0x00100000)
#define S3C2400_PA_MEMCTRL (0x14000000)
#define S3C2410_PA_MEMCTRL (0x48000000)
#define S3C2410_SZ_MEMCTRL SZ_1M
#define S3C24XX_SZ_MEMCTRL SZ_1M
/* USB host controller */
#define S3C2410_VA_USBHOST S3C2410_ADDR(0x00200000)
#define S3C24XX_VA_USBHOST S3C2410_ADDR(0x00200000)
#define S3C2400_PA_USBHOST (0x14200000)
#define S3C2410_PA_USBHOST (0x49000000)
#define S3C2410_SZ_USBHOST SZ_1M
#define S3C24XX_SZ_USBHOST SZ_1M
/* DMA controller */
#define S3C2410_VA_DMA S3C2410_ADDR(0x00300000)
#define S3C24XX_VA_DMA S3C2410_ADDR(0x00300000)
#define S3C2400_PA_DMA (0x14600000)
#define S3C2410_PA_DMA (0x4B000000)
#define S3C2410_SZ_DMA SZ_1M
#define S3C24XX_SZ_DMA SZ_1M
/* Clock and Power management */
#define S3C2410_VA_CLKPWR S3C2410_ADDR(0x00400000)
#define S3C24XX_VA_CLKPWR S3C2410_ADDR(0x00400000)
#define S3C2400_PA_CLKPWR (0x14800000)
#define S3C2410_PA_CLKPWR (0x4C000000)
#define S3C2410_SZ_CLKPWR SZ_1M
#define S3C24XX_SZ_CLKPWR SZ_1M
/* LCD controller */
#define S3C2410_VA_LCD S3C2410_ADDR(0x00600000)
#define S3C24XX_VA_LCD S3C2410_ADDR(0x00600000)
#define S3C2400_PA_LCD (0x14A00000)
#define S3C2410_PA_LCD (0x4D000000)
#define S3C2410_SZ_LCD SZ_1M
#define S3C24XX_SZ_LCD SZ_1M
/* NAND flash controller */
#define S3C2410_VA_NAND S3C2410_ADDR(0x00700000)
#define S3C24XX_VA_NAND S3C2410_ADDR(0x00700000)
#define S3C2410_PA_NAND (0x4E000000)
#define S3C2410_SZ_NAND SZ_1M
#define S3C24XX_SZ_NAND SZ_1M
/* MMC controller - available on the S3C2400 */
#define S3C2400_VA_MMC S3C2400_ADDR(0x00700000)
#define S3C2400_PA_MMC (0x15A00000)
#define S3C2400_SZ_MMC SZ_1M
/* UARTs */
#define S3C2410_VA_UART S3C2410_ADDR(0x00800000)
#define S3C24XX_VA_UART S3C2410_ADDR(0x00800000)
#define S3C2400_PA_UART (0x15000000)
#define S3C2410_PA_UART (0x50000000)
#define S3C2410_SZ_UART SZ_1M
#define S3C24XX_SZ_UART SZ_1M
/* Timers */
#define S3C2410_VA_TIMER S3C2410_ADDR(0x00900000)
#define S3C24XX_VA_TIMER S3C2410_ADDR(0x00900000)
#define S3C2400_PA_TIMER (0x15100000)
#define S3C2410_PA_TIMER (0x51000000)
#define S3C2410_SZ_TIMER SZ_1M
#define S3C24XX_SZ_TIMER SZ_1M
/* USB Device port */
#define S3C2410_VA_USBDEV S3C2410_ADDR(0x00A00000)
#define S3C24XX_VA_USBDEV S3C2410_ADDR(0x00A00000)
#define S3C2400_PA_USBDEV (0x15200140)
#define S3C2410_PA_USBDEV (0x52000000)
#define S3C2410_SZ_USBDEV SZ_1M
#define S3C24XX_SZ_USBDEV SZ_1M
/* Watchdog */
#define S3C2410_VA_WATCHDOG S3C2410_ADDR(0x00B00000)
#define S3C24XX_VA_WATCHDOG S3C2410_ADDR(0x00B00000)
#define S3C2400_PA_WATCHDOG (0x15300000)
#define S3C2410_PA_WATCHDOG (0x53000000)
#define S3C2410_SZ_WATCHDOG SZ_1M
#define S3C24XX_SZ_WATCHDOG SZ_1M
/* IIC hardware controller */
#define S3C2410_VA_IIC S3C2410_ADDR(0x00C00000)
#define S3C24XX_VA_IIC S3C2410_ADDR(0x00C00000)
#define S3C2400_PA_IIC (0x15400000)
#define S3C2410_PA_IIC (0x54000000)
#define S3C2410_SZ_IIC SZ_1M
#define S3C24XX_SZ_IIC SZ_1M
#define VA_IIC_BASE (S3C2410_VA_IIC)
#define VA_IIC_BASE (S3C24XX_VA_IIC)
/* IIS controller */
#define S3C2410_VA_IIS S3C2410_ADDR(0x00D00000)
#define S3C24XX_VA_IIS S3C2410_ADDR(0x00D00000)
#define S3C2400_PA_IIS (0x15508000)
#define S3C2410_PA_IIS (0x55000000)
#define S3C2410_SZ_IIS SZ_1M
#define S3C24XX_SZ_IIS SZ_1M
/* GPIO ports */
#define S3C2410_VA_GPIO S3C2410_ADDR(0x00E00000)
#define S3C24XX_VA_GPIO S3C2410_ADDR(0x00E00000)
#define S3C2400_PA_GPIO (0x15600000)
#define S3C2410_PA_GPIO (0x56000000)
#define S3C2410_SZ_GPIO SZ_1M
#define S3C24XX_SZ_GPIO SZ_1M
/* RTC */
#define S3C2410_VA_RTC S3C2410_ADDR(0x00F00000)
#define S3C24XX_VA_RTC S3C2410_ADDR(0x00F00000)
#define S3C2400_PA_RTC (0x15700040)
#define S3C2410_PA_RTC (0x57000000)
#define S3C2410_SZ_RTC SZ_1M
#define S3C24XX_SZ_RTC SZ_1M
/* ADC */
#define S3C2410_VA_ADC S3C2410_ADDR(0x01000000)
#define S3C24XX_VA_ADC S3C2410_ADDR(0x01000000)
#define S3C2400_PA_ADC (0x15800000)
#define S3C2410_PA_ADC (0x58000000)
#define S3C2410_SZ_ADC SZ_1M
#define S3C24XX_SZ_ADC SZ_1M
/* SPI */
#define S3C2410_VA_SPI S3C2410_ADDR(0x01100000)
#define S3C24XX_VA_SPI S3C2410_ADDR(0x01100000)
#define S3C2400_PA_SPI (0x15900000)
#define S3C2410_PA_SPI (0x59000000)
#define S3C2410_SZ_SPI SZ_1M
#define S3C24XX_SZ_SPI SZ_1M
/* SDI */
#define S3C2410_VA_SDI S3C2410_ADDR(0x01200000)
#define S3C24XX_VA_SDI S3C2410_ADDR(0x01200000)
#define S3C2410_PA_SDI (0x5A000000)
#define S3C2410_SZ_SDI SZ_1M
#define S3C24XX_SZ_SDI SZ_1M
/* CAMIF */
#define S3C2440_PA_CAMIF (0x4F000000)
......@@ -133,8 +156,8 @@
* implements it. We reserve two 16M regions for ISA.
*/
#define S3C2410_VA_ISA_WORD S3C2410_ADDR(0x02000000)
#define S3C2410_VA_ISA_BYTE S3C2410_ADDR(0x03000000)
#define S3C24XX_VA_ISA_WORD S3C2410_ADDR(0x02000000)
#define S3C24XX_VA_ISA_BYTE S3C2410_ADDR(0x03000000)
/* physical addresses of all the chip-select areas */
......@@ -149,5 +172,16 @@
#define S3C2410_SDRAM_PA (S3C2410_CS6)
#define S3C2400_CS0 (0x00000000)
#define S3C2400_CS1 (0x02000000)
#define S3C2400_CS2 (0x04000000)
#define S3C2400_CS3 (0x06000000)
#define S3C2400_CS4 (0x08000000)
#define S3C2400_CS5 (0x0A000000)
#define S3C2400_CS6 (0x0C000000)
#define S3C2400_CS7 (0x0E000000)
#define S3C2400_SDRAM_PA (S3C2400_CS6)
#endif /* __ASM_ARCH_MAP_H */
......@@ -10,18 +10,19 @@
* S3C2410 clock register definitions
*
* Changelog:
* 18-Aug-2004 Ben Dooks Added 2440 definitions
* 08-Aug-2004 Herbert Ptzl Added CLKCON definitions
* 19-06-2003 Ben Dooks Created file
* 12-03-2004 Ben Dooks Updated include protection
* 29-Sep-2004 Ben Dooks Fixed usage for assembly inclusion
* 10-Feb-2005 Ben Dooks Fixed CAMDIVN address (Guillaume Gourat)
* 18-Aug-2004 Ben Dooks Added 2440 definitions
* 08-Aug-2004 Herbert Ptzl Added CLKCON definitions
* 19-06-2003 Ben Dooks Created file
* 12-03-2004 Ben Dooks Updated include protection
* 29-Sep-2004 Ben Dooks Fixed usage for assembly inclusion
* 10-Feb-2005 Ben Dooks Fixed CAMDIVN address (Guillaume Gourat)
* 10-Mar-2005 Lucas Villa Real Changed S3C2410_VA to S3C24XX_VA
*/
#ifndef __ASM_ARM_REGS_CLOCK
#define __ASM_ARM_REGS_CLOCK "$Id: clock.h,v 1.4 2003/04/30 14:50:51 ben Exp $"
#define S3C2410_CLKREG(x) ((x) + S3C2410_VA_CLKPWR)
#define S3C2410_CLKREG(x) ((x) + S3C24XX_VA_CLKPWR)
#define S3C2410_PLLVAL(_m,_p,_s) ((_m) << 12 | ((_p) << 4) | ((_s)))
......
......@@ -18,6 +18,7 @@
* 17-10-2004 BJD Added GSTATUS1 register definitions
* 18-11-2004 BJD Fixed definitions of GPE3, GPE4, GPE5 and GPE6
* 18-11-2004 BJD Added S3C2440 AC97 controls
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/
......@@ -35,7 +36,7 @@
#define S3C2410_GPIO_BANKG (32*6)
#define S3C2410_GPIO_BANKH (32*7)
#define S3C2410_GPIO_BASE(pin) ((((pin) & ~31) >> 1) + S3C2410_VA_GPIO)
#define S3C2410_GPIO_BASE(pin) ((((pin) & ~31) >> 1) + S3C24XX_VA_GPIO)
#define S3C2410_GPIO_OFFSET(pin) ((pin) & 31)
/* general configuration options */
......@@ -44,7 +45,7 @@
/* configure GPIO ports A..G */
#define S3C2410_GPIOREG(x) ((x) + S3C2410_VA_GPIO)
#define S3C2410_GPIOREG(x) ((x) + S3C24XX_VA_GPIO)
/* port A - 22bits, zero in bit X makes pin X output
* 1 makes port special function, this is default
......
......@@ -13,6 +13,7 @@
* 19-06-2003 BJD Created file
* 26-06-2003 BJD Finished off definitions for register addresses
* 12-03-2004 BJD Updated include protection
* 07-03-2005 BJD Added FIFO size flags and S3C2440 MPLL
*/
#ifndef __ASM_ARCH_REGS_IIS_H
......@@ -20,6 +21,7 @@
#define S3C2410_IISCON (0x00)
#define S3C2440_IISCON_MPLL (1<<9)
#define S3C2410_IISCON_LRINDEX (1<<8)
#define S3C2410_IISCON_TXFIFORDY (1<<7)
#define S3C2410_IISCON_RXFIFORDY (1<<6)
......@@ -42,6 +44,7 @@
#define S3C2410_IISMOD_MSB (1<<4)
#define S3C2410_IISMOD_8BIT (0<<3)
#define S3C2410_IISMOD_16BIT (1<<3)
#define S3C2410_IISMOD_BITMASK (1<<3)
#define S3C2410_IISMOD_256FS (0<<1)
#define S3C2410_IISMOD_384FS (1<<1)
#define S3C2410_IISMOD_16FS (0<<0)
......@@ -50,7 +53,7 @@
#define S3C2410_IISPSR (0x08)
#define S3C2410_IISPSR_INTMASK (31<<5)
#define S3C2410_IISPSR_INTSHFIT (5)
#define S3C2410_IISPSR_INTSHIFT (5)
#define S3C2410_IISPSR_EXTMASK (31<<0)
#define S3C2410_IISPSR_EXTSHFIT (0)
......@@ -60,8 +63,10 @@
#define S3C2410_IISFCON_RXDMA (1<<14)
#define S3C2410_IISFCON_TXENABLE (1<<13)
#define S3C2410_IISFCON_RXENABLE (1<<12)
#define S3C2410_IISFCON_TXMASK (0x3f << 6)
#define S3C2410_IISFCON_TXSHIFT (6)
#define S3C2410_IISFCON_RXMASK (0x3f)
#define S3C2410_IISFCON_RXSHIFT (0)
#define S3C2410_IISFIFO (0x10)
#endif /* __ASM_ARCH_REGS_IIS_H */
......@@ -12,6 +12,7 @@
* Changelog:
* 19-06-2003 BJD Created file
* 12-03-2004 BJD Updated include protection
* 10-03-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/
......@@ -20,8 +21,8 @@
/* interrupt controller */
#define S3C2410_IRQREG(x) ((x) + S3C2410_VA_IRQ)
#define S3C2410_EINTREG(x) ((x) + S3C2410_VA_GPIO)
#define S3C2410_IRQREG(x) ((x) + S3C24XX_VA_IRQ)
#define S3C2410_EINTREG(x) ((x) + S3C24XX_VA_GPIO)
#define S3C2410_SRCPND S3C2410_IRQREG(0x000)
#define S3C2410_INTMOD S3C2410_IRQREG(0x004)
......
......@@ -13,13 +13,14 @@
* 12-06-2003 BJD Created file
* 26-06-2003 BJD Updated LCDCON register definitions
* 12-03-2004 BJD Updated include protection
* 10-03-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/
#ifndef ___ASM_ARCH_REGS_LCD_H
#define ___ASM_ARCH_REGS_LCD_H "$Id: lcd.h,v 1.3 2003/06/26 13:25:06 ben Exp $"
#define S3C2410_LCDREG(x) ((x) + S3C2410_VA_LCD)
#define S3C2410_LCDREG(x) ((x) + S3C24XX_VA_LCD)
/* LCD control registers */
#define S3C2410_LCDCON1 S3C2410_LCDREG(0x00)
......
......@@ -11,6 +11,7 @@
*
* Changelog:
* 29-Sep-2004 BJD Initial include for Linux
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*
*/
......@@ -18,7 +19,7 @@
#define __ASM_ARM_MEMREGS_H "$Id: regs.h,v 1.8 2003/05/01 15:55:41 ben Exp $"
#ifndef S3C2410_MEMREG
#define S3C2410_MEMREG(x) (S3C2410_VA_MEMCTRL + (x))
#define S3C2410_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
#endif
/* bus width, and wait state control */
......
......@@ -12,12 +12,13 @@
* Changelog:
* 19-06-2003 BJD Created file
* 12-03-2004 BJD Updated include protection
* 15-01-2005 LCVR Changed S3C2410_VA to S3C24XX_VA (s3c2400 support)
*/
#ifndef __ASM_ARCH_REGS_RTC_H
#define __ASM_ARCH_REGS_RTC_H __FILE__
#define S3C2410_RTCREG(x) ((x) + S3C2410_VA_RTC)
#define S3C2410_RTCREG(x) ((x) + S3C24XX_VA_RTC)
#define S3C2410_RTCCON S3C2410_RTCREG(0x40)
#define S3C2410_RTCCON_RTCEN (1<<0)
......
......@@ -27,14 +27,17 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Modifications:
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA (s3c2400 support)
*/
#ifndef __ASM_ARM_REGS_SERIAL_H
#define __ASM_ARM_REGS_SERIAL_H
#define S3C2410_VA_UART0 (S3C2410_VA_UART)
#define S3C2410_VA_UART1 (S3C2410_VA_UART + 0x4000 )
#define S3C2410_VA_UART2 (S3C2410_VA_UART + 0x8000 )
#define S3C24XX_VA_UART0 (S3C24XX_VA_UART)
#define S3C24XX_VA_UART1 (S3C24XX_VA_UART + 0x4000 )
#define S3C24XX_VA_UART2 (S3C24XX_VA_UART + 0x8000 )
#define S3C2410_PA_UART0 (S3C2410_PA_UART)
#define S3C2410_PA_UART1 (S3C2410_PA_UART + 0x4000 )
......
......@@ -14,13 +14,14 @@
* 26-06-2003 BJD Added more timer definitions to mux / control
* 12-03-2004 BJD Updated include protection
* 10-02-2005 BJD Added S3C2410_TCFG1_MUX4_SHIFT (Guillaume Gourat)
* 10-03-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/
#ifndef __ASM_ARCH_REGS_TIMER_H
#define __ASM_ARCH_REGS_TIMER_H "$Id: timer.h,v 1.4 2003/05/06 19:30:50 ben Exp $"
#define S3C2410_TIMERREG(x) (S3C2410_VA_TIMER + (x))
#define S3C2410_TIMERREG(x) (S3C24XX_VA_TIMER + (x))
#define S3C2410_TIMERREG2(tmr,reg) S3C2410_TIMERREG((reg)+0x0c+((tmr)*0x0c))
#define S3C2410_TCFG0 S3C2410_TIMERREG(0x00)
......
......@@ -11,13 +11,14 @@
* 01-08-2004 Initial creation
* 12-09-2004 Cleanup for submission
* 24-10-2004 Fixed S3C2410_UDC_MAXP_REG definition
* 10-03-2005 Changed S3C2410_VA to S3C24XX_VA
*/
#ifndef __ASM_ARCH_REGS_UDC_H
#define __ASM_ARCH_REGS_UDC_H
#define S3C2410_USBDREG(x) ((x) + S3C2410_VA_USBDEV)
#define S3C2410_USBDREG(x) ((x) + S3C24XX_VA_USBDEV)
#define S3C2410_UDC_FUNC_ADDR_REG S3C2410_USBDREG(0x0140)
#define S3C2410_UDC_PWR_REG S3C2410_USBDREG(0x0144)
......
......@@ -12,13 +12,14 @@
* Changelog:
* 21-06-2003 BJD Created file
* 12-03-2004 BJD Updated include protection
* 10-03-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/
#ifndef __ASM_ARCH_REGS_WATCHDOG_H
#define __ASM_ARCH_REGS_WATCHDOG_H "$Id: watchdog.h,v 1.2 2003/04/29 13:31:09 ben Exp $"
#define S3C2410_WDOGREG(x) ((x) + S3C2410_VA_WATCHDOG)
#define S3C2410_WDOGREG(x) ((x) + S3C24XX_VA_WATCHDOG)
#define S3C2410_WTCON S3C2410_WDOGREG(0x00)
#define S3C2410_WTDAT S3C2410_WDOGREG(0x04)
......
......@@ -27,13 +27,18 @@
#define UNI_N_CFG_AGP_BASE 0x90
#define UNI_N_CFG_GART_CTRL 0x94
#define UNI_N_CFG_INTERNAL_STATUS 0x98
#define UNI_N_CFG_GART_DUMMY_PAGE 0xa4
/* UNI_N_CFG_GART_CTRL bits definitions */
/* Not U3 */
#define UNI_N_CFG_GART_INVAL 0x00000001
#define UNI_N_CFG_GART_ENABLE 0x00000100
#define UNI_N_CFG_GART_2xRESET 0x00010000
#define UNI_N_CFG_GART_DISSBADET 0x00020000
/* The following seems to only be used only on U3 <j.glisse@gmail.com> */
#define U3_N_CFG_GART_SYNCMODE 0x00040000
#define U3_N_CFG_GART_PERFRD 0x00080000
#define U3_N_CFG_GART_B2BGNT 0x00200000
#define U3_N_CFG_GART_FASTDDR 0x00400000
/* My understanding of UniNorth AGP as of UniNorth rev 1.0x,
* revision 1.5 (x4 AGP) may need further changes.
......
#ifndef AGP_H
#define AGP_H 1
#include <asm/io.h>
/* nothing much needed here */
#define map_page_into_agp(page)
#define unmap_page_from_agp(page)
#define flush_agp_mappings()
#define flush_agp_cache() mb()
#endif
......@@ -42,7 +42,6 @@ struct nlm_host {
struct rpc_clnt * h_rpcclnt; /* RPC client to talk to peer */
char h_name[20]; /* remote hostname */
u32 h_version; /* interface version */
rpc_authflavor_t h_authflavor; /* RPC authentication type */
unsigned short h_proto; /* transport proto */
unsigned short h_reclaiming : 1,
h_server : 1, /* server side, not client side */
......@@ -143,8 +142,6 @@ extern unsigned long nlmsvc_timeout;
* Lockd client functions
*/
struct nlm_rqst * nlmclnt_alloc_call(void);
int nlmclnt_call(struct nlm_rqst *, u32);
int nlmclnt_async_call(struct nlm_rqst *, u32, rpc_action);
int nlmclnt_block(struct nlm_host *, struct file_lock *, u32 *);
int nlmclnt_cancel(struct nlm_host *, struct file_lock *);
u32 nlmclnt_grant(struct nlm_lock *);
......
......@@ -39,12 +39,14 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
* - ending slashes ok even for nonexistent files
* - internal "there are more path compnents" flag
* - locked when lookup done with dcache_lock held
* - dentry cache is untrusted; force a real lookup
*/
#define LOOKUP_FOLLOW 1
#define LOOKUP_DIRECTORY 2
#define LOOKUP_CONTINUE 4
#define LOOKUP_PARENT 16
#define LOOKUP_NOALT 32
#define LOOKUP_REVAL 64
/*
* Intent data
*/
......
......@@ -345,16 +345,13 @@ extern struct inode_operations nfs_dir_inode_operations;
extern struct file_operations nfs_dir_operations;
extern struct dentry_operations nfs_dentry_operations;
extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr);
/*
* linux/fs/nfs/symlink.c
*/
extern struct inode_operations nfs_symlink_inode_operations;
/*
* linux/fs/nfs/locks.c
*/
extern int nfs_lock(struct file *, int, struct file_lock *);
/*
* linux/fs/nfs/unlink.c
*/
......@@ -379,11 +376,8 @@ extern void nfs_commit_done(struct rpc_task *);
* return value!)
*/
extern int nfs_sync_inode(struct inode *, unsigned long, unsigned int, int);
extern int nfs_flush_inode(struct inode *, unsigned long, unsigned int, int);
extern int nfs_flush_list(struct list_head *, int, int);
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
extern int nfs_commit_inode(struct inode *, unsigned long, unsigned int, int);
extern int nfs_commit_list(struct list_head *, int);
#else
static inline int
nfs_commit_inode(struct inode *inode, unsigned long idx_start, unsigned int npages, int how)
......@@ -424,7 +418,6 @@ static inline int nfs_wb_page(struct inode *inode, struct page* page)
* Allocate and free nfs_write_data structures
*/
extern mempool_t *nfs_wdata_mempool;
extern mempool_t *nfs_commit_mempool;
static inline struct nfs_write_data *nfs_writedata_alloc(void)
{
......@@ -441,23 +434,6 @@ static inline void nfs_writedata_free(struct nfs_write_data *p)
mempool_free(p, nfs_wdata_mempool);
}
extern void nfs_writedata_release(struct rpc_task *task);
static inline struct nfs_write_data *nfs_commit_alloc(void)
{
struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, SLAB_NOFS);
if (p) {
memset(p, 0, sizeof(*p));
INIT_LIST_HEAD(&p->pages);
}
return p;
}
static inline void nfs_commit_free(struct nfs_write_data *p)
{
mempool_free(p, nfs_commit_mempool);
}
/* Hack for future NFS swap support */
#ifndef IS_SWAPFILE
# define IS_SWAPFILE(inode) (0)
......@@ -469,7 +445,6 @@ static inline void nfs_commit_free(struct nfs_write_data *p)
extern int nfs_readpage(struct file *, struct page *);
extern int nfs_readpages(struct file *, struct address_space *,
struct list_head *, unsigned);
extern int nfs_pagein_list(struct list_head *, int);
extern void nfs_readpage_result(struct rpc_task *);
/*
......@@ -610,6 +585,9 @@ struct nfs4_client {
wait_queue_head_t cl_waitq;
struct rpc_wait_queue cl_rpcwaitq;
/* used for the setclientid verifier */
struct timespec cl_boot_time;
/* idmapper */
struct idmap * cl_idmap;
......@@ -617,6 +595,7 @@ struct nfs4_client {
* This is used to generate the clientid, and the callback address.
*/
char cl_ipaddr[16];
unsigned char cl_id_uniquifier;
};
/*
......@@ -696,21 +675,26 @@ struct nfs4_exception {
int retry;
};
struct nfs4_state_recovery_ops {
int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *);
int (*recover_lock)(struct nfs4_state *, struct file_lock *);
};
extern struct dentry_operations nfs4_dentry_operations;
extern struct inode_operations nfs4_dir_inode_operations;
/* nfs4proc.c */
extern int nfs4_map_errors(int err);
extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short);
extern int nfs4_proc_setclientid_confirm(struct nfs4_client *);
extern int nfs4_open_reclaim(struct nfs4_state_owner *, struct nfs4_state *);
extern int nfs4_proc_async_renew(struct nfs4_client *);
extern int nfs4_proc_renew(struct nfs4_client *);
extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode);
extern int nfs4_wait_clnt_recover(struct rpc_clnt *, struct nfs4_client *);
extern struct inode *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
extern int nfs4_open_revalidate(struct inode *, struct dentry *, int);
extern int nfs4_handle_exception(struct nfs_server *, int, struct nfs4_exception *);
extern int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request);
extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops;
/* nfs4renewd.c */
extern void nfs4_schedule_state_renewal(struct nfs4_client *);
......@@ -728,6 +712,7 @@ extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *);
extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
extern void nfs4_put_state_owner(struct nfs4_state_owner *);
extern void nfs4_drop_state_owner(struct nfs4_state_owner *);
extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
extern void nfs4_put_open_state(struct nfs4_state *);
extern void nfs4_close_state(struct nfs4_state *, mode_t);
......
......@@ -53,5 +53,6 @@ struct nfs_server {
#define NFS_CAP_HARDLINKS (1U << 1)
#define NFS_CAP_SYMLINKS (1U << 2)
#define NFS_CAP_ACLS (1U << 3)
#define NFS_CAP_ATOMIC_OPEN (1U << 4)
#endif
......@@ -563,6 +563,7 @@ struct nfs4_readdir_arg {
u32 count;
struct page ** pages; /* zero-copy data */
unsigned int pgbase; /* zero-copy data */
const u32 * bitmask;
};
struct nfs4_readdir_res {
......@@ -681,7 +682,7 @@ struct nfs_rpc_ops {
int (*read) (struct nfs_read_data *);
int (*write) (struct nfs_write_data *);
int (*commit) (struct nfs_write_data *);
struct inode * (*create) (struct inode *, struct dentry *,
int (*create) (struct inode *, struct dentry *,
struct iattr *, int);
int (*remove) (struct inode *, struct qstr *);
int (*unlink_setup) (struct rpc_message *,
......@@ -693,13 +694,12 @@ struct nfs_rpc_ops {
int (*symlink) (struct inode *, struct qstr *, struct qstr *,
struct iattr *, struct nfs_fh *,
struct nfs_fattr *);
int (*mkdir) (struct inode *, struct qstr *, struct iattr *,
struct nfs_fh *, struct nfs_fattr *);
int (*mkdir) (struct inode *, struct dentry *, struct iattr *);
int (*rmdir) (struct inode *, struct qstr *);
int (*readdir) (struct dentry *, struct rpc_cred *,
u64, struct page *, unsigned int, int);
int (*mknod) (struct inode *, struct qstr *, struct iattr *,
dev_t, struct nfs_fh *, struct nfs_fattr *);
int (*mknod) (struct inode *, struct dentry *, struct iattr *,
dev_t);
int (*statfs) (struct nfs_server *, struct nfs_fh *,
struct nfs_fsstat *);
int (*fsinfo) (struct nfs_server *, struct nfs_fh *,
......@@ -731,7 +731,5 @@ extern struct nfs_rpc_ops nfs_v4_clientops;
extern struct rpc_version nfs_version2;
extern struct rpc_version nfs_version3;
extern struct rpc_version nfs_version4;
extern struct rpc_program nfs_program;
extern struct rpc_stat nfs_rpcstat;
#endif
......@@ -876,10 +876,13 @@
#define PCI_DEVICE_ID_APPLE_IPID_ATA100 0x003b
#define PCI_DEVICE_ID_APPLE_KEYLARGO_I 0x003e
#define PCI_DEVICE_ID_APPLE_K2_ATA100 0x0043
#define PCI_DEVICE_ID_APPLE_U3_AGP 0x004b
#define PCI_DEVICE_ID_APPLE_K2_GMAC 0x004c
#define PCI_DEVICE_ID_APPLE_SH_ATA 0x0050
#define PCI_DEVICE_ID_APPLE_SH_SUNGEM 0x0051
#define PCI_DEVICE_ID_APPLE_SH_FW 0x0052
#define PCI_DEVICE_ID_APPLE_U3L_AGP 0x0058
#define PCI_DEVICE_ID_APPLE_U3H_AGP 0x0059
#define PCI_DEVICE_ID_APPLE_TIGON3 0x1645
#define PCI_VENDOR_ID_YAMAHA 0x1073
......
......@@ -35,8 +35,7 @@ struct auth_cred {
* Client user credentials
*/
struct rpc_cred {
struct list_head cr_hash; /* hash chain */
struct rpc_auth * cr_auth;
struct hlist_node cr_hash; /* hash chain */
struct rpc_credops * cr_ops;
unsigned long cr_expire; /* when to gc */
atomic_t cr_count; /* ref count */
......@@ -59,10 +58,13 @@ struct rpc_cred {
*/
#define RPC_CREDCACHE_NR 8
#define RPC_CREDCACHE_MASK (RPC_CREDCACHE_NR - 1)
struct rpc_cred_cache {
struct hlist_head hashtable[RPC_CREDCACHE_NR];
unsigned long nextgc; /* next garbage collection */
unsigned long expire; /* cache expiry interval */
};
struct rpc_auth {
struct list_head au_credcache[RPC_CREDCACHE_NR];
unsigned long au_expire; /* cache expiry interval */
unsigned long au_nextgc; /* next garbage collection */
unsigned int au_cslack; /* call cred size estimate */
unsigned int au_rslack; /* reply verf size guess */
unsigned int au_flags; /* various flags */
......@@ -73,6 +75,7 @@ struct rpc_auth {
* case) */
atomic_t au_count; /* Reference counter */
struct rpc_cred_cache * au_credcache;
/* per-flavor data */
};
#define RPC_AUTH_PROC_CREDS 0x0010 /* process creds (including
......@@ -91,14 +94,16 @@ struct rpc_authops {
struct rpc_auth * (*create)(struct rpc_clnt *, rpc_authflavor_t);
void (*destroy)(struct rpc_auth *);
struct rpc_cred * (*lookup_cred)(struct rpc_auth *, struct auth_cred *, int);
struct rpc_cred * (*crcreate)(struct rpc_auth*, struct auth_cred *, int);
};
struct rpc_credops {
const char * cr_name; /* Name of the auth flavour */
void (*crdestroy)(struct rpc_cred *);
int (*crmatch)(struct auth_cred *, struct rpc_cred *, int);
u32 * (*crmarshal)(struct rpc_task *, u32 *, int);
u32 * (*crmarshal)(struct rpc_task *, u32 *);
int (*crrefresh)(struct rpc_task *);
u32 * (*crvalidate)(struct rpc_task *, u32 *);
int (*crwrap_req)(struct rpc_task *, kxdrproc_t,
......@@ -130,7 +135,7 @@ int rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
int rpcauth_refreshcred(struct rpc_task *);
void rpcauth_invalcred(struct rpc_task *);
int rpcauth_uptodatecred(struct rpc_task *);
void rpcauth_init_credcache(struct rpc_auth *);
int rpcauth_init_credcache(struct rpc_auth *, unsigned long);
void rpcauth_free_credcache(struct rpc_auth *);
static inline
......
......@@ -68,18 +68,21 @@ struct rpc_gss_init_res {
struct gss_cl_ctx {
atomic_t count;
u32 gc_proc;
enum rpc_gss_proc gc_proc;
u32 gc_seq;
spinlock_t gc_seq_lock;
struct gss_ctx *gc_gss_ctx;
struct xdr_netobj gc_wire_ctx;
u32 gc_win;
unsigned long gc_expiry;
};
struct gss_upcall_msg;
struct gss_cred {
struct rpc_cred gc_base;
u32 gc_flavor;
enum rpc_gss_svc gc_service;
struct gss_cl_ctx *gc_ctx;
struct gss_upcall_msg *gc_upcall;
};
#define gc_uid gc_base.cr_uid
......
......@@ -51,7 +51,6 @@ struct rpc_clnt {
cl_intr : 1,/* interruptible */
cl_chatty : 1,/* be verbose */
cl_autobind : 1,/* use getport() */
cl_droppriv : 1,/* enable NFS suid hack */
cl_oneshot : 1,/* dispose after use */
cl_dead : 1;/* abandoned */
......@@ -129,6 +128,7 @@ void rpc_restart_call(struct rpc_task *);
void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset);
void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset);
void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
size_t rpc_max_payload(struct rpc_clnt *);
static __inline__
int rpc_call(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, int flags)
......
......@@ -33,8 +33,9 @@ struct gss_ctx {
/* gss-api prototypes; note that these are somewhat simplified versions of
* the prototypes specified in RFC 2744. */
u32 gss_import_sec_context(
struct xdr_netobj *input_token,
int gss_import_sec_context(
const void* input_token,
size_t bufsize,
struct gss_api_mech *mech,
struct gss_ctx **ctx_id);
u32 gss_get_mic(
......@@ -50,8 +51,6 @@ u32 gss_verify_mic(
u32 gss_delete_sec_context(
struct gss_ctx **ctx_id);
struct gss_api_mech * gss_mech_get_by_name(char *name);
struct gss_api_mech * gss_mech_get_by_pseudoflavor(u32 pseudoflavor);
u32 gss_pseudoflavor_to_service(struct gss_api_mech *, u32 pseudoflavor);
char *gss_service_to_auth_domain_name(struct gss_api_mech *, u32 service);
......@@ -80,8 +79,9 @@ struct gss_api_mech {
/* and must provide the following operations: */
struct gss_api_ops {
u32 (*gss_import_sec_context)(
struct xdr_netobj *input_token,
int (*gss_import_sec_context)(
const void *input_token,
size_t bufsize,
struct gss_ctx *ctx_id);
u32 (*gss_get_mic)(
struct gss_ctx *ctx_id,
......@@ -105,7 +105,7 @@ void gss_mech_unregister(struct gss_api_mech *);
struct gss_api_mech * gss_mech_get_by_OID(struct xdr_netobj *);
/* Returns a reference to a mechanism, given a name like "krb5" etc. */
struct gss_api_mech *gss_mech_get_by_name(char *);
struct gss_api_mech *gss_mech_get_by_name(const char *);
/* Similar, but get by pseudoflavor. */
struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32);
......
......@@ -53,9 +53,8 @@ struct rpc_task {
struct rpc_message tk_msg; /* RPC call info */
__u32 * tk_buffer; /* XDR buffer */
size_t tk_bufsize;
__u8 tk_garb_retry,
tk_cred_retry,
tk_suid_retry;
__u8 tk_garb_retry;
__u8 tk_cred_retry;
unsigned long tk_cookie; /* Cookie for batching tasks */
......@@ -118,9 +117,7 @@ typedef void (*rpc_action)(struct rpc_task *);
*/
#define RPC_TASK_ASYNC 0x0001 /* is an async task */
#define RPC_TASK_SWAPPER 0x0002 /* is swapping in/out */
#define RPC_TASK_SETUID 0x0004 /* is setuid process */
#define RPC_TASK_CHILD 0x0008 /* is child of other task */
#define RPC_CALL_REALUID 0x0010 /* try using real uid */
#define RPC_CALL_MAJORSEEN 0x0020 /* major timeout seen */
#define RPC_TASK_ROOTCREDS 0x0040 /* force root creds */
#define RPC_TASK_DYNAMIC 0x0080 /* task was kmalloc'ed */
......@@ -129,7 +126,6 @@ typedef void (*rpc_action)(struct rpc_task *);
#define RPC_TASK_NOINTR 0x0400 /* uninterruptible task */
#define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC)
#define RPC_IS_SETUID(t) ((t)->tk_flags & RPC_TASK_SETUID)
#define RPC_IS_CHILD(t) ((t)->tk_flags & RPC_TASK_CHILD)
#define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER)
#define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS)
......
......@@ -140,6 +140,9 @@ struct rpc_xprt {
unsigned int rcvsize, /* socket receive buffer size */
sndsize; /* socket send buffer size */
size_t max_payload; /* largest RPC payload size,
in bytes */
struct rpc_wait_queue sending; /* requests waiting to send */
struct rpc_wait_queue resend; /* requests waiting to resend */
struct rpc_wait_queue pending; /* requests in flight */
......
......@@ -579,6 +579,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
p[1] <= '7' && p[2] == '>') {
loglev_char = p[1];
p += 3;
printed_len += 3;
} else {
loglev_char = default_message_loglevel
+ '0';
......@@ -591,8 +592,9 @@ asmlinkage int vprintk(const char *fmt, va_list args)
(unsigned long)t,
nanosec_rem/1000);
for (tp = tbuf; tp< tbuf + tlen; tp++)
emit_log_char (*tp);
for (tp = tbuf; tp < tbuf + tlen; tp++)
emit_log_char(*tp);
printed_len += tlen - 3;
} else {
if (p[0] != '<' || p[1] < '0' ||
p[1] > '7' || p[2] != '>') {
......@@ -601,8 +603,11 @@ asmlinkage int vprintk(const char *fmt, va_list args)
+ '0');
emit_log_char('>');
}
printed_len += 3;
}
log_level_unknown = 0;
if (!*p)
break;
}
emit_log_char(*p);
if (*p == '\n')
......
......@@ -29,7 +29,13 @@ extern struct exception_table_entry __stop___ex_table[];
static int cmp_ex(const void *a, const void *b)
{
const struct exception_table_entry *x = a, *y = b;
return x->insn - y->insn;
/* avoid overflow */
if (x->insn > y->insn)
return 1;
if (x->insn < y->insn)
return -1;
return 0;
}
void sort_extable(struct exception_table_entry *start,
......
This diff is collapsed.
This diff is collapsed.
......@@ -48,46 +48,48 @@
# define RPCDBG_FACILITY RPCDBG_AUTH
#endif
static inline int
get_bytes(char **ptr, const char *end, void *res, int len)
static const void *
simple_get_bytes(const void *p, const void *end, void *res, int len)
{
char *p, *q;
p = *ptr;
q = p + len;
if (q > end || q < p)
return -1;
const void *q = (const void *)((const char *)p + len);
if (unlikely(q > end || q < p))
return ERR_PTR(-EFAULT);
memcpy(res, p, len);
*ptr = q;
return 0;
return q;
}
static inline int
get_netobj(char **ptr, const char *end, struct xdr_netobj *res)
static const void *
simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
{
char *p, *q;
p = *ptr;
if (get_bytes(&p, end, &res->len, sizeof(res->len)))
return -1;
q = p + res->len;
if (q > end || q < p)
return -1;
if (!(res->data = kmalloc(res->len, GFP_KERNEL)))
return -1;
memcpy(res->data, p, res->len);
*ptr = q;
return 0;
const void *q;
unsigned int len;
p = simple_get_bytes(p, end, &len, sizeof(len));
if (IS_ERR(p))
return p;
q = (const void *)((const char *)p + len);
if (unlikely(q > end || q < p))
return ERR_PTR(-EFAULT);
res->data = kmalloc(len, GFP_KERNEL);
if (unlikely(res->data == NULL))
return ERR_PTR(-ENOMEM);
memcpy(res->data, p, len);
res->len = len;
return q;
}
static inline int
get_key(char **p, char *end, struct crypto_tfm **res)
static inline const void *
get_key(const void *p, const void *end, struct crypto_tfm **res)
{
struct xdr_netobj key;
int alg, alg_mode;
char *alg_name;
if (get_bytes(p, end, &alg, sizeof(alg)))
p = simple_get_bytes(p, end, &alg, sizeof(alg));
if (IS_ERR(p))
goto out_err;
if ((get_netobj(p, end, &key)))
p = simple_get_netobj(p, end, &key);
if (IS_ERR(p))
goto out_err;
switch (alg) {
......@@ -105,50 +107,63 @@ get_key(char **p, char *end, struct crypto_tfm **res)
goto out_err_free_tfm;
kfree(key.data);
return 0;
return p;
out_err_free_tfm:
crypto_free_tfm(*res);
out_err_free_key:
kfree(key.data);
p = ERR_PTR(-EINVAL);
out_err:
return -1;
return p;
}
static u32
gss_import_sec_context_kerberos(struct xdr_netobj *inbuf,
static int
gss_import_sec_context_kerberos(const void *p,
size_t len,
struct gss_ctx *ctx_id)
{
char *p = inbuf->data;
char *end = inbuf->data + inbuf->len;
const void *end = (const void *)((const char *)p + len);
struct krb5_ctx *ctx;
if (!(ctx = kmalloc(sizeof(*ctx), GFP_KERNEL)))
goto out_err;
memset(ctx, 0, sizeof(*ctx));
if (get_bytes(&p, end, &ctx->initiate, sizeof(ctx->initiate)))
p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate));
if (IS_ERR(p))
goto out_err_free_ctx;
if (get_bytes(&p, end, &ctx->seed_init, sizeof(ctx->seed_init)))
p = simple_get_bytes(p, end, &ctx->seed_init, sizeof(ctx->seed_init));
if (IS_ERR(p))
goto out_err_free_ctx;
if (get_bytes(&p, end, ctx->seed, sizeof(ctx->seed)))
p = simple_get_bytes(p, end, ctx->seed, sizeof(ctx->seed));
if (IS_ERR(p))
goto out_err_free_ctx;
if (get_bytes(&p, end, &ctx->signalg, sizeof(ctx->signalg)))
p = simple_get_bytes(p, end, &ctx->signalg, sizeof(ctx->signalg));
if (IS_ERR(p))
goto out_err_free_ctx;
if (get_bytes(&p, end, &ctx->sealalg, sizeof(ctx->sealalg)))
p = simple_get_bytes(p, end, &ctx->sealalg, sizeof(ctx->sealalg));
if (IS_ERR(p))
goto out_err_free_ctx;
if (get_bytes(&p, end, &ctx->endtime, sizeof(ctx->endtime)))
p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime));
if (IS_ERR(p))
goto out_err_free_ctx;
if (get_bytes(&p, end, &ctx->seq_send, sizeof(ctx->seq_send)))
p = simple_get_bytes(p, end, &ctx->seq_send, sizeof(ctx->seq_send));
if (IS_ERR(p))
goto out_err_free_ctx;
if (get_netobj(&p, end, &ctx->mech_used))
p = simple_get_netobj(p, end, &ctx->mech_used);
if (IS_ERR(p))
goto out_err_free_ctx;
if (get_key(&p, end, &ctx->enc))
p = get_key(p, end, &ctx->enc);
if (IS_ERR(p))
goto out_err_free_mech;
if (get_key(&p, end, &ctx->seq))
p = get_key(p, end, &ctx->seq);
if (IS_ERR(p))
goto out_err_free_key1;
if (p != end)
if (p != end) {
p = ERR_PTR(-EFAULT);
goto out_err_free_key2;
}
ctx_id->internal_ctx_id = ctx;
dprintk("RPC: Succesfully imported new context.\n");
......@@ -163,7 +178,7 @@ gss_import_sec_context_kerberos(struct xdr_netobj *inbuf,
out_err_free_ctx:
kfree(ctx);
out_err:
return GSS_S_FAILURE;
return PTR_ERR(p);
}
static void
......
......@@ -143,7 +143,7 @@ gss_mech_get(struct gss_api_mech *gm)
EXPORT_SYMBOL(gss_mech_get);
struct gss_api_mech *
gss_mech_get_by_name(char *name)
gss_mech_get_by_name(const char *name)
{
struct gss_api_mech *pos, *gm = NULL;
......@@ -233,8 +233,8 @@ EXPORT_SYMBOL(gss_mech_put);
/* The mech could probably be determined from the token instead, but it's just
* as easy for now to pass it in. */
u32
gss_import_sec_context(struct xdr_netobj *input_token,
int
gss_import_sec_context(const void *input_token, size_t bufsize,
struct gss_api_mech *mech,
struct gss_ctx **ctx_id)
{
......@@ -244,7 +244,7 @@ gss_import_sec_context(struct xdr_netobj *input_token,
(*ctx_id)->mech_type = gss_mech_get(mech);
return mech->gm_ops
->gss_import_sec_context(input_token, *ctx_id);
->gss_import_sec_context(input_token, bufsize, *ctx_id);
}
/* gss_get_mic: compute a mic over message and return mic_token. */
......
......@@ -49,52 +49,51 @@
# define RPCDBG_FACILITY RPCDBG_AUTH
#endif
static inline int
get_bytes(char **ptr, const char *end, void *res, int len)
static const void *
simple_get_bytes(const void *p, const void *end, void *res, int len)
{
char *p, *q;
p = *ptr;
q = p + len;
if (q > end || q < p)
return -1;
const void *q = (const void *)((const char *)p + len);
if (unlikely(q > end || q < p))
return ERR_PTR(-EFAULT);
memcpy(res, p, len);
*ptr = q;
return 0;
return q;
}
static inline int
get_netobj(char **ptr, const char *end, struct xdr_netobj *res)
static const void *
simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
{
char *p, *q;
p = *ptr;
if (get_bytes(&p, end, &res->len, sizeof(res->len)))
return -1;
q = p + res->len;
if(res->len == 0)
goto out_nocopy;
if (q > end || q < p)
return -1;
if (!(res->data = kmalloc(res->len, GFP_KERNEL)))
return -1;
memcpy(res->data, p, res->len);
out_nocopy:
*ptr = q;
return 0;
const void *q;
unsigned int len;
p = simple_get_bytes(p, end, &len, sizeof(len));
if (IS_ERR(p))
return p;
res->len = len;
if (len == 0) {
res->data = NULL;
return p;
}
q = (const void *)((const char *)p + len);
if (unlikely(q > end || q < p))
return ERR_PTR(-EFAULT);
res->data = kmalloc(len, GFP_KERNEL);
if (unlikely(res->data == NULL))
return ERR_PTR(-ENOMEM);
memcpy(res->data, p, len);
return q;
}
static inline int
get_key(char **p, char *end, struct crypto_tfm **res, int *resalg)
static inline const void *
get_key(const void *p, const void *end, struct crypto_tfm **res, int *resalg)
{
struct xdr_netobj key = {
.len = 0,
.data = NULL,
};
struct xdr_netobj key = { 0 };
int alg_mode,setkey = 0;
char *alg_name;
if (get_bytes(p, end, resalg, sizeof(int)))
p = simple_get_bytes(p, end, resalg, sizeof(*resalg));
if (IS_ERR(p))
goto out_err;
if ((get_netobj(p, end, &key)))
p = simple_get_netobj(p, end, &key);
if (IS_ERR(p))
goto out_err;
switch (*resalg) {
......@@ -111,10 +110,6 @@ get_key(char **p, char *end, struct crypto_tfm **res, int *resalg)
alg_mode = 0;
setkey = 0;
break;
case NID_cast5_cbc:
dprintk("RPC: SPKM3 get_key: case cast5_cbc, UNSUPPORTED \n");
goto out_err;
break;
default:
dprintk("RPC: SPKM3 get_key: unsupported algorithm %d", *resalg);
goto out_err_free_key;
......@@ -128,69 +123,81 @@ get_key(char **p, char *end, struct crypto_tfm **res, int *resalg)
if(key.len > 0)
kfree(key.data);
return 0;
return p;
out_err_free_tfm:
crypto_free_tfm(*res);
out_err_free_key:
if(key.len > 0)
kfree(key.data);
p = ERR_PTR(-EINVAL);
out_err:
return -1;
return p;
}
static u32
gss_import_sec_context_spkm3(struct xdr_netobj *inbuf,
static int
gss_import_sec_context_spkm3(const void *p, size_t len,
struct gss_ctx *ctx_id)
{
char *p = inbuf->data;
char *end = inbuf->data + inbuf->len;
const void *end = (const void *)((const char *)p + len);
struct spkm3_ctx *ctx;
if (!(ctx = kmalloc(sizeof(*ctx), GFP_KERNEL)))
goto out_err;
memset(ctx, 0, sizeof(*ctx));
if (get_netobj(&p, end, &ctx->ctx_id))
p = simple_get_netobj(p, end, &ctx->ctx_id);
if (IS_ERR(p))
goto out_err_free_ctx;
if (get_bytes(&p, end, &ctx->qop, sizeof(ctx->qop)))
p = simple_get_bytes(p, end, &ctx->qop, sizeof(ctx->qop));
if (IS_ERR(p))
goto out_err_free_ctx_id;
if (get_netobj(&p, end, &ctx->mech_used))
p = simple_get_netobj(p, end, &ctx->mech_used);
if (IS_ERR(p))
goto out_err_free_mech;
if (get_bytes(&p, end, &ctx->ret_flags, sizeof(ctx->ret_flags)))
p = simple_get_bytes(p, end, &ctx->ret_flags, sizeof(ctx->ret_flags));
if (IS_ERR(p))
goto out_err_free_mech;
if (get_bytes(&p, end, &ctx->req_flags, sizeof(ctx->req_flags)))
p = simple_get_bytes(p, end, &ctx->req_flags, sizeof(ctx->req_flags));
if (IS_ERR(p))
goto out_err_free_mech;
if (get_netobj(&p, end, &ctx->share_key))
p = simple_get_netobj(p, end, &ctx->share_key);
if (IS_ERR(p))
goto out_err_free_s_key;
if (get_key(&p, end, &ctx->derived_conf_key, &ctx->conf_alg)) {
dprintk("RPC: SPKM3 confidentiality key will be NULL\n");
}
p = get_key(p, end, &ctx->derived_conf_key, &ctx->conf_alg);
if (IS_ERR(p))
goto out_err_free_s_key;
if (get_key(&p, end, &ctx->derived_integ_key, &ctx->intg_alg)) {
dprintk("RPC: SPKM3 integrity key will be NULL\n");
}
p = get_key(p, end, &ctx->derived_integ_key, &ctx->intg_alg);
if (IS_ERR(p))
goto out_err_free_key1;
if (get_bytes(&p, end, &ctx->owf_alg, sizeof(ctx->owf_alg)))
goto out_err_free_s_key;
p = simple_get_bytes(p, end, &ctx->keyestb_alg, sizeof(ctx->keyestb_alg));
if (IS_ERR(p))
goto out_err_free_key2;
if (get_bytes(&p, end, &ctx->owf_alg, sizeof(ctx->owf_alg)))
goto out_err_free_s_key;
p = simple_get_bytes(p, end, &ctx->owf_alg, sizeof(ctx->owf_alg));
if (IS_ERR(p))
goto out_err_free_key2;
if (p != end)
goto out_err_free_s_key;
goto out_err_free_key2;
ctx_id->internal_ctx_id = ctx;
dprintk("Succesfully imported new spkm context.\n");
return 0;
out_err_free_key2:
crypto_free_tfm(ctx->derived_integ_key);
out_err_free_key1:
crypto_free_tfm(ctx->derived_conf_key);
out_err_free_s_key:
kfree(ctx->share_key.data);
out_err_free_mech:
......@@ -200,7 +207,7 @@ gss_import_sec_context_spkm3(struct xdr_netobj *inbuf,
out_err_free_ctx:
kfree(ctx);
out_err:
return GSS_S_FAILURE;
return PTR_ERR(p);
}
static void
......
......@@ -381,7 +381,6 @@ static int rsc_parse(struct cache_detail *cd,
else {
int N, i;
struct gss_api_mech *gm;
struct xdr_netobj tmp_buf;
/* gid */
if (get_int(&mesg, &rsci.cred.cr_gid))
......@@ -420,9 +419,7 @@ static int rsc_parse(struct cache_detail *cd,
gss_mech_put(gm);
goto out;
}
tmp_buf.len = len;
tmp_buf.data = buf;
if (gss_import_sec_context(&tmp_buf, gm, &rsci.mechctx)) {
if (gss_import_sec_context(buf, len, gm, &rsci.mechctx)) {
gss_mech_put(gm);
goto out;
}
......
......@@ -18,48 +18,29 @@
# define RPCDBG_FACILITY RPCDBG_AUTH
#endif
static struct rpc_credops null_credops;
static struct rpc_auth null_auth;
static struct rpc_cred null_cred;
static struct rpc_auth *
nul_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
{
struct rpc_auth *auth;
dprintk("RPC: creating NULL authenticator for client %p\n", clnt);
if (!(auth = (struct rpc_auth *) kmalloc(sizeof(*auth),GFP_KERNEL)))
return NULL;
auth->au_cslack = 4;
auth->au_rslack = 2;
auth->au_ops = &authnull_ops;
auth->au_expire = 1800 * HZ;
rpcauth_init_credcache(auth);
return (struct rpc_auth *) auth;
atomic_inc(&null_auth.au_count);
return &null_auth;
}
static void
nul_destroy(struct rpc_auth *auth)
{
dprintk("RPC: destroying NULL authenticator %p\n", auth);
rpcauth_free_credcache(auth);
atomic_dec(&null_auth.au_count);
}
/*
* Create NULL creds for current process
* Lookup NULL creds for current process
*/
static struct rpc_cred *
nul_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
nul_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
{
struct rpc_cred *cred;
if (!(cred = (struct rpc_cred *) kmalloc(sizeof(*cred),GFP_KERNEL)))
return NULL;
atomic_set(&cred->cr_count, 0);
cred->cr_flags = RPCAUTH_CRED_UPTODATE;
cred->cr_uid = acred->uid;
cred->cr_ops = &null_credops;
return cred;
return get_rpccred(&null_cred);
}
/*
......@@ -68,7 +49,6 @@ nul_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
static void
nul_destroy_cred(struct rpc_cred *cred)
{
kfree(cred);
}
/*
......@@ -84,7 +64,7 @@ nul_match(struct auth_cred *acred, struct rpc_cred *cred, int taskflags)
* Marshal credential.
*/
static u32 *
nul_marshal(struct rpc_task *task, u32 *p, int ruid)
nul_marshal(struct rpc_task *task, u32 *p)
{
*p++ = htonl(RPC_AUTH_NULL);
*p++ = 0;
......@@ -125,7 +105,7 @@ nul_validate(struct rpc_task *task, u32 *p)
return p;
}
struct rpc_authops authnull_ops = {
struct rpc_authops authnull_ops = {
.owner = THIS_MODULE,
.au_flavor = RPC_AUTH_NULL,
#ifdef RPC_DEBUG
......@@ -133,14 +113,32 @@ struct rpc_authops authnull_ops = {
#endif
.create = nul_create,
.destroy = nul_destroy,
.crcreate = nul_create_cred,
.lookup_cred = nul_lookup_cred,
};
static
struct rpc_auth null_auth = {
.au_cslack = 4,
.au_rslack = 2,
.au_ops = &authnull_ops,
};
static
struct rpc_credops null_credops = {
.cr_name = "AUTH_NULL",
.crdestroy = nul_destroy_cred,
.crmatch = nul_match,
.crmarshal = nul_marshal,
.crrefresh = nul_refresh,
.crvalidate = nul_validate,
};
static
struct rpc_cred null_cred = {
.cr_ops = &null_credops,
.cr_count = ATOMIC_INIT(1),
.cr_flags = RPCAUTH_CRED_UPTODATE,
#ifdef RPC_DEBUG
.cr_magic = RPCAUTH_CRED_MAGIC,
#endif
};
......@@ -19,8 +19,6 @@
struct unx_cred {
struct rpc_cred uc_base;
gid_t uc_gid;
uid_t uc_puid; /* process uid */
gid_t uc_pgid; /* process gid */
gid_t uc_gids[NFS_NGROUPS];
};
#define uc_uid uc_base.cr_uid
......@@ -36,24 +34,17 @@ struct unx_cred {
# define RPCDBG_FACILITY RPCDBG_AUTH
#endif
static struct rpc_auth unix_auth;
static struct rpc_cred_cache unix_cred_cache;
static struct rpc_credops unix_credops;
static struct rpc_auth *
unx_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
{
struct rpc_auth *auth;
dprintk("RPC: creating UNIX authenticator for client %p\n", clnt);
if (!(auth = (struct rpc_auth *) kmalloc(sizeof(*auth), GFP_KERNEL)))
return NULL;
auth->au_cslack = UNX_WRITESLACK;
auth->au_rslack = 2; /* assume AUTH_NULL verf */
auth->au_expire = UNX_CRED_EXPIRE;
auth->au_ops = &authunix_ops;
rpcauth_init_credcache(auth);
return auth;
if (atomic_inc_return(&unix_auth.au_count) == 0)
unix_cred_cache.nextgc = jiffies + (unix_cred_cache.expire >> 1);
return &unix_auth;
}
static void
......@@ -63,6 +54,15 @@ unx_destroy(struct rpc_auth *auth)
rpcauth_free_credcache(auth);
}
/*
* Lookup AUTH_UNIX creds for current process
*/
static struct rpc_cred *
unx_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
{
return rpcauth_lookup_credcache(auth, acred, flags);
}
static struct rpc_cred *
unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
{
......@@ -73,13 +73,13 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
acred->uid, acred->gid);
if (!(cred = (struct unx_cred *) kmalloc(sizeof(*cred), GFP_KERNEL)))
return NULL;
return ERR_PTR(-ENOMEM);
atomic_set(&cred->uc_count, 0);
atomic_set(&cred->uc_count, 1);
cred->uc_flags = RPCAUTH_CRED_UPTODATE;
if (flags & RPC_TASK_ROOTCREDS) {
cred->uc_uid = cred->uc_puid = 0;
cred->uc_gid = cred->uc_pgid = 0;
cred->uc_uid = 0;
cred->uc_gid = 0;
cred->uc_gids[0] = NOGROUP;
} else {
int groups = acred->group_info->ngroups;
......@@ -88,8 +88,6 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
cred->uc_uid = acred->uid;
cred->uc_gid = acred->gid;
cred->uc_puid = current->uid;
cred->uc_pgid = current->gid;
for (i = 0; i < groups; i++)
cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
if (i < NFS_NGROUPS)
......@@ -121,9 +119,7 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int taskflags)
int groups;
if (cred->uc_uid != acred->uid
|| cred->uc_gid != acred->gid
|| cred->uc_puid != current->uid
|| cred->uc_pgid != current->gid)
|| cred->uc_gid != acred->gid)
return 0;
groups = acred->group_info->ngroups;
......@@ -134,8 +130,8 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int taskflags)
return 0;
return 1;
}
return (cred->uc_uid == 0 && cred->uc_puid == 0
&& cred->uc_gid == 0 && cred->uc_pgid == 0
return (cred->uc_uid == 0
&& cred->uc_gid == 0
&& cred->uc_gids[0] == (gid_t) NOGROUP);
}
......@@ -144,7 +140,7 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int taskflags)
* Maybe we should keep a cached credential for performance reasons.
*/
static u32 *
unx_marshal(struct rpc_task *task, u32 *p, int ruid)
unx_marshal(struct rpc_task *task, u32 *p)
{
struct rpc_clnt *clnt = task->tk_client;
struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred;
......@@ -160,14 +156,8 @@ unx_marshal(struct rpc_task *task, u32 *p, int ruid)
*/
p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
/* Note: we don't use real uid if it involves raising privilege */
if (ruid && cred->uc_puid != 0 && cred->uc_pgid != 0) {
*p++ = htonl((u32) cred->uc_puid);
*p++ = htonl((u32) cred->uc_pgid);
} else {
*p++ = htonl((u32) cred->uc_uid);
*p++ = htonl((u32) cred->uc_gid);
}
*p++ = htonl((u32) cred->uc_uid);
*p++ = htonl((u32) cred->uc_gid);
hold = p++;
for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++)
*p++ = htonl((u32) cred->uc_gids[i]);
......@@ -223,11 +213,27 @@ struct rpc_authops authunix_ops = {
#endif
.create = unx_create,
.destroy = unx_destroy,
.lookup_cred = unx_lookup_cred,
.crcreate = unx_create_cred,
};
static
struct rpc_cred_cache unix_cred_cache = {
.expire = UNX_CRED_EXPIRE,
};
static
struct rpc_auth unix_auth = {
.au_cslack = UNX_WRITESLACK,
.au_rslack = 2, /* assume AUTH_NULL verf */
.au_ops = &authunix_ops,
.au_count = ATOMIC_INIT(0),
.au_credcache = &unix_cred_cache,
};
static
struct rpc_credops unix_credops = {
.cr_name = "AUTH_UNIX",
.crdestroy = unx_destroy_cred,
.crmatch = unx_match,
.crmarshal = unx_marshal,
......
......@@ -23,6 +23,7 @@
#include <asm/system.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/slab.h>
......@@ -406,12 +407,11 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
rpc_call_setup(task, msg, 0);
/* Set up the call info struct and execute the task */
if (task->tk_status == 0)
status = rpc_execute(task);
else {
status = task->tk_status;
status = task->tk_status;
if (status == 0)
rpc_execute(task);
else
rpc_release_task(task);
}
out:
rpc_clnt_sigunmask(clnt, &oldset);
......@@ -426,9 +426,9 @@ rpc_call_setup(struct rpc_task *task, struct rpc_message *msg, int flags)
task->tk_msg = *msg;
task->tk_flags |= flags;
/* Bind the user cred */
if (task->tk_msg.rpc_cred != NULL) {
if (task->tk_msg.rpc_cred != NULL)
rpcauth_holdcred(task);
} else
else
rpcauth_bindcred(task);
if (task->tk_status == 0)
......@@ -452,6 +452,20 @@ rpc_setbufsize(struct rpc_clnt *clnt, unsigned int sndsize, unsigned int rcvsize
xprt_sock_setbufsize(xprt);
}
/*
* Return size of largest payload RPC client can support, in bytes
*
* For stream transports, this is one RPC record fragment (see RFC
* 1831), as we don't support multi-record requests yet. For datagram
* transports, this is the size of an IP packet minus the IP, UDP, and
* RPC header sizes.
*/
size_t rpc_max_payload(struct rpc_clnt *clnt)
{
return clnt->cl_xprt->max_payload;
}
EXPORT_SYMBOL(rpc_max_payload);
/*
* Restart an (async) RPC call. Usually called from within the
* exit handler.
......@@ -871,21 +885,6 @@ call_decode(struct rpc_task *task)
goto out_retry;
}
/*
* The following is an NFS-specific hack to cater for setuid
* processes whose uid is mapped to nobody on the server.
*/
if (task->tk_client->cl_droppriv &&
(ntohl(*p) == NFSERR_ACCES || ntohl(*p) == NFSERR_PERM)) {
if (RPC_IS_SETUID(task) && task->tk_suid_retry) {
dprintk("RPC: %4d retry squashed uid\n", task->tk_pid);
task->tk_flags ^= RPC_CALL_REALUID;
task->tk_action = call_bind;
task->tk_suid_retry--;
goto out_retry;
}
}
task->tk_action = NULL;
if (decode)
......
This diff is collapsed.
This diff is collapsed.
......@@ -1460,8 +1460,11 @@ xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to)
if (xprt->stream) {
xprt->cwnd = RPC_MAXCWND(xprt);
xprt->nocong = 1;
} else
xprt->max_payload = (1U << 31) - 1;
} else {
xprt->cwnd = RPC_INITCWND;
xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
}
spin_lock_init(&xprt->sock_lock);
spin_lock_init(&xprt->xprt_lock);
init_waitqueue_head(&xprt->cong_wait);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment