aboutsummaryrefslogtreecommitdiffstats
path: root/fs/read_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/read_write.c')
-rw-r--r--fs/read_write.c18
1 files changed, 10 insertions, 8 deletions
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