Blame view

fs/ext4/file.c 17.8 KB
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1
  /*
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2
   *  linux/fs/ext4/file.c
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
3
4
5
6
7
8
9
10
11
12
13
14
   *
   * Copyright (C) 1992, 1993, 1994, 1995
   * Remy Card (card@masi.ibp.fr)
   * Laboratoire MASI - Institut Blaise Pascal
   * Universite Pierre et Marie Curie (Paris VI)
   *
   *  from
   *
   *  linux/fs/minix/file.c
   *
   *  Copyright (C) 1991, 1992  Linus Torvalds
   *
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
15
   *  ext4 fs regular file handling primitives
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
16
17
18
19
20
21
22
   *
   *  64-bit file support on 64-bit platforms by Jakub Jelinek
   *	(jj@sunsite.ms.mff.cuni.cz)
   */
  
  #include <linux/time.h>
  #include <linux/fs.h>
bc0b0d6d6   Theodore Ts'o   ext4: update the ...
23
24
  #include <linux/mount.h>
  #include <linux/path.h>
c94c2acf8   Matthew Wilcox   dax: move DAX-rel...
25
  #include <linux/dax.h>
871a29315   Christoph Hellwig   dquot: cleanup dq...
26
  #include <linux/quotaops.h>
c8c0df241   Zheng Liu   ext4: introduce l...
27
  #include <linux/pagevec.h>
e2e40f2c1   Christoph Hellwig   fs: move struct k...
28
  #include <linux/uio.h>
3dcf54515   Christoph Hellwig   ext4: move header...
29
30
  #include "ext4.h"
  #include "ext4_jbd2.h"
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
31
32
33
34
35
  #include "xattr.h"
  #include "acl.h"
  
  /*
   * Called when an inode is released. Note that this is different
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
36
   * from ext4_file_open: open gets called at every open, but release
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
37
38
   * gets called only when /all/ the files are closed.
   */
af5bc92dd   Theodore Ts'o   ext4: Fix whitesp...
39
  static int ext4_release_file(struct inode *inode, struct file *filp)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
40
  {
19f5fb7ad   Theodore Ts'o   ext4: Use bitops ...
41
  	if (ext4_test_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE)) {
7d8f9f7d1   Theodore Ts'o   ext4: Automatical...
42
  		ext4_alloc_da_blocks(inode);
19f5fb7ad   Theodore Ts'o   ext4: Use bitops ...
43
  		ext4_clear_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE);
7d8f9f7d1   Theodore Ts'o   ext4: Automatical...
44
  	}
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
45
46
  	/* if we are the last writer on the inode, drop the block reservation */
  	if ((filp->f_mode & FMODE_WRITE) &&
d6014301b   Aneesh Kumar K.V   ext4: Fix discard...
47
48
  			(atomic_read(&inode->i_writecount) == 1) &&
  		        !EXT4_I(inode)->i_reserved_data_blocks)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
49
  	{
0e855ac8b   Aneesh Kumar K.V   ext4: Convert tru...
50
  		down_write(&EXT4_I(inode)->i_data_sem);
c2ea3fde6   Theodore Ts'o   ext4: Remove old ...
51
  		ext4_discard_preallocations(inode);
0e855ac8b   Aneesh Kumar K.V   ext4: Convert tru...
52
  		up_write(&EXT4_I(inode)->i_data_sem);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
53
54
  	}
  	if (is_dx(inode) && filp->private_data)
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
55
  		ext4_htree_free_dir_info(filp->private_data);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
56
57
58
  
  	return 0;
  }
c197855ea   Stephen Hemminger   ext4: make local ...
59
  static void ext4_unwritten_wait(struct inode *inode)
e9e3bcecf   Eric Sandeen   ext4: serialize u...
60
61
  {
  	wait_queue_head_t *wq = ext4_ioend_wq(inode);
e27f41e1b   Dmitry Monakhov   ext4: give i_aiod...
62
  	wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_unwritten) == 0));
e9e3bcecf   Eric Sandeen   ext4: serialize u...
63
64
65
66
67
68
69
70
71
72
73
74
  }
  
  /*
   * This tests whether the IO in question is block-aligned or not.
   * Ext4 utilizes unwritten extents when hole-filling during direct IO, and they
   * are converted to written only after the IO is complete.  Until they are
   * mapped, these blocks appear as holes, so dio_zero_block() will assume that
   * it needs to zero out portions of the start and/or end block.  If 2 AIO
   * threads are at work on the same unwritten block, they must be synchronized
   * or one thread will zero the other's data, causing corruption.
   */
  static int
9b884164d   Al Viro   convert ext4 to -...
75
  ext4_unaligned_aio(struct inode *inode, struct iov_iter *from, loff_t pos)
e9e3bcecf   Eric Sandeen   ext4: serialize u...
76
77
78
  {
  	struct super_block *sb = inode->i_sb;
  	int blockmask = sb->s_blocksize - 1;
e9e3bcecf   Eric Sandeen   ext4: serialize u...
79

6e6358fc3   Theodore Ts'o   ext4: use i_size_...
80
  	if (pos >= i_size_read(inode))
e9e3bcecf   Eric Sandeen   ext4: serialize u...
81
  		return 0;
9b884164d   Al Viro   convert ext4 to -...
82
  	if ((pos | iov_iter_alignment(from)) & blockmask)
e9e3bcecf   Eric Sandeen   ext4: serialize u...
83
84
85
86
  		return 1;
  
  	return 0;
  }
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
87
  static ssize_t
