static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) { struct page *page = vmf->page; struct file *filp = vma->vm_file; struct dentry *dentry = filp->f_path.dentry; unsigned pagelen; int ret = -EINVAL; struct address_space *mapping; dfprintk(PAGECACHE, "NFS: vm_page_mkwrite(%s/%s(%ld), offset %lld)\n", dentry->d_parent->d_name.name, dentry->d_name.name, filp->f_mapping->host->i_ino, (long long)page_offset(page)); lock_page(page); mapping = page->mapping; if (mapping != dentry->d_inode->i_mapping) goto out_unlock; ret = 0; pagelen = nfs_page_length(page); if (pagelen == 0) goto out_unlock; ret = nfs_flush_incompatible(filp, page); if (ret != 0) goto out_unlock; ret = nfs_updatepage(filp, page, 0, pagelen); out_unlock: if (!ret) return VM_FAULT_LOCKED; unlock_page(page); return VM_FAULT_SIGBUS; }
static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) { struct file *filp = vma->vm_file; unsigned pagelen; int ret = -EINVAL; struct address_space *mapping; lock_page(page); mapping = page->mapping; if (mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping) goto out_unlock; ret = 0; pagelen = nfs_page_length(page); if (pagelen == 0) goto out_unlock; ret = nfs_flush_incompatible(filp, page); if (ret != 0) goto out_unlock; ret = nfs_updatepage(filp, page, 0, pagelen); if (ret == 0) ret = pagelen; out_unlock: unlock_page(page); return ret; }
static int nfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) { long status; lock_kernel(); status = nfs_updatepage(file, page, offset, to-offset); unlock_kernel(); return status; }
static int nfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) { long status; loff_t pos = ((loff_t)page->index<<PAGE_CACHE_SHIFT) + to; struct inode *inode = page->mapping->host; kunmap(page); lock_kernel(); status = nfs_updatepage(file, page, offset, to-offset); unlock_kernel(); /* most likely it's already done. CHECKME */ if (pos > inode->i_size) inode->i_size = pos; return status; }
static int nfs_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, struct page *page, void *fsdata) { unsigned offset = pos & (PAGE_CACHE_SIZE - 1); struct nfs_open_context *ctx = nfs_file_open_context(file); int status; dfprintk(PAGECACHE, "NFS: write_end(%pD2(%lu), %u@%lld)\n", file, mapping->host->i_ino, len, (long long) pos); /* * Zero any uninitialised parts of the page, and then mark the page * as up to date if it turns out that we're extending the file. */ if (!PageUptodate(page)) { unsigned pglen = nfs_page_length(page); unsigned end = offset + len; if (pglen == 0) { zero_user_segments(page, 0, offset, end, PAGE_CACHE_SIZE); SetPageUptodate(page); } else if (end >= pglen) { zero_user_segment(page, end, PAGE_CACHE_SIZE); if (offset == 0) SetPageUptodate(page); } else zero_user_segment(page, pglen, PAGE_CACHE_SIZE); } status = nfs_updatepage(file, page, offset, copied); unlock_page(page); page_cache_release(page); if (status < 0) return status; NFS_I(mapping->host)->write_io += copied; if (nfs_ctx_key_to_expire(ctx)) { status = nfs_wb_all(mapping->host); if (status < 0) return status; } return copied; }
static int nfs_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, struct page *page, void *fsdata) { unsigned offset = pos & (PAGE_CACHE_SIZE - 1); int status; lock_kernel(); status = nfs_updatepage(file, page, offset, copied); unlock_kernel(); unlock_page(page); page_cache_release(page); return status < 0 ? status : copied; }
static int nfs_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, struct page *page, void *fsdata) { unsigned offset = pos & (PAGE_CACHE_SIZE - 1); int status; dfprintk(PAGECACHE, "NFS: write_end(%s/%s(%ld), %u@%lld)\n", file->f_path.dentry->d_parent->d_name.name, file->f_path.dentry->d_name.name, mapping->host->i_ino, len, (long long) pos); /* * Zero any uninitialised parts of the page, and then mark the page * as up to date if it turns out that we're extending the file. */ if (!PageUptodate(page)) { unsigned pglen = nfs_page_length(page); unsigned end = offset + len; if (pglen == 0) { zero_user_segments(page, 0, offset, end, PAGE_CACHE_SIZE); SetPageUptodate(page); } else if (end >= pglen) { zero_user_segment(page, end, PAGE_CACHE_SIZE); if (offset == 0) SetPageUptodate(page); } else zero_user_segment(page, pglen, PAGE_CACHE_SIZE); } status = nfs_updatepage(file, page, offset, copied); unlock_page(page); page_cache_release(page); if (status < 0) return status; return copied; }
/* * Notification that a PTE pointing to an NFS page is about to be made * writable, implying that someone is about to modify the page through a * shared-writable mapping */ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) { struct page *page = vmf->page; struct file *filp = vma->vm_file; struct inode *inode = file_inode(filp); unsigned pagelen; int ret = VM_FAULT_NOPAGE; struct address_space *mapping; dfprintk(PAGECACHE, "NFS: vm_page_mkwrite(%pD2(%lu), offset %lld)\n", filp, filp->f_mapping->host->i_ino, (long long)page_offset(page)); /* make sure the cache has finished storing the page */ nfs_fscache_wait_on_page_write(NFS_I(inode), page); wait_on_bit_action(&NFS_I(inode)->flags, NFS_INO_INVALIDATING, nfs_wait_bit_killable, TASK_KILLABLE); lock_page(page); mapping = page_file_mapping(page); if (mapping != inode->i_mapping) goto out_unlock; wait_on_page_writeback(page); pagelen = nfs_page_length(page); if (pagelen == 0) goto out_unlock; ret = VM_FAULT_LOCKED; if (nfs_flush_incompatible(filp, page) == 0 && nfs_updatepage(filp, page, 0, pagelen) == 0) goto out; ret = VM_FAULT_SIGBUS; out_unlock: unlock_page(page); out: return ret; }
/* * Notification that a PTE pointing to an NFS page is about to be made * writable, implying that someone is about to modify the page through a * shared-writable mapping */ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) { struct page *page = vmf->page; struct file *filp = vma->vm_file; struct dentry *dentry = filp->f_path.dentry; unsigned pagelen; int ret = VM_FAULT_NOPAGE; struct address_space *mapping; dfprintk(PAGECACHE, "NFS: vm_page_mkwrite(%s/%s(%ld), offset %lld)\n", dentry->d_parent->d_name.name, dentry->d_name.name, filp->f_mapping->host->i_ino, (long long)page_offset(page)); /* make sure the cache has finished storing the page */ nfs_fscache_wait_on_page_write(NFS_I(dentry->d_inode), page); lock_page(page); mapping = page_file_mapping(page); if (mapping != dentry->d_inode->i_mapping) goto out_unlock; wait_on_page_writeback(page); pagelen = nfs_page_length(page); if (pagelen == 0) goto out_unlock; ret = VM_FAULT_LOCKED; if (nfs_flush_incompatible(filp, page) == 0 && nfs_updatepage(filp, page, 0, pagelen) == 0) goto out; ret = VM_FAULT_SIGBUS; out_unlock: unlock_page(page); out: return ret; }