diff options
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 8c88e186a773..870971e20967 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -1917,9 +1917,8 @@ static void shrink_readahead_size_eio(struct file *filp, | |||
1917 | } | 1917 | } |
1918 | 1918 | ||
1919 | /** | 1919 | /** |
1920 | * do_generic_file_read - generic file read routine | 1920 | * generic_file_buffered_read - generic file read routine |
1921 | * @filp: the file to read | 1921 | * @iocb: the iocb to read |
1922 | * @ppos: current file position | ||
1923 | * @iter: data destination | 1922 | * @iter: data destination |
1924 | * @written: already copied | 1923 | * @written: already copied |
1925 | * | 1924 | * |
@@ -1929,12 +1928,14 @@ static void shrink_readahead_size_eio(struct file *filp, | |||
1929 | * This is really ugly. But the goto's actually try to clarify some | 1928 | * This is really ugly. But the goto's actually try to clarify some |
1930 | * of the logic when it comes to error handling etc. | 1929 | * of the logic when it comes to error handling etc. |
1931 | */ | 1930 | */ |
1932 | static ssize_t do_generic_file_read(struct file *filp, loff_t *ppos, | 1931 | static ssize_t generic_file_buffered_read(struct kiocb *iocb, |
1933 | struct iov_iter *iter, ssize_t written) | 1932 | struct iov_iter *iter, ssize_t written) |
1934 | { | 1933 | { |
1934 | struct file *filp = iocb->ki_filp; | ||
1935 | struct address_space *mapping = filp->f_mapping; | 1935 | struct address_space *mapping = filp->f_mapping; |
1936 | struct inode *inode = mapping->host; | 1936 | struct inode *inode = mapping->host; |
1937 | struct file_ra_state *ra = &filp->f_ra; | 1937 | struct file_ra_state *ra = &filp->f_ra; |
1938 | loff_t *ppos = &iocb->ki_pos; | ||
1938 | pgoff_t index; | 1939 | pgoff_t index; |
1939 | pgoff_t last_index; | 1940 | pgoff_t last_index; |
1940 | pgoff_t prev_index; | 1941 | pgoff_t prev_index; |
@@ -1967,6 +1968,8 @@ find_page: | |||
1967 | 1968 | ||
1968 | page = find_get_page(mapping, index); | 1969 | page = find_get_page(mapping, index); |
1969 | if (!page) { | 1970 | if (!page) { |
1971 | if (iocb->ki_flags & IOCB_NOWAIT) | ||
1972 | goto would_block; | ||
1970 | page_cache_sync_readahead(mapping, | 1973 | page_cache_sync_readahead(mapping, |
1971 | ra, filp, | 1974 | ra, filp, |
1972 | index, last_index - index); | 1975 | index, last_index - index); |
@@ -1980,6 +1983,11 @@ find_page: | |||
1980 | index, last_index - index); | 1983 | index, last_index - index); |
1981 | } | 1984 | } |
1982 | if (!PageUptodate(page)) { | 1985 | if (!PageUptodate(page)) { |
1986 | if (iocb->ki_flags & IOCB_NOWAIT) { | ||
1987 | put_page(page); | ||
1988 | goto would_block; | ||
1989 | } | ||
1990 | |||
1983 | /* | 1991 | /* |
1984 | * See comment in do_read_cache_page on why | 1992 | * See comment in do_read_cache_page on why |
1985 | * wait_on_page_locked is used to avoid unnecessarily | 1993 | * wait_on_page_locked is used to avoid unnecessarily |
@@ -2161,6 +2169,8 @@ no_cached_page: | |||
2161 | goto readpage; | 2169 | goto readpage; |
2162 | } | 2170 | } |
2163 | 2171 | ||
2172 | would_block: | ||
2173 | error = -EAGAIN; | ||
2164 | out: | 2174 | out: |
2165 | ra->prev_pos = prev_index; | 2175 | ra->prev_pos = prev_index; |
2166 | ra->prev_pos <<= PAGE_SHIFT; | 2176 | ra->prev_pos <<= PAGE_SHIFT; |
@@ -2182,14 +2192,14 @@ out: | |||
2182 | ssize_t | 2192 | ssize_t |
2183 | generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) | 2193 | generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) |
2184 | { | 2194 | { |
2185 | struct file *file = iocb->ki_filp; | ||
2186 | ssize_t retval = 0; | ||
2187 | size_t count = iov_iter_count(iter); | 2195 | size_t count = iov_iter_count(iter); |
2196 | ssize_t retval = 0; | ||
2188 | 2197 | ||
2189 | if (!count) | 2198 | if (!count) |
2190 | goto out; /* skip atime */ | 2199 | goto out; /* skip atime */ |
2191 | 2200 | ||
2192 | if (iocb->ki_flags & IOCB_DIRECT) { | 2201 | if (iocb->ki_flags & IOCB_DIRECT) { |
2202 | struct file *file = iocb->ki_filp; | ||
2193 | struct address_space *mapping = file->f_mapping; | 2203 | struct address_space *mapping = file->f_mapping; |
2194 | struct inode *inode = mapping->host; | 2204 | struct inode *inode = mapping->host; |
2195 | loff_t size; | 2205 | loff_t size; |
@@ -2230,7 +2240,7 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) | |||
2230 | goto out; | 2240 | goto out; |
2231 | } | 2241 | } |
2232 | 2242 | ||
2233 | retval = do_generic_file_read(file, &iocb->ki_pos, iter, retval); | 2243 | retval = generic_file_buffered_read(iocb, iter, retval); |
2234 | out: | 2244 | out: |
2235 | return retval; | 2245 | return retval; |
2236 | } | 2246 | } |