9b884164d   Al Viro   convert ext4 to -...
88
  ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
89
  {
8ad2850f4   Theodore Ts'o   ext4: move ext4_f...
90
  	struct inode *inode = file_inode(iocb->ki_filp);
2ba48ce51   Al Viro   mirror O_APPEND a...
91
  	int o_direct = iocb->ki_flags & IOCB_DIRECT;
e142d0526   Jan Kara   ext4: use i_mutex...
92
  	int unaligned_aio = 0;
4bd809dbb   Zheng Liu   ext4: don't take ...
93
  	int overwrite = 0;
8563000d3   Zheng Liu   ext4: use consist...
94
  	ssize_t ret;
7608e6104   Theodore Ts'o   ext4: inline gene...
95

e142d0526   Jan Kara   ext4: use i_mutex...
96
97
98
99
  	inode_lock(inode);
  	ret = generic_write_checks(iocb, from);
  	if (ret <= 0)
  		goto out;
e2b465745   Eric Sandeen   ext4: store maxby...
100
  	/*
e142d0526   Jan Kara   ext4: use i_mutex...
101
102
103
  	 * Unaligned direct AIO must be serialized among each other as zeroing
  	 * of partial blocks of two competing unaligned AIOs can result in data
  	 * corruption.
f5ccfe1dd   Theodore Ts'o   ext4: fix locking...
104
  	 */
e142d0526   Jan Kara   ext4: use i_mutex...
105
  	if (o_direct && ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
f5ccfe1dd   Theodore Ts'o   ext4: fix locking...
106
  	    !is_sync_kiocb(iocb) &&
e142d0526   Jan Kara   ext4: use i_mutex...
107
108
  	    ext4_unaligned_aio(inode, from, iocb->ki_pos)) {
  		unaligned_aio = 1;
f5ccfe1dd   Theodore Ts'o   ext4: fix locking...
109
110
  		ext4_unwritten_wait(inode);
  	}
f5ccfe1dd   Theodore Ts'o   ext4: fix locking...
111
  	/*
e2b465745   Eric Sandeen   ext4: store maxby...
112
113
114
  	 * If we have encountered a bitmap-format file, the size limit
  	 * is smaller than s_maxbytes, which is for extent-mapped files.
  	 */
12e9b8920   Dmitry Monakhov   ext4: Use bitops ...
115
  	if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
e2b465745   Eric Sandeen   ext4: store maxby...
116
  		struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
117

3309dd04c   Al Viro   switch generic_wr...
118
  		if (iocb->ki_pos >= sbi->s_bitmap_maxbytes) {
f5ccfe1dd   Theodore Ts'o   ext4: fix locking...
119
  			ret = -EFBIG;
e768d7ff7   Al Viro   ext4_file_write_i...
120
  			goto out;
f5ccfe1dd   Theodore Ts'o   ext4: fix locking...
121
  		}
3309dd04c   Al Viro   switch generic_wr...
122
  		iov_iter_truncate(from, sbi->s_bitmap_maxbytes - iocb->ki_pos);
e2b465745   Eric Sandeen   ext4: store maxby...
123
  	}
a41537e69   Dmitry Monakhov   ext4: prevent bug...
124
  	iocb->private = &overwrite;
7ed07ba8c   Theodore Ts'o   ext4: factor out ...
125
  	if (o_direct) {
3309dd04c   Al Viro   switch generic_wr...
126
127
  		size_t length = iov_iter_count(from);
  		loff_t pos = iocb->ki_pos;
8ad2850f4   Theodore Ts'o   ext4: move ext4_f...
128

8ad2850f4   Theodore Ts'o   ext4: move ext4_f...
129
  		/* check whether we do a DIO overwrite or not */
e142d0526   Jan Kara   ext4: use i_mutex...
130
  		if (ext4_should_dioread_nolock(inode) && !unaligned_aio &&
4b0524aae   Jan Kara   ext4: allow unloc...
131
  		    pos + length <= i_size_read(inode)) {
8ad2850f4   Theodore Ts'o   ext4: move ext4_f...
132
133
134
135
136
  			struct ext4_map_blocks map;
  			unsigned int blkbits = inode->i_blkbits;
  			int err, len;
  
  			map.m_lblk = pos >> blkbits;
518eaa638   Fabian Frederick   ext4: create EXT4...
137
  			map.m_len = EXT4_MAX_BLOCKS(length, pos, blkbits);
8ad2850f4   Theodore Ts'o   ext4: move ext4_f...
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
  			len = map.m_len;
  
  			err = ext4_map_blocks(NULL, inode, &map, 0);
  			/*
  			 * 'err==len' means that all of blocks has
  			 * been preallocated no matter they are
  			 * initialized or not.  For excluding
  			 * unwritten extents, we need to check
  			 * m_flags.  There are two conditions that
  			 * indicate for initialized extents.  1) If we
  			 * hit extent cache, EXT4_MAP_MAPPED flag is
  			 * returned; 2) If we do a real lookup,
  			 * non-flags are returned.  So we should check
  			 * these two conditions.
  			 */
  			if (err == len && (map.m_flags & EXT4_MAP_MAPPED))
  				overwrite = 1;
  		}
f5ccfe1dd   Theodore Ts'o   ext4: fix locking...
156
  	}
7608e6104   Theodore Ts'o   ext4: inline gene...
157

