diff options
Diffstat (limited to 'fs/ext2/file.c')
-rw-r--r-- | fs/ext2/file.c | 76 |
1 files changed, 69 insertions, 7 deletions
diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 5efeefe17abb..423cc01c9d41 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c | |||
@@ -22,11 +22,59 @@ | |||
22 | #include <linux/pagemap.h> | 22 | #include <linux/pagemap.h> |
23 | #include <linux/dax.h> | 23 | #include <linux/dax.h> |
24 | #include <linux/quotaops.h> | 24 | #include <linux/quotaops.h> |
25 | #include <linux/iomap.h> | ||
26 | #include <linux/uio.h> | ||
25 | #include "ext2.h" | 27 | #include "ext2.h" |
26 | #include "xattr.h" | 28 | #include "xattr.h" |
27 | #include "acl.h" | 29 | #include "acl.h" |
28 | 30 | ||
29 | #ifdef CONFIG_FS_DAX | 31 | #ifdef CONFIG_FS_DAX |
32 | static ssize_t ext2_dax_read_iter(struct kiocb *iocb, struct iov_iter *to) | ||
33 | { | ||
34 | struct inode *inode = iocb->ki_filp->f_mapping->host; | ||
35 | ssize_t ret; | ||
36 | |||
37 | if (!iov_iter_count(to)) | ||
38 | return 0; /* skip atime */ | ||
39 | |||
40 | inode_lock_shared(inode); | ||
41 | ret = iomap_dax_rw(iocb, to, &ext2_iomap_ops); | ||
42 | inode_unlock_shared(inode); | ||
43 | |||
44 | file_accessed(iocb->ki_filp); | ||
45 | return ret; | ||
46 | } | ||
47 | |||
48 | static ssize_t ext2_dax_write_iter(struct kiocb *iocb, struct iov_iter *from) | ||
49 | { | ||
50 | struct file *file = iocb->ki_filp; | ||
51 | struct inode *inode = file->f_mapping->host; | ||
52 | ssize_t ret; | ||
53 | |||
54 | inode_lock(inode); | ||
55 | ret = generic_write_checks(iocb, from); | ||
56 | if (ret <= 0) | ||
57 | goto out_unlock; | ||
58 | ret = file_remove_privs(file); | ||
59 | if (ret) | ||
60 | goto out_unlock; | ||
61 | ret = file_update_time(file); | ||
62 | if (ret) | ||
63 | goto out_unlock; | ||
64 | |||
65 | ret = iomap_dax_rw(iocb, from, &ext2_iomap_ops); | ||
66 | if (ret > 0 && iocb->ki_pos > i_size_read(inode)) { | ||
67 | i_size_write(inode, iocb->ki_pos); | ||
68 | mark_inode_dirty(inode); | ||
69 | } | ||
70 | |||
71 | out_unlock: | ||
72 | inode_unlock(inode); | ||
73 | if (ret > 0) | ||
74 | ret = generic_write_sync(iocb, ret); | ||
75 | return ret; | ||
76 | } | ||
77 | |||
30 | /* | 78 | /* |
31 | * The lock ordering for ext2 DAX fault paths is: | 79 | * The lock ordering for ext2 DAX fault paths is: |
32 | * | 80 | * |
@@ -51,7 +99,7 @@ static int ext2_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
51 | } | 99 | } |
52 | down_read(&ei->dax_sem); | 100 | down_read(&ei->dax_sem); |
53 | 101 | ||
54 | ret = dax_fault(vma, vmf, ext2_get_block); | 102 | ret = iomap_dax_fault(vma, vmf, &ext2_iomap_ops); |
55 | 103 | ||
56 | up_read(&ei->dax_sem); | 104 | up_read(&ei->dax_sem); |
57 | if (vmf->flags & FAULT_FLAG_WRITE) | 105 | if (vmf->flags & FAULT_FLAG_WRITE) |
@@ -156,14 +204,28 @@ int ext2_fsync(struct file *file, loff_t start, loff_t end, int datasync) | |||
156 | return ret; | 204 | return ret; |
157 | } | 205 | } |
158 | 206 | ||
159 | /* | 207 | static ssize_t ext2_file_read_iter(struct kiocb *iocb, struct iov_iter *to) |
160 | * We have mostly NULL's here: the current defaults are ok for | 208 | { |
161 | * the ext2 filesystem. | 209 | #ifdef CONFIG_FS_DAX |
162 | */ | 210 | if (IS_DAX(iocb->ki_filp->f_mapping->host)) |
211 | return ext2_dax_read_iter(iocb, to); | ||
212 | #endif | ||
213 | return generic_file_read_iter(iocb, to); | ||
214 | } | ||
215 | |||
216 | static ssize_t ext2_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | ||
217 | { | ||
218 | #ifdef CONFIG_FS_DAX | ||
219 | if (IS_DAX(iocb->ki_filp->f_mapping->host)) | ||
220 | return ext2_dax_write_iter(iocb, from); | ||
221 | #endif | ||
222 | return generic_file_write_iter(iocb, from); | ||
223 | } | ||
224 | |||
163 | const struct file_operations ext2_file_operations = { | 225 | const struct file_operations ext2_file_operations = { |
164 | .llseek = generic_file_llseek, | 226 | .llseek = generic_file_llseek, |
165 | .read_iter = generic_file_read_iter, | 227 | .read_iter = ext2_file_read_iter, |
166 | .write_iter = generic_file_write_iter, | 228 | .write_iter = ext2_file_write_iter, |
167 | .unlocked_ioctl = ext2_ioctl, | 229 | .unlocked_ioctl = ext2_ioctl, |
168 | #ifdef CONFIG_COMPAT | 230 | #ifdef CONFIG_COMPAT |
169 | .compat_ioctl = ext2_compat_ioctl, | 231 | .compat_ioctl = ext2_compat_ioctl, |