Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@penguin.transmeta.com>2002-02-08 00:52:06 -0800
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-02-08 00:52:06 -0800
commit6444d1a165b68c470e6bf60d7972bd680b0a8650 (patch)
tree95457a573d8166155c681d8a68d76013acd51ad7
parent531d56ec271643e62b25f861d9f4a1cc60ab96c4 (diff)
parent61d292a705c07296ec8cc4f625871a3dbed4d1f5 (diff)
Merge http://gkernel.bkbits.net/vm-2.5
into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
-rw-r--r--drivers/net/Config.help11
-rw-r--r--drivers/net/Config.in3
-rw-r--r--drivers/net/eepro100.c7
-rw-r--r--drivers/net/natsemi.c6
-rw-r--r--drivers/net/pcnet32.c78
-rw-r--r--drivers/net/tulip/21142.c9
-rw-r--r--drivers/net/tulip/ChangeLog22
-rw-r--r--drivers/net/tulip/timer.c16
-rw-r--r--drivers/net/tulip/tulip.h3
-rw-r--r--drivers/net/tulip/tulip_core.c27
-rw-r--r--drivers/net/winbond-840.c2
-rw-r--r--fs/nfsd/export.c103
-rw-r--r--fs/nfsd/nfsctl.c41
-rw-r--r--fs/nfsd/vfs.c61
-rw-r--r--fs/proc/base.c3
-rw-r--r--include/linux/nfsd/export.h5
16 files changed, 197 insertions, 200 deletions
diff --git a/drivers/net/Config.help b/drivers/net/Config.help
index d34d5ca4569f..fe7ba7ec616a 100644
--- a/drivers/net/Config.help
+++ b/drivers/net/Config.help
@@ -1154,6 +1154,17 @@ CONFIG_NATSEMI
More specific information and updates are available from
<http://www.scyld.com/network/natsemi.html>.
+CONFIG_NATSEMI_CABLE_MAGIC
+ Some systems see lots of errors with NatSemi ethernet controllers
+ on certain cables. If you are seeing lots of errors, try turning
+ this option on. Some boards have incorrect values for supporting
+ resistors that can cause this change to break. If you turn this
+ option on and your network suddenly stops working, turn this
+ option off.
+
+ Say N unless you are certain you need this option.
+ Vendors should not enable this option by default.
+
CONFIG_SK_G16
If you have a network (Ethernet) card of this type, say Y and read
the Ethernet-HOWTO, available from
diff --git a/drivers/net/Config.in b/drivers/net/Config.in
index 818dabe64263..8e0c833cad1e 100644
--- a/drivers/net/Config.in
+++ b/drivers/net/Config.in
@@ -171,6 +171,9 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
dep_tristate ' Mylex EISA LNE390A/B support (EXPERIMENTAL)' CONFIG_LNE390 $CONFIG_EISA $CONFIG_EXPERIMENTAL
dep_tristate ' Myson MTD-8xx PCI Ethernet support' CONFIG_FEALNX $CONFIG_PCI
dep_tristate ' National Semiconductor DP8381x series PCI Ethernet support' CONFIG_NATSEMI $CONFIG_PCI
+ if [ "$CONFIG_NATSEMI" = "y" -o "$CONFIG_NATSEMI" = "m" ]; then
+ bool ' NatSemi workaround for high errors' CONFIG_NATSEMI_CABLE_MAGIC
+ fi
dep_tristate ' PCI NE2000 and clones support (see help)' CONFIG_NE2K_PCI $CONFIG_PCI
dep_tristate ' Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL
dep_tristate ' Racal-Interlan EISA ES3210 support (EXPERIMENTAL)' CONFIG_ES3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index 106343da1b9c..c670ba07f8aa 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -991,6 +991,11 @@ speedo_open(struct net_device *dev)
if ((sp->phy[0] & 0x8000) == 0)
sp->advertising = mdio_read(ioaddr, sp->phy[0] & 0x1f, 4);
+ if (mdio_read(ioaddr, sp->phy[0] & 0x1f, MII_BMSR) & BMSR_LSTATUS)
+ netif_carrier_on(dev);
+ else
+ netif_carrier_off(dev);
+
if (speedo_debug > 2) {
printk(KERN_DEBUG "%s: Done speedo_open(), status %8.8x.\n",
dev->name, inw(ioaddr + SCBStatus));
@@ -1102,7 +1107,7 @@ static void speedo_timer(unsigned long data)
/* Clear sticky bit. */
mdio_read(ioaddr, phy_num, 1);
/* If link beat has returned... */
- if (mdio_read(ioaddr, phy_num, 1) & 0x0004)
+ if (mdio_read(ioaddr, phy_num, MII_BMSR) & BMSR_LSTATUS)
netif_carrier_on(dev);
else
netif_carrier_off(dev);
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index a94d694536b6..d3d57823aa0e 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -394,7 +394,11 @@ enum register_offsets {
SDCFG = 0xF8
};
/* the values for the 'magic' registers above (PGSEL=1) */
+#ifdef CONFIG_NATSEMI_CABLE_MAGIC
+#define PMDCSR_VAL 0x1898
+#else
#define PMDCSR_VAL 0x189C
+#endif
#define TSTDAT_VAL 0x0
#define DSPCFG_VAL 0x5040
#define SDCFG_VAL 0x008c
@@ -1511,7 +1515,7 @@ static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
if (intr_status == 0)
break;
- if (intr_status & (IntrRxDone | IntrRxIntr))
+ if (intr_status & (IntrRxDone | IntrRxIntr | RxStatusFIFOOver | IntrRxErr | IntrRxOverrun ))
netdev_rx(dev);
if (intr_status & (IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr) ) {
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 25b86ec89538..8dd2af654ba1 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -65,15 +65,15 @@ static struct net_device *pcnet32_dev;
static const int max_interrupt_work = 80;
static const int rx_copybreak = 200;
-#define PORT_AUI 0x00
-#define PORT_10BT 0x01
-#define PORT_GPSI 0x02
-#define PORT_MII 0x03
+#define PCNET32_PORT_AUI 0x00
+#define PCNET32_PORT_10BT 0x01
+#define PCNET32_PORT_GPSI 0x02
+#define PCNET32_PORT_MII 0x03
-#define PORT_PORTSEL 0x03
-#define PORT_ASEL 0x04
-#define PORT_100 0x40
-#define PORT_FD 0x80
+#define PCNET32_PORT_PORTSEL 0x03
+#define PCNET32_PORT_ASEL 0x04
+#define PCNET32_PORT_100 0x40
+#define PCNET32_PORT_FD 0x80
#define PCNET32_DMA_MASK 0xffffffff
@@ -82,22 +82,22 @@ static const int rx_copybreak = 200;
* to internal options
*/
static unsigned char options_mapping[] = {
- PORT_ASEL, /* 0 Auto-select */
- PORT_AUI, /* 1 BNC/AUI */
- PORT_AUI, /* 2 AUI/BNC */
- PORT_ASEL, /* 3 not supported */
- PORT_10BT | PORT_FD, /* 4 10baseT-FD */
- PORT_ASEL, /* 5 not supported */
- PORT_ASEL, /* 6 not supported */
- PORT_ASEL, /* 7 not supported */
- PORT_ASEL, /* 8 not supported */
- PORT_MII, /* 9 MII 10baseT */
- PORT_MII | PORT_FD, /* 10 MII 10baseT-FD */
- PORT_MII, /* 11 MII (autosel) */
- PORT_10BT, /* 12 10BaseT */
- PORT_MII | PORT_100, /* 13 MII 100BaseTx */
- PORT_MII | PORT_100 | PORT_FD, /* 14 MII 100BaseTx-FD */
- PORT_ASEL /* 15 not supported */
+ PCNET32_PORT_ASEL, /* 0 Auto-select */
+ PCNET32_PORT_AUI, /* 1 BNC/AUI */
+ PCNET32_PORT_AUI, /* 2 AUI/BNC */
+ PCNET32_PORT_ASEL, /* 3 not supported */
+ PCNET32_PORT_10BT | PCNET32_PORT_FD, /* 4 10baseT-FD */
+ PCNET32_PORT_ASEL, /* 5 not supported */
+ PCNET32_PORT_ASEL, /* 6 not supported */
+ PCNET32_PORT_ASEL, /* 7 not supported */
+ PCNET32_PORT_ASEL, /* 8 not supported */
+ PCNET32_PORT_MII, /* 9 MII 10baseT */
+ PCNET32_PORT_MII | PCNET32_PORT_FD, /* 10 MII 10baseT-FD */
+ PCNET32_PORT_MII, /* 11 MII (autosel) */
+ PCNET32_PORT_10BT, /* 12 10BaseT */
+ PCNET32_PORT_MII | PCNET32_PORT_100, /* 13 MII 100BaseTx */
+ PCNET32_PORT_MII | PCNET32_PORT_100 | PCNET32_PORT_FD, /* 14 MII 100BaseTx-FD */
+ PCNET32_PORT_ASEL /* 15 not supported */
};
#define MAX_UNITS 8
@@ -709,12 +709,12 @@ pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int car
lp->ltint = ltint;
lp->mii = mii;
if (options[card_idx] > sizeof (options_mapping))
- lp->options = PORT_ASEL;
+ lp->options = PCNET32_PORT_ASEL;
else
lp->options = options_mapping[options[card_idx]];
- if (fdx && !(lp->options & PORT_ASEL) && full_duplex[card_idx])
- lp->options |= PORT_FD;
+ if (fdx && !(lp->options & PCNET32_PORT_ASEL) && full_duplex[card_idx])
+ lp->options |= PCNET32_PORT_FD;
if (a == NULL) {
printk(KERN_ERR "pcnet32: No access methods\n");
@@ -726,7 +726,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int car
/* detect special T1/E1 WAN card by checking for MAC address */
if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0 && dev->dev_addr[2] == 0x75)
- lp->options = PORT_FD | PORT_GPSI;
+ lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
lp->init_block.mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */
lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
@@ -829,16 +829,16 @@ pcnet32_open(struct net_device *dev)
/* set/reset autoselect bit */
val = lp->a.read_bcr (ioaddr, 2) & ~2;
- if (lp->options & PORT_ASEL)
+ if (lp->options & PCNET32_PORT_ASEL)
val |= 2;
lp->a.write_bcr (ioaddr, 2, val);
/* handle full duplex setting */
if (lp->full_duplex) {
val = lp->a.read_bcr (ioaddr, 9) & ~3;
- if (lp->options & PORT_FD) {
+ if (lp->options & PCNET32_PORT_FD) {
val |= 1;
- if (lp->options == (PORT_FD | PORT_AUI))
+ if (lp->options == (PCNET32_PORT_FD | PCNET32_PORT_AUI))
val |= 2;
}
lp->a.write_bcr (ioaddr, 9, val);
@@ -846,19 +846,19 @@ pcnet32_open(struct net_device *dev)
/* set/reset GPSI bit in test register */
val = lp->a.read_csr (ioaddr, 124) & ~0x10;
- if ((lp->options & PORT_PORTSEL) == PORT_GPSI)
+ if ((lp->options & PCNET32_PORT_PORTSEL) == PCNET32_PORT_GPSI)
val |= 0x10;
lp->a.write_csr (ioaddr, 124, val);
- if (lp->mii && !(lp->options & PORT_ASEL)) {
+ if (lp->mii && !(lp->options & PCNET32_PORT_ASEL)) {
val = lp->a.read_bcr (ioaddr, 32) & ~0x38; /* disable Auto Negotiation, set 10Mpbs, HD */
- if (lp->options & PORT_FD)
+ if (lp->options & PCNET32_PORT_FD)
val |= 0x10;
- if (lp->options & PORT_100)
+ if (lp->options & PCNET32_PORT_100)
val |= 0x08;
lp->a.write_bcr (ioaddr, 32, val);
} else {
- if (lp->options & PORT_ASEL) { /* enable auto negotiate, setup, disable fd */
+ if (lp->options & PCNET32_PORT_ASEL) { /* enable auto negotiate, setup, disable fd */
val = lp->a.read_bcr(ioaddr, 32) & ~0x98;
val |= 0x20;
lp->a.write_bcr(ioaddr, 32, val);
@@ -878,7 +878,7 @@ pcnet32_open(struct net_device *dev)
lp->a.write_csr (ioaddr, 5, val);
}
- lp->init_block.mode = le16_to_cpu((lp->options & PORT_PORTSEL) << 7);
+ lp->init_block.mode = le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7);
lp->init_block.filter[0] = 0x00000000;
lp->init_block.filter[1] = 0x00000000;
if (pcnet32_init_ring(dev))
@@ -1465,9 +1465,9 @@ static void pcnet32_set_multicast_list(struct net_device *dev)
if (dev->flags&IFF_PROMISC) {
/* Log any net taps. */
printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name);
- lp->init_block.mode = le16_to_cpu(0x8000 | (lp->options & PORT_PORTSEL) << 7);
+ lp->init_block.mode = le16_to_cpu(0x8000 | (lp->options & PCNET32_PORT_PORTSEL) << 7);
} else {
- lp->init_block.mode = le16_to_cpu((lp->options & PORT_PORTSEL) << 7);
+ lp->init_block.mode = le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7);
pcnet32_load_multicast (dev);
}
diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c
index 3a88c44120fe..7e66f90349a0 100644
--- a/drivers/net/tulip/21142.c
+++ b/drivers/net/tulip/21142.c
@@ -39,8 +39,13 @@ void t21142_timer(unsigned long data)
printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n",
dev->name, csr12, medianame[dev->if_port]);
if (tulip_media_cap[dev->if_port] & MediaIsMII) {
- tulip_check_duplex(dev);
- next_tick = 60*HZ;
+ if (tulip_check_duplex(dev) < 0) {
+ netif_carrier_off(dev);
+ next_tick = 3*HZ;
+ } else {
+ netif_carrier_on(dev);
+ next_tick = 60*HZ;
+ }
} else if (tp->nwayset) {
/* Don't screw up a negotiated session! */
if (tulip_debug > 1)
diff --git a/drivers/net/tulip/ChangeLog b/drivers/net/tulip/ChangeLog
index 8cd389cb5d70..3111685c2da4 100644
--- a/drivers/net/tulip/ChangeLog
+++ b/drivers/net/tulip/ChangeLog
@@ -1,3 +1,25 @@
+2002-01-28 Stefan Rompf <srompf@isg.de>,
+ Jeff Garzik <jgarzik@mandrakesoft.com>
+
+ * 21142.c (t21142_timer): Use return value of
+ tulip_check_duplex() to indicate to system whether or not
+ carrier is present. Use carrier presence/absence to determine
+ when next the 21142 media timer should check for link beat.
+
+ * timer (tulip_timer): Un-comment-out calls to
+ netif_carrier_{on,off}, as there is now value in
+ reporting link beta information to userspace.
+
+2002-01-28 Pavel Roskin <proski@gnu.org>
+
+ * tulip_core.c (tulip_init_one): Use tp->eeprom instead of
+ allocating a buffer for EEPROM copy on the stack.
+
+ * tulip_core.c: Add support for Conexant RS7112 (a.k.a. CN7112)
+ chip.
+ * tulip.h: Likewise. Increase EEPROM_SIZE to 512 bytes to
+ accomodate EEPROM on Conexant RS7112.
+
2002-02-07 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
* tulip_core (tulip_pci_tbl[]):
diff --git a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c
index 53c43912bad7..c67dd8531b59 100644
--- a/drivers/net/tulip/timer.c
+++ b/drivers/net/tulip/timer.c
@@ -83,10 +83,10 @@ void tulip_timer(unsigned long data)
medianame[mleaf->media & MEDIA_MASK]);
if ((p[2] & 0x61) == 0x01) /* Bogus Znyx board. */
goto actually_mii;
- /* netif_carrier_on(dev); */
+ netif_carrier_on(dev);
break;
}
- /* netif_carrier_off(dev); */
+ netif_carrier_off(dev);
if (tp->medialock)
break;
select_next_media:
@@ -110,11 +110,13 @@ void tulip_timer(unsigned long data)
}
case 1: case 3: /* 21140, 21142 MII */
actually_mii:
- if (tulip_check_duplex(dev) < 0)
- { /* netif_carrier_off(dev); */ }
- else
- { /* netif_carrier_on(dev); */ }
- next_tick = 60*HZ;
+ if (tulip_check_duplex(dev) < 0) {
+ netif_carrier_off(dev);
+ next_tick = 3*HZ;
+ } else {
+ netif_carrier_on(dev);
+ next_tick = 60*HZ;
+ }
break;
case 2: /* 21142 serial block has no link beat. */
default:
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
index 2171eb9dc8f8..c39cb3cb2b74 100644
--- a/drivers/net/tulip/tulip.h
+++ b/drivers/net/tulip/tulip.h
@@ -84,6 +84,7 @@ enum chips {
COMPEX9881,
I21145,
DM910X,
+ CONEXANT,
};
@@ -290,7 +291,7 @@ enum t21143_csr6_bits {
#define DESC_RING_WRAP 0x02000000
-#define EEPROM_SIZE 128 /* 2 << EEPROM_ADDRLEN */
+#define EEPROM_SIZE 512 /* 2 << EEPROM_ADDRLEN */
#define RUN_AT(x) (jiffies + (x))
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 52ad8a5b6af5..9143debdef24 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -15,8 +15,8 @@
*/
#define DRV_NAME "tulip"
-#define DRV_VERSION "1.1.0"
-#define DRV_RELDATE "Dec 11, 2001"
+#define DRV_VERSION "1.1.11"
+#define DRV_RELDATE "Feb 08, 2002"
#include <linux/config.h>
#include <linux/module.h>
@@ -185,6 +185,10 @@ struct tulip_chip_table tulip_tbl[] = {
{ "Davicom DM9102/DM9102A", 128, 0x0001ebef,
HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI,
tulip_timer },
+
+ /* RS7112 */
+ { "Conexant LANfinity", 256, 0x0001ebef,
+ HAS_MII | HAS_ACPI, tulip_timer },
};
@@ -212,6 +216,7 @@ static struct pci_device_id tulip_pci_tbl[] __devinitdata = {
{ 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
{ 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 },
{ 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+ { 0x14f1, 0x1803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CONEXANT },
{ } /* terminate list */
};
MODULE_DEVICE_TABLE(pci, tulip_pci_tbl);
@@ -418,7 +423,7 @@ media_picked:
tp->csr6 = 0x01a80200;
outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0);
- } else if (tp->chip_id == COMET) {
+ } else if (tp->chip_id == COMET || tp->chip_id == CONEXANT) {
/* Enable automatic Tx underrun recovery. */
outl(inl(ioaddr + 0x88) | 1, ioaddr + 0x88);
dev->if_port = tp->mii_cnt ? 11 : 0;
@@ -1254,7 +1259,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
u8 chip_rev;
int i, irq;
unsigned short sum;
- u8 ee_data[EEPROM_SIZE];
+ unsigned char *ee_data;
struct net_device *dev;
long ioaddr;
static int board_idx = -1;
@@ -1431,6 +1436,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
be polled, waiting for the value to be read bit serially from the
EEPROM.
*/
+ ee_data = tp->eeprom;
sum = 0;
if (chip_idx == LC82C168) {
for (i = 0; i < 3; i++) {
@@ -1453,17 +1459,22 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
int sa_offset = 0;
int ee_addr_size = tulip_read_eeprom(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
- for (i = 0; i < sizeof(ee_data)/2; i++)
+ for (i = 0; i < sizeof(tp->eeprom)/2; i++)
((u16 *)ee_data)[i] =
le16_to_cpu(tulip_read_eeprom(ioaddr, i, ee_addr_size));
/* DEC now has a specification (see Notes) but early board makers
just put the address in the first EEPROM locations. */
- /* This does memcmp(eedata, eedata+16, 8) */
+ /* This does memcmp(ee_data, ee_data+16, 8) */
for (i = 0; i < 8; i ++)
if (ee_data[i] != ee_data[16+i])
sa_offset = 20;
- if (ee_data[0] == 0xff && ee_data[1] == 0xff && ee_data[2] == 0) {
+ if (chip_idx == CONEXANT) {
+ /* Check that the tuple type and length is correct. */
+ if (ee_data[0x198] == 0x04 && ee_data[0x199] == 6)
+ sa_offset = 0x19A;
+ } else if (ee_data[0] == 0xff && ee_data[1] == 0xff &&
+ ee_data[2] == 0) {
sa_offset = 2; /* Grrr, damn Matrox boards. */
multiport_cnt = 4;
}
@@ -1556,8 +1567,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
}
if (tp->flags & HAS_MEDIA_TABLE) {
- memcpy(tp->eeprom, ee_data, sizeof(tp->eeprom));
-
sprintf(dev->name, "tulip%d", board_idx); /* hack */
tulip_parse_eeprom(dev);
strcpy(dev->name, "eth%d"); /* un-hack */
diff --git a/drivers/net/winbond-840.c b/drivers/net/winbond-840.c
index 514b57d19d25..90055d16871c 100644
--- a/drivers/net/winbond-840.c
+++ b/drivers/net/winbond-840.c
@@ -347,7 +347,7 @@ struct netdev_private {
struct w840_rx_desc *rx_ring;
dma_addr_t rx_addr[RX_RING_SIZE];
struct w840_tx_desc *tx_ring;
- dma_addr_t tx_addr[RX_RING_SIZE];
+ dma_addr_t tx_addr[TX_RING_SIZE];
dma_addr_t ring_dma_addr;
/* The addresses of receive-in-place skbuffs. */
struct sk_buff* rx_skbuff[RX_RING_SIZE];
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index a4a6d4cebd90..5fde41eaa47f 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -32,10 +32,9 @@
typedef struct svc_client svc_client;
typedef struct svc_export svc_export;
-static svc_export * exp_find(svc_client *clp, kdev_t dev);
-static svc_export * exp_parent(svc_client *clp, kdev_t dev,
+static svc_export * exp_parent(svc_client *clp, struct super_block *sb,
struct dentry *dentry);
-static svc_export * exp_child(svc_client *clp, kdev_t dev,
+static svc_export * exp_child(svc_client *clp, struct super_block *sb,
struct dentry *dentry);
static void exp_unexport_all(svc_client *clp);
static void exp_do_unexport(svc_export *unexp);
@@ -66,40 +65,37 @@ static int want_lock;
static int hash_count;
static DECLARE_WAIT_QUEUE_HEAD( hash_wait );
-
/*
- * Find a client's export for a device.
+ * Find the client's export entry matching xdev/xino.
*/
-static inline svc_export *
-exp_find(svc_client *clp, kdev_t dev)
+svc_export *
+exp_get(svc_client *clp, kdev_t dev, ino_t ino)
{
svc_export * exp;
- exp = clp->cl_export[EXPORT_HASH(dev)];
- while (exp && !kdev_same(exp->ex_dev, dev))
- exp = exp->ex_next;
+ if (!clp)
+ return NULL;
+
+ for (exp = clp->cl_export[EXPORT_HASH(dev)]; exp; exp = exp->ex_next) {
+ if (exp->ex_ino == ino && kdev_same(exp->ex_dev, dev))
+ break;
+ }
return exp;
}
-/*
- * Find the client's export entry matching xdev/xino.
- */
svc_export *
-exp_get(svc_client *clp, kdev_t dev, ino_t ino)
+exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry)
{
- svc_export * exp;
+ int hash = EXPORT_HASH(mnt->mnt_sb->s_dev);
+ svc_export *exp;
if (!clp)
return NULL;
- exp = clp->cl_export[EXPORT_HASH(dev)];
- if (exp)
- do {
- if (exp->ex_ino == ino && kdev_same(exp->ex_dev, dev))
- goto out;
- } while (NULL != (exp = exp->ex_next));
- exp = NULL;
-out:
+ for (exp = clp->cl_export[hash]; exp; exp = exp->ex_next) {
+ if (exp->ex_dentry == dentry && exp->ex_mnt == mnt)
+ break;
+ }
return exp;
}
@@ -107,14 +103,14 @@ out:
* Find the export entry for a given dentry. <gam3@acm.org>
*/
static svc_export *
-exp_parent(svc_client *clp, kdev_t dev, struct dentry *dentry)
+exp_parent(svc_client *clp, struct super_block *sb, struct dentry *dentry)
{
svc_export *exp;
if (clp == NULL)
return NULL;
- for (exp = clp->cl_export[EXPORT_HASH(dev)]; exp; exp = exp->ex_next)
+ for (exp = clp->cl_export[EXPORT_HASH(sb->s_dev)]; exp; exp = exp->ex_next)
if (is_subdir(dentry, exp->ex_dentry))
break;
return exp;
@@ -126,14 +122,14 @@ exp_parent(svc_client *clp, kdev_t dev, struct dentry *dentry)
* <gam3@acm.org>
*/
static svc_export *
-exp_child(svc_client *clp, kdev_t dev, struct dentry *dentry)
+exp_child(svc_client *clp, struct super_block *sb, struct dentry *dentry)
{
svc_export *exp;
if (clp == NULL)
return NULL;
- for (exp = clp->cl_export[EXPORT_HASH(dev)]; exp; exp = exp->ex_next) {
+ for (exp = clp->cl_export[EXPORT_HASH(sb->s_dev)]; exp; exp = exp->ex_next) {
struct dentry *ndentry = exp->ex_dentry;
if (ndentry && is_subdir(ndentry->d_parent, dentry))
break;
@@ -221,12 +217,12 @@ exp_export(struct nfsctl_export *nxp)
goto finish;
}
- if ((parent = exp_child(clp, dev, nd.dentry)) != NULL) {
+ if ((parent = exp_child(clp, inode->i_sb, nd.dentry)) != NULL) {
dprintk("exp_export: export not valid (Rule 3).\n");
goto finish;
}
/* Is this is a sub-export, must be a proper subset of FS */
- if ((parent = exp_parent(clp, dev, nd.dentry)) != NULL) {
+ if ((parent = exp_parent(clp, inode->i_sb, nd.dentry)) != NULL) {
dprintk("exp_export: sub-export not valid (Rule 2).\n");
goto finish;
}
@@ -380,55 +376,34 @@ out:
* since its harder to fool a kernel module than a user space program.
*/
int
-exp_rootfh(struct svc_client *clp, kdev_t dev, ino_t ino,
- char *path, struct knfsd_fh *f, int maxsize)
+exp_rootfh(struct svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
{
struct svc_export *exp;
struct nameidata nd;
struct inode *inode;
struct svc_fh fh;
+ kdev_t dev;
int err;
err = -EPERM;
- if (path) {
- if (path_init(path, LOOKUP_POSITIVE, &nd) &&
- path_walk(path, &nd)) {
- printk("nfsd: exp_rootfh path not found %s", path);
- return err;
- }
- dev = nd.dentry->d_inode->i_dev;
- ino = nd.dentry->d_inode->i_ino;
-
- dprintk("nfsd: exp_rootfh(%s [%p] %s:%02x:%02x/%ld)\n",
- path, nd.dentry, clp->cl_ident,
- major(dev), minor(dev), (long) ino);
- exp = exp_parent(clp, dev, nd.dentry);
- } else {
- dprintk("nfsd: exp_rootfh(%s:%02x:%02x/%ld)\n",
- clp->cl_ident, major(dev), minor(dev), (long) ino);
- if ((exp = exp_get(clp, dev, ino))) {
- nd.mnt = mntget(exp->ex_mnt);
- nd.dentry = dget(exp->ex_dentry);
- }
+ /* NB: we probably ought to check that it's NUL-terminated */
+ if (path_init(path, LOOKUP_POSITIVE, &nd) &&
+ path_walk(path, &nd)) {
+ printk("nfsd: exp_rootfh path not found %s", path);
+ return err;
}
+ inode = nd.dentry->d_inode;
+ dev = inode->i_dev;
+
+ dprintk("nfsd: exp_rootfh(%s [%p] %s:%02x:%02x/%ld)\n",
+ path, nd.dentry, clp->cl_ident,
+ major(dev), minor(dev), (long) inode->i_ino);
+ exp = exp_parent(clp, inode->i_sb, nd.dentry);
if (!exp) {
dprintk("nfsd: exp_rootfh export not found.\n");
goto out;
}
- inode = nd.dentry->d_inode;
- if (!inode) {
- printk("exp_rootfh: Aieee, NULL d_inode\n");
- goto out;
- }
- if (!kdev_same(inode->i_dev, dev) || inode->i_ino != ino) {
- printk("exp_rootfh: Aieee, ino/dev mismatch\n");
- printk("exp_rootfh: arg[dev(%02x:%02x):ino(%ld)]"
- " inode[dev(%02x:%02x):ino(%ld)]\n",
- major(dev), minor(dev), (long) ino,
- major(inode->i_dev), minor(inode->i_dev), (long) inode->i_ino);
- }
-
/*
* fh must be initialized before calling fh_compose
*/
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 25c4288bf818..ab0d92c62881 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -37,7 +37,6 @@ static int nfsctl_addclient(struct nfsctl_client *data);
static int nfsctl_delclient(struct nfsctl_client *data);
static int nfsctl_export(struct nfsctl_export *data);
static int nfsctl_unexport(struct nfsctl_export *data);
-static int nfsctl_getfh(struct nfsctl_fhparm *, __u8 *);
static int nfsctl_getfd(struct nfsctl_fdparm *, __u8 *);
static int nfsctl_getfs(struct nfsctl_fsparm *, struct knfsd_fh *);
#ifdef notyet
@@ -125,7 +124,7 @@ nfsctl_getfs(struct nfsctl_fsparm *data, struct knfsd_fh *res)
if (!(clp = exp_getclient(sin)))
err = -EPERM;
else
- err = exp_rootfh(clp, NODEV, 0, data->gd_path, res, data->gd_maxlen);
+ err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen);
exp_unlock();
return err;
}
@@ -148,40 +147,7 @@ nfsctl_getfd(struct nfsctl_fdparm *data, __u8 *res)
if (!(clp = exp_getclient(sin)))
err = -EPERM;
else
- err = exp_rootfh(clp, NODEV, 0, data->gd_path, &fh, NFS_FHSIZE);
- exp_unlock();
-
- if (err == 0) {
- if (fh.fh_size > NFS_FHSIZE)
- err = -EINVAL;
- else {
- memset(res,0, NFS_FHSIZE);
- memcpy(res, &fh.fh_base, fh.fh_size);
- }
- }
-
- return err;
-}
-
-static inline int
-nfsctl_getfh(struct nfsctl_fhparm *data, __u8 *res)
-{
- struct sockaddr_in *sin;
- struct svc_client *clp;
- int err = 0;
- struct knfsd_fh fh;
-
- if (data->gf_addr.sa_family != AF_INET)
- return -EPROTONOSUPPORT;
- if (data->gf_version < 2 || data->gf_version > NFSSVC_MAXVERS)
- return -EINVAL;
- sin = (struct sockaddr_in *)&data->gf_addr;
-
- exp_readlock();
- if (!(clp = exp_getclient(sin)))
- err = -EPERM;
- else
- err = exp_rootfh(clp, to_kdev_t(data->gf_dev), data->gf_ino, NULL, &fh, NFS_FHSIZE);
+ err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE);
exp_unlock();
if (err == 0) {
@@ -277,9 +243,6 @@ asmlinkage handle_sys_nfsservctl(int cmd, void *opaque_argp, void *opaque_resp)
err = nfsctl_ugidupdate(&arg->ca_umap);
break;
#endif
- case NFSCTL_GETFH:
- err = nfsctl_getfh(&arg->ca_getfh, res->cr_getfh);
- break;
case NFSCTL_GETFD:
err = nfsctl_getfd(&arg->ca_getfd, res->cr_getfh);
break;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index af9bd34b282a..245560649fef 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -114,35 +114,30 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
if (isdotent(name, len)) {
if (len==1)
dentry = dget(dparent);
- else { /* must be ".." */
+ else if (dparent != exp->ex_dentry)
+ dentry = dget(dparent->d_parent);
+ else if (!EX_CROSSMNT(exp))
+ dentry = dget(dparent); /* .. == . just like at / */
+ else {
/* checking mountpoint crossing is very different when stepping up */
- if (dparent == exp->ex_dentry) {
- if (!EX_CROSSMNT(exp))
- dentry = dget(dparent); /* .. == . just like at / */
- else
- {
- struct svc_export *exp2 = NULL;
- struct dentry *dp;
- struct vfsmount *mnt = mntget(exp->ex_mnt);
- dentry = dget(dparent);
- while(follow_up(&mnt, &dentry))
- ;
- dp = dget(dentry->d_parent);
- dput(dentry);
- dentry = dp;
- for ( ; exp2 == NULL && dp->d_parent != dp;
- dp=dp->d_parent)
- exp2 = exp_get(exp->ex_client, dp->d_inode->i_dev, dp->d_inode->i_ino);
- if (exp2==NULL) {
- dput(dentry);
- dentry = dget(dparent);
- } else {
- exp = exp2;
- }
- mntput(mnt);
- }
- } else
- dentry = dget(dparent->d_parent);
+ struct svc_export *exp2 = NULL;
+ struct dentry *dp;
+ struct vfsmount *mnt = mntget(exp->ex_mnt);
+ dentry = dget(dparent);
+ while(follow_up(&mnt, &dentry))
+ ;
+ dp = dget(dentry->d_parent);
+ dput(dentry);
+ dentry = dp;
+ for ( ; !exp2 && dp->d_parent != dp; dp=dp->d_parent)
+ exp2 = exp_get_by_name(exp->ex_client, mnt, dp);
+ if (!exp2) {
+ dput(dentry);
+ dentry = dget(dparent);
+ } else {
+ exp = exp2;
+ }
+ mntput(mnt);
}
} else {
fh_lock(fhp);
@@ -159,9 +154,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
struct dentry *mounts = dget(dentry);
while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts))
;
- exp2 = exp_get(rqstp->rq_client,
- mounts->d_inode->i_dev,
- mounts->d_inode->i_ino);
+ exp2 = exp_get_by_name(rqstp->rq_client, mnt, mounts);
if (exp2 && EX_CROSSMNT(exp2)) {
/* successfully crossed mount point */
exp = exp2;
@@ -591,6 +584,7 @@ nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
mm_segment_t oldfs;
int err;
struct file file;
+ struct inode *inode;
err = nfsd_open(rqstp, fhp, S_IFREG, MAY_READ, &file);
if (err)
@@ -598,14 +592,15 @@ nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
err = nfserr_perm;
if (!file.f_op->read)
goto out_close;
+ inode = file.f_dentry->d_inode;
#ifdef MSNFS
if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
- (!lock_may_read(file.f_dentry->d_inode, offset, *count)))
+ (!lock_may_read(inode, offset, *count)))
goto out_close;
#endif
/* Get readahead parameters */
- ra = nfsd_get_raparms(fhp->fh_export->ex_dev, fhp->fh_dentry->d_inode->i_ino);
+ ra = nfsd_get_raparms(inode->i_dev, inode->i_ino);
if (ra) {
file.f_reada = ra->p_reada;
file.f_ramax = ra->p_ramax;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index f1b0f2b65722..47c5cfdc6448 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1003,8 +1003,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
ei = PROC_I(inode);
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_ino = fake_ino(0, PROC_PID_INO);
- ei->file = NULL;
- ei->task = NULL;
+ ei->pde = NULL;
inode->i_mode = S_IFLNK|S_IRWXUGO;
inode->i_uid = inode->i_gid = 0;
inode->i_size = 64;
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index db948a701db7..4b3c95ffc05c 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -90,7 +90,10 @@ void exp_unlock(void);
struct svc_client * exp_getclient(struct sockaddr_in *sin);
void exp_putclient(struct svc_client *clp);
struct svc_export * exp_get(struct svc_client *clp, kdev_t dev, ino_t ino);
-int exp_rootfh(struct svc_client *, kdev_t, ino_t,
+struct svc_export * exp_get_by_name(struct svc_client *clp,
+ struct vfsmount *mnt,
+ struct dentry *dentry);
+int exp_rootfh(struct svc_client *,
char *path, struct knfsd_fh *, int maxsize);
int nfserrno(int errno);
void exp_nlmdetach(void);