[PATCH RFC] proc/pid/mem: implement SEEK_DATA and SEEK_HOLE

2014-05-24 Thread Konstantin Khlebnikov
lseek(fd, addr, SEEK_DATA) adjust file offset to the start address of next VMA,
or to addr if this address is allocated.

lseek(fd, addr, SEEK_HOLE) adjust file offset to the end address of VMA which
addr belongs to, or to addr itself if there is hole.

This way SEEK_HOLE reports a virtual zero-length hole between each contiguous
VMAs. This hack seems completely legit and allows to simplify implementation
(there is no function for finding next hole in VMAs' tree, walking along
 ->vm_next might be expensive) This also gives more information about layout.

Signed-off-by: Konstantin Khlebnikov 

---

I have no practical use for this, just found this interesting.
---
 fs/proc/base.c |   31 +--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 2d696b0..aba4b47 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -769,13 +769,40 @@ static ssize_t mem_write(struct file *file, const char 
__user *buf,
 
 loff_t mem_lseek(struct file *file, loff_t offset, int orig)
 {
+   struct mm_struct *mm = file->private_data;
+   struct vm_area_struct *vma;
+
switch (orig) {
-   case 0:
+   case SEEK_SET:
file->f_pos = offset;
break;
-   case 1:
+   case SEEK_CUR:
file->f_pos += offset;
break;
+   case SEEK_DATA:
+   case SEEK_HOLE:
+   if (!mm || !atomic_inc_not_zero(>mm_users))
+   return -ENXIO;
+   down_read(>mmap_sem);
+   vma = find_vma(mm, offset);
+   if (vma) {
+   if (orig == SEEK_DATA) {
+   if (offset >= vma->vm_start)
+   file->f_pos = offset;
+   else
+   file->f_pos = vma->vm_start;
+   } else {
+   if (offset < vma->vm_start)
+   file->f_pos = offset;
+   else
+   file->f_pos = vma->vm_end;
+   }
+   }
+   up_read(>mmap_sem);
+   mmput(mm);
+   if (!vma)
+   return -ENXIO;
+   break;
default:
return -EINVAL;
}

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RFC] proc/pid/mem: implement SEEK_DATA and SEEK_HOLE

2014-05-24 Thread Konstantin Khlebnikov
lseek(fd, addr, SEEK_DATA) adjust file offset to the start address of next VMA,
or to addr if this address is allocated.

lseek(fd, addr, SEEK_HOLE) adjust file offset to the end address of VMA which
addr belongs to, or to addr itself if there is hole.

This way SEEK_HOLE reports a virtual zero-length hole between each contiguous
VMAs. This hack seems completely legit and allows to simplify implementation
(there is no function for finding next hole in VMAs' tree, walking along
 -vm_next might be expensive) This also gives more information about layout.

Signed-off-by: Konstantin Khlebnikov koc...@gmail.com

---

I have no practical use for this, just found this interesting.
---
 fs/proc/base.c |   31 +--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 2d696b0..aba4b47 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -769,13 +769,40 @@ static ssize_t mem_write(struct file *file, const char 
__user *buf,
 
 loff_t mem_lseek(struct file *file, loff_t offset, int orig)
 {
+   struct mm_struct *mm = file-private_data;
+   struct vm_area_struct *vma;
+
switch (orig) {
-   case 0:
+   case SEEK_SET:
file-f_pos = offset;
break;
-   case 1:
+   case SEEK_CUR:
file-f_pos += offset;
break;
+   case SEEK_DATA:
+   case SEEK_HOLE:
+   if (!mm || !atomic_inc_not_zero(mm-mm_users))
+   return -ENXIO;
+   down_read(mm-mmap_sem);
+   vma = find_vma(mm, offset);
+   if (vma) {
+   if (orig == SEEK_DATA) {
+   if (offset = vma-vm_start)
+   file-f_pos = offset;
+   else
+   file-f_pos = vma-vm_start;
+   } else {
+   if (offset  vma-vm_start)
+   file-f_pos = offset;
+   else
+   file-f_pos = vma-vm_end;
+   }
+   }
+   up_read(mm-mmap_sem);
+   mmput(mm);
+   if (!vma)
+   return -ENXIO;
+   break;
default:
return -EINVAL;
}

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/