Commit 2ad3072d authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[PATCH] Fix page cache limit wrapping in filesystems

Several file systems in tree that nominally support files >2GB set their
s_maxbytes value to ~0ULL. This has the nasty side effect on 32bit machines
that when a file write reaches the page cache limit (e.g. 2^43) it'll silently
wrap and destroy data at the beginning of the file.

This patch changes the file systems in question to fill in a proper limit.

I also have an alternate patch that adds a check for this generically
in super.c, but preliminary comments from Al suggested that he prefered
to do it in the file systems, so it is done this way way.
parent d8fbaf73
...@@ -455,6 +455,8 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent) ...@@ -455,6 +455,8 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent)
server->namelen = maxlen; server->namelen = maxlen;
sb->s_maxbytes = fsinfo.maxfilesize; sb->s_maxbytes = fsinfo.maxfilesize;
if (sb->s_maxbytes > MAX_LFS_FILESIZE)
sb->s_maxbytes = MAX_LFS_FILESIZE;
/* Fire up the writeback cache */ /* Fire up the writeback cache */
if (nfs_reqlist_alloc(server) < 0) { if (nfs_reqlist_alloc(server) < 0) {
......
...@@ -1130,7 +1130,7 @@ struct super_block *ntfs_read_super(struct super_block *sb, void *options, ...@@ -1130,7 +1130,7 @@ struct super_block *ntfs_read_super(struct super_block *sb, void *options,
/* Inform the kernel about which super operations are available. */ /* Inform the kernel about which super operations are available. */
sb->s_op = &ntfs_super_operations; sb->s_op = &ntfs_super_operations;
sb->s_magic = NTFS_SUPER_MAGIC; sb->s_magic = NTFS_SUPER_MAGIC;
sb->s_maxbytes = ~0ULL >> 1; sb->s_maxbytes = MAX_LFS_FILESIZE;
ntfs_debug(DEBUG_OTHER, "Reading special files\n"); ntfs_debug(DEBUG_OTHER, "Reading special files\n");
if (ntfs_load_special_files(vol)) { if (ntfs_load_special_files(vol)) {
ntfs_error("Error loading special files\n"); ntfs_error("Error loading special files\n");
......
...@@ -1544,7 +1544,7 @@ udf_read_super(struct super_block *sb, void *options, int silent) ...@@ -1544,7 +1544,7 @@ udf_read_super(struct super_block *sb, void *options, int silent)
iput(inode); iput(inode);
goto error_out; goto error_out;
} }
sb->s_maxbytes = ~0ULL; sb->s_maxbytes = MAX_LFS_FILESIZE;
return sb; return sb;
error_out: error_out:
......
...@@ -520,6 +520,14 @@ extern int init_private_file(struct file *, struct dentry *, int); ...@@ -520,6 +520,14 @@ extern int init_private_file(struct file *, struct dentry *, int);
#define MAX_NON_LFS ((1UL<<31) - 1) #define MAX_NON_LFS ((1UL<<31) - 1)
/* Page cache limit. The filesystems should put that into their s_maxbytes
limits, otherwise bad things can happen in VM. */
#if BITS_PER_LONG==32
#define MAX_LFS_FILESIZE (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
#elif BITS_PER_LONG==64
#define MAX_LFS_FILESIZE 0x7fffffffffffffff
#endif
#define FL_POSIX 1 #define FL_POSIX 1
#define FL_FLOCK 2 #define FL_FLOCK 2
#define FL_BROKEN 4 /* broken flock() emulation */ #define FL_BROKEN 4 /* broken flock() emulation */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment