diff -pruN linux-2.4.27-rc4/arch/cris/drivers/eeprom.c linux-2.4.27-rc4.CAN-2004-0415/arch/cris/drivers/eeprom.c
--- linux-2.4.27-rc4/arch/cris/drivers/eeprom.c	2003-08-25 20:44:39.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/cris/drivers/eeprom.c	2004-09-07 13:53:38.000000000 +0900
@@ -506,7 +506,7 @@ static int eeprom_read_buf(loff_t addr, 
 static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t *off)
 {
   int read=0;
-  unsigned long p = file->f_pos;
+  unsigned long p = *off;
 
   unsigned char page;
 
@@ -540,7 +540,7 @@ static ssize_t eeprom_read(struct file *
     return -EFAULT;
   }
 
-  if( (p + count) > eeprom.size)
+  if(count > eeprom.size - p)
   {
     /* truncate count */
     count = eeprom.size - p;
@@ -560,7 +560,7 @@ static ssize_t eeprom_read(struct file *
   
   if(read > 0)
   {
-    file->f_pos += read;
+    *off = p + read;
   }
 
   eeprom.busy--;
@@ -605,7 +605,7 @@ static ssize_t eeprom_write(struct file 
   {
     restart = 0;
     written = 0;
-    p = file->f_pos;
+    p = *off;
    
     
     while( (written < count) && (p < eeprom.size))
@@ -733,10 +733,10 @@ static ssize_t eeprom_write(struct file 
 
   eeprom.busy--;
   wake_up_interruptible(&eeprom.wait_q);
-  if (written == 0 && file->f_pos >= eeprom.size){
+  if (written == 0 && p >= eeprom.size){
     return -ENOSPC;
   }
-  file->f_pos += written;
+  *off = p;
   return written;
 }
 
diff -pruN linux-2.4.27-rc4/arch/i386/kernel/mtrr.c linux-2.4.27-rc4.CAN-2004-0415/arch/i386/kernel/mtrr.c
--- linux-2.4.27-rc4/arch/i386/kernel/mtrr.c	2003-06-13 23:51:29.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/i386/kernel/mtrr.c	2004-09-07 13:53:38.000000000 +0900
@@ -1648,11 +1648,17 @@ static int mtrr_file_del (unsigned long 
 static ssize_t mtrr_read (struct file *file, char *buf, size_t len,
 			  loff_t *ppos)
 {
-    if (*ppos >= ascii_buf_bytes) return 0;
-    if (*ppos + len > ascii_buf_bytes) len = ascii_buf_bytes - *ppos;
-    if ( copy_to_user (buf, ascii_buffer + *ppos, len) ) return -EFAULT;
-    *ppos += len;
-    return len;
+	loff_t pos = *ppos;
+	if (pos < 0 || pos >= ascii_buf_bytes)
+		return 0;
+	if (len > ascii_buf_bytes - pos)
+		len = ascii_buf_bytes - pos;
+	if (copy_to_user(buf, ascii_buffer + pos, len))
+		return -EFAULT;
+	pos += len;
+	*ppos = pos;
+
+	return len;
 }   /*  End Function mtrr_read  */
 
 static ssize_t mtrr_write (struct file *file, const char *buf, size_t len,
diff -pruN linux-2.4.27-rc4/arch/ia64/kernel/efivars.c linux-2.4.27-rc4.CAN-2004-0415/arch/ia64/kernel/efivars.c
--- linux-2.4.27-rc4/arch/ia64/kernel/efivars.c	2003-11-29 03:26:19.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/ia64/kernel/efivars.c	2004-09-07 13:53:38.000000000 +0900
@@ -364,6 +364,7 @@ efi_systab_read(struct file *file, char 
 	int ret;
 	const int max_nr_entries = 7; 	/* num ptrs to tables we could expose */
 	const int max_line_len = 80;
+	loff_t pos = *ppos;
 
 	if (!efi.systab)
 		return 0;
@@ -388,13 +389,13 @@ efi_systab_read(struct file *file, char 
 	if (efi.boot_info)
 		length += sprintf(proc_buffer + length, "BOOTINFO=0x%lx\n", __pa(efi.boot_info));
 
-	if (*ppos >= length) {
+	if (pos != (unsigned) pos || pos >= length) {
 		ret = 0;
 		goto out;
 	}
 
-	data = proc_buffer + file->f_pos;
-	size = length - file->f_pos;
+	data = proc_buffer + pos;
+	size = length - pos;
 	if (size > count)
 		size = count;
 	if (copy_to_user(buffer, data, size)) {
@@ -402,7 +403,7 @@ efi_systab_read(struct file *file, char 
 		goto out;
 	}
 
-	*ppos += size;
+	*ppos = pos + size;
 	ret = size;
 
 out:
diff -pruN linux-2.4.27-rc4/arch/ia64/kernel/salinfo.c linux-2.4.27-rc4.CAN-2004-0415/arch/ia64/kernel/salinfo.c
--- linux-2.4.27-rc4/arch/ia64/kernel/salinfo.c	2004-04-14 22:05:26.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/ia64/kernel/salinfo.c	2004-09-07 13:53:38.000000000 +0900
@@ -451,6 +451,7 @@ salinfo_log_read(struct file *file, char
 	size_t size;
 	u8 *buf;
 	u64 bufsize;
+	loff_t pos = *ppos;
 
 	if (data->state == STATE_LOG_RECORD) {
 		buf = data->log_buffer;
@@ -462,17 +463,17 @@ salinfo_log_read(struct file *file, char
 		buf = NULL;
 		bufsize = 0;
 	}
-	if (*ppos >= bufsize)
+	if (pos != (unsigned)pos || pos >= bufsize)
 		return 0;
 
-	saldata = buf + file->f_pos;
-	size = bufsize - file->f_pos;
+	saldata = buf + pos;
+	size = bufsize - pos;
 	if (size > count)
 		size = count;
 	if (copy_to_user(buffer, saldata, size))
 		return -EFAULT;
 
-	*ppos += size;
+	*ppos = pos + size;
 	return size;
 }
 
diff -pruN linux-2.4.27-rc4/arch/mips/sibyte/sb1250/bcm1250_tbprof.c linux-2.4.27-rc4.CAN-2004-0415/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
--- linux-2.4.27-rc4/arch/mips/sibyte/sb1250/bcm1250_tbprof.c	2003-08-25 20:44:40.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/mips/sibyte/sb1250/bcm1250_tbprof.c	2004-09-07 13:53:38.000000000 +0900
@@ -300,6 +300,9 @@ static ssize_t sbprof_tb_read(struct fil
 	char *dest    =	 buf;
 	long  cur_off = *offp;
 
+	if (cur_off < 0)
+		return -EINVAL;
+
 	count = 0;
 	cur_sample = cur_off / TB_SAMPLE_SIZE;
 	sample_off = cur_off % TB_SAMPLE_SIZE;
diff -pruN linux-2.4.27-rc4/arch/ppc/config.in linux-2.4.27-rc4.CAN-2004-0415/arch/ppc/config.in
--- linux-2.4.27-rc4/arch/ppc/config.in	2004-04-14 22:05:27.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/ppc/config.in	2004-09-07 13:53:38.000000000 +0900
@@ -410,7 +410,6 @@ fi
 
 if [ "$CONFIG_ALL_PPC" = "y" ]; then
   bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE
-  bool 'Support for RTAS (RunTime Abstraction Services) in /proc' CONFIG_PPC_RTAS
   bool 'Support for PReP Residual Data' CONFIG_PREP_RESIDUAL
   dep_bool '  Support for reading of PReP Residual Data in /proc' CONFIG_PROC_PREPRESIDUAL $CONFIG_PREP_RESIDUAL
   define_bool CONFIG_PPCBUG_NVRAM y
diff -pruN linux-2.4.27-rc4/arch/ppc/kernel/ppc_htab.c linux-2.4.27-rc4.CAN-2004-0415/arch/ppc/kernel/ppc_htab.c
--- linux-2.4.27-rc4/arch/ppc/kernel/ppc_htab.c	2004-02-18 22:36:30.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/ppc/kernel/ppc_htab.c	2004-09-07 13:53:38.000000000 +0900
@@ -112,6 +112,7 @@ static ssize_t ppc_htab_read(struct file
 			     size_t count, loff_t *ppos)
 {
 	unsigned long mmcr0 = 0, pmc1 = 0, pmc2 = 0;
+	loff_t pos = *ppos;
 	int n = 0;
 #if defined(CONFIG_PPC_STD_MMU) && !defined(CONFIG_PPC64BRIDGE)
 	int valid;
@@ -219,14 +220,14 @@ return_string:
 		      "Non-error misses: %lu\n"
 		      "Error misses\t: %lu\n",
 		      pte_misses, pte_errors);
-	if (*ppos >= strlen(buffer))
+	if (pos != (unsigned)pos || pos >= strlen(buffer))
 		return 0;
-	if (n > strlen(buffer) - *ppos)
-		n = strlen(buffer) - *ppos;
+	if (n > strlen(buffer) - pos)
+		n = strlen(buffer) - pos;
 	if (n > count)
 		n = count;
-	copy_to_user(buf, buffer + *ppos, n);
-	*ppos += n;
+	copy_to_user(buf, buffer + pos, n);
+	*ppos = pos + n;
 	return n;
 }
 
diff -pruN linux-2.4.27-rc4/arch/ppc/platforms/Makefile linux-2.4.27-rc4.CAN-2004-0415/arch/ppc/platforms/Makefile
--- linux-2.4.27-rc4/arch/ppc/platforms/Makefile	2004-04-14 22:05:27.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/ppc/platforms/Makefile	2004-09-07 13:53:38.000000000 +0900
@@ -51,7 +51,6 @@ obj-$(CONFIG_ALL_PPC)		+= pmac_pic.o pma
 					prep_time.o prep_setup.o pmac_sleep.o \
 					pmac_nvram.o
 obj-$(CONFIG_PMAC_BACKLIGHT)	+= pmac_backlight.o
-obj-$(CONFIG_PPC_RTAS)		+= error_log.o proc_rtas.o
 obj-$(CONFIG_PREP_RESIDUAL)	+= residual.o
 obj-$(CONFIG_GEMINI)		+= gemini_pci.o gemini_setup.o gemini_prom.o
 obj-$(CONFIG_LOPEC)		+= lopec_setup.o lopec_pci.o
diff -pruN linux-2.4.27-rc4/arch/ppc/platforms/error_log.c linux-2.4.27-rc4.CAN-2004-0415/arch/ppc/platforms/error_log.c
--- linux-2.4.27-rc4/arch/ppc/platforms/error_log.c	2003-08-25 20:44:40.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/ppc/platforms/error_log.c	1970-01-01 09:00:00.000000000 +0900
@@ -1,183 +0,0 @@
-/*
- *  arch/ppc/kernel/error_log.c
- *
- *  Copyright (c) 2000 Tilmann Bitterberg
- *  (tilmann@bitterberg.de)
- *
- *  Error processing of errors found by rtas even-scan routine
- *  which is done with every heartbeat. (chrp_setup.c)
- */
-
-#include <linux/sched.h>
-
-#include <asm/prom.h>
-
-#include "error_log.h"
-
-/* ****************************************************************** */
-/*
- * EVENT-SCAN
- * The whole stuff below here doesn't take any action when it found
- * an error, it just prints as much information as possible and
- * then its up to the user to decide what to do.
- *
- * Returns 0 if no errors were found
- * Returns 1 if there may be more errors
- */
-int ppc_rtas_errorlog_scan(void)
-{
-const char *_errlog_severity[] = {
-#ifdef VERBOSE_ERRORS
-	"No Error\n\t\
-Should require no further information",
-	"Event\n\t\
-This is not really an error, it is an event. I use events\n\t\
-to communicate with RTAS back and forth.",
-	"Warning\n\t\
-Indicates a non-state-losing error, either fully recovered\n\t\
-by RTAS or not needing recovery. Ignore it.",
-	"Error sync\n\t\
-May only be fatal to a certain program or thread. Recovery\n\t\
-and continuation is possible, if I only had a handler for\n\t\
-this. Less serious",
-	"Error\n\t\
-Less serious, but still causing a loss of data and state.\n\t\
-I can't tell you exactly what to do, You have to decide\n\t\
-with help from the target and initiator field, what kind\n\t\
-of further actions may take place.",
-	"Fatal\n\t\
-Represent a permanent hardware failure and I believe this\n\t\
-affects my overall performance and behaviour. I would not\n\t\
-attempt to continue normal operation."
-#else
-	"No Error",
-	"Event",
-	"Warning",
-	"Error sync",
-	"Error",
-	"Fatal"
-#endif /* VERBOSE_ERRORS */
-};
-
-#if 0 /* unused?? */
-const char *_errlog_disposition[] = {
-#ifdef VERBOSE_ERRORS
-	"Fully recovered\n\t\
-There was an error, but it is fully recovered by RTAS.",
-	"Limited recovery\n\t\
-RTAS was able to recover the state of the machine, but some\n\t\
-feature of the machine has been disabled or lost (for example\n\t\
-error checking) or performance may suffer.",
-	"Not recovered\n\t\
-Whether RTAS did not try to recover anything or recovery failed:\n\t\
-HOUSTON, WE HAVE A PROBLEM!"
-#else
-	"Fully recovered",
-	"Limited recovery",
-	"Not recovered"
-#endif /* VERBOSE_ERRORS */
-};
-#endif
-
-const char *_errlog_extended[] = {
-#ifdef VERBOSE_ERRORS
-	"Not present\n\t\
-Sad, the RTAS call didn't return an extended error log.",
-	"Present\n\t\
-The extended log is present and hopefully it contains a lot of\n\t\
-useful information, which leads to the solution of the problem."
-#else
-	"Not present",
-	"Present"
-#endif /* VERBOSE_ERRORS */
-};
-
-const char *_errlog_initiator[] = {
-	"Unknown or not applicable",
-	"CPU",
-	"PCI",
-	"ISA",
-	"Memory",
-	"Power management"
-};
-
-const char *_errlog_target[] = {
-	"Unknown or not applicable",
-	"CPU",
-	"PCI",
-	"ISA",
-	"Memory",
-	"Power management"
-};
-	rtas_error_log error_log;
-	char logdata[1024];
-	int error;
-#if 0 /* unused?? */
-	int retries = 0; /* if HW error, try 10 times */
-#endif
-
-	error = call_rtas ("event-scan", 4, 1, (unsigned long *)&error_log,
-			INTERNAL_ERROR | EPOW_WARNING,
-			0, __pa(logdata), 1024);
-
-	if (error == 1) /* no errors found */
-		return 0;
-
-	if (error == -1) {
-		printk(KERN_ERR "Unable to get errors. Do you a favor and throw this box away\n");
-		return 0;
-	}
-	if (error_log.version != 1)
-		printk(KERN_WARNING "Unknown version (%d), please implement me\n",
-				error_log.version);
-
-	switch (error_log.disposition) {
-		case DISP_FULLY_RECOVERED:
-			/* there was an error, but everything is fine now */
-			return 0;
-		case DISP_NOT_RECOVERED:
-			printk("We have a really serious Problem!\n");
-		case DISP_LIMITED_RECOVERY:
-			printk("Error classification\n");
-			printk("Severity  : %s\n",
-					ppc_rtas_errorlog_check_severity (error_log));
-			printk("Initiator : %s\n",
-					ppc_rtas_errorlog_check_initiator (error_log));
-			printk("Target    : %s\n",
-					ppc_rtas_errorlog_check_target (error_log));
-			printk("Type      : %s\n",
-					ppc_rtas_errorlog_check_type (error_log));
-			printk("Ext. log  : %s\n",
-					ppc_rtas_errorlog_check_extended (error_log));
-			if (error_log.extended)
-				ppc_rtas_errorlog_disect_extended (logdata);
-			return 1;
-		default:
-			/* nothing */
-			break;
-	}
-	return 0;
-}
-/* ****************************************************************** */
-const char * ppc_rtas_errorlog_check_type (rtas_error_log error_log)
-{
-	const char *_errlog_type[] = {
-		"unknown type",
-		"too many tries failed",
-		"TCE error",
-		"RTAS device failed",
-		"target timed out",
-		"parity error on data",			/* 5 */
-		"parity error on address",
-		"parity error on external cache",
-		"access to invalid address",
-		"uncorrectable ECC error",
-		"corrected ECC error"			/* 10 */
-	};
-	if (error_log.type == TYPE_EPOW)
-		return "EPOW";
-	if (error_log.type >= TYPE_PMGM_POWER_SW_ON)
-		return "PowerMGM Event (not handled right now)";
-	return _errlog_type[error_log.type];
-}
-
diff -pruN linux-2.4.27-rc4/arch/ppc/platforms/error_log.h linux-2.4.27-rc4.CAN-2004-0415/arch/ppc/platforms/error_log.h
--- linux-2.4.27-rc4/arch/ppc/platforms/error_log.h	2003-08-25 20:44:40.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/ppc/platforms/error_log.h	1970-01-01 09:00:00.000000000 +0900
@@ -1,95 +0,0 @@
-#ifndef __ERROR_LOG_H__
-#define __ERROR_LOG_H__
-
-#define VERBOSE_ERRORS		1 /* Maybe I enlarge the kernel too much */
-#undef VERBOSE_ERRORS
-
-/* Event classes */
-/* XXX: Endianess correct? NOW*/
-#define INTERNAL_ERROR		0x80000000 /* set bit 0 */
-#define EPOW_WARNING		0x40000000 /* set bit 1 */
-#define POWERMGM_EVENTS		0x20000000 /* set bit 2 */
-
-/* event-scan returns */
-#define SEVERITY_FATAL		0x5
-#define SEVERITY_ERROR		0x4
-#define SEVERITY_ERROR_SYNC	0x3
-#define SEVERITY_WARNING	0x2
-#define SEVERITY_EVENT		0x1
-#define SEVERITY_NO_ERROR	0x0
-#define DISP_FULLY_RECOVERED	0x0
-#define DISP_LIMITED_RECOVERY	0x1
-#define DISP_NOT_RECOVERED	0x2
-#define PART_PRESENT		0x0
-#define PART_NOT_PRESENT	0x1
-#define INITIATOR_UNKNOWN	0x0
-#define INITIATOR_CPU		0x1
-#define INITIATOR_PCI		0x2
-#define INITIATOR_ISA		0x3
-#define INITIATOR_MEMORY	0x4
-#define INITIATOR_POWERMGM	0x5
-#define TARGET_UNKNOWN		0x0
-#define TARGET_CPU		0x1
-#define TARGET_PCI		0x2
-#define TARGET_ISA		0x3
-#define TARGET_MEMORY		0x4
-#define TARGET_POWERMGM		0x5
-#define TYPE_RETRY		0x01
-#define TYPE_TCE_ERR		0x02
-#define TYPE_INTERN_DEV_FAIL	0x03
-#define TYPE_TIMEOUT		0x04
-#define TYPE_DATA_PARITY	0x05
-#define TYPE_ADDR_PARITY	0x06
-#define TYPE_CACHE_PARITY	0x07
-#define TYPE_ADDR_INVALID	0x08
-#define TYPE_ECC_UNCORR		0x09
-#define TYPE_ECC_CORR		0x0a
-#define TYPE_EPOW		0x40
-/* I don't add PowerMGM events right now, this is a different topic */
-#define TYPE_PMGM_POWER_SW_ON	0x60
-#define TYPE_PMGM_POWER_SW_OFF	0x61
-#define TYPE_PMGM_LID_OPEN	0x62
-#define TYPE_PMGM_LID_CLOSE	0x63
-#define TYPE_PMGM_SLEEP_BTN	0x64
-#define TYPE_PMGM_WAKE_BTN	0x65
-#define TYPE_PMGM_BATTERY_WARN	0x66
-#define TYPE_PMGM_BATTERY_CRIT	0x67
-#define TYPE_PMGM_SWITCH_TO_BAT	0x68
-#define TYPE_PMGM_SWITCH_TO_AC	0x69
-#define TYPE_PMGM_KBD_OR_MOUSE	0x6a
-#define TYPE_PMGM_ENCLOS_OPEN	0x6b
-#define TYPE_PMGM_ENCLOS_CLOSED	0x6c
-#define TYPE_PMGM_RING_INDICATE	0x6d
-#define TYPE_PMGM_LAN_ATTENTION	0x6e
-#define TYPE_PMGM_TIME_ALARM	0x6f
-#define TYPE_PMGM_CONFIG_CHANGE	0x70
-#define TYPE_PMGM_SERVICE_PROC	0x71
-
-typedef struct _rtas_error_log {
-	unsigned long version:8;		/* Architectural version */
-	unsigned long severity:3;		/* Severity level of error */
-	unsigned long disposition:2;		/* Degree of recovery */
-	unsigned long extended:1;		/* extended log present? */
-	unsigned long /* reserved */ :2;	/* Reserved for future use */
-	unsigned long initiator:4;		/* Initiator of event */
-	unsigned long target:4;			/* Target of failed operation */
-	unsigned long type:8;			/* General event or error*/
-	unsigned long extended_log_length:32;	/* length in bytes */
-} rtas_error_log;
-
-/* ****************************************************************** */
-#define ppc_rtas_errorlog_check_severity(x) \
-	(_errlog_severity[x.severity])
-#define ppc_rtas_errorlog_check_target(x) \
-	(_errlog_target[x.target])
-#define ppc_rtas_errorlog_check_initiator(x) \
-	(_errlog_initiator[x.initiator])
-#define ppc_rtas_errorlog_check_extended(x) \
-	(_errlog_extended[x.extended])
-#define ppc_rtas_errorlog_disect_extended(x) \
-	do { /* implement me */ } while(0)
-extern const char * ppc_rtas_errorlog_check_type (rtas_error_log error_log);
-extern int ppc_rtas_errorlog_scan(void);
-
-
-#endif /* __ERROR_LOG_H__ */
diff -pruN linux-2.4.27-rc4/arch/ppc/platforms/proc_rtas.c linux-2.4.27-rc4.CAN-2004-0415/arch/ppc/platforms/proc_rtas.c
--- linux-2.4.27-rc4/arch/ppc/platforms/proc_rtas.c	2003-08-25 20:44:40.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/ppc/platforms/proc_rtas.c	1970-01-01 09:00:00.000000000 +0900
@@ -1,784 +0,0 @@
-/*
- *   arch/ppc/kernel/proc_rtas.c
- *   Copyright (C) 2000 Tilmann Bitterberg
- *   (tilmann@bitterberg.de)
- *
- *   RTAS (Runtime Abstraction Services) stuff
- *   Intention is to provide a clean user interface
- *   to use the RTAS.
- *
- *   TODO:
- *   Split off a header file and maybe move it to a different
- *   location. Write Documentation on what the /proc/rtas/ entries
- *   actually do.
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <linux/ctype.h>
-#include <linux/time.h>
-#include <linux/string.h>
-
-#include <asm/uaccess.h>
-#include <asm/bitops.h>
-#include <asm/processor.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/machdep.h> /* for ppc_md */
-#include <asm/time.h>
-
-/* Token for Sensors */
-#define KEY_SWITCH		0x0001
-#define ENCLOSURE_SWITCH	0x0002
-#define THERMAL_SENSOR		0x0003
-#define LID_STATUS		0x0004
-#define POWER_SOURCE		0x0005
-#define BATTERY_VOLTAGE		0x0006
-#define BATTERY_REMAINING	0x0007
-#define BATTERY_PERCENTAGE	0x0008
-#define EPOW_SENSOR		0x0009
-#define BATTERY_CYCLESTATE	0x000a
-#define BATTERY_CHARGING	0x000b
-
-/* IBM specific sensors */
-#define IBM_SURVEILLANCE	0x2328 /* 9000 */
-#define IBM_FANRPM		0x2329 /* 9001 */
-#define IBM_VOLTAGE		0x232a /* 9002 */
-#define IBM_DRCONNECTOR		0x232b /* 9003 */
-#define IBM_POWERSUPPLY		0x232c /* 9004 */
-#define IBM_INTQUEUE		0x232d /* 9005 */
-
-/* Status return values */
-#define SENSOR_CRITICAL_HIGH	13
-#define SENSOR_WARNING_HIGH	12
-#define SENSOR_NORMAL		11
-#define SENSOR_WARNING_LOW	10
-#define SENSOR_CRITICAL_LOW	 9
-#define SENSOR_SUCCESS		 0
-#define SENSOR_HW_ERROR		-1
-#define SENSOR_BUSY		-2
-#define SENSOR_NOT_EXIST	-3
-#define SENSOR_DR_ENTITY	-9000
-
-/* Location Codes */
-#define LOC_SCSI_DEV_ADDR	'A'
-#define LOC_SCSI_DEV_LOC	'B'
-#define LOC_CPU			'C'
-#define LOC_DISKETTE		'D'
-#define LOC_ETHERNET		'E'
-#define LOC_FAN			'F'
-#define LOC_GRAPHICS		'G'
-/* reserved / not used		'H' */
-#define LOC_IO_ADAPTER		'I'
-/* reserved / not used		'J' */
-#define LOC_KEYBOARD		'K'
-#define LOC_LCD			'L'
-#define LOC_MEMORY		'M'
-#define LOC_NV_MEMORY		'N'
-#define LOC_MOUSE		'O'
-#define LOC_PLANAR		'P'
-#define LOC_OTHER_IO		'Q'
-#define LOC_PARALLEL		'R'
-#define LOC_SERIAL		'S'
-#define LOC_DEAD_RING		'T'
-#define LOC_RACKMOUNTED		'U' /* for _u_nit is rack mounted */
-#define LOC_VOLTAGE		'V'
-#define LOC_SWITCH_ADAPTER	'W'
-#define LOC_OTHER		'X'
-#define LOC_FIRMWARE		'Y'
-#define LOC_SCSI		'Z'
-
-/* Tokens for indicators */
-#define TONE_FREQUENCY		0x0001 /* 0 - 1000 (HZ)*/
-#define TONE_VOLUME		0x0002 /* 0 - 100 (%) */
-#define SYSTEM_POWER_STATE	0x0003
-#define WARNING_LIGHT		0x0004
-#define DISK_ACTIVITY_LIGHT	0x0005
-#define HEX_DISPLAY_UNIT	0x0006
-#define BATTERY_WARNING_TIME	0x0007
-#define CONDITION_CYCLE_REQUEST	0x0008
-#define SURVEILLANCE_INDICATOR	0x2328 /* 9000 */
-#define DR_ACTION		0x2329 /* 9001 */
-#define DR_INDICATOR		0x232a /* 9002 */
-/* 9003 - 9004: Vendor specific */
-#define GLOBAL_INTERRUPT_QUEUE	0x232d /* 9005 */
-/* 9006 - 9999: Vendor specific */
-
-/* other */
-#define MAX_SENSORS		 17  /* I only know of 17 sensors */
-#define MAX_LINELENGTH          256
-#define SENSOR_PREFIX		"ibm,sensor-"
-#define cel_to_fahr(x)		((x*9/5)+32)
-
-
-/* Globals */
-static struct proc_dir_entry *proc_rtas;
-static struct rtas_sensors sensors;
-static struct device_node *rtas;
-static unsigned long power_on_time = 0; /* Save the time the user set */
-static char progress_led[MAX_LINELENGTH];
-
-static unsigned long rtas_tone_frequency = 1000;
-static unsigned long rtas_tone_volume = 0;
-
-/* ****************STRUCTS******************************************* */
-struct individual_sensor {
-	unsigned int token;
-	unsigned int quant;
-};
-
-struct rtas_sensors {
-        struct individual_sensor sensor[MAX_SENSORS];
-	unsigned int quant;
-};
-
-/* ****************************************************************** */
-/* Declarations */
-static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off,
-		int count, int *eof, void *data);
-static ssize_t ppc_rtas_clock_read(struct file * file, char * buf,
-		size_t count, loff_t *ppos);
-static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf,
-		size_t count, loff_t *ppos);
-static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
-		size_t count, loff_t *ppos);
-static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf,
-		size_t count, loff_t *ppos);
-static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf,
-		size_t count, loff_t *ppos);
-static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf,
-		size_t count, loff_t *ppos);
-
-static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf,
-		size_t count, loff_t *ppos);
-static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf,
-		size_t count, loff_t *ppos);
-static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf,
-		size_t count, loff_t *ppos);
-static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,
-		size_t count, loff_t *ppos);
-
-struct file_operations ppc_rtas_poweron_operations = {
-	read:		ppc_rtas_poweron_read,
-	write:		ppc_rtas_poweron_write
-};
-struct file_operations ppc_rtas_progress_operations = {
-	read:		ppc_rtas_progress_read,
-	write:		ppc_rtas_progress_write
-};
-
-struct file_operations ppc_rtas_clock_operations = {
-	read:		ppc_rtas_clock_read,
-	write:		ppc_rtas_clock_write
-};
-
-struct file_operations ppc_rtas_tone_freq_operations = {
-	read:		ppc_rtas_tone_freq_read,
-	write:		ppc_rtas_tone_freq_write
-};
-struct file_operations ppc_rtas_tone_volume_operations = {
-	read:		ppc_rtas_tone_volume_read,
-	write:		ppc_rtas_tone_volume_write
-};
-
-int ppc_rtas_find_all_sensors (void);
-int ppc_rtas_process_sensor(struct individual_sensor s, int state,
-		int error, char * buf);
-char * ppc_rtas_process_error(int error);
-int get_location_code(struct individual_sensor s, char * buf);
-int check_location_string (char *c, char * buf);
-int check_location (char *c, int idx, char * buf);
-
-/* ****************************************************************** */
-/* MAIN                                                               */
-/* ****************************************************************** */
-void proc_rtas_init(void)
-{
-	struct proc_dir_entry *entry;
-
-	rtas = find_devices("rtas");
-	if ((rtas == 0) || (_machine != _MACH_chrp)) {
-		return;
-	}
-
-	proc_rtas = proc_mkdir("rtas", 0);
-	if (proc_rtas == 0)
-		return;
-
-	/* /proc/rtas entries */
-
-	entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, proc_rtas);
-	if (entry) entry->proc_fops = &ppc_rtas_progress_operations;
-
-	entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, proc_rtas);
-	if (entry) entry->proc_fops = &ppc_rtas_clock_operations;
-
-	entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_rtas);
-	if (entry) entry->proc_fops = &ppc_rtas_poweron_operations;
-
-	create_proc_read_entry("sensors", S_IRUGO, proc_rtas,
-			ppc_rtas_sensor_read, NULL);
-
-	entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, proc_rtas);
-	if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations;
-
-	entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_rtas);
-	if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations;
-}
-
-/* ****************************************************************** */
-/* POWER-ON-TIME                                                      */
-/* ****************************************************************** */
-static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf,
-		size_t count, loff_t *ppos)
-{
-	struct rtc_time tm;
-	unsigned long nowtime;
-	char *dest;
-	int error;
-
-	nowtime = simple_strtoul(buf, &dest, 10);
-	if (*dest != '\0' && *dest != '\n') {
-		printk("ppc_rtas_poweron_write: Invalid time\n");
-		return count;
-	}
-	power_on_time = nowtime; /* save the time */
-
-	to_tm(nowtime, &tm);
-
-	error = call_rtas("set-time-for-power-on", 7, 1, NULL,
-			tm.tm_year, tm.tm_mon, tm.tm_mday,
-			tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */);
-	if (error != 0)
-		printk(KERN_WARNING "error: setting poweron time returned: %s\n",
-				ppc_rtas_process_error(error));
-	return count;
-}
-/* ****************************************************************** */
-static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf,
-		size_t count, loff_t *ppos)
-{
-	int n;
-	if (power_on_time == 0)
-		n = sprintf(buf, "Power on time not set\n");
-	else
-		n = sprintf(buf, "%lu\n", power_on_time);
-
-	if (*ppos >= strlen(buf))
-		return 0;
-	if (n > strlen(buf) - *ppos)
-		n = strlen(buf) - *ppos;
-	if (n > count)
-		n = count;
-	*ppos += n;
-	return n;
-}
-
-/* ****************************************************************** */
-/* PROGRESS                                                           */
-/* ****************************************************************** */
-static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf,
-		size_t count, loff_t *ppos)
-{
-	unsigned long hex;
-
-	strcpy(progress_led, buf); /* save the string */
-	/* Lets see if the user passed hexdigits */
-	hex = simple_strtoul(buf, NULL, 10);
-
-	ppc_md.progress ((char *)buf, hex);
-	return count;
-
-	/* clear the line */ /* ppc_md.progress("                   ", 0xffff);*/
-}
-/* ****************************************************************** */
-static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
-		size_t count, loff_t *ppos)
-{
-	int n = 0;
-	if (progress_led != NULL)
-		n = sprintf (buf, "%s\n", progress_led);
-	if (*ppos >= strlen(buf))
-		return 0;
-	if (n > strlen(buf) - *ppos)
-		n = strlen(buf) - *ppos;
-	if (n > count)
-		n = count;
-	*ppos += n;
-	return n;
-}
-
-/* ****************************************************************** */
-/* CLOCK                                                              */
-/* ****************************************************************** */
-static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf,
-		size_t count, loff_t *ppos)
-{
-	struct rtc_time tm;
-	unsigned long nowtime;
-	char *dest;
-	int error;
-
-	nowtime = simple_strtoul(buf, &dest, 10);
-	if (*dest != '\0' && *dest != '\n') {
-		printk("ppc_rtas_clock_write: Invalid time\n");
-		return count;
-	}
-
-	to_tm(nowtime, &tm);
-	error = call_rtas("set-time-of-day", 7, 1, NULL,
-			tm.tm_year, tm.tm_mon, tm.tm_mday,
-			tm.tm_hour, tm.tm_min, tm.tm_sec, 0);
-	if (error != 0)
-		printk(KERN_WARNING "error: setting the clock returned: %s\n",
-				ppc_rtas_process_error(error));
-	return count;
-}
-/* ****************************************************************** */
-static ssize_t ppc_rtas_clock_read(struct file * file, char * buf,
-		size_t count, loff_t *ppos)
-{
-	unsigned int year, mon, day, hour, min, sec;
-	unsigned long *ret = kmalloc(4*8, GFP_KERNEL);
-	int n, error;
-
-	error = call_rtas("get-time-of-day", 0, 8, ret);
-
-	year = ret[0]; mon  = ret[1]; day  = ret[2];
-	hour = ret[3]; min  = ret[4]; sec  = ret[5];
-
-	if (error != 0){
-		printk(KERN_WARNING "error: reading the clock returned: %s\n",
-				ppc_rtas_process_error(error));
-		n = sprintf (buf, "0");
-	} else {
-		n = sprintf (buf, "%lu\n", mktime(year, mon, day, hour, min, sec));
-	}
-	kfree(ret);
-
-	if (*ppos >= strlen(buf))
-		return 0;
-	if (n > strlen(buf) - *ppos)
-		n = strlen(buf) - *ppos;
-	if (n > count)
-		n = count;
-	*ppos += n;
-	return n;
-}
-
-/* ****************************************************************** */
-/* SENSOR STUFF                                                       */
-/* ****************************************************************** */
-static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off,
-		int count, int *eof, void *data)
-{
-	int i,j,n;
-	unsigned long ret;
-	int state, error;
-	char buffer[MAX_LINELENGTH*MAX_SENSORS]; /* May not be enough */
-
-	if (count < 0)
-		return -EINVAL;
-
-	n  = sprintf ( buffer  , "RTAS (RunTime Abstraction Services) Sensor Information\n");
-	n += sprintf ( buffer+n, "Sensor\t\tValue\t\tCondition\tLocation\n");
-	n += sprintf ( buffer+n, "********************************************************\n");
-
-	if (ppc_rtas_find_all_sensors() != 0) {
-		n += sprintf ( buffer+n, "\nNo sensors are available\n");
-		goto return_string;
-	}
-
-	for (i=0; i<sensors.quant; i++) {
-		j = sensors.sensor[i].quant;
-		/* A sensor may have multiple instances */
-		while (j >= 0) {
-			error =	call_rtas("get-sensor-state", 2, 2, &ret,
-				  sensors.sensor[i].token, sensors.sensor[i].quant-j);
-			state = (int) ret;
-			n += ppc_rtas_process_sensor(sensors.sensor[i], state, error, buffer+n );
-			n += sprintf (buffer+n, "\n");
-			j--;
-		} /* while */
-	} /* for */
-
-return_string:
-	if (off >= strlen(buffer)) {
-		*eof = 1;
-		return 0;
-	}
-	if (n > strlen(buffer) - off)
-		n = strlen(buffer) - off;
-	if (n > count)
-		n = count;
-	else
-		*eof = 1;
-	memcpy(buf, buffer + off, n);
-	*start = buf;
-	return n;
-}
-
-/* ****************************************************************** */
-
-int ppc_rtas_find_all_sensors (void)
-{
-	unsigned long *utmp;
-	int len, i, j;
-
-	utmp = (unsigned long *) get_property(rtas, "rtas-sensors", &len);
-	if (utmp == NULL) {
-		printk (KERN_ERR "error: could not get rtas-sensors\n");
-		return 1;
-	}
-
-	sensors.quant = len / 8;      /* int + int */
-
-	for (i=0, j=0; j<sensors.quant; i+=2, j++) {
-		sensors.sensor[j].token = utmp[i];
-		sensors.sensor[j].quant = utmp[i+1];
-	}
-	return 0;
-}
-
-/* ****************************************************************** */
-/*
- * Builds a string of what rtas returned
- */
-char * ppc_rtas_process_error(int error)
-{
-	switch (error) {
-		case SENSOR_CRITICAL_HIGH:
-			return "(critical high)";
-		case SENSOR_WARNING_HIGH:
-			return "(warning high)";
-		case SENSOR_NORMAL:
-			return "(normal)";
-		case SENSOR_WARNING_LOW:
-			return "(warning low)";
-		case SENSOR_CRITICAL_LOW:
-			return "(critical low)";
-		case SENSOR_SUCCESS:
-			return "(read ok)";
-		case SENSOR_HW_ERROR:
-			return "(hardware error)";
-		case SENSOR_BUSY:
-			return "(busy)";
-		case SENSOR_NOT_EXIST:
-			return "(non existant)";
-		case SENSOR_DR_ENTITY:
-			return "(dr entity removed)";
-		default:
-			return "(UNKNOWN)";
-	}
-}
-
-/* ****************************************************************** */
-/*
- * Builds a string out of what the sensor said
- */
-
-int ppc_rtas_process_sensor(struct individual_sensor s, int state,
-		int error, char * buf)
-{
-	/* Defined return vales */
-	const char * key_switch[]        = { "Off\t", "Normal\t", "Secure\t", "Mainenance" };
-	const char * enclosure_switch[]  = { "Closed", "Open" };
-	const char * lid_status[]        = { " ", "Open", "Closed" };
-	const char * power_source[]      = { "AC\t", "Battery", "AC & Battery" };
-	const char * battery_remaining[] = { "Very Low", "Low", "Mid", "High" };
-	const char * epow_sensor[]       = {
-		"EPOW Reset", "Cooling warning", "Power warning",
-		"System shutdown", "System halt", "EPOW main enclosure",
-		"EPOW power off" };
-	const char * battery_cyclestate[]  = { "None", "In progress", "Requested" };
-	const char * battery_charging[]    = { "Charging", "Discharching", "No current flow" };
-	const char * ibm_drconnector[]     = { "Empty", "Present" };
-	const char * ibm_intqueue[]        = { "Disabled", "Enabled" };
-
-	int have_strings = 0;
-	int temperature = 0;
-	int unknown = 0;
-	int n = 0;
-
-	/* What kind of sensor do we have here? */
-	switch (s.token) {
-		case KEY_SWITCH:
-			n += sprintf(buf+n, "Key switch:\t");
-			n += sprintf(buf+n, "%s\t", key_switch[state]);
-			have_strings = 1;
-			break;
-		case ENCLOSURE_SWITCH:
-			n += sprintf(buf+n, "Enclosure switch:\t");
-			n += sprintf(buf+n, "%s\t", enclosure_switch[state]);
-			have_strings = 1;
-			break;
-		case THERMAL_SENSOR:
-			n += sprintf(buf+n, "Temp. (°C/°F):\t");
-			temperature = 1;
-			break;
-		case LID_STATUS:
-			n += sprintf(buf+n, "Lid status:\t");
-			n += sprintf(buf+n, "%s\t", lid_status[state]);
-			have_strings = 1;
-			break;
-		case POWER_SOURCE:
-			n += sprintf(buf+n, "Power source:\t");
-			n += sprintf(buf+n, "%s\t", power_source[state]);
-			have_strings = 1;
-			break;
-		case BATTERY_VOLTAGE:
-			n += sprintf(buf+n, "Battery voltage:\t");
-			break;
-		case BATTERY_REMAINING:
-			n += sprintf(buf+n, "Battery remaining:\t");
-			n += sprintf(buf+n, "%s\t", battery_remaining[state]);
-			have_strings = 1;
-			break;
-		case BATTERY_PERCENTAGE:
-			n += sprintf(buf+n, "Battery percentage:\t");
-			break;
-		case EPOW_SENSOR:
-			n += sprintf(buf+n, "EPOW Sensor:\t");
-			n += sprintf(buf+n, "%s\t", epow_sensor[state]);
-			have_strings = 1;
-			break;
-		case BATTERY_CYCLESTATE:
-			n += sprintf(buf+n, "Battery cyclestate:\t");
-			n += sprintf(buf+n, "%s\t", battery_cyclestate[state]);
-			have_strings = 1;
-			break;
-		case BATTERY_CHARGING:
-			n += sprintf(buf+n, "Battery Charging:\t");
-			n += sprintf(buf+n, "%s\t", battery_charging[state]);
-			have_strings = 1;
-			break;
-		case IBM_SURVEILLANCE:
-			n += sprintf(buf+n, "Surveillance:\t");
-			break;
-		case IBM_FANRPM:
-			n += sprintf(buf+n, "Fan (rpm):\t");
-			break;
-		case IBM_VOLTAGE:
-			n += sprintf(buf+n, "Voltage (mv):\t");
-			break;
-		case IBM_DRCONNECTOR:
-			n += sprintf(buf+n, "DR connector:\t");
-			n += sprintf(buf+n, "%s\t", ibm_drconnector[state]);
-			have_strings = 1;
-			break;
-		case IBM_POWERSUPPLY:
-			n += sprintf(buf+n, "Powersupply:\t");
-			break;
-		case IBM_INTQUEUE:
-			n += sprintf(buf+n, "Interrupt queue:\t");
-			n += sprintf(buf+n, "%s\t", ibm_intqueue[state]);
-			have_strings = 1;
-			break;
-		default:
-			n += sprintf(buf+n,  "Unkown sensor (type %d), ignoring it\n",
-					s.token);
-			unknown = 1;
-			have_strings = 1;
-			break;
-	}
-	if (have_strings == 0) {
-		if (temperature) {
-			n += sprintf(buf+n, "%4d /%4d\t", state, cel_to_fahr(state));
-		} else
-			n += sprintf(buf+n, "%10d\t", state);
-	}
-	if (unknown == 0) {
-		n += sprintf ( buf+n, "%s\t", ppc_rtas_process_error(error));
-		n += get_location_code(s, buf+n);
-	}
-	return n;
-}
-
-/* ****************************************************************** */
-
-int check_location (char *c, int idx, char * buf)
-{
-	int n = 0;
-
-	switch (*(c+idx)) {
-		case LOC_PLANAR:
-			n += sprintf ( buf, "Planar #%c", *(c+idx+1));
-			break;
-		case LOC_CPU:
-			n += sprintf ( buf, "CPU #%c", *(c+idx+1));
-			break;
-		case LOC_FAN:
-			n += sprintf ( buf, "Fan #%c", *(c+idx+1));
-			break;
-		case LOC_RACKMOUNTED:
-			n += sprintf ( buf, "Rack #%c", *(c+idx+1));
-			break;
-		case LOC_VOLTAGE:
-			n += sprintf ( buf, "Voltage #%c", *(c+idx+1));
-			break;
-		case LOC_LCD:
-			n += sprintf ( buf, "LCD #%c", *(c+idx+1));
-			break;
-		case '.':
-			n += sprintf ( buf, "- %c", *(c+idx+1));
-		default:
-			n += sprintf ( buf, "Unknown location");
-			break;
-	}
-	return n;
-}
-
-
-/* ****************************************************************** */
-/*
- * Format:
- * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ]
- * the '.' may be an abbrevation
- */
-int check_location_string (char *c, char *buf)
-{
-	int n=0,i=0;
-
-	while (c[i]) {
-		if (isalpha(c[i]) || c[i] == '.') {
-			 n += check_location(c, i, buf+n);
-		}
-		else if (c[i] == '/' || c[i] == '-')
-			n += sprintf(buf+n, " at ");
-		i++;
-	}
-	return n;
-}
-
-
-/* ****************************************************************** */
-
-int get_location_code(struct individual_sensor s, char * buffer)
-{
-	char rstr[512], tmp[10], tmp2[10];
-	int n=0, i=0, llen, len;
-	/* char *buf = kmalloc(MAX_LINELENGTH, GFP_KERNEL); */
-	char *ret;
-
-	static int pos = 0; /* remember position where buffer was */
-
-	/* construct the sensor number like 0003 */
-	/* fill with zeros */
-	n = sprintf(tmp, "%d", s.token);
-	len = strlen(tmp);
-	while (strlen(tmp) < 4)
-		n += sprintf (tmp+n, "0");
-
-	/* invert the string */
-	while (tmp[i]) {
-		if (i<len)
-			tmp2[4-len+i] = tmp[i];
-		else
-			tmp2[3-i] = tmp[i];
-		i++;
-	}
-	tmp2[4] = '\0';
-
-	sprintf (rstr, SENSOR_PREFIX"%s", tmp2);
-
-	ret = (char *) get_property(rtas, rstr, &llen);
-
-	n=0;
-	if (ret[0] == '\0')
-		n += sprintf ( buffer+n, "--- ");/* does not have a location */
-	else {
-		char t[50];
-		ret += pos;
-
-		n += check_location_string(ret, buffer + n);
-		n += sprintf ( buffer+n, " ");
-		/* see how many characters we have printed */
-		sprintf ( t, "%s ", ret);
-
-		pos += strlen(t);
-		if (pos >= llen) pos=0;
-	}
-	return n;
-}
-/* ****************************************************************** */
-/* INDICATORS - Tone Frequency                                        */
-/* ****************************************************************** */
-static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf,
-		size_t count, loff_t *ppos)
-{
-	unsigned long freq;
-	char *dest;
-	int error;
-	freq = simple_strtoul(buf, &dest, 10);
-	if (*dest != '\0' && *dest != '\n') {
-		printk("ppc_rtas_tone_freq_write: Invalid tone freqency\n");
-		return count;
-	}
-	if (freq < 0) freq = 0;
-	rtas_tone_frequency = freq; /* save it for later */
-	error = call_rtas("set-indicator", 3, 1, NULL,
-			TONE_FREQUENCY, 0, freq);
-	if (error != 0)
-		printk(KERN_WARNING "error: setting tone frequency returned: %s\n",
-				ppc_rtas_process_error(error));
-	return count;
-}
-/* ****************************************************************** */
-static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf,
-		size_t count, loff_t *ppos)
-{
-	int n;
-	n = sprintf(buf, "%lu\n", rtas_tone_frequency);
-
-	if (*ppos >= strlen(buf))
-		return 0;
-	if (n > strlen(buf) - *ppos)
-		n = strlen(buf) - *ppos;
-	if (n > count)
-		n = count;
-	*ppos += n;
-	return n;
-}
-/* ****************************************************************** */
-/* INDICATORS - Tone Volume                                           */
-/* ****************************************************************** */
-static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf,
-		size_t count, loff_t *ppos)
-{
-	unsigned long volume;
-	char *dest;
-	int error;
-	volume = simple_strtoul(buf, &dest, 10);
-	if (*dest != '\0' && *dest != '\n') {
-		printk("ppc_rtas_tone_volume_write: Invalid tone volume\n");
-		return count;
-	}
-	if (volume < 0) volume = 0;
-	if (volume > 100) volume = 100;
-
-        rtas_tone_volume = volume; /* save it for later */
-	error = call_rtas("set-indicator", 3, 1, NULL,
-			TONE_VOLUME, 0, volume);
-	if (error != 0)
-		printk(KERN_WARNING "error: setting tone volume returned: %s\n",
-				ppc_rtas_process_error(error));
-	return count;
-}
-/* ****************************************************************** */
-static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,
-		size_t count, loff_t *ppos)
-{
-	int n;
-	n = sprintf(buf, "%lu\n", rtas_tone_volume);
-
-	if (*ppos >= strlen(buf))
-		return 0;
-	if (n > strlen(buf) - *ppos)
-		n = strlen(buf) - *ppos;
-	if (n > count)
-		n = count;
-	*ppos += n;
-	return n;
-}
diff -pruN linux-2.4.27-rc4/arch/ppc64/kernel/lparcfg.c linux-2.4.27-rc4.CAN-2004-0415/arch/ppc64/kernel/lparcfg.c
--- linux-2.4.27-rc4/arch/ppc64/kernel/lparcfg.c	2004-04-14 22:05:27.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/ppc64/kernel/lparcfg.c	2004-09-07 13:53:38.000000000 +0900
@@ -415,7 +415,7 @@ static ssize_t lparcfg_read(struct file 
 	pnt = (char *)(data) + p;
 	copy_to_user(buf, (void *)pnt, count);
 	read += count;
-	*ppos += read;
+	*ppos = p + read;
 	return read;
 }
 
