[PATCH] Don't force O_LARGEFILE for 32 bit processes on ia64
authorYoav Zach <yoav_zach@yahoo.com>
Thu, 23 Jun 2005 07:09:58 +0000 (00:09 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 23 Jun 2005 16:45:28 +0000 (09:45 -0700)
In ia64 kernel, the O_LARGEFILE flag is forced when opening a file.  This
is problematic for execution of 32 bit processes, which are not largefile
aware, either by SW emulation or by HW execution.

For such processes, the problem is two-fold:

1) When trying to open a file that is larger than 4G
   the operation should fail, but it's not
2) Writing to offset larger than 4G should fail, but
   it's not

The proposed patch takes advantage of the way 32 bit processes are
identified in ia64 systems.  Such processes have PER_LINUX32 for their
personality.  With the patch, the ia64 kernel will not enforce the
O_LARGEFILE flag if the current process has PER_LINUX32 set.  The behavior
for all other architectures remains unchanged.

Signed-off-by: Yoav Zach <yoav.zach@intel.com>
Acked-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/open.c
include/asm-ia64/fcntl.h
include/linux/fcntl.h

index 963bd81a44c881a19e95d5d74d00d960c5f78af8..2ebb72c1a876e22d3e164add4092e809cff1ed87 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -21,6 +21,7 @@
 #include <linux/vfs.h>
 #include <asm/uaccess.h>
 #include <linux/fs.h>
+#include <linux/personality.h>
 #include <linux/pagemap.h>
 #include <linux/syscalls.h>
 
@@ -935,9 +936,9 @@ asmlinkage long sys_open(const char __user * filename, int flags, int mode)
        char * tmp;
        int fd, error;
 
-#if BITS_PER_LONG != 32
-       flags |= O_LARGEFILE;
-#endif
+       if (force_o_largefile())
+               flags |= O_LARGEFILE;
+
        tmp = getname(filename);
        fd = PTR_ERR(tmp);
        if (!IS_ERR(tmp)) {
index d193981bb1d819918959cea33667f24bb7a13ef4..c9f8d835d0cc0860345312eff324beebdf7becd4 100644 (file)
@@ -81,4 +81,6 @@ struct flock {
 
 #define F_LINUX_SPECIFIC_BASE  1024
 
+#define force_o_largefile() ( ! (current->personality & PER_LINUX32) )
+
 #endif /* _ASM_IA64_FCNTL_H */
index 704fb76b6334c0bbe475a090cdd73908c0023510..8a7c82151de96388fd53c7f06296783bd247b14d 100644 (file)
 
 #ifdef __KERNEL__
 
+#ifndef force_o_largefile
+#define force_o_largefile() (BITS_PER_LONG != 32)
+#endif
+
 #if BITS_PER_LONG == 32
 #define IS_GETLK32(cmd)                ((cmd) == F_GETLK)
 #define IS_SETLK32(cmd)                ((cmd) == F_SETLK)