9b884164d   Al Viro   convert ext4 to -...
158
  	ret = __generic_file_write_iter(iocb, from);
5955102c9   Al Viro   wrappers for ->i_...
159
  	inode_unlock(inode);
7608e6104   Theodore Ts'o   ext4: inline gene...
160

e25922176   Christoph Hellwig   fs: simplify the ...
161
162
  	if (ret > 0)
  		ret = generic_write_sync(iocb, ret);
e9e3bcecf   Eric Sandeen   ext4: serialize u...
163

e768d7ff7   Al Viro   ext4_file_write_i...
164
165
166
  	return ret;
  
  out:
5955102c9   Al Viro   wrappers for ->i_...
167
  	inode_unlock(inode);
e9e3bcecf   Eric Sandeen   ext4: serialize u...
168
  	return ret;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
169
  }
923ae0ff9   Ross Zwisler   ext4: add DAX fun...
170
171
172
  #ifdef CONFIG_FS_DAX
  static int ext4_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
  {
01a33b4ac   Matthew Wilcox   ext4: start trans...
173
174
  	int result;
  	handle_t *handle = NULL;
ea3d7209c   Jan Kara   ext4: fix races b...
175
176
  	struct inode *inode = file_inode(vma->vm_file);
  	struct super_block *sb = inode->i_sb;
01a33b4ac   Matthew Wilcox   ext4: start trans...
177
178
179
180
181
  	bool write = vmf->flags & FAULT_FLAG_WRITE;
  
  	if (write) {
  		sb_start_pagefault(sb);
  		file_update_time(vma->vm_file);
ea3d7209c   Jan Kara   ext4: fix races b...
182
  		down_read(&EXT4_I(inode)->i_mmap_sem);
01a33b4ac   Matthew Wilcox   ext4: start trans...
183
184
  		handle = ext4_journal_start_sb(sb, EXT4_HT_WRITE_PAGE,
  						EXT4_DATA_TRANS_BLOCKS(sb));
ea3d7209c   Jan Kara   ext4: fix races b...
185
186
  	} else
  		down_read(&EXT4_I(inode)->i_mmap_sem);
01a33b4ac   Matthew Wilcox   ext4: start trans...
187
188
189
190
  
  	if (IS_ERR(handle))
  		result = VM_FAULT_SIGBUS;
  	else
6b524995a   Ross Zwisler   dax: remote unuse...
191
  		result = dax_fault(vma, vmf, ext4_dax_get_block);
01a33b4ac   Matthew Wilcox   ext4: start trans...
192
193
194
195
  
  	if (write) {
  		if (!IS_ERR(handle))
  			ext4_journal_stop(handle);
ea3d7209c   Jan Kara   ext4: fix races b...
196
  		up_read(&EXT4_I(inode)->i_mmap_sem);
01a33b4ac   Matthew Wilcox   ext4: start trans...
197
  		sb_end_pagefault(sb);
ea3d7209c   Jan Kara   ext4: fix races b...
198
199
  	} else
  		up_read(&EXT4_I(inode)->i_mmap_sem);
01a33b4ac   Matthew Wilcox   ext4: start trans...
200
201
  
  	return result;
923ae0ff9   Ross Zwisler   ext4: add DAX fun...
202
  }
11bd1a9ec   Matthew Wilcox   ext4: huge page f...
203
204
205
  static int ext4_dax_pmd_fault(struct vm_area_struct *vma, unsigned long addr,
  						pmd_t *pmd, unsigned int flags)
  {
01a33b4ac   Matthew Wilcox   ext4: start trans...
206
207
208
209
210
211
212
213
214
  	int result;
  	handle_t *handle = NULL;
  	struct inode *inode = file_inode(vma->vm_file);
  	struct super_block *sb = inode->i_sb;
  	bool write = flags & FAULT_FLAG_WRITE;
  
  	if (write) {
  		sb_start_pagefault(sb);
  		file_update_time(vma->vm_file);
ea3d7209c   Jan Kara   ext4: fix races b...
215
  		down_read(&EXT4_I(inode)->i_mmap_sem);
01a33b4ac   Matthew Wilcox   ext4: start trans...
216
217
218
  		handle = ext4_journal_start_sb(sb, EXT4_HT_WRITE_PAGE,
  				ext4_chunk_trans_blocks(inode,
  							PMD_SIZE / PAGE_SIZE));
ea3d7209c   Jan Kara   ext4: fix races b...
219
220
  	} else
  		down_read(&EXT4_I(inode)->i_mmap_sem);
01a33b4ac   Matthew Wilcox   ext4: start trans...
221
222
223
224
  
  	if (IS_ERR(handle))
  		result = VM_FAULT_SIGBUS;
  	else
6b524995a   Ross Zwisler   dax: remote unuse...
225
  		result = dax_pmd_fault(vma, addr, pmd, flags,
02fbd1397   Jan Kara   dax: Remove compl...
226
  					 ext4_dax_get_block);
01a33b4ac   Matthew Wilcox   ext4: start trans...
227
228
229
230
  
  	if (write) {
  		if (!IS_ERR(handle))
  			ext4_journal_stop(handle);
ea3d7209c   Jan Kara   ext4: fix races b...
231
  		up_read(&EXT4_I(inode)->i_mmap_sem);
01a33b4ac   Matthew Wilcox   ext4: start trans...
232
  		sb_end_pagefault(sb);
ea3d7209c   Jan Kara   ext4: fix races b...
233
234
  	} else
  		up_read(&EXT4_I(inode)->i_mmap_sem);
01a33b4ac   Matthew Wilcox   ext4: start trans...
235
236
  
  	return result;
11bd1a9ec   Matthew Wilcox   ext4: huge page f...
237
  }
