1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * file.c - NILFS regular file handling primitives including fsync().
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Written by Amagai Yoshiji and Ryusuke Konishi.
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <linux/fs.h>
11*4882a593Smuzhiyun #include <linux/mm.h>
12*4882a593Smuzhiyun #include <linux/writeback.h>
13*4882a593Smuzhiyun #include "nilfs.h"
14*4882a593Smuzhiyun #include "segment.h"
15*4882a593Smuzhiyun
nilfs_sync_file(struct file * file,loff_t start,loff_t end,int datasync)16*4882a593Smuzhiyun int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
17*4882a593Smuzhiyun {
18*4882a593Smuzhiyun /*
19*4882a593Smuzhiyun * Called from fsync() system call
20*4882a593Smuzhiyun * This is the only entry point that can catch write and synch
21*4882a593Smuzhiyun * timing for both data blocks and intermediate blocks.
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun * This function should be implemented when the writeback function
24*4882a593Smuzhiyun * will be implemented.
25*4882a593Smuzhiyun */
26*4882a593Smuzhiyun struct the_nilfs *nilfs;
27*4882a593Smuzhiyun struct inode *inode = file->f_mapping->host;
28*4882a593Smuzhiyun int err = 0;
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun if (nilfs_inode_dirty(inode)) {
31*4882a593Smuzhiyun if (datasync)
32*4882a593Smuzhiyun err = nilfs_construct_dsync_segment(inode->i_sb, inode,
33*4882a593Smuzhiyun start, end);
34*4882a593Smuzhiyun else
35*4882a593Smuzhiyun err = nilfs_construct_segment(inode->i_sb);
36*4882a593Smuzhiyun }
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun nilfs = inode->i_sb->s_fs_info;
39*4882a593Smuzhiyun if (!err)
40*4882a593Smuzhiyun err = nilfs_flush_device(nilfs);
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun return err;
43*4882a593Smuzhiyun }
44*4882a593Smuzhiyun
nilfs_page_mkwrite(struct vm_fault * vmf)45*4882a593Smuzhiyun static vm_fault_t nilfs_page_mkwrite(struct vm_fault *vmf)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun struct vm_area_struct *vma = vmf->vma;
48*4882a593Smuzhiyun struct page *page = vmf->page;
49*4882a593Smuzhiyun struct inode *inode = file_inode(vma->vm_file);
50*4882a593Smuzhiyun struct nilfs_transaction_info ti;
51*4882a593Smuzhiyun int ret = 0;
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun if (unlikely(nilfs_near_disk_full(inode->i_sb->s_fs_info)))
54*4882a593Smuzhiyun return VM_FAULT_SIGBUS; /* -ENOSPC */
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun sb_start_pagefault(inode->i_sb);
57*4882a593Smuzhiyun lock_page(page);
58*4882a593Smuzhiyun if (page->mapping != inode->i_mapping ||
59*4882a593Smuzhiyun page_offset(page) >= i_size_read(inode) || !PageUptodate(page)) {
60*4882a593Smuzhiyun unlock_page(page);
61*4882a593Smuzhiyun ret = -EFAULT; /* make the VM retry the fault */
62*4882a593Smuzhiyun goto out;
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun /*
66*4882a593Smuzhiyun * check to see if the page is mapped already (no holes)
67*4882a593Smuzhiyun */
68*4882a593Smuzhiyun if (PageMappedToDisk(page))
69*4882a593Smuzhiyun goto mapped;
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun if (page_has_buffers(page)) {
72*4882a593Smuzhiyun struct buffer_head *bh, *head;
73*4882a593Smuzhiyun int fully_mapped = 1;
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun bh = head = page_buffers(page);
76*4882a593Smuzhiyun do {
77*4882a593Smuzhiyun if (!buffer_mapped(bh)) {
78*4882a593Smuzhiyun fully_mapped = 0;
79*4882a593Smuzhiyun break;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun } while (bh = bh->b_this_page, bh != head);
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun if (fully_mapped) {
84*4882a593Smuzhiyun SetPageMappedToDisk(page);
85*4882a593Smuzhiyun goto mapped;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun unlock_page(page);
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun /*
91*4882a593Smuzhiyun * fill hole blocks
92*4882a593Smuzhiyun */
93*4882a593Smuzhiyun ret = nilfs_transaction_begin(inode->i_sb, &ti, 1);
94*4882a593Smuzhiyun /* never returns -ENOMEM, but may return -ENOSPC */
95*4882a593Smuzhiyun if (unlikely(ret))
96*4882a593Smuzhiyun goto out;
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun file_update_time(vma->vm_file);
99*4882a593Smuzhiyun ret = block_page_mkwrite(vma, vmf, nilfs_get_block);
100*4882a593Smuzhiyun if (ret) {
101*4882a593Smuzhiyun nilfs_transaction_abort(inode->i_sb);
102*4882a593Smuzhiyun goto out;
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun nilfs_set_file_dirty(inode, 1 << (PAGE_SHIFT - inode->i_blkbits));
105*4882a593Smuzhiyun nilfs_transaction_commit(inode->i_sb);
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun mapped:
108*4882a593Smuzhiyun wait_for_stable_page(page);
109*4882a593Smuzhiyun out:
110*4882a593Smuzhiyun sb_end_pagefault(inode->i_sb);
111*4882a593Smuzhiyun return block_page_mkwrite_return(ret);
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun static const struct vm_operations_struct nilfs_file_vm_ops = {
115*4882a593Smuzhiyun .fault = filemap_fault,
116*4882a593Smuzhiyun .map_pages = filemap_map_pages,
117*4882a593Smuzhiyun .page_mkwrite = nilfs_page_mkwrite,
118*4882a593Smuzhiyun };
119*4882a593Smuzhiyun
nilfs_file_mmap(struct file * file,struct vm_area_struct * vma)120*4882a593Smuzhiyun static int nilfs_file_mmap(struct file *file, struct vm_area_struct *vma)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun file_accessed(file);
123*4882a593Smuzhiyun vma->vm_ops = &nilfs_file_vm_ops;
124*4882a593Smuzhiyun return 0;
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun /*
128*4882a593Smuzhiyun * We have mostly NULL's here: the current defaults are ok for
129*4882a593Smuzhiyun * the nilfs filesystem.
130*4882a593Smuzhiyun */
131*4882a593Smuzhiyun const struct file_operations nilfs_file_operations = {
132*4882a593Smuzhiyun .llseek = generic_file_llseek,
133*4882a593Smuzhiyun .read_iter = generic_file_read_iter,
134*4882a593Smuzhiyun .write_iter = generic_file_write_iter,
135*4882a593Smuzhiyun .unlocked_ioctl = nilfs_ioctl,
136*4882a593Smuzhiyun #ifdef CONFIG_COMPAT
137*4882a593Smuzhiyun .compat_ioctl = nilfs_compat_ioctl,
138*4882a593Smuzhiyun #endif /* CONFIG_COMPAT */
139*4882a593Smuzhiyun .mmap = nilfs_file_mmap,
140*4882a593Smuzhiyun .open = generic_file_open,
141*4882a593Smuzhiyun /* .release = nilfs_release_file, */
142*4882a593Smuzhiyun .fsync = nilfs_sync_file,
143*4882a593Smuzhiyun .splice_read = generic_file_splice_read,
144*4882a593Smuzhiyun .splice_write = iter_file_splice_write,
145*4882a593Smuzhiyun };
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun const struct inode_operations nilfs_file_inode_operations = {
148*4882a593Smuzhiyun .setattr = nilfs_setattr,
149*4882a593Smuzhiyun .permission = nilfs_permission,
150*4882a593Smuzhiyun .fiemap = nilfs_fiemap,
151*4882a593Smuzhiyun };
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun /* end of file */
154