aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext3/dir.c3
-rw-r--r--fs/ext4/file.c3
-rw-r--r--fs/read_write.c18
-rw-r--r--include/linux/fs.h2
4 files changed, 15 insertions, 11 deletions
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index 92490e9f85ca..901f67e37864 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -303,7 +303,8 @@ loff_t ext3_dir_llseek(struct file *file, loff_t offset, int origin)
303 303
304 if (likely(dx_dir)) 304 if (likely(dx_dir))
305 return generic_file_llseek_size(file, offset, origin, 305 return generic_file_llseek_size(file, offset, origin,
306 ext3_get_htree_eof(file)); 306 ext3_get_htree_eof(file),
307 i_size_read(inode));
307 else 308 else
308 return generic_file_llseek(file, offset, origin); 309 return generic_file_llseek(file, offset, origin);
309} 310}
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 8c7642a00054..f3dadd0a0d51 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -225,7 +225,8 @@ loff_t ext4_llseek(struct file *file, loff_t offset, int origin)
225 else 225 else
226 maxbytes = inode->i_sb->s_maxbytes; 226 maxbytes = inode->i_sb->s_maxbytes;
227 227
228 return generic_file_llseek_size(file, offset, origin, maxbytes); 228 return generic_file_llseek_size(file, offset, origin,
229 maxbytes, i_size_read(inode));
229} 230}
230 231
231const struct file_operations ext4_file_operations = { 232const struct file_operations ext4_file_operations = {
diff --git a/fs/read_write.c b/fs/read_write.c
index c20614f86c01..1adfb691e4f1 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -55,10 +55,11 @@ static loff_t lseek_execute(struct file *file, struct inode *inode,
55 * @file: file structure to seek on 55 * @file: file structure to seek on
56 * @offset: file offset to seek to 56 * @offset: file offset to seek to
57 * @origin: type of seek 57 * @origin: type of seek
58 * @size: max size of file system 58 * @size: max size of this file in file system
59 * @eof: offset used for SEEK_END position
59 * 60 *
60 * This is a variant of generic_file_llseek that allows passing in a custom 61 * This is a variant of generic_file_llseek that allows passing in a custom
61 * file size. 62 * maximum file size and a custom EOF position, for e.g. hashed directories
62 * 63 *
63 * Synchronization: 64 * Synchronization:
64 * SEEK_SET and SEEK_END are unsynchronized (but atomic on 64bit platforms) 65 * SEEK_SET and SEEK_END are unsynchronized (but atomic on 64bit platforms)
@@ -67,13 +68,13 @@ static loff_t lseek_execute(struct file *file, struct inode *inode,
67 */ 68 */
68loff_t 69loff_t
69generic_file_llseek_size(struct file *file, loff_t offset, int origin, 70generic_file_llseek_size(struct file *file, loff_t offset, int origin,
70 loff_t maxsize) 71 loff_t maxsize, loff_t eof)
71{ 72{
72 struct inode *inode = file->f_mapping->host; 73 struct inode *inode = file->f_mapping->host;
73 74
74 switch (origin) { 75 switch (origin) {
75 case SEEK_END: 76 case SEEK_END:
76 offset += i_size_read(inode); 77 offset += eof;
77 break; 78 break;
78 case SEEK_CUR: 79 case SEEK_CUR:
79 /* 80 /*
@@ -99,7 +100,7 @@ generic_file_llseek_size(struct file *file, loff_t offset, int origin,
99 * In the generic case the entire file is data, so as long as 100 * In the generic case the entire file is data, so as long as
100 * offset isn't at the end of the file then the offset is data. 101 * offset isn't at the end of the file then the offset is data.
101 */ 102 */
102 if (offset >= i_size_read(inode)) 103 if (offset >= eof)
103 return -ENXIO; 104 return -ENXIO;
104 break; 105 break;
105 case SEEK_HOLE: 106 case SEEK_HOLE:
@@ -107,9 +108,9 @@ generic_file_llseek_size(struct file *file, loff_t offset, int origin,
107 * There is a virtual hole at the end of the file, so as long as 108 * There is a virtual hole at the end of the file, so as long as
108 * offset isn't i_size or larger, return i_size. 109 * offset isn't i_size or larger, return i_size.
109 */ 110 */
110 if (offset >= i_size_read(inode)) 111 if (offset >= eof)
111 return -ENXIO; 112 return -ENXIO;
112 offset = i_size_read(inode); 113 offset = eof;
113 break; 114 break;
114 } 115 }
115 116
@@ -132,7 +133,8 @@ loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
132 struct inode *inode = file->f_mapping->host; 133 struct inode *inode = file->f_mapping->host;
133 134
134 return generic_file_llseek_size(file, offset, origin, 135 return generic_file_llseek_size(file, offset, origin,
135 inode->i_sb->s_maxbytes); 136 inode->i_sb->s_maxbytes,
137 i_size_read(inode));
136} 138}
137EXPORT_SYMBOL(generic_file_llseek); 139EXPORT_SYMBOL(generic_file_llseek);
138 140
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6a6ca85bee23..34acf51273dd 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2454,7 +2454,7 @@ extern loff_t noop_llseek(struct file *file, loff_t offset, int origin);
2454extern loff_t no_llseek(struct file *file, loff_t offset, int origin); 2454extern loff_t no_llseek(struct file *file, loff_t offset, int origin);
2455extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin); 2455extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin);
2456extern loff_t generic_file_llseek_size(struct file *file, loff_t offset, 2456extern loff_t generic_file_llseek_size(struct file *file, loff_t offset,
2457 int origin, loff_t maxsize); 2457 int origin, loff_t maxsize, loff_t eof);
2458extern int generic_file_open(struct inode * inode, struct file * filp); 2458extern int generic_file_open(struct inode * inode, struct file * filp);
2459extern int nonseekable_open(struct inode * inode, struct file * filp); 2459extern int nonseekable_open(struct inode * inode, struct file * filp);
2460 2460