ea3d7209c   Jan Kara   ext4: fix races b...
238
  /*
1e9d180ba   Ross Zwisler   ext2, ext4: fix i...
239
   * Handle write fault for VM_MIXEDMAP mappings. Similarly to ext4_dax_fault()
ea3d7209c   Jan Kara   ext4: fix races b...
240
241
242
243
244
245
246
247
248
249
250
251
   * handler we check for races agaist truncate. Note that since we cycle through
   * i_mmap_sem, we are sure that also any hole punching that began before we
   * were called is finished by now and so if it included part of the file we
   * are working on, our pte will get unmapped and the check for pte_same() in
   * wp_pfn_shared() fails. Thus fault gets retried and things work out as
   * desired.
   */
  static int ext4_dax_pfn_mkwrite(struct vm_area_struct *vma,
  				struct vm_fault *vmf)
  {
  	struct inode *inode = file_inode(vma->vm_file);
  	struct super_block *sb = inode->i_sb;
ea3d7209c   Jan Kara   ext4: fix races b...
252
  	loff_t size;
d5be7a03b   Ross Zwisler   ext4: call dax_pf...
253
  	int ret;
ea3d7209c   Jan Kara   ext4: fix races b...
254
255
256
257
258
259
260
  
  	sb_start_pagefault(sb);
  	file_update_time(vma->vm_file);
  	down_read(&EXT4_I(inode)->i_mmap_sem);
  	size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT;
  	if (vmf->pgoff >= size)
  		ret = VM_FAULT_SIGBUS;
d5be7a03b   Ross Zwisler   ext4: call dax_pf...
261
262
  	else
  		ret = dax_pfn_mkwrite(vma, vmf);
ea3d7209c   Jan Kara   ext4: fix races b...
263
264
265
266
  	up_read(&EXT4_I(inode)->i_mmap_sem);
  	sb_end_pagefault(sb);
  
  	return ret;
923ae0ff9   Ross Zwisler   ext4: add DAX fun...
267
268
269
270
  }
  
  static const struct vm_operations_struct ext4_dax_vm_ops = {
  	.fault		= ext4_dax_fault,
11bd1a9ec   Matthew Wilcox   ext4: huge page f...
271
  	.pmd_fault	= ext4_dax_pmd_fault,
1e9d180ba   Ross Zwisler   ext2, ext4: fix i...
272
  	.page_mkwrite	= ext4_dax_fault,
ea3d7209c   Jan Kara   ext4: fix races b...
273
  	.pfn_mkwrite	= ext4_dax_pfn_mkwrite,
923ae0ff9   Ross Zwisler   ext4: add DAX fun...
274
275
276
277
  };
  #else
  #define ext4_dax_vm_ops	ext4_file_vm_ops
  #endif
f0f37e2f7   Alexey Dobriyan   const: mark struc...
278
  static const struct vm_operations_struct ext4_file_vm_ops = {
ea3d7209c   Jan Kara   ext4: fix races b...
279
  	.fault		= ext4_filemap_fault,
f1820361f   Kirill A. Shutemov   mm: implement ->m...
280
  	.map_pages	= filemap_map_pages,
2e9ee8503   Aneesh Kumar K.V   ext4: Use page_mk...
281
282
283
284
285
  	.page_mkwrite   = ext4_page_mkwrite,
  };
  
  static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
  {
c9c7429c2   Michael Halcrow   ext4 crypto: impl...
286
287
288
  	struct inode *inode = file->f_mapping->host;
  
  	if (ext4_encrypted_inode(inode)) {
a7550b30a   Jaegeuk Kim   ext4 crypto: migr...
289
  		int err = fscrypt_get_encryption_info(inode);
c9c7429c2   Michael Halcrow   ext4 crypto: impl...
290
291
  		if (err)
  			return 0;
a7550b30a   Jaegeuk Kim   ext4 crypto: migr...
292
  		if (!fscrypt_has_encryption_key(inode))
abdd438b2   Theodore Ts'o   ext4 crypto: hand...
293
  			return -ENOKEY;
c9c7429c2   Michael Halcrow   ext4 crypto: impl...
294
  	}
2e9ee8503   Aneesh Kumar K.V   ext4: Use page_mk...
295
  	file_accessed(file);
923ae0ff9   Ross Zwisler   ext4: add DAX fun...
296
297
  	if (IS_DAX(file_inode(file))) {
  		vma->vm_ops = &ext4_dax_vm_ops;
11bd1a9ec   Matthew Wilcox   ext4: huge page f...
298
  		vma->vm_flags |= VM_MIXEDMAP | VM_HUGEPAGE;
923ae0ff9   Ross Zwisler   ext4: add DAX fun...
299
300
301
  	} else {
  		vma->vm_ops = &ext4_file_vm_ops;
  	}
2e9ee8503   Aneesh Kumar K.V   ext4: Use page_mk...
302
303
  	return 0;
  }
