Support lseek(2) in ashmem driver

Signed-off-by: Bjorn Bringert <bringert@android.com>
Change-Id: I509d18b21832e229737ea7ebaa231fb107eb61d7
diff --git a/mm/ashmem.c b/mm/ashmem.c
index b6c5e2a..f92eb34 100644
--- a/mm/ashmem.c
+++ b/mm/ashmem.c
@@ -178,7 +178,7 @@
 	struct ashmem_area *asma;
 	int ret;
 
-	ret = nonseekable_open(inode, file);
+	ret = generic_file_open(inode, file);
 	if (unlikely(ret))
 		return ret;
 
@@ -230,6 +230,42 @@
 	}
 
 	ret = asma->file->f_op->read(asma->file, buf, len, pos);
+	if (ret < 0) {
+		goto out;
+	}
+
+	/** Update backing file pos, since f_ops->read() doesn't */
+	asma->file->f_pos = *pos;
+
+out:
+	mutex_unlock(&ashmem_mutex);
+	return ret;
+}
+
+static loff_t ashmem_llseek(struct file *file, loff_t offset, int origin)
+{
+	struct ashmem_area *asma = file->private_data;
+	int ret;
+
+	mutex_lock(&ashmem_mutex);
+
+	if (asma->size == 0) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (!asma->file) {
+		ret = -EBADF;
+		goto out;
+	}
+
+	ret = asma->file->f_op->llseek(asma->file, offset, origin);
+	if (ret < 0) {
+		goto out;
+	}
+
+	/** Copy f_pos from backing file, since f_ops->llseek() sets it */
+	file->f_pos = asma->file->f_pos;
 
 out:
 	mutex_unlock(&ashmem_mutex);
@@ -640,6 +676,7 @@
 	.open = ashmem_open,
 	.release = ashmem_release,
         .read = ashmem_read,
+        .llseek = ashmem_llseek,
 	.mmap = ashmem_mmap,
 	.unlocked_ioctl = ashmem_ioctl,
 	.compat_ioctl = ashmem_ioctl,