diff -u --recursive --new-file v2.1.55/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.1.55/linux/Documentation/Configure.help Sun Sep 7 13:10:42 1997 +++ linux/Documentation/Configure.help Sat Sep 13 11:07:26 1997 @@ -1381,13 +1381,9 @@ machine on the Internet that has a program like lynx or netscape). EtherTalk is the name used for appletalk over ethernet and the cheaper and slower LocalTalk is appletalk over a proprietary - apple network using serial links. Ethertalk is fully supported by - Linux, however the localtalk drivers are not yet ready to ship. The - kernel however supports localtalk and when such drivers become - available all you will need to do is download and install the - localtalk driver in order to join a Localtalk network. The - NET-2-HOWTO, available via ftp (user: anonymous) in - sunsite.unc.edu:/pub/Linux/docs/HOWTO contains valuable information + apple network using serial links. Ethertalk and Localtalk is fully + supported by Linux. The NET-2-HOWTO, available via ftp (user: anonymous) + in sunsite.unc.edu:/pub/Linux/docs/HOWTO contains valuable information as well. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). The module will be called appletalk.o. If you want to compile @@ -1408,8 +1404,6 @@ If you are in doubt, this card is the one with the 65C02 chip on it. You also need version 1.3.3 or later of the netatalk package. This driver is experimental, which means that it may not work. - In particular the module support is not yet working for the 2.1.xx - kernels, so choose Y or N, but not M for now. See README.ltpc in the drivers/net directory, and the web site http://www.math.unm.edu/~bradford/ltpc.html @@ -1418,10 +1412,8 @@ This allows you to use COPS AppleTalk cards to connect to LocalTalk networks. You also need version 1.3.3 or later of the netatalk package. This driver is experimental, which means that it may not - work. In particular the module support is not yet working for the - 2.1.xx kernels, so choose Y or N, but not M for now. This driver - will only work if you choose "Appletalk DDP" networking support, - above. + work. This driver will only work if you choose "Appletalk DDP" + networking support, above. Please read the file Documentation/networking/README.cops. See the web site http://www.math.unm.edu/~bradford/ltpc.html for localtalk IP tools. @@ -1430,7 +1422,7 @@ CONFIG_COPS_DAYNA Support COPS compatible cards with Dayna style firmware (Dayna DL2000/ Daynatalk/PC (half length), COPS LT-95, Farallon PhoneNET PC - III). + III, Farallon PhoneNET PC II). Tangent firmware support CONFIG_COPS_TANGENT diff -u --recursive --new-file v2.1.55/linux/arch/alpha/defconfig linux/arch/alpha/defconfig --- v2.1.55/linux/arch/alpha/defconfig Wed Sep 3 20:52:41 1997 +++ linux/arch/alpha/defconfig Wed Sep 10 11:18:52 1997 @@ -42,6 +42,7 @@ CONFIG_SYSCTL=y CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set CONFIG_BINFMT_EM86=y # CONFIG_PARPORT is not set @@ -141,7 +142,6 @@ # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_NCR53C8XX is not set -# CONFIG_SCSI_PPA is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_QLOGIC_FAS is not set CONFIG_SCSI_QLOGIC_ISP=y @@ -150,8 +150,6 @@ # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_ULTRASTOR is not set -# CONFIG_SCSI_MESH is not set -# CONFIG_SCSI_MAC53C94 is not set # # Network device support @@ -164,6 +162,7 @@ # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set # CONFIG_NET_ISA is not set CONFIG_NET_EISA=y # CONFIG_PCNET32 is not set @@ -176,7 +175,6 @@ # CONFIG_NET_POCKET is not set # CONFIG_FDDI is not set # CONFIG_DLCI is not set -# CONFIG_PLIP is not set # CONFIG_PPP is not set # CONFIG_NET_RADIO is not set # CONFIG_SLIP is not set diff -u --recursive --new-file v2.1.55/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c --- v2.1.55/linux/arch/alpha/kernel/bios32.c Sun Sep 7 13:10:42 1997 +++ linux/arch/alpha/kernel/bios32.c Wed Sep 10 11:18:52 1997 @@ -1182,32 +1182,6 @@ } -const char *pcibios_strerror (int error) -{ - static char buf[80]; - - switch (error) { - case PCIBIOS_SUCCESSFUL: - return "SUCCESSFUL"; - - case PCIBIOS_FUNC_NOT_SUPPORTED: - return "FUNC_NOT_SUPPORTED"; - - case PCIBIOS_BAD_VENDOR_ID: - return "SUCCESSFUL"; - - case PCIBIOS_DEVICE_NOT_FOUND: - return "DEVICE_NOT_FOUND"; - - case PCIBIOS_BAD_REGISTER_NUMBER: - return "BAD_REGISTER_NUMBER"; - - default: - sprintf (buf, "UNKNOWN RETURN 0x%x", error); - return buf; - } -} - asmlinkage int sys_pciconfig_read( unsigned long bus, unsigned long dfn, diff -u --recursive --new-file v2.1.55/linux/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c --- v2.1.55/linux/arch/alpha/kernel/osf_sys.c Thu Jul 17 10:06:03 1997 +++ linux/arch/alpha/kernel/osf_sys.c Wed Sep 10 11:18:52 1997 @@ -135,8 +135,6 @@ { int error; struct file *file; - struct dentry *dentry; - struct inode *inode; struct osf_dirent_callback buf; error = -EBADF; @@ -147,14 +145,6 @@ if (!file) goto out; - dentry = file->f_dentry; - if (!dentry) - goto out; - - inode = dentry->d_inode; - if (!inode) - goto out; - buf.dirent = dirent; buf.basep = basep; buf.count = count; @@ -164,7 +154,7 @@ if (!file->f_op || !file->f_op->readdir) goto out; - error = file->f_op->readdir(inode, file, &buf, osf_filldir); + error = file->f_op->readdir(file, &buf, osf_filldir); if (error < 0) goto out; diff -u --recursive --new-file v2.1.55/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c --- v2.1.55/linux/arch/i386/kernel/setup.c Sun Jul 27 12:11:00 1997 +++ linux/arch/i386/kernel/setup.c Sat Sep 13 11:07:26 1997 @@ -257,7 +257,8 @@ { static const char *model[] = { "SSA5 (PR-75, PR-90, PR-100)", "5k86 (PR-120, PR-133)", - "5k86 (PR-166)", "5k86 (PR-200)", "", "", "K6" + "5k86 (PR-166)", "5k86 (PR-200)", "", "", + "K6(PR-133..PR-166)","K6(PR-133..PR-200)" }; if (nr < sizeof(model)/sizeof(char *)) return model[nr]; diff -u --recursive --new-file v2.1.55/linux/drivers/block/ataflop.c linux/drivers/block/ataflop.c --- v2.1.55/linux/drivers/block/ataflop.c Tue May 13 22:41:04 1997 +++ linux/drivers/block/ataflop.c Sat Sep 13 11:07:26 1997 @@ -1981,7 +1981,7 @@ if (!filp || (filp->f_mode & (2 | OPEN_WRITE_BIT))) /* if the file is mounted OR (writable now AND writable at open time) Linus: Does this cover all cases? */ - block_fsync (inode, filp); + block_fsync (filp, filp->f_dentry); if (fd_ref[drive] < 0) fd_ref[drive] = 0; diff -u --recursive --new-file v2.1.55/linux/drivers/block/floppy.c linux/drivers/block/floppy.c --- v2.1.55/linux/drivers/block/floppy.c Sun Sep 7 13:10:42 1997 +++ linux/drivers/block/floppy.c Sat Sep 13 11:07:26 1997 @@ -3503,7 +3503,7 @@ if (!filp || (filp->f_mode & (2 | OPEN_WRITE_BIT))) /* if the file is mounted OR (writable now AND writable at * open time) Linus: Does this cover all cases? */ - block_fsync(inode,filp); + block_fsync(filp, filp->f_dentry); if (UDRS->fd_ref < 0) UDRS->fd_ref=0; diff -u --recursive --new-file v2.1.55/linux/drivers/block/rd.c linux/drivers/block/rd.c --- v2.1.55/linux/drivers/block/rd.c Sun Sep 7 13:10:42 1997 +++ linux/drivers/block/rd.c Sat Sep 13 11:07:26 1997 @@ -360,7 +360,7 @@ * Read block 0 to test for gzipped kernel */ if (fp->f_op->llseek) - fp->f_op->llseek(fp->f_dentry->d_inode, fp, start_block * BLOCK_SIZE, 0); + fp->f_op->llseek(fp, start_block * BLOCK_SIZE, 0); fp->f_pos = start_block * BLOCK_SIZE; fp->f_op->read(fp->f_dentry->d_inode, fp, buf, size); @@ -390,8 +390,7 @@ * Read block 1 to test for minix and ext2 superblock */ if (fp->f_op->llseek) - fp->f_op->llseek(fp->f_dentry->d_inode, fp, - (start_block+1) * BLOCK_SIZE, 0); + fp->f_op->llseek(fp, (start_block+1) * BLOCK_SIZE, 0); fp->f_pos = (start_block+1) * BLOCK_SIZE; fp->f_op->read(fp->f_dentry->d_inode, fp, buf, size); @@ -421,7 +420,7 @@ done: if (fp->f_op->llseek) - fp->f_op->llseek(fp->f_dentry->d_inode, fp, start_block * BLOCK_SIZE, 0); + fp->f_op->llseek(fp, start_block * BLOCK_SIZE, 0); fp->f_pos = start_block * BLOCK_SIZE; if ((nblocks > 0) && blk_size[MAJOR(device)]) { diff -u --recursive --new-file v2.1.55/linux/drivers/block/swim3.c linux/drivers/block/swim3.c --- v2.1.55/linux/drivers/block/swim3.c Mon Aug 18 18:19:45 1997 +++ linux/drivers/block/swim3.c Sat Sep 13 11:07:27 1997 @@ -842,7 +842,7 @@ return -ENXIO; fs = &floppy_states[0]; if (filp == 0 || (filp->f_mode & (2 | OPEN_WRITE_BIT))) - block_fsync(inode, filp); + block_fsync(filp, filp->f_dentry); sw = fs->swim3; if (fs->ref_count > 0 && --fs->ref_count == 0) { swim3_action(fs, MOTOR_OFF); diff -u --recursive --new-file v2.1.55/linux/drivers/char/amigamouse.c linux/drivers/char/amigamouse.c --- v2.1.55/linux/drivers/char/amigamouse.c Wed Apr 23 19:01:17 1997 +++ linux/drivers/char/amigamouse.c Sat Sep 13 11:07:27 1997 @@ -159,11 +159,10 @@ MSE_INT_ON(); } -static int fasync_mouse(struct inode *inode, struct file *filp, int on) +static int fasync_mouse(struct file *filp, int on) { int retval; - - retval = fasync_helper(inode, filp, on, &mouse.fasyncptr); + retval = fasync_helper(filp, on, &mouse.fasyncptr); if (retval < 0) return retval; return 0; @@ -175,7 +174,7 @@ static int release_mouse(struct inode * inode, struct file * file) { - fasync_mouse(inode, file, 0); + fasync_mouse(file, 0); if (--mouse.active) return 0; free_irq(IRQ_AMIGA_VERTB, mouse_interrupt); diff -u --recursive --new-file v2.1.55/linux/drivers/char/apm_bios.c linux/drivers/char/apm_bios.c --- v2.1.55/linux/drivers/char/apm_bios.c Thu Sep 11 09:02:23 1997 +++ linux/drivers/char/apm_bios.c Sat Sep 13 11:07:27 1997 @@ -958,7 +958,7 @@ as = (struct apm_bios_struct *)kmalloc(sizeof(*as), GFP_KERNEL); if (as == NULL) { - printk(KERN_ERR "apm_bios: cannot allocate struct of size %d bytes", + printk(KERN_ER "apm_bios: cannot allocate struct of size %d bytes", sizeof(*as)); return -ENOMEM; } diff -u --recursive --new-file v2.1.55/linux/drivers/char/atarimouse.c linux/drivers/char/atarimouse.c --- v2.1.55/linux/drivers/char/atarimouse.c Mon Jun 16 16:35:54 1997 +++ linux/drivers/char/atarimouse.c Sat Sep 13 11:07:27 1997 @@ -54,11 +54,10 @@ /* ikbd_mouse_rel_pos(); */ } -static int fasync_mouse(struct inode *inode, struct file *filp, int on) +static int fasync_mouse(struct file *filp, int on) { int retval; - - retval = fasync_helper(inode, filp, on, &mouse.fasyncptr); + retval = fasync_helper(filp, on, &mouse.fasyncptr); if (retval < 0) return retval; return 0; @@ -66,7 +65,7 @@ static int release_mouse(struct inode *inode, struct file *file) { - fasync_mouse(inode, file, 0); + fasync_mouse(file, 0); if (--mouse.active) return 0; ikbd_mouse_disable(); diff -u --recursive --new-file v2.1.55/linux/drivers/char/atixlmouse.c linux/drivers/char/atixlmouse.c --- v2.1.55/linux/drivers/char/atixlmouse.c Wed Apr 23 19:01:17 1997 +++ linux/drivers/char/atixlmouse.c Sat Sep 13 11:07:27 1997 @@ -95,11 +95,10 @@ ATIXL_MSE_ENABLE_UPDATE(); } -static int fasync_mouse(struct inode *inode, struct file *filp, int on) +static int fasync_mouse(struct file *filp, int on) { int retval; - - retval = fasync_helper(inode, filp, on, &mouse.fasync); + retval = fasync_helper(filp, on, &mouse.fasync); if (retval < 0) return retval; return 0; @@ -107,7 +106,7 @@ static int release_mouse(struct inode * inode, struct file * file) { - fasync_mouse(inode, file, 0); + fasync_mouse(file, 0); if (--mouse.active) return 0; ATIXL_MSE_INT_OFF(); /* Interrupts are really shut down here */ diff -u --recursive --new-file v2.1.55/linux/drivers/char/busmouse.c linux/drivers/char/busmouse.c --- v2.1.55/linux/drivers/char/busmouse.c Tue May 13 22:41:06 1997 +++ linux/drivers/char/busmouse.c Sat Sep 13 11:07:27 1997 @@ -106,11 +106,12 @@ MSE_INT_ON(); } -static int fasync_mouse(struct inode *inode, struct file *filp, int on) +static int fasync_mouse(struct file *filp, int on) { int retval; + struct inode *inode = filp->f_dentry->d_inode; - retval = fasync_helper(inode, filp, on, &mouse.fasyncptr); + retval = fasync_helper(filp, on, &mouse.fasyncptr); if (retval < 0) return retval; return 0; @@ -122,7 +123,7 @@ static int close_mouse(struct inode * inode, struct file * file) { - fasync_mouse(inode, file, 0); + fasync_mouse(file, 0); if (--mouse.active) return 0; MSE_INT_OFF(); diff -u --recursive --new-file v2.1.55/linux/drivers/char/fbmem.c linux/drivers/char/fbmem.c --- v2.1.55/linux/drivers/char/fbmem.c Mon Aug 4 16:25:37 1997 +++ linux/drivers/char/fbmem.c Sat Sep 13 11:07:27 1997 @@ -199,10 +199,9 @@ } } -static int -fb_mmap(struct inode *inode, struct file *file, struct vm_area_struct * vma) +static int fb_mmap(struct file *file, struct vm_area_struct * vma) { - struct fb_ops *fb = registered_fb[GET_FB_IDX(inode->i_rdev)]; + struct fb_ops *fb = registered_fb[GET_FB_IDX(file->f_dentry->d_inode->i_rdev)]; struct fb_fix_screeninfo fix; if (! fb) diff -u --recursive --new-file v2.1.55/linux/drivers/char/lp.c linux/drivers/char/lp.c --- v2.1.55/linux/drivers/char/lp.c Wed Sep 3 20:52:42 1997 +++ linux/drivers/char/lp.c Sat Sep 13 11:07:27 1997 @@ -371,8 +371,7 @@ return retv; } -static long long lp_lseek(struct inode * inode, struct file * file, - long long offset, int origin) +static long long lp_lseek(struct file * file, long long offset, int origin) { return -ESPIPE; } diff -u --recursive --new-file v2.1.55/linux/drivers/char/lp_m68k.c linux/drivers/char/lp_m68k.c --- v2.1.55/linux/drivers/char/lp_m68k.c Mon Jun 16 16:35:55 1997 +++ linux/drivers/char/lp_m68k.c Sat Sep 13 11:07:27 1997 @@ -353,8 +353,7 @@ } #endif -static long long lp_lseek(struct inode * inode, struct file * file, - long long offset, int origin) +static long long lp_lseek(struct file * file, long long offset, int origin) { return -ESPIPE; } diff -u --recursive --new-file v2.1.55/linux/drivers/char/mem.c linux/drivers/char/mem.c --- v2.1.55/linux/drivers/char/mem.c Sun Sep 7 13:10:42 1997 +++ linux/drivers/char/mem.c Sat Sep 13 11:07:27 1997 @@ -117,7 +117,7 @@ return do_write_mem(file,__va(p),p,buf,count); } -static int mmap_mem(struct inode * inode, struct file * file, struct vm_area_struct * vma) +static int mmap_mem(struct file * file, struct vm_area_struct * vma) { unsigned long offset = vma->vm_offset; @@ -330,7 +330,7 @@ return written ? written : -EFAULT; } -static int mmap_zero(struct inode * inode, struct file * file, struct vm_area_struct * vma) +static int mmap_zero(struct file * file, struct vm_area_struct * vma) { if (vma->vm_flags & VM_SHARED) return -EINVAL; @@ -350,8 +350,7 @@ * both devices with "a" now. This was previously impossible. SRB. */ -static long long null_lseek(struct inode * inode, struct file * file, - long long offset, int orig) +static long long null_lseek(struct file * file, long long offset, int orig) { return file->f_pos=0; } @@ -363,8 +362,7 @@ * also note that seeking relative to the "end of file" isn't supported: * it has no meaning, so it returns -EINVAL. */ -static long long memory_lseek(struct inode * inode, struct file * file, - long long offset, int orig) +static long long memory_lseek(struct file * file, long long offset, int orig) { switch (orig) { case 0: diff -u --recursive --new-file v2.1.55/linux/drivers/char/msbusmouse.c linux/drivers/char/msbusmouse.c --- v2.1.55/linux/drivers/char/msbusmouse.c Tue May 13 22:41:07 1997 +++ linux/drivers/char/msbusmouse.c Sat Sep 13 11:07:27 1997 @@ -89,11 +89,11 @@ } } -static int fasync_mouse(struct inode *inode, struct file *filp, int on) +static int fasync_mouse(struct file *filp, int on) { int retval; - retval = fasync_helper(inode, filp, on, &mouse.fasyncptr); + retval = fasync_helper(filp, on, &mouse.fasyncptr); if (retval < 0) return retval; return 0; @@ -101,7 +101,7 @@ static int release_mouse(struct inode * inode, struct file * file) { - fasync_mouse(inode, file, 0); + fasync_mouse(file, 0); if (--mouse.active) return 0; MS_MSE_INT_OFF(); diff -u --recursive --new-file v2.1.55/linux/drivers/char/nvram.c linux/drivers/char/nvram.c --- v2.1.55/linux/drivers/char/nvram.c Mon Aug 4 16:25:37 1997 +++ linux/drivers/char/nvram.c Sat Sep 13 11:07:27 1997 @@ -211,8 +211,7 @@ * The are the file operation function for user access to /dev/nvram */ -static long long nvram_llseek( struct inode *inode, struct file *file, - loff_t offset, int origin ) +static long long nvram_llseek(struct file *file,loff_t offset, int origin ) { switch( origin ) { case 0: diff -u --recursive --new-file v2.1.55/linux/drivers/char/pc110pad.c linux/drivers/char/pc110pad.c --- v2.1.55/linux/drivers/char/pc110pad.c Mon Aug 4 16:25:37 1997 +++ linux/drivers/char/pc110pad.c Sat Sep 13 11:07:27 1997 @@ -474,11 +474,11 @@ -static int fasync_pad(struct inode *inode, struct file *filp, int on) +static int fasync_pad(struct file *filp, int on) { int retval; - retval = fasync_helper(inode, filp, on, &asyncptr); + retval = fasync_helper(filp, on, &asyncptr); if (retval < 0) return retval; return 0; @@ -490,7 +490,7 @@ */ static int close_pad(struct inode * inode, struct file * file) { - fasync_pad(inode, file, 0); + fasync_pad(file, 0); if (--active) return 0; outb(0x30, current_params.io+2); /* switch off digitiser */ diff -u --recursive --new-file v2.1.55/linux/drivers/char/psaux.c linux/drivers/char/psaux.c --- v2.1.55/linux/drivers/char/psaux.c Mon Aug 4 16:25:37 1997 +++ linux/drivers/char/psaux.c Sat Sep 13 11:07:27 1997 @@ -102,11 +102,11 @@ return queue->head == queue->tail; } -static int fasync_aux(struct inode *inode, struct file *filp, int on) +static int fasync_aux(struct file *filp, int on) { int retval; - retval = fasync_helper(inode, filp, on, &queue->fasync); + retval = fasync_helper(filp, on, &queue->fasync); if (retval < 0) return retval; return 0; @@ -239,7 +239,7 @@ static int release_aux(struct inode * inode, struct file * file) { - fasync_aux(inode, file, 0); + fasync_aux(file, 0); if (--aux_count) return 0; aux_start_atomic(); @@ -387,7 +387,7 @@ { unsigned char status; - fasync_aux(inode, file, 0); + fasync_aux(file, 0); if (!--qp_count) { if (!poll_qp_status()) printk("Warning: Mouse device busy in release_qp()\n"); diff -u --recursive --new-file v2.1.55/linux/drivers/char/rtc.c linux/drivers/char/rtc.c --- v2.1.55/linux/drivers/char/rtc.c Thu Jul 17 10:06:04 1997 +++ linux/drivers/char/rtc.c Sat Sep 13 11:07:27 1997 @@ -76,8 +76,7 @@ static struct timer_list rtc_irq_timer; -static long long rtc_llseek(struct inode *inode, struct file *file, - loff_t offset, int origin); +static long long rtc_llseek(struct file *file, loff_t offset, int origin); static long rtc_read(struct inode *inode, struct file *file, char *buf, unsigned long count); @@ -142,8 +141,7 @@ * Now all the various file operations that we export. */ -static long long rtc_llseek(struct inode *inode, struct file *file, - loff_t offset, int origin) +static long long rtc_llseek(struct file *file, loff_t offset, int origin) { return -ESPIPE; } diff -u --recursive --new-file v2.1.55/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c --- v2.1.55/linux/drivers/char/tpqic02.c Tue May 13 22:41:07 1997 +++ linux/drivers/char/tpqic02.c Sat Sep 13 11:07:27 1997 @@ -1712,8 +1712,7 @@ } /* qic02_tape_interrupt */ -static long long qic02_tape_lseek(struct inode * inode, struct file * file, - long long offset, int origin) +static long long qic02_tape_lseek(struct file * file, long long offset, int origin) { return -EINVAL; /* not supported */ } /* qic02_tape_lseek */ diff -u --recursive --new-file v2.1.55/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c --- v2.1.55/linux/drivers/char/tty_io.c Mon Aug 4 16:25:37 1997 +++ linux/drivers/char/tty_io.c Sat Sep 13 11:07:27 1997 @@ -115,7 +115,7 @@ static int tty_release(struct inode *, struct file *); static int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg); -static int tty_fasync(struct inode * inode, struct file * filp, int on); +static int tty_fasync(struct file * filp, int on); #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -327,8 +327,7 @@ return cmd == TIOCSPGRP ? -ENOTTY : -EIO; } -static long long tty_lseek(struct inode * inode, struct file * file, - long long offset, int orig) +static long long tty_lseek(struct file * file, long long offset, int orig) { return -ESPIPE; } @@ -381,7 +380,7 @@ continue; if (filp->f_op != &tty_fops) continue; - tty_fasync(filp->f_dentry->d_inode, filp, 0); + tty_fasync(filp, 0); filp->f_op = fops; } @@ -926,7 +925,7 @@ check_tty_count(tty, "release_dev"); - tty_fasync(filp->f_dentry->d_inode, filp, 0); + tty_fasync(filp, 0); idx = MINOR(tty->device) - tty->driver.minor_start; pty_master = (tty->driver.type == TTY_DRIVER_TYPE_PTY && @@ -1263,7 +1262,7 @@ * to set up the fasync queue. It returns negative on error, 0 if it did * no changes and positive if it added/deleted the entry. */ -int fasync_helper(struct inode * inode, struct file * filp, int on, struct fasync_struct **fapp) +int fasync_helper(struct file * filp, int on, struct fasync_struct **fapp) { struct fasync_struct *fa, **fp; unsigned long flags; @@ -1298,16 +1297,16 @@ return 1; } -static int tty_fasync(struct inode * inode, struct file * filp, int on) +static int tty_fasync(struct file * filp, int on) { struct tty_struct * tty; int retval; tty = (struct tty_struct *)filp->private_data; - if (tty_paranoia_check(tty, inode->i_rdev, "tty_fasync")) + if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "tty_fasync")) return 0; - retval = fasync_helper(inode, filp, on, &tty->fasync); + retval = fasync_helper(filp, on, &tty->fasync); if (retval <= 0) return retval; diff -u --recursive --new-file v2.1.55/linux/drivers/char/vc_screen.c linux/drivers/char/vc_screen.c --- v2.1.55/linux/drivers/char/vc_screen.c Mon Jul 7 08:24:28 1997 +++ linux/drivers/char/vc_screen.c Sat Sep 13 11:07:27 1997 @@ -79,11 +79,10 @@ return size; } -static long long -vcs_lseek(struct inode *inode, struct file *file, long long offset, int orig) +static long long vcs_lseek(struct file *file, long long offset, int orig) { int size; - size = vcs_size(inode); + size = vcs_size(file->f_dentry->d_inode); switch (orig) { case 0: diff -u --recursive --new-file v2.1.55/linux/drivers/char/wdt.c linux/drivers/char/wdt.c --- v2.1.55/linux/drivers/char/wdt.c Tue May 13 22:41:07 1997 +++ linux/drivers/char/wdt.c Sat Sep 13 11:07:27 1997 @@ -155,8 +155,7 @@ } -static long long wdt_llseek(struct inode *inode, struct file *file, long long offset, - int origin) +static long long wdt_llseek(struct file *file, long long offset, int origin) { return -ESPIPE; } diff -u --recursive --new-file v2.1.55/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c --- v2.1.55/linux/drivers/isdn/isdn_common.c Mon Aug 11 14:47:04 1997 +++ linux/drivers/isdn/isdn_common.c Sat Sep 13 11:07:27 1997 @@ -922,8 +922,7 @@ return -ENODEV; } -static LSTYPE -isdn_lseek(struct inode *inode, struct file *file, LSARG offset, int orig) +static LSTYPE isdn_lseek(struct file *file, LSARG offset, int orig) { return -ESPIPE; } diff -u --recursive --new-file v2.1.55/linux/drivers/macintosh/adb.c linux/drivers/macintosh/adb.c --- v2.1.55/linux/drivers/macintosh/adb.c Mon Aug 18 18:19:45 1997 +++ linux/drivers/macintosh/adb.c Sat Sep 13 11:07:27 1997 @@ -86,8 +86,7 @@ return 0; } -static long long adb_lseek(struct inode *inode, struct file *file, - long long offset, int origin) +static long long adb_lseek(struct file *file, long long offset, int origin) { return -ESPIPE; } diff -u --recursive --new-file v2.1.55/linux/drivers/macintosh/nvram.c linux/drivers/macintosh/nvram.c --- v2.1.55/linux/drivers/macintosh/nvram.c Mon Aug 18 18:19:46 1997 +++ linux/drivers/macintosh/nvram.c Sat Sep 13 11:07:27 1997 @@ -12,8 +12,7 @@ #define NVRAM_SIZE 8192 -static long long nvram_llseek(struct inode *inode, struct file *file, - loff_t offset, int origin) +static long long nvram_llseek(struct file *file, loff_t offset, int origin) { switch (origin) { case 1: diff -u --recursive --new-file v2.1.55/linux/drivers/net/Config.in linux/drivers/net/Config.in --- v2.1.55/linux/drivers/net/Config.in Thu Sep 4 17:07:30 1997 +++ linux/drivers/net/Config.in Sat Sep 13 11:07:27 1997 @@ -126,7 +126,7 @@ fi # -# LocalTalk +# AppleTalk # if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_ATALK" != "n" ]; then @@ -136,6 +136,7 @@ bool 'Dayna firmware support' CONFIG_COPS_DAYNA bool 'Tangent firmware support' CONFIG_COPS_TANGENT fi + dep_tristate 'IP-over-DDP driver support' CONFIG_IPDDP $CONFIG_ATALK fi fi @@ -202,10 +203,10 @@ # # WAN drivers support # -if [ "$CONFIG_WAN_ROUTER" = "y" ]; then +if [ "$CONFIG_WAN_ROUTER" != "n" ]; then bool 'WAN drivers' CONFIG_WAN_DRIVERS if [ "$CONFIG_WAN_DRIVERS" = "y" ]; then - bool 'Sangoma WANPIPE(tm) multiprotocol cards' CONFIG_VENDOR_SANGOMA + dep_tristate 'Sangoma WANPIPE(tm) multiprotocol cards' CONFIG_VENDOR_SANGOMA $CONFIG_WAN_DRIVERS if [ "$CONFIG_VENDOR_SANGOMA" = "y" ]; then int ' Maximum number of cards' CONFIG_WANPIPE_CARDS 1 bool ' WANPIPE X.25 support' CONFIG_WANPIPE_X25 diff -u --recursive --new-file v2.1.55/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v2.1.55/linux/drivers/net/Makefile Thu Sep 4 17:07:30 1997 +++ linux/drivers/net/Makefile Sat Sep 13 11:07:27 1997 @@ -727,6 +727,14 @@ endif endif +ifeq ($(CONFIG_IPDDP),y) +L_OBJS += ipddp.o +else + ifeq ($(CONFIG_IPDDP),m) + M_OBJS += ipddp.o + endif +endif + ifeq ($(CONFIG_BAYCOM),y) L_OBJS += baycom.o CONFIG_HDLCDRV_BUILTIN = y diff -u --recursive --new-file v2.1.55/linux/drivers/net/Space.c linux/drivers/net/Space.c --- v2.1.55/linux/drivers/net/Space.c Thu Sep 4 17:07:30 1997 +++ linux/drivers/net/Space.c Sat Sep 13 11:07:27 1997 @@ -326,6 +326,17 @@ # define NEXT_DEV (&dev_cops) #endif /* COPS */ +#if defined(CONFIG_IPDDP) + extern int ipddp_init(struct device *dev); + static struct device dev_ipddp = { + "ipddp0\0 ", + 0, 0, 0, 0, + 0x0, 0, + 0, 0, 0, NEXT_DEV, ipddp_init }; +# undef NEXT_DEV +# define NEXT_DEV (&dev_ipddp) +#endif /* CONFIG_IPDDP */ + /* The first device defaults to I/O base '0', which means autoprobe. */ #ifndef ETH0_ADDR # define ETH0_ADDR 0 diff -u --recursive --new-file v2.1.55/linux/drivers/net/ipddp.c linux/drivers/net/ipddp.c --- v2.1.55/linux/drivers/net/ipddp.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/ipddp.c Sat Sep 13 11:07:27 1997 @@ -0,0 +1,309 @@ +/* + * ipddp.c: IP-over-DDP driver for Linux + * + * Authors: + * - Original code by: Bradford W. Johnson + * - Moved to driver by: Jay Schulist + * + * Derived from: + * - Almost all code already existed in net/appletalk/ddp.c I just + * moved/reorginized it into a driver file. Original IP-over-DDP code + * was done by Bradford W. Johnson + * - skeleton.c: A network driver outline for linux. + * Written 1993-94 by Donald Becker. + * - dummy.c: A dummy net driver. By Nick Holloway. + * + * Copyright 1993 United States Government as represented by the + * Director, National Security Agency. + * + * This software may be used and distributed according to the terms + * of the GNU Public License, incorporated herein by reference. + */ + +static const char *version = +"ipddp.c:v0.01 8/28/97 Bradford W. Johnson \n"; + +#include +#ifdef MODULE +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ipddp.h" /* Our stuff */ + +/* + * The name of the card. Is used for messages and in the requests for + * io regions, irqs and dma channels + */ + +static const char *cardname = "ipddp"; + +/* Use 0 for production, 1 for verification, 2 for debug, 3 for verbose debug */ +#ifndef IPDDP_DEBUG +#define IPDDP_DEBUG 1 +#endif +static unsigned int ipddp_debug = IPDDP_DEBUG; + +/* Index to functions, as function prototypes. */ +static int ipddp_xmit(struct sk_buff *skb, struct device *dev); +static struct net_device_stats *ipddp_get_stats(struct device *dev); +static int ipddp_rebuild_header(struct sk_buff *skb); +static int ipddp_header(struct sk_buff *skb, struct device *dev, + unsigned short type, void *daddr, void *saddr, unsigned len); +static int ipddp_ioctl(struct device *dev, struct ifreq *ifr, int cmd); + + +static int ipddp_open(struct device *dev) +{ +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif + + return 0; +} + +static int ipddp_close(struct device *dev) +{ +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif + + return 0; +} + +int ipddp_init(struct device *dev) +{ + static unsigned version_printed = 0; + + if (ipddp_debug && version_printed++ == 0) + printk("%s", version); + + /* Initalize the device structure. */ + dev->hard_start_xmit = ipddp_xmit; + + dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL); + if(!dev->priv) + return -ENOMEM; + memset(dev->priv,0,sizeof(struct enet_statistics)); + + dev->open = ipddp_open; + dev->stop = ipddp_close; + dev->get_stats = ipddp_get_stats; + dev->do_ioctl = ipddp_ioctl; + dev->hard_header = ipddp_header; /* see ip_output.c */ + dev->rebuild_header = ipddp_rebuild_header; + + dev->type = ARPHRD_IPDDP; /* IP over DDP tunnel */ + dev->family = AF_INET; + dev->mtu = 585; + dev->flags |= IFF_NOARP; + + /* + * The worst case header we will need is currently a + * ethernet header (14 bytes) and a ddp header (sizeof ddpehdr+1) + * We send over SNAP so that takes another 8 bytes. + */ + dev->hard_header_len = 14+8+sizeof(struct ddpehdr)+1; + + /* Fill in the device structure with ethernet-generic values. */ + ether_setup(dev); + + return 0; +} + +/* + * Transmit LLAP/ELAP frame using aarp_send_ddp. + */ +static int ipddp_xmit(struct sk_buff *skb, struct device *dev) +{ + /* Retrieve the saved address hint */ + struct at_addr *a=(struct at_addr *)skb->data; + skb_pull(skb,4); + + ((struct net_device_stats *) dev->priv)->tx_packets++; + ((struct net_device_stats *) dev->priv)->tx_bytes+=skb->len; + + if(ipddp_debug>1) + printk("ipddp_xmit: Headroom %d\n",skb_headroom(skb)); + + if(aarp_send_ddp(skb->dev,skb,a,NULL) < 0) + dev_kfree_skb(skb,FREE_WRITE); + + return 0; +} + +/* + * Get the current statistics. This may be called with the card open or closed. + */ +static struct net_device_stats *ipddp_get_stats(struct device *dev) +{ + return (struct net_device_stats *)dev->priv; +} + +/* + * Now the packet really wants to go out. + */ +static int ipddp_rebuild_header(struct sk_buff *skb) +{ + u32 paddr = ((struct rtable*)skb->dst)->rt_gateway; + struct ddpehdr *ddp; + struct at_addr at; + struct ipddp_route *rt; + struct at_addr *our_addr; + + /* + * On entry skb->data points to the ddpehdr we reserved earlier. + * skb->h.raw will be the higher level header. + */ + + /* + * We created this earlier. + */ + + ddp = (struct ddpehdr *) (skb->data+4); + + /* find appropriate route */ + + for(rt=ipddp_route_head;rt;rt=rt->next) + { + if(rt->ip == paddr) + break; + } + + if(!rt) { + printk("ipddp unreachable dst %08lx\n",ntohl(paddr)); + return -ENETUNREACH; + } + + our_addr = atalk_find_dev_addr(rt->dev); + + /* fill in ddpehdr */ + ddp->deh_len = skb->len; + ddp->deh_hops = 1; + ddp->deh_pad = 0; + ddp->deh_sum = 0; + ddp->deh_dnet = rt->at.s_net; /* FIXME more hops?? */ + ddp->deh_snet = our_addr->s_net; + ddp->deh_dnode = rt->at.s_node; + ddp->deh_snode = our_addr->s_node; + ddp->deh_dport = 72; + ddp->deh_sport = 72; + + *((__u8 *)(ddp+1)) = 22; /* ddp type = IP */ + + /* fix up length field */ + *((__u16 *)ddp)=ntohs(*((__u16 *)ddp)); + + /* set skb->dev to appropriate device */ + skb->dev = rt->dev; + + /* skb->raddr = (unsigned long) at */ + at = rt->at; + /* Hide it at the start of the buffer */ + memcpy(skb->data,(void *)&at,sizeof(at)); + skb->arp = 1; /* so the actual device doesn't try to arp it... */ + skb->protocol = htons(ETH_P_ATALK); /* Protocol has changed */ + + return 0; +} + +static int ipddp_header(struct sk_buff *skb, struct device *dev, + unsigned short type, void *daddr, void *saddr, unsigned len) +{ + if(ipddp_debug>=2) + printk("%s: ipddp_header\n", cardname); + + /* Push down the header space and the type byte */ + skb_push(skb, sizeof(struct ddpehdr)+1+4); + + return 0; +} + +static int ipddp_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +{ + struct ipddp_route *urt = (struct ipddp_route *)ifr->ifr_data; + + if(!suser()) + return -EPERM; + + /* for now we only have one route at a time */ + + switch(cmd) + { + case SIOCADDIPDDPRT: + if(copy_from_user(&ipddp_route_test,urt,sizeof(struct ipddp_route))) + return -EFAULT; + ipddp_route_test.dev = atrtr_get_dev(&ipddp_route_test.at); + if (dev==NULL) + return -ENETUNREACH; + ipddp_route_test.next = NULL; + printk("%s: Added route through %s\n", + ipddp_route_test.dev->name, cardname); + ipddp_route_head = &ipddp_route_test; + return 0; + + case SIOCFINDIPDDPRT: + if(copy_to_user(urt,&ipddp_route_test,sizeof(struct ipddp_route))) + return -EFAULT; + return 0; + + case SIOCDELIPDDPRT: + ipddp_route_test.dev = NULL; + ipddp_route_head = NULL; + return 0; + + default: + return -EINVAL; + } +} + +#ifdef MODULE /* Module specific functions for ipddp.c */ + +static struct device dev_ipddp= +{ + "ipddp0\0 ", + 0, 0, 0, 0, + 0x0, 0, + 0, 0, 0, NULL, ipddp_init +}; + +int init_module(void) +{ + if (register_netdev(&dev_ipddp) != 0) + return -EIO; + + return 0; +} + +void cleanup_module(void) +{ + unregister_netdev(&dev_ipddp); + kfree(dev_ipddp.priv); + dev_ipddp.priv = NULL; +} + +#endif /* MODULE */ diff -u --recursive --new-file v2.1.55/linux/drivers/net/ipddp.h linux/drivers/net/ipddp.h --- v2.1.55/linux/drivers/net/ipddp.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/ipddp.h Sat Sep 13 11:07:27 1997 @@ -0,0 +1,27 @@ +/* + * ipddp.h: Header for IP-over-DDP driver for Linux. + */ + +#ifndef __LINUX_IPDDP_H +#define __LINUX_IPDDP_H + +#ifdef __KERNEL__ + +#define SIOCADDIPDDPRT SIOCDEVPRIVATE +#define SIOCDELIPDDPRT SIOCDEVPRIVATE+1 +#define SIOCFINDIPDDPRT SIOCDEVPRIVATE+2 + +struct ipddp_route +{ + struct device *dev; /* Carrier device */ + __u32 ip; /* IP address */ + struct at_addr at; /* Gateway appletalk address */ + int flags; + struct ipddp_route *next; +}; + +static struct ipddp_route *ipddp_route_head; +static struct ipddp_route ipddp_route_test; + +#endif /* __KERNEL__ */ +#endif /* __LINUX_IPDDP_H */ diff -u --recursive --new-file v2.1.55/linux/drivers/net/x25_asy.c linux/drivers/net/x25_asy.c --- v2.1.55/linux/drivers/net/x25_asy.c Tue May 13 22:41:12 1997 +++ linux/drivers/net/x25_asy.c Sat Sep 13 11:07:27 1997 @@ -4,6 +4,11 @@ * o tbusy handling * o allow users to set the parameters * o sync/async switching ? + * + * Note: This does _not_ implement CCITT X.25 asynchronous framing + * recommendations. Its primarily for testing purposes. If you wanted + * to do CCITT then in theory all you need is to nick the HDLC async + * checksum routines from ppp.c */ #include diff -u --recursive --new-file v2.1.55/linux/drivers/sound/dmasound.c linux/drivers/sound/dmasound.c --- v2.1.55/linux/drivers/sound/dmasound.c Wed May 28 10:51:32 1997 +++ linux/drivers/sound/dmasound.c Sat Sep 13 11:07:28 1997 @@ -668,10 +668,9 @@ static int sound_open(struct inode *inode, struct file *file); -static int sound_fsync(struct inode *inode, struct file *filp); +static int sound_fsync(struct file *filp, struct dentry *dentry); static void sound_release(struct inode *inode, struct file *file); -static long long sound_lseek(struct inode *inode, struct file *file, - long long offset, int orig); +static long long sound_lseek(struct file *file, long long offset, int orig); static long sound_read(struct inode *inode, struct file *file, char *buf, unsigned long count); static long sound_write(struct inode *inode, struct file *file, @@ -3071,9 +3070,9 @@ } -static int sound_fsync(struct inode *inode, struct file *filp) +static int sound_fsync(struct file *filp, struct dentry *dentry) { - int dev = MINOR(inode->i_rdev) & 0x0f; + int dev = MINOR(dentry->d_inode->i_rdev) & 0x0f; switch (dev) { case SND_DEV_STATUS: @@ -3116,8 +3115,7 @@ } -static long long sound_lseek(struct inode *inode, struct file *file, - long long offset, int orig) +static long long sound_lseek(struct file *file, long long offset, int orig) { return -ESPIPE; } @@ -3186,25 +3184,25 @@ return(0); case SNDCTL_DSP_POST: case SNDCTL_DSP_SYNC: - return(sound_fsync(inode, file)); + return(sound_fsync(file, file->f_dentry)); /* ++TeSche: before changing any of these it's probably wise to * wait until sound playing has settled down */ case SNDCTL_DSP_SPEED: - sound_fsync(inode, file); + sound_fsync(file, file->f_dentry); IOCTL_IN(arg, data); return(IOCTL_OUT(arg, sound_set_speed(data))); case SNDCTL_DSP_STEREO: - sound_fsync(inode, file); + sound_fsync(file, file->f_dentry); IOCTL_IN(arg, data); return(IOCTL_OUT(arg, sound_set_stereo(data))); case SOUND_PCM_WRITE_CHANNELS: - sound_fsync(inode, file); + sound_fsync(file, file->f_dentry); IOCTL_IN(arg, data); return(IOCTL_OUT(arg, sound_set_stereo(data-1)+1)); case SNDCTL_DSP_SETFMT: - sound_fsync(inode, file); + sound_fsync(file, file->f_dentry); IOCTL_IN(arg, data); return(IOCTL_OUT(arg, sound_set_format(data))); case SNDCTL_DSP_GETFMTS: diff -u --recursive --new-file v2.1.55/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c --- v2.1.55/linux/drivers/sound/soundcard.c Thu Jul 17 10:06:06 1997 +++ linux/drivers/sound/soundcard.c Sat Sep 13 11:07:28 1997 @@ -80,8 +80,7 @@ return sound_write_sw (dev, &files[dev], buf, count); } -static long long -sound_lseek (struct inode *inode, struct file *file, long long offset, int orig) +static long long sound_lseek (struct file *file, long long offset, int orig) { return -EPERM; } @@ -256,13 +255,13 @@ } static int -sound_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma) +sound_mmap (struct file *file, struct vm_area_struct *vma) { int dev, dev_class; unsigned long size; struct dma_buffparms *dmap = NULL; - dev = MINOR (inode->i_rdev); + dev = MINOR (file->f_dentry->d_inode->i_rdev); files[dev].flags = file->f_flags; diff -u --recursive --new-file v2.1.55/linux/fs/binfmt_aout.c linux/fs/binfmt_aout.c --- v2.1.55/linux/fs/binfmt_aout.c Sun Sep 7 13:10:43 1997 +++ linux/fs/binfmt_aout.c Sat Sep 13 11:07:28 1997 @@ -62,7 +62,7 @@ #define DUMP_SEEK(offset) \ if (file.f_op->llseek) { \ - if (file.f_op->llseek(inode,&file,(offset),0) != (offset)) \ + if (file.f_op->llseek(&file,(offset),0) != (offset)) \ goto close_coredump; \ } else file.f_pos = (offset) @@ -492,7 +492,7 @@ /* Seek into the file */ if (file->f_op->llseek) { - if ((error = file->f_op->llseek(inode, file, 0, 0)) != 0) + if ((error = file->f_op->llseek(file, 0, 0)) != 0) return -ENOEXEC; } else file->f_pos = 0; diff -u --recursive --new-file v2.1.55/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c --- v2.1.55/linux/fs/binfmt_elf.c Sun Sep 7 13:10:43 1997 +++ linux/fs/binfmt_elf.c Sat Sep 13 11:07:28 1997 @@ -815,7 +815,7 @@ /* seek to the beginning of the file */ if (file->f_op->llseek) { - if ((error = file->f_op->llseek(inode, file, 0, 0)) != 0) + if ((error = file->f_op->llseek(file, 0, 0)) != 0) return -ENOEXEC; } else file->f_pos = 0; @@ -924,7 +924,7 @@ static int dump_seek(struct file *file, off_t off) { if (file->f_op->llseek) { - if (file->f_op->llseek(file->f_dentry->d_inode, file, off, 0) != off) + if (file->f_op->llseek(file, off, 0) != off) return 0; } else file->f_pos = off; diff -u --recursive --new-file v2.1.55/linux/fs/block_dev.c linux/fs/block_dev.c --- v2.1.55/linux/fs/block_dev.c Sun Dec 29 00:10:46 1996 +++ linux/fs/block_dev.c Sat Sep 13 11:07:28 1997 @@ -287,7 +287,12 @@ return read; } -int block_fsync(struct inode *inode, struct file *filp) +/* + * Filp may be NULL when we are called by an msync of a vma + * since the vma has no handle. + */ + +int block_fsync(struct file *filp, struct dentry *dentry) { - return fsync_dev (inode->i_rdev); + return fsync_dev(dentry->d_inode->i_rdev); } diff -u --recursive --new-file v2.1.55/linux/fs/buffer.c linux/fs/buffer.c --- v2.1.55/linux/fs/buffer.c Wed Sep 3 20:52:43 1997 +++ linux/fs/buffer.c Sat Sep 13 11:07:28 1997 @@ -282,9 +282,13 @@ return 0; } -int file_fsync (struct inode *inode, struct file *filp) +/* + * filp may be NULL if called via the msync of a vma. + */ + +int file_fsync(struct file *filp, struct dentry *dentry) { - return fsync_dev(inode->i_dev); + return fsync_dev(dentry->d_inode->i_dev); } asmlinkage int sys_fsync(unsigned int fd) @@ -316,7 +320,7 @@ if (!file->f_op || !file->f_op->fsync) goto out; - err = file->f_op->fsync(inode,file); + err = file->f_op->fsync(file, file->f_dentry); out: unlock_kernel(); @@ -353,7 +357,7 @@ goto out; /* this needs further work, at the moment it is identical to fsync() */ - err = file->f_op->fsync(inode,file); + err = file->f_op->fsync(file, file->f_dentry); out: unlock_kernel(); diff -u --recursive --new-file v2.1.55/linux/fs/dcache.c linux/fs/dcache.c --- v2.1.55/linux/fs/dcache.c Sun Sep 7 13:10:43 1997 +++ linux/fs/dcache.c Sat Sep 13 12:09:32 1997 @@ -119,7 +119,7 @@ * something (at which point we need to unuse * all dentries). */ -void shrink_dcache(void) +void prune_dcache(int count) { for (;;) { struct dentry *dentry; @@ -143,6 +143,8 @@ parent = dentry->d_parent; d_free(dentry); dput(parent); + if (!--count) + break; } } } @@ -211,8 +213,10 @@ if (root_inode) { res = d_alloc(NULL, &(const struct qstr) { "/", 1, 0 }); - res->d_parent = res; - d_instantiate(res, root_inode); + if (res) { + res->d_parent = res; + d_instantiate(res, root_inode); + } } return res; } @@ -344,7 +348,7 @@ x = y; y = __tmp; } while (0) /* - * We cannibalize "newdentry" when moving dentry on top of it, + * We cannibalize "target" when moving dentry on top of it, * because it's going to be thrown away anyway. We could be more * polite about it, though. * diff -u --recursive --new-file v2.1.55/linux/fs/exec.c linux/fs/exec.c --- v2.1.55/linux/fs/exec.c Wed Sep 3 20:52:43 1997 +++ linux/fs/exec.c Sat Sep 13 11:07:28 1997 @@ -365,7 +365,7 @@ if (!file.f_op->read) goto close_readexec; if (file.f_op->llseek) { - if (file.f_op->llseek(inode,&file,offset,0) != offset) + if (file.f_op->llseek(&file,offset,0) != offset) goto close_readexec; } else file.f_pos = offset; diff -u --recursive --new-file v2.1.55/linux/fs/ext2/file.c linux/fs/ext2/file.c --- v2.1.55/linux/fs/ext2/file.c Thu Jul 17 10:06:06 1997 +++ linux/fs/ext2/file.c Sat Sep 13 11:07:28 1997 @@ -36,7 +36,7 @@ #include #include -static long long ext2_file_lseek(struct inode *, struct file *, long long, int); +static long long ext2_file_lseek(struct file *, long long, int); static long ext2_file_write (struct inode *, struct file *, const char *, unsigned long); static int ext2_release_file (struct inode *, struct file *); @@ -84,12 +84,13 @@ /* * Make sure the offset never goes beyond the 32-bit mark.. */ -static long long ext2_file_lseek(struct inode *inode, +static long long ext2_file_lseek( struct file *file, long long offset, int origin) { long long retval; + struct inode *inode = file->f_dentry->d_inode; switch (origin) { case 2: diff -u --recursive --new-file v2.1.55/linux/fs/ext2/fsync.c linux/fs/ext2/fsync.c --- v2.1.55/linux/fs/ext2/fsync.c Fri Apr 4 08:52:24 1997 +++ linux/fs/ext2/fsync.c Sat Sep 13 11:07:28 1997 @@ -284,9 +284,15 @@ return err; } -int ext2_sync_file (struct inode * inode, struct file * file) +/* + * File may be NULL when we are called. Perhaps we shouldn't + * even pass file to fsync ? + */ + +int ext2_sync_file(struct file * file, struct dentry *dentry) { int wait, err = 0; + struct inode *inode = dentry->d_inode; if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) diff -u --recursive --new-file v2.1.55/linux/fs/fat/mmap.c linux/fs/fat/mmap.c --- v2.1.55/linux/fs/fat/mmap.c Thu Jul 17 10:06:07 1997 +++ linux/fs/fat/mmap.c Sat Sep 13 11:07:28 1997 @@ -91,8 +91,10 @@ * This is used for a general mmap of an msdos file * Returns 0 if ok, or a negative error code if not. */ -int fat_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma) +int fat_mmap(struct file * file, struct vm_area_struct * vma) { + struct inode *inode = file->f_dentry->d_inode; + if (vma->vm_flags & VM_SHARED) /* only PAGE_COW or read-only supported now */ return -EINVAL; if (vma->vm_offset & (inode->i_sb->s_blocksize - 1)) diff -u --recursive --new-file v2.1.55/linux/fs/fcntl.c linux/fs/fcntl.c --- v2.1.55/linux/fs/fcntl.c Thu Jul 17 10:06:07 1997 +++ linux/fs/fcntl.c Sat Sep 13 11:07:28 1997 @@ -83,7 +83,7 @@ /* Did FASYNC state change? */ if ((arg ^ filp->f_flags) & FASYNC) { if (filp->f_op->fasync) - filp->f_op->fasync(inode, filp, (arg & FASYNC) != 0); + filp->f_op->fasync(filp, (arg & FASYNC) != 0); } /* required for strict SunOS emulation */ diff -u --recursive --new-file v2.1.55/linux/fs/inode.c linux/fs/inode.c --- v2.1.55/linux/fs/inode.c Thu Sep 11 09:02:23 1997 +++ linux/fs/inode.c Sat Sep 13 12:08:28 1997 @@ -125,33 +125,6 @@ sema_init(&inode->i_sem, 1); } - -/* - * Look out! This returns with the inode lock held if - * it got an inode.. - */ -static struct inode * grow_inodes(void) -{ - struct inode * inode = (struct inode *)__get_free_page(GFP_KERNEL); - - if (inode) { - int size; - struct inode * tmp; - - spin_lock(&inode_lock); - size = PAGE_SIZE - 2*sizeof(struct inode); - tmp = inode; - do { - tmp++; - init_once(tmp); - list_add(&tmp->i_list, &inode_unused); - size -= sizeof(struct inode); - } while (size >= 0); - init_once(inode); - } - return inode; -} - static inline void write_inode(struct inode *inode) { if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->write_inode) @@ -238,7 +211,8 @@ */ void clear_inode(struct inode *inode) { - truncate_inode_pages(inode, 0); + if (inode->i_nrpages) + truncate_inode_pages(inode, 0); wait_on_inode(inode); if (IS_WRITABLE(inode) && inode->i_sb && inode->i_sb->dq_op) inode->i_sb->dq_op->drop(inode); @@ -253,6 +227,7 @@ static void dispose_list(struct list_head * head) { struct list_head *next; + int count = 0; next = head->next; for (;;) { @@ -263,12 +238,14 @@ if (tmp == head) break; inode = list_entry(tmp, struct inode, i_list); - truncate_inode_pages(inode, 0); + clear_inode(inode); + count++; } /* Add them all to the unused list in one fell swoop */ spin_lock(&inode_lock); list_splice(head, &inode_unused); + inodes_stat.nr_free_inodes += count; spin_unlock(&inode_lock); } @@ -326,25 +303,25 @@ } /* - * This is called with the inode lock held. It just looks at the last - * inode on the in-use list, and if the inode is trivially freeable - * we just move it to the unused list. - * - * Otherwise we just move the inode to be the first inode and expect to - * get back to the problem later.. + * This is called with the inode lock held. It searches + * the in-use for the specified number of freeable inodes. + * Freeable inodes are moved to a temporary list and then + * placed on the unused list by dispose_list. + * + * N.B. The spinlock is released to call dispose_list. */ #define CAN_UNUSE(inode) \ (((inode)->i_count == 0) && \ - ((inode)->i_nrpages == 0) && \ (!(inode)->i_state)) -static void try_to_free_inodes(void) +static void try_to_free_inodes(int goal) { struct list_head * tmp; struct list_head *head = &inode_in_use; + LIST_HEAD(freeable); + int found = 0, search = goal << 1; - tmp = head->prev; - if (tmp != head) { + while ((tmp = head->prev) != head && search--) { struct inode * inode; list_del(tmp); @@ -352,13 +329,81 @@ if (CAN_UNUSE(inode)) { list_del(&inode->i_hash); INIT_LIST_HEAD(&inode->i_hash); - head = &inode_unused; + list_add(tmp, &freeable); + if (++found < goal) + continue; + break; } list_add(tmp, head); } + /* + * If we didn't free any inodes, do a limited + * pruning of the dcache to help the next time. + */ + spin_unlock(&inode_lock); + if (found) + dispose_list(&freeable); + else + prune_dcache(goal); + spin_lock(&inode_lock); +} + +/* + * This is called with the spinlock held, but releases + * the lock when freeing or allocating inodes. + * Look out! This returns with the inode lock held if + * it got an inode.. + */ +static struct inode * grow_inodes(void) +{ + struct inode * inode; + + /* + * Check whether to shrink the dcache ... if we've + * allocated more than half of the nominal maximum, + * try shrinking before allocating more. + */ + if (inodes_stat.nr_inodes >= (max_inodes >> 1)) { + struct list_head * tmp; + + spin_unlock(&inode_lock); + prune_dcache(128); + spin_lock(&inode_lock); + try_to_free_inodes(128); + tmp = inode_unused.next; + if (tmp != &inode_unused) { + inodes_stat.nr_free_inodes--; + list_del(tmp); + inode = list_entry(tmp, struct inode, i_list); + return inode; + } + } + + spin_unlock(&inode_lock); + inode = (struct inode *)__get_free_page(GFP_KERNEL); + if (inode) { + int size; + struct inode * tmp; + + spin_lock(&inode_lock); + size = PAGE_SIZE - 2*sizeof(struct inode); + tmp = inode; + do { + tmp++; + init_once(tmp); + list_add(&tmp->i_list, &inode_unused); + inodes_stat.nr_free_inodes++; + size -= sizeof(struct inode); + } while (size >= 0); + init_once(inode); + inodes_stat.nr_inodes += PAGE_SIZE / sizeof(struct inode); + } + return inode; } - +/* + * Called with the inode lock held. + */ static struct inode * find_inode(struct super_block * sb, unsigned long ino, struct list_head *head) { struct list_head *tmp; @@ -416,17 +461,22 @@ struct list_head * tmp; spin_lock(&inode_lock); - try_to_free_inodes(); + /* + * Check whether to restock the unused list. + */ + if (inodes_stat.nr_free_inodes < 16) + try_to_free_inodes(8); tmp = inode_unused.next; if (tmp != &inode_unused) { list_del(tmp); + inodes_stat.nr_free_inodes--; inode = list_entry(tmp, struct inode, i_list); add_new_inode: + list_add(&inode->i_list, &inode_in_use); inode->i_sb = NULL; inode->i_dev = 0; inode->i_ino = ++last_ino; inode->i_count = 1; - list_add(&inode->i_list, &inode_in_use); inode->i_state = 0; spin_unlock(&inode_lock); clean_inode(inode); @@ -437,7 +487,6 @@ * Warning: if this succeeded, we will now * return with the inode lock. */ - spin_unlock(&inode_lock); inode = grow_inodes(); if (inode) goto add_new_inode; @@ -455,6 +504,7 @@ if (tmp != &inode_unused) { list_del(tmp); + inodes_stat.nr_free_inodes--; inode = list_entry(tmp, struct inode, i_list); add_new_inode: list_add(&inode->i_list, &inode_in_use); @@ -477,20 +527,18 @@ * state of the inode when it is locked, as we * just created it (so there can be no old holders * that haven't tested I_LOCK). - * - * Verify this some day! */ inode->i_state &= ~I_LOCK; + wake_up(&inode->i_wait); return inode; } /* - * Uhhuh.. We need to expand. Unlock for the allocation, - * but note that "grow_inodes()" will return with the - * lock held again if the allocation succeeded. + * Uhhuh.. We need to expand. Note that "grow_inodes()" will + * release the spinlock, but will return with the lock held + * again if the allocation succeeded. */ - spin_unlock(&inode_lock); inode = grow_inodes(); if (inode) { /* We released the lock, so.. */ @@ -498,6 +546,7 @@ if (!old) goto add_new_inode; list_add(&inode->i_list, &inode_unused); + inodes_stat.nr_free_inodes++; spin_unlock(&inode_lock); wait_on_inode(old); return old; @@ -518,14 +567,25 @@ struct inode * inode; spin_lock(&inode_lock); + if (!inodes_stat.nr_free_inodes) + goto restock; +search: inode = find_inode(sb, ino, head); if (!inode) { - try_to_free_inodes(); return get_new_inode(sb, ino, head); } spin_unlock(&inode_lock); wait_on_inode(inode); return inode; + + /* + * We restock the freelist before calling find, + * in order to avoid repeating the search. + * (The unused list usually won't be empty.) + */ +restock: + try_to_free_inodes(8); + goto search; } void insert_inode_hash(struct inode *inode) @@ -560,8 +620,17 @@ } if (list_empty(&inode->i_hash)) { list_del(&inode->i_list); + INIT_LIST_HEAD(&inode->i_list); + spin_unlock(&inode_lock); + clear_inode(inode); + spin_lock(&inode_lock); list_add(&inode->i_list, &inode_unused); + inodes_stat.nr_free_inodes++; } + } + if (inode->i_count > (1<<15)) { + printk("iput: device %s inode %ld count wrapped\n", + kdevname(inode->i_dev), inode->i_ino); } spin_unlock(&inode_lock); } diff -u --recursive --new-file v2.1.55/linux/fs/locks.c linux/fs/locks.c --- v2.1.55/linux/fs/locks.c Thu Jul 17 10:06:07 1997 +++ linux/fs/locks.c Sat Sep 13 11:07:28 1997 @@ -322,7 +322,7 @@ return -EINVAL; if (filp->f_op->lock) { - error = filp->f_op->lock(inode, filp, F_GETLK, &file_lock); + error = filp->f_op->lock(filp, F_GETLK, &file_lock); if (error < 0) return error; fl = &file_lock; @@ -420,7 +420,7 @@ } if (filp->f_op->lock != NULL) { - error = filp->f_op->lock(inode, filp, cmd, &file_lock); + error = filp->f_op->lock(filp, cmd, &file_lock); if (error < 0) return (error); } @@ -451,7 +451,7 @@ locks_delete_lock(before, 0); if (filp->f_op->lock) { file_lock.fl_type = F_UNLCK; - filp->f_op->lock(inode, filp, F_SETLK, &file_lock); + filp->f_op->lock(filp, F_SETLK, &file_lock); /* List may have changed: */ before = &inode->i_flock; } diff -u --recursive --new-file v2.1.55/linux/fs/minix/fsync.c linux/fs/minix/fsync.c --- v2.1.55/linux/fs/minix/fsync.c Mon Oct 28 04:29:26 1996 +++ linux/fs/minix/fsync.c Sat Sep 13 11:07:28 1997 @@ -328,10 +328,14 @@ } /* - * The function which is called for file synchronization. + * The function which is called for file synchronization. File may be + * NULL */ -int minix_sync_file(struct inode * inode, struct file * file) + +int minix_sync_file(struct file * file, struct dentry *dentry) { + struct inode *inode = dentry->d_inode; + if (INODE_VERSION(inode) == MINIX_V1) return V1_minix_sync_file(inode, file); else diff -u --recursive --new-file v2.1.55/linux/fs/ncpfs/file.c linux/fs/ncpfs/file.c --- v2.1.55/linux/fs/ncpfs/file.c Mon Aug 18 18:19:46 1997 +++ linux/fs/ncpfs/file.c Sat Sep 13 11:07:28 1997 @@ -24,7 +24,7 @@ return a < b ? a : b; } -static int ncp_fsync(struct inode *inode, struct file *file) +static int ncp_fsync(struct file *file, struct dentry *dentry) { return 0; } diff -u --recursive --new-file v2.1.55/linux/fs/ncpfs/mmap.c linux/fs/ncpfs/mmap.c --- v2.1.55/linux/fs/ncpfs/mmap.c Thu Sep 11 09:02:23 1997 +++ linux/fs/ncpfs/mmap.c Sat Sep 13 11:07:28 1997 @@ -116,8 +116,10 @@ /* This is used for a general mmap of a ncp file */ -int ncp_mmap(struct inode *inode, struct file *file, struct vm_area_struct *vma) +int ncp_mmap(struct file *file, struct vm_area_struct *vma) { + struct inode *inode = file->f_dentry->d_inode; + DPRINTK("ncp_mmap: called\n"); if (!ncp_conn_valid(NCP_SERVER(inode))) { diff -u --recursive --new-file v2.1.55/linux/fs/nfs/file.c linux/fs/nfs/file.c --- v2.1.55/linux/fs/nfs/file.c Thu Jul 17 10:06:07 1997 +++ linux/fs/nfs/file.c Sat Sep 13 11:07:28 1997 @@ -32,13 +32,12 @@ #define NFSDBG_FACILITY NFSDBG_FILE -static int nfs_file_mmap(struct inode *, struct file *, - struct vm_area_struct *); +static int nfs_file_mmap(struct file *, struct vm_area_struct *); static long nfs_file_read(struct inode *, struct file *, char *, unsigned long); static long nfs_file_write(struct inode *, struct file *, const char *, unsigned long); static int nfs_file_close(struct inode *, struct file *); -static int nfs_fsync(struct inode *, struct file *); +static int nfs_fsync(struct file *, struct dentry *dentry); static struct file_operations nfs_file_operations = { NULL, /* lseek - default */ @@ -114,20 +113,21 @@ } static int -nfs_file_mmap(struct inode * inode, struct file * file, - struct vm_area_struct * vma) +nfs_file_mmap(struct file * file, struct vm_area_struct * vma) { int status; + struct inode *inode = file->f_dentry->d_inode; dfprintk(VFS, "nfs: mmap(%x/%ld)\n", inode->i_dev, inode->i_ino); if ((status = nfs_revalidate_inode(NFS_SERVER(inode), inode)) < 0) return status; - return generic_file_mmap(inode, file, vma); + return generic_file_mmap(file, vma); } -static int nfs_fsync(struct inode *inode, struct file *file) +static int nfs_fsync(struct file *file, struct dentry *dentry) { + struct inode *inode = dentry->d_inode; dfprintk(VFS, "nfs: fsync(%x/%ld)\n", inode->i_dev, inode->i_ino); return nfs_flush_dirty_pages(inode, 0, 0); @@ -175,9 +175,10 @@ * Lock a (portion of) a file */ int -nfs_lock(struct inode *inode, struct file *filp, int cmd, struct file_lock *fl) +nfs_lock(struct file *filp, int cmd, struct file_lock *fl) { int status; + struct inode * inode; dprintk("NFS: nfs_lock(f=%4x/%ld, t=%x, fl=%x, r=%ld:%ld)\n", filp->f_dentry->d_inode->i_dev, filp->f_dentry->d_inode->i_ino, diff -u --recursive --new-file v2.1.55/linux/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c --- v2.1.55/linux/fs/nfsd/vfs.c Thu Sep 11 09:02:23 1997 +++ linux/fs/nfsd/vfs.c Sat Sep 13 11:07:28 1997 @@ -294,7 +294,7 @@ void nfsd_sync(struct inode *inode, struct file *filp) { - filp->f_op->fsync(inode, filp); + filp->f_op->fsync(filp, filp->f_dentry); } /* @@ -928,7 +928,8 @@ file.f_inode->i_dev, file.f_inode->i_ino, (int) file.f_pos, (int) oldlen, (int) cd.buflen); */ - err = file.f_op->readdir(&file, &cd, (filldir_t) func); + err = file.f_op->readdir(&file, + &cd, (filldir_t) func); if (err < 0) { nfsd_close(&file); diff -u --recursive --new-file v2.1.55/linux/fs/open.c linux/fs/open.c --- v2.1.55/linux/fs/open.c Mon Aug 18 18:19:46 1997 +++ linux/fs/open.c Sat Sep 13 11:07:28 1997 @@ -717,7 +717,7 @@ struct inode * inode = dentry->d_inode; if (filp->f_op && filp->f_op->release) - error = filp->f_op->release(inode,filp); + error = filp->f_op->release(inode, filp); filp->f_dentry = NULL; if (filp->f_mode & FMODE_WRITE) put_write_access(inode); diff -u --recursive --new-file v2.1.55/linux/fs/pipe.c linux/fs/pipe.c --- v2.1.55/linux/fs/pipe.c Thu Sep 11 09:02:24 1997 +++ linux/fs/pipe.c Sat Sep 13 11:07:28 1997 @@ -133,8 +133,7 @@ return written; } -static long long pipe_lseek(struct inode * inode, struct file * file, - long long offset, int orig) +static long long pipe_lseek(struct file * file, long long offset, int orig) { return -ESPIPE; } diff -u --recursive --new-file v2.1.55/linux/fs/proc/generic.c linux/fs/proc/generic.c --- v2.1.55/linux/fs/proc/generic.c Mon Jul 7 13:07:09 1997 +++ linux/fs/proc/generic.c Sat Sep 13 11:07:28 1997 @@ -20,8 +20,7 @@ char * buf, unsigned long nbytes); static long proc_file_write(struct inode * inode, struct file * file, const char * buffer, unsigned long count); -static long long proc_file_lseek(struct inode * inode, struct file * file, - long long offset, int orig); +static long long proc_file_lseek(struct file * file, long long offset, int orig); int proc_match(int len, const char *name,struct proc_dir_entry * de) { @@ -190,8 +189,7 @@ } -static long long proc_file_lseek(struct inode * inode, struct file * file, - long long offset, int orig) +static long long proc_file_lseek(struct file * file, long long offset, int orig) { switch (orig) { case 0: diff -u --recursive --new-file v2.1.55/linux/fs/proc/mem.c linux/fs/proc/mem.c --- v2.1.55/linux/fs/proc/mem.c Sat Jul 5 20:53:22 1997 +++ linux/fs/proc/mem.c Sat Sep 13 11:07:28 1997 @@ -187,8 +187,7 @@ #endif -static long long mem_lseek(struct inode * inode, struct file * file, - long long offset, int orig) +static long long mem_lseek(struct file * file, long long offset, int orig) { switch (orig) { case 0: @@ -205,8 +204,7 @@ /* * This isn't really reliable by any means.. */ -int mem_mmap(struct inode * inode, struct file * file, - struct vm_area_struct * vma) +int mem_mmap(struct file * file, struct vm_area_struct * vma) { struct task_struct *tsk; pgd_t *src_dir, *dest_dir; @@ -214,7 +212,8 @@ pte_t *src_table, *dest_table; unsigned long stmp, dtmp; struct vm_area_struct *src_vma = NULL; - + struct inode *inode = file->f_dentry->d_inode; + /* Get the source's task information */ tsk = get_task(inode->i_ino >> 16); diff -u --recursive --new-file v2.1.55/linux/fs/proc/scsi.c linux/fs/proc/scsi.c --- v2.1.55/linux/fs/proc/scsi.c Sat Jul 5 20:53:22 1997 +++ linux/fs/proc/scsi.c Sat Sep 13 11:07:28 1997 @@ -33,7 +33,7 @@ char * buf, unsigned long count); static long proc_writescsi(struct inode * inode, struct file * file, const char * buf, unsigned long count); -static long long proc_scsilseek(struct inode *, struct file *, long long, int); +static long long proc_scsilseek(struct file *, long long, int); extern void build_proc_dir_hba_entries(uint); @@ -177,8 +177,7 @@ } -static long long proc_scsilseek(struct inode * inode, struct file * file, - long long offset, int orig) +static long long proc_scsilseek(struct file * file, long long offset, int orig) { switch (orig) { case 0: diff -u --recursive --new-file v2.1.55/linux/fs/read_write.c linux/fs/read_write.c --- v2.1.55/linux/fs/read_write.c Mon Aug 18 18:19:46 1997 +++ linux/fs/read_write.c Sat Sep 13 11:07:29 1997 @@ -19,16 +19,13 @@ #include -static long long default_llseek(struct inode *inode, - struct file *file, - long long offset, - int origin) +static long long default_llseek(struct file *file, long long offset, int origin) { long long retval; switch (origin) { case 2: - offset += inode->i_size; + offset += file->f_dentry->d_inode->i_size; break; case 1: offset += file->f_pos; @@ -45,15 +42,14 @@ return retval; } -static inline long long llseek(struct inode * inode, struct file *file, - long long offset, unsigned int origin) +static inline long long llseek(struct file *file, long long offset, unsigned int origin) { - long long (*fn)(struct inode *, struct file *, long long, int); + long long (*fn)(struct file *, long long, int); fn = default_llseek; if (file->f_op && file->f_op->llseek) fn = file->f_op->llseek; - return fn(inode, file, offset, origin); + return fn(file, offset, origin); } asmlinkage long sys_lseek(unsigned int fd, off_t offset, unsigned int origin) @@ -73,7 +69,7 @@ retval = -EINVAL; if (origin > 2) goto bad; - retval = llseek(inode, file, offset, origin); + retval = llseek(file, offset, origin); bad: unlock_kernel(); return retval; @@ -100,8 +96,7 @@ if (origin > 2) goto bad; - offset = llseek(inode, file, - (((unsigned long long) offset_high << 32) | offset_low), + offset = llseek(file, (((unsigned long long) offset_high << 32) | offset_low), origin); retval = offset; diff -u --recursive --new-file v2.1.55/linux/fs/smbfs/file.c linux/fs/smbfs/file.c --- v2.1.55/linux/fs/smbfs/file.c Wed Sep 3 20:52:43 1997 +++ linux/fs/smbfs/file.c Sat Sep 13 11:07:29 1997 @@ -25,8 +25,7 @@ return a < b ? a : b; } -static int -smb_fsync(struct inode *inode, struct file *file) +static int smb_fsync(struct file *file, struct dentry *dir) { return 0; } @@ -182,16 +181,16 @@ } static int -smb_file_mmap(struct inode * inode, struct file * file, - struct vm_area_struct * vma) +smb_file_mmap(struct file * file, struct vm_area_struct * vma) { int status; + struct inode * inode = file->f_dentry->d_inode; status = smb_revalidate_inode(inode); if (status < 0) return status; - return generic_file_mmap(inode, file, vma); + return generic_file_mmap(file, vma); } /* diff -u --recursive --new-file v2.1.55/linux/fs/smbfs/proc.c linux/fs/smbfs/proc.c --- v2.1.55/linux/fs/smbfs/proc.c Thu Sep 11 09:02:24 1997 +++ linux/fs/smbfs/proc.c Sat Sep 13 11:07:29 1997 @@ -5,6 +5,7 @@ * Copyright (C) 1997 by Volker Lendecke * * 28/06/96 - Fixed long file name support (smb_proc_readdir_long) by Yuri Per + * 04/09/97 - Fixed smb_d_path to be non-recursive by Riccardo Facchetti */ #include @@ -16,6 +17,7 @@ #include #include #include +#include #include #include @@ -79,22 +81,36 @@ return p + 4; } -static int smb_d_path(struct dentry * entry, char * buf) +static int smb_d_path(struct dentry * entry, char * buffer) { - if (IS_ROOT(entry)) { - *buf = '\\'; - return 1; - } else { - int len = smb_d_path(entry->d_parent, buf); - - buf += len; - if (len > 1) { - *buf++ = '\\'; - len++; - } - memcpy(buf, entry->d_name.name, entry->d_name.len); - return len + entry->d_name.len; + char *page, *path, *buf = buffer; + int len = 0; + + page = (char *) __get_free_page(GFP_KERNEL); + + /* + * Get the path + */ + path = d_path(entry, page, PAGE_SIZE); + + /* + * path is a string with a trailing '\0' + */ + len = strlen(path); + + /* + * Now encode it the DOSish way and copy it to the + * output buffer. No need to terminate output buffer + * with a trailing '\0'. + */ + while (*path) { + *buf++ = ((*path != '/') ? *path : '\\'); + path++; } + + free_page((unsigned long) page); + + return len; } static char *smb_encode_path(struct smb_sb_info *server, char *buf, @@ -112,6 +128,15 @@ *buf++ = 0; } + /* + * XXX smb_d_path don't put the trailing '\0' in the buf. + * The problem may arise when (dir != NULL && name == NULL && + * server->opt.protocol <= SMB_PROTOCOL_COREPLUS)) + * because str_upper() rely on trailing '\0' for converting the + * start to upper chars. I don't know samba, so I suspect a bug but I + * don't want to do something stupid here. + * -Riccardo + */ if (server->opt.protocol <= SMB_PROTOCOL_COREPLUS) str_upper(start); diff -u --recursive --new-file v2.1.55/linux/fs/sysv/fsync.c linux/fs/sysv/fsync.c --- v2.1.55/linux/fs/sysv/fsync.c Sun Nov 26 09:23:10 1995 +++ linux/fs/sysv/fsync.c Sat Sep 13 11:07:29 1997 @@ -178,9 +178,10 @@ return err; } -int sysv_sync_file(struct inode * inode, struct file * file) +int sysv_sync_file(struct file * file, struct dentry *dentry) { int wait, err = 0; + struct inode *inode = dentry->d_inode; if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) diff -u --recursive --new-file v2.1.55/linux/include/linux/atalk.h linux/include/linux/atalk.h --- v2.1.55/linux/include/linux/atalk.h Mon Jul 7 16:02:46 1997 +++ linux/include/linux/atalk.h Sat Sep 13 11:07:29 1997 @@ -16,6 +16,7 @@ #define ATADDR_ANYPORT (__u8)0 #define ATADDR_BCAST (__u8)255 #define DDP_MAXSZ 587 +#define DDP_MAXHOPS 15 /* 4 bits of hop counter */ #define SIOCATALKDIFADDR (SIOCPROTOPRIVATE + 0) @@ -70,8 +71,6 @@ unsigned char src_port; }; -#define DDP_MAXHOPS 15 /* 4 bits of hop counter */ - #ifdef __KERNEL__ #include @@ -154,11 +153,14 @@ } extern struct at_addr *atalk_find_dev_addr(struct device *dev); +extern struct device *atrtr_get_dev(struct at_addr *sa); extern int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr); extern void aarp_send_probe(struct device *dev, struct at_addr *addr); + #ifdef MODULE +extern void aarp_device_down(struct device *dev); extern void aarp_cleanup_module(void); -#endif +#endif /* MODULE */ -#endif -#endif +#endif /* __KERNEL__ */ +#endif /* __LINUX_ATALK_H__ */ diff -u --recursive --new-file v2.1.55/linux/include/linux/dcache.h linux/include/linux/dcache.h --- v2.1.55/linux/include/linux/dcache.h Wed Sep 3 20:52:44 1997 +++ linux/include/linux/dcache.h Thu Sep 11 09:17:19 1997 @@ -102,8 +102,10 @@ /* allocate/de-allocate */ extern struct dentry * d_alloc(struct dentry * parent, const struct qstr *name); -extern void shrink_dcache(void); +extern void prune_dcache(int); extern int d_invalidate(struct dentry *); + +#define shrink_dcache() prune_dcache(0) /* only used at mount-time */ extern struct dentry * d_alloc_root(struct inode * root_inode, struct dentry * old_root); diff -u --recursive --new-file v2.1.55/linux/include/linux/ext2_fs.h linux/include/linux/ext2_fs.h --- v2.1.55/linux/include/linux/ext2_fs.h Thu Jul 17 10:06:08 1997 +++ linux/include/linux/ext2_fs.h Sat Sep 13 11:07:29 1997 @@ -465,7 +465,7 @@ extern int ext2_write (struct inode *, struct file *, char *, int); /* fsync.c */ -extern int ext2_sync_file (struct inode *, struct file *); +extern int ext2_sync_file (struct file *, struct dentry *); /* ialloc.c */ extern struct inode * ext2_new_inode (const struct inode *, int, int *); diff -u --recursive --new-file v2.1.55/linux/include/linux/fs.h linux/include/linux/fs.h --- v2.1.55/linux/include/linux/fs.h Thu Sep 11 09:02:24 1997 +++ linux/include/linux/fs.h Sat Sep 13 11:44:43 1997 @@ -469,7 +469,7 @@ #define FASYNC_MAGIC 0x4601 -extern int fasync_helper(struct inode *, struct file *, int, struct fasync_struct **); +extern int fasync_helper(struct file *, int, struct fasync_struct **); #include #include @@ -529,20 +529,20 @@ typedef int (*filldir_t)(void *, const char *, int, off_t, ino_t); struct file_operations { - long long (*llseek) (struct inode *, struct file *, long long, int); + long long (*llseek) (struct file *, long long, int); long (*read) (struct inode *, struct file *, char *, unsigned long); long (*write) (struct inode *, struct file *, const char *, unsigned long); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, poll_table *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); - int (*mmap) (struct inode *, struct file *, struct vm_area_struct *); + int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*release) (struct inode *, struct file *); - int (*fsync) (struct inode *, struct file *); - int (*fasync) (struct inode *, struct file *, int); + int (*fsync) (struct file *, struct dentry *); + int (*fasync) (struct file *, int); int (*check_media_change) (kdev_t dev); int (*revalidate) (kdev_t dev); - int (*lock) (struct inode *, struct file *, int, struct file_lock *); + int (*lock) (struct file *, int, struct file_lock *); }; struct inode_operations { @@ -783,7 +783,7 @@ extern int brw_page(int, struct page *, kdev_t, int [], int, int); extern int generic_readpage(struct inode *, struct page *); -extern int generic_file_mmap(struct inode *, struct file *, struct vm_area_struct *); +extern int generic_file_mmap(struct file *, struct vm_area_struct *); extern long generic_file_read(struct inode *, struct file *, char *, unsigned long); extern long generic_file_write(struct inode *, struct file *, const char *, unsigned long); @@ -808,8 +808,8 @@ extern long char_write(struct inode *, struct file *, const char *, unsigned long); extern long block_write(struct inode *, struct file *, const char *, unsigned long); -extern int block_fsync(struct inode *, struct file *); -extern int file_fsync(struct inode *, struct file *); +extern int block_fsync(struct file *, struct dentry *dir); +extern int file_fsync(struct file *, struct dentry *dir); extern void dcache_add(struct inode *, const char *, int, unsigned long); extern int dcache_lookup(struct inode *, const char *, int, unsigned long *); diff -u --recursive --new-file v2.1.55/linux/include/linux/msdos_fs.h linux/include/linux/msdos_fs.h --- v2.1.55/linux/include/linux/msdos_fs.h Thu Sep 11 09:02:24 1997 +++ linux/include/linux/msdos_fs.h Sat Sep 13 11:07:29 1997 @@ -232,7 +232,7 @@ extern void fat_truncate(struct inode *inode); /* mmap.c */ -extern int fat_mmap(struct inode *, struct file *, struct vm_area_struct *); +extern int fat_mmap(struct file *, struct vm_area_struct *); /* vfat.c */ diff -u --recursive --new-file v2.1.55/linux/include/linux/ncp_fs.h linux/include/linux/ncp_fs.h --- v2.1.55/linux/include/linux/ncp_fs.h Mon Jul 7 16:03:54 1997 +++ linux/include/linux/ncp_fs.h Sat Sep 13 11:07:29 1997 @@ -150,7 +150,7 @@ void ncp_unlock_server(struct ncp_server *server); /* linux/fs/ncpfs/mmap.c */ -int ncp_mmap(struct inode *inode, struct file *file, struct vm_area_struct *vma); +int ncp_mmap(struct file *file, struct vm_area_struct *vma); #endif /* __KERNEL__ */ diff -u --recursive --new-file v2.1.55/linux/include/linux/nfs_fs.h linux/include/linux/nfs_fs.h --- v2.1.55/linux/include/linux/nfs_fs.h Mon Jul 7 16:02:05 1997 +++ linux/include/linux/nfs_fs.h Sat Sep 13 11:07:29 1997 @@ -169,8 +169,7 @@ /* * linux/fs/nfs/locks.c */ -extern int nfs_lock(struct inode *inode, struct file *file, - int cmd, struct file_lock *fl); +extern int nfs_lock(struct file *file, int cmd, struct file_lock *fl); /* * linux/fs/nfs/write.c diff -u --recursive --new-file v2.1.55/linux/include/linux/smb_fs.h linux/include/linux/smb_fs.h --- v2.1.55/linux/include/linux/smb_fs.h Thu Sep 11 09:02:24 1997 +++ linux/include/linux/smb_fs.h Sat Sep 13 11:07:29 1997 @@ -149,7 +149,7 @@ int *lrparam, unsigned char **rparam); /* linux/fs/smbfs/mmap.c */ -int smb_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma); +int smb_mmap(struct file * file, struct vm_area_struct * vma); #endif /* __KERNEL__ */ diff -u --recursive --new-file v2.1.55/linux/include/linux/tty_flip.h linux/include/linux/tty_flip.h --- v2.1.55/linux/include/linux/tty_flip.h Sun May 22 21:55:15 1994 +++ linux/include/linux/tty_flip.h Tue Sep 9 19:41:41 1997 @@ -10,10 +10,11 @@ _INLINE_ void tty_insert_flip_char(struct tty_struct *tty, unsigned char ch, char flag) { - if (tty->flip.count++ >= TTY_FLIPBUF_SIZE) - return; - *tty->flip.flag_buf_ptr++ = flag; - *tty->flip.char_buf_ptr++ = ch; + if (tty->flip.count < TTY_FLIPBUF_SIZE) { + tty->flip.count++; + *tty->flip.flag_buf_ptr++ = flag; + *tty->flip.char_buf_ptr++ = ch; + } } _INLINE_ void tty_schedule_flip(struct tty_struct *tty) diff -u --recursive --new-file v2.1.55/linux/mm/filemap.c linux/mm/filemap.c --- v2.1.55/linux/mm/filemap.c Sun Sep 7 13:10:43 1997 +++ linux/mm/filemap.c Sat Sep 13 11:07:29 1997 @@ -1173,9 +1173,11 @@ }; /* This is used for a general mmap of a disk file */ -int generic_file_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma) + +int generic_file_mmap(struct file * file, struct vm_area_struct * vma) { struct vm_operations_struct * ops; + struct inode *inode = file->f_dentry->d_inode; if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) { ops = &file_shared_mmap; @@ -1214,7 +1216,7 @@ if (error) return error; if (flags & MS_SYNC) - return file_fsync(vma->vm_dentry->d_inode, NULL); + return file_fsync(NULL,vma->vm_dentry); return 0; } return 0; diff -u --recursive --new-file v2.1.55/linux/mm/mmap.c linux/mm/mmap.c --- v2.1.55/linux/mm/mmap.c Mon Aug 18 18:19:47 1997 +++ linux/mm/mmap.c Sat Sep 13 11:07:29 1997 @@ -296,7 +296,7 @@ } } if (!error) - error = file->f_op->mmap(file->f_dentry->d_inode, file, vma); + error = file->f_op->mmap(file, vma); if (error) { if (correct_wcount) diff -u --recursive --new-file v2.1.55/linux/net/Config.in linux/net/Config.in --- v2.1.55/linux/net/Config.in Thu Jul 17 10:06:09 1997 +++ linux/net/Config.in Sat Sep 13 11:07:29 1997 @@ -31,9 +31,6 @@ fi fi tristate 'Appletalk DDP' CONFIG_ATALK -if [ "$CONFIG_ATALK" != "n" ]; then - bool 'IP-over-DDP support (EXPERIMENTAL)' CONFIG_IPDDP -fi tristate 'Amateur Radio AX.25 Level 2' CONFIG_AX25 if [ "$CONFIG_AX25" != "n" ]; then bool 'AX.25 DAMA Slave support' CONFIG_AX25_DAMA_SLAVE @@ -53,6 +50,6 @@ # if [ "$CONFIG_LLC" = "y" ]; then # bool 'Netbeui (EXPERIMENTAL)' CONFIG_NETBEUI # fi - bool 'WAN router' CONFIG_WAN_ROUTER + tristate 'WAN router' CONFIG_WAN_ROUTER fi endmenu diff -u --recursive --new-file v2.1.55/linux/net/appletalk/Makefile linux/net/appletalk/Makefile --- v2.1.55/linux/net/appletalk/Makefile Mon Apr 7 11:35:32 1997 +++ linux/net/appletalk/Makefile Sat Sep 13 11:07:29 1997 @@ -1,5 +1,5 @@ # -# Makefile for the Linux TCP/IP (INET) layer. +# Makefile for the Linux AppleTalk layer. # # Note! Dependencies are done automagically by 'make dep', which also # removes any old dependencies. DON'T put your own dependencies here @@ -8,8 +8,10 @@ # Note 2! The CFLAGS definition is now in the main makefile... O_TARGET := appletalk.o -O_OBJS := aarp.o ddp.o +O_OBJS := aarp.o M_OBJS := $(O_TARGET) + +OX_OBJS += ddp.o ifeq ($(CONFIG_SYSCTL),y) O_OBJS += sysctl_net_atalk.o diff -u --recursive --new-file v2.1.55/linux/net/appletalk/aarp.c linux/net/appletalk/aarp.c --- v2.1.55/linux/net/appletalk/aarp.c Mon Jun 16 16:36:01 1997 +++ linux/net/appletalk/aarp.c Sat Sep 13 11:07:29 1997 @@ -22,7 +22,9 @@ * References: * Inside Appletalk (2nd Ed). */ - + +#include +#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) #include #include #include @@ -89,7 +91,6 @@ /* * Delete an aarp queue */ - static void aarp_expire(struct aarp_entry *a) { struct sk_buff *skb; @@ -403,10 +404,9 @@ } /* - * Find an entry. We might return an expired but not yet purged entry. We - * don't care as it will do no harm. + * Find an entry. We might return an expired but not yet purged entry. We + * don't care as it will do no harm. */ - static struct aarp_entry *aarp_find_entry(struct aarp_entry *list, struct device *dev, struct at_addr *sat) { unsigned long flags; @@ -426,7 +426,6 @@ /* * Send a DDP frame */ - int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr) { static char ddp_eth_multicast[ETH_ALEN]={ 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; @@ -620,7 +619,6 @@ * An entry in the aarp unresolved queue has become resolved. Send * all the frames queued under it. */ - static void aarp_resolved(struct aarp_entry **list, struct aarp_entry *a, int hash) { struct sk_buff *skb; @@ -662,7 +660,6 @@ * This is called by the SNAP driver whenever we see an AARP SNAP * frame. We currently only support ethernet. */ - static int aarp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) { struct elapaarp *ea=(struct elapaarp *)skb->h.raw; @@ -833,39 +830,32 @@ #ifdef MODULE -/* Free all the entries in an aarp list. Caller should turn off interrupts. */ -static void free_entry_list(struct aarp_entry *list) +/* + * Remove the AARP entries associated with a device. + * Called from cleanup_module() in ddp.c. + */ +void aarp_device_down(struct device *dev) { - struct aarp_entry *tmp; + int ct = 0; - while (list != NULL) + for(ct = 0; ct < AARP_HASH_SIZE; ct++) { - tmp = list->next; - aarp_expire(list); - list = tmp; + aarp_expire_device(&resolved[ct], dev); + aarp_expire_device(&unresolved[ct], dev); } + + return; } -/* General module cleanup. Called from cleanup_module() in ddp.c. */ +/* + * General module cleanup. Called from cleanup_module() in ddp.c. + */ void aarp_cleanup_module(void) { - unsigned long flags; - int i; - - save_flags(flags); - cli(); - del_timer(&aarp_timer); unregister_netdevice_notifier(&aarp_notifier); unregister_snap_client(aarp_snap_id); - - for (i = 0; i < AARP_HASH_SIZE; i++) - { - free_entry_list(resolved[i]); - free_entry_list(unresolved[i]); - } - - restore_flags(flags); } #endif /* MODULE */ +#endif /* CONFIG_ATALK || CONFIG_ATALK_MODULE */ diff -u --recursive --new-file v2.1.55/linux/net/appletalk/ddp.c linux/net/appletalk/ddp.c --- v2.1.55/linux/net/appletalk/ddp.c Thu Sep 4 17:07:32 1997 +++ linux/net/appletalk/ddp.c Sat Sep 13 11:07:29 1997 @@ -25,6 +25,10 @@ * Alan Cox : Posix bits * Alan Cox/Mike Freeman : Possible fix to NBP problems * Bradford Johnson : IP-over-DDP (experimental) + * Jay Schulist : Moved IP-over-DDP to its own + * driver file. (ipddp.c & ipddp.h) + * Jay Schulist : Made work as module with + * Appletalk drivers, cleaned it. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -34,6 +38,7 @@ */ #include +#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) #include #include #include @@ -72,35 +77,34 @@ #undef APPLETALK_DEBUG - #ifdef APPLETALK_DEBUG #define DPRINT(x) print(x) #else #define DPRINT(x) -#endif +#endif /* APPLETALK_DEBUG */ #ifdef CONFIG_SYSCTL extern inline void atalk_register_sysctl(void); extern inline void atalk_unregister_sysctl(void); -#endif +#endif /* CONFIG_SYSCTL */ struct datalink_proto *ddp_dl, *aarp_dl; static struct proto_ops atalk_dgram_ops; #define min(a,b) (((a)<(b))?(a):(b)) -/***********************************************************************************************************************\ -* * -* Handlers for the socket list. * -* * -\***********************************************************************************************************************/ - -static struct sock *atalk_socket_list=NULL; +/**************************************************************************\ +* * +* Handlers for the socket list. * +* * +\**************************************************************************/ + +static struct sock *atalk_socket_list = NULL; /* - * Note: Sockets may not be removed _during_ an interrupt or inet_bh - * handler using this technique. They can be added although we do not - * use this facility. + * Note: Sockets may not be removed _during_ an interrupt or inet_bh + * handler using this technique. They can be added although we do not + * use this facility. */ extern inline void atalk_remove_socket(struct sock *sk) @@ -117,70 +121,73 @@ { struct sock *s; - for( s = atalk_socket_list; s != NULL; s = s->next ) + for(s = atalk_socket_list; s != NULL; s = s->next) { - if ( to->sat_port != s->protinfo.af_at.src_port ) + if(to->sat_port != s->protinfo.af_at.src_port) { continue; } - if ( to->sat_addr.s_net == 0 && - to->sat_addr.s_node == ATADDR_BCAST && - s->protinfo.af_at.src_net == atif->address.s_net ) + if(to->sat_addr.s_net == 0 + && to->sat_addr.s_node == ATADDR_BCAST + && s->protinfo.af_at.src_net == atif->address.s_net) { break; } - if ( to->sat_addr.s_net == s->protinfo.af_at.src_net && - (to->sat_addr.s_node == s->protinfo.af_at.src_node - ||to->sat_addr.s_node == ATADDR_BCAST - ||to->sat_addr.s_node == ATADDR_ANYNODE )) + if(to->sat_addr.s_net == s->protinfo.af_at.src_net + && (to->sat_addr.s_node == s->protinfo.af_at.src_node + || to->sat_addr.s_node == ATADDR_BCAST + || to->sat_addr.s_node == ATADDR_ANYNODE)) { break; } /* XXXX.0 */ } - return( s ); + + return (s); } /* - * Find a socket in the list. + * Find a socket in the list. */ - static struct sock *atalk_find_socket(struct sockaddr_at *sat) { struct sock *s; - for ( s = atalk_socket_list; s != NULL; s = s->next ) + for(s = atalk_socket_list; s != NULL; s = s->next) { - if ( s->protinfo.af_at.src_net != sat->sat_addr.s_net ) + if(s->protinfo.af_at.src_net != sat->sat_addr.s_net) { continue; } - if ( s->protinfo.af_at.src_node != sat->sat_addr.s_node ) + + if(s->protinfo.af_at.src_node != sat->sat_addr.s_node) { continue; } - if ( s->protinfo.af_at.src_port != sat->sat_port ) + + if(s->protinfo.af_at.src_port != sat->sat_port) { continue; } + break; } - return( s ); + + return (s); } extern inline void atalk_destroy_socket(struct sock *sk) { - sklist_destroy_socket(&atalk_socket_list,sk); + sklist_destroy_socket(&atalk_socket_list, sk); MOD_DEC_USE_COUNT; } /* - * Called from proc fs + * Called from proc fs */ - int atalk_get_info(char *buffer, char **start, off_t offset, int length, int dummy) { struct sock *s; @@ -189,76 +196,74 @@ off_t begin=0; /* - * Output the appletalk data for the /proc virtual fs. + * Output the appletalk data for the /proc virtual fs. */ - len += sprintf (buffer,"Type local_addr remote_addr tx_queue rx_queue st uid\n"); - for (s = atalk_socket_list; s != NULL; s = s->next) + len += sprintf(buffer,"Type local_addr remote_addr tx_queue rx_queue st uid\n"); + for(s = atalk_socket_list; s != NULL; s = s->next) { - len += sprintf (buffer+len,"%02X ", s->type); - len += sprintf (buffer+len,"%04X:%02X:%02X ", + len += sprintf(buffer+len,"%02X ", s->type); + len += sprintf(buffer+len,"%04X:%02X:%02X ", ntohs(s->protinfo.af_at.src_net), s->protinfo.af_at.src_node, s->protinfo.af_at.src_port); - len += sprintf (buffer+len,"%04X:%02X:%02X ", + len += sprintf(buffer+len,"%04X:%02X:%02X ", ntohs(s->protinfo.af_at.dest_net), s->protinfo.af_at.dest_node, s->protinfo.af_at.dest_port); - len += sprintf (buffer+len,"%08X:%08X ", - atomic_read(&s->wmem_alloc), - atomic_read(&s->rmem_alloc)); - len += sprintf (buffer+len,"%02X %d\n", s->state, SOCK_INODE(s->socket)->i_uid); + len += sprintf(buffer+len,"%08X:%08X ", + atomic_read(&s->wmem_alloc), + atomic_read(&s->rmem_alloc)); + len += sprintf(buffer+len,"%02X %d\n", s->state, + SOCK_INODE(s->socket)->i_uid); /* Are we still dumping unwanted data then discard the record */ - pos=begin+len; + pos = begin + len; - if(posoffset+length) /* We have dumped enough */ + if(pos > offset + length) /* We have dumped enough */ break; } /* The data in question runs from begin to begin+len */ - *start=buffer+(offset-begin); /* Start of wanted data */ - len-=(offset-begin); /* Remove unwanted header data from length */ - if(len>length) - len=length; /* Remove unwanted tail data from length */ + *start = buffer + (offset - begin); /* Start of wanted data */ + len -= (offset - begin); /* Remove unwanted header data from length */ + if(len > length) + len = length; /* Remove unwanted tail data from length */ - return len; + return (len); } -/*******************************************************************************************************************\ -* * -* Routing tables for the Appletalk socket layer * -* * -\*******************************************************************************************************************/ - +/**************************************************************************\ +* * +* Routing tables for the Appletalk socket layer. * +* * +\**************************************************************************/ -static struct atalk_route *atalk_router_list=NULL; -static struct atalk_route atrtr_default; /* For probing devices or in a routerless network */ -static struct atalk_iface *atalk_iface_list=NULL; +static struct atalk_route *atalk_router_list = NULL; +static struct atalk_iface *atalk_iface_list = NULL; +static struct atalk_route atrtr_default; /* For probing devices or in a routerless network */ /* - * Appletalk interface control + * Appletalk interface control */ /* - * Drop a device. Doesn't drop any of its routes - that is the - * the callers problem. Called when we down the interface or - * delete the address. + * Drop a device. Doesn't drop any of its routes - that is the the callers + * problem. Called when we down the interface or delete the address. */ - static void atif_drop_device(struct device *dev) { struct atalk_iface **iface = &atalk_iface_list; struct atalk_iface *tmp; - while ((tmp = *iface) != NULL) + while((tmp = *iface) != NULL) { - if (tmp->dev == dev) + if(tmp->dev == dev) { *iface = tmp->next; kfree_s(tmp, sizeof(struct atalk_iface)); @@ -267,15 +272,19 @@ else iface = &tmp->next; } + + MOD_DEC_USE_COUNT; } static struct atalk_iface *atif_add_device(struct device *dev, struct at_addr *sa) { - struct atalk_iface *iface=(struct atalk_iface *) - kmalloc(sizeof(*iface), GFP_KERNEL); + struct atalk_iface *iface = (struct atalk_iface *) + kmalloc(sizeof(*iface), GFP_KERNEL); unsigned long flags; + if(iface==NULL) - return NULL; + return (NULL); + iface->dev=dev; dev->atalk_ptr=iface; iface->address= *sa; @@ -285,13 +294,15 @@ iface->next=atalk_iface_list; atalk_iface_list=iface; restore_flags(flags); - return iface; + + MOD_INC_USE_COUNT; + + return (iface); } /* - * Perform phase 2 AARP probing on our tentative address. + * Perform phase 2 AARP probing on our tentative address. */ - static int atif_probe_device(struct atalk_iface *atif) { int ct; @@ -310,19 +321,20 @@ * addresses. This needs tidying up when someone does localtalk * drivers */ + if((atif->dev->type == ARPHRD_LOCALTLK || atif->dev->type == ARPHRD_PPP) && atif->dev->do_ioctl) { /* fake up the request and pass it down */ sa = (struct sockaddr_at*)&atreq.ifr_addr; sa->sat_addr.s_node = probe_node; - sa->sat_addr.s_net = probe_net; - if (!(err=atif->dev->do_ioctl(atif->dev,&atreq,SIOCSIFADDR))) + sa->sat_addr.s_net = probe_net; + if(!(err=atif->dev->do_ioctl(atif->dev,&atreq,SIOCSIFADDR))) { (void)atif->dev->do_ioctl(atif->dev,&atreq,SIOCGIFADDR); atif->address.s_net=htons(sa->sat_addr.s_net); atif->address.s_node=sa->sat_addr.s_node; - return 0; + return (0); } /* * If it didn't like our faked request then fail: @@ -330,190 +342,197 @@ * through. That needs us to fix all the devices up * properly. We can then also dump the localtalk test. */ - return err; + return (err); } /* - * Offset the network we start probing with. + * Offset the network we start probing with. */ - if(probe_net==ATADDR_ANYNET) + if(probe_net == ATADDR_ANYNET) { if(!netrange) - probe_net=ntohs(atif->nets.nr_firstnet); + probe_net = ntohs(atif->nets.nr_firstnet); else - probe_net=ntohs(atif->nets.nr_firstnet) + (jiffies%netrange); + probe_net = ntohs(atif->nets.nr_firstnet) + (jiffies%netrange); } if(probe_node == ATADDR_ANYNODE) probe_node = jiffies&0xFF; - /* - * Scan the networks. + * Scan the networks. */ - for(netct=0;netct<=netrange;netct++) + for(netct = 0; netct <= netrange; netct++) { /* - * Sweep the available nodes from a given start. + * Sweep the available nodes from a given start. */ - atif->address.s_net=htons(probe_net); - for(nodect=0;nodect<256;nodect++) + atif->address.s_net = htons(probe_net); + for(nodect = 0; nodect < 256; nodect++) { - atif->address.s_node=((nodect+probe_node)&0xFF); - if(atif->address.s_node>0&&atif->address.s_node<254) + atif->address.s_node = ((nodect+probe_node) & 0xFF); + if(atif->address.s_node > 0 && atif->address.s_node<254) { /* - * Probe a proposed address. + * Probe a proposed address. */ - for(ct=0;ctdev, &atif->address); /* - * Defer 1/10th + * Defer 1/10th */ current->timeout = jiffies + (HZ/10); current->state = TASK_INTERRUPTIBLE; schedule(); - if(atif->status&ATIF_PROBE_FAIL) + if(atif->status & ATIF_PROBE_FAIL) break; } - if(!(atif->status&ATIF_PROBE_FAIL)) - return 0; + if(!(atif->status & ATIF_PROBE_FAIL)) + return (0); } - atif->status&=~ATIF_PROBE_FAIL; + atif->status &= ~ATIF_PROBE_FAIL; } probe_net++; - if(probe_net>ntohs(atif->nets.nr_lastnet)) - probe_net=ntohs(atif->nets.nr_firstnet); + if(probe_net > ntohs(atif->nets.nr_lastnet)) + probe_net = ntohs(atif->nets.nr_firstnet); } - return -EADDRINUSE; /* Network is full... */ + + return (-EADDRINUSE); /* Network is full... */ } struct at_addr *atalk_find_dev_addr(struct device *dev) { struct atalk_iface *iface=dev->atalk_ptr; + if(iface) - return &iface->address; - return NULL; + return (&iface->address); + + return (NULL); } static struct at_addr *atalk_find_primary(void) { struct atalk_iface *iface; - struct atalk_iface *fiface; + struct atalk_iface *fiface = NULL; + /* - * Return a point-to-point interface only if - * there is no non-ptp interface available. + * Return a point-to-point interface only if + * there is no non-ptp interface available. */ - fiface=NULL; - for(iface=atalk_iface_list;iface!=NULL;iface=iface->next) + for(iface=atalk_iface_list; iface != NULL; iface=iface->next) { - if(!fiface && !(iface->dev->flags&IFF_LOOPBACK)) + if(!fiface && !(iface->dev->flags & IFF_LOOPBACK)) fiface=iface; - if(!(iface->dev->flags&(IFF_LOOPBACK|IFF_POINTOPOINT))) - return &iface->address; + if(!(iface->dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) + return (&iface->address); } - if (fiface) - return &fiface->address; - if ( atalk_iface_list != NULL ) - return &atalk_iface_list->address; + + if(fiface) + return (&fiface->address); + if(atalk_iface_list != NULL) + return (&atalk_iface_list->address); else - return NULL; + return (NULL); } /* - * Find a match for 'any network' - ie any of our interfaces with that - * node number will do just nicely. + * Find a match for 'any network' - ie any of our interfaces with that + * node number will do just nicely. */ - static struct atalk_iface *atalk_find_anynet(int node, struct device *dev) { struct atalk_iface *iface=dev->atalk_ptr; - if (iface==NULL || ( iface->status & ATIF_PROBE )) - return NULL; - if ( node == ATADDR_BCAST || iface->address.s_node == node || node == ATADDR_ANYNODE) - return iface; - return NULL; + + if(iface==NULL || (iface->status & ATIF_PROBE)) + return (NULL); + if(node == ATADDR_BCAST || iface->address.s_node == node + || node == ATADDR_ANYNODE) + return (iface); + + return (NULL); } /* - * Find a match for a specific network:node pair + * Find a match for a specific network:node pair */ - static struct atalk_iface *atalk_find_interface(int net, int node) { struct atalk_iface *iface; - for(iface=atalk_iface_list;iface!=NULL;iface=iface->next) + + for(iface=atalk_iface_list; iface != NULL; iface=iface->next) { if((node==ATADDR_BCAST || node==ATADDR_ANYNODE || iface->address.s_node==node) && iface->address.s_net==net - && !(iface->status&ATIF_PROBE)) - return iface; + && !(iface->status & ATIF_PROBE)) + return (iface); } - return NULL; + + return (NULL); } /* - * Find a route for an appletalk packet. This ought to get cached in - * the socket (later on...). We know about host routes and the fact - * that a route must be direct to broadcast. + * Find a route for an appletalk packet. This ought to get cached in + * the socket (later on...). We know about host routes and the fact + * that a route must be direct to broadcast. */ - static struct atalk_route *atrtr_find(struct at_addr *target) { struct atalk_route *r; - for(r=atalk_router_list;r!=NULL;r=r->next) + + for(r=atalk_router_list; r != NULL; r=r->next) { - if(!(r->flags&RTF_UP)) + if(!(r->flags & RTF_UP)) continue; - if(r->target.s_net==target->s_net) + if(r->target.s_net == target->s_net) { - if(!(r->flags&RTF_HOST) || r->target.s_node==target->s_node) - return r; + if(!(r->flags&RTF_HOST) + || r->target.s_node == target->s_node) + return (r); } } + if(atrtr_default.dev) - return &atrtr_default; - return NULL; + return (&atrtr_default); + + return (NULL); } /* - * Given an appletalk network find the device to use. This can be - * a simple lookup. + * Given an appletalk network find the device to use. This can be + * a simple lookup. */ - -static struct device *atrtr_get_dev(struct at_addr *sa) +struct device *atrtr_get_dev(struct at_addr *sa) { struct atalk_route *atr=atrtr_find(sa); - if(atr==NULL) - return NULL; + + if(atr == NULL) + return (NULL); else - return atr->dev; + return (atr->dev); } /* - * Set up a default router. + * Set up a default router. */ - static void atrtr_set_default(struct device *dev) { - atrtr_default.dev=dev; - atrtr_default.flags= RTF_UP; - atrtr_default.gateway.s_net=htons(0); - atrtr_default.gateway.s_node=0; + atrtr_default.dev = dev; + atrtr_default.flags = RTF_UP; + atrtr_default.gateway.s_net = htons(0); + atrtr_default.gateway.s_node = 0; } /* - * Add a router. Basically make sure it looks valid and stuff the - * entry in the list. While it uses netranges we always set them to one - * entry to work like netatalk. + * Add a router. Basically make sure it looks valid and stuff the + * entry in the list. While it uses netranges we always set them to one + * entry to work like netatalk. */ - static int atrtr_create(struct rtentry *r, struct device *devhint) { struct sockaddr_at *ta=(struct sockaddr_at *)&r->rt_dst; @@ -525,113 +544,113 @@ save_flags(flags); /* - * Fixme: Raise/Lower a routing change semaphore for these - * operations. + * Fixme: Raise/Lower a routing change semaphore for these + * operations. */ /* - * Validate the request + * Validate the request */ - if(ta->sat_family!=AF_APPLETALK) - return -EINVAL; + if(ta->sat_family != AF_APPLETALK) + return (-EINVAL); if(devhint == NULL && ga->sat_family != AF_APPLETALK) - return -EINVAL; + return (-EINVAL); /* - * Now walk the routing table and make our decisions + * Now walk the routing table and make our decisions. */ - - for(rt=atalk_router_list;rt!=NULL;rt=rt->next) + for(rt=atalk_router_list; rt!=NULL; rt=rt->next) { if(r->rt_flags != rt->flags) continue; if(ta->sat_addr.s_net == rt->target.s_net) { - if(!(rt->flags&RTF_HOST)) + if(!(rt->flags & RTF_HOST)) break; if(ta->sat_addr.s_node == rt->target.s_node) break; } } - if ( devhint == NULL ) + if(devhint == NULL) { - for ( riface = NULL, iface = atalk_iface_list; iface; iface = iface->next ) + for(riface = NULL, iface = atalk_iface_list; iface; iface = iface->next) { - if ( riface == NULL && ntohs( ga->sat_addr.s_net ) >= ntohs( iface->nets.nr_firstnet ) && - ntohs( ga->sat_addr.s_net ) <= ntohs( iface->nets.nr_lastnet )) + if(riface == NULL && ntohs(ga->sat_addr.s_net) >= ntohs(iface->nets.nr_firstnet) && + ntohs(ga->sat_addr.s_net) <= ntohs(iface->nets.nr_lastnet)) { riface = iface; } - if ( ga->sat_addr.s_net == iface->address.s_net && ga->sat_addr.s_node == iface->address.s_node ) + if(ga->sat_addr.s_net == iface->address.s_net + && ga->sat_addr.s_node == iface->address.s_node) riface = iface; } - if ( riface == NULL ) - return -ENETUNREACH; + + if(riface == NULL) + return (-ENETUNREACH); devhint = riface->dev; } - if(rt==NULL) + if(rt == NULL) { - rt=(struct atalk_route *)kmalloc(sizeof(struct atalk_route), GFP_KERNEL); - if(rt==NULL) - return -ENOBUFS; + rt = (struct atalk_route *)kmalloc(sizeof(struct atalk_route), GFP_KERNEL); + if(rt == NULL) + return (-ENOBUFS); cli(); - rt->next=atalk_router_list; - atalk_router_list=rt; + rt->next = atalk_router_list; + atalk_router_list = rt; } /* - * Fill in the entry. + * Fill in the routing entry. */ - rt->target=ta->sat_addr; - rt->dev=devhint; - rt->flags=r->rt_flags; - rt->gateway=ga->sat_addr; + rt->target = ta->sat_addr; + rt->dev = devhint; + rt->flags = r->rt_flags; + rt->gateway = ga->sat_addr; restore_flags(flags); - return 0; -} + return (0); +} /* - * Delete a route. Find it and discard it. + * Delete a route. Find it and discard it. */ - static int atrtr_delete( struct at_addr *addr ) { struct atalk_route **r = &atalk_router_list; struct atalk_route *tmp; - while ((tmp = *r) != NULL) + while((tmp = *r) != NULL) { - if (tmp->target.s_net == addr->s_net && - (!(tmp->flags&RTF_GATEWAY) || - tmp->target.s_node == addr->s_node )) + if(tmp->target.s_net == addr->s_net + && (!(tmp->flags&RTF_GATEWAY) + || tmp->target.s_node == addr->s_node)) { *r = tmp->next; kfree_s(tmp, sizeof(struct atalk_route)); - return 0; + return (0); } r = &tmp->next; } - return -ENOENT; + + return (-ENOENT); } /* - * Called when a device is downed. Just throw away any routes - * via it. + * Called when a device is downed. Just throw away any routes + * via it. */ - void atrtr_device_down(struct device *dev) { struct atalk_route **r = &atalk_router_list; struct atalk_route *tmp; - while ((tmp = *r) != NULL) + while((tmp = *r) != NULL) { - if (tmp->dev == dev) + if(tmp->dev == dev) { *r = tmp->next; kfree_s(tmp, sizeof(struct atalk_route)); @@ -639,53 +658,51 @@ else r = &tmp->next; } - if(atrtr_default.dev==dev) + + if(atrtr_default.dev == dev) atrtr_set_default(NULL); } /* - * A device event has occurred. Watch for devices going down and - * delete our use of them (iface and route). + * A device event has occurred. Watch for devices going down and + * delete our use of them (iface and route). */ - static int ddp_device_event(struct notifier_block *this, unsigned long event, void *ptr) { - if(event==NETDEV_DOWN) + if(event == NETDEV_DOWN) { /* Discard any use of this */ atrtr_device_down((struct device *)ptr); atif_drop_device((struct device *)ptr); } - return NOTIFY_DONE; + + return (NOTIFY_DONE); } /* - * ioctl calls. Shouldn't even need touching. + * ioctl calls. Shouldn't even need touching. */ /* - * Device configuration ioctl calls. + * Device configuration ioctl calls. */ - int atif_ioctl(int cmd, void *arg) { struct ifreq atreq; - static char aarp_mcast[6]={0x09,0x00,0x00,0xFF,0xFF,0xFF}; + static char aarp_mcast[6] = {0x09, 0x00, 0x00, 0xFF, 0xFF, 0xFF}; struct netrange *nr; struct sockaddr_at *sa; struct device *dev; struct atalk_iface *atif; - int err; int ct; int limit; struct rtentry rtdef; - err = copy_from_user(&atreq,arg,sizeof(atreq)); - if (err) - return -EFAULT; + if(copy_from_user(&atreq,arg,sizeof(atreq))) + return (-EFAULT); - if((dev=dev_get(atreq.ifr_name))==NULL) - return -ENODEV; + if((dev = dev_get(atreq.ifr_name)) == NULL) + return (-ENODEV); sa=(struct sockaddr_at*)&atreq.ifr_addr; atif=atalk_find_dev(dev); @@ -694,149 +711,154 @@ { case SIOCSIFADDR: if(!suser()) - return -EPERM; - if(sa->sat_family!=AF_APPLETALK) - return -EINVAL; - if(dev->type!=ARPHRD_ETHER&&dev->type!=ARPHRD_LOOPBACK - &&dev->type!=ARPHRD_LOCALTLK && dev->type!=ARPHRD_PPP) - return -EPROTONOSUPPORT; + return (-EPERM); + if(sa->sat_family != AF_APPLETALK) + return (-EINVAL); + if(dev->type != ARPHRD_ETHER + && dev->type != ARPHRD_LOOPBACK + && dev->type != ARPHRD_LOCALTLK + && dev->type != ARPHRD_PPP) + return (-EPROTONOSUPPORT); + nr=(struct netrange *)&sa->sat_zero[0]; + /* - * Phase 1 is fine on localtalk but we don't - * do Ethertalk phase 1. Anyone wanting to add - * it go ahead. + * Phase 1 is fine on Localtalk but we don't do + * Ethertalk phase 1. Anyone wanting to add it go ahead. */ - if(dev->type==ARPHRD_ETHER && nr->nr_phase!=2) - return -EPROTONOSUPPORT; - if(sa->sat_addr.s_node==ATADDR_BCAST || sa->sat_addr.s_node == 254) - return -EINVAL; + if(dev->type == ARPHRD_ETHER && nr->nr_phase != 2) + return (-EPROTONOSUPPORT); + if(sa->sat_addr.s_node == ATADDR_BCAST + || sa->sat_addr.s_node == 254) + return (-EINVAL); if(atif) { /* - * Already setting address. + * Already setting address. */ if(atif->status&ATIF_PROBE) - return -EBUSY; + return (-EBUSY); - atif->address.s_net=sa->sat_addr.s_net; - atif->address.s_node=sa->sat_addr.s_node; + atif->address.s_net = sa->sat_addr.s_net; + atif->address.s_node = sa->sat_addr.s_node; atrtr_device_down(dev); /* Flush old routes */ } else { atif=atif_add_device(dev, &sa->sat_addr); if (atif == NULL) - return -ENOMEM; + return (-ENOMEM); } atif->nets= *nr; /* - * Check if the chosen address is used. If so we - * error and atalkd will try another. + * Check if the chosen address is used. If so we + * error and atalkd will try another. */ - if(!(dev->flags&IFF_LOOPBACK) && atif_probe_device(atif)<0) + if(!(dev->flags & IFF_LOOPBACK) && atif_probe_device(atif) < 0) { atif_drop_device(dev); - return -EADDRINUSE; + return (-EADDRINUSE); } /* - * Hey it worked - add the direct - * routes. + * Hey it worked - add the direct routes. */ - sa=(struct sockaddr_at *)&rtdef.rt_gateway; - sa->sat_family=AF_APPLETALK; - sa->sat_addr.s_net=atif->address.s_net; - sa->sat_addr.s_node=atif->address.s_node; - sa=(struct sockaddr_at *)&rtdef.rt_dst; - rtdef.rt_flags=RTF_UP; - sa->sat_family=AF_APPLETALK; - sa->sat_addr.s_node=ATADDR_ANYNODE; - if(dev->flags&IFF_LOOPBACK) - rtdef.rt_flags|=RTF_HOST; + sa = (struct sockaddr_at *)&rtdef.rt_gateway; + sa->sat_family = AF_APPLETALK; + sa->sat_addr.s_net = atif->address.s_net; + sa->sat_addr.s_node = atif->address.s_node; + sa = (struct sockaddr_at *)&rtdef.rt_dst; + rtdef.rt_flags = RTF_UP; + sa->sat_family = AF_APPLETALK; + sa->sat_addr.s_node = ATADDR_ANYNODE; + if(dev->flags & IFF_LOOPBACK) + rtdef.rt_flags |= RTF_HOST; + /* - * Routerless initial state. + * Routerless initial state. */ - if(nr->nr_firstnet==htons(0) && nr->nr_lastnet==htons(0xFFFE)) + if(nr->nr_firstnet == htons(0) + && nr->nr_lastnet == htons(0xFFFE)) { - sa->sat_addr.s_net=atif->address.s_net; + sa->sat_addr.s_net = atif->address.s_net; atrtr_create(&rtdef, dev); atrtr_set_default(dev); } else { - limit=ntohs(nr->nr_lastnet); - if(limit-ntohs(nr->nr_firstnet) > 256) + limit = ntohs(nr->nr_lastnet); + if(limit - ntohs(nr->nr_firstnet) > 256) { printk(KERN_WARNING "Too many routes/iface.\n"); - return -EINVAL; + return (-EINVAL); } for(ct=ntohs(nr->nr_firstnet);ct<=limit;ct++) { - sa->sat_addr.s_net=htons(ct); + sa->sat_addr.s_net = htons(ct); atrtr_create(&rtdef, dev); } } dev_mc_add(dev, aarp_mcast, 6, 1); - return 0; + return (0); + case SIOCGIFADDR: - if(atif==NULL) - return -EADDRNOTAVAIL; + if(atif == NULL) + return (-EADDRNOTAVAIL); ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_family=AF_APPLETALK; ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_addr=atif->address; break; + case SIOCGIFBRDADDR: - if(atif==NULL) - return -EADDRNOTAVAIL; + if(atif == NULL) + return (-EADDRNOTAVAIL); ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_family=AF_APPLETALK; ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_addr.s_net=atif->address.s_net; ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_addr.s_node=ATADDR_BCAST; break; + case SIOCATALKDIFADDR: if(!suser()) - return -EPERM; - if(sa->sat_family!=AF_APPLETALK) - return -EINVAL; - if(atif==NULL) - return -EADDRNOTAVAIL; + return (-EPERM); + if(sa->sat_family != AF_APPLETALK) + return (-EINVAL); + if(atif == NULL) + return (-EADDRNOTAVAIL); atrtr_device_down(atif->dev); atif_drop_device(atif->dev); break; } - err = copy_to_user(arg,&atreq,sizeof(atreq)); - if (err) - { - err = -EFAULT; - } - return err; + if(copy_to_user(arg, &atreq, sizeof(atreq))) + return (-EFAULT); + + return (0); } /* - * Routing ioctl() calls + * Routing ioctl() calls */ - static int atrtr_ioctl(unsigned int cmd, void *arg) { - int err; struct rtentry rt; - err = copy_from_user(&rt,arg,sizeof(rt)); - if (err) - return -EFAULT; + if(copy_from_user(&rt, arg, sizeof(rt))) + return (-EFAULT); switch(cmd) { case SIOCDELRT: - if(rt.rt_dst.sa_family!=AF_APPLETALK) - return -EINVAL; - return atrtr_delete(&((struct sockaddr_at *)&rt.rt_dst)->sat_addr); + if(rt.rt_dst.sa_family != AF_APPLETALK) + return (-EINVAL); + return (atrtr_delete(&((struct sockaddr_at *)&rt.rt_dst)->sat_addr)); + case SIOCADDRT: - return atrtr_create(&rt, NULL); + return (atrtr_create(&rt, NULL)); + default: - return -EINVAL; + return (-EINVAL); } } @@ -849,28 +871,28 @@ off_t pos=0; off_t begin=0; - len += sprintf (buffer,"Interface Address Networks Status\n"); - for (iface = atalk_iface_list; iface != NULL; iface = iface->next) + len += sprintf(buffer,"Interface Address Networks Status\n"); + for(iface = atalk_iface_list; iface != NULL; iface = iface->next) { - len += sprintf (buffer+len,"%-16s %04X:%02X %04X-%04X %d\n", - iface->dev->name, - ntohs(iface->address.s_net),iface->address.s_node, - ntohs(iface->nets.nr_firstnet),ntohs(iface->nets.nr_lastnet), - iface->status); - pos=begin+len; - if(posdev->name, ntohs(iface->address.s_net), + iface->address.s_node, ntohs(iface->nets.nr_firstnet), + ntohs(iface->nets.nr_lastnet), iface->status); + pos = begin + len; + if(pos < offset) { - len=0; - begin=pos; + len = 0; + begin = pos; } - if(pos>offset+length) + if(pos > offset + length) break; } - *start=buffer+(offset-begin); - len-=(offset-begin); - if(len>length) - len=length; - return len; + *start = buffer + (offset - begin); + len -= (offset - begin); + if(len > length) + len = length; + + return (len); } /* Called from proc fs - just make it print the routes neatly */ @@ -882,138 +904,151 @@ off_t pos=0; off_t begin=0; - len += sprintf (buffer,"Target Router Flags Dev\n"); + len += sprintf(buffer,"Target Router Flags Dev\n"); if(atrtr_default.dev) { - rt=&atrtr_default; - len += sprintf (buffer+len,"Default %04X:%02X %-4d %s\n", + rt = &atrtr_default; + len += sprintf(buffer+len,"Default %04X:%02X %-4d %s\n", ntohs(rt->gateway.s_net), rt->gateway.s_node, rt->flags, rt->dev->name); } - for (rt = atalk_router_list; rt != NULL; rt = rt->next) + + for(rt = atalk_router_list; rt != NULL; rt = rt->next) { - len += sprintf (buffer+len,"%04X:%02X %04X:%02X %-4d %s\n", + len += sprintf(buffer+len,"%04X:%02X %04X:%02X %-4d %s\n", ntohs(rt->target.s_net),rt->target.s_node, ntohs(rt->gateway.s_net), rt->gateway.s_node, rt->flags, rt->dev->name); - pos=begin+len; - if(posoffset+length) + if(pos > offset + length) break; } - *start=buffer+(offset-begin); - len-=(offset-begin); - if(len>length) - len=length; - return len; -} - -/*******************************************************************************************************************\ -* * -* Handling for system calls applied via the various interfaces to an Appletalk socket object * -* * -\*******************************************************************************************************************/ + + *start = buffer + (offset - begin); + len -= (offset - begin); + if(len > length) + len = length; + + return (len); +} + +/**************************************************************************\ +* * +* Handling for system calls applied via the various interfaces to an * +* Appletalk socket object. * +* * +\**************************************************************************/ /* - * Checksum: This is 'optional'. It's quite likely also a good - * candidate for assembler hackery 8) + * Checksum: This is 'optional'. It's quite likely also a good + * candidate for assembler hackery 8) */ - unsigned short atalk_checksum(struct ddpehdr *ddp, int len) { unsigned long sum=0; /* Assume unsigned long is >16 bits */ unsigned char *data=(unsigned char *)ddp; - len-=4; /* skip header 4 bytes */ - data+=4; + len -= 4; /* skip header 4 bytes */ + data += 4; /* This ought to be unwrapped neatly. I'll trust gcc for now */ while(len--) { - sum+=*data; - sum<<=1; - if(sum&0x10000) + sum += *data; + sum <<= 1; + if(sum & 0x10000) { sum++; - sum&=0xFFFF; + sum &= 0xFFFF; } data++; } + if(sum) return htons((unsigned short)sum); + return 0xFFFF; /* Use 0xFFFF for 0. 0 itself means none */ } /* - * Create a socket. Initialise the socket, blank the addresses - * set the state. + * Create a socket. Initialise the socket, blank the addresses + * set the state. */ - static int atalk_create(struct socket *sock, int protocol) { struct sock *sk; - sk=sk_alloc(AF_APPLETALK, GFP_KERNEL); - if(sk==NULL) - return(-ENOMEM); + + sk = sk_alloc(AF_APPLETALK, GFP_KERNEL); + if(sk == NULL) + return (-ENOMEM); + switch(sock->type) { - /* This RAW is an extension. It is trivial to do and gives you - the full ELAP frame. Should be handy for CAP 8) */ + /* + * We permit SOCK_DGRAM and RAW is an extension. It is + * trivial to do and gives you the full ELAP frame. + * Should be handy for CAP 8) + */ case SOCK_RAW: - /* We permit DDP datagram sockets */ case SOCK_DGRAM: sock->ops = &atalk_dgram_ops; break; + default: sk_free((void *)sk); - return(-ESOCKTNOSUPPORT); + return (-ESOCKTNOSUPPORT); } MOD_INC_USE_COUNT; sock_init_data(sock,sk); - sk->destruct=NULL; + sk->destruct = NULL; /* Checksums on by default */ - sk->mtu=DDP_MAXSZ; - sk->zapped=1; - return(0); + sk->mtu = DDP_MAXSZ; + sk->zapped = 1; + + return (0); } /* - * Free a socket. No work needed + * Free a socket. No work needed */ - static int atalk_release(struct socket *sock, struct socket *peer) { struct sock *sk=sock->sk; - if(sk==NULL) - return(0); + + if(sk == NULL) + return (0); + if(!sk->dead) sk->state_change(sk); - sk->dead=1; - sock->sk=NULL; + + sk->dead = 1; + sock->sk = NULL; atalk_destroy_socket(sk); - return(0); + + return (0); } /* - * Pick a source address if one is not given. Just return - * an error if not supportable. + * Pick a source address if one is not given. Just return + * an error if not supportable. */ - static int atalk_pick_port(struct sockaddr_at *sat) { - for ( sat->sat_port = ATPORT_RESERVED; sat->sat_port < ATPORT_LAST; sat->sat_port++ ) + for(sat->sat_port = ATPORT_RESERVED; sat->sat_port < ATPORT_LAST; sat->sat_port++) { - if ( atalk_find_socket( sat ) == NULL ) + if(atalk_find_socket(sat) == NULL) return sat->sat_port; } - return -EBUSY; + + return (-EBUSY); } static int atalk_autobind(struct sock *sk) @@ -1022,381 +1057,189 @@ struct sockaddr_at sat; int n; - if ( ap == NULL || ap->s_net == htons( ATADDR_ANYNET )) - return -EADDRNOTAVAIL; - sk->protinfo.af_at.src_net = sat.sat_addr.s_net = ap->s_net; + if(ap == NULL || ap->s_net == htons(ATADDR_ANYNET)) + return (-EADDRNOTAVAIL); + + sk->protinfo.af_at.src_net = sat.sat_addr.s_net = ap->s_net; sk->protinfo.af_at.src_node = sat.sat_addr.s_node = ap->s_node; - if (( n = atalk_pick_port( &sat )) < 0 ) - return( n ); - sk->protinfo.af_at.src_port=n; + if((n = atalk_pick_port(&sat)) < 0) + return (n); + + sk->protinfo.af_at.src_port = n; atalk_insert_socket(sk); - sk->zapped=0; - return 0; + sk->zapped = 0; + + return (0); } /* - * Set the address 'our end' of the connection. + * Set the address 'our end' of the connection. */ - static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { struct sock *sk; struct sockaddr_at *addr=(struct sockaddr_at *)uaddr; - sk=sock->sk; + sk = sock->sk; - if(sk->zapped==0) - return(-EINVAL); + if(sk->zapped == 0) + return (-EINVAL); - if(addr_len!=sizeof(struct sockaddr_at)) - return -EINVAL; + if(addr_len != sizeof(struct sockaddr_at)) + return (-EINVAL); - if(addr->sat_family!=AF_APPLETALK) - return -EAFNOSUPPORT; + if(addr->sat_family != AF_APPLETALK) + return (-EAFNOSUPPORT); - if(addr->sat_addr.s_net==htons(ATADDR_ANYNET)) + if(addr->sat_addr.s_net == htons(ATADDR_ANYNET)) { struct at_addr *ap=atalk_find_primary(); - if(ap==NULL) - return -EADDRNOTAVAIL; - sk->protinfo.af_at.src_net=addr->sat_addr.s_net=ap->s_net; - sk->protinfo.af_at.src_node=addr->sat_addr.s_node=ap->s_node; + + if(ap == NULL) + return (-EADDRNOTAVAIL); + + sk->protinfo.af_at.src_net = addr->sat_addr.s_net = ap->s_net; + sk->protinfo.af_at.src_node = addr->sat_addr.s_node= ap->s_node; } else { - if ( atalk_find_interface( addr->sat_addr.s_net, addr->sat_addr.s_node ) == NULL ) - return -EADDRNOTAVAIL; - sk->protinfo.af_at.src_net=addr->sat_addr.s_net; - sk->protinfo.af_at.src_node=addr->sat_addr.s_node; + if(atalk_find_interface(addr->sat_addr.s_net, addr->sat_addr.s_node) == NULL) + return (-EADDRNOTAVAIL); + + sk->protinfo.af_at.src_net = addr->sat_addr.s_net; + sk->protinfo.af_at.src_node = addr->sat_addr.s_node; } if(addr->sat_port == ATADDR_ANYPORT) { int n = atalk_pick_port(addr); if(n < 0) - return n; - sk->protinfo.af_at.src_port=addr->sat_port=n; + return (n); + + sk->protinfo.af_at.src_port = addr->sat_port = n; } else - sk->protinfo.af_at.src_port=addr->sat_port; + sk->protinfo.af_at.src_port = addr->sat_port; - if(atalk_find_socket(addr)!=NULL) - return -EADDRINUSE; + if(atalk_find_socket(addr) != NULL) + return (-EADDRINUSE); atalk_insert_socket(sk); - sk->zapped=0; - return(0); + sk->zapped = 0; + + return (0); } /* - * Set the address we talk to. + * Set the address we talk to. */ - static int atalk_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) { struct sock *sk=sock->sk; struct sockaddr_at *addr; - sk->state = TCP_CLOSE; + sk->state = TCP_CLOSE; sock->state = SS_UNCONNECTED; - if(addr_len!=sizeof(*addr)) - return(-EINVAL); - addr=(struct sockaddr_at *)uaddr; - - if(addr->sat_family!=AF_APPLETALK) - return -EAFNOSUPPORT; - if(addr->sat_addr.s_node==ATADDR_BCAST && !sk->broadcast) + if(addr_len != sizeof(*addr)) + return (-EINVAL); + addr = (struct sockaddr_at *)uaddr; + + if(addr->sat_family != AF_APPLETALK) + return (-EAFNOSUPPORT); + + if(addr->sat_addr.s_node == ATADDR_BCAST && !sk->broadcast) { #if 1 printk(KERN_WARNING "%s is broken and did not set SO_BROADCAST. It will break when 2.2 is released.\n", current->comm); #else - return -EACCES; + return (-EACCES); #endif } + if(sk->zapped) { - if(atalk_autobind(sk)<0) - return -EBUSY; + if(atalk_autobind(sk) < 0) + return (-EBUSY); } - if(atrtr_get_dev(&addr->sat_addr)==NULL) - return -ENETUNREACH; + if(atrtr_get_dev(&addr->sat_addr) == NULL) + return (-ENETUNREACH); + + sk->protinfo.af_at.dest_port = addr->sat_port; + sk->protinfo.af_at.dest_net = addr->sat_addr.s_net; + sk->protinfo.af_at.dest_node = addr->sat_addr.s_node; - sk->protinfo.af_at.dest_port=addr->sat_port; - sk->protinfo.af_at.dest_net=addr->sat_addr.s_net; - sk->protinfo.af_at.dest_node=addr->sat_addr.s_node; sock->state = SS_CONNECTED; - sk->state=TCP_ESTABLISHED; - return(0); + sk->state = TCP_ESTABLISHED; + + return (0); } /* - * Not relevant + * Not relevant */ - static int atalk_accept(struct socket *sock, struct socket *newsock, int flags) { - if(newsock->sk) { + if(newsock->sk) + { sk_free(newsock->sk); MOD_DEC_USE_COUNT; } - return -EOPNOTSUPP; + + return (-EOPNOTSUPP); } /* - * Find the name of an appletalk socket. Just copy the right - * fields into the sockaddr. + * Find the name of an appletalk socket. Just copy the right + * fields into the sockaddr. */ - static int atalk_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) { struct sockaddr_at sat; struct sock *sk; - sk=sock->sk; + sk = sock->sk; if(sk->zapped) { - if(atalk_autobind(sk)<0) - return -ENOBUFS; + if(atalk_autobind(sk) < 0) + return (-ENOBUFS); } *uaddr_len = sizeof(struct sockaddr_at); if(peer) { - if(sk->state!=TCP_ESTABLISHED) - return -ENOTCONN; - sat.sat_addr.s_net=sk->protinfo.af_at.dest_net; - sat.sat_addr.s_node=sk->protinfo.af_at.dest_node; - sat.sat_port=sk->protinfo.af_at.dest_port; + if(sk->state != TCP_ESTABLISHED) + return (-ENOTCONN); + sat.sat_addr.s_net = sk->protinfo.af_at.dest_net; + sat.sat_addr.s_node = sk->protinfo.af_at.dest_node; + sat.sat_port = sk->protinfo.af_at.dest_port; } else { - sat.sat_addr.s_net=sk->protinfo.af_at.src_net; - sat.sat_addr.s_node=sk->protinfo.af_at.src_node; - sat.sat_port=sk->protinfo.af_at.src_port; + sat.sat_addr.s_net = sk->protinfo.af_at.src_net; + sat.sat_addr.s_node = sk->protinfo.af_at.src_node; + sat.sat_port = sk->protinfo.af_at.src_port; } - sat.sat_family = AF_APPLETALK; - memcpy(uaddr,&sat,sizeof(sat)); - return(0); -} - -/* - * IP-over-DDP support. Under construction. - */ - -#ifdef CONFIG_IPDDP - -#define SIOCADDIPDDPRT SIOCDEVPRIVATE -#define SIOCDELIPDDPRT SIOCDEVPRIVATE+1 -#define SIOCFINDIPDDPRT SIOCDEVPRIVATE+2 - -struct ipddp_route -{ - struct device *dev; /* Carrier device */ - __u32 ip; /* IP address */ - struct at_addr at; /* Gateway appletalk address */ - int flags; - struct ipddp_route *next; -}; - -static struct ipddp_route *ipddp_route_head; - -static struct ipddp_route ipddp_route_test; - -int ipddp_open(struct device *dev) -{ - MOD_INC_USE_COUNT; - return 0; -} -int ipddp_close(struct device *dev) -{ - MOD_DEC_USE_COUNT; - return 0; -} - -int ipddp_xmit(struct sk_buff *skb, struct device *dev) -{ - /* Retrieve the saved address hint */ - struct at_addr *a=(struct at_addr *)skb->data; - skb_pull(skb,4); - - ((struct net_device_stats *) dev->priv)->tx_packets++; - ((struct net_device_stats *) dev->priv)->tx_bytes+=skb->len; - - /* printk("ipddp_xmit called with headroom %d\n",skb_headroom(skb)); */ - - if( aarp_send_ddp(skb->dev,skb,a,NULL) < 0 ) - dev_kfree_skb(skb,FREE_WRITE); - - return 0; -} - -struct net_device_stats *ipddp_get_stats(struct device *dev) -{ - return (struct net_device_stats *) dev->priv; -} - -int ipddp_ioctl(struct device *dev, struct ifreq *ifr, int cmd) -{ - struct ipddp_route *urt = (struct ipddp_route *)ifr->ifr_data; - - if(!suser()) - return -EPERM; - - /* for now we only have one route at a time */ - - switch(cmd) - { - case SIOCADDIPDDPRT: - if(copy_from_user(&ipddp_route_test,urt,sizeof(struct ipddp_route))) - return -EFAULT; - ipddp_route_test.dev = atrtr_get_dev(&ipddp_route_test.at); - if (dev==NULL) - return -ENETUNREACH; - ipddp_route_test.next = NULL; - printk("added ipddp route through %s\n",ipddp_route_test.dev->name); - ipddp_route_head = &ipddp_route_test; - return 0; - case SIOCFINDIPDDPRT: - if(copy_to_user(urt,&ipddp_route_test,sizeof(struct ipddp_route))) - return -EFAULT; - return 0; - case SIOCDELIPDDPRT: - ipddp_route_test.dev = NULL; - ipddp_route_head = NULL; - return 0; - default: - return -EINVAL; - } -} - -int ipddp_header (struct sk_buff *skb, struct device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) -{ - /* printk("ipddp_header\n"); */ - /* Push down the header space and the type byte */ - skb_push(skb, sizeof(struct ddpehdr)+1+4); - return 0; -} - -/* - * Now the packet really wants to go out. - */ - -int ipddp_rebuild_header (struct sk_buff *skb) -{ - struct ddpehdr *ddp; - struct at_addr at; - struct ipddp_route *rt; - struct at_addr *our_addr; - u32 paddr = ((struct rtable *)skb->dst)->rt_gateway; - - /* - * On entry skb->data points to the ddpehdr we reserved earlier. - * skb->h.raw will be the higher level header. - */ - - /* - * We created this earlier - */ - - ddp = (struct ddpehdr *) (skb->data+4); - - /* find appropriate route */ - - for(rt=ipddp_route_head;rt;rt=rt->next) - { - if(rt->ip == paddr) - break; - } - - if(!rt) { - printk("ipddp unreachable dst %08lx\n",ntohl(paddr)); - return -ENETUNREACH; - } - - our_addr = atalk_find_dev_addr(rt->dev); - - /* fill in ddpehdr */ - ddp->deh_len = skb->len; - ddp->deh_hops = 1; - ddp->deh_pad = 0; - ddp->deh_sum = 0; - ddp->deh_dnet = rt->at.s_net; /* FIXME more hops?? */ - ddp->deh_snet = our_addr->s_net; - ddp->deh_dnode = rt->at.s_node; - ddp->deh_snode = our_addr->s_node; - ddp->deh_dport = 72; - ddp->deh_sport = 72; - - *((__u8 *)(ddp+1)) = 22; /* ddp type = IP */ - - /* fix up length field */ - *((__u16 *)ddp)=ntohs(*((__u16 *)ddp)); - - /* set skb->dev to appropriate device */ - skb->dev = rt->dev; - - /* skb->raddr = (unsigned long) at */ - at = rt->at; - /* Hide it at the start of the buffer */ - memcpy(skb->data,(void *)&at,sizeof(at)); - skb->arp = 1; /* so the actual device doesn't try to arp it... */ - skb->protocol = htons(ETH_P_ATALK); /* Protocol has changed */ - - return 0; -} + sat.sat_family = AF_APPLETALK; + memcpy(uaddr, &sat, sizeof(sat)); -int ipddp_init (struct device *dev) -{ - ether_setup(dev); - dev->hard_start_xmit = ipddp_xmit; - dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL); - if(!dev->priv) - return -ENOMEM; - memset(dev->priv,0,sizeof(struct enet_statistics)); - dev->get_stats = ipddp_get_stats; - dev->do_ioctl = ipddp_ioctl; - dev->type = ARPHRD_IPDDP; /* IP over DDP tunnel */ - dev->family = AF_INET; - dev->mtu = 585; - dev->flags |= IFF_NOARP; - dev->hard_header = ipddp_header; /* see ip_output.c */ - dev->rebuild_header = ipddp_rebuild_header; - /* - * The worst case header we will need is currently a - * ethernet header (14 bytes) and a ddp header (sizeof ddpehdr+1) - * We send over SNAP so that takes another 8 bytes. - */ - dev->hard_header_len = 14+8+sizeof(struct ddpehdr)+1; - dev->open = ipddp_open; - dev->stop = ipddp_close; - - return 0; + return (0); } -static struct device dev_ipddp = { - "ipddp0\0 ", - 0, 0, 0, 0, - 0x0, 0, - 0, 0, 0, NULL, ipddp_init }; - -#endif /* CONFIG_IPDDP */ - /* - * Receive a packet (in skb) from device dev. This has come from the SNAP decoder, and on entry - * skb->h.raw is the DDP header, skb->len is the DDP length. The physical headers have been - * extracted. PPP should probably pass frames marked as for this layer - * [ie ARPHRD_ETHERTALK] + * Receive a packet (in skb) from device dev. This has come from the SNAP + * decoder, and on entry skb->h.raw is the DDP header, skb->len is the DDP + * header, skb->len is the DDP length. The physical headers have been + * extracted. PPP should probably pass frames marked as for this layer. + * [ie ARPHRD_ETHERTALK] */ - static int atalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) { struct sock *sock; @@ -1406,13 +1249,12 @@ int origlen; /* Size check */ - if(skb->lenlen < sizeof(*ddp)) { kfree_skb(skb,FREE_READ); - return(0); + return (0); } - /* * Fix up the length field [Ok this is horrible but otherwise * I end up with unions of bit fields and messy bit field order @@ -1423,254 +1265,264 @@ * run until we put it back) */ - *((__u16 *)ddp)=ntohs(*((__u16 *)ddp)); + *((__u16 *)ddp) = ntohs(*((__u16 *)ddp)); /* - * Trim buffer in case of stray trailing data + * Trim buffer in case of stray trailing data */ origlen = skb->len; - skb_trim(skb,min(skb->len,ddp->deh_len)); + skb_trim(skb, min(skb->len, ddp->deh_len)); /* - * Size check to see if ddp->deh_len was crap - * (Otherwise we'll detonate most spectacularly - * in the middle of recvmsg()). + * Size check to see if ddp->deh_len was crap + * (Otherwise we'll detonate most spectacularly + * in the middle of recvmsg()). */ - - if(skb->lenlen < sizeof(*ddp)) { kfree_skb(skb,FREE_READ); - return(0); + return (0); } /* - * Any checksums. Note we don't do htons() on this == is assumed to be - * valid for net byte orders all over the networking code... + * Any checksums. Note we don't do htons() on this == is assumed to be + * valid for net byte orders all over the networking code... */ - - if(ddp->deh_sum && atalk_checksum(ddp, ddp->deh_len)!= ddp->deh_sum) + if(ddp->deh_sum && atalk_checksum(ddp, ddp->deh_len) != ddp->deh_sum) { /* Not a valid appletalk frame - dustbin time */ - kfree_skb(skb,FREE_READ); - return(0); + kfree_skb(skb, FREE_READ); + return (0); } if(call_in_firewall(AF_APPLETALK, skb->dev, ddp, NULL,&skb)!=FW_ACCEPT) { kfree_skb(skb, FREE_READ); - return 0; + return (0); } /* Check the packet is aimed at us */ if(ddp->deh_dnet == 0) /* Net 0 is 'this network' */ - atif=atalk_find_anynet(ddp->deh_dnode, dev); + atif = atalk_find_anynet(ddp->deh_dnode, dev); else - atif=atalk_find_interface(ddp->deh_dnet,ddp->deh_dnode); + atif = atalk_find_interface(ddp->deh_dnet, ddp->deh_dnode); - /* Not ours */ - if(atif==NULL) + /* + * Not ours, so we route the packet via the correct Appletalk interface. + */ + if(atif == NULL) { struct atalk_route *rt; struct at_addr ta; - /* Don't route multicast, etc., packets, or packets - sent to "this network" */ + /* + * Don't route multicast, etc., packets, or packets + * sent to "this network" + */ if (skb->pkt_type != PACKET_HOST || ddp->deh_dnet == 0) { kfree_skb(skb, FREE_READ); - return(0); + return (0); } /* - * Check firewall allows this routing + * Check firewall allows this routing */ - - if(call_fw_firewall(AF_APPLETALK, skb->dev, ddp, NULL, &skb)!=FW_ACCEPT) + if(call_fw_firewall(AF_APPLETALK, skb->dev, ddp, NULL, &skb) != FW_ACCEPT) { kfree_skb(skb, FREE_READ); - return(0); + return (0); } - ta.s_net=ddp->deh_dnet; - ta.s_node=ddp->deh_dnode; + ta.s_net = ddp->deh_dnet; + ta.s_node = ddp->deh_dnode; /* Route the packet */ - rt=atrtr_find(&ta); - if(rt==NULL || ddp->deh_hops==15) + rt = atrtr_find(&ta); + if(rt == NULL || ddp->deh_hops == DDP_MAXHOPS) { kfree_skb(skb, FREE_READ); - return(0); + return (0); } ddp->deh_hops++; /* - * Route goes through another gateway, so - * set the target to the gateway instead. + * Route goes through another gateway, so + * set the target to the gateway instead. */ - - if(rt->flags&RTF_GATEWAY) + if(rt->flags & RTF_GATEWAY) { - ta.s_net = rt->gateway.s_net; + ta.s_net = rt->gateway.s_net; ta.s_node = rt->gateway.s_node; } /* Fix up skb->len field */ - skb_trim(skb,min(origlen, rt->dev->hard_header_len + + skb_trim(skb, min(origlen, rt->dev->hard_header_len + ddp_dl->header_length + ddp->deh_len)); - *((__u16 *)ddp)=ntohs(*((__u16 *)ddp)); /* Mend the byte order */ + /* Mend the byte order */ + *((__u16 *)ddp) = ntohs(*((__u16 *)ddp)); /* - * Send the buffer onwards - */ - - /* - * Now we must always be careful. If it's come from - * localtalk to ethertalk it might not fit + * Send the buffer onwards * - * Order matters here: If a packet has to be copied - * to make a new headroom (rare hopefully) then it - * won't need unsharing. + * Now we must always be careful. If it's come from + * localtalk to ethertalk it might not fit * - * Note. ddp-> becomes invalid at the realloc. + * Order matters here: If a packet has to be copied + * to make a new headroom (rare hopefully) then it + * won't need unsharing. + * + * Note. ddp-> becomes invalid at the realloc. */ - - if(skb_headroom(skb)<22) + if(skb_headroom(skb) < 22) /* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */ - skb=skb_realloc_headroom(skb, 32); + skb = skb_realloc_headroom(skb, 32); else - skb=skb_unshare(skb, GFP_ATOMIC, FREE_READ); + skb = skb_unshare(skb, GFP_ATOMIC, FREE_READ); /* - * If the buffer didnt vanish into the lack of - * space bitbucket we can send it. + * If the buffer didn't vanish into the lack of + * space bitbucket we can send it. */ - if(skb) { skb->arp = 1; /* Resolved */ - if(aarp_send_ddp(rt->dev, skb, &ta, NULL)==-1) + if(aarp_send_ddp(rt->dev, skb, &ta, NULL) == -1) kfree_skb(skb, FREE_READ); } - return 0; + + return (0); } - /* Which socket - atalk_search_socket() looks for a *full match* - of the tuple */ - tosat.sat_addr.s_net = ddp->deh_dnet; + /* + * Which socket - atalk_search_socket() looks for a *full match* + * of the tuple. + */ + tosat.sat_addr.s_net = ddp->deh_dnet; tosat.sat_addr.s_node = ddp->deh_dnode; tosat.sat_port = ddp->deh_dport; - sock=atalk_search_socket( &tosat, atif ); + sock = atalk_search_socket(&tosat, atif); - if(sock==NULL) /* But not one of our sockets */ + if(sock == NULL) /* But not one of our sockets */ { - kfree_skb(skb,FREE_READ); - return(0); + kfree_skb(skb, FREE_READ); + return (0); } #ifdef CONFIG_IPDDP /* * Check if IP-over-DDP */ - - if(skb->data[12]==22) + if(skb->data[12] == 22) { - struct net_device_stats *estats = - (struct net_device_stats *) dev_ipddp.priv; - skb->protocol=htons(ETH_P_IP); - skb_pull(skb,13); - skb->dev=&dev_ipddp; + struct device *dev; + struct net_device_stats *estats; + + if((dev = dev_get("ipddp0")) == NULL) + return (-ENODEV); + + estats = (struct net_device_stats *) dev->priv; + skb->protocol = htons(ETH_P_IP); + skb_pull(skb, 13); + skb->dev = dev; skb->h.raw = skb->data; + /* printk("passing up ipddp, 0x%02x better be 45\n",skb->data[0]); * printk("tot_len %d, skb->len %d\n", * ntohs(skb->h.iph->tot_len),skb->len); */ + estats->rx_packets++; - estats->rx_bytes+=skb->len+13; - netif_rx(skb); - return 0; + estats->rx_bytes += skb->len + 13; + netif_rx(skb); /* Send the SKB up to a higher place. */ + + return (0); } -#endif /* CONFIG_IPDDP */ +#endif /* CONFIG_IPDDP */ + /* * Queue packet (standard) */ skb->sk = sock; - if(sock_queue_rcv_skb(sock,skb)<0) + if(sock_queue_rcv_skb(sock, skb) < 0) { - skb->sk=NULL; + skb->sk = NULL; kfree_skb(skb, FREE_WRITE); } - return(0); + + return (0); } /* - * Receive a localtalk frame. We make some demands on the caller here. - * Caller must provide enough headroom on the packet to pull the short - * header and append a long one. + * Receive a localtalk frame. We make some demands on the caller here. + * Caller must provide enough headroom on the packet to pull the short + * header and append a long one. */ - - static int ltalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) { struct ddpehdr *ddp; struct at_addr *ap; + /* - * Expand any short form frames. + * Expand any short form frames. */ - - if(skb->mac.raw[2]==1) + if(skb->mac.raw[2] == 1) { /* - * Find our address. + * Find our address. */ - ap=atalk_find_dev_addr(dev); - if(ap==NULL || skb->lenlen < sizeof(struct ddpshdr)) { kfree_skb(skb, FREE_READ); - return 0; + return (0); } /* - * The push leaves us with a ddephdr not an shdr, and - * handily the port bytes in the right place preset. + * The push leaves us with a ddephdr not an shdr, and + * handily the port bytes in the right place preset. */ - skb_push(skb, sizeof(*ddp)-4); - ddp=(struct ddpehdr *)skb->data; + skb_push(skb, sizeof(*ddp) - 4); + ddp = (struct ddpehdr *)skb->data; /* - * Now fill in the long header. + * Now fill in the long header. */ /* - * These two first. The mac overlays the new source/dest - * network information so we MUST copy these before - * we write the network numbers ! + * These two first. The mac overlays the new source/dest + * network information so we MUST copy these before + * we write the network numbers ! */ - ddp->deh_dnode=skb->mac.raw[0]; /* From physical header */ - ddp->deh_snode=skb->mac.raw[1]; /* From physical header */ + ddp->deh_dnode = skb->mac.raw[0]; /* From physical header */ + ddp->deh_snode = skb->mac.raw[1]; /* From physical header */ - ddp->deh_dnet=ap->s_net; /* Network number */ - ddp->deh_snet=ap->s_net; - ddp->deh_sum=0; /* No checksum */ + ddp->deh_dnet = ap->s_net; /* Network number */ + ddp->deh_snet = ap->s_net; + ddp->deh_sum = 0; /* No checksum */ /* - * Not sure about this bit... + * Not sure about this bit... */ - ddp->deh_len=skb->len; - ddp->deh_hops=15; /* Non routable, so force a drop + ddp->deh_len = skb->len; + ddp->deh_hops = DDP_MAXHOPS; /* Non routable, so force a drop if we slip up later */ - *((__u16 *)ddp)=htons(*((__u16 *)ddp)); /* Mend the byte order */ + + /* Mend the byte order */ + *((__u16 *)ddp) = htons(*((__u16 *)ddp)); } skb->h.raw = skb->data; - return atalk_rcv(skb,dev,pt); + + return (atalk_rcv(skb, dev, pt)); } static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, @@ -1688,66 +1540,68 @@ int err; int flags = msg->msg_flags; - if(flags&~MSG_DONTWAIT) - return -EINVAL; + if(flags & ~MSG_DONTWAIT) + return (-EINVAL); - if(len>587) - return -EMSGSIZE; + if(len > DDP_MAXSZ) + return (-EMSGSIZE); if(usat) { if(sk->zapped) { - if(atalk_autobind(sk)<0) - return -EBUSY; + if(atalk_autobind(sk) < 0) + return (-EBUSY); } - if(msg->msg_namelen msg_namelen < sizeof(*usat)) + return (-EINVAL); if(usat->sat_family != AF_APPLETALK) - return -EINVAL; + return (-EINVAL); + /* netatalk doesn't implement this check */ - if(usat->sat_addr.s_node==ATADDR_BCAST && !sk->broadcast) + if(usat->sat_addr.s_node == ATADDR_BCAST && !sk->broadcast) { printk(KERN_INFO "SO_BROADCAST: Fix your netatalk as it will break before 2.2\n"); #if 0 - return -EPERM; + return (-EPERM); #endif } } else { - if(sk->state!=TCP_ESTABLISHED) - return -ENOTCONN; - usat=&local_satalk; - usat->sat_family=AF_APPLETALK; - usat->sat_port=sk->protinfo.af_at.dest_port; - usat->sat_addr.s_node=sk->protinfo.af_at.dest_node; - usat->sat_addr.s_net=sk->protinfo.af_at.dest_net; + if(sk->state != TCP_ESTABLISHED) + return (-ENOTCONN); + usat =& local_satalk; + usat->sat_family = AF_APPLETALK; + usat->sat_port = sk->protinfo.af_at.dest_port; + usat->sat_addr.s_node = sk->protinfo.af_at.dest_node; + usat->sat_addr.s_net = sk->protinfo.af_at.dest_net; } /* Build a packet */ SOCK_DEBUG(sk, "SK %p: Got address.\n",sk); - size=sizeof(struct ddpehdr)+len+ddp_dl->header_length; /* For headers */ + /* For headers */ + size = sizeof(struct ddpehdr) + len + ddp_dl->header_length; - if(usat->sat_addr.s_net!=0 || usat->sat_addr.s_node == ATADDR_ANYNODE) + if(usat->sat_addr.s_net != 0 || usat->sat_addr.s_node == ATADDR_ANYNODE) { - rt=atrtr_find(&usat->sat_addr); - if(rt==NULL) - return -ENETUNREACH; - dev=rt->dev; + rt = atrtr_find(&usat->sat_addr); + if(rt == NULL) + return (-ENETUNREACH); + dev = rt->dev; } else { struct at_addr at_hint; - at_hint.s_node=0; - at_hint.s_net=sk->protinfo.af_at.src_net; - rt=atrtr_find(&at_hint); - if(rt==NULL) - return -ENETUNREACH; - dev=rt->dev; + at_hint.s_node = 0; + at_hint.s_net = sk->protinfo.af_at.src_net; + rt = atrtr_find(&at_hint); + if(rt == NULL) + return (-ENETUNREACH); + dev = rt->dev; } SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", sk, size, dev->name); @@ -1755,105 +1609,105 @@ size += dev->hard_header_len; skb = sock_alloc_send_skb(sk, size, 0, flags&MSG_DONTWAIT, &err); - if(skb==NULL) - return err; + if(skb == NULL) + return (err); - skb->sk=sk; - skb->arp=1; - skb_reserve(skb,ddp_dl->header_length); - skb_reserve(skb,dev->hard_header_len); + skb->sk = sk; + skb->arp = 1; + skb_reserve(skb, ddp_dl->header_length); + skb_reserve(skb, dev->hard_header_len); - skb->dev=dev; + skb->dev = dev; SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk); - ddp=(struct ddpehdr *)skb_put(skb,sizeof(struct ddpehdr)); - ddp->deh_pad=0; - ddp->deh_hops=0; - ddp->deh_len=len+sizeof(*ddp); + ddp = (struct ddpehdr *)skb_put(skb,sizeof(struct ddpehdr)); + ddp->deh_pad = 0; + ddp->deh_hops = 0; + ddp->deh_len = len + sizeof(*ddp); /* - * Fix up the length field [Ok this is horrible but otherwise - * I end up with unions of bit fields and messy bit field order - * compiler/endian dependencies.. - */ - *((__u16 *)ddp)=ntohs(*((__u16 *)ddp)); - - ddp->deh_dnet=usat->sat_addr.s_net; - ddp->deh_snet=sk->protinfo.af_at.src_net; - ddp->deh_dnode=usat->sat_addr.s_node; - ddp->deh_snode=sk->protinfo.af_at.src_node; - ddp->deh_dport=usat->sat_port; - ddp->deh_sport=sk->protinfo.af_at.src_port; + * Fix up the length field [Ok this is horrible but otherwise + * I end up with unions of bit fields and messy bit field order + * compiler/endian dependencies.. + */ + *((__u16 *)ddp) = ntohs(*((__u16 *)ddp)); + + ddp->deh_dnet = usat->sat_addr.s_net; + ddp->deh_snet = sk->protinfo.af_at.src_net; + ddp->deh_dnode = usat->sat_addr.s_node; + ddp->deh_snode = sk->protinfo.af_at.src_node; + ddp->deh_dport = usat->sat_port; + ddp->deh_sport = sk->protinfo.af_at.src_port; SOCK_DEBUG(sk, "SK %p: Copy user data (%d bytes).\n", sk, len); - err = memcpy_fromiovec(skb_put(skb,len),msg->msg_iov,len); - if (err) + err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len); + if(err) { kfree_skb(skb, FREE_WRITE); - return -EFAULT; + return (-EFAULT); } - if(sk->no_check==1) - ddp->deh_sum=0; + if(sk->no_check == 1) + ddp->deh_sum = 0; else - ddp->deh_sum=atalk_checksum(ddp, len+sizeof(*ddp)); + ddp->deh_sum = atalk_checksum(ddp, len + sizeof(*ddp)); - if(call_out_firewall(AF_APPLETALK, skb->dev, ddp, NULL, &skb)!=FW_ACCEPT) + if(call_out_firewall(AF_APPLETALK, skb->dev, ddp, NULL, &skb) != FW_ACCEPT) { kfree_skb(skb, FREE_WRITE); - return -EPERM; + return (-EPERM); } /* - * Loopback broadcast packets to non gateway targets (ie routes - * to group we are in) + * Loopback broadcast packets to non gateway targets (ie routes + * to group we are in) */ - - if(ddp->deh_dnode==ATADDR_BCAST) + if(ddp->deh_dnode == ATADDR_BCAST) { - if((!(rt->flags&RTF_GATEWAY))&&(!(dev->flags&IFF_LOOPBACK))) + if((!(rt->flags&RTF_GATEWAY)) && (!(dev->flags&IFF_LOOPBACK))) { - struct sk_buff *skb2=skb_copy(skb, GFP_KERNEL); + struct sk_buff *skb2 = skb_copy(skb, GFP_KERNEL); if(skb2) { - loopback=1; + loopback = 1; SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk); - if(aarp_send_ddp(dev,skb2,&usat->sat_addr, NULL)==-1) + if(aarp_send_ddp(dev, skb2, &usat->sat_addr, NULL) == -1) kfree_skb(skb2, FREE_WRITE); /* else queued/sent above in the aarp queue */ } } } - if((dev->flags&IFF_LOOPBACK) || loopback) + if((dev->flags & IFF_LOOPBACK) || loopback) { SOCK_DEBUG(sk, "SK %p: Loop back.\n", sk); /* loop back */ skb_orphan(skb); ddp_dl->datalink_header(ddp_dl, skb, dev->dev_addr); - skb->mac.raw=skb->data; - skb->h.raw = skb->data + ddp_dl->header_length + dev->hard_header_len; + skb->mac.raw = skb->data; + skb->h.raw = skb->data + ddp_dl->header_length + dev->hard_header_len; skb_pull(skb,dev->hard_header_len); skb_pull(skb,ddp_dl->header_length); - atalk_rcv(skb,dev,NULL); + atalk_rcv(skb, dev, NULL); } else { SOCK_DEBUG(sk, "SK %p: send out.\n", sk); - if ( rt->flags & RTF_GATEWAY ) { + if (rt->flags & RTF_GATEWAY) + { gsat.sat_addr = rt->gateway; usat = &gsat; } - if(aarp_send_ddp(dev,skb,&usat->sat_addr, NULL)==-1) + if(aarp_send_ddp(dev, skb, &usat->sat_addr, NULL) == -1) kfree_skb(skb, FREE_WRITE); /* else queued/sent above in the aarp queue */ } SOCK_DEBUG(sk, "SK %p: Done write (%d).\n", sk, len); - return len; -} + return (len); +} static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm) @@ -1863,60 +1717,60 @@ struct ddpehdr *ddp = NULL; int copied = 0; struct sk_buff *skb; - int er = 0; + int err = 0; - skb=skb_recv_datagram(sk,flags&~MSG_DONTWAIT,flags&MSG_DONTWAIT,&er); - if(skb==NULL) - return er; + skb = skb_recv_datagram(sk,flags&~MSG_DONTWAIT,flags&MSG_DONTWAIT,&err); + if(skb == NULL) + return (err); ddp = (struct ddpehdr *)(skb->h.raw); - if(sk->type==SOCK_RAW) + if(sk->type == SOCK_RAW) { - copied=ddp->deh_len; + copied = ddp->deh_len; if(copied > size) { - copied=size; - msg->msg_flags|=MSG_TRUNC; + copied = size; + msg->msg_flags |= MSG_TRUNC; } - er = skb_copy_datagram_iovec(skb,0,msg->msg_iov,copied); - if (er) - goto out; + + err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); } else { - copied=ddp->deh_len - sizeof(*ddp); - if (copied > size) + copied = ddp->deh_len - sizeof(*ddp); + if(copied > size) { copied = size; - msg->msg_flags|=MSG_TRUNC; + msg->msg_flags |= MSG_TRUNC; } - er = skb_copy_datagram_iovec(skb,sizeof(*ddp),msg->msg_iov,copied); - if (er) - goto out; - } - if(sat) - { - sat->sat_family=AF_APPLETALK; - sat->sat_port=ddp->deh_sport; - sat->sat_addr.s_node=ddp->deh_snode; - sat->sat_addr.s_net=ddp->deh_snet; - } - msg->msg_namelen=sizeof(*sat); -out: - skb_free_datagram(sk, skb); - return er ? er : (copied); -} + err = skb_copy_datagram_iovec(skb,sizeof(*ddp),msg->msg_iov,copied); + } + if(!err) + { + if(sat) + { + sat->sat_family = AF_APPLETALK; + sat->sat_port = ddp->deh_sport; + sat->sat_addr.s_node = ddp->deh_snode; + sat->sat_addr.s_net = ddp->deh_snet; + } + msg->msg_namelen = sizeof(*sat); + } + + skb_free_datagram(sk, skb); /* Free the datagram. */ + + return (err ? err : (copied)); +} static int atalk_shutdown(struct socket *sk,int how) { - return -EOPNOTSUPP; + return (-EOPNOTSUPP); } /* - * Appletalk ioctl calls. + * Appletalk ioctl calls. */ - static int atalk_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) { long amount=0; @@ -1929,43 +1783,48 @@ */ case TIOCOUTQ: amount = sk->sndbuf - atomic_read(&sk->wmem_alloc); - if(amount<0) - amount=0; + if(amount < 0) + amount = 0; break; + case TIOCINQ: { struct sk_buff *skb; /* These two are safe on a single CPU system as only user tasks fiddle here */ - if((skb=skb_peek(&sk->receive_queue))!=NULL) - amount=skb->len-sizeof(struct ddpehdr); + if((skb = skb_peek(&sk->receive_queue)) != NULL) + amount = skb->len-sizeof(struct ddpehdr); break; } + case SIOCGSTAMP: - if (sk) + if(sk) { - if(sk->stamp.tv_sec==0) + if(sk->stamp.tv_sec == 0) return -ENOENT; - return copy_to_user((void *)arg,&sk->stamp,sizeof(struct timeval)) ? -EFAULT : 0; + return (copy_to_user((void *)arg,&sk->stamp,sizeof(struct timeval)) ? -EFAULT : 0); } - return -EINVAL; + return (-EINVAL); + /* - * Routing + * Routing */ case SIOCADDRT: case SIOCDELRT: if(!suser()) return -EPERM; - return(atrtr_ioctl(cmd,(void *)arg)); + return (atrtr_ioctl(cmd,(void *)arg)); + /* - * Interface + * Interface */ case SIOCGIFADDR: case SIOCSIFADDR: case SIOCGIFBRDADDR: case SIOCATALKDIFADDR: - return atif_ioctl(cmd,(void *)arg); + return (atif_ioctl(cmd,(void *)arg)); + /* - * Physical layer ioctl calls + * Physical layer ioctl calls */ case SIOCSIFLINK: case SIOCGIFHWADDR: @@ -1979,7 +1838,7 @@ case SIOCGIFCOUNT: case SIOGIFINDEX: case SIOGIFNAME: - return(dev_ioctl(cmd,(void *) arg)); + return ((dev_ioctl(cmd,(void *) arg))); case SIOCSIFMETRIC: case SIOCSIFBRDADDR: @@ -1989,20 +1848,23 @@ case SIOCSIFMEM: case SIOCGIFDSTADDR: case SIOCSIFDSTADDR: - return -EINVAL; + return (-EINVAL); default: - return -EINVAL; + return (-EINVAL); } - return put_user(amount, (int *)arg); + + return (put_user(amount, (int *)arg)); } -static struct net_proto_family atalk_family_ops = { +static struct net_proto_family atalk_family_ops= +{ AF_APPLETALK, atalk_create }; -static struct proto_ops atalk_dgram_ops = { +static struct proto_ops atalk_dgram_ops= +{ AF_APPLETALK, sock_no_dup, @@ -2023,7 +1885,8 @@ atalk_recvmsg }; -static struct notifier_block ddp_notifier={ +static struct notifier_block ddp_notifier= +{ ddp_device_event, NULL, 0 @@ -2047,41 +1910,53 @@ NULL }; -static char ddp_snap_id[]={0x08,0x00,0x07,0x80,0x9B}; +static char ddp_snap_id[] = {0x08, 0x00, 0x07, 0x80, 0x9B}; + +/* + * Export symbols for use by drivers when Appletalk is a module. + */ +EXPORT_SYMBOL(aarp_send_ddp); +EXPORT_SYMBOL(atrtr_get_dev); +EXPORT_SYMBOL(atalk_find_dev_addr); #ifdef CONFIG_PROC_FS -static struct proc_dir_entry proc_appletalk = { +static struct proc_dir_entry proc_appletalk= +{ PROC_NET_ATALK, 9, "appletalk", S_IFREG | S_IRUGO, 1, 0, 0, 0, &proc_net_inode_operations, atalk_get_info }; -static struct proc_dir_entry proc_atalk_route = { + +static struct proc_dir_entry proc_atalk_route= +{ PROC_NET_AT_ROUTE, 11,"atalk_route", S_IFREG | S_IRUGO, 1, 0, 0, 0, &proc_net_inode_operations, atalk_rt_get_info }; -static struct proc_dir_entry proc_atalk_iface = { + +static struct proc_dir_entry proc_atalk_iface= +{ PROC_NET_ATIF, 11,"atalk_iface", S_IFREG | S_IRUGO, 1, 0, 0, 0, &proc_net_inode_operations, atalk_if_get_info }; -#endif +#endif /* CONFIG_PROC_FS */ /* Called by proto.c on kernel start up */ __initfunc(void atalk_proto_init(struct net_proto *pro)) { (void) sock_register(&atalk_family_ops); - if ((ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv)) == NULL) + if((ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv)) == NULL) printk(KERN_CRIT "Unable to register DDP with SNAP.\n"); - ltalk_packet_type.type=htons(ETH_P_LOCALTALK); + ltalk_packet_type.type = htons(ETH_P_LOCALTALK); dev_add_pack(<alk_packet_type); - ppptalk_packet_type.type=htons(ETH_P_PPPTALK); + ppptalk_packet_type.type = htons(ETH_P_PPPTALK); dev_add_pack(&ppptalk_packet_type); register_netdevice_notifier(&ddp_notifier); @@ -2091,88 +1966,80 @@ proc_net_register(&proc_appletalk); proc_net_register(&proc_atalk_route); proc_net_register(&proc_atalk_iface); -#endif +#endif /* CONFIG_PROC_FS */ #ifdef CONFIG_SYSCTL atalk_register_sysctl(); -#endif - -#ifdef CONFIG_IPDDP - register_netdev(&dev_ipddp); -#endif /* CONFIG_IPDDP */ +#endif /* CONFIG_SYSCTL */ printk(KERN_INFO "Appletalk 0.18 for Linux NET3.037\n"); } #ifdef MODULE -EXPORT_NO_SYMBOLS; int init_module(void) { atalk_proto_init(NULL); - return 0; + return (0); } /* - * FIX THIS: If there are any routes/devices configured - * for appletalk we must not be unloaded. + * Actually down the interface. */ - -/* Remove all route entries. Interrupts must be off. */ -extern inline void free_route_list(void) +static void atalk_iface_down(struct atalk_iface *iface) { - struct atalk_route *list = atalk_router_list, *tmp; + atrtr_device_down(iface->dev); /* Remove all routes for the device */ + aarp_device_down(iface->dev); /* Remove AARP entries for the device */ + atif_drop_device(iface->dev); /* Remove the device */ - while (list != NULL) - { - tmp = list->next; - kfree_s(list, sizeof(struct atalk_route)); - list = tmp; - } + return; } -/* Remove all interface entries. Interrupts must be off. */ -extern inline void free_interface_list(void) -{ - struct atalk_iface *list = atalk_iface_list, *tmp; - - while (list != NULL) - { - tmp = list->next; - list->dev->atalk_ptr = NULL; - kfree_s(list, sizeof(struct atalk_iface)); - list = tmp; - } -} +/* + * Note on MOD_{INC,DEC}_USE_COUNT: + * + * Use counts are incremented/decremented when + * sockets are created/deleted. + * + * Appletalk interfaces are not incremented untill atalkd is run + * and are only decremented when they are downed. + * + * Ergo, before the appletalk module can be removed, all Appletalk + * sockets be closed from user space. + */ void cleanup_module(void) { - unsigned long flags; + struct atalk_iface *ifaces = atalk_iface_list, *tmp; - save_flags(flags); - cli(); - - aarp_cleanup_module(); + while(ifaces != NULL) + { + tmp = ifaces->next; + ifaces->dev->atalk_ptr = NULL; + atalk_iface_down(ifaces); + ifaces = tmp; + } #ifdef CONFIG_SYSCTL atalk_unregister_sysctl(); -#endif +#endif /* CONFIG_SYSCTL */ #ifdef CONFIG_PROC_FS proc_net_unregister(PROC_NET_ATALK); proc_net_unregister(PROC_NET_AT_ROUTE); proc_net_unregister(PROC_NET_ATIF); -#endif +#endif /* CONFIG_PROC_FS */ + + aarp_cleanup_module(); /* General aarp clean-up. */ + unregister_netdevice_notifier(&ddp_notifier); dev_remove_pack(<alk_packet_type); dev_remove_pack(&ppptalk_packet_type); unregister_snap_client(ddp_snap_id); sock_unregister(atalk_family_ops.family); - free_route_list(); - free_interface_list(); - - restore_flags(flags); + return; } #endif /* MODULE */ +#endif /* CONFIG_ATALK || CONFIG_ATALK_MODULE */ diff -u --recursive --new-file v2.1.55/linux/net/appletalk/sysctl_net_atalk.c linux/net/appletalk/sysctl_net_atalk.c --- v2.1.55/linux/net/appletalk/sysctl_net_atalk.c Sun Jul 20 20:41:59 1997 +++ linux/net/appletalk/sysctl_net_atalk.c Sat Sep 13 11:07:29 1997 @@ -59,9 +59,3 @@ { } #endif - - - - - - diff -u --recursive --new-file v2.1.55/linux/net/core/dev.c linux/net/core/dev.c --- v2.1.55/linux/net/core/dev.c Thu Sep 4 17:07:32 1997 +++ linux/net/core/dev.c Sat Sep 13 11:07:29 1997 @@ -1006,7 +1006,7 @@ strcpy(ifr.ifr_name, dev->name); - err = copy_to_user(&ifr, arg, sizeof(struct ifreq)); + err = copy_to_user(arg, &ifr, sizeof(struct ifreq)); return (err)?-EFAULT:0; } diff -u --recursive --new-file v2.1.55/linux/net/ipv4/arp.c linux/net/ipv4/arp.c --- v2.1.55/linux/net/ipv4/arp.c Thu May 15 16:48:05 1997 +++ linux/net/ipv4/arp.c Sat Sep 13 11:07:29 1997 @@ -1265,7 +1265,7 @@ arp = (struct arphdr *) skb_put(skb,sizeof(struct arphdr) + 2*(dev->addr_len+4)); skb->arp = 1; skb->dev = dev; - skb->protocol = htons (ETH_P_IP); + skb->protocol = htons (ETH_P_ARP); /* * Fill the device header for the ARP frame diff -u --recursive --new-file v2.1.55/linux/net/ipv6/icmp.c linux/net/ipv6/icmp.c --- v2.1.55/linux/net/ipv6/icmp.c Thu Jun 26 12:33:41 1997 +++ linux/net/ipv6/icmp.c Sat Sep 13 11:07:29 1997 @@ -92,7 +92,6 @@ /* * getfrag callback - * not static because it's needed in ndisc.c */ static int icmpv6_getfrag(const void *data, struct in6_addr *saddr, @@ -131,11 +130,12 @@ } /* - * an inline helper for the "simple" if statement bellow + * an inline helper for the "simple" if statement below * checks if parameter problem report is caused by an * unrecognized IPv6 option that has the Option Type * highest-order two bits set to 10 */ + static __inline__ int opt_unrec(struct sk_buff *skb, __u32 offset) { char *buff = skb->nh.raw; diff -u --recursive --new-file v2.1.55/linux/net/ipv6/ip6_fib.c linux/net/ipv6/ip6_fib.c --- v2.1.55/linux/net/ipv6/ip6_fib.c Mon Apr 14 16:28:28 1997 +++ linux/net/ipv6/ip6_fib.c Sat Sep 13 11:07:29 1997 @@ -235,7 +235,15 @@ key = (struct rt6key *)((u8 *)fn->leaf + offset); + /* + * Prefix match + */ if (addr_match(&key->addr, addr, fn->fn_bit)) { + + /* + * Exact match ? + */ + if (plen == fn->fn_bit) { /* clean up an intermediate node */ if ((fn->fn_flags & RTN_RTINFO) == 0) { @@ -248,6 +256,10 @@ return fn; } + /* + * We have more bits to go + */ + if (plen > fn->fn_bit) { /* Walk down on tree. */ fn->fn_sernum = sernum; @@ -255,6 +267,11 @@ pn = fn; fn = dir ? fn->right: fn->left; + /* + * Round we go. Note if fn has become + * NULL then dir is set and fn is handled + * top of loop. + */ continue; } } @@ -611,7 +628,8 @@ } /* - * called to trim the tree of intermediate nodes when possible + * Called to trim the tree of intermediate nodes when possible. "fn" + * is the node we want to try and remove. */ static void fib6_del_2(struct fib6_node *fn) @@ -621,6 +639,10 @@ fn->fn_flags &= ~RTN_RTINFO; rt6_stats.fib_route_nodes--; + /* + * Can't delete a root node + */ + if (fn->fn_flags & RTN_TL_ROOT) return; @@ -630,43 +652,89 @@ child = NULL; + /* + * We have a child to left + */ + if (fn->left) { children++; child = fn->left; } + /* + * To right + */ + if (fn->right) { children++; child = fn->right; } + /* + * We can't tidy a case of two children. + */ + if (children > 1 || (fn->fn_flags & RTN_RTINFO)) break; + /* + * The node we plan to tidy has an stree. Talk about + * making life hard. + */ + if (fn->subtree) goto stree_node; + /* + * Up we go + */ + pn = fn->parent; + /* + * Not a ROOT - we can tidy + */ + if ((fn->fn_flags & RTN_ROOT) == 0) { + /* + * Make our child our parents child + */ if (pn->left == fn) pn->left = child; else pn->right = child; + /* + * Reparent the child + */ if (child) child->parent = pn; + /* + * Discard leaf entries + */ if (fn->leaf) rt6_release(fn->leaf); } else { if (children) break; + /* + * No children so no subtree + */ pn->subtree = NULL; } + /* + * We are discarding + */ node_free(fn); + + /* + * Our merge of entries might propogate further + * up the tree, so move up a level and retry. + */ + fn = pn; } while (!(fn->fn_flags & RTN_TL_ROOT)); @@ -685,18 +753,29 @@ fn->leaf = rt; } +/* + * Remove our entry in the tree. This throws away the route entry + * from the list of entries attached to this fib node. It doesn't + * expunge from the tree. + */ + static struct fib6_node * fib6_del_1(struct rt6_info *rt) { struct fib6_node *fn; fn = rt->rt6i_node; + /* We need a fib node! */ if (fn) { struct rt6_info **back; struct rt6_info *lf; back = &fn->leaf; + /* + * Walk the leaf entries looking for ourself + */ + for(lf = fn->leaf; lf; lf=lf->u.next) { if (rt == lf) { /* diff -u --recursive --new-file v2.1.55/linux/net/ipv6/ip6_input.c linux/net/ipv6/ip6_input.c --- v2.1.55/linux/net/ipv6/ip6_input.c Thu May 15 16:48:06 1997 +++ linux/net/ipv6/ip6_input.c Sat Sep 13 11:07:29 1997 @@ -374,6 +374,9 @@ if (ipv6_chk_mcast_addr(skb->dev, &hdr->daddr)) deliver = 1; + /* + * IPv6 multicast router mode isnt currently supported. + */ #if 0 if (ipv6_config.multicast_route) { int addr_type; diff -u --recursive --new-file v2.1.55/linux/net/ipv6/ip6_output.c linux/net/ipv6/ip6_output.c --- v2.1.55/linux/net/ipv6/ip6_output.c Thu Mar 27 14:40:16 1997 +++ linux/net/ipv6/ip6_output.c Sat Sep 13 11:07:29 1997 @@ -47,7 +47,9 @@ if (dev->hard_header) { int mac; - + + /* Maybe when Alexey has done his new magic I'll hack this + it seems to be worth 1-2% on IPv4 */ #if 0 if (dst->hh) hh_copy_header(dst->hh, skb); @@ -143,7 +145,7 @@ /* * To avoid extra problems ND packets are send through this - * routine. It's code duplication but i really want to avoid + * routine. It's code duplication but I really want to avoid * extra checks since ipv6_build_header is used by TCP (which * is for us performace critical) */ diff -u --recursive --new-file v2.1.55/linux/net/ipv6/route.c linux/net/ipv6/route.c --- v2.1.55/linux/net/ipv6/route.c Mon Aug 4 16:25:41 1997 +++ linux/net/ipv6/route.c Sat Sep 13 11:07:29 1997 @@ -733,6 +733,25 @@ int ip6_route_del(struct in6_rtmsg *rtmsg) { + struct rt6_info *rt; + struct device *dev=NULL; + + /* + * Find device + */ + if(rtmsg->rtmsg_ifindex) + dev=dev_get_by_index(rtmsg->rtmsg_ifindex); + /* + * Find route + */ + rt=rt6_lookup(&rtmsg->rtmsg_dst, &rtmsg->rtmsg_src, dev, rtmsg->rtmsg_flags); + + /* + * Blow it away + */ + if(rt) + ip6_del_rt(rt); + return 0; } diff -u --recursive --new-file v2.1.55/linux/net/netlink.c linux/net/netlink.c --- v2.1.55/linux/net/netlink.c Thu Sep 4 17:07:32 1997 +++ linux/net/netlink.c Sat Sep 13 11:07:29 1997 @@ -126,8 +126,7 @@ return err ? -EFAULT : count; } -static loff_t netlink_lseek(struct inode * inode, struct file * file, - loff_t offset, int origin) +static long long netlink_lseek(struct file * file, long long offset, int origin) { return -ESPIPE; } diff -u --recursive --new-file v2.1.55/linux/net/socket.c linux/net/socket.c --- v2.1.55/linux/net/socket.c Thu Sep 4 17:07:32 1997 +++ linux/net/socket.c Sat Sep 13 11:07:29 1997 @@ -96,8 +96,7 @@ #include -static long long sock_lseek(struct inode *inode, struct file *file, - long long offset, int whence); +static long long sock_lseek(struct file *file, long long offset, int whence); static long sock_read(struct inode *inode, struct file *file, char *buf, unsigned long size); static long sock_write(struct inode *inode, struct file *file, @@ -107,7 +106,7 @@ static unsigned int sock_poll(struct file *file, poll_table *wait); static int sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); -static int sock_fasync(struct inode *inode, struct file *filp, int on); +static int sock_fasync(struct file *filp, int on); /* @@ -353,8 +352,7 @@ * Sockets are not seekable. */ -static long long sock_lseek(struct inode *inode, struct file *file, - long long offset, int whence) +static long long sock_lseek(struct file *file,long long offset, int whence) { return -ESPIPE; } @@ -482,7 +480,7 @@ printk(KERN_DEBUG "sock_close: NULL inode\n"); return 0; } - sock_fasync(inode, filp, 0); + sock_fasync(filp, 0); sock_release(socki_lookup(inode)); return 0; } @@ -491,7 +489,7 @@ * Update the socket async list */ -static int sock_fasync(struct inode *inode, struct file *filp, int on) +static int sock_fasync(struct file *filp, int on) { struct fasync_struct *fa, *fna=NULL, **prev; struct socket *sock; @@ -504,7 +502,7 @@ return -ENOMEM; } - sock = socki_lookup(inode); + sock = socki_lookup(filp->f_dentry->d_inode); prev=&(sock->fasync_list); diff -u --recursive --new-file v2.1.55/linux/net/sunrpc/sunrpc_syms.c linux/net/sunrpc/sunrpc_syms.c --- v2.1.55/linux/net/sunrpc/sunrpc_syms.c Sun Apr 13 10:18:23 1997 +++ linux/net/sunrpc/sunrpc_syms.c Sat Sep 13 11:47:49 1997 @@ -74,7 +74,9 @@ /* RPC statistics */ #ifdef CONFIG_PROC_FS EXPORT_SYMBOL(rpc_proc_register); +EXPORT_SYMBOL(rpc_register_sysctl); EXPORT_SYMBOL(rpc_proc_unregister); +EXPORT_SYMBOL(rpc_proc_init); EXPORT_SYMBOL(rpc_proc_read); EXPORT_SYMBOL(svc_proc_register); EXPORT_SYMBOL(svc_proc_unregister); diff -u --recursive --new-file v2.1.55/linux/net/unix/garbage.c linux/net/unix/garbage.c --- v2.1.55/linux/net/unix/garbage.c Thu Sep 11 09:02:24 1997 +++ linux/net/unix/garbage.c Sat Sep 13 11:07:30 1997 @@ -35,31 +35,20 @@ */ #include -#include -#include #include -#include #include -#include #include #include -#include -#include -#include -#include #include -#include #include #include -#include - -#include #include #include #include #include #include #include +#include #include /* Internal data structures and random procedures: */