From 4f8db55023463ddeab756102d3bde159cce3c184 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:38:07 -0500 Subject: [PATCH] Linux 2.4.0-test7-pre5 - i2c-old compile fix. - sparc updates (pte_pagenr cleanups) - make ipv6 loadable as a module together with CONFIG_INET_ECN - get rid of bdf_prm.b_un.age_super - it just confused the buffer aging - smbfs knows about nls and ascii mount options - small joystick driver updates - make sure to mark inode dirty after having changed the size! - hgafb documentation update --- Documentation/Configure.help | 15 ++ MAINTAINERS | 7 + arch/arm/kernel/semaphore.c | 1 + arch/sparc/mm/srmmu.c | 8 +- arch/sparc/mm/sun4c.c | 8 +- drivers/char/i2c-old.c | 8 - drivers/char/joystick/amijoy.c | 21 ++- drivers/char/joystick/db9.c | 104 +++++------ drivers/char/joystick/gamecon.c | 28 ++- drivers/char/joystick/sidewinder.c | 6 +- drivers/char/joystick/spaceball.c | 47 +++-- drivers/isdn/eicon/Divas_mod.c | 1 + drivers/video/hgafb.c | 224 ++++++++++++++++------ fs/Config.in | 4 +- fs/buffer.c | 14 +- fs/inode.c | 3 +- fs/nls/Config.in | 3 +- fs/smbfs/ChangeLog | 11 ++ fs/smbfs/Makefile | 2 +- fs/smbfs/dir.c | 27 ++- fs/smbfs/getopt.c | 61 ++++++ fs/smbfs/getopt.h | 15 ++ fs/smbfs/inode.c | 158 ++++++++++++++-- fs/smbfs/proc.c | 369 +++++++++++++++++++++++++++---------- fs/smbfs/sock.c | 14 +- include/asm-arm/arch-arc/irq.h | 1 + include/asm-arm/arch-arc/system.h | 1 - include/asm-sparc/pgtable.h | 8 +- include/asm-sparc/spinlock.h | 9 +- include/asm-sparc/unistd.h | 4 +- include/asm-sparc64/spinlock.h | 2 + include/asm-sparc64/unistd.h | 4 +- include/linux/smb.h | 7 + include/linux/smb_fs.h | 8 +- include/linux/smb_fs_sb.h | 16 +- include/linux/smb_mount.h | 35 +++- kernel/ksyms.c | 1 + mm/filemap.c | 2 +- mm/highmem.c | 2 +- net/netsyms.c | 1 + 40 files changed, 927 insertions(+), 333 deletions(-) create mode 100644 fs/smbfs/getopt.c create mode 100644 fs/smbfs/getopt.h diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 12f162feb..58c7f23db 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -11305,6 +11305,21 @@ CONFIG_SMB_FS want), say M here and read Documentation/modules.txt. The module will be called smbfs.o. Most people say N, however. +nls support setting +CONFIG_SMB_NLS_REMOTE + This setting allows you to specify a default value for which + codepage the server uses. If this field is left blank no + translations will be done by default. The local codepage/charset + default to CONFIG_NLS_DEFAULT. + + The nls settings can be changed at mount time, if your smbmount + supports that, using the codepage and iocharset parameters. + + Currently no smbmount distributed with samba supports this, it is + assumed future versions will. In the meantime you can get an + unofficial patch for samba 2.0.7 from: + http://www.hojdpunkten.ac.se/054/samba/index.html + Coda file system support (advanced network fs) CONFIG_CODA_FS Coda is an advanced network file system, similar to NFS in that it diff --git a/MAINTAINERS b/MAINTAINERS index d74d1596e..faac0cebc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -450,6 +450,13 @@ M: asun@cobaltnet.com L: linux-kernel@vger.rutgers.edu S: Maintained +HGA FRAMEBUFFER DRIVER +P: Ferenc Bakonyi +M: fero@drama.obuda.kando.hu +L: linux-nvidia@lists.surfsouth.com +W: http://drama.obuda.kando.hu/~fero/cgi-bin/hgafb.shtml +S: Maintained + HIGH-SPEED SCC DRIVER FOR AX.25 P: Klaus Kudielka M: klaus.kudielka@ieee.org diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c index ab2e095af..d29f8cf1f 100644 --- a/arch/arm/kernel/semaphore.c +++ b/arch/arm/kernel/semaphore.c @@ -7,6 +7,7 @@ * * Modified for ARM by Russell King */ +#include #include #include diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 96fbf1b88..4f5bd16c5 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1,4 +1,4 @@ -/* $Id: srmmu.c,v 1.220 2000/08/09 00:00:15 davem Exp $ +/* $Id: srmmu.c,v 1.221 2000/08/14 00:46:13 anton Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -137,8 +137,8 @@ static inline unsigned long srmmu_pgd_page(pgd_t pgd) static inline unsigned long srmmu_pmd_page(pmd_t pmd) { return srmmu_device_memory(pmd_val(pmd))?~0:(unsigned long)__nocache_va((pmd_val(pmd) & SRMMU_PTD_PMASK) << 4); } -static inline unsigned long srmmu_pte_pagenr(pte_t pte) -{ return srmmu_device_memory(pte_val(pte))?~0:(((pte_val(pte) & SRMMU_PTE_PMASK) << 4) >> PAGE_SHIFT); } +static inline struct page *srmmu_pte_page(pte_t pte) +{ return (mem_map + (unsigned long)(srmmu_device_memory(pte_val(pte))?~0:(((pte_val(pte) & SRMMU_PTE_PMASK) << 4) >> PAGE_SHIFT))); } static inline int srmmu_pte_none(pte_t pte) { return !(pte_val(pte) & 0xFFFFFFF); } @@ -2153,7 +2153,7 @@ void __init ld_mmu_srmmu(void) BTFIXUPSET_CALL(set_pte, srmmu_set_pte, BTFIXUPCALL_SWAPO0O1); BTFIXUPSET_CALL(switch_mm, srmmu_switch_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(sparc_pte_pagenr, srmmu_pte_pagenr, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_page, srmmu_pte_page, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pgd_page, srmmu_pgd_page, BTFIXUPCALL_NORM); diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index 0ce0ca1e8..66bc3af7b 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -1,4 +1,4 @@ -/* $Id: sun4c.c,v 1.197 2000/08/09 00:00:15 davem Exp $ +/* $Id: sun4c.c,v 1.198 2000/08/14 00:46:13 anton Exp $ * sun4c.c: Doing in software what should be done in hardware. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -2156,9 +2156,9 @@ static pte_t sun4c_mk_pte_io(unsigned long page, pgprot_t pgprot, int space) return __pte(((page - PAGE_OFFSET) >> PAGE_SHIFT) | pgprot_val(pgprot)); } -static unsigned long sun4c_pte_pagenr(pte_t pte) +static struct page *sun4c_pte_page(pte_t pte) { - return (pte_val(pte) & SUN4C_PFN_MASK); + return (mem_map + (unsigned long)(pte_val(pte) & SUN4C_PFN_MASK)); } static inline unsigned long sun4c_pmd_page(pmd_t pmd) @@ -2650,7 +2650,7 @@ void __init ld_mmu_sun4c(void) BTFIXUPSET_CALL(set_pte, sun4c_set_pte, BTFIXUPCALL_STO1O0); - BTFIXUPSET_CALL(sparc_pte_pagenr, sun4c_pte_pagenr, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_page, sun4c_pte_page, BTFIXUPCALL_NORM); #if PAGE_SHIFT <= 12 BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_ANDNINT(PAGE_SIZE - 1)); #else diff --git a/drivers/char/i2c-old.c b/drivers/char/i2c-old.c index bd9750fc3..c896057cd 100644 --- a/drivers/char/i2c-old.c +++ b/drivers/char/i2c-old.c @@ -36,10 +36,6 @@ static struct i2c_bus *busses[I2C_BUS_MAX]; static struct i2c_driver *drivers[I2C_DRIVER_MAX]; static int bus_count = 0, driver_count = 0; -#ifdef CONFIG_VIDEO_BT848 -extern int i2c_tuner_init(void); -extern int msp3400c_init(void); -#endif #ifdef CONFIG_VIDEO_BUZ extern int saa7111_init(void); extern int saa7185_init(void); @@ -54,10 +50,6 @@ int i2c_init(void) printk(KERN_INFO "i2c: initialized%s\n", scan ? " (i2c bus scan enabled)" : ""); /* anything to do here ? */ -#ifdef CONFIG_VIDEO_BT848 - i2c_tuner_init(); - msp3400c_init(); -#endif #ifdef CONFIG_VIDEO_BUZ saa7111_init(); saa7185_init(); diff --git a/drivers/char/joystick/amijoy.c b/drivers/char/joystick/amijoy.c index f17aeda24..452d173d7 100644 --- a/drivers/char/joystick/amijoy.c +++ b/drivers/char/joystick/amijoy.c @@ -1,5 +1,5 @@ /* - * $Id: amijoy.c,v 1.4 2000/05/29 10:39:54 vojtech Exp $ + * $Id: amijoy.c,v 1.5 2000/07/21 22:52:24 vojtech Exp $ * * Copyright (c) 1998-2000 Vojtech Pavlik * @@ -77,7 +77,7 @@ static int amijoy_open(struct input_dev *dev) return 0; if (request_irq(IRQ_AMIGA_VERTB, amijoy_interrupt, 0, "amijoy", NULL)) { - amijoy_used--; + (*used)--; printk(KERN_ERR "amijoy.c: Can't allocate irq %d\n", amijoy_irq); return -EBUSY; } @@ -89,7 +89,7 @@ static void amijoy_close(struct input_dev *dev) { int *used = dev->private; - if (!--(*port->used)) + if (!--(*used)) free_irq(IRQ_AMIGA_VERTB, amijoy_interrupt); } @@ -112,13 +112,21 @@ static int __init amijoy_init(void) for (i = 0; i < 2; i++) if (amijoy[i]) { + if (!request_mem_region(CUSTOM_PHYSADDR+10+i*2, 2, + amijoy [Denise]")) { + if (i == 1 && amijoy[0]) { + input_unregister_device(amijoy_dev); + release_mem_region(CUSTOM_PHYSADDR+10, 2); + } + return -EBUSY; + } amijoy_dev[i].open = amijoy_open; amijoy_dev[i].close = amijoy_close; amijoy_dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); amijoy_dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y); amijoy_dev[i].keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); - for (j = 0; j < 2; j++) + for (j = 0; j < 2; j++) { amijoy_dev[i].absmin[ABS_X + j] = -1; amijoy_dev[i].absmax[ABS_X + j] = 1; } @@ -134,6 +142,7 @@ static int __init amijoy_init(void) input_register_device(amijoy_dev + i); printk(KERN_INFO "input%d: %s at joy%ddat\n", amijoy_dev[i].number, amijoy_name, i); } + return 0; } static void _exit amijoy_exit(void) @@ -141,8 +150,10 @@ static void _exit amijoy_exit(void) int i; for (i = 0; i < 2; i++) - if (amijoy[i]) + if (amijoy[i]) { input_unregister_device(amijoy_dev + i); + release_mem_region(CUSTOM_PHYSADDR+10+i*2, 2); + } } module_init(amijoy_init); diff --git a/drivers/char/joystick/db9.c b/drivers/char/joystick/db9.c index f9edd0755..4277e7f3d 100644 --- a/drivers/char/joystick/db9.c +++ b/drivers/char/joystick/db9.c @@ -1,5 +1,5 @@ /* - * $Id: db9.c,v 1.5 2000/05/29 20:39:38 vojtech Exp $ + * $Id: db9.c,v 1.6 2000/06/25 10:57:50 vojtech Exp $ * * Copyright (c) 1999 Vojtech Pavlik * @@ -95,7 +95,7 @@ static short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, static short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START }; static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 8, 1, 1, 7 }; -static short *db9_btn[DB9_MAX_PAD] = { db9_multi_btn, db9_multi_btn, db9_genesis_btn, NULL, db9_genesis_btn, +static short *db9_btn[DB9_MAX_PAD] = { NULL, db9_multi_btn, db9_multi_btn, db9_genesis_btn, NULL, db9_genesis_btn, db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn }; static char *db9_name[DB9_MAX_PAD] = { NULL, "Multisystem joystick", "Multisystem joystick (2 fire)", "Genesis pad", NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad", "Multisystem (0.8.0.2) joystick", @@ -113,36 +113,36 @@ static void db9_timer(unsigned long private) data = parport_read_data(port) >> 3; - input_report_abs(dev + 1, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1)); - input_report_abs(dev + 1, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1)); - input_report_key(dev + 1, BTN_TRIGGER, ~data&DB9_FIRE1); + input_report_abs(dev + 1, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); + input_report_abs(dev + 1, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); + input_report_key(dev + 1, BTN_TRIGGER, ~data & DB9_FIRE1); case DB9_MULTI_0802: data = parport_read_status(port) >> 3; - input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1)); - input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1)); - input_report_key(dev, BTN_TRIGGER, data&DB9_FIRE1); + input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); + input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); + input_report_key(dev, BTN_TRIGGER, data & DB9_FIRE1); break; case DB9_MULTI_STICK: data = parport_read_data(port); - input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1)); - input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1)); - input_report_key(dev, BTN_TRIGGER, ~data&DB9_FIRE1); + input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); + input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); + input_report_key(dev, BTN_TRIGGER, ~data & DB9_FIRE1); break; case DB9_MULTI2_STICK: data = parport_read_data(port); - input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1)); - input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1)); - input_report_key(dev, BTN_TRIGGER, ~data&DB9_FIRE1); - input_report_key(dev, BTN_THUMB, ~data&DB9_FIRE2); + input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); + input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); + input_report_key(dev, BTN_TRIGGER, ~data & DB9_FIRE1); + input_report_key(dev, BTN_THUMB, ~data & DB9_FIRE2); break; case DB9_GENESIS_PAD: @@ -150,16 +150,16 @@ static void db9_timer(unsigned long private) parport_write_control(port, DB9_NOSELECT); data = parport_read_data(port); - input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1)); - input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1)); - input_report_key(dev, BTN_B, ~data&DB9_FIRE1); - input_report_key(dev, BTN_C, ~data&DB9_FIRE2); + input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); + input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); + input_report_key(dev, BTN_B, ~data & DB9_FIRE1); + input_report_key(dev, BTN_C, ~data & DB9_FIRE2); parport_write_control(port, DB9_NORMAL); data=parport_read_data(port); - input_report_key(dev, BTN_A, ~data&DB9_FIRE1); - input_report_key(dev, BTN_START, ~data&DB9_FIRE2); + input_report_key(dev, BTN_A, ~data & DB9_FIRE1); + input_report_key(dev, BTN_START, ~data & DB9_FIRE2); break; case DB9_GENESIS5_PAD: @@ -167,18 +167,18 @@ static void db9_timer(unsigned long private) parport_write_control(port, DB9_NOSELECT); data=parport_read_data(port); - input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1)); - input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1)); - input_report_key(dev, BTN_B, ~data&DB9_FIRE1); - input_report_key(dev, BTN_C, ~data&DB9_FIRE2); + input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); + input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); + input_report_key(dev, BTN_B, ~data & DB9_FIRE1); + input_report_key(dev, BTN_C, ~data & DB9_FIRE2); parport_write_control(port, DB9_NORMAL); data=parport_read_data(port); - input_report_key(dev, BTN_A, ~data&DB9_FIRE1); - input_report_key(dev, BTN_X, ~data&DB9_FIRE2); - input_report_key(dev, BTN_Y, ~data&DB9_LEFT); - input_report_key(dev, BTN_START, ~data&DB9_RIGHT); + input_report_key(dev, BTN_A, ~data & DB9_FIRE1); + input_report_key(dev, BTN_X, ~data & DB9_FIRE2); + input_report_key(dev, BTN_Y, ~data & DB9_LEFT); + input_report_key(dev, BTN_START, ~data & DB9_RIGHT); break; case DB9_GENESIS6_PAD: @@ -187,17 +187,17 @@ static void db9_timer(unsigned long private) udelay(DB9_GENESIS6_DELAY); data=parport_read_data(port); - input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1)); - input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1)); - input_report_key(dev, BTN_B, ~data&DB9_FIRE1); - input_report_key(dev, BTN_C, ~data&DB9_FIRE2); + input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); + input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); + input_report_key(dev, BTN_B, ~data & DB9_FIRE1); + input_report_key(dev, BTN_C, ~data & DB9_FIRE2); parport_write_control(port, DB9_NORMAL); udelay(DB9_GENESIS6_DELAY); data=parport_read_data(port); - input_report_key(dev, BTN_A, ~data&DB9_FIRE1); - input_report_key(dev, BTN_X, ~data&DB9_FIRE2); + input_report_key(dev, BTN_A, ~data & DB9_FIRE1); + input_report_key(dev, BTN_X, ~data & DB9_FIRE2); parport_write_control(port, DB9_NOSELECT); /* 2 */ udelay(DB9_GENESIS6_DELAY); @@ -207,10 +207,10 @@ static void db9_timer(unsigned long private) udelay(DB9_GENESIS6_DELAY); data=parport_read_data(port); - input_report_key(dev, BTN_Y, ~data&DB9_LEFT); - input_report_key(dev, BTN_Z, ~data&DB9_DOWN); - input_report_key(dev, BTN_MODE, ~data&DB9_UP); - input_report_key(dev, BTN_START, ~data&DB9_RIGHT); + input_report_key(dev, BTN_Y, ~data & DB9_LEFT); + input_report_key(dev, BTN_Z, ~data & DB9_DOWN); + input_report_key(dev, BTN_MODE, ~data & DB9_UP); + input_report_key(dev, BTN_START, ~data & DB9_RIGHT); parport_write_control(port, DB9_NORMAL); udelay(DB9_GENESIS6_DELAY); @@ -224,32 +224,32 @@ static void db9_timer(unsigned long private) parport_write_control(port, DB9_SATURN0); data = parport_read_data(port); - input_report_key(dev, BTN_Y, ~data&DB9_LEFT); - input_report_key(dev, BTN_Z, ~data&DB9_DOWN); - input_report_key(dev, BTN_TL,~data&DB9_UP); - input_report_key(dev, BTN_TR,~data&DB9_RIGHT); + input_report_key(dev, BTN_Y, ~data & DB9_LEFT); + input_report_key(dev, BTN_Z, ~data & DB9_DOWN); + input_report_key(dev, BTN_TL, ~data & DB9_UP); + input_report_key(dev, BTN_TR, ~data & DB9_RIGHT); parport_write_control(port, DB9_SATURN2); data = parport_read_data(port); - input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1)); - input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1)); + input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); + input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); parport_write_control(port, DB9_NORMAL); data = parport_read_data(port); - input_report_key(dev, BTN_A, ~data&DB9_LEFT); - input_report_key(dev, BTN_B, ~data&DB9_UP); - input_report_key(dev, BTN_C, ~data&DB9_DOWN); - input_report_key(dev, BTN_X, ~data&DB9_RIGHT); + input_report_key(dev, BTN_A, ~data & DB9_LEFT); + input_report_key(dev, BTN_B, ~data & DB9_UP); + input_report_key(dev, BTN_C, ~data & DB9_DOWN); + input_report_key(dev, BTN_X, ~data & DB9_RIGHT); break; case DB9_CD32_PAD: data=parport_read_data(port); - input_report_abs(dev, ABS_X, (data&DB9_DOWN ?0:1) - (data&DB9_UP ?0:1)); - input_report_abs(dev, ABS_Y, (data&DB9_RIGHT?0:1) - (data&DB9_LEFT?0:1)); + input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); + input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); parport_write_control(port, 0x0a); @@ -257,7 +257,7 @@ static void db9_timer(unsigned long private) data = parport_read_data(port); parport_write_control(port, 0x02); parport_write_control(port, 0x0a); - input_report_key(dev, db9_cd32_btn[i], ~data&DB9_FIRE2); + input_report_key(dev, db9_cd32_btn[i], ~data & DB9_FIRE2); } parport_write_control(port, 0x00); diff --git a/drivers/char/joystick/gamecon.c b/drivers/char/joystick/gamecon.c index a92ef58a9..c1d37248f 100644 --- a/drivers/char/joystick/gamecon.c +++ b/drivers/char/joystick/gamecon.c @@ -1,5 +1,5 @@ /* - * $Id: gamecon.c,v 1.4 2000/05/29 21:08:45 vojtech Exp $ + * $Id: gamecon.c,v 1.5 2000/06/25 09:56:58 vojtech Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * @@ -157,7 +157,7 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) static unsigned char gc_nes_bytes[] = { 0, 1, 2, 3 }; static unsigned char gc_snes_bytes[] = { 8, 0, 2, 3, 9, 1, 10, 11 }; -static short gc_snes_btn[] = { BTN_A, BTN_B, BTN_START, BTN_SELECT, BTN_X, BTN_Y, BTN_TL, BTN_TR }; +static short gc_snes_btn[] = { BTN_A, BTN_B, BTN_SELECT, BTN_START, BTN_X, BTN_Y, BTN_TL, BTN_TR }; /* * gc_nes_read_packet() reads a NES/SNES packet. @@ -515,7 +515,7 @@ static struct gc __init *gc_probe(int *config) case GC_N64: for (j = 0; j < 10; j++) - set_bit(gc_n64_btn[j], gc->dev[j].keybit); + set_bit(gc_n64_btn[j], gc->dev[i].keybit); for (j = 0; j < 2; j++) { set_bit(ABS_X + j, gc->dev[i].absbit); @@ -530,18 +530,15 @@ static struct gc __init *gc_probe(int *config) break; case GC_SNES: - for (j = 0; j < 8; j++) - set_bit(gc_snes_btn[j], gc->dev[j].keybit); - break; - + for (j = 4; j < 8; j++) + set_bit(gc_snes_btn[j], gc->dev[i].keybit); case GC_NES: for (j = 0; j < 4; j++) - set_bit(gc_snes_btn[j], gc->dev[j].keybit); + set_bit(gc_snes_btn[j], gc->dev[i].keybit); break; case GC_MULTI2: set_bit(BTN_THUMB, gc->dev[i].keybit); - case GC_MULTI: set_bit(BTN_TRIGGER, gc->dev[i].keybit); break; @@ -656,12 +653,13 @@ void __exit gc_exit(void) { int i, j; - for (i = 0; i < 3; i++) { - for (j = 0; j < 5; j++) - if (gc_base[i]->pads[0] & gc_status_bit[j]) - input_unregister_device(gc_base[i]->dev + j); - parport_unregister_device(gc_base[i]->pd); - } + for (i = 0; i < 3; i++) + if (gc_base[i]) { + for (j = 0; j < 5; j++) + if (gc_base[i]->pads[0] & gc_status_bit[j]) + input_unregister_device(gc_base[i]->dev + j); + parport_unregister_device(gc_base[i]->pd); + } } module_init(gc_init); diff --git a/drivers/char/joystick/sidewinder.c b/drivers/char/joystick/sidewinder.c index 861966b4e..85be9f8b1 100644 --- a/drivers/char/joystick/sidewinder.c +++ b/drivers/char/joystick/sidewinder.c @@ -1,5 +1,5 @@ /* - * $Id: sidewinder.c,v 1.14 2000/05/29 11:27:55 vojtech Exp $ + * $Id: sidewinder.c,v 1.16 2000/07/14 09:02:41 vojtech Exp $ * * Copyright (c) 1998-2000 Vojtech Pavlik * @@ -330,8 +330,8 @@ static int sw_parse(unsigned char *buf, struct sw *sw) if (sw_parity(GB(i*15,15))) return -1; - input_report_key(dev + i, ABS_X, GB(i*15+3,1) - GB(i*15+2,1)); - input_report_key(dev + i, ABS_Y, GB(i*15+0,1) - GB(i*15+1,1)); + input_report_abs(dev + i, ABS_X, GB(i*15+3,1) - GB(i*15+2,1)); + input_report_abs(dev + i, ABS_Y, GB(i*15+0,1) - GB(i*15+1,1)); for (j = 0; j < 10; j++) input_report_key(dev, sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1)); diff --git a/drivers/char/joystick/spaceball.c b/drivers/char/joystick/spaceball.c index 4f5059330..8e2936f73 100644 --- a/drivers/char/joystick/spaceball.c +++ b/drivers/char/joystick/spaceball.c @@ -1,5 +1,5 @@ /* - * $Id: spaceball.c,v 1.6 2000/05/29 11:19:51 vojtech Exp $ + * $Id: spaceball.c,v 1.7 2000/06/24 11:55:40 vojtech Exp $ * * Copyright (c) 1999-2000 Vojtech Pavlik * @@ -46,7 +46,7 @@ */ #define JS_SBALL_MAX_LENGTH 128 -static int spaceball_axes[] = { ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ }; +static int spaceball_axes[] = { ABS_X, ABS_Z, ABS_Y, ABS_RX, ABS_RZ, ABS_RY }; static char *spaceball_name = "SpaceTec SpaceBall 4000 FLX"; /* @@ -70,10 +70,12 @@ static void spaceball_process_packet(struct spaceball* spaceball) { struct input_dev *dev = &spaceball->dev; unsigned char *data = spaceball->data; - int i, d; + int i; if (spaceball->idx < 2) return; + printk("%c %d\n", spaceball->data[0], spaceball->idx); + switch (spaceball->data[0]) { case '@': /* Reset packet */ @@ -84,17 +86,17 @@ static void spaceball_process_packet(struct spaceball* spaceball) break; case 'D': /* Ball data */ - if (spaceball->idx != 16) return; + if (spaceball->idx != 15) return; for (i = 0; i < 6; i++) { - d = ((data[2 * i + 3] << 8) | data[2 * i + 2]); - input_report_abs(dev, spaceball_axes[i], d - ((d & 0x8000) ? 0x10000 : 0)); + input_report_abs(dev, spaceball_axes[i], + (__s16)((data[2 * i + 3] << 8) | data[2 * i + 2])); } break; case '.': /* Button data, part2 */ - if (spaceball->idx != 4) return; - input_report_key(dev, BTN_LEFT, data[2] & 1); - input_report_key(dev, BTN_RIGHT, data[2] & 2); + if (spaceball->idx != 3) return; + input_report_key(dev, BTN_0, data[2] & 1); + input_report_key(dev, BTN_1, data[2] & 2); break; case '?': /* Error packet */ @@ -118,22 +120,27 @@ static void spaceball_interrupt(struct serio *serio, unsigned char data, unsigne switch (data) { case 0xd: - if (spaceball->idx) - spaceball_process_packet(spaceball); + spaceball_process_packet(spaceball); spaceball->idx = 0; spaceball->escape = 0; return; + case '^': + if (!spaceball->escape) { + spaceball->escape ^= 1; + return; + } + spaceball->escape = 0; case 'M': case 'Q': case 'S': - if (spaceball->escape) + if (spaceball->escape) { + spaceball->escape = 0; data = 0xd; - case '^': - spaceball->escape ^= 1; + } default: if (spaceball->escape) { - printk(KERN_WARNING "spaceball.c: Unknown escaped character: %#x\n", data); spaceball->escape = 0; + printk(KERN_WARNING "spaceball.c: Unknown escaped character: %#x (%c)\n", data, data); } if (spaceball->idx < JS_SBALL_MAX_LENGTH) spaceball->data[spaceball->idx++] = data; @@ -172,15 +179,15 @@ static void spaceball_connect(struct serio *serio, struct serio_dev *dev) memset(spaceball, 0, sizeof(struct spaceball)); spaceball->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - spaceball->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); + spaceball->dev.keybit[LONG(BTN_0)] = BIT(BTN_0) | BIT(BTN_1); for (i = 0; i < 6; i++) { t = spaceball_axes[i]; set_bit(t, spaceball->dev.absbit); - spaceball->dev.absmin[t] = i < 3 ? -10000 : -2000; - spaceball->dev.absmax[t] = i < 3 ? 10000 : 2000; - spaceball->dev.absflat[t] = i < 3 ? 50 : 10; - spaceball->dev.absfuzz[t] = i < 3 ? 12 : 2; + spaceball->dev.absmin[t] = i < 3 ? -8000 : -1600; + spaceball->dev.absmax[t] = i < 3 ? 8000 : 1600; + spaceball->dev.absflat[t] = i < 3 ? 40 : 8; + spaceball->dev.absfuzz[t] = i < 3 ? 8 : 2; } spaceball->serio = serio; diff --git a/drivers/isdn/eicon/Divas_mod.c b/drivers/isdn/eicon/Divas_mod.c index 752255682..8cb2a0409 100644 --- a/drivers/isdn/eicon/Divas_mod.c +++ b/drivers/isdn/eicon/Divas_mod.c @@ -25,6 +25,7 @@ */ +#include #include #undef N_DATA diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c index d2b09416b..8b389f846 100644 --- a/drivers/video/hgafb.c +++ b/drivers/video/hgafb.c @@ -7,6 +7,8 @@ * * History: * + * - Revision 0.1.6 (17 Aug 2000): new style structs + * documentation * - Revision 0.1.5 (13 Mar 2000): spinlocks instead of saveflags();cli();etc * minor fixes * - Revision 0.1.4 (24 Jan 2000): fixed a bug in hga_card_detect() for @@ -107,19 +109,23 @@ spinlock_t hga_reg_lock = SPIN_LOCK_UNLOCKED; /* Framebuffer driver structures */ static struct fb_var_screeninfo hga_default_var = { - 720, 348, /* xres, yres */ - 720, 348, /* xres_virtual, yres_virtual */ - 0, 0, /* xoffset, yoffset */ - 1, /* bits_per_pixel */ - 0, /* grayscale */ - {0, 1, 0}, /* red */ - {0, 1, 0}, /* green */ - {0, 1, 0}, /* blue */ - {0, 0, 0}, /* transp */ - 0, /* nonstd (FB_NONSTD_HGA ?) */ - 0, /* activate */ - -1, -1, /* height, width */ - 0, /* accel_flags */ + xres: 720, + yres: 348, + xres_virtual: 720, + yres_virtual: 348, + xoffset: 0, + yoffset: 0, + bits_per_pixel: 1, + grayscale: 0, + red: {0, 1, 0}, + green: {0, 1, 0}, + blue: {0, 1, 0}, + transp: {0, 0, 0}, + nonstd: 0, /* (FB_NONSTD_HGA ?) */ + activate: 0, + height: -1, + width: -1, + accel_flags: 0, /* pixclock */ /* left_margin, right_margin */ /* upper_margin, lower_margin */ @@ -129,19 +135,19 @@ static struct fb_var_screeninfo hga_default_var = { }; static struct fb_fix_screeninfo hga_fix = { - "HGA", /* id */ - (unsigned long) NULL, /* smem_start */ - 0, /* smem_len */ - FB_TYPE_PACKED_PIXELS, /* type (not sure) */ - 0, /* type_aux (not sure) */ - FB_VISUAL_MONO10, /* visual */ - 8, /* xpanstep */ - 8, /* ypanstep */ - 0, /* ywrapstep */ - 90, /* line_length */ - 0, /* mmio_start */ - 0, /* mmio_len */ - FB_ACCEL_NONE /* accel */ + id: "HGA", + smem_start: (unsigned long) NULL, + smem_len: 0, + type: FB_TYPE_PACKED_PIXELS, /* (not sure) */ + type_aux: 0, /* (not sure) */ + visual: FB_VISUAL_MONO10, + xpanstep: 8, + ypanstep: 8, + ywrapstep: 0, + line_length: 90, + mmio_start: 0, + mmio_len: 0, + accel: FB_ACCEL_NONE }; static struct fb_info fb_info; @@ -377,9 +383,15 @@ static int __init hga_card_detect(void) * * ------------------------------------------------------------------------- */ - /* - * Get the Fixed Part of the Display - */ +/** + * hga_get_fix - get the fixed part of the display + * @fix:struct fb_fix_screeninfo to fill in + * @con:unused + * @info:pointer to fb_info object containing info for current hga board + * + * This wrapper function copies @info->fix to @fix. + * A zero is returned on success and %-EINVAL for failure. + */ int hga_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info) { @@ -390,10 +402,15 @@ int hga_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info) return 0; } - - /* - * Get the User Defined Part of the Display - */ +/** + * hga_get_var - get the user defined part of the display + * @var:struct fb_var_screeninfo to fill in + * @con:unused + * @info:pointer to fb_info object containing info for current hga board + * + * This wrapper function copies @info->var to @var. + * A zero is returned on success and %-EINVAL for failure. + */ int hga_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) { @@ -404,13 +421,23 @@ int hga_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) return 0; } - /* - * Set the User Defined Part of the Display - * This is the most mystical function (at least for me). - * What is the exact specification of xxx_set_var? - * Should it handle xoffset, yoffset? Should it do pannig? - * What does vmode mean? - */ +/** + * hga_set_var - set the user defined part of the display + * @var:new video mode + * @con:unused + * @info:pointer to fb_info object containing info for current hga board + * + * This function is called for changing video modes. Since HGA cards have + * only one fixed mode we have not much to do. After checking input + * parameters @var is copied to @info->var and @info->changevar is called. + * A zero is returned on success and %-EINVAL for failure. + * + * FIXME: + * This is the most mystical function (at least for me). + * What is the exact specification of xxx_set_var()? + * Should it handle xoffset, yoffset? Should it do panning? + * What does vmode mean? + */ int hga_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) { @@ -431,10 +458,20 @@ int hga_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) return 0; } - - /* - * Get the Colormap - */ +/** + * hga_getcolreg - read color registers + * @regno:register index to read out + * @red:red value + * @green:green value + * @blue:blue value + * @transp:transparency value + * @info:unused + * + * This callback function is used to read the color registers of a HGA + * board. Since we have only two fixed colors, RGB values are 0x0000 + * for register0 and 0xaaaa for register1. + * A zero is returned on success and 1 for failure. + */ static int hga_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, u_int *transp, struct fb_info *info) @@ -450,6 +487,17 @@ static int hga_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, return 0; } +/** + * hga_get_cmap - get the colormap + * @cmap:struct fb_cmap to fill in + * @kspc:called from kernel space? + * @con:unused + * @info:pointer to fb_info object containing info for current hga board + * + * This wrapper function passes it's input parameters to fb_get_cmap(). + * Callback function hga_getcolreg() is used to read the color registers. + */ + int hga_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) { @@ -458,9 +506,19 @@ int hga_get_cmap(struct fb_cmap *cmap, int kspc, int con, return fb_get_cmap(cmap, kspc, hga_getcolreg, info); } - /* - * Set the Colormap - */ +/** + * hga_setcolreg - set color registers + * @regno:register index to set + * @red:red value, unused + * @green:green value, unused + * @blue:blue value, unused + * @transp:transparency value, unused + * @info:unused + * + * This callback function is used to set the color registers of a HGA + * board. Since we have only two fixed colors only @regno is checked. + * A zero is returned on success and 1 for failure. + */ static int hga_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) @@ -470,6 +528,17 @@ static int hga_setcolreg(u_int regno, u_int red, u_int green, u_int blue, return 0; } +/** + * hga_set_cmap - set the colormap + * @cmap:struct fb_cmap to set + * @kspc:called from kernel space? + * @con:unused + * @info:pointer to fb_info object containing info for current hga board + * + * This wrapper function passes it's input parameters to fb_set_cmap(). + * Callback function hga_setcolreg() is used to set the color registers. + */ + int hga_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) { @@ -478,11 +547,17 @@ int hga_set_cmap(struct fb_cmap *cmap, int kspc, int con, return fb_set_cmap(cmap, kspc, hga_setcolreg, info); } - /* - * Pan or Wrap the Display - * - * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag - */ +/** + * hga_pan_display - pan or wrap the display + * @var:contains new xoffset, yoffset and vmode values + * @con:unused + * @info:pointer to fb_info object containing info for current hga board + * + * This function looks only at xoffset, yoffset and the %FB_VMODE_YWRAP + * flag in @var. If input parameters are correct it calls hga_pan() to + * program the hardware. @info->var is updated to the new values. + * A zero is returned on success and %-EINVAL for failure. + */ int hga_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info *info) @@ -531,6 +606,18 @@ static struct fb_ops hgafb_ops = { * * ------------------------------------------------------------------------- */ +/** + * hgafbcon_switch - switch console + * @con:new console to switch to + * @info:pointer to fb_info object containing info for current hga board + * + * This function should install a new colormap and change the video mode. + * Since we have fixed colors and only one video mode we have nothing to + * do. + * Only console administration is done but it should go to fbcon.c IMHO. + * A zero is returned on success and %-EINVAL for failure. + */ + static int hgafbcon_switch(int con, struct fb_info *info) { CHKINFO(-EINVAL); @@ -564,6 +651,17 @@ static int hgafbcon_switch(int con, struct fb_info *info) return 0; } +/** + * hgafbcon_updatevar - update the user defined part of the display + * @con:console to update or -1 when no consoles defined on this fb + * @info:pointer to fb_info object containing info for current hga board + * + * This function is called when @var is changed by fbcon.c without calling + * hga_set_var(). It usually means scrolling. hga_pan_display() is called + * to update the hardware and @info->var. + * A zero is returned on success and %-EINVAL for failure. + */ + static int hgafbcon_updatevar(int con, struct fb_info *info) { CHKINFO(-EINVAL); @@ -571,17 +669,21 @@ static int hgafbcon_updatevar(int con, struct fb_info *info) return (con < 0) ? -EINVAL : hga_pan_display(&fb_display[con].var, con, info); } +/** + * hgafbcon_blank - (un)blank the screen + * @blank_mode:blanking method to use + * @info:unused + * + * Blank the screen if blank_mode != 0, else unblank. + * Implements VESA suspend and powerdown modes on hardware that supports + * disabling hsync/vsync: + * @blank_mode == 2 means suspend vsync, + * @blank_mode == 3 means suspend hsync, + * @blank_mode == 4 means powerdown. + */ + static void hgafbcon_blank(int blank_mode, struct fb_info *info) { - /* - * Blank the screen if blank_mode != 0, else unblank. - * Implements VESA suspend and powerdown modes on hardware - * that supports disabling hsync/vsync: - * blank_mode == 2: suspend vsync - * blank_mode == 3: suspend hsync - * blank_mode == 4: powerdown - */ - CHKINFO( ); DPRINTK("hga_blank: blank_mode:%d, info:%x, fb_info:%x\n", blank_mode, (unsigned)info, (unsigned)&fb_info); diff --git a/fs/Config.in b/fs/Config.in index e48f75496..183aab8f8 100644 --- a/fs/Config.in +++ b/fs/Config.in @@ -99,7 +99,9 @@ if [ "$CONFIG_NET" = "y" ]; then fi dep_tristate 'SMB file system support (to mount Windows shares etc.)' CONFIG_SMB_FS $CONFIG_INET - + if [ "$CONFIG_SMB_FS" != "n" ]; then + string 'Default Remote NLS Option' CONFIG_SMB_NLS_REMOTE "" + fi if [ "$CONFIG_IPX" != "n" -o "$CONFIG_INET" != "n" ]; then tristate 'NCP file system support (to mount NetWare volumes)' CONFIG_NCP_FS source fs/ncpfs/Config.in diff --git a/fs/buffer.c b/fs/buffer.c index 8c7316156..ca6e2f919 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -119,7 +119,7 @@ union bdflush_param { when trying to refill buffers. */ int interval; /* jiffies delay between kupdate flushes */ int age_buffer; /* Time for normal buffer to age before we flush it */ - int age_super; /* Time for superblock to age before we flush it */ + int dummy1; /* unused, was age_super */ int dummy2; /* unused */ int dummy3; /* unused */ } b_un; @@ -894,7 +894,7 @@ void balance_dirty(kdev_t dev) static __inline__ void __mark_dirty(struct buffer_head *bh, int flag) { - bh->b_flushtime = jiffies + (flag ? bdf_prm.b_un.age_super : bdf_prm.b_un.age_buffer); + bh->b_flushtime = jiffies + bdf_prm.b_un.age_buffer; refile_buffer(bh); } @@ -1714,8 +1714,10 @@ int generic_commit_write(struct file *file, struct page *page, loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; __block_commit_write(inode,page,from,to); kunmap(page); - if (pos > inode->i_size) + if (pos > inode->i_size) { inode->i_size = pos; + mark_inode_dirty(inode); + } return 0; } @@ -1837,6 +1839,7 @@ int brw_kiovec(int rw, int nr, struct kiobuf *iovec[], int pageind; int bhind; int offset; + int sectors = size>>9; unsigned long blocknr; struct kiobuf * iobuf = NULL; struct page * map; @@ -1888,9 +1891,10 @@ int brw_kiovec(int rw, int nr, struct kiobuf *iovec[], tmp->b_this_page = tmp; init_buffer(tmp, end_buffer_io_kiobuf, iobuf); - tmp->b_dev = dev; + tmp->b_rdev = tmp->b_dev = dev; tmp->b_blocknr = blocknr; - tmp->b_state = 1 << BH_Mapped; + tmp->b_rsector = blocknr*sectors; + tmp->b_state = (1 << BH_Mapped) | (1 << BH_Lock) | (1 << BH_Req); if (rw == WRITE) { set_bit(BH_Uptodate, &tmp->b_state); diff --git a/fs/inode.c b/fs/inode.c index 455c4af6e..2199d6888 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -771,6 +771,7 @@ void iput(struct inode *inode) list_del(&inode->i_list); INIT_LIST_HEAD(&inode->i_list); inode->i_state|=I_FREEING; + inodes_stat.nr_inodes--; spin_unlock(&inode_lock); if (inode->i_data.nrpages) @@ -799,11 +800,11 @@ void iput(struct inode *inode) list_del(&inode->i_list); INIT_LIST_HEAD(&inode->i_list); inode->i_state|=I_FREEING; + inodes_stat.nr_inodes--; spin_unlock(&inode_lock); clear_inode(inode); } } - inodes_stat.nr_inodes--; destroy_inode(inode); } } diff --git a/fs/nls/Config.in b/fs/nls/Config.in index c33e9d6b8..5c9754aca 100644 --- a/fs/nls/Config.in +++ b/fs/nls/Config.in @@ -4,7 +4,8 @@ # msdos and Joliet want NLS if [ "$CONFIG_JOLIET" = "y" -o "$CONFIG_FAT_FS" != "n" \ - -o "$CONFIG_NTFS_FS" != "n" -o "$CONFIG_NCPFS_NLS" = "y" ]; then + -o "$CONFIG_NTFS_FS" != "n" -o "$CONFIG_NCPFS_NLS" = "y" \ + -o "$CONFIG_SMB_FS" != "n" ]; then define_bool CONFIG_NLS y else define_bool CONFIG_NLS n diff --git a/fs/smbfs/ChangeLog b/fs/smbfs/ChangeLog index 893890334..a57b1cc67 100644 --- a/fs/smbfs/ChangeLog +++ b/fs/smbfs/ChangeLog @@ -1,5 +1,16 @@ ChangeLog for smbfs. +2000-08-14 Urban Widmark + + * dir.c: support case sensitive shares + * inode.c: ascii mount options + * proc.c: check length of paths to avoid buffer overflow + * proc.c: don't do interruptable_sleep in smb_retry to avoid signal + problem/race. + * proc.c: O_RDONLY & smb_revalidate_inode fix (tail -f) + * proc.c: add nls support + * sock.c: attempt to fix smb_data_callback (avoid infinite loop) + 2000-07-25 Urban Widmark * proc.c: fix 3 places where bad server responses could cause an Oops. diff --git a/fs/smbfs/Makefile b/fs/smbfs/Makefile index 3ea59f6cc..825b0156a 100644 --- a/fs/smbfs/Makefile +++ b/fs/smbfs/Makefile @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definitions are now in the main makefile... O_TARGET := smbfs.o -O_OBJS := proc.o dir.o cache.o sock.o inode.o file.o ioctl.o +O_OBJS := proc.o dir.o cache.o sock.o inode.o file.o ioctl.o getopt.o M_OBJS := $(O_TARGET) # If you want debugging output, you may add these flags to the EXTRA_CFLAGS diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index 9598ab82c..b2d5c4099 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c @@ -14,6 +14,7 @@ #include #include +#include #include #include "smb_debug.h" @@ -142,7 +143,7 @@ out: } /* - * Note: in order to allow the smbclient process to open the + * Note: in order to allow the smbmount process to open the * mount point, we don't revalidate if conn_pid is NULL. */ static int @@ -190,6 +191,13 @@ static struct dentry_operations smbfs_dentry_operations = d_delete: smb_delete_dentry, }; +static struct dentry_operations smbfs_dentry_operations_case = +{ + d_revalidate: smb_lookup_validate, + d_delete: smb_delete_dentry, +}; + + /* * This is the callback when the dcache has a lookup hit. */ @@ -249,8 +257,7 @@ smb_compare_dentry(struct dentry *dir, struct qstr *a, struct qstr *b) if (a->len != b->len) goto out; - for (i=0; i < a->len; i++) - { + for (i=0; i < a->len; i++) { if (tolower(a->name[i]) != tolower(b->name[i])) goto out; } @@ -300,6 +307,7 @@ smb_lookup(struct inode *dir, struct dentry *dentry) struct smb_fattr finfo; struct inode *inode; int error; + struct smb_sb_info *server; error = -ENAMETOOLONG; if (dentry->d_name.len > SMB_MAXNAMELEN) @@ -315,15 +323,18 @@ smb_lookup(struct inode *dir, struct dentry *dentry) inode = NULL; if (error == -ENOENT) goto add_entry; - if (!error) - { + if (!error) { error = -EACCES; finfo.f_ino = smb_invent_inos(1); inode = smb_iget(dir->i_sb, &finfo); - if (inode) - { + if (inode) { add_entry: - dentry->d_op = &smbfs_dentry_operations; + server = server_from_dentry(dentry); + if (server->mnt->flags & SMB_MOUNT_CASE) + dentry->d_op = &smbfs_dentry_operations_case; + else + dentry->d_op = &smbfs_dentry_operations; + d_add(dentry, inode); smb_renew_times(dentry); error = 0; diff --git a/fs/smbfs/getopt.c b/fs/smbfs/getopt.c new file mode 100644 index 000000000..0c5d111b3 --- /dev/null +++ b/fs/smbfs/getopt.c @@ -0,0 +1,61 @@ +/* + * getopt.c + */ + +#include +#include + +#include "getopt.h" + +/** + * smb_getopt - option parser + * @caller: name of the caller, for error messages + * @options: the options string + * @opts: an array of &struct option entries controlling parser operations + * @optopt: output; will contain the current option + * @optarg: output; will contain the value (if one exists) + * @flag: output; may be NULL; should point to a long for or'ing flags + * @value: output; may be NULL; will be overwritten with the integer value + * of the current argument. + * + * Helper to parse options on the format used by mount ("a=b,c=d,e,f"). + * Returns opts->val if a matching entry in the 'opts' array is found, + * 0 when no more tokens are found, -1 if an error is encountered. + */ +int smb_getopt(char *caller, char **options, struct option *opts, + char **optopt, char **optarg, unsigned long *flag, + unsigned long *value) +{ + char *token; + char *val; + int i; + + if ( (token = strsep(options, ",")) == NULL) + return 0; + *optopt = token; + + *optarg = NULL; + if ((val = strchr (token, '=')) != NULL) { + *val++ = 0; + if (value) + *value = simple_strtoul(val, NULL, 0); + *optarg = val; + } + + for (i = 0; opts[i].name != NULL; i++) { + if (!strcmp(opts[i].name, token)) { + if (opts[i].has_arg && (!val || !*val)) { + printk("%s: the %s option requires an argument\n", + caller, token); + return -1; + } + + if (flag && opts[i].flag) + *flag |= opts[i].flag; + + return opts[i].val; + } + } + printk("%s: Unrecognized mount option %s\n", caller, token); + return -1; +} diff --git a/fs/smbfs/getopt.h b/fs/smbfs/getopt.h new file mode 100644 index 000000000..691f21103 --- /dev/null +++ b/fs/smbfs/getopt.h @@ -0,0 +1,15 @@ +#ifndef _LINUX_GETOPT_H +#define _LINUX_GETOPT_H + +struct option { + const char *name; + int has_arg; + unsigned long flag; + int val; +}; + +extern int smb_getopt(char *caller, char **options, struct option *opts, + char **optopt, char **optarg, unsigned long *flag, + unsigned long *value); + +#endif /* _LINUX_GETOPT_H */ diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index d7cb992b8..d26f079ff 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,7 @@ #include #include "smb_debug.h" +#include "getopt.h" static void smb_delete_inode(struct inode *); static void smb_put_super(struct super_block *); @@ -282,6 +284,82 @@ smb_delete_inode(struct inode *ino) clear_inode(ino); } +/* FIXME: flags and has_arg could probably be merged. */ +struct option opts[] = { + { "version", 1, 0, 'v' }, + { "win95", 0, SMB_MOUNT_WIN95, 1 }, + { "oldattr", 0, SMB_MOUNT_OLDATTR, 1 }, + { "dirattr", 0, SMB_MOUNT_DIRATTR, 1 }, + { "case", 0, SMB_MOUNT_CASE, 1 }, + { "uid", 1, 0, 'u' }, + { "gid", 1, 0, 'g' }, + { "file_mode", 1, 0, 'f' }, + { "dir_mode", 1, 0, 'd' }, + { "iocharset", 1, 0, 'i' }, + { "codepage", 1, 0, 'c' }, + { NULL, 0, 0, 0} +}; + +static int +parse_options(struct smb_mount_data_kernel *mnt, char *options) +{ + int c; + unsigned long flags; + unsigned long value; + char *optarg; + char *optopt; + + flags = 0; + while ( (c = smb_getopt("smbfs", &options, opts, + &optopt, &optarg, &flags, &value)) > 0) { + + VERBOSE("'%s' -> '%s'\n", optopt, optarg ? optarg : ""); + + switch (c) { + case 1: + /* got a "flag" option */ + break; + case 'v': + if (value != SMB_MOUNT_VERSION) { + printk ("smbfs: Bad mount version %ld, expected %d\n", + value, SMB_MOUNT_VERSION); + return 0; + } + mnt->version = value; + break; + case 'u': + mnt->uid = value; + break; + case 'g': + mnt->gid = value; + break; + case 'f': + mnt->file_mode = value & (S_IRWXU | S_IRWXG | S_IRWXO); + mnt->file_mode |= S_IFREG; + break; + case 'd': + mnt->dir_mode = value & (S_IRWXU | S_IRWXG | S_IRWXO); + mnt->dir_mode |= S_IFDIR; + break; + case 'i': + strncpy(mnt->codepage.local_name, optarg, + SMB_NLS_MAXNAMELEN); + break; + case 'c': + strncpy(mnt->codepage.remote_name, optarg, + SMB_NLS_MAXNAMELEN); + break; + default: + printk ("smbfs: Unrecognized mount option %s\n", + optopt); + return -1; + } + } + mnt->flags = flags; + return c; +} + + static void smb_put_super(struct super_block *sb) { @@ -300,18 +378,32 @@ smb_put_super(struct super_block *sb) kfree(sb->u.smbfs_sb.temp_buf); if (server->packet) smb_vfree(server->packet); + + if(sb->u.smbfs_sb.remote_nls) { + unload_nls(sb->u.smbfs_sb.remote_nls); + sb->u.smbfs_sb.remote_nls = NULL; + } + if(sb->u.smbfs_sb.local_nls) { + unload_nls(sb->u.smbfs_sb.local_nls); + sb->u.smbfs_sb.local_nls = NULL; + } } struct super_block * smb_read_super(struct super_block *sb, void *raw_data, int silent) { - struct smb_mount_data *mnt; + struct smb_mount_data_kernel *mnt; + struct smb_mount_data *oldmnt; struct inode *root_inode; struct smb_fattr root; + int ver; if (!raw_data) goto out_no_data; - if (((struct smb_mount_data *) raw_data)->version != SMB_MOUNT_VERSION) + + oldmnt = (struct smb_mount_data *) raw_data; + ver = oldmnt->version; + if (ver != SMB_MOUNT_OLDVERSION && cpu_to_be32(ver) != SMB_MOUNT_ASCII) goto out_wrong_data; sb->s_blocksize = 1024; /* Eh... Is this correct? */ @@ -320,6 +412,7 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent) sb->s_flags = 0; sb->s_op = &smb_sops; + sb->u.smbfs_sb.mnt = NULL; sb->u.smbfs_sb.sock_file = NULL; init_MUTEX(&sb->u.smbfs_sb.sem); init_waitqueue_head(&sb->u.smbfs_sb.wait); @@ -332,30 +425,61 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent) goto out_no_mem; /* Allocate the global temp buffer */ - sb->u.smbfs_sb.temp_buf = kmalloc(SMB_MAXPATHLEN + 20, GFP_KERNEL); + sb->u.smbfs_sb.temp_buf = kmalloc(2*SMB_MAXPATHLEN + 20, GFP_KERNEL); if (!sb->u.smbfs_sb.temp_buf) goto out_no_temp; + /* Setup NLS stuff */ + sb->u.smbfs_sb.remote_nls = NULL; + sb->u.smbfs_sb.local_nls = NULL; + sb->u.smbfs_sb.name_buf = sb->u.smbfs_sb.temp_buf + SMB_MAXPATHLEN + 20; + /* Allocate the mount data structure */ - mnt = kmalloc(sizeof(struct smb_mount_data), GFP_KERNEL); + /* FIXME: merge this with the other malloc and get a whole page? */ + mnt = kmalloc(sizeof(struct smb_mount_data_kernel), GFP_KERNEL); if (!mnt) goto out_no_mount; - *mnt = *((struct smb_mount_data *) raw_data); - /* FIXME: passes config flags in high bits of file mode. Should be a - separate flags field. (but smbmount includes kernel headers ...) */ - mnt->version = (mnt->file_mode >> 9); - mnt->file_mode &= (S_IRWXU | S_IRWXG | S_IRWXO); - mnt->file_mode |= S_IFREG; - mnt->dir_mode &= (S_IRWXU | S_IRWXG | S_IRWXO); - mnt->dir_mode |= S_IFDIR; sb->u.smbfs_sb.mnt = mnt; + + memset(mnt, 0, sizeof(struct smb_mount_data_kernel)); + strncpy(mnt->codepage.local_name, CONFIG_NLS_DEFAULT, + SMB_NLS_MAXNAMELEN); + strncpy(mnt->codepage.local_name, CONFIG_SMB_NLS_REMOTE, + SMB_NLS_MAXNAMELEN); + + if (ver == SMB_MOUNT_OLDVERSION) { + mnt->version = oldmnt->version; + + /* FIXME: is this enough to convert uid/gid's ? */ + mnt->mounted_uid = oldmnt->mounted_uid; + mnt->uid = oldmnt->uid; + mnt->gid = oldmnt->gid; + + mnt->file_mode = + oldmnt->file_mode & (S_IRWXU | S_IRWXG | S_IRWXO); + mnt->dir_mode = + oldmnt->dir_mode & (S_IRWXU | S_IRWXG | S_IRWXO); + mnt->file_mode |= S_IFREG; + mnt->dir_mode |= S_IFDIR; + + mnt->flags = (oldmnt->file_mode >> 9); + } else { + if (parse_options(mnt, raw_data)) + goto out_bad_option; + + mnt->mounted_uid = current->uid; + } + smb_setcodepage(&sb->u.smbfs_sb, &mnt->codepage); + if (!sb->u.smbfs_sb.convert) + PARANOIA("convert funcptr was NULL!\n"); + /* * Display the enabled options * Note: smb_proc_getattr uses these in 2.4 (but was changed in 2.2) */ - if (mnt->version & SMB_FIX_OLDATTR) + if (mnt->flags & SMB_MOUNT_OLDATTR) printk("SMBFS: Using core getattr (Win 95 speedup)\n"); - else if (mnt->version & SMB_FIX_DIRATTR) + else if (mnt->flags & SMB_MOUNT_DIRATTR) printk("SMBFS: Using dir ff getattr\n"); /* @@ -374,16 +498,18 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent) out_no_root: iput(root_inode); +out_bad_option: kfree(sb->u.smbfs_sb.mnt); out_no_mount: kfree(sb->u.smbfs_sb.temp_buf); out_no_temp: smb_vfree(sb->u.smbfs_sb.packet); out_no_mem: - printk(KERN_ERR "smb_read_super: allocation failure\n"); + if (!sb->u.smbfs_sb.mnt) + printk(KERN_ERR "smb_read_super: allocation failure\n"); goto out_fail; out_wrong_data: - printk(KERN_ERR "SMBFS: need mount version %d\n", SMB_MOUNT_VERSION); + printk(KERN_ERR "smbfs: mount_data version %d is not supported\n", ver); goto out_fail; out_no_data: printk(KERN_ERR "smb_read_super: missing data argument\n"); diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c index e969320b7..7863cd2da 100644 --- a/fs/smbfs/proc.c +++ b/fs/smbfs/proc.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -25,10 +26,14 @@ #include "smb_debug.h" + /* Features. Undefine if they cause problems, this should perhaps be a config option. */ #define SMBFS_POSIX_UNLINK 1 +/* Allow smb_retry to be interrupted. Not sure of the benefit ... */ +/* #define SMB_RETRY_INTR */ + #define SMB_VWV(packet) ((packet) + SMB_HEADER_LEN) #define SMB_CMD(packet) (*(packet+8)) #define SMB_WCT(packet) (*(packet+SMB_HEADER_LEN - 1)) @@ -48,6 +53,20 @@ static int smb_proc_do_getattr(struct smb_sb_info *server, struct dentry *dir, struct smb_fattr *fattr); + +static inline void +smb_lock_server(struct smb_sb_info *server) +{ + down(&(server->sem)); +} + +static inline void +smb_unlock_server(struct smb_sb_info *server) +{ + up(&(server->sem)); +} + + static void str_upper(char *name, int len) { @@ -83,6 +102,96 @@ static void reverse_string(char *buf, int len) } } +/* no conversion, just a wrapper for memcpy. */ +static int convert_memcpy(char *output, int olen, + const char *input, int ilen, + struct nls_table *nls_from, + struct nls_table *nls_to) +{ + memcpy(output, input, ilen); + return ilen; +} + +/* convert from one "codepage" to another (possibly being utf8). */ +static int convert_cp(char *output, int olen, + const char *input, int ilen, + struct nls_table *nls_from, + struct nls_table *nls_to) +{ + int len = 0; + int n; + wchar_t ch; + + if (!nls_from || !nls_to) { + PARANOIA("nls_from=%p, nls_to=%p\n", nls_from, nls_to); + return convert_memcpy(output, olen, input, ilen, NULL, NULL); + } + + while (ilen > 0) { + /* convert by changing to unicode and back to the new cp */ + n = nls_from->char2uni((unsigned char *)input, ilen, &ch); + if (n < 0) + goto out; + input += n; + ilen -= n; + + n = nls_to->uni2char(ch, output, olen); + if (n < 0) + goto out; + output += n; + olen -= n; + + len += n; + } +out: + return len; +} + +static int setcodepage(struct smb_sb_info *server, + struct nls_table **p, char *name) +{ + struct nls_table *nls; + + if (!name || !*name) { + nls = NULL; + } else if ( (nls = load_nls(name)) == NULL) { + printk (KERN_ERR "smbfs: failed to load nls '%s'\n", name); + return -EINVAL; + } + + /* if already set, unload the previous one. */ + if (*p) + unload_nls(*p); + *p = nls; + + return 0; +} + +/* Handles all changes to codepage settings. */ +int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp) +{ + int n; + + smb_lock_server(server); + + n = setcodepage(server, &server->local_nls, cp->local_name); + if (n != 0) + goto out; + n = setcodepage(server, &server->remote_nls, cp->remote_name); + if (n != 0) + setcodepage(server, &server->local_nls, NULL); + +out: + if (server->local_nls != NULL && server->remote_nls != NULL) + server->convert = convert_cp; + else + server->convert = convert_memcpy; + + smb_unlock_server(server); + return n; +} + + /*****************************************************************************/ /* */ /* Encoding/Decoding section */ @@ -107,9 +216,11 @@ smb_encode_smb_length(__u8 * p, __u32 len) * smb_build_path: build the path to entry and name storing it in buf. * The path returned will have the trailing '\0'. */ -static int smb_build_path(struct dentry * entry, struct qstr * name, char * buf) +static int smb_build_path(struct smb_sb_info *server, char * buf, + struct dentry * entry, struct qstr * name) { char *path = buf; + int len; if (entry == NULL) goto test_name_and_out; @@ -129,9 +240,16 @@ static int smb_build_path(struct dentry * entry, struct qstr * name, char * buf) * and store it in reversed order [see reverse_string()] */ for (;;) { - memcpy(path, entry->d_name.name, entry->d_name.len); - reverse_string(path, entry->d_name.len); - path += entry->d_name.len; + if (entry->d_name.len > SMB_MAXNAMELEN) + return -ENAMETOOLONG; + if (path - buf + entry->d_name.len > SMB_MAXPATHLEN) + return -ENAMETOOLONG; + + len = server->convert(path, SMB_MAXNAMELEN, + entry->d_name.name, entry->d_name.len, + server->local_nls, server->remote_nls); + reverse_string(path, len); + path += len; *(path++) = '\\'; @@ -147,25 +265,28 @@ test_name_and_out: if (name != NULL) { *(path++) = '\\'; name_and_out: - memcpy(path, name->name, name->len); - path += name->len; + len = server->convert(path, SMB_MAXNAMELEN, + name->name, name->len, + server->local_nls, server->remote_nls); + path += len; } out: *(path++) = '\0'; return (path-buf); } -static char *smb_encode_path(struct smb_sb_info *server, char *buf, - struct dentry *dir, struct qstr *name) +static int smb_encode_path(struct smb_sb_info *server, char *buf, + struct dentry *dir, struct qstr *name) { - char *start = buf; - - buf += smb_build_path(dir, name, buf); + int result; + result = smb_build_path(server, buf, dir, name); + if (result < 0) + goto out; if (server->opt.protocol <= SMB_PROTOCOL_COREPLUS) - str_upper(start, buf - start); - - return buf; + str_upper(buf, result); +out: + return result; } /* The following are taken directly from msdos-fs */ @@ -464,18 +585,6 @@ err_unknown: return EIO; } -static inline void -smb_lock_server(struct smb_sb_info *server) -{ - down(&(server->sem)); -} - -static inline void -smb_unlock_server(struct smb_sb_info *server) -{ - up(&(server->sem)); -} - /* * smb_retry: This function should be called when smb_request_ok has * indicated an error. If the error was indicated because the @@ -495,8 +604,7 @@ smb_retry(struct smb_sb_info *server) smb_close_socket(server); - if (pid == 0) - { + if (pid == 0) { printk(KERN_ERR "smb_retry: no connection process\n"); server->state = CONN_RETRIED; goto out; @@ -511,26 +619,35 @@ smb_retry(struct smb_sb_info *server) * Note: use the "priv" flag, as a user process may need to reconnect. */ error = kill_proc(pid, SIGUSR1, 1); - if (error) - { + if (error) { printk(KERN_ERR "smb_retry: signal failed, error=%d\n", error); goto out_restore; } - VERBOSE("signalled pid %d, waiting for new connection\n", - server->conn_pid); + VERBOSE("signalled pid %d, waiting for new connection\n", pid); /* * Wait for the new connection. */ +#ifdef SMB_RETRY_INTR interruptible_sleep_on_timeout(&server->wait, 5*HZ); if (signal_pending(current)) printk(KERN_INFO "smb_retry: caught signal\n"); +#else + /* + * We don't want to be interrupted. For example, what if 'current' + * already has recieved a signal? sleep_on would terminate immediately + * and smbmount would not be able to re-establish connection. + * + * smbmount should be able to reconnect later, but it can't because + * it will get an -EIO on attempts to open the mountpoint! + */ + sleep_on_timeout(&server->wait, 5*HZ); +#endif /* * Check for a valid connection. */ - if (server->state == CONN_VALID) - { + if (server->state == CONN_VALID) { /* This should be changed to VERBOSE, except many smbfs problems is with the userspace daemon not reconnecting. */ PARANOIA("sucessful, new pid=%d, generation=%d\n", @@ -656,7 +773,7 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt) if (server->opt.protocol == SMB_PROTOCOL_NT1 && (server->opt.max_xmit < 0x1000) && !(server->opt.capabilities & SMB_CAP_NT_SMBS)) { - server->mnt->version |= SMB_FIX_WIN95; + server->mnt->flags |= SMB_MOUNT_WIN95; #ifdef SMBFS_DEBUG_VERBOSE printk(KERN_NOTICE "smb_newconn: detected WIN95 server\n"); #endif @@ -667,7 +784,11 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt) server->opt.capabilities); out: +#ifdef SMB_RETRY_INTR wake_up_interruptible(&server->wait); +#else + wake_up(&server->wait); +#endif return error; out_putf: @@ -738,7 +859,7 @@ smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish) { struct inode *ino = dentry->d_inode; int mode, read_write = 0x42, read_only = 0x40; - int error; + int res; char *p; /* @@ -748,6 +869,9 @@ smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish) if (!(ino->i_mode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode = read_only; #if 0 + /* FIXME: why is this code not in? below we fix it so that a caller + wanting RO doesn't get RW. smb_revalidate_inode does some + optimization based on access mode. tail -f needs it to be correct. */ if (!(wish & (O_WRONLY | O_RDWR))) mode = read_only; #endif @@ -757,20 +881,23 @@ smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish) WSET(server->packet, smb_vwv0, mode); WSET(server->packet, smb_vwv1, aSYSTEM | aHIDDEN | aDIR); *p++ = 4; - p = smb_encode_path(server, p, dentry, NULL); + res = smb_encode_path(server, p, dentry, NULL); + if (res < 0) + goto out; + p += res; + smb_setup_bcc(server, p); - error = smb_request_ok(server, SMBopen, 7, 0); - if (error != 0) - { + res = smb_request_ok(server, SMBopen, 7, 0); + if (res != 0) { if (smb_retry(server)) goto retry; if (mode == read_write && - (error == -EACCES || error == -ETXTBSY || error == -EROFS)) + (res == -EACCES || res == -ETXTBSY || res == -EROFS)) { VERBOSE("%s/%s R/W failed, error=%d, retrying R/O\n", - DENTRY_PATH(dentry), error); + DENTRY_PATH(dentry), res); mode = read_only; goto retry; } @@ -783,10 +910,12 @@ smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish) /* smb_vwv2 has mtime */ /* smb_vwv4 has size */ ino->u.smbfs_i.access = (WVAL(server->packet, smb_vwv6) & SMB_ACCMASK); + if (!(wish & (O_WRONLY | O_RDWR))) + ino->u.smbfs_i.access = SMB_O_RDONLY; ino->u.smbfs_i.open = server->generation; out: - return error; + return res; } /* @@ -1025,7 +1154,7 @@ smb_proc_create(struct dentry *dentry, __u16 attr, time_t ctime, __u16 *fileid) { struct smb_sb_info *server = server_from_dentry(dentry); char *p; - int error; + int result; smb_lock_server(server); @@ -1034,22 +1163,24 @@ smb_proc_create(struct dentry *dentry, __u16 attr, time_t ctime, __u16 *fileid) WSET(server->packet, smb_vwv0, attr); DSET(server->packet, smb_vwv1, utc2local(server, ctime)); *p++ = 4; - p = smb_encode_path(server, p, dentry, NULL); + result = smb_encode_path(server, p, dentry, NULL); + if (result < 0) + goto out; + p += result; smb_setup_bcc(server, p); - error = smb_request_ok(server, SMBcreate, 1, 0); - if (error < 0) - { + result = smb_request_ok(server, SMBcreate, 1, 0); + if (result < 0) { if (smb_retry(server)) goto retry; goto out; } *fileid = WVAL(server->packet, smb_vwv0); - error = 0; + result = 0; out: smb_unlock_server(server); - return error; + return result; } int @@ -1064,14 +1195,22 @@ smb_proc_mv(struct dentry *old_dentry, struct dentry *new_dentry) retry: p = smb_setup_header(server, SMBmv, 1, 0); WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN | aDIR); + *p++ = 4; - p = smb_encode_path(server, p, old_dentry, NULL); + result = smb_encode_path(server, p, old_dentry, NULL); + if (result < 0) + goto out; + p += result; + *p++ = 4; - p = smb_encode_path(server, p, new_dentry, NULL); + result = smb_encode_path(server, p, new_dentry, NULL); + if (result < 0) + goto out; + p += result; + smb_setup_bcc(server, p); - if ((result = smb_request_ok(server, SMBmv, 0, 0)) < 0) - { + if ((result = smb_request_ok(server, SMBmv, 0, 0)) < 0) { if (smb_retry(server)) goto retry; goto out; @@ -1097,12 +1236,14 @@ smb_proc_generic_command(struct dentry *dentry, __u8 command) retry: p = smb_setup_header(server, command, 0, 0); *p++ = 4; - p = smb_encode_path(server, p, dentry, NULL); + result = smb_encode_path(server, p, dentry, NULL); + if (result < 0) + goto out; + p += result; smb_setup_bcc(server, p); result = smb_request_ok(server, command, 0, 0); - if (result < 0) - { + if (result < 0) { if (smb_retry(server)) goto retry; goto out; @@ -1165,11 +1306,13 @@ smb_proc_unlink(struct dentry *dentry) p = smb_setup_header(server, SMBunlink, 1, 0); WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN); *p++ = 4; - p = smb_encode_path(server, p, dentry, NULL); + result = smb_encode_path(server, p, dentry, NULL); + if (result < 0) + goto out; + p += result; smb_setup_bcc(server, p); - if ((result = smb_request_ok(server, SMBunlink, 0, 0)) < 0) - { + if ((result = smb_request_ok(server, SMBunlink, 0, 0)) < 0) { #if SMBFS_POSIX_UNLINK if (result == -EACCES && !flag) { /* Posix semantics is for the read-only state @@ -1220,8 +1363,7 @@ smb_proc_trunc(struct smb_sb_info *server, __u16 fid, __u32 length) *p++ = 0; smb_setup_bcc(server, p); - if ((result = smb_request_ok(server, SMBwrite, 1, 0)) < 0) - { + if ((result = smb_request_ok(server, SMBwrite, 1, 0)) < 0) { if (smb_retry(server)) goto retry; goto out; @@ -1306,6 +1448,8 @@ smb_decode_dirent(struct smb_sb_info *server, __u8 *p, len--; entry->len = len; + /* FIXME: These only work for ascii chars, and recent smbmount doesn't + allow the flag to be set anyway. Remove? */ switch (server->opt.case_handling) { case SMB_CASE_UPPER: str_upper(entry->name, len); @@ -1316,7 +1460,13 @@ smb_decode_dirent(struct smb_sb_info *server, __u8 *p, default: break; } - DEBUG1("len=%d, name=%.*s\n", len, len, entry->name); + + entry->len = server->convert(server->name_buf, SMB_MAXNAMELEN, + entry->name, len, + server->remote_nls, server->local_nls); + entry->name = server->name_buf; + + DEBUG1("len=%d, name=%.*s\n", entry->len, entry->len, entry->name); return p + 22; } @@ -1355,7 +1505,10 @@ retry: WSET(server->packet, smb_vwv1, aDIR); *p++ = 4; if (first == 1) { - p = smb_encode_path(server, p, dir, &mask); + result = smb_encode_path(server, p, dir, &mask); + if (result < 0) + goto unlock_return; + p += result; *p++ = 5; WSET(p, 0, 0); p += 2; @@ -1467,12 +1620,11 @@ smb_decode_long_dirent(struct smb_sb_info *server, char *p, switch (level) { case 1: len = *((unsigned char *) p + 22); - entry->len = len; entry->name = p + 23; result = p + 24 + len; VERBOSE("info 1 at %p, len=%d, name=%.*s\n", - p, entry->len, entry->len, entry->name); + p, len, len, entry->name); break; case 260: result = p + WVAL(p, 0); @@ -1482,14 +1634,14 @@ smb_decode_long_dirent(struct smb_sb_info *server, char *p, entry->name = p + 94; if (len && entry->name[len-1] == '\0') len--; - entry->len = len; VERBOSE("info 260 at %p, len=%d, name=%.*s\n", - p, entry->len, entry->len, entry->name); + p, len, len, entry->name); break; default: PARANOIA("Unknown info level %d\n", level); result = p + WVAL(p, 0); + goto out; } switch (server->opt.case_handling) { @@ -1503,6 +1655,11 @@ smb_decode_long_dirent(struct smb_sb_info *server, char *p, break; } + entry->len = server->convert(server->name_buf, SMB_MAXNAMELEN, + entry->name, len, + server->remote_nls, server->local_nls); + entry->name = server->name_buf; +out: return result; } @@ -1561,7 +1718,12 @@ retry: * Encode the initial path */ mask = param + 12; - mask_len = smb_encode_path(server, mask, dir, &star) - mask; + + mask_len = smb_encode_path(server, mask, dir, &star); + if (mask_len < 0) { + entries = mask_len; + goto unlock_return; + } first = 1; VERBOSE("starting fpos=%d, mask=%s\n", fpos, mask); @@ -1753,7 +1915,11 @@ smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry, int mask_len, result; retry: - mask_len = smb_encode_path(server, mask, dentry, NULL) - mask; + mask_len = smb_encode_path(server, mask, dentry, NULL); + if (mask_len < 0) { + result = mask_len; + goto out; + } VERBOSE("name=%s, len=%d\n", mask, mask_len); WSET(param, 0, aSYSTEM | aHIDDEN | aDIR); WSET(param, 2, 1); /* max count */ @@ -1828,7 +1994,10 @@ smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir, retry: p = smb_setup_header(server, SMBgetatr, 0, 0); *p++ = 4; - p = smb_encode_path(server, p, dir, NULL); + result = smb_encode_path(server, p, dir, NULL); + if (result < 0) + goto out; + p += result; smb_setup_bcc(server, p); if ((result = smb_request_ok(server, SMBgetatr, 10, 0)) < 0) @@ -1874,7 +2043,10 @@ smb_proc_getattr_trans2(struct smb_sb_info *server, struct dentry *dir, retry: WSET(param, 0, 1); /* Info level SMB_INFO_STANDARD */ DSET(param, 2, 0); - p = smb_encode_path(server, param + 6, dir, NULL); + result = smb_encode_path(server, param + 6, dir, NULL); + if (result < 0) + goto out; + p = param + 6 + result; result = smb_trans2_request(server, TRANSACT2_QPATHINFO, 0, NULL, p - param, param, @@ -1905,7 +2077,7 @@ smb_proc_getattr_trans2(struct smb_sb_info *server, struct dentry *dir, * Kludge alert: Win 95 swaps the date and time field, * contrary to the CIFS docs and Win NT practice. */ - if (server->mnt->version & SMB_FIX_WIN95) { + if (server->mnt->flags & SMB_MOUNT_WIN95) { off_date = 2; off_time = 0; } @@ -1945,21 +2117,16 @@ smb_proc_do_getattr(struct smb_sb_info *server, struct dentry *dir, /* * Select whether to use core or trans2 getattr. + * Win 95 appears to break with the trans2 getattr. */ - if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2) { - /* - * Win 95 appears to break with the trans2 getattr. - * Note: mnt->version options are set at mount time (inode.c) - */ - if (server->mnt->version & (SMB_FIX_OLDATTR|SMB_FIX_WIN95)) - goto core_attr; - if (server->mnt->version & SMB_FIX_DIRATTR) + if (server->opt.protocol < SMB_PROTOCOL_LANMAN2 || + (server->mnt->flags & (SMB_MOUNT_OLDATTR|SMB_MOUNT_WIN95)) ) { + result = smb_proc_getattr_core(server, dir, fattr); + } else { + if (server->mnt->flags & SMB_MOUNT_DIRATTR) result = smb_proc_getattr_ff(server, dir, fattr); else result = smb_proc_getattr_trans2(server, dir, fattr); - } else { - core_attr: - result = smb_proc_getattr_core(server, dir, fattr); } smb_finish_dirent(server, fattr); @@ -2008,14 +2175,16 @@ smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry, WSET(server->packet, smb_vwv6, 0); WSET(server->packet, smb_vwv7, 0); *p++ = 4; - p = smb_encode_path(server, p, dentry, NULL); + result = smb_encode_path(server, p, dentry, NULL); + if (result < 0) + goto out; + p += result; *p++ = 4; *p++ = 0; smb_setup_bcc(server, p); result = smb_request_ok(server, SMBsetatr, 0, 0); - if (result < 0) - { + if (result < 0) { if (smb_retry(server)) goto retry; goto out; @@ -2073,8 +2242,7 @@ smb_proc_setattr_ext(struct smb_sb_info *server, #endif result = smb_request_ok(server, SMBsetattrE, 0, 0); - if (result < 0) - { + if (result < 0) { if (smb_retry(server)) goto retry; goto out; @@ -2107,7 +2275,10 @@ smb_proc_setattr_trans2(struct smb_sb_info *server, retry: WSET(param, 0, 1); /* Info level SMB_INFO_STANDARD */ DSET(param, 2, 0); - p = smb_encode_path(server, param + 6, dir, NULL); + result = smb_encode_path(server, param + 6, dir, NULL); + if (result < 0) + goto out; + p = param + 6 + result; WSET(data, 0, 0); /* creation time */ WSET(data, 2, 0); @@ -2170,8 +2341,7 @@ smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr) smb_lock_server(server); /* setting the time on a Win95 server fails (tridge) */ if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2 && - !(server->mnt->version & SMB_FIX_WIN95)) - { + !(server->mnt->flags & SMB_MOUNT_WIN95)) { if (smb_is_open(inode) && inode->u.smbfs_i.access != SMB_O_RDONLY) result = smb_proc_setattr_ext(server, inode, fattr); @@ -2182,8 +2352,7 @@ smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr) * Fail silently on directories ... timestamp can't be set? */ result = 0; - if (S_ISREG(inode->i_mode)) - { + if (S_ISREG(inode->i_mode)) { /* * Set the mtime by opening and closing the file. * Note that the file is opened read-only, but this @@ -2192,8 +2361,7 @@ smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr) result = -EACCES; if (!smb_is_open(inode)) smb_proc_open(server, dentry, SMB_O_RDONLY); - if (smb_is_open(inode)) - { + if (smb_is_open(inode)) { inode->i_mtime = fattr->f_mtime; result = smb_proc_close_inode(server, inode); } @@ -2208,7 +2376,7 @@ int smb_proc_dskattr(struct super_block *sb, struct statfs *attr) { struct smb_sb_info *server = &(sb->u.smbfs_sb); - int error; + int result; char *p; smb_lock_server(server); @@ -2216,8 +2384,7 @@ smb_proc_dskattr(struct super_block *sb, struct statfs *attr) retry: smb_setup_header(server, SMBdskattr, 0, 0); - if ((error = smb_request_ok(server, SMBdskattr, 5, 0)) < 0) - { + if ((result = smb_request_ok(server, SMBdskattr, 5, 0)) < 0) { if (smb_retry(server)) goto retry; goto out; @@ -2226,11 +2393,11 @@ smb_proc_dskattr(struct super_block *sb, struct statfs *attr) attr->f_blocks = WVAL(p, 0); attr->f_bsize = WVAL(p, 2) * WVAL(p, 4); attr->f_bavail = attr->f_bfree = WVAL(p, 6); - error = 0; + result = 0; out: smb_unlock_server(server); - return error; + return result; } int diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c index 0c52bf871..01ae6ec87 100644 --- a/fs/smbfs/sock.c +++ b/fs/smbfs/sock.c @@ -111,12 +111,16 @@ smb_data_callback(void* ptr) unsigned char peek_buf[4]; int result; mm_segment_t fs; + int count = 100; /* this is a lot, we should have some data waiting */ + int found = 0; fs = get_fs(); set_fs(get_ds()); lock_kernel(); - while (1) { + while (count-- > 0) { + peek_buf[0] = 0; + result = -EIO; if (job->sk->dead) { PARANOIA("sock dead!\n"); @@ -125,7 +129,7 @@ smb_data_callback(void* ptr) result = _recvfrom(socket, (void *) peek_buf, 1, MSG_PEEK | MSG_DONTWAIT); - if (result == -EAGAIN) + if (result < 0) break; if (peek_buf[0] != 0x85) break; @@ -136,13 +140,15 @@ smb_data_callback(void* ptr) DEBUG1("got SESSION KEEPALIVE\n"); - if (result == -EAGAIN) + if (result < 0) break; + found = 1; } unlock_kernel(); set_fs(fs); - if (result != -EAGAIN) + DEBUG1("found=%d, count=%d, result=%d\n", found, count, result); + if (found) found_data(job->sk); kfree(ptr); } diff --git a/include/asm-arm/arch-arc/irq.h b/include/asm-arm/arch-arc/irq.h index 7a922e991..61997a1b2 100644 --- a/include/asm-arm/arch-arc/irq.h +++ b/include/asm-arm/arch-arc/irq.h @@ -10,6 +10,7 @@ * 11-01-1998 RMK Added mask_and_ack_irq * 22-08-1998 RMK Restructured IRQ routines */ +#include #include #ifdef CONFIG_ARCH_ARC diff --git a/include/asm-arm/arch-arc/system.h b/include/asm-arm/arch-arc/system.h index d80ddd13f..0caf739d6 100644 --- a/include/asm-arm/arch-arc/system.h +++ b/include/asm-arm/arch-arc/system.h @@ -3,7 +3,6 @@ * * Copyright (c) 1996-1999 Russell King and Dave Gilbert */ -#include static void arch_idle(void) { diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h index 2debbf084..8562fc287 100644 --- a/include/asm-sparc/pgtable.h +++ b/include/asm-sparc/pgtable.h @@ -1,4 +1,4 @@ -/* $Id: pgtable.h,v 1.101 2000/08/09 00:00:17 davem Exp $ */ +/* $Id: pgtable.h,v 1.102 2000/08/14 00:46:13 anton Exp $ */ #ifndef _SPARC_PGTABLE_H #define _SPARC_PGTABLE_H @@ -201,11 +201,9 @@ extern unsigned long empty_zero_page; #define SIZEOF_PTR_LOG2 2 -BTFIXUPDEF_CALL_CONST(unsigned long, sparc_pte_pagenr, pte_t) BTFIXUPDEF_CALL_CONST(unsigned long, pmd_page, pmd_t) BTFIXUPDEF_CALL_CONST(unsigned long, pgd_page, pgd_t) -#define sparc_pte_pagenr(pte) BTFIXUP_CALL(sparc_pte_pagenr)(pte) #define pmd_page(pmd) BTFIXUP_CALL(pmd_page)(pmd) #define pgd_page(pgd) BTFIXUP_CALL(pgd_page)(pgd) @@ -305,7 +303,9 @@ BTFIXUPDEF_CALL_CONST(pte_t, pte_mkyoung, pte_t) /* Permanent address of a page. */ #define page_address(page) ((page)->virtual) -#define pte_page(x) (mem_map+sparc_pte_pagenr(x)) + +BTFIXUPDEF_CALL(struct page *, pte_page, pte_t) +#define pte_page(pte) BTFIXUP_CALL(pte_page)(pte) /* * Conversion functions: convert a page and protection to a page entry, diff --git a/include/asm-sparc/spinlock.h b/include/asm-sparc/spinlock.h index 0b3df22b9..84b0f03f5 100644 --- a/include/asm-sparc/spinlock.h +++ b/include/asm-sparc/spinlock.h @@ -16,7 +16,7 @@ * Define this to use the verbose/debugging versions in * arch/sparc/lib/debuglocks.c * - * Be sure to make check_asm whenever changing this option. + * Be sure to make dep whenever changing this option. */ #define SPIN_LOCK_DEBUG @@ -28,7 +28,7 @@ struct _spinlock_debug { typedef struct _spinlock_debug spinlock_t; #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0, 0 } -#define spin_lock_init(lp) do { (lp)->owner_pc = 0; (lp)->lock = 0; } while(0) +#define spin_lock_init(lp) do { *(lp)= SPIN_LOCK_UNLOCKED; } while(0) #define spin_is_locked(lp) (*((volatile unsigned char *)(&((lp)->lock))) != 0) #define spin_unlock_wait(lp) do { barrier(); } while(*(volatile unsigned char *)(&(lp)->lock)) @@ -49,6 +49,8 @@ typedef struct _rwlock_debug rwlock_t; #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, {0} } +#define rwlock_init(lp) do { *(lp)= RW_LOCK_UNLOCKED; } while(0) + extern void _do_read_lock(rwlock_t *rw, char *str); extern void _do_read_unlock(rwlock_t *rw, char *str); extern void _do_write_lock(rwlock_t *rw, char *str); @@ -144,6 +146,9 @@ typedef struct { volatile unsigned int lock; } rwlock_t; #define RW_LOCK_UNLOCKED (rwlock_t) { 0 } +#define rwlock_init(lp) do { *(lp)= RW_LOCK_UNLOCKED; } while(0) + + /* Sort of like atomic_t's on Sparc, but even more clever. * * ------------------------------------ diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index 6dc356942..741949c5e 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h @@ -1,4 +1,4 @@ -/* $Id: unistd.h,v 1.68 2000/08/12 20:49:49 jj Exp $ */ +/* $Id: unistd.h,v 1.70 2000/08/14 05:39:07 jj Exp $ */ #ifndef _SPARC_UNISTD_H #define _SPARC_UNISTD_H @@ -170,7 +170,7 @@ /* #define __NR_putmsg 152 SunOS Specific */ #define __NR_poll 153 /* Common */ #define __NR_getdents64 154 /* Linux specific */ -#define __NR_fstat64 155 /* Linux sparc32 Specific */ +#define __NR_fcntl64 155 /* Linux sparc32 Specific */ /* #define __NR_getdirentries 156 SunOS Specific */ #define __NR_statfs 157 /* Common */ #define __NR_fstatfs 158 /* Common */ diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h index ea34fbefe..a6f5aa9ae 100644 --- a/include/asm-sparc64/spinlock.h +++ b/include/asm-sparc64/spinlock.h @@ -109,6 +109,7 @@ extern int _spin_trylock (spinlock_t *lock); typedef unsigned int rwlock_t; #define RW_LOCK_UNLOCKED 0 +#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0) extern void __read_lock(rwlock_t *); extern void __read_unlock(rwlock_t *); @@ -128,6 +129,7 @@ typedef struct { unsigned int reader_pc[4]; } rwlock_t; #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0xff, { 0, 0, 0, 0 } } +#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0) extern void _do_read_lock(rwlock_t *rw, char *str); extern void _do_read_unlock(rwlock_t *rw, char *str); diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index e66e4abd6..f89c5d50a 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h @@ -1,4 +1,4 @@ -/* $Id: unistd.h,v 1.46 2000/08/12 20:49:49 jj Exp $ */ +/* $Id: unistd.h,v 1.47 2000/08/14 05:39:07 jj Exp $ */ #ifndef _SPARC64_UNISTD_H #define _SPARC64_UNISTD_H @@ -170,7 +170,7 @@ /* #define __NR_putmsg 152 SunOS Specific */ #define __NR_poll 153 /* Common */ #define __NR_getdents64 154 /* Linux specific */ -/* #define __NR_fstat64 155 Linux sparc32 Specific */ +/* #define __NR_fcntl64 155 Linux sparc32 Specific */ /* #define __NR_getdirentries 156 SunOS Specific */ #define __NR_statfs 157 /* Common */ #define __NR_fstatfs 158 /* Common */ diff --git a/include/linux/smb.h b/include/linux/smb.h index 852d5b0dd..1382db0dc 100644 --- a/include/linux/smb.h +++ b/include/linux/smb.h @@ -62,6 +62,13 @@ struct smb_conn_opt { #ifdef __KERNEL__ +#define SMB_NLS_MAXNAMELEN 20 +struct smb_nls_codepage { + char local_name[SMB_NLS_MAXNAMELEN]; + char remote_name[SMB_NLS_MAXNAMELEN]; +}; + + #define SMB_MAXNAMELEN 255 #define SMB_MAXPATHLEN 1024 diff --git a/include/linux/smb_fs.h b/include/linux/smb_fs.h index 375ff3112..e475057fc 100644 --- a/include/linux/smb_fs.h +++ b/include/linux/smb_fs.h @@ -73,13 +73,6 @@ smb_vfree(void *obj) #define SMB_F_CACHEVALID 0x01 /* directory cache valid */ #define SMB_F_LOCALWRITE 0x02 /* file modified locally */ -/* - * Bug fix flags - */ -#define SMB_FIX_WIN95 0x0001 /* Win 95 server */ -#define SMB_FIX_OLDATTR 0x0002 /* Use core getattr (Win 95 speedup) */ -#define SMB_FIX_DIRATTR 0x0004 /* Use find_first for getattr */ - /* NT1 protocol capability bits */ #define SMB_CAP_RAW_MODE 0x0001 @@ -122,6 +115,7 @@ unsigned long smb_invent_inos(unsigned long); struct inode *smb_iget(struct super_block *, struct smb_fattr *); /* linux/fs/smbfs/proc.c */ +int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp); __u32 smb_len(unsigned char *); __u8 *smb_encode_smb_length(__u8 *, __u32); __u8 *smb_setup_header(struct smb_sb_info *, __u8, __u16, __u16); diff --git a/include/linux/smb_fs_sb.h b/include/linux/smb_fs_sb.h index 31052af1f..4bad7e928 100644 --- a/include/linux/smb_fs_sb.h +++ b/include/linux/smb_fs_sb.h @@ -23,7 +23,7 @@ struct smb_sb_info { enum smb_conn_state state; struct file * sock_file; - struct smb_mount_data *mnt; + struct smb_mount_data_kernel *mnt; unsigned char *temp_buf; /* Connections are counted. Each time a new socket arrives, @@ -41,8 +41,20 @@ struct smb_sb_info { unsigned short rcls; /* The error codes we received */ unsigned short err; - /* We use our on data_ready callback, but need the original one */ + /* We use our own data_ready callback, but need the original one */ void *data_ready; + + /* nls pointers for codepage conversions */ + struct nls_table *remote_nls; + struct nls_table *local_nls; + + /* utf8 can make strings longer so we can't do in-place conversion. + This is a buffer for temporary stuff. We only need one so no need + to put it on the stack. This points to temp_buf space. */ + char *name_buf; + + int (*convert)(char *, int, const char *, int, + struct nls_table *, struct nls_table *); }; #endif /* __KERNEL__ */ diff --git a/include/linux/smb_mount.h b/include/linux/smb_mount.h index 886d945d5..ea240db51 100644 --- a/include/linux/smb_mount.h +++ b/include/linux/smb_mount.h @@ -11,7 +11,7 @@ #include -#define SMB_MOUNT_VERSION 6 +#define SMB_MOUNT_VERSION 6 struct smb_mount_data { int version; @@ -22,4 +22,37 @@ struct smb_mount_data { __kernel_mode_t dir_mode; }; + +#ifdef __KERNEL__ + +/* "vers" in big-endian */ +#define SMB_MOUNT_ASCII 0x76657273 + +#define SMB_MOUNT_OLDVERSION 6 +#undef SMB_MOUNT_VERSION +#define SMB_MOUNT_VERSION 7 + +/* flags */ +#define SMB_MOUNT_WIN95 0x0001 /* Win 95 server */ +#define SMB_MOUNT_OLDATTR 0x0002 /* Use core getattr (Win 95 speedup) */ +#define SMB_MOUNT_DIRATTR 0x0004 /* Use find_first for getattr */ +#define SMB_MOUNT_CASE 0x0008 /* Be case sensitive */ + + +struct smb_mount_data_kernel { + int version; + + __kernel_uid_t mounted_uid; /* Who may umount() this filesystem? */ + __kernel_uid_t uid; + __kernel_gid_t gid; + __kernel_mode_t file_mode; + __kernel_mode_t dir_mode; + + u32 flags; + + struct smb_nls_codepage codepage; +}; + +#endif + #endif diff --git a/kernel/ksyms.c b/kernel/ksyms.c index bcc6d2e31..660d492f6 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -527,6 +527,7 @@ EXPORT_SYMBOL(get_fast_time); /* library functions */ EXPORT_SYMBOL(strnicmp); EXPORT_SYMBOL(strspn); +EXPORT_SYMBOL(strsep); /* software interrupts */ EXPORT_SYMBOL(tasklet_hi_vec); diff --git a/mm/filemap.c b/mm/filemap.c index 58f642b30..54b66fbd7 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -414,7 +414,7 @@ static int writeout_one_page(struct page *page) if (buffer_locked(bh) || !buffer_dirty(bh) || !buffer_uptodate(bh)) continue; - bh->b_flushtime = 0; + bh->b_flushtime = jiffies; ll_rw_block(WRITE, 1, &bh); } while ((bh = bh->b_this_page) != head); return 0; diff --git a/mm/highmem.c b/mm/highmem.c index 6208e347d..3be601c6f 100644 --- a/mm/highmem.c +++ b/mm/highmem.c @@ -339,7 +339,7 @@ repeat_page: bh->b_count = bh_orig->b_count; bh->b_rdev = bh_orig->b_rdev; bh->b_state = bh_orig->b_state; - bh->b_flushtime = 0; + bh->b_flushtime = jiffies; bh->b_next_free = NULL; bh->b_prev_free = NULL; /* bh->b_this_page */ diff --git a/net/netsyms.c b/net/netsyms.c index fe78e71f1..8968a8d72 100644 --- a/net/netsyms.c +++ b/net/netsyms.c @@ -359,6 +359,7 @@ EXPORT_SYMBOL(tcp_sockets_allocated); EXPORT_SYMBOL(sysctl_tcp_reordering); EXPORT_SYMBOL(sysctl_tcp_rmem); EXPORT_SYMBOL(sysctl_tcp_wmem); +EXPORT_SYMBOL(sysctl_tcp_ecn); EXPORT_SYMBOL(tcp_cwnd_application_limited); EXPORT_SYMBOL(xrlim_allow); -- 2.11.4.GIT