bc0b0d6d6   Theodore Ts'o   ext4: update the ...
304
305
306
307
308
  static int ext4_file_open(struct inode * inode, struct file * filp)
  {
  	struct super_block *sb = inode->i_sb;
  	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
  	struct vfsmount *mnt = filp->f_path.mnt;
9dd78d8c9   Miklos Szeredi   ext4: use dget_pa...
309
  	struct dentry *dir;
bc0b0d6d6   Theodore Ts'o   ext4: update the ...
310
311
  	struct path path;
  	char buf[64], *cp;
c9c7429c2   Michael Halcrow   ext4 crypto: impl...
312
  	int ret;
bc0b0d6d6   Theodore Ts'o   ext4: update the ...
313
314
315
316
317
318
319
320
321
322
323
  
  	if (unlikely(!(sbi->s_mount_flags & EXT4_MF_MNTDIR_SAMPLED) &&
  		     !(sb->s_flags & MS_RDONLY))) {
  		sbi->s_mount_flags |= EXT4_MF_MNTDIR_SAMPLED;
  		/*
  		 * Sample where the filesystem has been mounted and
  		 * store it in the superblock for sysadmin convenience
  		 * when trying to sort through large numbers of block
  		 * devices or filesystem images.
  		 */
  		memset(buf, 0, sizeof(buf));
3899167db   Al Viro   Get rid of mnt_mo...
324
325
  		path.mnt = mnt;
  		path.dentry = mnt->mnt_root;
bc0b0d6d6   Theodore Ts'o   ext4: update the ...
326
  		cp = d_path(&path, buf, sizeof(buf));
bc0b0d6d6   Theodore Ts'o   ext4: update the ...
327
  		if (!IS_ERR(cp)) {
044ce47fe   Jan Kara   ext4: convert las...
328
329
  			handle_t *handle;
  			int err;
9924a92a8   Theodore Ts'o   ext4: pass contex...
330
  			handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1);
044ce47fe   Jan Kara   ext4: convert las...
331
332
  			if (IS_ERR(handle))
  				return PTR_ERR(handle);
5d6012553   liang xie   ext4: add missing...
333
  			BUFFER_TRACE(sbi->s_sbh, "get_write_access");
044ce47fe   Jan Kara   ext4: convert las...
334
335
336
337
338
  			err = ext4_journal_get_write_access(handle, sbi->s_sbh);
  			if (err) {
  				ext4_journal_stop(handle);
  				return err;
  			}
cf8039036   Darrick J. Wong   ext4: prevent sta...
339
340
  			strlcpy(sbi->s_es->s_last_mounted, cp,
  				sizeof(sbi->s_es->s_last_mounted));
044ce47fe   Jan Kara   ext4: convert las...
341
342
  			ext4_handle_dirty_super(handle, sb);
  			ext4_journal_stop(handle);
bc0b0d6d6   Theodore Ts'o   ext4: update the ...
343
344
  		}
  	}
abdd438b2   Theodore Ts'o   ext4 crypto: hand...
345
  	if (ext4_encrypted_inode(inode)) {
a7550b30a   Jaegeuk Kim   ext4 crypto: migr...
346
  		ret = fscrypt_get_encryption_info(inode);
abdd438b2   Theodore Ts'o   ext4 crypto: hand...
347
348
  		if (ret)
  			return -EACCES;
a7550b30a   Jaegeuk Kim   ext4 crypto: migr...
349
  		if (!fscrypt_has_encryption_key(inode))
abdd438b2   Theodore Ts'o   ext4 crypto: hand...
350
351
  			return -ENOKEY;
  	}
9dd78d8c9   Miklos Szeredi   ext4: use dget_pa...
352

c0a37d487   Miklos Szeredi   ext4: use file_de...
353
  	dir = dget_parent(file_dentry(filp));
9dd78d8c9   Miklos Szeredi   ext4: use dget_pa...
354
  	if (ext4_encrypted_inode(d_inode(dir)) &&
a7550b30a   Jaegeuk Kim   ext4 crypto: migr...
355
  			!fscrypt_has_permitted_context(d_inode(dir), inode)) {
ff978b09f   Theodore Ts'o   ext4 crypto: move...
356
  		ext4_warning(inode->i_sb,
8d2ae1cbe   Jakub Wilk   ext4: remove trai...
357
  			     "Inconsistent encryption contexts: %lu/%lu",
9dd78d8c9   Miklos Szeredi   ext4: use dget_pa...
358
  			     (unsigned long) d_inode(dir)->i_ino,
ff978b09f   Theodore Ts'o   ext4 crypto: move...
359
  			     (unsigned long) inode->i_ino);
9dd78d8c9   Miklos Szeredi   ext4: use dget_pa...
360
  		dput(dir);
ff978b09f   Theodore Ts'o   ext4 crypto: move...
361
362
  		return -EPERM;
  	}
9dd78d8c9   Miklos Szeredi   ext4: use dget_pa...
363
  	dput(dir);
8aefcd557   Theodore Ts'o   ext4: dynamically...
364
365
366
367
  	/*
  	 * Set up the jbd2_inode if we are opening the inode for
  	 * writing and the journal is present
  	 */
a361293f5   Jan Kara   jbd2: Fix oops in...
368
  	if (filp->f_mode & FMODE_WRITE) {
c9c7429c2   Michael Halcrow   ext4 crypto: impl...
369
  		ret = ext4_inode_attach_jinode(inode);
a361293f5   Jan Kara   jbd2: Fix oops in...
370
371
  		if (ret < 0)
  			return ret;
8aefcd557   Theodore Ts'o   ext4: dynamically...
372
  	}
abdd438b2   Theodore Ts'o   ext4 crypto: hand...
373
  	return dquot_file_open(inode, filp);
