diff options
author | Christoph Hellwig <hch@lst.de> | 2017-09-01 11:39:09 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-09-04 19:05:15 -0400 |
commit | 8a2af06415ef0fc922162503dd18da0d9be7771f (patch) | |
tree | 60dceeb288d975df988d33e3eb29fdcfebf80778 | |
parent | cc4a41fe5541a73019a864883297bd5043aa6d98 (diff) |
ashmem: switch to ->read_iter
And use the proper VFS helper for using the backing file.
Also make sure we hold ashmem_lock while updating f_pos to make sure that
it's not racy.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | drivers/staging/android/ashmem.c | 29 |
1 files changed, 8 insertions, 21 deletions
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 6ba270e0494d..0f695df14c9d 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c | |||
@@ -294,19 +294,9 @@ static int ashmem_release(struct inode *ignored, struct file *file) | |||
294 | return 0; | 294 | return 0; |
295 | } | 295 | } |
296 | 296 | ||
297 | /** | 297 | static ssize_t ashmem_read_iter(struct kiocb *iocb, struct iov_iter *iter) |
298 | * ashmem_read() - Reads a set of bytes from an Ashmem-enabled file | ||
299 | * @file: The associated backing file. | ||
300 | * @buf: The buffer of data being written to | ||
301 | * @len: The number of bytes being read | ||
302 | * @pos: The position of the first byte to read. | ||
303 | * | ||
304 | * Return: 0 if successful, or another return code if not. | ||
305 | */ | ||
306 | static ssize_t ashmem_read(struct file *file, char __user *buf, | ||
307 | size_t len, loff_t *pos) | ||
308 | { | 298 | { |
309 | struct ashmem_area *asma = file->private_data; | 299 | struct ashmem_area *asma = iocb->ki_filp->private_data; |
310 | int ret = 0; | 300 | int ret = 0; |
311 | 301 | ||
312 | mutex_lock(&ashmem_mutex); | 302 | mutex_lock(&ashmem_mutex); |
@@ -320,20 +310,17 @@ static ssize_t ashmem_read(struct file *file, char __user *buf, | |||
320 | goto out_unlock; | 310 | goto out_unlock; |
321 | } | 311 | } |
322 | 312 | ||
323 | mutex_unlock(&ashmem_mutex); | ||
324 | |||
325 | /* | 313 | /* |
326 | * asma and asma->file are used outside the lock here. We assume | 314 | * asma and asma->file are used outside the lock here. We assume |
327 | * once asma->file is set it will never be changed, and will not | 315 | * once asma->file is set it will never be changed, and will not |
328 | * be destroyed until all references to the file are dropped and | 316 | * be destroyed until all references to the file are dropped and |
329 | * ashmem_release is called. | 317 | * ashmem_release is called. |
330 | */ | 318 | */ |
331 | ret = __vfs_read(asma->file, buf, len, pos); | 319 | mutex_unlock(&ashmem_mutex); |
332 | if (ret >= 0) | 320 | ret = vfs_iter_read(asma->file, iter, &iocb->ki_pos, 0); |
333 | /** Update backing file pos, since f_ops->read() doesn't */ | 321 | mutex_lock(&ashmem_mutex); |
334 | asma->file->f_pos = *pos; | 322 | if (ret > 0) |
335 | return ret; | 323 | asma->file->f_pos = iocb->ki_pos; |
336 | |||
337 | out_unlock: | 324 | out_unlock: |
338 | mutex_unlock(&ashmem_mutex); | 325 | mutex_unlock(&ashmem_mutex); |
339 | return ret; | 326 | return ret; |
@@ -834,7 +821,7 @@ static const struct file_operations ashmem_fops = { | |||
834 | .owner = THIS_MODULE, | 821 | .owner = THIS_MODULE, |
835 | .open = ashmem_open, | 822 | .open = ashmem_open, |
836 | .release = ashmem_release, | 823 | .release = ashmem_release, |
837 | .read = ashmem_read, | 824 | .read_iter = ashmem_read_iter, |
838 | .llseek = ashmem_llseek, | 825 | .llseek = ashmem_llseek, |
839 | .mmap = ashmem_mmap, | 826 | .mmap = ashmem_mmap, |
840 | .unlocked_ioctl = ashmem_ioctl, | 827 | .unlocked_ioctl = ashmem_ioctl, |