-#define VMA_DEBUG(vma, fmt, arg...) \
- CDEBUG(D_MMAP, "vma(%p) start(%ld) end(%ld) pgoff(%ld) inode(%p): " \
- fmt, vma, vma->vm_start, vma->vm_end, vma->vm_pgoff, \
- vma->vm_file->f_dentry->d_inode, ## arg);
+static void ll_vm_close(struct vm_area_struct *vma)
+{
+ struct inode *inode = vma->vm_file->f_dentry->d_inode;
+ struct ll_inode_info *lli = ll_i2info(inode);
+ ENTRY;
+
+ LASSERT(vma->vm_file);
+
+ spin_lock(&lli->lli_lock);
+ LASSERT(atomic_read(&lli->lli_mmap_cnt) > 0);
+
+ atomic_dec(&lli->lli_mmap_cnt);
+ if (atomic_read(&lli->lli_mmap_cnt) == 0) {
+ struct lov_stripe_md *lsm = lli->lli_smd;
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ int count;
+
+ spin_unlock(&lli->lli_lock);
+
+ if (!lsm)
+ return;
+ count = obd_join_lru(sbi->ll_dt_exp, lsm, 1);
+ VMA_DEBUG(vma, "join %d unused locks to lru\n", count);
+ } else {
+ spin_unlock(&lli->lli_lock);
+ }
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+#ifndef HAVE_FILEMAP_POPULATE
+static int (*filemap_populate)(struct vm_area_struct * area, unsigned long address, unsigned long len, pgprot_t prot, unsigned long pgoff, int nonblock);
+#endif
+static int ll_populate(struct vm_area_struct *area, unsigned long address,
+ unsigned long len, pgprot_t prot, unsigned long pgoff,
+ int nonblock)
+{
+ int rc = 0;
+ ENTRY;
+
+ /* always set nonblock as true to avoid page read ahead */
+ rc = filemap_populate(area, address, len, prot, pgoff, 1);
+ RETURN(rc);
+}
+#endif
+
+/* return the user space pointer that maps to a file offset via a vma */
+static inline unsigned long file_to_user(struct vm_area_struct *vma, __u64 byte)
+{
+ return vma->vm_start + (byte - ((__u64)vma->vm_pgoff << CFS_PAGE_SHIFT));
+
+}