bc0b0d6d6   Theodore Ts'o   ext4: update the ...
374
  }
e0d10bfa9   Toshiyuki Okajima   ext4: improve lls...
375
  /*
c8c0df241   Zheng Liu   ext4: introduce l...
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
   * Here we use ext4_map_blocks() to get a block mapping for a extent-based
   * file rather than ext4_ext_walk_space() because we can introduce
   * SEEK_DATA/SEEK_HOLE for block-mapped and extent-mapped file at the same
   * function.  When extent status tree has been fully implemented, it will
   * track all extent status for a file and we can directly use it to
   * retrieve the offset for SEEK_DATA/SEEK_HOLE.
   */
  
  /*
   * When we retrieve the offset for SEEK_DATA/SEEK_HOLE, we would need to
   * lookup page cache to check whether or not there has some data between
   * [startoff, endoff] because, if this range contains an unwritten extent,
   * we determine this extent as a data or a hole according to whether the
   * page cache has data or not.
   */
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
391
392
  static int ext4_find_unwritten_pgoff(struct inode *inode,
  				     int whence,
2d90c160e   Jan Kara   ext4: more effici...
393
  				     ext4_lblk_t end_blk,
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
394
  				     loff_t *offset)
c8c0df241   Zheng Liu   ext4: introduce l...
395
396
  {
  	struct pagevec pvec;
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
397
  	unsigned int blkbits;
c8c0df241   Zheng Liu   ext4: introduce l...
398
399
  	pgoff_t index;
  	pgoff_t end;
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
400
  	loff_t endoff;
c8c0df241   Zheng Liu   ext4: introduce l...
401
402
403
  	loff_t startoff;
  	loff_t lastoff;
  	int found = 0;
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
404
  	blkbits = inode->i_sb->s_blocksize_bits;
c8c0df241   Zheng Liu   ext4: introduce l...
405
406
  	startoff = *offset;
  	lastoff = startoff;
2d90c160e   Jan Kara   ext4: more effici...
407
  	endoff = (loff_t)end_blk << blkbits;
c8c0df241   Zheng Liu   ext4: introduce l...
408

09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
409
410
  	index = startoff >> PAGE_SHIFT;
  	end = endoff >> PAGE_SHIFT;
c8c0df241   Zheng Liu   ext4: introduce l...
411
412
413
414
415
416
417
418
419
420
  
  	pagevec_init(&pvec, 0);
  	do {
  		int i, num;
  		unsigned long nr_pages;
  
  		num = min_t(pgoff_t, end - index, PAGEVEC_SIZE);
  		nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index,
  					  (pgoff_t)num);
  		if (nr_pages == 0) {
965c8e59c   Andrew Morton   lseek: the "whenc...
421
  			if (whence == SEEK_DATA)
c8c0df241   Zheng Liu   ext4: introduce l...
422
  				break;
965c8e59c   Andrew Morton   lseek: the "whenc...
423
  			BUG_ON(whence != SEEK_HOLE);
c8c0df241   Zheng Liu   ext4: introduce l...
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
  			/*
  			 * If this is the first time to go into the loop and
  			 * offset is not beyond the end offset, it will be a
  			 * hole at this offset
  			 */
  			if (lastoff == startoff || lastoff < endoff)
  				found = 1;
  			break;
  		}
  
  		/*
  		 * If this is the first time to go into the loop and
  		 * offset is smaller than the first page offset, it will be a
  		 * hole at this offset.
  		 */
965c8e59c   Andrew Morton   lseek: the "whenc...
439
  		if (lastoff == startoff && whence == SEEK_HOLE &&
c8c0df241   Zheng Liu   ext4: introduce l...
440
441
442
443
444
445
446
447
448
449
450
451
452
  		    lastoff < page_offset(pvec.pages[0])) {
  			found = 1;
  			break;
  		}
  
  		for (i = 0; i < nr_pages; i++) {
  			struct page *page = pvec.pages[i];
  			struct buffer_head *bh, *head;
  
  			/*
  			 * If the current offset is not beyond the end of given
  			 * range, it will be a hole.
  			 */
965c8e59c   Andrew Morton   lseek: the "whenc...
453
  			if (lastoff < endoff && whence == SEEK_HOLE &&
c8c0df241   Zheng Liu   ext4: introduce l...
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
  			    page->index > end) {
  				found = 1;
  				*offset = lastoff;
  				goto out;
  			}
  
  			lock_page(page);
  
  			if (unlikely(page->mapping != inode->i_mapping)) {
  				unlock_page(page);
  				continue;
  			}
  
  			if (!page_has_buffers(page)) {
  				unlock_page(page);
  				continue;
  			}
  
  			if (page_has_buffers(page)) {
  				lastoff = page_offset(page);
  				bh = head = page_buffers(page);
  				do {
  					if (buffer_uptodate(bh) ||
  					    buffer_unwritten(bh)) {
965c8e59c   Andrew Morton   lseek: the "whenc...
478
  						if (whence == SEEK_DATA)
c8c0df241   Zheng Liu   ext4: introduce l...
479
480
  							found = 1;
  					} else {
965c8e59c   Andrew Morton   lseek: the "whenc...
481
  						if (whence == SEEK_HOLE)
c8c0df241   Zheng Liu   ext4: introduce l...
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
  							found = 1;
  					}
  					if (found) {
  						*offset = max_t(loff_t,
  							startoff, lastoff);
  						unlock_page(page);
  						goto out;
  					}
  					lastoff += bh->b_size;
  					bh = bh->b_this_page;
  				} while (bh != head);
  			}
  
  			lastoff = page_offset(page) + PAGE_SIZE;
  			unlock_page(page);
  		}
  
  		/*
  		 * The no. of pages is less than our desired, that would be a
  		 * hole in there.
  		 */
965c8e59c   Andrew Morton   lseek: the "whenc...
503
  		if (nr_pages < num && whence == SEEK_HOLE) {
c8c0df241   Zheng Liu   ext4: introduce l...
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
  			found = 1;
  			*offset = lastoff;
  			break;
  		}
  
  		index = pvec.pages[i - 1]->index + 1;
  		pagevec_release(&pvec);
  	} while (index <= end);
  
  out:
  	pagevec_release(&pvec);
  	return found;
  }
  
  /*
   * ext4_seek_data() retrieves the offset for SEEK_DATA.
   */
  static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize)
  {
  	struct inode *inode = file->f_mapping->host;
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
524
525
526
527
  	struct extent_status es;
  	ext4_lblk_t start, last, end;
  	loff_t dataoff, isize;
  	int blkbits;
2d90c160e   Jan Kara   ext4: more effici...
528
  	int ret;
c8c0df241   Zheng Liu   ext4: introduce l...
529

5955102c9   Al Viro   wrappers for ->i_...
530
  	inode_lock(inode);
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
531
532
533
  
  	isize = i_size_read(inode);
  	if (offset >= isize) {
5955102c9   Al Viro   wrappers for ->i_...
534
  		inode_unlock(inode);
c8c0df241   Zheng Liu   ext4: introduce l...
535
536
  		return -ENXIO;
  	}
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
537
538
539
540
541
542
543
544
  
  	blkbits = inode->i_sb->s_blocksize_bits;
  	start = offset >> blkbits;
  	last = start;
  	end = isize >> blkbits;
  	dataoff = offset;
  
  	do {
2d90c160e   Jan Kara   ext4: more effici...
545
546
547
548
549
550
551
  		ret = ext4_get_next_extent(inode, last, end - last + 1, &es);
  		if (ret <= 0) {
  			/* No extent found -> no data */
  			if (ret == 0)
  				ret = -ENXIO;
  			inode_unlock(inode);
  			return ret;
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
552
  		}
c8c0df241   Zheng Liu   ext4: introduce l...
553

2d90c160e   Jan Kara   ext4: more effici...
554
555
556
557
  		last = es.es_lblk;
  		if (last != start)
  			dataoff = (loff_t)last << blkbits;
  		if (!ext4_es_is_unwritten(&es))
c8c0df241   Zheng Liu   ext4: introduce l...
558
  			break;
c8c0df241   Zheng Liu   ext4: introduce l...
559

ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
560
561
562
563
564
  		/*
  		 * If there is a unwritten extent at this offset,
  		 * it will be as a data or a hole according to page
  		 * cache that has data or not.
  		 */
2d90c160e   Jan Kara   ext4: more effici...
565
566
567
568
  		if (ext4_find_unwritten_pgoff(inode, SEEK_DATA,
  					      es.es_lblk + es.es_len, &dataoff))
  			break;
  		last += es.es_len;
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
569
  		dataoff = (loff_t)last << blkbits;
2d90c160e   Jan Kara   ext4: more effici...
570
  		cond_resched();
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
571
  	} while (last <= end);
c8c0df241   Zheng Liu   ext4: introduce l...
572

5955102c9   Al Viro   wrappers for ->i_...
573
  	inode_unlock(inode);
c8c0df241   Zheng Liu   ext4: introduce l...
574

ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
575
576
577
578
  	if (dataoff > isize)
  		return -ENXIO;
  
  	return vfs_setpos(file, dataoff, maxsize);
c8c0df241   Zheng Liu   ext4: introduce l...
579
580
581
  }
  
  /*
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
582
   * ext4_seek_hole() retrieves the offset for SEEK_HOLE.
c8c0df241   Zheng Liu   ext4: introduce l...
583
584
585
586
   */
  static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize)
  {
  	struct inode *inode = file->f_mapping->host;
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
587
588
589
590
  	struct extent_status es;
  	ext4_lblk_t start, last, end;
  	loff_t holeoff, isize;
  	int blkbits;
2d90c160e   Jan Kara   ext4: more effici...
591
  	int ret;
c8c0df241   Zheng Liu   ext4: introduce l...
592

5955102c9   Al Viro   wrappers for ->i_...
593
  	inode_lock(inode);
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
594
595
596
  
  	isize = i_size_read(inode);
  	if (offset >= isize) {
5955102c9   Al Viro   wrappers for ->i_...
597
  		inode_unlock(inode);
c8c0df241   Zheng Liu   ext4: introduce l...
598
599
  		return -ENXIO;
  	}
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
600
601
602
603
604
  	blkbits = inode->i_sb->s_blocksize_bits;
  	start = offset >> blkbits;
  	last = start;
  	end = isize >> blkbits;
  	holeoff = offset;
c8c0df241   Zheng Liu   ext4: introduce l...
605

ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
606
  	do {
2d90c160e   Jan Kara   ext4: more effici...
607
608
609
610
  		ret = ext4_get_next_extent(inode, last, end - last + 1, &es);
  		if (ret < 0) {
  			inode_unlock(inode);
  			return ret;
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
611
  		}
2d90c160e   Jan Kara   ext4: more effici...
612
613
614
615
616
  		/* Found a hole? */
  		if (ret == 0 || es.es_lblk > last) {
  			if (last != start)
  				holeoff = (loff_t)last << blkbits;
  			break;
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
617
  		}
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
618
619
620
621
622
  		/*
  		 * If there is a unwritten extent at this offset,
  		 * it will be as a data or a hole according to page
  		 * cache that has data or not.
  		 */
2d90c160e   Jan Kara   ext4: more effici...
623
624
625
626
  		if (ext4_es_is_unwritten(&es) &&
  		    ext4_find_unwritten_pgoff(inode, SEEK_HOLE,
  					      last + es.es_len, &holeoff))
  			break;
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
627

2d90c160e   Jan Kara   ext4: more effici...
628
629
630
  		last += es.es_len;
  		holeoff = (loff_t)last << blkbits;
  		cond_resched();
ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
631
  	} while (last <= end);
5955102c9   Al Viro   wrappers for ->i_...
632
  	inode_unlock(inode);
c8c0df241   Zheng Liu   ext4: introduce l...
633

ad7fefb10   Theodore Ts'o   Revert "ext4: fix...
634
635
636
637
  	if (holeoff > isize)
  		holeoff = isize;
  
  	return vfs_setpos(file, holeoff, maxsize);
c8c0df241   Zheng Liu   ext4: introduce l...
638
639
640
  }
  
  /*
ec7268ce2   Eric Sandeen   ext4: use core vf...
641
642
643
   * ext4_llseek() handles both block-mapped and extent-mapped maxbytes values
   * by calling generic_file_llseek_size() with the appropriate maxbytes
   * value for each.
e0d10bfa9   Toshiyuki Okajima   ext4: improve lls...
644
   */
