diff -u --recursive --new-file v2.2.6/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.2.6/linux/Documentation/Configure.help Fri Apr 16 14:47:30 1999 +++ linux/Documentation/Configure.help Tue Apr 20 15:17:20 1999 @@ -7443,6 +7443,26 @@ case insensitive, and case in names is preserved. Say Y. You can disable it at mount time with the -N os2 parameter of ncpmount. +Lowercase DOS filenames on LONG namespace volume +CONFIG_NCPFS_SMALLDOS + Saying Y here will convert every filename with creator/owner DOS + namespace on NetWare servers to lowercase characters as silently + kernel does when you mount NetWare file server volumes with DOS + namespace without OS2/LONG namespace support. Saying N here will + give you these filenames with uppercase characters. + + This is only cosmetic option because of OS2/LONG namespace is + case insensitive. The only major reason for this option is + backward compatibility when you want to do step from DOS to + OS2/LONG namespace support. Long filenames (created by Win95) + will not be affected. + + This option does not solve a problem that filenames appear + differently in Linux box and in MS environment because of MS + does an additional conversions on client side. You can achieve + simillar effects enabling ncpfs option "Allow using of Native + Language Support" below. + Allow mounting of volume subdirectories CONFIG_NCPFS_MOUNT_SUBDIR Allows you to mount not only whole servers or whole volumes, but @@ -7461,6 +7481,25 @@ servers. Do not say Y if security is primary for you because root can read your session key (from /proc/kcore). +Allow using of Native Language Support +CONFIG_NCPFS_NLS + Allows you to use codepages and I/O charsets for file name translation + between file system on server and input/output. This may be useful, + if you want to access to the server with other operating systems, + e.g. Windows 95. See also NLS for more Information. + + To select codepages and I/O charsets use ncpfs-2.2.0.13 or newer. + +Symbolic links and mode permission bits +CONFIG_NCPFS_EXTRAS + This enables the use of symbolic links and an execute permission + bit on NCPFS. The file server need not have long name space or NFS + name space loaded for these to work, they are stored using rarely + found combinations of Hidden, System and Shared flags. + + To use the new attributes, you are recommended to use the flags + '-f 600 -d 755' on the ncpmount commandline. + nls codepage 437 CONFIG_NLS_CODEPAGE_437 The Microsoft fat filesystem family can deal with filenames in diff -u --recursive --new-file v2.2.6/linux/Documentation/fb/matroxfb.txt linux/Documentation/fb/matroxfb.txt --- v2.2.6/linux/Documentation/fb/matroxfb.txt Tue Jan 19 11:32:50 1999 +++ linux/Documentation/fb/matroxfb.txt Tue Apr 20 15:13:00 1999 @@ -1,6 +1,6 @@ [This file is cloned from VesaFB. Thanks go to Gerd Knorr] -what is matroxfb? +What is matroxfb? ================= This is a driver for a graphic framebuffer for Matrox devices on @@ -221,6 +221,8 @@ sync:X - sync. pulse - bit 0 inverts HSYNC polarity, bit 1 VSYNC polarity. If bit 3 (value 0x08) is set, composite sync instead of HSYNC is generated. If bit 5 (value 0x20) is set, sync on green is turned on. + Do not forget that if you want sync on green, you also probably + want composite sync. Default depends on `vesa'. depth:X - Bits per pixel: 0=text, 4,8,15,16,24 or 32. Default depends on `vesa'. @@ -284,8 +286,6 @@ + current fbset is not able to set 15bpp videomode: you must specify depth==16 and green.length==5. fbset does not allow you to set green.length. - + hardware cursor is available only in accelerated videomodes. Maybe that - this is misfeature and not feature. + text mode uses 6 bit VGA palette instead of 8 bit (one of 262144 colors instead of one of 16M colors). It is due to hardware limitation of MilleniumI/II and SVGALib compatibility. diff -u --recursive --new-file v2.2.6/linux/Makefile linux/Makefile --- v2.2.6/linux/Makefile Fri Apr 16 14:47:30 1999 +++ linux/Makefile Fri Apr 16 14:47:55 1999 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 2 -SUBLEVEL = 6 +SUBLEVEL = 7 EXTRAVERSION = ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) diff -u --recursive --new-file v2.2.6/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c --- v2.2.6/linux/arch/alpha/kernel/time.c Tue Mar 23 14:35:46 1999 +++ linux/arch/alpha/kernel/time.c Wed Apr 21 10:04:31 1999 @@ -18,6 +18,9 @@ * fixed tick loss calculation in timer_interrupt * (round system clock to nearest tick instead of truncating) * fixed algorithm in time_init for getting time from CMOS clock + * 1999-04-16 Thorsten Kranzkowski (dl8bcu@gmx.net) + * fixed algorithm in do_gettimeofday() for calculating the precise time + * from processor cycle counter (now taking lost_ticks into account) */ #include #include @@ -314,8 +317,10 @@ void do_gettimeofday(struct timeval *tv) { - unsigned long flags, now, delta_cycles, delta_usec; + unsigned long flags, delta_cycles, delta_usec; unsigned long sec, usec; + __u32 now; + extern volatile unsigned long lost_ticks; /*kernel/sched.c*/ now = rpcc(); save_and_cli(flags); @@ -337,8 +342,14 @@ * with no clear gain. */ - delta_usec = delta_cycles * state.scaled_ticks_per_cycle * 15625; + delta_usec = (delta_cycles * state.scaled_ticks_per_cycle + + state.partial_tick + + (lost_ticks << FIX_SHIFT) ) * 15625; delta_usec = ((delta_usec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2; + + /* the 'lost_tics' term above implements this: + * delta_usec += lost_ticks * (1000000 / HZ); + */ usec += delta_usec; if (usec >= 1000000) { diff -u --recursive --new-file v2.2.6/linux/drivers/pci/oldproc.c linux/drivers/pci/oldproc.c --- v2.2.6/linux/drivers/pci/oldproc.c Fri Apr 16 14:47:30 1999 +++ linux/drivers/pci/oldproc.c Wed Apr 21 09:28:49 1999 @@ -445,6 +445,7 @@ DEVICE( 3DFX, 3DFX_VOODOO2, "Voodoo2"), DEVICE( 3DFX, 3DFX_BANSHEE, "Banshee"), DEVICE( SIGMADES, SIGMADES_6425, "REALmagic64/GX"), + DEVICE( AVM, AVM_A1, "A1 (Fritz)"), DEVICE( STALLION, STALLION_ECHPCI832,"EasyConnection 8/32"), DEVICE( STALLION, STALLION_ECHPCI864,"EasyConnection 8/64"), DEVICE( STALLION, STALLION_EIOPCI,"EasyIO"), @@ -784,6 +785,7 @@ case PCI_VENDOR_ID_O2: return "O2 Micro"; case PCI_VENDOR_ID_3DFX: return "3Dfx"; case PCI_VENDOR_ID_SIGMADES: return "Sigma Designs"; + case PCI_VENDOR_ID_AVM: return "AVM"; case PCI_VENDOR_ID_CCUBE: return "C-Cube"; case PCI_VENDOR_ID_DIPIX: return "Dipix"; case PCI_VENDOR_ID_STALLION: return "Stallion Technologies"; diff -u --recursive --new-file v2.2.6/linux/drivers/video/matroxfb.c linux/drivers/video/matroxfb.c --- v2.2.6/linux/drivers/video/matroxfb.c Wed Mar 10 15:29:48 1999 +++ linux/drivers/video/matroxfb.c Tue Apr 20 15:13:00 1999 @@ -4,7 +4,7 @@ * * (c) 1998,1999 Petr Vandrovec * - * Version: 1.9 1999/01/04 + * Version: 1.15 1999/04/19 * * MTRR stuff: 1998 Tom Rini * @@ -24,6 +24,9 @@ * "Daniel Haun" * Testing, hardware cursor fixes * + * "Scott Wood" + * Fixes + * * "Gerd Knorr" * Betatesting * @@ -452,7 +455,7 @@ #define CPMINFO const struct matrox_fb_info* minfo, #define PMINFO minfo, -static inline struct matrox_fb_info* mxinfo(struct display* p) { +static inline struct matrox_fb_info* mxinfo(const struct display* p) { return (struct matrox_fb_info*)p->fb_info; } @@ -474,7 +477,7 @@ #define PMINFO #if 0 -static inline struct matrox_fb_info* mxinfo(struct display* p) { +static inline struct matrox_fb_info* mxinfo(const struct display* p) { return &global_mxinfo; } #endif @@ -2191,7 +2194,7 @@ step = ACCESS_FBINFO(devflags.textstep); offs = yy * p->next_line + xx * step; - attr = attr_fgcol(p,scr_readw(s)) | (attr_bgcol(p,scr_readw(s)) << 4); + attr = attr_fgcol(p, scr_readw(s)) | (attr_bgcol(p, scr_readw(s)) << 4); while (count-- > 0) { unsigned int chr = ((scr_readw(s++)) & p->charmask) << 8; if (chr & 0x10000) chr ^= 0x10008; @@ -2395,6 +2398,10 @@ DBG("initMatrox") + if (ACCESS_FBINFO(currcon_display) != p) + return; + if (p->dispsw && p->conp) + fb_con.con_cursor(p->conp, CM_ERASE); p->dispsw_data = NULL; if ((p->var.accel_flags & FB_ACCELF_TEXT) != FB_ACCELF_TEXT) { if (p->type == FB_TYPE_TEXT) { @@ -4274,6 +4281,17 @@ for (i = 0; i < 21; i++) { outTi3026(PMINFO DACseq[i], hw->DACreg[i]); } + if (oldhw) { + outTi3026(PMINFO TVP3026_XPLLADDR, 0x00); + oldhw->DACclk[0] = inTi3026(PMINFO TVP3026_XPIXPLLDATA); + oldhw->DACclk[3] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA); + outTi3026(PMINFO TVP3026_XPLLADDR, 0x15); + oldhw->DACclk[1] = inTi3026(PMINFO TVP3026_XPIXPLLDATA); + oldhw->DACclk[4] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA); + outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A); + oldhw->DACclk[2] = inTi3026(PMINFO TVP3026_XPIXPLLDATA); + oldhw->DACclk[5] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA); + } if (!oldhw || memcmp(hw->DACclk, oldhw->DACclk, 6)) { /* agrhh... setting up PLL is very slow on Millenium... */ /* Mystique PLL is locked in few ms, but Millenium PLL lock takes about 0.15 s... */ @@ -5296,7 +5314,7 @@ "MGA-G200 (AGP)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF, 0, 0, - DEVF_VIDEO64BIT | DEVF_SWAPS, + DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB, 230000, &vbG200, "unknown G200 (AGP)"}, @@ -5743,20 +5761,26 @@ } #ifndef MODULE +static int __init initialized = 0; + __initfunc(void matroxfb_init(void)) { DBG("matroxfb_init") -#if defined(CONFIG_FB_OF) -/* Nothing to do, must be called from offb */ -#else - matrox_init(); -#endif + + if (!initialized) { + initialized = 1; + matrox_init(); + } } #if defined(CONFIG_FB_OF) __initfunc(int matrox_of_init(struct device_node *dp)) { DBG("matrox_of_init"); - matrox_init(); + + if (!initialized) { + initialized = 1; + matrox_init(); + } if (!fb_list) return -ENXIO; return 0; } diff -u --recursive --new-file v2.2.6/linux/fs/buffer.c linux/fs/buffer.c --- v2.2.6/linux/fs/buffer.c Mon Mar 29 11:09:11 1999 +++ linux/fs/buffer.c Wed Apr 21 11:10:00 1999 @@ -486,33 +486,6 @@ remove_from_lru_list(bh); } -static inline void put_last_lru(struct buffer_head * bh) -{ - if (bh) { - struct buffer_head **bhp = &lru_list[bh->b_list]; - - if (bh == *bhp) { - *bhp = bh->b_next_free; - return; - } - - if(bh->b_dev == B_FREE) - panic("Wrong block for lru list"); - - /* Add to back of free list. */ - remove_from_lru_list(bh); - if(!*bhp) { - *bhp = bh; - (*bhp)->b_prev_free = bh; - } - - bh->b_next_free = *bhp; - bh->b_prev_free = (*bhp)->b_prev_free; - (*bhp)->b_prev_free->b_next_free = bh; - (*bhp)->b_prev_free = bh; - } -} - static inline void put_last_free(struct buffer_head * bh) { if (bh) { @@ -726,8 +699,6 @@ bh = get_hash_table(dev, block, size); if (bh) { if (!buffer_dirty(bh)) { - if (buffer_uptodate(bh)) - put_last_lru(bh); bh->b_flushtime = 0; } return bh; @@ -854,6 +825,7 @@ return; } buf->b_count = 0; + buf->b_state = 0; remove_from_queues(buf); put_last_free(buf); } @@ -1525,13 +1497,27 @@ * Use gfp() for the hash table to decrease TLB misses, use * SLAB cache for buffer heads. */ -void __init buffer_init(void) +void __init buffer_init(unsigned long memory_size) { - int order = 5; /* Currently maximum order.. */ + int order; unsigned int nr_hash; - nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct buffer_head *); - hash_table = (struct buffer_head **) __get_free_pages(GFP_ATOMIC, order); + /* we need to guess at the right sort of size for a buffer cache. + the heuristic from working with large databases and getting + fsync times (ext2) manageable, is the following */ + + memory_size >>= 20; + for (order = 5; (1UL << order) < memory_size; order++); + + /* try to allocate something until we get it or we're asking + for something that is really too small */ + + do { + nr_hash = (1UL << order) * PAGE_SIZE / + sizeof(struct buffer_head *); + hash_table = (struct buffer_head **) + __get_free_pages(GFP_ATOMIC, order); + } while (hash_table == NULL && --order > 4); if (!hash_table) panic("Failed to allocate buffer hash table\n"); diff -u --recursive --new-file v2.2.6/linux/fs/fat/fatfs_syms.c linux/fs/fat/fatfs_syms.c --- v2.2.6/linux/fs/fat/fatfs_syms.c Wed May 20 19:10:40 1998 +++ linux/fs/fat/fatfs_syms.c Tue Apr 20 14:37:10 1999 @@ -54,6 +54,7 @@ EXPORT_SYMBOL(unlock_fat); EXPORT_SYMBOL(fat_dir_ioctl); EXPORT_SYMBOL(fat_readpage); +EXPORT_SYMBOL(fat_is_binary); int init_fat_fs(void) { diff -u --recursive --new-file v2.2.6/linux/fs/fat/inode.c linux/fs/fat/inode.c --- v2.2.6/linux/fs/fat/inode.c Fri Apr 16 14:47:31 1999 +++ linux/fs/fat/inode.c Tue Apr 20 14:37:10 1999 @@ -703,8 +703,8 @@ if(raw_entry->attr & ATTR_SYS) if (MSDOS_SB(sb)->options.sys_immutable) inode->i_flags |= S_IMMUTABLE; - MSDOS_I(inode)->i_binary = is_binary(MSDOS_SB(sb)->options.conversion, - raw_entry->ext); + MSDOS_I(inode)->i_binary = + fat_is_binary(MSDOS_SB(sb)->options.conversion, raw_entry->ext); MSDOS_I(inode)->i_attrs = raw_entry->attr & ATTR_UNUSED; /* this is as close to the truth as we can get ... */ inode->i_blksize = MSDOS_SB(sb)->cluster_size*SECTOR_SIZE; diff -u --recursive --new-file v2.2.6/linux/fs/fat/misc.c linux/fs/fat/misc.c --- v2.2.6/linux/fs/fat/misc.c Fri Jan 23 18:10:32 1998 +++ linux/fs/fat/misc.c Tue Apr 20 14:37:10 1999 @@ -51,11 +51,11 @@ /* - * is_binary selects optional text conversion based on the conversion mode and - * the extension part of the file name. + * fat_is_binary selects optional text conversion based on the conversion mode + * and the extension part of the file name. */ -int is_binary(char conversion,char *extension) +int fat_is_binary(char conversion,char *extension) { char *walk; diff -u --recursive --new-file v2.2.6/linux/fs/msdos/namei.c linux/fs/msdos/namei.c --- v2.2.6/linux/fs/msdos/namei.c Fri Apr 16 14:47:31 1999 +++ linux/fs/msdos/namei.c Tue Apr 20 14:37:10 1999 @@ -713,7 +713,7 @@ fat_cache_inval_inode(old_inode); old_inode->i_version = ++event; MSDOS_I(old_inode)->i_binary = - is_binary(MSDOS_SB(sb)->options.conversion, free_de->ext); + fat_is_binary(MSDOS_SB(sb)->options.conversion, free_de->ext); old_inode->i_ino = free_ino; fat_mark_buffer_dirty(sb, free_bh, 1); old_de->name[0] = DELETED_FLAG; diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/Config.in linux/fs/ncpfs/Config.in --- v2.2.6/linux/fs/ncpfs/Config.in Sun Jul 26 11:57:18 1998 +++ linux/fs/ncpfs/Config.in Tue Apr 20 15:17:20 1999 @@ -6,5 +6,10 @@ bool ' Clear remove/delete inhibit when needed' CONFIG_NCPFS_STRONG bool ' Use NFS namespace if available' CONFIG_NCPFS_NFS_NS bool ' Use LONG (OS/2) namespace if available' CONFIG_NCPFS_OS2_NS +if [ "$CONFIG_NCPFS_OS2_NS" = "y" ]; then + bool ' Lowercase DOS filenames' CONFIG_NCPFS_SMALLDOS +fi bool ' Allow mounting of volume subdirectories' CONFIG_NCPFS_MOUNT_SUBDIR # bool ' NDS interserver authentication support' CONFIG_NCPFS_NDS_DOMAINS +bool ' Use Native Language Support' CONFIG_NCPFS_NLS +bool ' Enable symbolic links and execute flags' CONFIG_NCPFS_EXTRAS diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/Makefile linux/fs/ncpfs/Makefile --- v2.2.6/linux/fs/ncpfs/Makefile Thu Jul 16 18:09:28 1998 +++ linux/fs/ncpfs/Makefile Tue Apr 20 15:17:20 1999 @@ -9,7 +9,7 @@ O_TARGET := ncpfs.o O_OBJS := dir.o file.o inode.o ioctl.o mmap.o ncplib_kernel.o sock.o \ - ncpsign_kernel.o + symlink.o ncpsign_kernel.o M_OBJS := $(O_TARGET) # If you want debugging output, please uncomment the following line diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c --- v2.2.6/linux/fs/ncpfs/dir.c Fri Apr 16 14:47:31 1999 +++ linux/fs/ncpfs/dir.c Tue Apr 20 15:17:20 1999 @@ -4,6 +4,7 @@ * Copyright (C) 1995, 1996 by Volker Lendecke * Modified for big endian by J.F. Chadima and David S. Miller * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache + * Modified 1998 Wolfram Pienkoss for NLS * */ @@ -22,6 +23,7 @@ #include #include + #include "ncplib_kernel.h" struct ncp_dirent { @@ -54,7 +56,10 @@ static int ncp_rmdir(struct inode *, struct dentry *); static int ncp_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); - +#ifdef CONFIG_NCPFS_EXTRAS +extern int ncp_symlink(struct inode *, struct dentry *, const char *); +#endif + static struct file_operations ncp_dir_operations = { NULL, /* lseek - default */ @@ -77,7 +82,11 @@ ncp_lookup, /* lookup */ NULL, /* link */ ncp_unlink, /* unlink */ +#ifdef CONFIG_NCPFS_EXTRAS + ncp_symlink, /* symlink */ +#else NULL, /* symlink */ +#endif ncp_mkdir, /* mkdir */ ncp_rmdir, /* rmdir */ NULL, /* mknod */ @@ -191,14 +200,6 @@ } } -/* Here we encapsulate the inode number handling that depends upon the - * mount mode: When we mount a complete server, the memory address of - * the ncp_inode_info is used as the inode number. When only a single - * volume is mounted, then the dirEntNum is used as the inode - * number. As this is unique for the complete volume, this should - * enable the NFS exportability of a ncpfs-mounted volume. - */ - /* * Generate a unique inode number. */ @@ -253,37 +254,30 @@ ncp_force_unlink(struct inode *dir, struct dentry* dentry) { int res=0x9c,res2; - struct iattr ia; + struct nw_modify_dos_info info; + __u32 old_nwattr; + struct inode *inode; + memset(&info, 0, sizeof(info)); + /* remove the Read-Only flag on the NW server */ + inode = dentry->d_inode; - memset(&ia,0,sizeof(struct iattr)); - ia.ia_mode = dentry->d_inode->i_mode; - ia.ia_mode |= NCP_SERVER(dir)->m.file_mode & 0222; /* set write bits */ - ia.ia_valid = ATTR_MODE; - - res2=ncp_notify_change(dentry, &ia); - if (res2) - { - goto leave_me; - } + old_nwattr = NCP_FINFO(inode)->nwattr; + info.attributes = old_nwattr & ~(aRONLY|aDELETEINHIBIT|aRENAMEINHIBIT); + res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(inode), inode, NULL, DM_ATTRIBUTES, &info); + if (res2) + goto leave_me; /* now try again the delete operation */ - res = ncp_del_file_or_subdir2(NCP_SERVER(dir), dentry); if (res) /* delete failed, set R bit again */ { - memset(&ia,0,sizeof(struct iattr)); - ia.ia_mode = dentry->d_inode->i_mode; - ia.ia_mode &= ~(NCP_SERVER(dir)->m.file_mode & 0222); /* clear write bits */ - ia.ia_valid = ATTR_MODE; - - res2=ncp_notify_change(dentry, &ia); - if (res2) - { + info.attributes = old_nwattr; + res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(inode), inode, NULL, DM_ATTRIBUTES, &info); + if (res2) goto leave_me; - } } leave_me: return(res); @@ -293,63 +287,58 @@ #ifdef CONFIG_NCPFS_STRONG static int ncp_force_rename(struct inode *old_dir, struct dentry* old_dentry, char *_old_name, - struct inode *new_dir, struct dentry* new_dentry, char *_new_name, - int *done_flag) + struct inode *new_dir, struct dentry* new_dentry, char *_new_name) { + struct nw_modify_dos_info info; int res=0x90,res2; - struct iattr ia; + struct inode *old_inode = old_dentry->d_inode; + __u32 old_nwattr = NCP_FINFO(old_inode)->nwattr; + __u32 new_nwattr = 0; /* shut compiler warning */ + int old_nwattr_changed = 0; + int new_nwattr_changed = 0; + memset(&info, 0, sizeof(info)); + /* remove the Read-Only flag on the NW server */ - memset(&ia,0,sizeof(struct iattr)); - ia.ia_mode = old_dentry->d_inode->i_mode; - if (S_ISDIR(ia.ia_mode)) - goto leave_me; - ia.ia_mode |= NCP_SERVER(old_dir)->m.file_mode & 0222; /* set write bits */ - ia.ia_valid = ATTR_MODE; - - res2=ncp_notify_change(old_dentry, &ia); - if (res2) - { - goto leave_me; - } - + info.attributes = old_nwattr & ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT); + res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(old_inode), old_inode, NULL, DM_ATTRIBUTES, &info); + if (!res2) + old_nwattr_changed = 1; + if (new_dentry && new_dentry->d_inode) { + new_nwattr = NCP_FINFO(new_dentry->d_inode)->nwattr; + info.attributes = new_nwattr & ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT); + res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(new_dir), new_dir, _new_name, DM_ATTRIBUTES, &info); + if (!res2) + new_nwattr_changed = 1; + } /* now try again the rename operation */ - res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir), - old_dir, _old_name, - new_dir, _new_name); - - if (!res) { - ncp_invalid_dir_cache(old_dir); - ncp_invalid_dir_cache(new_dir); - d_move(old_dentry,new_dentry); - *done_flag=1; - - if (!old_dentry->d_inode) { - DPRINTK(KERN_INFO "ncpfs: no inode -- file remains rw\n"); - goto leave_me; - } - if ((res2=ncp_lookup_validate(old_dentry))) { - DPRINTK(KERN_DEBUG "ncpfs: ncp_lookup_validate returned %d\n",res2); - } - } - - memset(&ia,0,sizeof(struct iattr)); - ia.ia_mode = old_dentry->d_inode->i_mode; - ia.ia_mode &= ~(NCP_SERVER(old_dentry->d_inode)->m.file_mode & 0222); /* clear write bits */ - ia.ia_valid = ATTR_MODE; - - DPRINTK(KERN_INFO "calling ncp_notify_change() with %s/%s\n", - old_dentry->d_parent->d_name.name,old_dentry->d_name.name); - - res2=ncp_notify_change(old_dentry, &ia); - if (res2) - { - printk(KERN_INFO "ncpfs: ncp_notify_change (2) failed: %08x\n",res2); - /* goto leave_me; */ - } - - leave_me: + /* but only if something really happened */ + if (new_nwattr_changed || old_nwattr_changed) { + res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir), + old_dir, _old_name, + new_dir, _new_name); + } + if (res) + goto leave_me; + /* file was successfully renamed, so: + do not set attributes on old file - it no longer exists + copy attributes from old file to new */ + new_nwattr_changed = old_nwattr_changed; + new_nwattr = old_nwattr; + old_nwattr_changed = 0; + +leave_me:; + if (old_nwattr_changed) { + info.attributes = old_nwattr; + res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(old_inode), old_inode, NULL, DM_ATTRIBUTES, &info); + /* ignore errors */ + } + if (new_nwattr_changed) { + info.attributes = new_nwattr; + res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(new_dir), new_dir, _new_name, DM_ATTRIBUTES, &info); + /* ignore errors */ + } return(res); } #endif /* CONFIG_NCPFS_STRONG */ @@ -386,11 +375,6 @@ printk(KERN_DEBUG "ncp_lookup_validate: %s, len %d\n", __name, len); #endif - if (!ncp_preserve_case(dir)) { - str_lower(__name); - down_case = 1; - } - /* If the file is in the dir cache, we do not have to ask the server. */ @@ -400,17 +384,14 @@ #endif if (ncp_is_server_root(dir)) { - str_upper(__name); + io2vol(server, __name, 1); down_case = 1; res = ncp_lookup_volume(server, __name, &(finfo.nw_info.i)); } else { - if (!ncp_preserve_case(dir)) - { - str_upper(__name); - down_case = 1; - } + down_case = !ncp_preserve_case(dir); + io2vol(server, __name, down_case); res = ncp_obtain_info(server, dir, __name, &(finfo.nw_info.i)); } @@ -429,6 +410,9 @@ else printk(KERN_DEBUG "ncp_lookup_validate: found, but dirEntNum changed\n"); #endif + vol2io(server, finfo.nw_info.i.entryName, + !ncp_preserve_entry_case(dir, + finfo.nw_info.i.NSCreator)); ncp_update_inode2(dentry->d_inode, &finfo.nw_info); } if (!val) ncp_invalid_dir_cache(dir); @@ -535,10 +519,11 @@ c_last_returned_index = 0; index = 0; - if (!ncp_preserve_case(inode)) { - for (i = 0; i < c_size; i++) { - str_lower(c_entry[i].i.entryName); - } + for (i = 0; i < c_size; i++) + { + vol2io(server, c_entry[i].i.entryName, + !ncp_preserve_entry_case(inode, + c_entry[i].i.NSCreator)); } } } @@ -730,7 +715,7 @@ struct dentry* dent; result = -ENOENT; - str_upper(server->m.mounted_vol); + io2vol(server, server->m.mounted_vol, 1); if (ncp_lookup_volume(server, server->m.mounted_vol, &(server->root.finfo.i)) != 0) { #ifdef NCPFS_PARANOIA @@ -738,7 +723,7 @@ #endif goto out; } - str_lower(server->root.finfo.i.entryName); + vol2io(server, server->root.finfo.i.entryName, 1); dent = server->root_dentry; if (dent) { struct inode* ino = dent->d_inode; @@ -786,11 +771,6 @@ printk(KERN_DEBUG "ncp_lookup: %s, len %d\n", __name, len); #endif - if (!ncp_preserve_case(dir)) { - str_lower(__name); - down_case = 1; - } - /* If the file is in the dir cache, we do not have to ask the server. */ @@ -830,17 +810,14 @@ #endif if (ncp_is_server_root(dir)) { - str_upper(__name); + io2vol(server, __name, 1); down_case = 1; res = ncp_lookup_volume(server, __name, &(finfo.nw_info.i)); } else { - if (!ncp_preserve_case(dir)) - { - str_upper(__name); - down_case = 1; - } + down_case = !ncp_preserve_case(dir); + io2vol(server, __name, down_case); res = ncp_obtain_info(server, dir, __name, &(finfo.nw_info.i)); } @@ -851,8 +828,11 @@ /* * If we didn't find an entry, make a negative dentry. */ - if (res != 0) + if (res != 0) { goto add_entry; + } else vol2io(server, finfo.nw_info.i.entryName, + ncp_preserve_entry_case(dir, + finfo.nw_info.i.NSCreator)); } /* @@ -906,18 +886,19 @@ goto out; } -static int ncp_create(struct inode *dir, struct dentry *dentry, int mode) +int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode, + int attributes) { int error, result; struct ncpfs_inode_info finfo; __u8 _name[dentry->d_name.len + 1]; - + #ifdef NCPFS_PARANOIA -printk(KERN_DEBUG "ncp_create: creating %s/%s, mode=%x\n", +printk(KERN_DEBUG "ncp_create_new: creating %s/%s, mode=%x\n", dentry->d_parent->d_name.name, dentry->d_name.name, mode); #endif if (!dir || !S_ISDIR(dir->i_mode)) { - printk(KERN_WARNING "ncp_create: inode is NULL or not a directory\n"); + printk(KERN_WARNING "ncp_create_new: inode is NULL or not a directory\n"); return -ENOENT; } error = -EIO; @@ -927,14 +908,12 @@ strncpy(_name, dentry->d_name.name, dentry->d_name.len); _name[dentry->d_name.len] = '\0'; - if (!ncp_preserve_case(dir)) { - str_upper(_name); - } + io2vol(NCP_SERVER(dir), _name, !ncp_preserve_case(dir)); error = -EACCES; result = ncp_open_create_file_or_subdir(NCP_SERVER(dir), dir, _name, OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE, - 0, AR_READ | AR_WRITE, &finfo.nw_info); + attributes, AR_READ | AR_WRITE, &finfo.nw_info); if (!result) { finfo.nw_info.access = O_RDWR; error = ncp_instantiate(dir, dentry, &finfo); @@ -948,6 +927,11 @@ return error; } +static int ncp_create(struct inode *dir, struct dentry *dentry, int mode) +{ + return ncp_create_new(dir, dentry, mode, 0); +} + static int ncp_mkdir(struct inode *dir, struct dentry *dentry, int mode) { int error; @@ -967,9 +951,7 @@ strncpy(_name, dentry->d_name.name, dentry->d_name.len); _name[dentry->d_name.len] = '\0'; - if (!ncp_preserve_case(dir)) { - str_upper(_name); - } + io2vol(NCP_SERVER(dir), _name, !ncp_preserve_case(dir)); error = -EACCES; if (ncp_open_create_file_or_subdir(NCP_SERVER(dir), dir, _name, @@ -1008,17 +990,34 @@ strncpy(_name, dentry->d_name.name, dentry->d_name.len); _name[dentry->d_name.len] = '\0'; - if (!ncp_preserve_case(dir)) - { - str_upper(_name); - } - error = -EACCES; + io2vol(NCP_SERVER(dir), _name, !ncp_preserve_case(dir)); result = ncp_del_file_or_subdir(NCP_SERVER(dir), dir, _name); - if (!result) - { - ncp_invalid_dir_cache(dir); - error = 0; - } + switch (result) { + case 0x00: + ncp_invalid_dir_cache(dir); + error = 0; + break; + case 0x85: /* unauthorized to delete file */ + case 0x8A: /* unauthorized to delete file */ + error = -EACCES; + break; + case 0x8F: + case 0x90: /* read only */ + error = -EPERM; + break; + case 0x9F: /* in use by another client */ + error = -EBUSY; + break; + case 0xA0: /* directory not empty */ + error = -ENOTEMPTY; + break; + case 0xFF: /* someone deleted file */ + error = -ENOENT; + break; + default: + error = -EACCES; + break; + } out: return error; } @@ -1052,19 +1051,38 @@ error = ncp_del_file_or_subdir2(NCP_SERVER(dir), dentry); #ifdef CONFIG_NCPFS_STRONG + /* 9C is Invalid path.. It should be 8F, 90 - read only, but + it is not :-( */ if (error == 0x9C && NCP_SERVER(dir)->m.flags & NCP_MOUNT_STRONG) { /* R/O */ error = ncp_force_unlink(dir, dentry); } #endif - if (!error) { - DPRINTK(KERN_DEBUG "ncp: removed %s/%s\n", - dentry->d_parent->d_name.name, dentry->d_name.name); - ncp_invalid_dir_cache(dir); - d_delete(dentry); - } else if (error == 0xFF) { - error = -ENOENT; - } else { - error = -EACCES; + switch (error) { + case 0x00: + DPRINTK(KERN_DEBUG "ncp: removed %s/%s\n", + dentry->d_parent->d_name.name, dentry->d_name.name); + ncp_invalid_dir_cache(dir); + d_delete(dentry); + break; + case 0x85: + case 0x8A: + error = -EACCES; + break; + case 0x8D: /* some files in use */ + case 0x8E: /* all files in use */ + error = -EBUSY; + break; + case 0x8F: /* some read only */ + case 0x90: /* all read only */ + case 0x9C: /* !!! returned when in-use or read-only by NW4 */ + error = -EPERM; + break; + case 0xFF: + error = -ENOENT; + break; + default: + error = -EACCES; + break; } out: @@ -1076,7 +1094,7 @@ { int old_len = old_dentry->d_name.len; int new_len = new_dentry->d_name.len; - int error, done_flag=0; + int error; char _old_name[old_dentry->d_name.len + 1]; char _new_name[new_dentry->d_name.len + 1]; @@ -1099,44 +1117,38 @@ strncpy(_old_name, old_dentry->d_name.name, old_len); _old_name[old_len] = '\0'; - if (!ncp_preserve_case(old_dir)) { - str_upper(_old_name); - } + io2vol(NCP_SERVER(old_dir), _old_name, !ncp_preserve_case(old_dir)); strncpy(_new_name, new_dentry->d_name.name, new_len); _new_name[new_len] = '\0'; - if (!ncp_preserve_case(new_dir)) { - str_upper(_new_name); - } + io2vol(NCP_SERVER(new_dir), _new_name, !ncp_preserve_case(new_dir)); error = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir), old_dir, _old_name, new_dir, _new_name); #ifdef CONFIG_NCPFS_STRONG - if (error == 0x90 && NCP_SERVER(old_dir)->m.flags & NCP_MOUNT_STRONG) { /* RO */ + if ((error == 0x90 || error == -EACCES) && NCP_SERVER(old_dir)->m.flags & NCP_MOUNT_STRONG) { /* RO */ error = ncp_force_rename(old_dir, old_dentry, _old_name, - new_dir, new_dentry, _new_name, - &done_flag); + new_dir, new_dentry, _new_name); } #endif - if (error == 0) - { - if (done_flag == 0) /* if 1, the following already happened */ - { /* in ncp_force_rename() */ - DPRINTK(KERN_DEBUG "ncp renamed %s -> %s.\n", + switch (error) { + case 0x00: + DPRINTK(KERN_DEBUG "ncp renamed %s -> %s.\n", old_dentry->d_name.name,new_dentry->d_name.name); - ncp_invalid_dir_cache(old_dir); - ncp_invalid_dir_cache(new_dir); - if (!S_ISDIR(old_dentry->d_inode->i_mode)) - d_move(old_dentry,new_dentry); - } - } else { - if (error == 0x9E) + ncp_invalid_dir_cache(old_dir); + ncp_invalid_dir_cache(new_dir); + /* d_move(old_dentry, new_dentry); */ + break; + case 0x9E: error = -ENAMETOOLONG; - else if (error == 0xFF) + break; + case 0xFF: error = -ENOENT; - else + break; + default: error = -EACCES; + break; } out: return error; @@ -1155,14 +1167,12 @@ static int utc2local(int time) { - return time - sys_tz.tz_minuteswest * 60 + - (sys_tz.tz_dsttime ? 3600 : 0); + return time - sys_tz.tz_minuteswest * 60; } static int local2utc(int time) { - return time + sys_tz.tz_minuteswest * 60 - - (sys_tz.tz_dsttime ? 3600 : 0); + return time + sys_tz.tz_minuteswest * 60; } /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */ @@ -1171,7 +1181,9 @@ { int month, year, secs; - month = ((date >> 5) & 15) - 1; + /* first subtract and mask after that... Otherwise, if + date == 0, bad things happen */ + month = ((date >> 5) - 1) & 15; year = date >> 9; secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + 86400 * ((date & 31) - 1 + day_n[month] + (year / 4) + diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c --- v2.2.6/linux/fs/ncpfs/inode.c Fri Apr 16 14:47:31 1999 +++ linux/fs/ncpfs/inode.c Tue Apr 20 15:17:20 1999 @@ -4,6 +4,7 @@ * Copyright (C) 1995, 1996 by Volker Lendecke * Modified for big endian by J.F. Chadima and David S. Miller * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache + * Modified 1998 Wolfram Pienkoss for NLS * */ @@ -27,6 +28,7 @@ #include #include + #include "ncplib_kernel.h" static void ncp_read_inode(struct inode *); @@ -49,6 +51,10 @@ }; extern struct dentry_operations ncp_dentry_operations; +#ifdef CONFIG_NCPFS_EXTRAS +extern struct inode_operations ncp_symlink_inode_operations; +extern int ncp_symlink(struct inode*, struct dentry*, const char*); +#endif static struct nw_file_info *read_nwinfo = NULL; static struct semaphore read_sem = MUTEX; @@ -62,6 +68,12 @@ NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum; NCP_FINFO(inode)->volNumber = nwinfo->i.volNumber; +#ifdef CONFIG_NCPFS_SMALLDOS + NCP_FINFO(inode)->origNS = nwinfo->i.NSCreator; +#endif +#ifdef CONFIG_NCPFS_STRONG + NCP_FINFO(inode)->nwattr = nwinfo->i.attributes; +#endif NCP_FINFO(inode)->opened = nwinfo->opened; NCP_FINFO(inode)->access = nwinfo->access; NCP_FINFO(inode)->server_file_handle = nwinfo->server_file_handle; @@ -79,12 +91,42 @@ struct ncp_server *server = NCP_SERVER(inode); if (!NCP_FINFO(inode)->opened) { +#ifdef CONFIG_NCPFS_STRONG + NCP_FINFO(inode)->nwattr = nwi->attributes; +#endif if (nwi->attributes & aDIR) { inode->i_mode = server->m.dir_mode; inode->i_size = 512; } else { inode->i_mode = server->m.file_mode; inode->i_size = le32_to_cpu(nwi->dataStreamSize); +#ifdef CONFIG_NCPFS_EXTRAS + if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS)) && (nwi->attributes & aSHARED)) { + switch (nwi->attributes & (aHIDDEN|aSYSTEM)) { + case aHIDDEN: + if (server->m.flags & NCP_MOUNT_SYMLINKS) { + if ((inode->i_size >= NCP_MIN_SYMLINK_SIZE) + && (inode->i_size <= NCP_MAX_SYMLINK_SIZE)) { + inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK; + break; + } + } + /* FALLTHROUGH */ + case 0: + if (server->m.flags & NCP_MOUNT_EXTRAS) + inode->i_mode |= 0444; + break; + case aSYSTEM: + if (server->m.flags & NCP_MOUNT_EXTRAS) + inode->i_mode |= (inode->i_mode >> 2) & 0111; + break; + /* case aSYSTEM|aHIDDEN: */ + default: + /* reserved combination */ + break; + } + } +#endif } if (nwi->attributes & aRONLY) inode->i_mode &= ~0222; } @@ -114,6 +156,34 @@ } else { inode->i_mode = server->m.file_mode; inode->i_size = le32_to_cpu(nwi->dataStreamSize); +#ifdef CONFIG_NCPFS_EXTRAS + if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS)) + && (nwi->attributes & aSHARED)) { + switch (nwi->attributes & (aHIDDEN|aSYSTEM)) { + case aHIDDEN: + if (server->m.flags & NCP_MOUNT_SYMLINKS) { + if ((inode->i_size >= NCP_MIN_SYMLINK_SIZE) + && (inode->i_size <= NCP_MAX_SYMLINK_SIZE)) { + inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK; + break; + } + } + /* FALLTHROUGH */ + case 0: + if (server->m.flags & NCP_MOUNT_EXTRAS) + inode->i_mode |= 0444; + break; + case aSYSTEM: + if (server->m.flags & NCP_MOUNT_EXTRAS) + inode->i_mode |= (inode->i_mode >> 2) & 0111; + break; + /* case aSYSTEM|aHIDDEN: */ + default: + /* reserved combination */ + break; + } + } +#endif } if (nwi->attributes & aRONLY) inode->i_mode &= ~0222; @@ -157,6 +227,10 @@ inode->i_op = &ncp_file_inode_operations; } else if (S_ISDIR(inode->i_mode)) { inode->i_op = &ncp_dir_inode_operations; +#ifdef CONFIG_NCPFS_EXTRAS + } else if (S_ISLNK(inode->i_mode)) { + inode->i_op = &ncp_symlink_inode_operations; +#endif } else { inode->i_op = NULL; } @@ -211,7 +285,6 @@ { struct ncp_inode_info *root = &(server->root); struct nw_info_struct *i = &(root->finfo.i); - unsigned short dummy; DPRINTK(KERN_DEBUG "ncp_init_root: i = %x\n", (int) i); @@ -219,15 +292,13 @@ i->dataStreamSize= 1024; i->dirEntNum = 0; i->DosDirNum = 0; +#ifdef CONFIG_NCPFS_SMALLDOS + i->NSCreator = NW_NS_DOS; +#endif i->volNumber = NCP_NUMBER_OF_VOLUMES + 1; /* illegal volnum */ - ncp_date_unix2dos(0, &(i->creationTime), &(i->creationDate)); - ncp_date_unix2dos(0, &(i->modifyTime ), &(i->modifyDate)); - ncp_date_unix2dos(0, &(dummy ), &(i->lastAccessDate)); - i->creationTime = le16_to_cpu(i->creationTime); - i->creationDate = le16_to_cpu(i->creationDate); - i->modifyTime = le16_to_cpu(i->modifyTime); - i->modifyDate = le16_to_cpu(i->modifyDate); - i->lastAccessDate= le16_to_cpu(i->lastAccessDate); + /* set dates of mountpoint to Jan 1, 1986; 00:00 */ + i->creationTime = i->modifyTime = cpu_to_le16(0x0000); + i->creationDate = i->modifyDate = i->lastAccessDate = cpu_to_le16(0x0C21); i->nameLen = 0; i->entryName[0] = '\0'; @@ -264,8 +335,6 @@ lock_super(sb); - sb->s_flags |= MS_ODD_RENAME; /* This should go away */ - sb->s_blocksize = 1024; /* Eh... Is this correct? */ sb->s_blocksize_bits = 10; sb->s_magic = NCP_SUPER_MAGIC; @@ -310,6 +379,14 @@ server->m.dir_mode = (server->m.dir_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFDIR; +#ifdef CONFIG_NCPFS_NLS + /* load the default NLS charsets */ + server->nls_charsets.codepage[0] = 0; + server->nls_charsets.iocharset[0] = 0; + server->nls_vol = load_nls_default(); + server->nls_io = load_nls_default(); +#endif /* CONFIG_NCPFS_NLS */ + server->packet_size = NCP_PACKET_SIZE; server->packet = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL); if (server->packet == NULL) @@ -379,6 +456,10 @@ out_no_packet: printk(KERN_ERR "ncp_read_super: could not alloc packet\n"); out_free_server: +#ifdef CONFIG_NCPFS_NLS + unload_nls(server->nls_io); + unload_nls(server->nls_vol); +#endif ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server)); goto out_unlock; out_no_server: @@ -418,6 +499,20 @@ ncp_disconnect(server); ncp_unlock_server(server); +#ifdef CONFIG_NCPFS_NLS + /* unload the NLS charsets */ + if (server->nls_vol) + { + unload_nls(server->nls_vol); + server->nls_vol = NULL; + } + if (server->nls_io) + { + unload_nls(server->nls_io); + server->nls_io = NULL; + } +#endif /* CONFIG_NCPFS_NLS */ + fput(server->ncp_filp); kill_proc(server->m.wdog_pid, SIGTERM, 1); @@ -459,9 +554,12 @@ int result = 0; int info_mask; struct nw_modify_dos_info info; + struct ncp_server *server; result = -EIO; - if (!ncp_conn_valid(NCP_SERVER(inode))) + + server = NCP_SERVER(inode); + if ((!server) || !ncp_conn_valid(server)) goto out; result = inode_change_ok(inode, attr); @@ -470,11 +568,11 @@ result = -EPERM; if (((attr->ia_valid & ATTR_UID) && - (attr->ia_uid != NCP_SERVER(inode)->m.uid))) + (attr->ia_uid != server->m.uid))) goto out; if (((attr->ia_valid & ATTR_GID) && - (attr->ia_gid != NCP_SERVER(inode)->m.gid))) + (attr->ia_gid != server->m.gid))) goto out; if (((attr->ia_valid & ATTR_MODE) && @@ -488,26 +586,53 @@ #if 1 if ((attr->ia_valid & ATTR_MODE) != 0) { - if (!S_ISREG(inode->i_mode)) + if (S_ISDIR(inode->i_mode)) { + umode_t newmode; + + info_mask |= DM_ATTRIBUTES; + newmode = attr->ia_mode; + newmode &= NCP_SERVER(inode)->m.dir_mode; + + if (newmode & 0222) + info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT); + else + info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT); + } else if (!S_ISREG(inode->i_mode)) { return -EPERM; } else { umode_t newmode; - +#ifdef CONFIG_NCPFS_EXTRAS + int extras; + + extras = server->m.flags & NCP_MOUNT_EXTRAS; +#endif info_mask |= DM_ATTRIBUTES; newmode=attr->ia_mode; - newmode &= NCP_SERVER(inode)->m.file_mode; +#ifdef CONFIG_NCPFS_EXTRAS + if (!extras) +#endif + newmode &= server->m.file_mode; if (newmode & 0222) /* any write bit set */ { - info.attributes &= ~0x60001; + info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT); } else { - info.attributes |= 0x60001; + info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT); } +#ifdef CONFIG_NCPFS_EXTRAS + if (extras) { + if (newmode & 0111) /* any execute bit set */ + info.attributes |= aSHARED | aSYSTEM; + /* read for group/world and not in default file_mode */ + else if (newmode & ~server->m.file_mode & 0444) + info.attributes |= aSHARED; + } +#endif } } #endif @@ -548,6 +673,10 @@ result = 0; } } +#ifdef CONFIG_NCPFS_STRONG + if ((!result) && (info_mask & DM_ATTRIBUTES)) + NCP_FINFO(inode)->nwattr = info.attributes; +#endif } if ((attr->ia_valid & ATTR_SIZE) != 0) { int written; diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/ioctl.c linux/fs/ncpfs/ioctl.c --- v2.2.6/linux/fs/ncpfs/ioctl.c Tue Mar 17 22:18:15 1998 +++ linux/fs/ncpfs/ioctl.c Tue Apr 20 15:17:20 1999 @@ -3,6 +3,7 @@ * * Copyright (C) 1995, 1996 by Volker Lendecke * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache + * Modified 1998 Wolfram Pienkoss for NLS * */ @@ -17,6 +18,7 @@ #include #include + #include "ncplib_kernel.h" /* maximum limit for ncp_objectname_ioctl */ @@ -485,6 +487,69 @@ return 0; } #endif /* CONFIG_NCPFS_NDS_DOMAINS */ + +#ifdef CONFIG_NCPFS_NLS +/* Here we are select the iocharset and the codepage for NLS. + * Thanks Petr Vandrovec for idea and many hints. + */ + case NCP_IOC_SETCHARSETS: + if ( (permission(inode, MAY_WRITE) != 0) + && (current->uid != server->m.mounted_uid)) + { + return -EACCES; + } + if (server->root_setuped) return -EBUSY; + { + struct ncp_nls_ioctl user; + struct nls_table *codepage; + struct nls_table *iocharset; + struct nls_table *oldset_io; + struct nls_table *oldset_cp; + + if (copy_from_user(&user, + (struct ncp_nls_ioctl*)arg, + sizeof(user))) return -EFAULT; + + codepage = NULL; + if (!user.codepage[0]) { + codepage = load_nls_default(); + } + else { + codepage = load_nls(user.codepage); + if (! codepage) { + return -EBADRQC; + } + } + + iocharset = NULL; + if (user.iocharset[0] == 0) { + iocharset = load_nls_default(); + } + else { + iocharset = load_nls(user.iocharset); + if (! iocharset) { + unload_nls(codepage); + return -EBADRQC; + } + } + + oldset_cp = server->nls_vol; + server->nls_vol = codepage; + oldset_io = server->nls_io; + server->nls_io = iocharset; + server->nls_charsets = user; + if (oldset_cp) unload_nls(oldset_cp); + if (oldset_io) unload_nls(oldset_io); + return 0; + } + + case NCP_IOC_GETCHARSETS: /* not tested */ + if (copy_to_user((struct ncp_nls_ioctl*)arg, + &(server->nls_charsets), + sizeof(server->nls_charsets))) return -EFAULT; + return 0; +#endif /* CONFIG_NCPFS_NLS */ + default: return -EINVAL; } diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/ncplib_kernel.c linux/fs/ncpfs/ncplib_kernel.c --- v2.2.6/linux/fs/ncpfs/ncplib_kernel.c Fri Oct 9 13:27:15 1998 +++ linux/fs/ncpfs/ncplib_kernel.c Tue Apr 20 15:17:20 1999 @@ -238,7 +238,8 @@ } static void ncp_add_handle_path(struct ncp_server *server, __u8 vol_num, - __u32 dir_base, int have_dir_base, char *path) + __u32 dir_base, int have_dir_base, + const char *path) { ncp_add_byte(server, vol_num); ncp_add_dword(server, dir_base); @@ -468,12 +469,17 @@ target->nameLen = strlen(volname); strcpy(target->entryName, volname); target->attributes = aDIR; + /* set dates to Jan 1, 1986 00:00 */ + target->creationTime = target->modifyTime = cpu_to_le16(0x0000); + target->creationDate = target->modifyDate = target->lastAccessDate = cpu_to_le16(0x0C21); return 0; } -int ncp_modify_file_or_subdir_dos_info(struct ncp_server *server, - struct inode *dir, __u32 info_mask, - struct nw_modify_dos_info *info) +int ncp_modify_file_or_subdir_dos_info_path(struct ncp_server *server, + struct inode *dir, + const char *path, + __u32 info_mask, + const struct nw_modify_dos_info *info) { __u8 volnum = NCP_FINFO(dir)->volNumber; __u32 dirent = NCP_FINFO(dir)->dirEntNum; @@ -487,13 +493,22 @@ ncp_add_dword(server, info_mask); ncp_add_mem(server, info, sizeof(*info)); - ncp_add_handle_path(server, volnum, dirent, 1, NULL); + ncp_add_handle_path(server, volnum, dirent, 1, path); result = ncp_request(server, 87); ncp_unlock_server(server); return result; } +int ncp_modify_file_or_subdir_dos_info(struct ncp_server *server, + struct inode *dir, + __u32 info_mask, + const struct nw_modify_dos_info *info) +{ + return ncp_modify_file_or_subdir_dos_info_path(server, dir, NULL, + info_mask, info); +} + static int ncp_DeleteNSEntry(struct ncp_server *server, __u8 have_dir_base, __u8 volnum, __u32 dirent, @@ -787,6 +802,35 @@ ncp_unlock_server(server); return result; } + +#ifdef CONFIG_NCPFS_EXTRAS +int +ncp_read_kernel(struct ncp_server *server, const char *file_id, + __u32 offset, __u16 to_read, char *target, int *bytes_read) { + int error; + mm_segment_t old_fs; + + old_fs = get_fs(); + set_fs(get_ds()); + error = ncp_read(server, file_id, offset, to_read, target, bytes_read); + set_fs(old_fs); + return error; +} + +int +ncp_write_kernel(struct ncp_server *server, const char *file_id, + __u32 offset, __u16 to_write, + const char *source, int *bytes_written) { + int error; + mm_segment_t old_fs; + + old_fs = get_fs(); + set_fs(get_ds()); + error = ncp_write(server, file_id, offset, to_write, source, bytes_written); + set_fs(old_fs); + return error; +} +#endif #ifdef CONFIG_NCPFS_IOCTL_LOCKING int diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/ncplib_kernel.h linux/fs/ncpfs/ncplib_kernel.h --- v2.2.6/linux/fs/ncpfs/ncplib_kernel.h Tue Mar 10 10:03:34 1998 +++ linux/fs/ncpfs/ncplib_kernel.h Tue Apr 20 15:17:20 1999 @@ -4,6 +4,7 @@ * Copyright (C) 1995, 1996 by Volker Lendecke * Modified for big endian by J.F. Chadima and David S. Miller * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache + * Modified 1998 Wolfram Pienkoss for NLS * */ @@ -23,6 +24,10 @@ #include #include +#ifdef CONFIG_NCPFS_NLS +#include +#endif + #include #include #include @@ -36,12 +41,19 @@ int ncp_read(struct ncp_server *, const char *, __u32, __u16, char *, int *); int ncp_write(struct ncp_server *, const char *, __u32, __u16, const char *, int *); +#ifdef CONFIG_NCPFS_EXTRAS +int ncp_read_kernel(struct ncp_server *, const char *, __u32, __u16, char *, int *); +int ncp_write_kernel(struct ncp_server *, const char *, __u32, __u16, + const char *, int *); +#endif int ncp_obtain_info(struct ncp_server *server, struct inode *, char *, struct nw_info_struct *target); int ncp_lookup_volume(struct ncp_server *, char *, struct nw_info_struct *); int ncp_modify_file_or_subdir_dos_info(struct ncp_server *, struct inode *, - __u32, struct nw_modify_dos_info *info); + __u32, const struct nw_modify_dos_info *info); +int ncp_modify_file_or_subdir_dos_info_path(struct ncp_server *, struct inode *, + const char* path, __u32, const struct nw_modify_dos_info *info); int ncp_del_file_or_subdir2(struct ncp_server *, struct dentry*); int ncp_del_file_or_subdir(struct ncp_server *, struct inode *, char *); @@ -75,4 +87,83 @@ ncp_mount_subdir(struct ncp_server* server, __u8 volNumber, __u8 srcNS, __u32 srcDirEntNum); #endif /* CONFIG_NCPFS_MOUNT_SUBDIR */ + +#ifdef CONFIG_NCPFS_NLS +/* This are the NLS conversion routines with inspirations and code parts + * from the vfat file system and hints from Petr Vandrovec. + */ + +/* + * It should be replaced by charset specifc conversion. Gordon Chaffee + * has prepared some things, but I don't know, what he thinks about it. + * The conversion tables for the io charsets should be generatable by + * Unicode table, shouldn't it? I have written so generation code for it. + * The tables for the vendor specific codepages...? Hmm. The Samba sources + * contains also any hints. + */ + +#define toupperif(c, u) ((((u) != 0) && ((c) >= 'a') && ((c) <= 'z')) \ + ? (c)-('a'-'A') : (c)) +#define tolowerif(c, u) ((((u) != 0) && ((c) >= 'A') && ((c) <= 'Z')) \ + ? (c)-('A'-'a') : (c)) + +static inline void +io2vol(struct ncp_server *server, char *name, int case_trans) +{ + unsigned char nc; + unsigned char *np; + unsigned char *up; + struct nls_unicode uc; + struct nls_table *nls_in; + struct nls_table *nls_out; + + nls_in = server->nls_io; + nls_out = server->nls_vol; + np = name; + + while (*np) + { + nc = 0; + uc = nls_in->charset2uni[toupperif(*np, case_trans)]; + up = nls_out->page_uni2charset[uc.uni2]; + if (up != NULL) nc = up[uc.uni1]; + if (nc != 0) *np = nc; + np++; + } +} + +static inline void +vol2io(struct ncp_server *server, char *name, int case_trans) +{ + unsigned char nc; + unsigned char *np; + unsigned char *up; + struct nls_unicode uc; + struct nls_table *nls_in; + struct nls_table *nls_out; + + nls_in = server->nls_vol; + nls_out = server->nls_io; + np = name; + + while (*np) + { + nc = 0; + uc = nls_in->charset2uni[*np]; + up = nls_out->page_uni2charset[uc.uni2]; + if (up != NULL) nc = up[uc.uni1]; + if (nc == 0) nc = *np; + *np = tolowerif(nc, case_trans); + np++; + } +} + +#else + +#define io2vol(S,N,U) if (U) str_upper(N) +#define vol2io(S,N,U) if (U) str_lower(N) + +#endif /* CONFIG_NCPFS_NLS */ + #endif /* _NCPLIB_H */ + diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/symlink.c linux/fs/ncpfs/symlink.c --- v2.2.6/linux/fs/ncpfs/symlink.c Wed Dec 31 16:00:00 1969 +++ linux/fs/ncpfs/symlink.c Tue Apr 20 15:17:20 1999 @@ -0,0 +1,212 @@ +/* + * linux/fs/ncpfs/symlink.c + * + * Code for allowing symbolic links on NCPFS (i.e. NetWare) + * Symbolic links are not supported on native NetWare, so we use an + * infrequently-used flag (Sh) and store a two-word magic header in + * the file to make sure we don't accidentally use a non-link file + * as a link. + * + * from linux/fs/ext2/symlink.c + * + * Copyright (C) 1998-99, Frank A. Vorstenbosch + * + * ncpfs symlink handling code + * NLS support (c) 1999 Petr Vandrovec + * + */ + +#include + +#ifdef CONFIG_NCPFS_EXTRAS + +#include +#include + +#include +#include +#include +#include +#include +#include +#include "ncplib_kernel.h" + + +/* these magic numbers must appear in the symlink file -- this makes it a bit + more resilient against the magic attributes being set on random files. */ + +#define NCP_SYMLINK_MAGIC0 le32_to_cpu(0x6c6d7973) /* "symlnk->" */ +#define NCP_SYMLINK_MAGIC1 le32_to_cpu(0x3e2d6b6e) + +static int ncp_readlink(struct dentry *, char *, int); +static struct dentry *ncp_follow_link(struct dentry *, struct dentry *, unsigned int); +int ncp_create_new(struct inode *dir, struct dentry *dentry, + int mode,int attributes); + +/* + * symlinks can't do much... + */ +struct inode_operations ncp_symlink_inode_operations={ + NULL, /* no file-operations */ + NULL, /* create */ + NULL, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + ncp_readlink, /* readlink */ + ncp_follow_link, /* follow_link */ + NULL, /* readpage */ + NULL, /* writepage */ + NULL, /* bmap */ + NULL, /* truncate */ + NULL, /* permission */ + NULL /* smap */ +}; + +/* ----- follow a symbolic link ------------------------------------------ */ + +static struct dentry *ncp_follow_link(struct dentry *dentry, + struct dentry *base, + unsigned int follow) +{ + struct inode *inode=dentry->d_inode; + int error, length, cnt; + char *link; + +#ifdef DEBUG + printk("ncp_follow_link(dentry=%p,base=%p,follow=%u)\n",dentry,base,follow); +#endif + + if(!S_ISLNK(inode->i_mode)) { + dput(base); + return ERR_PTR(-EINVAL); + } + + if(ncp_make_open(inode,O_RDONLY)) { + dput(base); + return ERR_PTR(-EIO); + } + + for (cnt = 0; (link=(char *)kmalloc(NCP_MAX_SYMLINK_SIZE+1, GFP_NFS))==NULL; cnt++) { + if (cnt > 10) { + dput(base); + return ERR_PTR(-EAGAIN); /* -ENOMEM? */ + } + schedule(); + } + + error=ncp_read_kernel(NCP_SERVER(inode),NCP_FINFO(inode)->file_handle, + 0,NCP_MAX_SYMLINK_SIZE,link,&length); + + if (error!=0 || lengthd_inode; + char *link; + int length,error; + +#ifdef DEBUG + printk("ncp_readlink(dentry=%p,buffer=%p,buflen=%d)\n",dentry,buffer,buflen); +#endif + + if(!S_ISLNK(inode->i_mode)) + return -EINVAL; + + if(ncp_make_open(inode,O_RDONLY)) + return -EIO; + + if((link=(char *)kmalloc(NCP_MAX_SYMLINK_SIZE+1,GFP_NFS))==NULL) + return -ENOMEM; + + error = ncp_read_kernel(NCP_SERVER(inode),NCP_FINFO(inode)->file_handle, + 0,NCP_MAX_SYMLINK_SIZE,link,&length); + + if (error!=0 || length < NCP_MIN_SYMLINK_SIZE || buflen < (length-8) || + ((__u32 *)link)[0]!=NCP_SYMLINK_MAGIC0 ||((__u32 *)link)[1]!=NCP_SYMLINK_MAGIC1) { + error = -EIO; + goto out; + } + + link[length] = 0; + + vol2io(NCP_SERVER(inode), link+8, 0); + + error = length - 8; + if(copy_to_user(buffer, link+8, error)) + error = -EFAULT; + +out:; + kfree(link); + return error; +} + +/* ----- create a new symbolic link -------------------------------------- */ + +int ncp_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { + int i,length; + struct inode *inode; + char *link; + +#ifdef DEBUG + printk("ncp_symlink(dir=%p,dentry=%p,symname=%s)\n",dir,dentry,symname); +#endif + + if (!(NCP_SERVER(dir)->m.flags & NCP_MOUNT_SYMLINKS)) + return -EPERM; /* EPERM is returned by VFS if symlink procedure does not exist */ + + if ((length=strlen(symname))>NCP_MAX_SYMLINK_SIZE) + return -EINVAL; + + if ((link=(char *)kmalloc(length+9,GFP_NFS))==NULL) + return -ENOMEM; + + if (ncp_create_new(dir,dentry,0,aSHARED|aHIDDEN)) { + kfree(link); + return -EIO; + } + + inode=dentry->d_inode; + + ((__u32 *)link)[0]=NCP_SYMLINK_MAGIC0; + ((__u32 *)link)[1]=NCP_SYMLINK_MAGIC1; + memcpy(link+8, symname, length+1); /* including last zero for io2vol */ + + /* map to/from server charset, do not touch upper/lower case as + symlink can point out of ncp filesystem */ + io2vol(NCP_SERVER(inode), link+8, 0); + + if(ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, + 0, length+8, link, &i) || i!=length+8) { + kfree(link); + return -EIO; + } + + kfree(link); + return 0; +} +#endif + +/* ----- EOF ----- */ diff -u --recursive --new-file v2.2.6/linux/fs/nfs/dir.c linux/fs/nfs/dir.c --- v2.2.6/linux/fs/nfs/dir.c Fri Apr 16 14:47:31 1999 +++ linux/fs/nfs/dir.c Wed Apr 21 09:22:23 1999 @@ -109,7 +109,7 @@ dfprintk(VFS, "NFS: nfs_dir_open(%s/%s)\n", dentry->d_parent->d_name.name, dentry->d_name.name); - return nfs_revalidate_inode(NFS_DSERVER(dentry), dentry); + return _nfs_revalidate_inode(NFS_DSERVER(dentry), dentry); } static ssize_t @@ -439,8 +439,10 @@ goto out_bad; /* Filehandle matches? */ - if (memcmp(dentry->d_fsdata, &fhandle, sizeof(struct nfs_fh))) - goto out_bad; + if (memcmp(dentry->d_fsdata, &fhandle, sizeof(struct nfs_fh))) { + if (dentry->d_count < 2 || nfs_revalidate(dentry)) + goto out_bad; + } /* Ok, remeber that we successfully checked it.. */ nfs_renew_times(dentry); diff -u --recursive --new-file v2.2.6/linux/fs/nfs/file.c linux/fs/nfs/file.c --- v2.2.6/linux/fs/nfs/file.c Tue Mar 23 14:35:48 1999 +++ linux/fs/nfs/file.c Wed Apr 21 10:32:57 1999 @@ -37,6 +37,7 @@ static ssize_t nfs_file_write(struct file *, const char *, size_t, loff_t *); static int nfs_file_flush(struct file *); static int nfs_fsync(struct file *, struct dentry *dentry); +static int nfs_file_open(struct inode *inode, struct file *filp); static struct file_operations nfs_file_operations = { NULL, /* lseek - default */ @@ -46,7 +47,7 @@ NULL, /* select - default */ NULL, /* ioctl - default */ nfs_file_mmap, /* mmap */ - NULL, /* no special open is needed */ + nfs_file_open, /* open */ nfs_file_flush, /* flush */ NULL, /* release */ nfs_fsync, /* fsync */ @@ -103,6 +104,19 @@ } return status; } + +/* + * Open the file. + * Just checks the cache is synchronized. + */ +static int +nfs_file_open(struct inode *inode, struct file *filp) +{ + struct dentry *dentry = filp->f_dentry; + + return _nfs_revalidate_inode(NFS_DSERVER(dentry), dentry); +} + static ssize_t nfs_file_read(struct file * file, char * buf, size_t count, loff_t *ppos) diff -u --recursive --new-file v2.2.6/linux/fs/nfs/inode.c linux/fs/nfs/inode.c --- v2.2.6/linux/fs/nfs/inode.c Fri Apr 16 14:47:31 1999 +++ linux/fs/nfs/inode.c Wed Apr 21 09:22:23 1999 @@ -234,6 +234,11 @@ server->rsize = nfs_block_size(data->rsize, NULL); server->wsize = nfs_block_size(data->wsize, NULL); server->flags = data->flags; + + if (data->flags & NFS_MOUNT_NOAC) { + data->acregmin = data->acregmax = 0; + data->acdirmin = data->acdirmax = 0; + } server->acregmin = data->acregmin*HZ; server->acregmax = data->acregmax*HZ; server->acdirmin = data->acdirmin*HZ; @@ -659,10 +664,6 @@ struct inode *inode = dentry->d_inode; int status = 0; struct nfs_fattr fattr; - - /* Don't bother revalidating if we've done it recently */ - if (jiffies - NFS_READTIME(inode) < NFS_ATTRTIMEO(inode)) - goto out; dfprintk(PAGECACHE, "NFS: revalidating %s/%s, ino=%ld\n", dentry->d_parent->d_name.name, dentry->d_name.name, diff -u --recursive --new-file v2.2.6/linux/fs/nls/Config.in linux/fs/nls/Config.in --- v2.2.6/linux/fs/nls/Config.in Wed Jan 13 15:00:43 1999 +++ linux/fs/nls/Config.in Tue Apr 20 15:17:20 1999 @@ -4,7 +4,7 @@ # msdos and Joliet want NLS if [ "$CONFIG_JOLIET" = "y" -o "$CONFIG_FAT_FS" != "n" \ - -o "$CONFIG_NTFS_FS" != "n" ]; then + -o "$CONFIG_NTFS_FS" != "n" -o "$CONFIG_NCPFS_NLS" = "y" ]; then define_bool CONFIG_NLS y else define_bool CONFIG_NLS n diff -u --recursive --new-file v2.2.6/linux/include/asm-i386/bitops.h linux/include/asm-i386/bitops.h --- v2.2.6/linux/include/asm-i386/bitops.h Mon Dec 28 15:00:53 1998 +++ linux/include/asm-i386/bitops.h Wed Apr 21 13:04:34 1999 @@ -46,7 +46,7 @@ __asm__ __volatile__( LOCK_PREFIX "btsl %1,%0" :"=m" (ADDR) - :"ir" (nr)); + :"Ir" (nr)); } extern __inline__ void clear_bit(int nr, volatile void * addr) @@ -54,7 +54,7 @@ __asm__ __volatile__( LOCK_PREFIX "btrl %1,%0" :"=m" (ADDR) - :"ir" (nr)); + :"Ir" (nr)); } extern __inline__ void change_bit(int nr, volatile void * addr) @@ -62,7 +62,7 @@ __asm__ __volatile__( LOCK_PREFIX "btcl %1,%0" :"=m" (ADDR) - :"ir" (nr)); + :"Ir" (nr)); } extern __inline__ int test_and_set_bit(int nr, volatile void * addr) @@ -72,7 +72,7 @@ __asm__ __volatile__( LOCK_PREFIX "btsl %2,%1\n\tsbbl %0,%0" :"=r" (oldbit),"=m" (ADDR) - :"ir" (nr)); + :"Ir" (nr)); return oldbit; } @@ -83,7 +83,7 @@ __asm__ __volatile__( LOCK_PREFIX "btrl %2,%1\n\tsbbl %0,%0" :"=r" (oldbit),"=m" (ADDR) - :"ir" (nr)); + :"Ir" (nr)); return oldbit; } @@ -94,7 +94,7 @@ __asm__ __volatile__( LOCK_PREFIX "btcl %2,%1\n\tsbbl %0,%0" :"=r" (oldbit),"=m" (ADDR) - :"ir" (nr)); + :"Ir" (nr)); return oldbit; } @@ -113,7 +113,7 @@ __asm__ __volatile__( "btl %2,%1\n\tsbbl %0,%0" :"=r" (oldbit) - :"m" (ADDR),"ir" (nr)); + :"m" (ADDR),"Ir" (nr)); return oldbit; } diff -u --recursive --new-file v2.2.6/linux/include/linux/fs.h linux/include/linux/fs.h --- v2.2.6/linux/include/linux/fs.h Fri Apr 16 14:47:31 1999 +++ linux/include/linux/fs.h Wed Apr 21 13:04:36 1999 @@ -169,7 +169,7 @@ extern void update_atime (struct inode *inode); #define UPDATE_ATIME(inode) update_atime (inode) -extern void buffer_init(void); +extern void buffer_init(unsigned long); extern void inode_init(void); extern void file_table_init(void); extern void dcache_init(void); diff -u --recursive --new-file v2.2.6/linux/include/linux/msdos_fs.h linux/include/linux/msdos_fs.h --- v2.2.6/linux/include/linux/msdos_fs.h Fri Jul 31 17:10:57 1998 +++ linux/include/linux/msdos_fs.h Wed Apr 21 13:06:02 1999 @@ -195,7 +195,7 @@ }; /* misc.c */ -extern int is_binary(char conversion,char *extension); +extern int fat_is_binary(char conversion,char *extension); extern void lock_fat(struct super_block *sb); extern void unlock_fat(struct super_block *sb); extern int fat_add_cluster(struct inode *inode); diff -u --recursive --new-file v2.2.6/linux/include/linux/ncp.h linux/include/linux/ncp.h --- v2.2.6/linux/include/linux/ncp.h Fri Jul 31 17:10:57 1998 +++ linux/include/linux/ncp.h Wed Apr 21 13:06:05 1999 @@ -3,6 +3,7 @@ * * Copyright (C) 1995 by Volker Lendecke * Modified for sparc by J.F. Chadima + * Modified for __constant_ntoh by Frank A. Vorstenbosch * */ @@ -58,11 +59,21 @@ /* these define the attribute byte as seen by NCP */ #define aRONLY (ntohl(0x01000000)) -#define aHIDDEN (ntohl(0x02000000)) -#define aSYSTEM (ntohl(0x04000000)) +#define aHIDDEN (__constant_ntohl(0x02000000)) +#define aSYSTEM (__constant_ntohl(0x04000000)) #define aEXECUTE (ntohl(0x08000000)) #define aDIR (ntohl(0x10000000)) #define aARCH (ntohl(0x20000000)) +#define aSHARED (ntohl(0x80000000)) +#define aDONTSUBALLOCATE (ntohl(1L<<(11+8))) +#define aTRANSACTIONAL (ntohl(1L<<(12+8))) +#define aPURGE (ntohl(1L<<(16-8))) +#define aRENAMEINHIBIT (ntohl(1L<<(17-8))) +#define aDELETEINHIBIT (ntohl(1L<<(18-8))) +#define aDONTCOMPRESS (nothl(1L<<(27-24))) + +#define NCP_MIN_SYMLINK_SIZE 8 +#define NCP_MAX_SYMLINK_SIZE 512 #define AR_READ (ntohs(0x0100)) #define AR_WRITE (ntohs(0x0200)) diff -u --recursive --new-file v2.2.6/linux/include/linux/ncp_fs.h linux/include/linux/ncp_fs.h --- v2.2.6/linux/include/linux/ncp_fs.h Fri Jul 31 17:11:03 1998 +++ linux/include/linux/ncp_fs.h Wed Apr 21 13:06:18 1999 @@ -13,6 +13,15 @@ #include #include + +/* NLS charsets by ioctl */ +#define NCP_IOCSNAME_LEN 20 +struct ncp_nls_ioctl +{ + unsigned char codepage[NCP_IOCSNAME_LEN+1]; + unsigned char iocharset[NCP_IOCSNAME_LEN+1]; +}; + #include #include @@ -111,6 +120,9 @@ #define NCP_IOC_GETPRIVATEDATA _IOWR('n', 10, struct ncp_privatedata_ioctl) #define NCP_IOC_SETPRIVATEDATA _IOR('n', 10, struct ncp_privatedata_ioctl) +#define NCP_IOC_GETCHARSETS _IOWR('n', 11, struct ncp_nls_ioctl) +#define NCP_IOC_SETCHARSETS _IOR('n', 11, struct ncp_nls_ioctl) + /* * The packet size to allocate. One page should be enough. */ @@ -155,6 +167,12 @@ __u32 dirEntNum __attribute__((packed)); __u32 DosDirNum __attribute__((packed)); __u32 volNumber __attribute__((packed)); +#ifdef CONFIG_NCPFS_SMALLDOS + __u32 origNS; +#endif +#ifdef CONFIG_NCPFS_STRONG + __u32 nwattr; +#endif int opened; int access; __u32 server_file_handle __attribute__((packed)); @@ -272,11 +290,14 @@ return server->name_space[NCP_FINFO(inode)->volNumber]; } -static inline int ncp_preserve_case(struct inode *i) -{ +static inline int ncp_preserve_entry_case(struct inode *i, __u32 nscreator) { #if defined(CONFIG_NCPFS_NFS_NS) || defined(CONFIG_NCPFS_OS2_NS) int ns = ncp_namespace(i); #endif +#if defined(CONFIG_NCPFS_SMALLDOS) && defined(CONFIG_NCPFS_OS2_NS) + if ((ns == NW_NS_OS2) && (nscreator == NW_NS_DOS)) + return 0; +#endif return #ifdef CONFIG_NCPFS_OS2_NS (ns == NW_NS_OS2) || @@ -285,6 +306,11 @@ (ns == NW_NS_NFS) || #endif /* CONFIG_NCPFS_NFS_NS */ 0; +} + +static inline int ncp_preserve_case(struct inode *i) +{ + return ncp_preserve_entry_case(i, NW_NS_OS2); } static inline int ncp_case_sensitive(struct inode *i) diff -u --recursive --new-file v2.2.6/linux/include/linux/ncp_fs_sb.h linux/include/linux/ncp_fs_sb.h --- v2.2.6/linux/include/linux/ncp_fs_sb.h Fri Jul 31 17:11:03 1998 +++ linux/include/linux/ncp_fs_sb.h Wed Apr 21 13:06:18 1999 @@ -73,6 +73,10 @@ size_t len; void* data; } priv; + + struct ncp_nls_ioctl nls_charsets; /* NLS user data */ + struct nls_table *nls_vol; /* codepage used on volume */ + struct nls_table *nls_io; /* charset used for input and display */ }; static inline int ncp_conn_valid(struct ncp_server *server) diff -u --recursive --new-file v2.2.6/linux/include/linux/ncp_mount.h linux/include/linux/ncp_mount.h --- v2.2.6/linux/include/linux/ncp_mount.h Fri Jul 31 17:11:03 1998 +++ linux/include/linux/ncp_mount.h Wed Apr 21 13:06:18 1999 @@ -16,11 +16,13 @@ #define NCP_MOUNT_VERSION 3 /* Values for flags */ -#define NCP_MOUNT_SOFT 0x0001 -#define NCP_MOUNT_INTR 0x0002 -#define NCP_MOUNT_STRONG 0x0004 /* enable delete/rename of r/o files */ -#define NCP_MOUNT_NO_OS2 0x0008 -#define NCP_MOUNT_NO_NFS 0x0010 +#define NCP_MOUNT_SOFT 0x0001 +#define NCP_MOUNT_INTR 0x0002 +#define NCP_MOUNT_STRONG 0x0004 /* enable delete/rename of r/o files */ +#define NCP_MOUNT_NO_OS2 0x0008 /* do not use OS/2 (LONG) namespace */ +#define NCP_MOUNT_NO_NFS 0x0010 /* do not use NFS namespace */ +#define NCP_MOUNT_EXTRAS 0x0020 +#define NCP_MOUNT_SYMLINKS 0x0040 /* enable symlinks */ struct ncp_mount_data { int version; diff -u --recursive --new-file v2.2.6/linux/include/linux/pagemap.h linux/include/linux/pagemap.h --- v2.2.6/linux/include/linux/pagemap.h Fri Apr 16 14:47:31 1999 +++ linux/include/linux/pagemap.h Wed Apr 21 13:04:48 1999 @@ -20,8 +20,6 @@ #define PAGE_HASH_BITS 12 #define PAGE_HASH_SIZE (1 << PAGE_HASH_BITS) -#define PAGE_AGE_VALUE 16 - extern unsigned long page_cache_size; /* # of pages currently in the hash table */ extern struct page * page_hash_table[PAGE_HASH_SIZE]; diff -u --recursive --new-file v2.2.6/linux/include/linux/pci.h linux/include/linux/pci.h --- v2.2.6/linux/include/linux/pci.h Fri Apr 16 14:47:31 1999 +++ linux/include/linux/pci.h Wed Apr 21 13:04:36 1999 @@ -927,6 +927,9 @@ #define PCI_VENDOR_ID_CCUBE 0x123f +#define PCI_VENDOR_ID_AVM 0x1244 +#define PCI_DEVICE_ID_AVM_A1 0x0a00 + #define PCI_VENDOR_ID_DIPIX 0x1246 #define PCI_VENDOR_ID_STALLION 0x124d diff -u --recursive --new-file v2.2.6/linux/init/main.c linux/init/main.c --- v2.2.6/linux/init/main.c Fri Apr 16 14:47:31 1999 +++ linux/init/main.c Wed Apr 21 11:10:00 1999 @@ -1166,7 +1166,7 @@ filescache_init(); dcache_init(); vma_init(); - buffer_init(); + buffer_init(memory_end-memory_start); signals_init(); inode_init(); file_table_init(); diff -u --recursive --new-file v2.2.6/linux/mm/page_alloc.c linux/mm/page_alloc.c --- v2.2.6/linux/mm/page_alloc.c Mon Jan 25 17:44:34 1999 +++ linux/mm/page_alloc.c Wed Apr 21 13:03:48 1999 @@ -33,7 +33,7 @@ for the ring buffers */ #define NR_MEM_LISTS 12 #else -#define NR_MEM_LISTS 6 +#define NR_MEM_LISTS 10 #endif /* The start of this MUST match the start of "struct page" */