diff -pruN linux-2.4.27-rc4/arch/ppc64/kernel/nvram.c linux-2.4.27-rc4.CAN-2004-0415/arch/ppc64/kernel/nvram.c
--- linux-2.4.27-rc4/arch/ppc64/kernel/nvram.c	2004-02-18 22:36:30.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/ppc64/kernel/nvram.c	2004-09-07 13:53:38.000000000 +0900
@@ -78,11 +78,12 @@ static ssize_t dev_ppc64_read_nvram(stru
 			  size_t count, loff_t *ppos)
 {
 	unsigned long len;
-	char *tmp_buffer;
+	char *tmp_buffer; 
+	loff_t pos = *ppos;
 
 	if (verify_area(VERIFY_WRITE, buf, count))
 		return -EFAULT;
-	if (*ppos >= rtas_nvram_size)
+	if ((unsigned)pos != pos || pos >= rtas_nvram_size)
 		return 0;
 	if (count > rtas_nvram_size)
 		count = rtas_nvram_size;
@@ -93,7 +94,7 @@ static ssize_t dev_ppc64_read_nvram(stru
 		return 0;
 	}
 
-	len = read_nvram(tmp_buffer, count, ppos);
+	len = read_nvram(tmp_buffer, count, &pos);
 	if ((long)len <= 0) {
 		kfree(tmp_buffer);
 		return len;
@@ -105,6 +106,7 @@ static ssize_t dev_ppc64_read_nvram(stru
 	}
 
 	kfree(tmp_buffer);
+	*ppos = pos;
 	return len;
 
 }
@@ -114,10 +116,11 @@ static ssize_t dev_ppc64_write_nvram(str
 {
 	unsigned long len;
 	char * tmp_buffer;
+	loff_t pos = *ppos;
 
 	if (verify_area(VERIFY_READ, buf, count))
 		return -EFAULT;
-	if (*ppos >= rtas_nvram_size)
+	if (pos != (unsigned) pos || pos >= rtas_nvram_size)
 		return 0;
 	if (count > rtas_nvram_size)
 		count = rtas_nvram_size;
@@ -133,7 +136,8 @@ static ssize_t dev_ppc64_write_nvram(str
 		return -EFAULT;
 	}
 
-	len = write_nvram(tmp_buffer, count, ppos);
+	len = write_nvram(tmp_buffer, count, &pos);
+	*ppos = pos;
 
 	kfree(tmp_buffer);
 	return len;
diff -pruN linux-2.4.27-rc4/arch/ppc64/kernel/proc_pmc.c linux-2.4.27-rc4.CAN-2004-0415/arch/ppc64/kernel/proc_pmc.c
--- linux-2.4.27-rc4/arch/ppc64/kernel/proc_pmc.c	2004-02-18 22:36:30.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/ppc64/kernel/proc_pmc.c	2004-09-07 13:53:38.000000000 +0900
@@ -445,8 +445,9 @@ static ssize_t read_profile(struct file 
 	}
 	pnt = (char *)(perfmon_base.profile_buffer) + p - sizeof(unsigned int);
 	copy_to_user(buf,(void *)pnt,count);
+	p += count;
 	read += count;
-	*ppos += read;
+	*ppos = p;
 	return read;
 }
 
@@ -460,19 +461,17 @@ static ssize_t read_trace(struct file *f
 			    size_t count, loff_t *ppos)
 {
 	unsigned long p = *ppos;
-	ssize_t read;
 	char * pnt;
 
 	if (p >= (perfmon_base.trace_length)) return 0;
 	if (count > (perfmon_base.trace_length) - p)
 		count = (perfmon_base.trace_length) - p;
-	read = 0;
 
 	pnt = (char *)(perfmon_base.trace_buffer) + p;
 	copy_to_user(buf,(void *)pnt,count);
-	read += count;
-	*ppos += read;
-	return read;
+	p += count;
+	*ppos = p;
+	return count;
 }
 
 static ssize_t write_trace(struct file * file, const char * buf,
@@ -491,13 +490,11 @@ static ssize_t read_timeslice(struct fil
 	if (p >= (perfmon_base.timeslice_length)) return 0;
 	if (count > (perfmon_base.timeslice_length) - p)
 		count = (perfmon_base.timeslice_length) - p;
-	read = 0;
 
 	pnt = (char *)(perfmon_base.timeslice_buffer) + p;
 	copy_to_user(buf,(void *)pnt,count);
-	read += count;
-	*ppos += read;
-	return read;
+	*ppos = p + count;
+	return count;
 }
 
 static ssize_t write_timeslice(struct file * file, const char * buf,
diff -pruN linux-2.4.27-rc4/arch/ppc64/kernel/rtas-proc.c linux-2.4.27-rc4.CAN-2004-0415/arch/ppc64/kernel/rtas-proc.c
--- linux-2.4.27-rc4/arch/ppc64/kernel/rtas-proc.c	2004-02-18 22:36:30.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/ppc64/kernel/rtas-proc.c	2004-09-07 17:56:40.000000000 +0900
@@ -337,6 +337,7 @@ static ssize_t ppc_rtas_poweron_read(str
 {
 	char stkbuf[40];  /* its small, its on stack */
 	int n;
+	loff_t pos = *ppos;
 
 	if (power_on_time == 0)
 		n = snprintf(stkbuf, 40, "Power on time not set\n");
@@ -344,15 +345,15 @@ static ssize_t ppc_rtas_poweron_read(str
 		n = snprintf(stkbuf, 40, "%lu\n", power_on_time);
 
 	int sn = strlen(stkbuf) +1;
-	if (*ppos >= sn)
+	if (pos != (unsigned)pos || pos >= sn)
 		return 0;
-	if (n > sn - *ppos)
-		n = sn - *ppos;
+	if (n > sn - pos)
+		n = sn - pos;
 	if (n > count)
 		n = count;
-	if (copy_to_user(buf, stkbuf + (*ppos), n))
+	if (copy_to_user(buf, stkbuf + pos, n))
 		return -EFAULT;
-	*ppos += n;
+	*ppos = pos + n;
 	return n;
 }
 
@@ -384,6 +385,7 @@ static ssize_t ppc_rtas_progress_read(st
 		size_t count, loff_t *ppos)
 {
 	int n = 0, sn;
+	loff_t pos = *ppos;
 	
 	if (progress_led == NULL)
 		return 0;
@@ -396,20 +398,20 @@ static ssize_t ppc_rtas_progress_read(st
 	n = sprintf (tmpbuf, "%s\n", progress_led);
 
 	sn = strlen (tmpbuf) +1;
-	if (*ppos >= sn) {
+	if (pos != (unsigned)pos || pos >= sn) {
 		kfree(tmpbuf);
 		return 0;
 	}
-	if (n > sn - *ppos)
-		n = sn - *ppos;
+	if (n > sn - pos)
+		n = sn - pos;
 	if (n > count)
 		n = count;
-	if (copy_to_user(buf, tmpbuf + (*ppos), n)) {
+	if (copy_to_user(buf, tmpbuf + pos), n) {
 		kfree(tmpbuf);
 		return -EFAULT;
 	}
 	kfree(tmpbuf);
-	*ppos += n;
+	*ppos = pos + n;
 	return n;
 }
 
@@ -453,6 +455,7 @@ static ssize_t ppc_rtas_clock_read(struc
 	unsigned int year, mon, day, hour, min, sec;
 	unsigned long *ret = kmalloc(4*8, GFP_KERNEL);
 	int n, error;
+	loff_t pos = *ppos;
 
 	error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
 	
@@ -471,16 +474,16 @@ static ssize_t ppc_rtas_clock_read(struc
 	kfree(ret);
 
 	int sn = strlen(stkbuf) +1;
-	if (*ppos >= sn)
+	if (pos != (unsigned)pos || pos >= sn)
 		return 0;
-	if (n > sn - *ppos)
-		n = sn - *ppos;
+	if (n > sn - pos)
+		n = sn - pos;
 	if (n > count)
 		n = count;
-	if (copy_to_user(buf, stkbuf + (*ppos), n))
+	if (copy_to_user(buf, stkbuf + pos, n))
 		return -EFAULT;
 
-	*ppos += n;
+	*ppos = pos + n;
 	return n;
 }
 
@@ -878,20 +881,21 @@ static ssize_t ppc_rtas_tone_freq_read(s
 {
 	int n, sn;
 	char stkbuf[40];  /* its small, its on stack */
+	loff_t pos = *ppos;
 
 	n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_frequency);
 
 	sn = strlen(stkbuf) +1;
-	if (*ppos >= sn)
+	if (pos != (unsigned)pos || pos >= sn)
 		return 0;
-	if (n > sn - *ppos)
-		n = sn - *ppos;
+	if (n > sn - pos)
+		n = sn - pos;
 	if (n > count)
 		n = count;
-	if (copy_to_user(buf, stkbuf + (*ppos), n))
+	if (copy_to_user(buf, stkbuf + pos, n))
 		return -EFAULT;
 
-	*ppos += n;
+	*ppos = pos + n;
 	return n;
 }
 /* ****************************************************************** */
@@ -933,19 +937,20 @@ static ssize_t ppc_rtas_tone_volume_read
 {
 	int n, sn;
 	char stkbuf[40];  /* its small, its on stack */
+	loff_t pos = *ppos;
 
 	n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_volume);
 	sn = strlen(stkbuf) +1;
-	if (*ppos >= sn)
+	if (pos != (unsigned)pos || pos >= sn)
 		return 0;
-	if (n > sn - *ppos)
-		n = sn - *ppos;
+	if (n > sn - pos)
+		n = sn - pos;
 	if (n > count)
 		n = count;
-	if (copy_to_user(buf, stkbuf + (*ppos), n))
+	if (copy_to_user(buf, stkbuf + pos, n))
 		return -EFAULT;
 
-	*ppos += n;
+	*ppos = pos + n;
 	return n;
 }
 
@@ -1064,6 +1069,7 @@ static ssize_t ppc_rtas_errinjct_read(st
 	char * buffer;
 	int i, sn;
 	int n = 0;
+	loff_t pos = *ppos;
 
 	int m = MAX_ERRINJCT_TOKENS * (ERRINJCT_TOKEN_LEN+1);
 	buffer = (char *)kmalloc(m, GFP_KERNEL);
@@ -1078,22 +1084,22 @@ static ssize_t ppc_rtas_errinjct_read(st
 	}
 
 	sn = strlen(buffer) +1;
-	if (*ppos >= sn) {
+	if (pos != (unsigned)pos || pos >= sn) {
 		kfree(buffer);
 		return 0;
 	}
-	if (n > sn - *ppos)
-		n = sn - *ppos;
+	if (n > sn - pos)
+		n = sn - pos;
 
 	if (n > count)
 		n = count;
 
-	if (copy_to_user(buf, buffer + *ppos, n)) {
+	if (copy_to_user(buf, buffer + pos, n)) {
 		kfree(buffer);
 		return -EFAULT;
 	}
 
-	*ppos += n;
+	*ppos = pos + n;
 
 	kfree(buffer);
 	return n;
diff -pruN linux-2.4.27-rc4/arch/s390/kernel/debug.c linux-2.4.27-rc4.CAN-2004-0415/arch/s390/kernel/debug.c
--- linux-2.4.27-rc4/arch/s390/kernel/debug.c	2003-08-25 20:44:40.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/s390/kernel/debug.c	2004-09-07 13:53:38.000000000 +0900
@@ -470,8 +470,8 @@ static ssize_t debug_output(struct file 
 				goto out;
 	}
 out:
-	p_info->offset           = *offset + count;
-	p_info->act_entry_offset = size;	
+	p_info->offset           += count;
+	p_info->act_entry_offset = size;
 	*offset = p_info->offset;
 	return count;
 }
@@ -1068,7 +1068,7 @@ static int debug_input_level_fn(debug_in
 		       input_buf[0]);
 	}
       out:
-	*offset += in_buf_size;
+	*offset = in_buf_size;
 	return rc;		/* number of input characters */
 }
 
@@ -1135,7 +1135,7 @@ static int debug_input_flush_fn(debug_in
         printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]);
 
       out:
-        *offset += in_buf_size;
+        *offset = in_buf_size;
         return rc;              /* number of input characters */
 }
 
diff -pruN linux-2.4.27-rc4/arch/s390x/kernel/debug.c linux-2.4.27-rc4.CAN-2004-0415/arch/s390x/kernel/debug.c
--- linux-2.4.27-rc4/arch/s390x/kernel/debug.c	2003-08-25 20:44:40.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/s390x/kernel/debug.c	2004-09-07 13:53:38.000000000 +0900
@@ -470,7 +470,7 @@ static ssize_t debug_output(struct file 
 				goto out;
 	}
 out:
-	p_info->offset           = *offset + count;
+	p_info->offset           += count;
 	p_info->act_entry_offset = size;	
 	*offset = p_info->offset;
 	return count;
@@ -1068,7 +1068,7 @@ static int debug_input_level_fn(debug_in
 		       input_buf[0]);
 	}
       out:
-	*offset += in_buf_size;
+	*offset = in_buf_size;
 	return rc;		/* number of input characters */
 }
 
@@ -1135,7 +1135,7 @@ static int debug_input_flush_fn(debug_in
         printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]);
 
       out:
-        *offset += in_buf_size;
+        *offset = in_buf_size;
         return rc;              /* number of input characters */
 }
 
diff -pruN linux-2.4.27-rc4/arch/x86_64/kernel/mtrr.c linux-2.4.27-rc4.CAN-2004-0415/arch/x86_64/kernel/mtrr.c
--- linux-2.4.27-rc4/arch/x86_64/kernel/mtrr.c	2004-04-14 22:05:28.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/arch/x86_64/kernel/mtrr.c	2004-09-07 13:53:38.000000000 +0900
@@ -961,16 +961,19 @@ static int mtrr_file_del (u64 base, u32 
 static ssize_t mtrr_read (struct file *file, char *buf, size_t len,
 		loff_t * ppos)
 {
-	if (*ppos >= ascii_buf_bytes)
+	loff_t n = *ppos;
+	unsigned pos = n;
+
+	if (pos != n || pos >= ascii_buf_bytes)
 		return 0;
 
-	if (*ppos + len > ascii_buf_bytes)
-		len = ascii_buf_bytes - *ppos;
+	if (len > ascii_buf_bytes - pos)
+		len = ascii_buf_bytes - pos;
 
-	if (copy_to_user (buf, ascii_buffer + *ppos, len))
+	if (copy_to_user (buf, ascii_buffer + pos, len))
 		return -EFAULT;
 
-	*ppos += len;
+	*ppos = pos + len;
 	return len;
 }
 
diff -pruN linux-2.4.27-rc4/drivers/block/acsi_slm.c linux-2.4.27-rc4.CAN-2004-0415/drivers/block/acsi_slm.c
--- linux-2.4.27-rc4/drivers/block/acsi_slm.c	2002-11-29 08:53:12.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/block/acsi_slm.c	2004-09-07 13:53:38.000000000 +0900
@@ -367,6 +367,7 @@ static ssize_t slm_read( struct file *fi
 
 {
 	struct inode *node = file->f_dentry->d_inode;
+	loff_t pos = *ppos;
 	unsigned long page;
 	int length;
 	int end;
@@ -381,18 +382,18 @@ static ssize_t slm_read( struct file *fi
 		count = length;
 		goto out;
 	}
-	if (file->f_pos >= length) {
+	if (pos != (unsigned) pos || pos >= length) {
 		count = 0;
 		goto out;
 	}
-	if (count + file->f_pos > length)
-		count = length - file->f_pos;
-	end = count + file->f_pos;
-	if (copy_to_user(buf, (char *)page + file->f_pos, count)) {
+	if (count > length - pos)
+		count = length - pos;
+	end = count + pos;
+	if (copy_to_user(buf, (char *)page + pos, count)) {
 		count = -EFAULT;
 		goto out;
 	}
-	file->f_pos = end;
+	*ppos = end;
 out:	free_page( page );
 	return( count );
 }
diff -pruN linux-2.4.27-rc4/drivers/block/rd.c linux-2.4.27-rc4.CAN-2004-0415/drivers/block/rd.c
--- linux-2.4.27-rc4/drivers/block/rd.c	2002-11-29 08:53:12.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/block/rd.c	2004-09-07 13:53:38.000000000 +0900
@@ -320,14 +320,19 @@ out:
 static ssize_t initrd_read(struct file *file, char *buf,
 			   size_t count, loff_t *ppos)
 {
-	int left;
+	loff_t n = *ppos;
+	unsigned pos = n;
+	unsigned left = initrd_end - initrd_start;
 
-	left = initrd_end - initrd_start - *ppos;
+	if (pos != n || pos >= left)
+		return 0;
+
+	left -= pos;
 	if (count > left) count = left;
 	if (count == 0) return 0;
-	if (copy_to_user(buf, (char *)initrd_start + *ppos, count))
+	if (copy_to_user(buf, (char *)initrd_start + pos, count))
 		return -EFAULT;
-	*ppos += count;
+	*ppos = pos + count;
 	return count;
 }
 
diff -pruN linux-2.4.27-rc4/drivers/char/i8k.c linux-2.4.27-rc4.CAN-2004-0415/drivers/char/i8k.c
--- linux-2.4.27-rc4/drivers/char/i8k.c	2002-11-29 08:53:12.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/char/i8k.c	2004-09-07 13:53:38.000000000 +0900
@@ -493,6 +493,7 @@ static int i8k_get_info(char *buffer, ch
 
 static ssize_t i8k_read(struct file *f, char *buffer, size_t len, loff_t *fpos)
 {
+    loff_t pos = *fpos;
     int n;
     char info[128];
 
@@ -501,19 +502,19 @@ static ssize_t i8k_read(struct file *f, 
 	return n;
     }
 
-    if (*fpos >= n) {
+    if (pos != (unsigned)pos || pos >= n) {
 	return 0;
     }
 
-    if ((*fpos + len) >= n) {
-	len = n - *fpos;
+    if (len >= n - pos) {
+	len = n - pos;
     }
 
     if (copy_to_user(buffer, info, len) != 0) {
 	return -EFAULT;
     }
 
-    *fpos += len;
+    *fpos = pos + len;
     return len;
 }
 
diff -pruN linux-2.4.27-rc4/drivers/char/istallion.c linux-2.4.27-rc4.CAN-2004-0415/drivers/char/istallion.c
--- linux-2.4.27-rc4/drivers/char/istallion.c	2002-08-03 09:39:43.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/char/istallion.c	2004-09-07 13:53:38.000000000 +0900
@@ -4854,6 +4854,7 @@ static ssize_t stli_memread(struct file 
 	void		*memptr;
 	stlibrd_t	*brdp;
 	int		brdnr, size, n;
+	loff_t		pos = *offp;
 
 #if DEBUG
 	printk(KERN_DEBUG "stli_memread(fp=%x,buf=%x,count=%x,offp=%x)\n",
@@ -4868,25 +4869,26 @@ static ssize_t stli_memread(struct file 
 		return(-ENODEV);
 	if (brdp->state == 0)
 		return(-ENODEV);
-	if (fp->f_pos >= brdp->memsize)
+	if (pos != (unsigned)pos || pos >= brdp->memsize)
 		return(0);
 
-	size = MIN(count, (brdp->memsize - fp->f_pos));
+	size = MIN(count, (brdp->memsize - pos));
 
 	save_flags(flags);
 	cli();
 	EBRDENABLE(brdp);
 	while (size > 0) {
-		memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos);
-		n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize)));
+		memptr = (void *) EBRDGETMEMPTR(brdp, pos);
+		n = MIN(size, (brdp->pagesize - (((unsigned long) pos) % brdp->pagesize)));
 		if (copy_to_user(buf, memptr, n)) {
 			count = -EFAULT;
 			goto out;
 		}
-		fp->f_pos += n;
+		pos += n;
 		buf += n;
 		size -= n;
 	}
+	*offp = pos;
 out:
 	EBRDDISABLE(brdp);
 	restore_flags(flags);
@@ -4909,6 +4911,7 @@ static ssize_t stli_memwrite(struct file
 	stlibrd_t	*brdp;
 	char		*chbuf;
 	int		brdnr, size, n;
+	loff_t		pos = *offp;
 
 #if DEBUG
 	printk(KERN_DEBUG "stli_memwrite(fp=%x,buf=%x,count=%x,offp=%x)\n",
@@ -4923,26 +4926,27 @@ static ssize_t stli_memwrite(struct file
 		return(-ENODEV);
 	if (brdp->state == 0)
 		return(-ENODEV);
-	if (fp->f_pos >= brdp->memsize)
+	if (pos != (unsigned)pos || pos >= brdp->memsize)
 		return(0);
 
 	chbuf = (char *) buf;
-	size = MIN(count, (brdp->memsize - fp->f_pos));
+	size = MIN(count, (brdp->memsize - pos));
 
 	save_flags(flags);
 	cli();
 	EBRDENABLE(brdp);
 	while (size > 0) {
-		memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos);
-		n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize)));
+		memptr = (void *) EBRDGETMEMPTR(brdp, pos);
+		n = MIN(size, (brdp->pagesize - (((unsigned long) pos) % brdp->pagesize)));
 		if (copy_from_user(memptr, chbuf, n)) {
 			count = -EFAULT;
 			goto out;
 		}
-		fp->f_pos += n;
+		pos += n;
 		chbuf += n;
 		size -= n;
 	}
+	*offp = pos;
 out:
 	EBRDDISABLE(brdp);
 	restore_flags(flags);
diff -pruN linux-2.4.27-rc4/drivers/char/mem.c linux-2.4.27-rc4.CAN-2004-0415/drivers/char/mem.c
--- linux-2.4.27-rc4/drivers/char/mem.c	2003-11-29 03:26:20.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/char/mem.c	2004-09-07 13:53:38.000000000 +0900
@@ -64,7 +64,7 @@ static ssize_t do_write_mem(struct file 
 	if (copy_from_user(p, buf, count))
 		return -EFAULT;
 	written += count;
-	*ppos += written;
+	*ppos = realp + written;
 	return written;
 }
 
@@ -105,7 +105,7 @@ static ssize_t read_mem(struct file * fi
 	if (copy_to_user(buf, __va(p), count))
 		return -EFAULT;
 	read += count;
-	*ppos += read;
+	*ppos = p + read;
 	return read;
 }
 
diff -pruN linux-2.4.27-rc4/drivers/char/nvram.c linux-2.4.27-rc4.CAN-2004-0415/drivers/char/nvram.c
--- linux-2.4.27-rc4/drivers/char/nvram.c	2003-06-13 23:51:33.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/char/nvram.c	2004-09-07 13:53:38.000000000 +0900
@@ -252,9 +252,13 @@ static ssize_t
 nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 {
 	unsigned char contents[NVRAM_BYTES];
-	unsigned i = *ppos;
+	loff_t n = *ppos;
+	unsigned i = n;
 	unsigned char *tmp;
 
+	if (i != n || i >= NVRAM_BYTES)
+		return 0;
+
 	spin_lock_irq(&rtc_lock);
 
 	if (!__nvram_check_checksum())
@@ -281,10 +285,14 @@ static ssize_t
 nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
 {
 	unsigned char contents[NVRAM_BYTES];
-	unsigned i = *ppos;
+	loff_t n = *ppos;
+	unsigned i = n;
 	unsigned char *tmp;
 	int len;
 
+	if (i != n || i >= NVRAM_BYTES)
+		return 0;
+
 	len = (NVRAM_BYTES - i) < count ? (NVRAM_BYTES - i) : count;
 	if (copy_from_user(contents, buf, len))
 		return -EFAULT;
diff -pruN linux-2.4.27-rc4/drivers/char/nwflash.c linux-2.4.27-rc4.CAN-2004-0415/drivers/char/nwflash.c
--- linux-2.4.27-rc4/drivers/char/nwflash.c	2001-10-13 05:48:42.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/char/nwflash.c	2004-09-07 13:53:38.000000000 +0900
@@ -133,7 +133,8 @@ static int flash_ioctl(struct inode *ino
 
 static ssize_t flash_read(struct file *file, char *buf, size_t size, loff_t * ppos)
 {
-	unsigned long p = *ppos;
+	loff_t n = *ppos;
+	unsigned long p = n;
 	unsigned int count = size;
 	int ret = 0;
 
@@ -144,7 +145,7 @@ static ssize_t flash_read(struct file *f
 	if (count)
 		ret = -ENXIO;
 
-	if (p < gbFlashSize) {
+	if (n == p && p < gbFlashSize) {
 		if (count > gbFlashSize - p)
 			count = gbFlashSize - p;
 
@@ -157,7 +158,7 @@ static ssize_t flash_read(struct file *f
 		ret = copy_to_user(buf, (void *)(FLASH_BASE + p), count);
 		if (ret == 0) {
 			ret = count;
-			*ppos += count;
+			*ppos = p + count;
 		}
 		up(&nwflash_sem);
 	}
@@ -166,7 +167,8 @@ static ssize_t flash_read(struct file *f
 
 static ssize_t flash_write(struct file *file, const char *buf, size_t size, loff_t * ppos)
 {
-	unsigned long p = *ppos;
+	loff_t n = *ppos;
+	unsigned long p = n;
 	unsigned int count = size;
 	int written;
 	int nBlock, temp, rc;
@@ -185,7 +187,7 @@ static ssize_t flash_write(struct file *
 	/*
 	 * check for out of range pos or count
 	 */
-	if (p >= gbFlashSize)
+	if (p != n || p >= gbFlashSize)
 		return count ? -ENXIO : 0;
 
 	if (count > gbFlashSize - p)
@@ -274,7 +276,7 @@ static ssize_t flash_write(struct file *
 		p += rc;
 		buf += rc;
 		written += rc;
-		*ppos += rc;
+		*ppos = p;
 
 		if (flashdebug)
 			printk(KERN_DEBUG "flash_write: written 0x%X bytes OK.\n", written);
diff -pruN linux-2.4.27-rc4/drivers/char/raw.c linux-2.4.27-rc4.CAN-2004-0415/drivers/char/raw.c
--- linux-2.4.27-rc4/drivers/char/raw.c	2003-06-13 23:51:33.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/char/raw.c	2004-09-07 13:53:38.000000000 +0900
@@ -301,6 +301,7 @@ ssize_t	rw_raw_dev(int rw, struct file *
 	int		minor;
 	kdev_t		dev;
 	unsigned long	limit;
+	loff_t		off = *offp;
 
 	int		sector_size, sector_bits, sector_mask;
 	int		max_sectors;
@@ -338,12 +339,12 @@ ssize_t	rw_raw_dev(int rw, struct file *
 		 MAJOR(dev), MINOR(dev), limit);
 	
 	err = -EINVAL;
-	if ((*offp & sector_mask) || (size & sector_mask))
+	if ((off & sector_mask) || (size & sector_mask))
 		goto out_free;
 	err = 0;
 	if (size)
 		err = -ENXIO;
-	if ((*offp >> sector_bits) >= limit)
+	if ((off >> sector_bits) >= limit)
 		goto out_free;
 
 	/*
@@ -353,7 +354,7 @@ ssize_t	rw_raw_dev(int rw, struct file *
 	 */
 
 	transferred = 0;
-	blocknr = *offp >> sector_bits;
+	blocknr = off >> sector_bits;
 	while (size > 0) {
 		blocks = size >> sector_bits;
 		if (blocks > max_sectors)
@@ -390,7 +391,7 @@ ssize_t	rw_raw_dev(int rw, struct file *
 	}
 	
 	if (transferred) {
-		*offp += transferred;
+		*offp = off + transferred;
 		err = transferred;
 	}
 
diff -pruN linux-2.4.27-rc4/drivers/char/tpqic02.c linux-2.4.27-rc4.CAN-2004-0415/drivers/char/tpqic02.c
--- linux-2.4.27-rc4/drivers/char/tpqic02.c	2002-11-29 08:53:12.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/char/tpqic02.c	2004-09-07 13:53:38.000000000 +0900
@@ -1818,6 +1818,7 @@ static ssize_t qic02_tape_read(struct fi
 	kdev_t dev = filp->f_dentry->d_inode->i_rdev;
 	unsigned short flags = filp->f_flags;
 	unsigned long bytes_todo, bytes_done, total_bytes_done = 0;
+	loff_t pos = *ppos;
 	int stat;
 
 	if (status_zombie == YES) {
@@ -1898,6 +1899,7 @@ static ssize_t qic02_tape_read(struct fi
 
 	/*****************************/
 		if (bytes_todo == 0) {
+			*ppos = pos;
 			return total_bytes_done;
 		}
 
@@ -1966,7 +1968,7 @@ static ssize_t qic02_tape_read(struct fi
 		if (bytes_done > 0) {
 			status_bytes_rd = YES;
 			buf += bytes_done;
-			*ppos += bytes_done;
+			pos += bytes_done;
 			total_bytes_done += bytes_done;
 			count -= bytes_done;
 		}
diff -pruN linux-2.4.27-rc4/drivers/char/vc_screen.c linux-2.4.27-rc4.CAN-2004-0415/drivers/char/vc_screen.c
--- linux-2.4.27-rc4/drivers/char/vc_screen.c	2001-09-17 13:22:40.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/char/vc_screen.c	2004-09-07 13:53:38.000000000 +0900
@@ -64,12 +64,25 @@ vcs_size(struct inode *inode)
 	return size;
 }
 
+/* We share this temporary buffer with the console write code
+ * so that we can easily avoid touching user space while holding the
+ * console spinlock.
+ */
+extern char con_buf[PAGE_SIZE];
+#define CON_BUF_SIZE	PAGE_SIZE
+extern struct semaphore con_buf_sem;
+
 static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
 {
-	int size = vcs_size(file->f_dentry->d_inode);
+	int size;
+
+	down(&con_buf_sem);
+
+	size = vcs_size(file->f_dentry->d_inode);
 
 	switch (orig) {
 		default:
+			up(&con_buf_sem);
 			return -EINVAL;
 		case 2:
 			offset += size;
@@ -79,26 +92,22 @@ static loff_t vcs_lseek(struct file *fil
 		case 0:
 			break;
 	}
-	if (offset < 0 || offset > size)
+	if (offset < 0 || offset > size) {
+		up(&con_buf_sem);
 		return -EINVAL;
+	}
 	file->f_pos = offset;
+	up (&con_buf_sem);
 	return file->f_pos;
 }
 
-/* We share this temporary buffer with the console write code
- * so that we can easily avoid touching user space while holding the
- * console spinlock.
- */
-extern char con_buf[PAGE_SIZE];
-#define CON_BUF_SIZE	PAGE_SIZE
-extern struct semaphore con_buf_sem;
-
 static ssize_t
 vcs_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 {
 	struct inode *inode = file->f_dentry->d_inode;
 	unsigned int currcons = MINOR(inode->i_rdev);
-	long pos = *ppos;
+	loff_t n;
+	unsigned pos;
 	long viewed, attr, read;
 	int col, maxcol;
 	unsigned short *org = NULL;
@@ -106,6 +115,9 @@ vcs_read(struct file *file, char *buf, s
 
 	down(&con_buf_sem);
 
+	n = *ppos; 
+	pos = n;
+
 	/* Select the proper current console and verify
 	 * sanity of the situation under the console lock.
 	 */
@@ -124,11 +136,10 @@ vcs_read(struct file *file, char *buf, s
 	if (!vc_cons_allocated(currcons))
 		goto unlock_out;
 
-	ret = -EINVAL;
-	if (pos < 0)
-		goto unlock_out;
 	read = 0;
 	ret = 0;
+	if (pos != n)
+		goto unlock_out;
 	while (count) {
 		char *con_buf0, *con_buf_start;
 		long this_round, size;
@@ -244,16 +255,15 @@ vcs_read(struct file *file, char *buf, s
 		acquire_console_sem();
 
 		if (ret) {
-			read += (orig_count - ret);
 			ret = -EFAULT;
-			break;
+			goto unlock_out;
 		}
 		buf += orig_count;
 		pos += orig_count;
 		read += orig_count;
 		count -= orig_count;
 	}
-	*ppos += read;
+	*ppos = pos;
 	if (read)
 		ret = read;
 unlock_out:
@@ -267,7 +277,8 @@ vcs_write(struct file *file, const char 
 {
 	struct inode *inode = file->f_dentry->d_inode;
 	unsigned int currcons = MINOR(inode->i_rdev);
-	long pos = *ppos;
+	loff_t n;
+	unsigned pos;
 	long viewed, attr, size, written;
 	char *con_buf0;
 	int col, maxcol;
@@ -276,6 +287,9 @@ vcs_write(struct file *file, const char 
 
 	down(&con_buf_sem);
 
+	n = *ppos;
+	pos = n;
+
 	/* Select the proper current console and verify
 	 * sanity of the situation under the console lock.
 	 */
@@ -297,7 +311,7 @@ vcs_write(struct file *file, const char 
 
 	size = vcs_size(inode);
 	ret = -EINVAL;
-	if (pos < 0 || pos > size)
+	if (pos != n || pos > size)
 		goto unlock_out;
 	if (count > size - pos)
 		count = size - pos;
@@ -435,7 +449,7 @@ vcs_write(struct file *file, const char 
 		if (org0)
 			update_region(currcons, (unsigned long)(org0), org-org0);
 	}
-	*ppos += written;
+	*ppos = pos;
 	ret = written;
 
 unlock_out:
diff -pruN linux-2.4.27-rc4/drivers/gsc/eisa_eeprom.c linux-2.4.27-rc4.CAN-2004-0415/drivers/gsc/eisa_eeprom.c
--- linux-2.4.27-rc4/drivers/gsc/eisa_eeprom.c	2002-11-29 08:53:12.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/gsc/eisa_eeprom.c	2004-09-07 13:53:38.000000000 +0900
@@ -34,24 +34,30 @@ static ssize_t eisa_eeprom_read(struct f
 	unsigned char *tmp;
 	ssize_t ret;
 	int i;
+	loff_t n = *ppos;
+	unsigned pos = n;
 	
-	if (*ppos >= HPEE_MAX_LENGTH)
+	if (n != pos || pos >= HPEE_MAX_LENGTH)
 		return 0;
 	
-	count = *ppos + count < HPEE_MAX_LENGTH ? count : HPEE_MAX_LENGTH - *ppos;
+	if (count > HPEE_MAX_LENGTH - pos)
+		count = HPEE_MAX_LENGTH - pos;
+
 	tmp = kmalloc(count, GFP_KERNEL);
 	if (tmp) {
 		for (i = 0; i < count; i++)
-			tmp[i] = gsc_readb(eeprom_addr+(*ppos)++);
+			tmp[i] = gsc_readb(eeprom_addr+(pos)++);
 
 		if (copy_to_user (buf, tmp, count))
 			ret = -EFAULT;
-		else
+		else {
 			ret = count;
+			*ppos = pos;
+		}
 		kfree (tmp);
 	} else
 		ret = -ENOMEM;
-	
+
 	return ret;
 }
 
diff -pruN linux-2.4.27-rc4/drivers/hotplug/pci_hotplug_core.c linux-2.4.27-rc4.CAN-2004-0415/drivers/hotplug/pci_hotplug_core.c
--- linux-2.4.27-rc4/drivers/hotplug/pci_hotplug_core.c	2004-09-07 13:53:02.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/hotplug/pci_hotplug_core.c	2004-09-07 13:53:38.000000000 +0900
@@ -616,7 +616,7 @@ static ssize_t power_read_file (struct f
 		retval = -EFAULT;
 		goto exit;
 	}
-	*offset += len;
+	*offset = len;
 	retval = len;
 
 exit:
@@ -727,7 +727,7 @@ static ssize_t attention_read_file (stru
 		retval = -EFAULT;
 		goto exit;
 	}
-	*offset += len;
+	*offset = len;
 	retval = len;
 
 exit:
@@ -792,14 +792,15 @@ static ssize_t latch_read_file (struct f
 	int retval;
 	int len;
 	u8 value;
+	loff_t off = *offset;
 
-	dbg("count = %d, offset = %lld\n", count, *offset);
+	dbg("count = %d, offset = %lld\n", count, off);
 
-	if (*offset < 0)
+	if (off < 0)
 		return -EINVAL;
 	if (count <= 0)
 		return 0;
-	if (*offset != 0)
+	if (off != 0)
 		return 0;
 
 	if (slot == NULL) {
@@ -820,7 +821,7 @@ static ssize_t latch_read_file (struct f
 		retval = -EFAULT;
 		goto exit;
 	}
-	*offset += len;
+	*offset = off + len;
 	retval = len;
 
 exit:
@@ -835,14 +836,15 @@ static ssize_t presence_read_file (struc
 	int retval;
 	int len;
 	u8 value;
+	loff_t off = *offset;
 
 	dbg("count = %d, offset = %lld\n", count, *offset);
 
-	if (*offset < 0)
+	if (off < 0)
 		return -EINVAL;
 	if (count <= 0)
 		return 0;
-	if (*offset != 0)
+	if (off != 0)
 		return 0;
 
 	if (slot == NULL) {
@@ -863,7 +865,7 @@ static ssize_t presence_read_file (struc
 		retval = -EFAULT;
 		goto exit;
 	}
-	*offset += len;
+	*offset = off + len;
 	retval = len;
 
 exit:
@@ -878,14 +880,15 @@ static ssize_t address_read_file (struct
 	int retval;
 	int len;
 	u32 address;
+	loff_t off = *offset;
 
-	dbg("count = %d, offset = %lld\n", count, *offset);
+	dbg("count = %d, offset = %lld\n", count, off);
 
-	if (*offset < 0)
+	if (off < 0)
 		return -EINVAL;
 	if (count <= 0)
 		return 0;
-	if (*offset != 0)
+	if (off != 0)
 		return 0;
 
 	if (slot == NULL) {
@@ -909,7 +912,7 @@ static ssize_t address_read_file (struct
 		retval = -EFAULT;
 		goto exit;
 	}
-	*offset += len;
+	*offset  = off + len;
 	retval = len;
 
 exit:
@@ -927,14 +930,15 @@ static ssize_t max_bus_speed_read_file (
 	int retval;
 	int len = 0;
 	enum pci_bus_speed value;
+	loff_t off = *offset;
 	
-	dbg ("count = %d, offset = %lld\n", count, *offset);
+	dbg ("count = %d, offset = %lld\n", count, off);
 
-	if (*offset < 0)
+	if (off < 0)
 		return -EINVAL;
 	if (count <= 0)
 		return 0;
-	if (*offset != 0)
+	if (off != 0)
 		return 0;
 
 	if (slot == NULL) {
@@ -961,7 +965,7 @@ static ssize_t max_bus_speed_read_file (
 		retval = -EFAULT;
 		goto exit;
 	}
-	*offset += len;
+	*offset = off + len;
 	retval = len;
 
 exit:
@@ -977,14 +981,15 @@ static ssize_t cur_bus_speed_read_file (
 	int retval;
 	int len = 0;
 	enum pci_bus_speed value;
+	loff_t off = *offset;
 
-	dbg ("count = %d, offset = %lld\n", count, *offset);
+	dbg ("count = %d, offset = %lld\n", count, off);
 
-	if (*offset < 0)
+	if (off < 0)
 		return -EINVAL;
 	if (count <= 0)
 		return 0;
-	if (*offset != 0)
+	if (off != 0)
 		return 0;
 
 	if (slot == NULL) {
@@ -1011,7 +1016,7 @@ static ssize_t cur_bus_speed_read_file (
 		retval = -EFAULT;
 		goto exit;
 	}
-	*offset += len;
+	*offset = off + len;
 	retval = len;
 
 exit:
diff -pruN linux-2.4.27-rc4/drivers/ieee1394/pcilynx.c linux-2.4.27-rc4.CAN-2004-0415/drivers/ieee1394/pcilynx.c
--- linux-2.4.27-rc4/drivers/ieee1394/pcilynx.c	2004-09-07 13:53:02.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/ieee1394/pcilynx.c	2004-09-07 13:53:38.000000000 +0900
@@ -1065,12 +1065,15 @@ static ssize_t mem_read(struct file *fil
         ssize_t retval;
         void *membase;
 
-        if ((off + count) > PCILYNX_MAX_MEMORY+1) {
-                count = PCILYNX_MAX_MEMORY+1 - off;
-        }
-        if (count == 0 || off > PCILYNX_MAX_MEMORY) {
+	if (!count)
+		return 0;
+	if (off < 0)
+		return -EINVAL;
+	if (off > PCILYNX_MAX_MEMORY)
                 return -ENOSPC;
-        }
+
+	if (count > PCILYNX_MAX_MEMORY + 1 - off)
+		count = PCILYNX_MAX_MEMORY + 1 - off;
 
         switch (md->type) {
         case rom:
@@ -1091,6 +1094,7 @@ static ssize_t mem_read(struct file *fil
 
         if (count < mem_mindma) {
                 memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, count);
+		off += count;
                 goto out;
         }
 
@@ -1121,6 +1125,7 @@ static ssize_t mem_read(struct file *fil
         if (bcount) {
                 memcpy_fromio(md->lynx->mem_dma_buffer + count - bcount,
                               membase+off, bcount);
+		off += bcount;
         }
 
  out:
@@ -1128,7 +1133,7 @@ static ssize_t mem_read(struct file *fil
         up(&md->lynx->mem_dma_mutex);
 
 	if (retval) return -EFAULT;
-        *offset += count;
+        *offset = off;
         return count;
 }
 
@@ -1137,32 +1142,36 @@ static ssize_t mem_write(struct file *fi
                          loff_t *offset)
 {
         struct memdata *md = (struct memdata *)file->private_data;
+	loff_t off = *offset;
 
-        if (((*offset) + count) > PCILYNX_MAX_MEMORY+1) {
-                count = PCILYNX_MAX_MEMORY+1 - *offset;
-        }
-        if (count == 0 || *offset > PCILYNX_MAX_MEMORY) {
-                return -ENOSPC;
-        }
+	if (!count)
+		return 0;
+	if (off < 0)
+		return -EINVAL;
+	if (off > PCILYNX_MAX_MEMORY)
+		return -ENOSPC;
+
+	if (count > PCILYNX_MAX_MEMORY + 1 - off)
+		count = PCILYNX_MAX_MEMORY + 1 - off;
 
         /* FIXME: dereferencing pointers to PCI mem doesn't work everywhere */
         switch (md->type) {
         case aux:
-		if (copy_from_user(md->lynx->aux_port+(*offset), buffer, count))
+		if (copy_from_user(md->lynx->aux_port+off, buffer, count))
 			return -EFAULT;
                 break;
         case ram:
-		if (copy_from_user(md->lynx->local_ram+(*offset), buffer, count))
+		if (copy_from_user(md->lynx->local_ram+off, buffer, count))
 			return -EFAULT;
                 break;
         case rom:
                 /* the ROM may be writeable */
-		if (copy_from_user(md->lynx->local_rom+(*offset), buffer, count))
+		if (copy_from_user(md->lynx->local_rom+off, buffer, count))
 			return -EFAULT;
                 break;
         }
 
-        file->f_pos += count;
+	*offset = off + count;
         return count;
 }
 #endif /* CONFIG_IEEE1394_PCILYNX_PORTS */
diff -pruN linux-2.4.27-rc4/drivers/isdn/divert/divert_procfs.c linux-2.4.27-rc4.CAN-2004-0415/drivers/isdn/divert/divert_procfs.c
--- linux-2.4.27-rc4/drivers/isdn/divert/divert_procfs.c	2001-12-22 02:41:54.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/isdn/divert/divert_procfs.c	2004-09-07 13:53:38.000000000 +0900
@@ -80,6 +80,7 @@ static ssize_t
 isdn_divert_read(struct file *file, char *buf, size_t count, loff_t * off)
 {
 	struct divert_info *inf;
+	loff_t pos = *off;
 	int len;
 
 	if (!*((struct divert_info **) file->private_data)) {
@@ -95,7 +96,7 @@ isdn_divert_read(struct file *file, char
 	if ((len = strlen(inf->info_start)) <= count) {
 		if (copy_to_user(buf, inf->info_start, len))
 			return -EFAULT;
-		file->f_pos += len;
+		*off = pos + len;
 		return (len);
 	}
 	return (0);
diff -pruN linux-2.4.27-rc4/drivers/isdn/hysdn/hysdn_procconf.c linux-2.4.27-rc4.CAN-2004-0415/drivers/isdn/hysdn/hysdn_procconf.c
--- linux-2.4.27-rc4/drivers/isdn/hysdn/hysdn_procconf.c	2001-12-22 02:41:54.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/isdn/hysdn/hysdn_procconf.c	2004-09-07 13:53:38.000000000 +0900
@@ -212,29 +212,27 @@ hysdn_conf_write(struct file *file, cons
 static ssize_t
 hysdn_conf_read(struct file *file, char *buf, size_t count, loff_t * off)
 {
+	loff_t pos = *off;
 	char *cp;
 	int i;
 
 	if (off != &file->f_pos)	/* fs error check */
 		return -ESPIPE;
 
-	if (file->f_mode & FMODE_READ) {
-		if (!(cp = file->private_data))
-			return (-EFAULT);	/* should never happen */
-		i = strlen(cp);	/* get total string length */
-		if (*off < i) {
-			/* still bytes to transfer */
-			cp += *off;	/* point to desired data offset */
-			i -= *off;	/* remaining length */
-			if (i > count)
-				i = count;	/* limit length to transfer */
-			if (copy_to_user(buf, cp, i))
-				return (-EFAULT);	/* copy error */
-			*off += i;	/* adjust offset */
-		} else
-			return (0);
+	if (!(cp = file->private_data))
+		return (-EFAULT);	/* should never happen */
+	i = strlen(cp);	/* get total string length */
+	if (pos == (unsigned)pos && pos < i) {
+		/* still bytes to transfer */
+		cp += pos;	/* point to desired data offset */
+		i -= pos;	/* remaining length */
+		if (i > count)
+			i = count;	/* limit length to transfer */
+		if (copy_to_user(buf, cp, i))
+			return (-EFAULT);	/* copy error */
+		*off = pos + i;	/* adjust offset */
 	} else
-		return (-EPERM);	/* no permission to read */
+		return (0);
 
 	return (i);
 }				/* hysdn_conf_read */
diff -pruN linux-2.4.27-rc4/drivers/isdn/hysdn/hysdn_proclog.c linux-2.4.27-rc4.CAN-2004-0415/drivers/isdn/hysdn/hysdn_proclog.c
--- linux-2.4.27-rc4/drivers/isdn/hysdn/hysdn_proclog.c	2001-12-22 02:41:54.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/isdn/hysdn/hysdn_proclog.c	2004-09-07 13:53:38.000000000 +0900
@@ -210,6 +210,7 @@ hysdn_log_read(struct file *file, char *
 	word ino;
 	struct procdata *pd = NULL;
 	hysdn_card *card;
+	loff_t pos = *off;
 
 	if (!*((struct log_data **) file->private_data)) {
 		if (file->f_flags & O_NONBLOCK)
@@ -238,7 +239,7 @@ hysdn_log_read(struct file *file, char *
 	if ((len = strlen(inf->log_start)) <= count) {
 		if (copy_to_user(buf, inf->log_start, len))
 			return -EFAULT;
-		file->f_pos += len;
+		*off = pos + len;
 		return (len);
 	}
 	return (0);
diff -pruN linux-2.4.27-rc4/drivers/isdn/isdn_common.c linux-2.4.27-rc4.CAN-2004-0415/drivers/isdn/isdn_common.c
--- linux-2.4.27-rc4/drivers/isdn/isdn_common.c	2002-08-03 09:39:44.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/isdn/isdn_common.c	2004-09-07 13:53:38.000000000 +0900
@@ -976,10 +976,14 @@ isdn_read(struct file *file, char *buf, 
 	int chidx;
 	int retval;
 	char *p;
+	loff_t pos = *off;
 
 	if (off != &file->f_pos)
 		return -ESPIPE;
 
+	if (pos != (unsigned) pos)
+		return -EINVAL;
+
 	lock_kernel();
 	if (minor == ISDN_MINOR_STATUS) {
 		if (!file->private_data) {
@@ -996,7 +1000,7 @@ isdn_read(struct file *file, char *buf, 
 				retval = -EFAULT;
 				goto out;
 			}
-			*off += len;
+			*off = pos + len;
 			retval = len;
 			goto out;
 		}
@@ -1027,7 +1031,7 @@ isdn_read(struct file *file, char *buf, 
 		cli();
 		len = isdn_readbchan(drvidx, chidx, p, 0, count,
 				     &dev->drv[drvidx]->rcv_waitq[chidx]);
-		*off += len;
+		*off = pos + len;
 		restore_flags(flags);
 		if (copy_to_user(buf,p,len)) 
 			len = -EFAULT;
@@ -1064,7 +1068,7 @@ isdn_read(struct file *file, char *buf, 
 		else
 			dev->drv[drvidx]->stavail = 0;
 		restore_flags(flags);
-		*off += len;
+		*off = pos + len;
 		retval = len;
 		goto out;
 	}
diff -pruN linux-2.4.27-rc4/drivers/macintosh/ans-lcd.c linux-2.4.27-rc4.CAN-2004-0415/drivers/macintosh/ans-lcd.c
--- linux-2.4.27-rc4/drivers/macintosh/ans-lcd.c	2002-02-26 04:37:58.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/macintosh/ans-lcd.c	2004-09-07 13:53:38.000000000 +0900
@@ -53,7 +53,6 @@ anslcd_write( struct file * file, const 
 				size_t count, loff_t *ppos )
 {
 	const char * p = buf;
-	int i;
 
 #ifdef DEBUG
 	printk(KERN_DEBUG "LCD: write\n");
@@ -61,13 +60,13 @@ anslcd_write( struct file * file, const 
 
 	if ( verify_area(VERIFY_READ, buf, count) )
 		return -EFAULT;
-	for ( i = *ppos; count > 0; ++i, ++p, --count ) 
-	{
+	while (count--) {
 		char c;
-		__get_user(c, p);
+		if (__get_user(c, p++))
+			return -EFAULT;
 		anslcd_write_byte_data( c );
 	}
-	*ppos = i;
+	*ppos = p - buf;
 	return p - buf;
 }
 
diff -pruN linux-2.4.27-rc4/drivers/macintosh/nvram.c linux-2.4.27-rc4.CAN-2004-0415/drivers/macintosh/nvram.c
--- linux-2.4.27-rc4/drivers/macintosh/nvram.c	2003-06-13 23:51:34.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/macintosh/nvram.c	2004-09-07 13:53:43.000000000 +0900
@@ -37,14 +37,15 @@ static loff_t nvram_llseek(struct file *
 static ssize_t read_nvram(struct file *file, char *buf,
 			  size_t count, loff_t *ppos)
 {
-	unsigned int i;
+	loff_t n = *ppos;
+	unsigned int i = n;
 	char *p = buf;
 
 	if (verify_area(VERIFY_WRITE, buf, count))
 		return -EFAULT;
-	if (*ppos >= NVRAM_SIZE)
+	if (i != n || i >= NVRAM_SIZE)
 		return 0;
-	for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count)
+	for (; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count)
 		if (__put_user(nvram_read_byte(i), p))
 			return -EFAULT;
 	*ppos = i;
@@ -54,15 +55,16 @@ static ssize_t read_nvram(struct file *f
 static ssize_t write_nvram(struct file *file, const char *buf,
 			   size_t count, loff_t *ppos)
 {
-	unsigned int i;
+	loff_t n = *ppos;
+	unsigned int i = n;
 	const char *p = buf;
 	char c;
 
 	if (verify_area(VERIFY_READ, buf, count))
 		return -EFAULT;
-	if (*ppos >= NVRAM_SIZE)
+	if (i != n || i >= NVRAM_SIZE)
 		return 0;
-	for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) {
+	for (; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) {
 		if (__get_user(c, p))
 			return -EFAULT;
 		nvram_write_byte(c, i);
diff -pruN linux-2.4.27-rc4/drivers/mtd/mtdchar.c linux-2.4.27-rc4.CAN-2004-0415/drivers/mtd/mtdchar.c
--- linux-2.4.27-rc4/drivers/mtd/mtdchar.c	2003-06-13 23:51:34.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/mtd/mtdchar.c	2004-09-07 13:53:38.000000000 +0900
@@ -125,11 +125,15 @@ static ssize_t mtd_read(struct file *fil
 	int ret=0;
 	int len;
 	char *kbuf;
+	loff_t pos = *ppos;
 	
 	DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");
 
-	if (*ppos + count > mtd->size)
-		count = mtd->size - *ppos;
+	if (pos < 0 || pos > mtd->size)
+		return 0;
+
+	if (count > mtd->size - pos)
+		count = mtd->size - pos;
 
 	if (!count)
 		return 0;
@@ -146,9 +150,9 @@ static ssize_t mtd_read(struct file *fil
 		if (!kbuf)
 			return -ENOMEM;
 		
-		ret = MTD_READ(mtd, *ppos, len, &retlen, kbuf);
+		ret = MTD_READ(mtd, pos, len, &retlen, kbuf);
 		if (!ret) {
-			*ppos += retlen;
+			pos += retlen;
 			if (copy_to_user(buf, kbuf, retlen)) {
 			        kfree(kbuf);
 				return -EFAULT;
@@ -167,6 +171,8 @@ static ssize_t mtd_read(struct file *fil
 		kfree(kbuf);
 	}
 	
+	*ppos = pos;
+	
 	return total_retlen;
 } /* mtd_read */
 
@@ -176,17 +182,18 @@ static ssize_t mtd_write(struct file *fi
 	char *kbuf;
 	size_t retlen;
 	size_t total_retlen=0;
+	loff_t pos = *ppos;
 	int ret=0;
 	int len;
 
 	DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n");
 	
-	if (*ppos == mtd->size)
+	if (pos < 0 || pos >= mtd->size)
 		return -ENOSPC;
-	
-	if (*ppos + count > mtd->size)
-		count = mtd->size - *ppos;
 
+	if (count > mtd->size - pos)
+		count = mtd->size - pos;
+	
 	if (!count)
 		return 0;
 
@@ -207,9 +214,9 @@ static ssize_t mtd_write(struct file *fi
 			return -EFAULT;
 		}
 		
-	        ret = (*(mtd->write))(mtd, *ppos, len, &retlen, kbuf);
+	        ret = (*(mtd->write))(mtd, pos, len, &retlen, kbuf);
 		if (!ret) {
-			*ppos += retlen;
+			pos += retlen;
 			total_retlen += retlen;
 			count -= retlen;
 			buf += retlen;
@@ -221,6 +228,7 @@ static ssize_t mtd_write(struct file *fi
 		
 		kfree(kbuf);
 	}
+	*ppos = pos;
 
 	return total_retlen;
 } /* mtd_write */
diff -pruN linux-2.4.27-rc4/drivers/pci/proc.c linux-2.4.27-rc4.CAN-2004-0415/drivers/pci/proc.c
--- linux-2.4.27-rc4/drivers/pci/proc.c	2002-11-29 08:53:14.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/pci/proc.c	2004-09-07 13:53:38.000000000 +0900
@@ -47,7 +47,8 @@ proc_bus_pci_read(struct file *file, cha
 	const struct inode *ino = file->f_dentry->d_inode;
 	const struct proc_dir_entry *dp = ino->u.generic_ip;
 	struct pci_dev *dev = dp->data;
-	unsigned int pos = *ppos;
+	loff_t n = *ppos;
+	unsigned pos = n;
 	unsigned int cnt, size;
 
 	/*
@@ -63,7 +64,7 @@ proc_bus_pci_read(struct file *file, cha
 	else
 		size = 64;
 
-	if (pos >= size)
+	if (pos != n || pos >= size)
 		return 0;
 	if (nbytes >= size)
 		nbytes = size;
@@ -129,10 +130,11 @@ proc_bus_pci_write(struct file *file, co
 	const struct inode *ino = file->f_dentry->d_inode;
 	const struct proc_dir_entry *dp = ino->u.generic_ip;
 	struct pci_dev *dev = dp->data;
-	int pos = *ppos;
+	loff_t n = *ppos;
+	unsigned pos = n;
 	int cnt;
 
-	if (pos >= PCI_CFG_SPACE_SIZE)
+	if (pos != n || pos >= PCI_CFG_SPACE_SIZE)
 		return 0;
 	if (nbytes >= PCI_CFG_SPACE_SIZE)
 		nbytes = PCI_CFG_SPACE_SIZE;
diff -pruN linux-2.4.27-rc4/drivers/pnp/isapnp_proc.c linux-2.4.27-rc4.CAN-2004-0415/drivers/pnp/isapnp_proc.c
--- linux-2.4.27-rc4/drivers/pnp/isapnp_proc.c	2002-11-29 08:53:14.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/pnp/isapnp_proc.c	2004-09-07 13:53:38.000000000 +0900
@@ -102,6 +102,7 @@ static ssize_t isapnp_info_entry_read(st
 				      size_t count, loff_t * offset)
 {
 	isapnp_info_buffer_t *buf;
+	loff_t pos = *offset;
 	long size = 0, size1;
 	int mode;
 
@@ -111,15 +112,15 @@ static ssize_t isapnp_info_entry_read(st
 	buf = (isapnp_info_buffer_t *) file->private_data;
 	if (!buf)
 		return -EIO;
-	if (file->f_pos >= buf->size)
+	if (pos != (unsigned) pos || pos >= buf->size)
 		return 0;
 	size = buf->size < count ? buf->size : count;
-	size1 = buf->size - file->f_pos;
+	size1 = buf->size - pos;
 	if (size1 < size)
 		size = size1;
-	if (copy_to_user(buffer, buf->buffer + file->f_pos, size))
+	if (copy_to_user(buffer, buf->buffer + pos, size))
 		return -EFAULT;
-	file->f_pos += size;
+	*offset = pos + size;
 	return size;
 }
 
@@ -128,6 +129,7 @@ static ssize_t isapnp_info_entry_write(s
 {
 	isapnp_info_buffer_t *buf;
 	long size = 0, size1;
+	loff_t pos = *offset;
 	int mode;
 
 	mode = file->f_flags & O_ACCMODE;
@@ -136,19 +138,19 @@ static ssize_t isapnp_info_entry_write(s
 	buf = (isapnp_info_buffer_t *) file->private_data;
 	if (!buf)
 		return -EIO;
-	if (file->f_pos < 0)
+	if (pos < 0)
 		return -EINVAL;
-	if (file->f_pos >= buf->len)
+	if (pos >= buf->len)
 		return -ENOMEM;
 	size = buf->len < count ? buf->len : count;
-	size1 = buf->len - file->f_pos;
+	size1 = buf->len - pos;
 	if (size1 < size)
 		size = size1;
-	if (copy_from_user(buf->buffer + file->f_pos, buffer, size))
+	if (copy_from_user(buf->buffer + pos, buffer, size))
 		return -EFAULT;
-	if (buf->size < file->f_pos + size)
-		buf->size = file->f_pos + size;
-	file->f_pos += size;
+	if (buf->size < pos + size)
+		buf->size = pos + size;
+	*offset = pos + size;
 	return size;
 }
 
@@ -240,14 +242,15 @@ static ssize_t isapnp_proc_bus_read(stru
 	struct inode *ino = file->f_dentry->d_inode;
 	struct proc_dir_entry *dp = ino->u.generic_ip;
 	struct pci_dev *dev = dp->data;
-	int pos = *ppos;
+	loff_t n = *ppos;
+	unsigned pos = n;
 	int cnt, size = 256;
 
-	if (pos >= size)
+	if (pos != n || pos >= size)
 		return 0;
 	if (nbytes >= size)
 		nbytes = size;
-	if (pos + nbytes > size)
+	if (nbytes > size - pos)
 		nbytes = size - pos;
 	cnt = nbytes;
 
diff -pruN linux-2.4.27-rc4/drivers/s390/block/dasd.c linux-2.4.27-rc4.CAN-2004-0415/drivers/s390/block/dasd.c
--- linux-2.4.27-rc4/drivers/s390/block/dasd.c	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/s390/block/dasd.c	2004-09-07 13:53:38.000000000 +0900
@@ -4655,15 +4655,17 @@ dasd_generic_read (struct file *file, ch
 		   loff_t * offset)
 {
 	loff_t len;
+	loff_t n = *offset;
+	unsigned pos = n;
 	tempinfo_t *p_info = (tempinfo_t *) file->private_data;
 
-	if (*offset >= p_info->len) {
+	if (n != pos || pos >= p_info->len) {
 		return 0;	/* EOF */
 	} else {
-		len = MIN (user_len, (p_info->len - *offset));
-		if (copy_to_user (user_buf, &(p_info->data[*offset]), len))
+		len = MIN (user_len, (p_info->len - pos));
+		if (copy_to_user (user_buf, &(p_info->data[pos]), len))
 			return -EFAULT;
-		(*offset) += len;
+		*offset = pos + len;
 		return len;	/* number of bytes "read" */
 	}
 }
diff -pruN linux-2.4.27-rc4/drivers/s390/char/tapechar.c linux-2.4.27-rc4.CAN-2004-0415/drivers/s390/char/tapechar.c
--- linux-2.4.27-rc4/drivers/s390/char/tapechar.c	2001-11-10 07:05:02.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/s390/char/tapechar.c	2004-09-07 13:53:38.000000000 +0900
@@ -161,6 +161,7 @@ tape_read (struct file *filp, char *data
 	size_t block_size;
 	ccw_req_t *cqr;
 	int rc;
+	loff_t pos = *ppos;
 #ifdef TAPE_DEBUG
         debug_text_event (tape_debug_area,6,"c:read");
 #endif /* TAPE_DEBUG */
@@ -230,7 +231,7 @@ tape_read (struct file *filp, char *data
 	debug_text_event (tape_debug_area,6,"c:rbytes:");
 	debug_int_event (tape_debug_area,6,block_size - ti->devstat.rescnt);
 #endif	/* TAPE_DEBUG */
-	filp->f_pos += block_size - ti->devstat.rescnt;
+	*ppos = pos + (block_size - ti->devstat.rescnt);
 	return block_size - ti->devstat.rescnt;
 }
 
@@ -246,6 +247,8 @@ tape_write (struct file *filp, const cha
 	ccw_req_t *cqr;
 	int nblocks, i, rc;
 	size_t written = 0;
+	loff_t pos = *ppos;
+
 #ifdef TAPE_DEBUG
 	debug_text_event (tape_debug_area,6,"c:write");
 #endif
@@ -318,15 +321,17 @@ tape_write (struct file *filp, const cha
 	        debug_text_event (tape_debug_area,6,"c:wbytes:"); 
 		debug_int_event (tape_debug_area,6,block_size - ti->devstat.rescnt);
 #endif
-		filp->f_pos += block_size - ti->devstat.rescnt;
 		written += block_size - ti->devstat.rescnt;
-		if (ti->devstat.rescnt > 0)
+		if (ti->devstat.rescnt > 0) {
+			*ppos = pos + written;
 			return written;
+		}
 	}
 #ifdef TAPE_DEBUG
 	debug_text_event (tape_debug_area,6,"c:wtotal:");
 	debug_int_event (tape_debug_area,6,written);
 #endif
+	*ppos = pos + written;
 	return written;
 }
 
diff -pruN linux-2.4.27-rc4/drivers/s390/net/ctcmain.c linux-2.4.27-rc4.CAN-2004-0415/drivers/s390/net/ctcmain.c
--- linux-2.4.27-rc4/drivers/s390/net/ctcmain.c	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/s390/net/ctcmain.c	2004-09-07 13:53:38.000000000 +0900
@@ -2934,6 +2934,7 @@ static int ctc_ctrl_open(struct inode *i
 	file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL);
 	if (file->private_data == NULL)
 		return -ENOMEM;
+	*(char *)file->private_data = '\0';
 	MOD_INC_USE_COUNT;
 	return 0;
 }
@@ -2999,6 +3000,7 @@ static ssize_t ctc_ctrl_read(struct file
 	ctc_priv *privptr;
 	ssize_t ret = 0;
 	char *p = sbuf;
+	loff_t pos = *off;
 	int l;
 
 	if (!(dev = find_netdev_by_ino(ino)))
@@ -3008,19 +3010,19 @@ static ssize_t ctc_ctrl_read(struct file
 
 	privptr = (ctc_priv *)dev->priv;
 
-	if (file->f_pos == 0)
+	if (!*sbuf || pos == 0)
 		sprintf(sbuf, "%d\n", privptr->channel[READ]->max_bufsize);
 
 	l = strlen(sbuf);
 	p = sbuf;
-	if (file->f_pos < l) {
-		p += file->f_pos;
+	if (pos == (unsigned)pos && pos < l) {
+		p += pos;
 		l = strlen(p);
 		ret = (count > l) ? l : count;
 		if (copy_to_user(buf, p, ret))
 			return -EFAULT;
+		*off = pos + ret;
 	}
-	file->f_pos += ret;
 	return ret;
 }
 
@@ -3084,6 +3086,7 @@ static ssize_t ctc_loglevel_read(struct 
 	ctc_priv *privptr;
 	ssize_t ret = 0;
 	char *p = sbuf;
+	loff_t pos = *off;
 	int l;
 
 	if (!(dev = find_netdev_by_ino(ino)))
@@ -3093,19 +3096,19 @@ static ssize_t ctc_loglevel_read(struct 
 
 	privptr = (ctc_priv *)dev->priv;
 
-	if (file->f_pos == 0)
+	if (!*sbus || pos == 0)
 		sprintf(sbuf, "0x%02x\n", loglevel);
 
 	l = strlen(sbuf);
 	p = sbuf;
-	if (file->f_pos < l) {
-		p += file->f_pos;
+	if (pos == (unsigned)pos && pos < l) {
+		p += pos;
 		l = strlen(p);
 		ret = (count > l) ? l : count;
 		if (copy_to_user(buf, p, ret))
 			return -EFAULT;
+		*off = pos + ret;
 	}
-	file->f_pos += ret;
 	return ret;
 }
 
@@ -3116,6 +3119,7 @@ static int ctc_stat_open(struct inode *i
 	file->private_data = kmalloc(STATS_BUFSIZE, GFP_KERNEL);
 	if (file->private_data == NULL)
 		return -ENOMEM;
+	*(char *)file->private_data = '\0';
 	MOD_INC_USE_COUNT;
 	return 0;
 }
@@ -3155,6 +3159,7 @@ static ssize_t ctc_stat_read(struct file
 	ctc_priv *privptr;
 	ssize_t ret = 0;
 	char *p = sbuf;
+	loff_t pos = *off;
 	int l;
 
 	if (!(dev = find_netdev_by_ino(ino)))
@@ -3164,7 +3169,7 @@ static ssize_t ctc_stat_read(struct file
 
 	privptr = (ctc_priv *)dev->priv;
 
-	if (file->f_pos == 0) {
+	if (!*sbus || pos == 0) {
 		p += sprintf(p, "Device FSM state: %s\n",
 			     fsm_getstate_str(privptr->fsm));
 		p += sprintf(p, "RX channel FSM state: %s\n",
@@ -3186,14 +3191,14 @@ static ssize_t ctc_stat_read(struct file
 	}
 	l = strlen(sbuf);
 	p = sbuf;
-	if (file->f_pos < l) {
-		p += file->f_pos;
+	if (pos == (unsigned)pos && pos < l) {
+		p += pos;
 		l = strlen(p);
 		ret = (count > l) ? l : count;
 		if (copy_to_user(buf, p, ret))
 			return -EFAULT;
+		*off = pos + ret;
 	}
-	file->f_pos += ret;
 	return ret;
 }
 
diff -pruN linux-2.4.27-rc4/drivers/s390/net/netiucv.c linux-2.4.27-rc4.CAN-2004-0415/drivers/s390/net/netiucv.c
--- linux-2.4.27-rc4/drivers/s390/net/netiucv.c	2003-08-25 20:44:42.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/s390/net/netiucv.c	2004-09-07 13:53:38.000000000 +0900
@@ -1375,6 +1375,7 @@ netiucv_buffer_open(struct inode *inode,
 	file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL);
 	if (file->private_data == NULL)
 		return -ENOMEM;
+	*(char *)file->private_data = '\0';
 	MOD_INC_USE_COUNT;
 	return 0;
 }
@@ -1440,6 +1441,7 @@ netiucv_buffer_read(struct file *file, c
 	netiucv_priv *privptr;
 	ssize_t ret = 0;
 	char *p = sbuf;
+	loff_t pos = *ppos;
 	int l;
 
 	if (!(dev = find_netdev_by_ino(ino)))
@@ -1449,19 +1451,20 @@ netiucv_buffer_read(struct file *file, c
 
 	privptr = (netiucv_priv *)dev->priv;
 
-	if (file->f_pos == 0)
+	if (!*sbuf || pos == 0)
 		sprintf(sbuf, "%d\n", privptr->conn->max_buffsize);
 
 	l = strlen(sbuf);
 	p = sbuf;
-	if (file->f_pos < l) {
-		p += file->f_pos;
+	if (pos == (unsigned)pos && pos < l) {
+		p += pos;
 		l = strlen(p);
 		ret = (count > l) ? l : count;
 		if (copy_to_user(buf, p, ret))
 			return -EFAULT;
 	}
-	file->f_pos += ret;
+	pos += ret;
+	*ppos = pos;
 	return ret;
 }
 
@@ -1471,6 +1474,7 @@ netiucv_user_open(struct inode *inode, s
 	file->private_data = kmalloc(CTRL_BUFSIZE, GFP_KERNEL);
 	if (file->private_data == NULL)
 		return -ENOMEM;
+	*(char *)file->private_data = '\0';
 	MOD_INC_USE_COUNT;
 	return 0;
 }
@@ -1535,6 +1539,7 @@ netiucv_user_read(struct file *file, cha
 	netiucv_priv *privptr;
 	ssize_t ret = 0;
 	char *p = sbuf;
+	loff_t pos = *ppos;
 	int l;
 
 	if (!(dev = find_netdev_by_ino(ino)))
@@ -1545,20 +1550,20 @@ netiucv_user_read(struct file *file, cha
 	privptr = (netiucv_priv *)dev->priv;
 
 
-	if (file->f_pos == 0)
+	if (!*sbuf || pos == 0)
 		sprintf(sbuf, "%s\n",
 			netiucv_printname(privptr->conn->userid));
 
 	l = strlen(sbuf);
 	p = sbuf;
-	if (file->f_pos < l) {
-		p += file->f_pos;
+	if (pos == (unsigned)pos && pos < l) {
+		p += pos;
 		l = strlen(p);
 		ret = (count > l) ? l : count;
 		if (copy_to_user(buf, p, ret))
 			return -EFAULT;
+		*ppos = pos + ret;
 	}
-	file->f_pos += ret;
 	return ret;
 }
 
@@ -1570,6 +1575,7 @@ netiucv_stat_open(struct inode *inode, s
 	file->private_data = kmalloc(STATS_BUFSIZE, GFP_KERNEL);
 	if (file->private_data == NULL)
 		return -ENOMEM;
+	*(char *)file->private_data = '\0';
 	MOD_INC_USE_COUNT;
 	return 0;
 }
@@ -1600,6 +1606,7 @@ static ssize_t
 netiucv_stat_read(struct file *file, char *buf, size_t count, loff_t *off)
 {
 	unsigned int ino = ((struct inode *)file->f_dentry->d_inode)->i_ino;
+	loff_t pos = *ppos;
 	char *sbuf = (char *)file->private_data;
 	net_device *dev;
 	netiucv_priv *privptr;
@@ -1614,7 +1621,7 @@ netiucv_stat_read(struct file *file, cha
 
 	privptr = (netiucv_priv *)dev->priv;
 
-	if (file->f_pos == 0) {
+	if (!*sbuf || pos == 0) {
 		p += sprintf(p, "Device FSM state: %s\n",
 			     fsm_getstate_str(privptr->fsm));
 		p += sprintf(p, "Connection FSM state: %s\n",
@@ -1638,14 +1645,14 @@ netiucv_stat_read(struct file *file, cha
 	}
 	l = strlen(sbuf);
 	p = sbuf;
-	if (file->f_pos < l) {
-		p += file->f_pos;
+	if (pos == (unsigned)pos && pos < l) {
+		p += pos;
 		l = strlen(p);
 		ret = (count > l) ? l : count;
 		if (copy_to_user(buf, p, ret))
 			return -EFAULT;
+		*ppos = pos + ret;
 	}
-	file->f_pos += ret;
 	return ret;
 }
 
diff -pruN linux-2.4.27-rc4/drivers/s390/net/qeth.c linux-2.4.27-rc4.CAN-2004-0415/drivers/s390/net/qeth.c
--- linux-2.4.27-rc4/drivers/s390/net/qeth.c	2003-08-25 20:44:42.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/s390/net/qeth.c	2004-09-07 13:53:38.000000000 +0900
@@ -9792,7 +9792,7 @@ static ssize_t qeth_procfile_write(struc
 	int pos=0,end_pos;
 	char dbf_text[15];
 
-	if (*offset>0) return user_len;
+	if (*offset) return user_len;
 	buffer=vmalloc(__max(user_len+1,QETH_DBF_MISC_LEN));
 	if (buffer == NULL)
 		return -ENOMEM;
@@ -10308,14 +10308,16 @@ static ssize_t qeth_procfile_read(struct
 {
 	loff_t len;
 	tempinfo_t *p_info = (tempinfo_t *) file->private_data;
+	loff_t n = *offset;
+	unsigned long pos = n;
 	
-	if (*offset >= p_info->len) {
+	if (pos != n || pos >= p_info->len) {
 		return 0;
 	} else {
-		len = __min(user_len, (p_info->len - *offset));
-		if (copy_to_user (user_buf, &(p_info->data[*offset]), len))
+		len = __min(user_len, (p_info->len - pos));
+		if (copy_to_user (user_buf, &(p_info->data[pos]), len))
 			return -EFAULT;
-		(*offset) += len;
+		*offset = pos + len;
 		return len;
 	}
 }
@@ -10350,7 +10352,7 @@ static ssize_t qeth_ipato_procfile_write
 	qeth_card_t *card;
 #define BUFFER_LEN (10+32+1+5+1+DEV_NAME_LEN+1)
 
-	if (*offset>0) return user_len;
+	if (*offset) return user_len;
 	buffer=vmalloc(__max(__max(user_len+1,BUFFER_LEN),QETH_DBF_MISC_LEN));
 
 	if (buffer == NULL)
@@ -10474,7 +10476,7 @@ static ssize_t qeth_ipato_procfile_write
 	PRINT_ERR("unknown ipato information command\n");
 out:
 	vfree(buffer);
-	*offset = *offset + user_len;
+	*offset = user_len;
 #undef BUFFER_LEN
 	return user_len;
 }
diff -pruN linux-2.4.27-rc4/drivers/s390/s390io.c linux-2.4.27-rc4.CAN-2004-0415/drivers/s390/s390io.c
--- linux-2.4.27-rc4/drivers/s390/s390io.c	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/s390/s390io.c	2004-09-07 13:53:38.000000000 +0900
@@ -8328,14 +8328,15 @@ chan_subch_read (struct file *file, char
 {
 	loff_t len;
 	tempinfo_t *p_info = (tempinfo_t *) file->private_data;
+	loff_t pos = *offset;
 
-	if (*offset >= p_info->len) {
+	if (pos < 0 || pos >= p_info->len) {
 		return 0;
 	} else {
-		len = MIN (user_len, (p_info->len - *offset));
-		if (copy_to_user (user_buf, &(p_info->data[*offset]), len))
+		len = MIN (user_len, (p_info->len - pos));
+		if (copy_to_user (user_buf, &(p_info->data[pos]), len))
 			return -EFAULT;
-		(*offset) += len;
+		*offset = pos + len;
 		return len;
 	}
 }
@@ -8410,14 +8411,15 @@ cio_device_entry_read (struct file *file
 {
 	loff_t len;
 	tempinfo_t *p_info = (tempinfo_t *) file->private_data;
+	loff_t pos = *offset;
 
-	if (*offset >= p_info->len) {
+	if (pos < 0 || pos >= p_info->len) {
 		return 0;
 	} else {
-		len = MIN (user_len, (p_info->len - *offset));
-		if (copy_to_user (user_buf, &(p_info->data[*offset]), len))
+		len = MIN (user_len, (p_info->len - pos));
+		if (copy_to_user (user_buf, &(p_info->data[pos]), len))
 			return -EFAULT;
-		(*offset) += len;
+		*offset = pos + len;
 		return len;
 	}
 }
@@ -8874,14 +8876,15 @@ cio_ignore_proc_read (struct file *file,
 {
 	loff_t len;
 	tempinfo_t *p_info = (tempinfo_t *) file->private_data;
+	loff_t pos = *offset;
 
-	if (*offset >= p_info->len) {
+	if (pos < 0 || pos >= p_info->len) {
 		return 0;
 	} else {
 		len = MIN (user_len, (p_info->len - *offset));
 		if (copy_to_user (user_buf, &(p_info->data[*offset]), len))
 			return -EFAULT;
-		(*offset) += len;
+		(*offset) = pos + len;
 		return len;
 	}
 }
@@ -8994,14 +8997,15 @@ cio_irq_proc_read (struct file *file, ch
 {
 	loff_t len;
 	tempinfo_t *p_info = (tempinfo_t *) file->private_data;
+	loff_t pos = *offset;
 
-	if (*offset >= p_info->len) {
+	if (pos < 0 || pos >= p_info->len) {
 		return 0;
 	} else {
 		len = MIN (user_len, (p_info->len - *offset));
 		if (copy_to_user (user_buf, &(p_info->data[*offset]), len))
 			return -EFAULT;
-		(*offset) += len;
+		(*offset) = pos + len;
 		return len;
 	}
 }
@@ -9123,14 +9127,15 @@ cio_chpids_proc_read( struct file *file,
 {
      loff_t len;
      tempinfo_t *p_info = (tempinfo_t *) file->private_data;
+     loff_t pos = *offset;
      
-     if ( *offset>=p_info->len) {
+     if (pos < 0 || pos >= p_info->len) {
 	  return 0;
      } else {
-	  len = MIN(user_len, (p_info->len - *offset));
-	  if (copy_to_user( user_buf, &(p_info->data[*offset]), len))
+	  len = MIN(user_len, (p_info->len - pos));
+	  if (copy_to_user( user_buf, &(p_info->data[pos]), len))
 	       return -EFAULT; 
-	  (* offset) += len;
+	  *offset = pos + len;
 	  return len;
      }
 }
diff -pruN linux-2.4.27-rc4/drivers/sbus/char/flash.c linux-2.4.27-rc4.CAN-2004-0415/drivers/sbus/char/flash.c
--- linux-2.4.27-rc4/drivers/sbus/char/flash.c	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/sbus/char/flash.c	2004-09-07 13:53:38.000000000 +0900
@@ -105,9 +105,15 @@ static ssize_t
 flash_read(struct file * file, char * buf,
 	   size_t count, loff_t *ppos)
 {
-	unsigned long p = file->f_pos;
+	loff_t p = *ppos;
 	int i;
 	
+	if (p > flash.read_size)
+		return 0;
+
+	if (p < 0)
+		return -EINVAL;
+
 	if (count > flash.read_size - p)
 		count = flash.read_size - p;
 
@@ -118,7 +124,7 @@ flash_read(struct file * file, char * bu
 		buf++;
 	}
 
-	file->f_pos += count;
+	*ppos = p + count;
 	return count;
 }
 
diff -pruN linux-2.4.27-rc4/drivers/scsi/osst.c linux-2.4.27-rc4.CAN-2004-0415/drivers/scsi/osst.c
--- linux-2.4.27-rc4/drivers/scsi/osst.c	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/scsi/osst.c	2004-09-07 13:53:38.000000000 +0900
@@ -3148,6 +3148,7 @@ static ssize_t osst_write(struct file * 
 	ST_mode * STm;
 	ST_partstat * STps;
 	int dev = TAPE_NR(inode->i_rdev);
+	loff_t pos = *ppos;
 
 	STp = os_scsi_tapes[dev];
 
@@ -3369,7 +3370,7 @@ if (SRpnt) printk(KERN_ERR "osst%d:A: No
 		if (i == (-ENOSPC)) {
 			transfer = STp->buffer->writing;	/* FIXME -- check this logic */
 			if (transfer <= do_count) {
-				filp->f_pos += do_count - transfer;
+				pos += do_count - transfer;
 				count -= do_count - transfer;
 				if (STps->drv_block >= 0) {
 					STps->drv_block += (do_count - transfer) / STp->block_size;
@@ -3407,7 +3408,7 @@ if (SRpnt) printk(KERN_ERR "osst%d:A: No
 			goto out;
 		}
 
-		filp->f_pos += do_count;
+		pos += do_count;
 		b_point += do_count;
 		count -= do_count;
 		if (STps->drv_block >= 0) {
@@ -3429,7 +3430,7 @@ if (SRpnt) printk(KERN_ERR "osst%d:A: No
 		if (STps->drv_block >= 0) {
 			STps->drv_block += blks;
 		}
-		filp->f_pos += count;
+		pos += count;
 		count = 0;
 	}
 
@@ -3459,6 +3460,7 @@ if (SRpnt) printk(KERN_ERR "osst%d:A: No
 	retval = total;
 
 out:
+	*ppos = pos;
 	if (SRpnt != NULL) scsi_release_request(SRpnt);
 
 	up(&STp->lock);
@@ -3479,6 +3481,7 @@ static ssize_t osst_read(struct file * f
 	ST_partstat * STps;
 	Scsi_Request *SRpnt = NULL;
 	int dev = TAPE_NR(inode->i_rdev);
+	loff_t pos = *ppos;
 
 	STp = os_scsi_tapes[dev];
 
@@ -3614,7 +3617,7 @@ static ssize_t osst_read(struct file * f
 			}
 			STp->logical_blk_num += transfer / STp->block_size;
 			STps->drv_block      += transfer / STp->block_size;
-			filp->f_pos          += transfer;
+			pos                  += transfer;
 			buf                  += transfer;
 			total                += transfer;
 		}
@@ -3653,6 +3656,7 @@ static ssize_t osst_read(struct file * f
 	retval = total;
 
 out:
+	*ppos = pos;
 	if (SRpnt != NULL) scsi_release_request(SRpnt);
 
 	up(&STp->lock);
@@ -5501,6 +5505,7 @@ static struct file_operations osst_fops 
 	read:		osst_read,
 	write:		osst_write,
 	ioctl:		osst_ioctl,
+	llseek:		no_llseek,
 	open:		os_scsi_tape_open,
 	flush:		os_scsi_tape_flush,
 	release:	os_scsi_tape_close,
diff -pruN linux-2.4.27-rc4/drivers/scsi/st.c linux-2.4.27-rc4.CAN-2004-0415/drivers/scsi/st.c
--- linux-2.4.27-rc4/drivers/scsi/st.c	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/scsi/st.c	2004-09-07 13:53:38.000000000 +0900
@@ -1202,6 +1202,7 @@ static ssize_t
 	ST_mode *STm;
 	ST_partstat *STps;
 	int dev = TAPE_NR(inode->i_rdev);
+	loff_t pos = *ppos;
 
 	read_lock(&st_dev_arr_lock);
 	STp = scsi_tapes[dev];
@@ -1433,7 +1434,7 @@ static ssize_t
 					residual *= STp->block_size;
 				if (residual <= do_count) {
 					/* Within the data in this write() */
-					filp->f_pos += do_count - residual;
+					pos += do_count - residual;
 					count -= do_count - residual;
 					if (STps->drv_block >= 0) {
 						if (STp->block_size == 0 &&
@@ -1489,7 +1490,7 @@ static ssize_t
 				retval = total - count;
 			goto out;
 		}
-		filp->f_pos += do_count;
+		pos += do_count;
 		b_point += do_count;
 		count -= do_count;
 		if (STps->drv_block >= 0) {
@@ -1508,7 +1509,7 @@ static ssize_t
 			retval = i;
 			goto out;
 		}
-		filp->f_pos += count;
+		pos += count;
 		count = 0;
 	}
 
@@ -1543,6 +1544,7 @@ static ssize_t
 	retval = total - count;
 
  out:
+	*ppos = pos;
 	if (SRpnt != NULL)
 		scsi_release_request(SRpnt);
 	up(&STp->lock);
@@ -1743,6 +1745,7 @@ static ssize_t
 	ST_mode *STm;
 	ST_partstat *STps;
 	int dev = TAPE_NR(inode->i_rdev);
+	loff_t pos = *ppos;
 
 	read_lock(&st_dev_arr_lock);
 	STp = scsi_tapes[dev];
@@ -1887,7 +1890,7 @@ static ssize_t
 				retval = i;
 				goto out;
 			}
-			filp->f_pos += transfer;
+			pos += transfer;
 			buf += transfer;
 			total += transfer;
 		}
@@ -1917,6 +1920,7 @@ static ssize_t
 	retval = total;
 
  out:
+	*ppos = pos;
 	if (SRpnt != NULL) {
 		scsi_release_request(SRpnt);
 		SRpnt = NULL;
@@ -3774,6 +3778,7 @@ static struct file_operations st_fops =
 	read:		st_read,
 	write:		st_write,
 	ioctl:		st_ioctl,
+	llseek:		no_llseek,
 	open:		st_open,
 	flush:		st_flush,
 	release:	st_release,
diff -pruN linux-2.4.27-rc4/drivers/usb/brlvger.c linux-2.4.27-rc4.CAN-2004-0415/drivers/usb/brlvger.c
--- linux-2.4.27-rc4/drivers/usb/brlvger.c	2004-09-07 13:53:02.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/usb/brlvger.c	2004-09-07 13:53:38.000000000 +0900
@@ -596,6 +596,9 @@ brlvger_write(struct file *file, const c
 
 	off = *pos;
 
+	if (off < 0)
+		return -EINVAL;
+
 	if(off > priv->plength)
 		return -ESPIPE;;
 
diff -pruN linux-2.4.27-rc4/drivers/usb/devio.c linux-2.4.27-rc4.CAN-2004-0415/drivers/usb/devio.c
--- linux-2.4.27-rc4/drivers/usb/devio.c	2003-11-29 03:26:20.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/usb/devio.c	2004-09-07 13:53:38.000000000 +0900
@@ -80,7 +80,7 @@ static ssize_t usbdev_read(struct file *
 	struct dev_state *ps = (struct dev_state *)file->private_data;
 	ssize_t ret = 0;
 	unsigned len;
-	loff_t pos;
+	loff_t pos, last;
 	int i;
 
 	pos = *ppos;
@@ -102,37 +102,38 @@ static ssize_t usbdev_read(struct file *
 			goto err;
 		}
 
-		*ppos += len;
+		pos += len;
 		buf += len;
 		nbytes -= len;
 		ret += len;
 	}
 
-	pos = sizeof(struct usb_device_descriptor);
+	last = sizeof(struct usb_device_descriptor);
 	for (i = 0; nbytes && i < ps->dev->descriptor.bNumConfigurations; i++) {
 		struct usb_config_descriptor *config =
 			(struct usb_config_descriptor *)ps->dev->rawdescriptors[i];
 		unsigned int length = le16_to_cpu(config->wTotalLength);
 
-		if (*ppos < pos + length) {
-			len = length - (*ppos - pos);
+		if (pos < last + length) {
+			len = length - (pos - last);
 			if (len > nbytes)
 				len = nbytes;
 
 			if (copy_to_user(buf,
-			    ps->dev->rawdescriptors[i] + (*ppos - pos), len)) {
+			    ps->dev->rawdescriptors[i] + (pos - last), len)) {
 				ret = -EFAULT;
 				goto err;
 			}
 
-			*ppos += len;
+			pos += len;
 			buf += len;
 			nbytes -= len;
 			ret += len;
 		}
 
-		pos += length;
+		last += length;
 	}
+	*ppos = pos;
 
 err:
 	up_read(&ps->devsem);
diff -pruN linux-2.4.27-rc4/drivers/usb/drivers.c linux-2.4.27-rc4.CAN-2004-0415/drivers/usb/drivers.c
--- linux-2.4.27-rc4/drivers/usb/drivers.c	2000-04-27 07:22:55.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/usb/drivers.c	2004-09-07 13:53:38.000000000 +0900
@@ -52,9 +52,10 @@ static ssize_t usb_driver_read(struct fi
 	struct list_head *tmp = usb_driver_list.next;
 	char *page, *start, *end;
 	ssize_t ret = 0;
-	unsigned int pos, len;
+	loff_t n = *ppos;
+	unsigned int pos = n, len;
 
-	if (*ppos < 0)
+	if (pos != n)
 		return -EINVAL;
 	if (nbytes <= 0)
 		return 0;
@@ -64,7 +65,6 @@ static ssize_t usb_driver_read(struct fi
                 return -ENOMEM;
 	start = page;
 	end = page + (PAGE_SIZE - 100);
-	pos = *ppos;
 	for (; tmp != &usb_driver_list; tmp = tmp->next) {
 		struct usb_driver *driver = list_entry(tmp, struct usb_driver, driver_list);
 		int minor = driver->fops ? driver->minor : -1;
@@ -88,7 +88,7 @@ static ssize_t usb_driver_read(struct fi
 		if (copy_to_user(buf, page + pos, len))
 			ret = -EFAULT;
 		else
-			*ppos += len;
+			*ppos = pos + len;
 	}
 	free_page((unsigned long)page);
 	return ret;
diff -pruN linux-2.4.27-rc4/drivers/usb/host/uhci-debug.h linux-2.4.27-rc4.CAN-2004-0415/drivers/usb/host/uhci-debug.h
--- linux-2.4.27-rc4/drivers/usb/host/uhci-debug.h	2003-11-29 03:26:20.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/usb/host/uhci-debug.h	2004-09-07 13:53:38.000000000 +0900
@@ -530,16 +530,14 @@ static ssize_t uhci_proc_read(struct fil
 			loff_t *ppos)
 {
 	struct uhci_proc *up = file->private_data;
-	unsigned int pos;
+	loff_t n = *ppos;
+	unsigned int pos = n;
 	unsigned int size;
 
-	pos = *ppos;
 	size = up->size;
-	if (pos >= size)
+	if (pos != n || pos >= size)
 		return 0;
-	if (nbytes >= size)
-		nbytes = size;
-	if (pos + nbytes > size)
+	if (nbytes > size - pos)
 		nbytes = size - pos;
 
 	if (!access_ok(VERIFY_WRITE, buf, nbytes))
@@ -548,7 +546,7 @@ static ssize_t uhci_proc_read(struct fil
 	if (copy_to_user(buf, up->data + pos, nbytes))
 		return -EFAULT;
 
-	*ppos += nbytes;
+	*ppos = pos + nbytes;
 
 	return nbytes;
 }
diff -pruN linux-2.4.27-rc4/drivers/video/fbmem.c linux-2.4.27-rc4.CAN-2004-0415/drivers/video/fbmem.c
--- linux-2.4.27-rc4/drivers/video/fbmem.c	2004-02-18 22:36:31.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/video/fbmem.c	2004-09-07 13:53:38.000000000 +0900
@@ -404,7 +404,7 @@ static int fbmem_read_proc(char *buf, ch
 static ssize_t
 fb_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 {
-	unsigned long p = *ppos;
+	loff_t p = *ppos;
 	struct inode *inode = file->f_dentry->d_inode;
 	int fbidx = GET_FB_IDX(inode->i_rdev);
 	struct fb_info *info = registered_fb[fbidx];
@@ -414,12 +414,13 @@ fb_read(struct file *file, char *buf, si
 	if (! fb || ! info->disp)
 		return -ENODEV;
 
+	if (p < 0)
+		return -EINVAL;
+
 	fb->fb_get_fix(&fix,PROC_CONSOLE(info), info);
 	if (p >= fix.smem_len)
 	    return 0;
-	if (count >= fix.smem_len)
-	    count = fix.smem_len;
-	if (count + p > fix.smem_len)
+	if (count > fix.smem_len - p)
 		count = fix.smem_len - p;
 	if (count) {
 	    char *base_addr;
@@ -428,7 +429,7 @@ fb_read(struct file *file, char *buf, si
 	    count -= copy_to_user(buf, base_addr+p, count);
 	    if (!count)
 		return -EFAULT;
-	    *ppos += count;
+	    *ppos = p + count;
 	}
 	return count;
 }
@@ -436,7 +437,7 @@ fb_read(struct file *file, char *buf, si
 static ssize_t
 fb_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
 {
-	unsigned long p = *ppos;
+	loff_t p = *ppos;
 	struct inode *inode = file->f_dentry->d_inode;
 	int fbidx = GET_FB_IDX(inode->i_rdev);
 	struct fb_info *info = registered_fb[fbidx];
@@ -447,13 +448,14 @@ fb_write(struct file *file, const char *
 	if (! fb || ! info->disp)
 		return -ENODEV;
 
+	if (p < 0)
+		return -EINVAL;
+
 	fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
 	if (p > fix.smem_len)
 	    return -ENOSPC;
-	if (count >= fix.smem_len)
-	    count = fix.smem_len;
 	err = 0;
-	if (count + p > fix.smem_len) {
+	if (count > fix.smem_len - p) {
 	    count = fix.smem_len - p;
 	    err = -ENOSPC;
 	}
@@ -462,7 +464,7 @@ fb_write(struct file *file, const char *
 
 	    base_addr = info->disp->screen_base;
 	    count -= copy_from_user(base_addr+p, buf, count);
-	    *ppos += count;
+	    *ppos = p + count;
 	    err = -EFAULT;
 	}
 	if (count)
diff -pruN linux-2.4.27-rc4/drivers/zorro/proc.c linux-2.4.27-rc4.CAN-2004-0415/drivers/zorro/proc.c
--- linux-2.4.27-rc4/drivers/zorro/proc.c	2002-11-29 08:53:15.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/drivers/zorro/proc.c	2004-09-07 13:53:38.000000000 +0900
@@ -50,11 +50,9 @@ proc_bus_zorro_read(struct file *file, c
 	struct ConfigDev cd;
 	loff_t pos = *ppos;
 
-	if (pos >= sizeof(struct ConfigDev))
+	if (pos < 0 || pos >= sizeof(struct ConfigDev))
 		return 0;
-	if (nbytes >= sizeof(struct ConfigDev))
-		nbytes = sizeof(struct ConfigDev);
-	if (pos + nbytes > sizeof(struct ConfigDev))
+	if (nbytes > sizeof(struct ConfigDev) - pos)
 		nbytes = sizeof(struct ConfigDev) - pos;
 
 	/* Construct a ConfigDev */
@@ -67,7 +65,7 @@ proc_bus_zorro_read(struct file *file, c
 
 	if (copy_to_user(buf, &cd, nbytes))
 		return -EFAULT;
-	*ppos += nbytes;
+	*ppos = pos + nbytes;
 
 	return nbytes;
 }
diff -pruN linux-2.4.27-rc4/fs/devfs/base.c linux-2.4.27-rc4.CAN-2004-0415/fs/devfs/base.c
--- linux-2.4.27-rc4/fs/devfs/base.c	2004-04-14 22:05:40.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/fs/devfs/base.c	2004-09-07 13:53:38.000000000 +0900
@@ -3312,7 +3312,7 @@ static ssize_t devfsd_read (struct file 
 {
     int done = FALSE;
     int ival;
-    loff_t pos, devname_offset, tlen, rpos;
+    loff_t pos, devname_offset, tlen, rpos, old_pos;
     devfs_handle_t de;
     struct devfsd_buf_entry *entry;
     struct fs_info *fs_info = file->f_dentry->d_inode->i_sb->u.generic_sbp;
@@ -3363,8 +3363,8 @@ static ssize_t devfsd_read (struct file 
     info->namelen = DEVFS_PATHLEN - pos - 1;
     if (info->mode == 0) info->mode = de->mode;
     devname_offset = info->devname - (char *) info;
-    rpos = *ppos;
-    if (rpos < devname_offset)
+    old_pos = rpos = *ppos;
+    if (rpos >= 0 && rpos < devname_offset)
     {
 	/*  Copy parts of the header  */
 	tlen = devname_offset - rpos;
@@ -3390,7 +3390,7 @@ static ssize_t devfsd_read (struct file 
 	}
 	rpos += tlen;
     }
-    tlen = rpos - *ppos;
+    tlen = rpos - old_pos;
     if (done)
     {
 	devfs_handle_t parent;
@@ -3504,16 +3504,17 @@ static ssize_t stat_read (struct file *f
 			  loff_t *ppos)
 {
     ssize_t num;
+    loff_t n = *ppos;
     char txt[80];
 
     num = sprintf (txt, "Number of entries: %u  number of bytes: %u\n",
 		   stat_num_entries, stat_num_bytes) + 1;
     /*  Can't seek (pread) on this device  */
     if (ppos != &file->f_pos) return -ESPIPE;
-    if (*ppos >= num) return 0;
-    if (*ppos + len > num) len = num - *ppos;
-    if ( copy_to_user (buf, txt + *ppos, len) ) return -EFAULT;
-    *ppos += len;
+    if (n != (unsigned)n || n >= num) return 0;
+    if (len > num - n) len = num - n;
+    if ( copy_to_user (buf, txt + n, len) ) return -EFAULT;
+    *ppos = n + len;
     return len;
 }   /*  End Function stat_read  */
 #endif
diff -pruN linux-2.4.27-rc4/fs/hfs/file.c linux-2.4.27-rc4.CAN-2004-0415/fs/hfs/file.c
--- linux-2.4.27-rc4/fs/hfs/file.c	2002-02-26 04:38:08.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/fs/hfs/file.c	2004-09-07 13:53:38.000000000 +0900
@@ -150,7 +150,7 @@ static hfs_rwret_t hfs_file_read(struct 
 		return -EINVAL;
 	}
 	pos = *ppos;
-	if (pos >= HFS_FORK_MAX) {
+	if (pos < 0 || pos >= HFS_FORK_MAX) {
 		return 0;
 	}
 	size = inode->i_size;
@@ -167,7 +167,7 @@ static hfs_rwret_t hfs_file_read(struct 
 	}
 	if ((read = hfs_do_read(inode, HFS_I(inode)->fork, pos,
 				buf, left, filp->f_reada != 0)) > 0) {
-	        *ppos += read;
+	        *ppos = pos + read;
 		filp->f_reada = 1;
 	}
 
@@ -197,7 +197,7 @@ static hfs_rwret_t hfs_file_write(struct
 
 	pos = (filp->f_flags & O_APPEND) ? inode->i_size : *ppos;
 
-	if (pos >= HFS_FORK_MAX) {
+	if (pos < 0 || pos >= HFS_FORK_MAX) {
 		return 0;
 	}
 	if (count > HFS_FORK_MAX) {
@@ -207,8 +207,8 @@ static hfs_rwret_t hfs_file_write(struct
 	        pos += written;
 
 	*ppos = pos;
-	if (*ppos > inode->i_size) {
-	        inode->i_size = *ppos;
+	if (pos > inode->i_size) {
+	        inode->i_size = pos;
 		mark_inode_dirty(inode);
 	}
 
diff -pruN linux-2.4.27-rc4/fs/hfs/file_cap.c linux-2.4.27-rc4.CAN-2004-0415/fs/hfs/file_cap.c
--- linux-2.4.27-rc4/fs/hfs/file_cap.c	2001-09-10 23:31:25.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/fs/hfs/file_cap.c	2004-09-07 13:53:38.000000000 +0900
@@ -191,7 +191,7 @@ static hfs_rwret_t cap_info_write(struct
 				  hfs_rwarg_t count, loff_t *ppos)
 {
         struct inode *inode = filp->f_dentry->d_inode;
-	hfs_u32 pos;
+	hfs_u32 pos, last;
 
 	if (!S_ISREG(inode->i_mode)) {
 		hfs_warn("hfs_file_write: mode = %07o\n", inode->i_mode);
@@ -207,14 +207,14 @@ static hfs_rwret_t cap_info_write(struct
 		return 0;
 	}
 
-	*ppos += count;
-	if (*ppos > HFS_FORK_MAX) {
-		*ppos = HFS_FORK_MAX;
+	last = pos + count;
+	if (last > HFS_FORK_MAX) {
+		last = HFS_FORK_MAX;
 		count = HFS_FORK_MAX - pos;
 	}
 
-	if (*ppos > inode->i_size)
-	        inode->i_size = *ppos;
+	if (last > inode->i_size)
+	        inode->i_size = last;
 
 	/* Only deal with the part we store in memory */
 	if (pos < sizeof(struct hfs_cap_info)) {
@@ -272,6 +272,7 @@ static hfs_rwret_t cap_info_write(struct
 		}
 	}
 
+	*ppos = last;
 	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 	mark_inode_dirty(inode);
 	return count;
diff -pruN linux-2.4.27-rc4/fs/hfs/file_hdr.c linux-2.4.27-rc4.CAN-2004-0415/fs/hfs/file_hdr.c
--- linux-2.4.27-rc4/fs/hfs/file_hdr.c	2001-08-13 02:56:56.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/fs/hfs/file_hdr.c	2004-09-07 13:53:38.000000000 +0900
@@ -384,7 +384,7 @@ static hfs_rwret_t hdr_read(struct file 
 	struct hfs_cat_entry *entry = HFS_I(inode)->entry;
 	const struct hfs_hdr_layout *layout;
 	off_t start, length, offset;
-	off_t pos = *ppos;
+	loff_t pos = *ppos;
 	int left, lcv, read = 0;
 
 	if (!S_ISREG(inode->i_mode)) {
@@ -399,7 +399,7 @@ static hfs_rwret_t hdr_read(struct file 
 	}
 
 	/* Adjust count to fit within the bounds of the file */
-	if ((pos >= inode->i_size) || (count <= 0)) {
+	if (pos != (unsigned)pos || pos >= inode->i_size || count <= 0) {
 		return 0;
 	} else if (count > inode->i_size - pos) {
 		count = inode->i_size - pos;
@@ -646,7 +646,7 @@ static hfs_rwret_t hdr_write(struct file
 		hfs_warn("hfs_hdr_write: mode = %07o\n", inode->i_mode);
 		return -EINVAL;
 	}
-	if (count <= 0) {
+	if (count <= 0 || pos != (unsigned)pos) {
 		return 0;
 	}
 
diff -pruN linux-2.4.27-rc4/fs/openpromfs/inode.c linux-2.4.27-rc4.CAN-2004-0415/fs/openpromfs/inode.c
--- linux-2.4.27-rc4/fs/openpromfs/inode.c	2001-12-22 02:42:03.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/fs/openpromfs/inode.c	2004-09-07 13:53:38.000000000 +0900
@@ -69,17 +69,18 @@ static ssize_t nodenum_read(struct file 
 			    size_t count, loff_t *ppos)
 {
 	struct inode *inode = file->f_dentry->d_inode;
+	loff_t pos = *ppos;
 	char buffer[10];
 	
 	if (count < 0 || !inode->u.generic_ip)
 		return -EINVAL;
 	sprintf (buffer, "%8.8x\n", (u32)(long)(inode->u.generic_ip));
-	if (file->f_pos >= 9)
+	if (pos != (unsigned)pos || pos >= 9)
 		return 0;
-	if (count > 9 - file->f_pos)
-		count = 9 - file->f_pos;
-	copy_to_user(buf, buffer + file->f_pos, count);
-	file->f_pos += count;
+	if (count > 9 - pos)
+		count = 9 - pos;
+	copy_to_user(buf, buffer + pos, count);
+	*ppos = pos + count;
 	return count;
 }
 
@@ -87,6 +88,7 @@ static ssize_t property_read(struct file
 			     size_t count, loff_t *ppos)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
+	loff_t pos = *ppos;
 	int i, j, k;
 	u32 node;
 	char *p, *s;
@@ -94,7 +96,7 @@ static ssize_t property_read(struct file
 	openprom_property *op;
 	char buffer[64];
 	
-	if (filp->f_pos >= 0xffffff)
+	if (pos < 0 || pos >= 0xffffff)
 		return -EINVAL;
 	if (!filp->private_data) {
 		node = nodes[(u16)((long)inode->u.generic_ip)].node;
@@ -180,7 +182,7 @@ static ssize_t property_read(struct file
 	} else {
 		i = (op->len << 1) + 1;
 	}
-	k = filp->f_pos;
+	k = pos;
 	if (k >= i) return 0;
 	if (count > i - k) count = i - k;
 	if (op->flag & OPP_STRING) {
@@ -196,16 +198,16 @@ static ssize_t property_read(struct file
 			j = count;
 
 		if (j >= 0) {
-			copy_to_user(buf + k - filp->f_pos,
+			copy_to_user(buf + k - pos,
 				     op->value + k - 1, j);
 			count -= j;
 			k += j;
 		}
 
 		if (count)
-			__put_user('\'', &buf [k++ - filp->f_pos]);
+			__put_user('\'', &buf [k++ - pos]);
 		if (count > 1)
-			__put_user('\n', &buf [k++ - filp->f_pos]);
+			__put_user('\n', &buf [k++ - pos]);
 
 	} else if (op->flag & OPP_STRINGLIST) {
 		char *tmp;
@@ -273,47 +275,48 @@ static ssize_t property_read(struct file
 
 		if ((k < i - 1) && (k & 1)) {
 			sprintf (buffer, "%02x", *(op->value + (k >> 1)));
-			__put_user(buffer[1], &buf[k++ - filp->f_pos]);
+			__put_user(buffer[1], &buf[k++ - pos]);
 			count--;
 		}
 
 		for (; (count > 1) && (k < i - 1); k += 2) {
 			sprintf (buffer, "%02x", *(op->value + (k >> 1)));
-			copy_to_user (buf + k - filp->f_pos, buffer, 2);
+			copy_to_user (buf + k - pos, buffer, 2);
 			count -= 2;
 		}
 
 		if (count && (k < i - 1)) {
 			sprintf (buffer, "%02x", *(op->value + (k >> 1)));
-			__put_user(buffer[0], &buf[k++ - filp->f_pos]);
+			__put_user(buffer[0], &buf[k++ - pos]);
 			count--;
 		}
 
 		if (count)
-			__put_user('\n', &buf [k++ - filp->f_pos]);
+			__put_user('\n', &buf [k++ - pos]);
 	}
-	count = k - filp->f_pos;
-	filp->f_pos = k;
+	count = k - pos;
+	*ppos = k;
 	return count;
 }
 
 static ssize_t property_write(struct file *filp, const char *buf,
 			      size_t count, loff_t *ppos)
 {
+	loff_t pos = *ppos;
 	int i, j, k;
 	char *p;
 	u32 *q;
 	void *b;
 	openprom_property *op;
 	
-	if (filp->f_pos >= 0xffffff)
+	if (pos < 0 || pos >= 0xffffff)
 		return -EINVAL;
 	if (!filp->private_data) {
 		i = property_read (filp, NULL, 0, 0);
 		if (i)
 			return i;
 	}
-	k = filp->f_pos;
+	k = pos;
 	op = (openprom_property *)filp->private_data;
 	if (!(op->flag & OPP_STRING)) {
 		u32 *first, *last;
@@ -433,7 +436,8 @@ static ssize_t property_write(struct fil
 				op->len = i;
 		} else
 			op->len = i;
-		filp->f_pos += count;
+		pos += count;
+		*ppos = pos;
 	}
 write_try_string:
 	if (!(op->flag & OPP_BINARY)) {
@@ -450,7 +454,8 @@ write_try_string:
 				op->flag |= OPP_QUOTED;
 				buf++;
 				count--;
-				filp->f_pos++;
+				pos++;
+				*ppos = pos;
 				if (!count) {
 					op->flag |= OPP_STRING;
 					return 1;
@@ -459,9 +464,9 @@ write_try_string:
 				op->flag |= OPP_NOTQUOTED;
 		}
 		op->flag |= OPP_STRING;
-		if (op->alloclen <= count + filp->f_pos) {
+		if (op->alloclen <= count + pos) {
 			b = kmalloc (sizeof (openprom_property)
-				     + 2 * (count + filp->f_pos), GFP_KERNEL);
+				     + 2 * (count + pos), GFP_KERNEL);
 			if (!b)
 				return -ENOMEM;
 			memcpy (b, filp->private_data,
@@ -469,14 +474,14 @@ write_try_string:
 				+ strlen (op->name) + op->alloclen);
 			memset (((char *)b) + sizeof (openprom_property)
 				+ strlen (op->name) + op->alloclen, 
-				0, 2*(count - filp->f_pos) - op->alloclen);
+				0, 2*(count - pos) - op->alloclen);
 			op = (openprom_property *)b;
-			op->alloclen = 2*(count + filp->f_pos);
+			op->alloclen = 2*(count + pos);
 			b = filp->private_data;
 			filp->private_data = (void *)op;
 			kfree (b);
 		}
-		p = op->value + filp->f_pos - ((op->flag & OPP_QUOTED) ? 1 : 0);
+		p = op->value + pos - ((op->flag & OPP_QUOTED) ? 1 : 0);
 		copy_from_user (p, buf, count);
 		op->flag |= OPP_DIRTY;
 		for (i = 0; i < count; i++, p++)
@@ -486,17 +491,19 @@ write_try_string:
 			}
 		if (i < count) {
 			op->len = p - op->value;
-			filp->f_pos += i + 1;
+			pos += i + 1;
+			*ppos = pos;
 			if ((p > op->value) && (op->flag & OPP_QUOTED)
 			    && (*(p - 1) == '\''))
 				op->len--;
 		} else {
 			if (p - op->value > op->len)
 				op->len = p - op->value;
-			filp->f_pos += count;
+			pos += count;
+			*ppos = pos;
 		}
 	}
-	return filp->f_pos - k;
+	return pos - k;
 }
 
 int property_release (struct inode *inode, struct file *filp)
diff -pruN linux-2.4.27-rc4/fs/proc/base.c linux-2.4.27-rc4.CAN-2004-0415/fs/proc/base.c
--- linux-2.4.27-rc4/fs/proc/base.c	2004-09-07 13:53:02.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/fs/proc/base.c	2004-09-07 13:53:38.000000000 +0900
@@ -337,6 +337,7 @@ static ssize_t proc_info_read(struct fil
 	ssize_t length;
 	ssize_t end;
 	struct task_struct *task = inode->u.proc_i.task;
+	loff_t pos = *ppos;
 
 	if (count > PROC_BLOCK_SIZE)
 		count = PROC_BLOCK_SIZE;
@@ -350,14 +351,14 @@ static ssize_t proc_info_read(struct fil
 		return length;
 	}
 	/* Static 4kB (or whatever) block capacity */
-	if (*ppos >= length) {
+	if (pos < 0 || pos >= length) {
 		free_page(page);
 		return 0;
 	}
-	if (count + *ppos > length)
-		count = length - *ppos;
-	end = count + *ppos;
-	copy_to_user(buf, (char *) page + *ppos, count);
+	if (count > length - pos)
+		count = length - pos;
+	end = count + pos;
+	copy_to_user(buf, (char *) page + pos, count);
 	*ppos = end;
 	free_page(page);
 	return count;
diff -pruN linux-2.4.27-rc4/fs/proc/generic.c linux-2.4.27-rc4.CAN-2004-0415/fs/proc/generic.c
--- linux-2.4.27-rc4/fs/proc/generic.c	2003-11-29 03:26:21.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/fs/proc/generic.c	2004-09-07 13:53:38.000000000 +0900
@@ -56,6 +56,7 @@ proc_file_read(struct file * file, char 
 	ssize_t	n, count;
 	char	*start;
 	struct proc_dir_entry * dp;
+	loff_t pos = *ppos;
 
 	dp = (struct proc_dir_entry *) inode->u.generic_ip;
 	if (!(page = (char*) __get_free_page(GFP_KERNEL)))
@@ -64,6 +65,8 @@ proc_file_read(struct file * file, char 
 	while ((nbytes > 0) && !eof)
 	{
 		count = MIN(PROC_BLOCK_SIZE, nbytes);
+		if ((unsigned)pos > INT_MAX)
+			break;
 
 		start = NULL;
 		if (dp->get_info) {
@@ -71,11 +74,11 @@ proc_file_read(struct file * file, char 
 			 * Handle backwards compatibility with the old net
 			 * routines.
 			 */
-			n = dp->get_info(page, &start, *ppos, count);
+			n = dp->get_info(page, &start, pos, count);
 			if (n < count)
 				eof = 1;
 		} else if (dp->read_proc) {
-			n = dp->read_proc(page, &start, *ppos,
+			n = dp->read_proc(page, &start, pos,
 					  count, &eof, dp->data);
 		} else
 			break;
@@ -84,8 +87,8 @@ proc_file_read(struct file * file, char 
 			/*
 			 * For proc files that are less than 4k
 			 */
-			start = page + *ppos;
-			n -= *ppos;
+			start = page + pos;
+			n -= pos;
 			if (n <= 0)
 				break;
 			if (n > count)
@@ -111,12 +114,13 @@ proc_file_read(struct file * file, char 
 			break;
 		}
 
-		*ppos += start < page ? (long)start : n; /* Move down the file */
+		pos += start < page ? (long)start : n; /* Move down the file */
 		nbytes -= n;
 		buf += n;
 		retval += n;
 	}
 	free_page((unsigned long) page);
+	*ppos = pos;
 	return retval;
 }
 
diff -pruN linux-2.4.27-rc4/fs/proc/kcore.c linux-2.4.27-rc4.CAN-2004-0415/fs/proc/kcore.c
--- linux-2.4.27-rc4/fs/proc/kcore.c	2003-11-29 03:26:21.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/fs/proc/kcore.c	2004-09-07 13:53:38.000000000 +0900
@@ -96,8 +96,9 @@ static ssize_t read_kcore(struct file *f
 		if (copy_to_user(buf, (void *) (PAGE_OFFSET+p-PAGE_SIZE), count))
 			return -EFAULT;
 		read += count;
+		p += count;
 	}
-	*ppos += read;
+	*ppos = p;
 	return read;
 }
 #else /* CONFIG_KCORE_AOUT */
diff -pruN linux-2.4.27-rc4/fs/proc/proc_misc.c linux-2.4.27-rc4.CAN-2004-0415/fs/proc/proc_misc.c
--- linux-2.4.27-rc4/fs/proc/proc_misc.c	2003-11-29 03:26:21.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/fs/proc/proc_misc.c	2004-09-07 13:53:38.000000000 +0900
@@ -500,12 +500,13 @@ static int swaps_read_proc(char *page, c
 static ssize_t read_profile(struct file *file, char *buf,
 			    size_t count, loff_t *ppos)
 {
-	unsigned long p = *ppos;
+	loff_t n = *ppos;
+	unsigned p = n;
 	ssize_t read;
 	char * pnt;
 	unsigned int sample_step = 1 << prof_shift;
 
-	if (p >= (prof_len+1)*sizeof(unsigned int))
+	if (p != n || p >= (prof_len+1)*sizeof(unsigned int))
 		return 0;
 	if (count > (prof_len+1)*sizeof(unsigned int) - p)
 		count = (prof_len+1)*sizeof(unsigned int) - p;
@@ -519,7 +520,7 @@ static ssize_t read_profile(struct file 
 	if (copy_to_user(buf,(void *)pnt,count))
 		return -EFAULT;
 	read += count;
-	*ppos += read;
+	*ppos = n + read;
 	return read;
 }
 
diff -pruN linux-2.4.27-rc4/fs/udf/file.c linux-2.4.27-rc4.CAN-2004-0415/fs/udf/file.c
--- linux-2.4.27-rc4/fs/udf/file.c	2002-08-03 09:39:45.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/fs/udf/file.c	2004-09-07 13:53:38.000000000 +0900
@@ -155,7 +155,8 @@ static ssize_t udf_file_write(struct fil
 {
 	ssize_t retval;
 	struct inode *inode = file->f_dentry->d_inode;
-	int err, pos;
+	int err;
+	loff_t pos;
 
 	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
 	{
@@ -164,8 +165,11 @@ static ssize_t udf_file_write(struct fil
 		else
 			pos = *ppos;
 
-		if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
-			pos + count))
+		if (pos < 0 || pos + count < pos)
+			return 0;
+
+		if (inode->i_sb->s_blocksize - udf_file_entry_alloc_offset(inode) <
+			pos + count)
 		{
 			udf_expand_file_adinicb(inode, pos + count, &err);
 			if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
diff -pruN linux-2.4.27-rc4/mm/shmem.c linux-2.4.27-rc4.CAN-2004-0415/mm/shmem.c
--- linux-2.4.27-rc4/mm/shmem.c	2004-09-07 13:53:02.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/mm/shmem.c	2004-09-07 13:53:38.000000000 +0900
@@ -1051,9 +1051,13 @@ static void do_shmem_file_read(struct fi
 	struct inode *inode = filp->f_dentry->d_inode;
 	struct address_space *mapping = inode->i_mapping;
 	unsigned long index, offset;
+	loff_t pos = *ppos;
 
-	index = *ppos >> PAGE_CACHE_SHIFT;
-	offset = *ppos & ~PAGE_CACHE_MASK;
+	if (unlikely(pos < 0))
+		return;
+
+	index = pos >> PAGE_CACHE_SHIFT;
+	offset = pos & ~PAGE_CACHE_MASK;
 
 	for (;;) {
 		struct page *page = NULL;
diff -pruN linux-2.4.27-rc4/net/8021q/vlanproc.c linux-2.4.27-rc4.CAN-2004-0415/net/8021q/vlanproc.c
--- linux-2.4.27-rc4/net/8021q/vlanproc.c	2003-11-29 03:26:21.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/net/8021q/vlanproc.c	2004-09-07 13:53:38.000000000 +0900
@@ -234,7 +234,9 @@ static ssize_t vlan_proc_read(struct fil
 	struct inode *inode = file->f_dentry->d_inode;
 	struct proc_dir_entry *dent;
 	char *page;
-	int pos, offs, len;
+	int pos, len;
+	loff_t n = *ppos;
+	unsigned offs = n;
 
 	if (count <= 0)
 		return 0;
@@ -251,15 +253,14 @@ static ssize_t vlan_proc_read(struct fil
 		return -ENOBUFS;
 
 	pos = dent->get_info(page, dent->data, 0, 0);
-	offs = file->f_pos;
-	if (offs < pos) {
+	if (offs == n && offs < pos) {
 		len = min_t(int, pos - offs, count);
 		if (copy_to_user(buf, (page + offs), len)) {
 			kfree(page);
 			return -EFAULT;
 		}
 
-		file->f_pos += len;
+		*ppos = offs + len;
 	} else {
 		len = 0;
 	}
diff -pruN linux-2.4.27-rc4/net/atm/br2684.c linux-2.4.27-rc4.CAN-2004-0415/net/atm/br2684.c
--- linux-2.4.27-rc4/net/atm/br2684.c	2004-02-18 22:36:32.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/net/atm/br2684.c	2004-09-07 13:53:46.000000000 +0900
@@ -736,6 +736,8 @@ static ssize_t br2684_proc_read(struct f
 {
 	unsigned long page;
 	int len = 0, x, left;
+	loff_t n = *pos;
+
 	page = get_free_page(GFP_KERNEL);
 	if (!page)
 		return -ENOMEM;
@@ -744,7 +746,7 @@ static ssize_t br2684_proc_read(struct f
 		left = count;
 	read_lock(&devs_lock);
 	for (;;) {
-		x = br2684_proc_engine(*pos, &((char *) page)[len]);
+		x = br2684_proc_engine(n, &((char *) page)[len]);
 		if (x == 0)
 			break;
 		if (x > left)
@@ -759,11 +761,12 @@ static ssize_t br2684_proc_read(struct f
 		}
 		len += x;
 		left -= x;
-		(*pos)++;
+		n++;
 		if (left < 256)
 			break;
 	}
 	read_unlock(&devs_lock);
+	*pos = n;
 	if (len > 0 && copy_to_user(buf, (char *) page, len))
 		len = -EFAULT;
 	free_page(page);
diff -pruN linux-2.4.27-rc4/net/atm/mpoa_proc.c linux-2.4.27-rc4.CAN-2004-0415/net/atm/mpoa_proc.c
--- linux-2.4.27-rc4/net/atm/mpoa_proc.c	2004-04-14 22:05:41.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/net/atm/mpoa_proc.c	2004-09-07 13:53:38.000000000 +0900
@@ -109,6 +109,7 @@ static ssize_t proc_mpc_read(struct file
 	eg_cache_entry *eg_entry;
 	struct timeval now;
 	unsigned char ip_string[16];
+	loff_t n = *pos;
 	if(count == 0)
 	        return 0;
 	page = get_free_page(GFP_KERNEL);
@@ -150,14 +151,14 @@ static ssize_t proc_mpc_read(struct file
 		mpc = mpc->next;
 	}
 
-	if (*pos >= length) length = 0;
+	if (n != (unsigned)n || n >= length) length = 0;
 	else {
-	  if ((count + *pos) > length) count = length - *pos;
+	  if (count > length - n) count = length - n;
 	  if (copy_to_user(buff, (char *)page , count)) {
  		  free_page(page);
 		  return -EFAULT;
           }
-	  *pos += count;
+	  *pos = n + count;
 	}
 
  	free_page(page);
diff -pruN linux-2.4.27-rc4/net/wanrouter/wanproc.c linux-2.4.27-rc4.CAN-2004-0415/net/wanrouter/wanproc.c
--- linux-2.4.27-rc4/net/wanrouter/wanproc.c	2001-09-10 23:58:35.000000000 +0900
+++ linux-2.4.27-rc4.CAN-2004-0415/net/wanrouter/wanproc.c	2004-09-07 13:53:38.000000000 +0900
@@ -243,7 +243,9 @@ typedef struct wan_stat_entry
 		struct inode *inode = file->f_dentry->d_inode;
 		struct proc_dir_entry* dent;
 		char* page;
-		int pos, offs, len;
+		int pos, len;
+		loff_t n = *ppos;
+		unsigned offs = n;
 
 		if (count <= 0)
 			return 0;
@@ -257,14 +259,13 @@ typedef struct wan_stat_entry
 			return -ENOBUFS;
 			
 		pos = dent->get_info(page, dent->data, 0, 0);
-		offs = file->f_pos;
-		if (offs < pos) {
+		if (offs == n && offs < pos) {
 			len = min_t(unsigned int, pos - offs, count);
 			if (copy_to_user(buf, (page + offs), len)) {
 				kfree(page);
 				return -EFAULT;
 			}
-			file->f_pos += len;
+			*ppos = offs + len;
 		}
 		else
 			len = 0;