965c8e59c   Andrew Morton   lseek: the "whenc...
645
  loff_t ext4_llseek(struct file *file, loff_t offset, int whence)
e0d10bfa9   Toshiyuki Okajima   ext4: improve lls...
646
647
648
649
650
651
652
653
  {
  	struct inode *inode = file->f_mapping->host;
  	loff_t maxbytes;
  
  	if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
  		maxbytes = EXT4_SB(inode->i_sb)->s_bitmap_maxbytes;
  	else
  		maxbytes = inode->i_sb->s_maxbytes;
e0d10bfa9   Toshiyuki Okajima   ext4: improve lls...
654

965c8e59c   Andrew Morton   lseek: the "whenc...
655
  	switch (whence) {
c8c0df241   Zheng Liu   ext4: introduce l...
656
657
658
  	case SEEK_SET:
  	case SEEK_CUR:
  	case SEEK_END:
965c8e59c   Andrew Morton   lseek: the "whenc...
659
  		return generic_file_llseek_size(file, offset, whence,
c8c0df241   Zheng Liu   ext4: introduce l...
660
661
662
663
664
665
666
667
  						maxbytes, i_size_read(inode));
  	case SEEK_DATA:
  		return ext4_seek_data(file, offset, maxbytes);
  	case SEEK_HOLE:
  		return ext4_seek_hole(file, offset, maxbytes);
  	}
  
  	return -EINVAL;
e0d10bfa9   Toshiyuki Okajima   ext4: improve lls...
668
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
669
  const struct file_operations ext4_file_operations = {
e0d10bfa9   Toshiyuki Okajima   ext4: improve lls...
670
  	.llseek		= ext4_llseek,
aad4f8bb4   Al Viro   switch simple gen...
671
  	.read_iter	= generic_file_read_iter,
9b884164d   Al Viro   convert ext4 to -...
672
  	.write_iter	= ext4_file_write_iter,
5cdd7b2d7   Andi Kleen   Convert ext4 to u...
673
  	.unlocked_ioctl = ext4_ioctl,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
674
  #ifdef CONFIG_COMPAT
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
675
  	.compat_ioctl	= ext4_compat_ioctl,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
676
  #endif
2e9ee8503   Aneesh Kumar K.V   ext4: Use page_mk...
677
  	.mmap		= ext4_file_mmap,
bc0b0d6d6   Theodore Ts'o   ext4: update the ...
678
  	.open		= ext4_file_open,
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
679
680
  	.release	= ext4_release_file,
  	.fsync		= ext4_sync_file,
dbe6ec815   Toshi Kani   ext2/4, xfs: call...
681
  	.get_unmapped_area = thp_get_unmapped_area,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
682
  	.splice_read	= generic_file_splice_read,
8d0207652   Al Viro   ->splice_write() ...
683
  	.splice_write	= iter_file_splice_write,
2fe17c107   Christoph Hellwig   fallocate should ...
684
  	.fallocate	= ext4_fallocate,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
685
  };
754661f14   Arjan van de Ven   [PATCH] mark stru...
686
  const struct inode_operations ext4_file_inode_operations = {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
687
  	.setattr	= ext4_setattr,
3e3398a08   Mingming Cao   ext4: delayed all...
688
  	.getattr	= ext4_getattr,
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
689
  	.listxattr	= ext4_listxattr,
4e34e719e   Christoph Hellwig   fs: take the ACL ...
690
  	.get_acl	= ext4_get_acl,
64e178a71   Christoph Hellwig   ext2/3/4: use gen...
691
  	.set_acl	= ext4_set_acl,
6873fa0de   Eric Sandeen   Hook ext4 to the ...
692
  	.fiemap		= ext4_fiemap,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
693
  };