~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/nilfs2/file.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php