]> err.no Git - linux-2.6/blobdiff - fs/ocfs2/mmap.c
ocfs2: Force use of GFP_NOFS in ocfs2_write()
[linux-2.6] / fs / ocfs2 / mmap.c
index 843cf9ddefe8aa659b09c23138da2184717074b2..af01158b39f553fd7f04f7970ce0a88d4293953c 100644 (file)
@@ -46,12 +46,12 @@ static struct page *ocfs2_nopage(struct vm_area_struct * area,
                                 unsigned long address,
                                 int *type)
 {
-       struct inode *inode = area->vm_file->f_dentry->d_inode;
        struct page *page = NOPAGE_SIGBUS;
        sigset_t blocked, oldset;
        int ret;
 
-       mlog_entry("(inode %lu, address %lu)\n", inode->i_ino, address);
+       mlog_entry("(area=%p, address=%lu, type=%p)\n", area, address,
+                  type);
 
        /* The best way to deal with signals in this path is
         * to block them upfront, rather than allowing the
@@ -82,16 +82,30 @@ static struct vm_operations_struct ocfs2_file_vm_ops = {
 
 int ocfs2_mmap(struct file *file, struct vm_area_struct *vma)
 {
-       /* We don't want to support shared writable mappings yet. */
-       if (((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE))
-           && ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) {
+       int ret = 0, lock_level = 0;
+       struct ocfs2_super *osb = OCFS2_SB(file->f_dentry->d_inode->i_sb);
+
+       /*
+        * Only support shared writeable mmap for local mounts which
+        * don't know about holes.
+        */
+       if ((!ocfs2_mount_local(osb) || ocfs2_sparse_alloc(osb)) &&
+           ((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE)) &&
+           ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) {
                mlog(0, "disallow shared writable mmaps %lx\n", vma->vm_flags);
                /* This is -EINVAL because generic_file_readonly_mmap
                 * returns it in a similar situation. */
                return -EINVAL;
        }
 
-       file_accessed(file);
+       ret = ocfs2_meta_lock_atime(file->f_dentry->d_inode,
+                                   file->f_vfsmnt, &lock_level);
+       if (ret < 0) {
+               mlog_errno(ret);
+               goto out;
+       }
+       ocfs2_meta_unlock(file->f_dentry->d_inode, lock_level);
+out:
        vma->vm_ops = &ocfs2_file_vm_ops;
        return 0;
 }