Blame view

fs/gfs2/file.c 25.5 KB
b3b94faa5   David Teigland   [GFS2] The core o...
1
2
  /*
   * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3a8a9a103   Steven Whitehouse   [GFS2] Update cop...
3
   * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
b3b94faa5   David Teigland   [GFS2] The core o...
4
5
6
   *
   * This copyrighted material is made available to anyone wishing to use,
   * modify, copy, or redistribute it subject to the terms and conditions
e9fc2aa09   Steven Whitehouse   [GFS2] Update cop...
7
   * of the GNU General Public License version 2.
b3b94faa5   David Teigland   [GFS2] The core o...
8
   */
b3b94faa5   David Teigland   [GFS2] The core o...
9
10
11
12
13
14
15
16
  #include <linux/slab.h>
  #include <linux/spinlock.h>
  #include <linux/completion.h>
  #include <linux/buffer_head.h>
  #include <linux/pagemap.h>
  #include <linux/uio.h>
  #include <linux/blkdev.h>
  #include <linux/mm.h>
f58ba8891   Miklos Szeredi   [GFS2] don't call...
17
  #include <linux/mount.h>
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
18
  #include <linux/fs.h>
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
19
  #include <linux/gfs2_ondisk.h>
71b86f562   Steven Whitehouse   [GFS2] Further up...
20
  #include <linux/ext2_fs.h>
2fe17c107   Christoph Hellwig   fallocate should ...
21
22
  #include <linux/falloc.h>
  #include <linux/swap.h>
71b86f562   Steven Whitehouse   [GFS2] Further up...
23
  #include <linux/crc32.h>
33c3de328   Steven Whitehouse   [GFS2] Don't flus...
24
  #include <linux/writeback.h>
b3b94faa5   David Teigland   [GFS2] The core o...
25
  #include <asm/uaccess.h>
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
26
27
  #include <linux/dlm.h>
  #include <linux/dlm_plock.h>
b3b94faa5   David Teigland   [GFS2] The core o...
28
29
  
  #include "gfs2.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
30
  #include "incore.h"
b3b94faa5   David Teigland   [GFS2] The core o...
31
32
33
34
35
  #include "bmap.h"
  #include "dir.h"
  #include "glock.h"
  #include "glops.h"
  #include "inode.h"
b3b94faa5   David Teigland   [GFS2] The core o...
36
37
  #include "log.h"
  #include "meta_io.h"
b3b94faa5   David Teigland   [GFS2] The core o...
38
39
40
  #include "quota.h"
  #include "rgrp.h"
  #include "trans.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
41
  #include "util.h"
b3b94faa5   David Teigland   [GFS2] The core o...
42

b3b94faa5   David Teigland   [GFS2] The core o...
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  /**
   * gfs2_llseek - seek to a location in a file
   * @file: the file
   * @offset: the offset
   * @origin: Where to seek from (SEEK_SET, SEEK_CUR, or SEEK_END)
   *
   * SEEK_END requires the glock for the file because it references the
   * file's size.
   *
   * Returns: The new offset, or errno
   */
  
  static loff_t gfs2_llseek(struct file *file, loff_t offset, int origin)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
57
  	struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
b3b94faa5   David Teigland   [GFS2] The core o...
58
59
  	struct gfs2_holder i_gh;
  	loff_t error;
9453615a1   Steven Whitehouse   GFS2: Fix lseek a...
60
61
62
63
  	switch (origin) {
  	case SEEK_END: /* These reference inode->i_size */
  	case SEEK_DATA:
  	case SEEK_HOLE:
b3b94faa5   David Teigland   [GFS2] The core o...
64
65
66
  		error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY,
  					   &i_gh);
  		if (!error) {
ef3d0fd27   Andi Kleen   vfs: do (nearly) ...
67
  			error = generic_file_llseek(file, offset, origin);
b3b94faa5   David Teigland   [GFS2] The core o...
68
69
  			gfs2_glock_dq_uninit(&i_gh);
  		}
9453615a1   Steven Whitehouse   GFS2: Fix lseek a...
70
71
72
  		break;
  	case SEEK_CUR:
  	case SEEK_SET:
ef3d0fd27   Andi Kleen   vfs: do (nearly) ...
73
  		error = generic_file_llseek(file, offset, origin);
9453615a1   Steven Whitehouse   GFS2: Fix lseek a...
74
75
76
77
  		break;
  	default:
  		error = -EINVAL;
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
78
79
80
  
  	return error;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
81
  /**
f0e522a90   Steven Whitehouse   [GFS2] Remove "NF...
82
   * gfs2_readdir - Read directory entries from a directory
b3b94faa5   David Teigland   [GFS2] The core o...
83
84
85
86
87
88
   * @file: The directory to read from
   * @dirent: Buffer for dirents
   * @filldir: Function used to do the copying
   *
   * Returns: errno
   */
f0e522a90   Steven Whitehouse   [GFS2] Remove "NF...
89
  static int gfs2_readdir(struct file *file, void *dirent, filldir_t filldir)
b3b94faa5   David Teigland   [GFS2] The core o...
90
  {
71b86f562   Steven Whitehouse   [GFS2] Further up...
91
  	struct inode *dir = file->f_mapping->host;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
92
  	struct gfs2_inode *dip = GFS2_I(dir);
b3b94faa5   David Teigland   [GFS2] The core o...
93
  	struct gfs2_holder d_gh;
cd915493f   Steven Whitehouse   [GFS2] Change all...
94
  	u64 offset = file->f_pos;
b3b94faa5   David Teigland   [GFS2] The core o...
95
  	int error;
719ee3446   Steven Whitehouse   GFS2: high time t...
96
97
  	gfs2_holder_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
  	error = gfs2_glock_nq(&d_gh);
b3b94faa5   David Teigland   [GFS2] The core o...
98
99
100
101
  	if (error) {
  		gfs2_holder_uninit(&d_gh);
  		return error;
  	}
dfe4d34b3   Bob Peterson   GFS2: Add readahe...
102
  	error = gfs2_dir_read(dir, &offset, dirent, filldir, &file->f_ra);
b3b94faa5   David Teigland   [GFS2] The core o...
103
104
  
  	gfs2_glock_dq_uninit(&d_gh);
b3b94faa5   David Teigland   [GFS2] The core o...
105
  	file->f_pos = offset;
b3b94faa5   David Teigland   [GFS2] The core o...
106
107
  	return error;
  }
128e5ebaf   Steven Whitehouse   [GFS2] Remove ifl...
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
  /**
   * fsflags_cvt
   * @table: A table of 32 u32 flags
   * @val: a 32 bit value to convert
   *
   * This function can be used to convert between fsflags values and
   * GFS2's own flags values.
   *
   * Returns: the converted flags
   */
  static u32 fsflags_cvt(const u32 *table, u32 val)
  {
  	u32 res = 0;
  	while(val) {
  		if (val & 1)
  			res |= *table;
  		table++;
  		val >>= 1;
  	}
  	return res;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
129

128e5ebaf   Steven Whitehouse   [GFS2] Remove ifl...
130
131
132
133
134
135
  static const u32 fsflags_to_gfs2[32] = {
  	[3] = GFS2_DIF_SYNC,
  	[4] = GFS2_DIF_IMMUTABLE,
  	[5] = GFS2_DIF_APPENDONLY,
  	[7] = GFS2_DIF_NOATIME,
  	[12] = GFS2_DIF_EXHASH,
b9af7ca6d   Steven Whitehouse   [GFS2] Fix settin...
136
  	[14] = GFS2_DIF_INHERIT_JDATA,
71b86f562   Steven Whitehouse   [GFS2] Further up...
137
  };
128e5ebaf   Steven Whitehouse   [GFS2] Remove ifl...
138
139
140
141
142
143
  static const u32 gfs2_to_fsflags[32] = {
  	[gfs2fl_Sync] = FS_SYNC_FL,
  	[gfs2fl_Immutable] = FS_IMMUTABLE_FL,
  	[gfs2fl_AppendOnly] = FS_APPEND_FL,
  	[gfs2fl_NoAtime] = FS_NOATIME_FL,
  	[gfs2fl_ExHash] = FS_INDEX_FL,
128e5ebaf   Steven Whitehouse   [GFS2] Remove ifl...
144
  	[gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL,
7ea9ea832   Steven Whitehouse   [GFS2] Update ioc...
145
  };
71b86f562   Steven Whitehouse   [GFS2] Further up...
146

b09e593d7   Steven Whitehouse   [GFS2] Fix a ref ...
147
  static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
71b86f562   Steven Whitehouse   [GFS2] Further up...
148
  {
81454098f   Josef Sipek   [PATCH] struct pa...
149
  	struct inode *inode = filp->f_path.dentry->d_inode;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
150
  	struct gfs2_inode *ip = GFS2_I(inode);
71b86f562   Steven Whitehouse   [GFS2] Further up...
151
152
  	struct gfs2_holder gh;
  	int error;
128e5ebaf   Steven Whitehouse   [GFS2] Remove ifl...
153
  	u32 fsflags;
71b86f562   Steven Whitehouse   [GFS2] Further up...
154

719ee3446   Steven Whitehouse   GFS2: high time t...
155
156
  	gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
  	error = gfs2_glock_nq(&gh);
71b86f562   Steven Whitehouse   [GFS2] Further up...
157
158
  	if (error)
  		return error;
907b9bceb   Steven Whitehouse   [GFS2/DLM] Fix tr...
159

383f01fbf   Steven Whitehouse   GFS2: Banish stru...
160
161
  	fsflags = fsflags_cvt(gfs2_to_fsflags, ip->i_diskflags);
  	if (!S_ISDIR(inode->i_mode) && ip->i_diskflags & GFS2_DIF_JDATA)
c9f6a6bbc   Steven Whitehouse   [GFS2] Remove sup...
162
  		fsflags |= FS_JOURNAL_DATA_FL;
128e5ebaf   Steven Whitehouse   [GFS2] Remove ifl...
163
  	if (put_user(fsflags, ptr))
71b86f562   Steven Whitehouse   [GFS2] Further up...
164
  		error = -EFAULT;
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
165
  	gfs2_glock_dq(&gh);
71b86f562   Steven Whitehouse   [GFS2] Further up...
166
167
168
  	gfs2_holder_uninit(&gh);
  	return error;
  }
6b124d8db   Steven Whitehouse   [GFS2] Only set i...
169
170
171
  void gfs2_set_inode_flags(struct inode *inode)
  {
  	struct gfs2_inode *ip = GFS2_I(inode);
6b124d8db   Steven Whitehouse   [GFS2] Only set i...
172
  	unsigned int flags = inode->i_flags;
9964afbb7   Steven Whitehouse   GFS2: Add S_NOSEC...
173
174
175
  	flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_NOSEC);
  	if ((ip->i_eattr == 0) && !is_sxid(inode->i_mode))
  		inode->i_flags |= S_NOSEC;
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
176
  	if (ip->i_diskflags & GFS2_DIF_IMMUTABLE)
6b124d8db   Steven Whitehouse   [GFS2] Only set i...
177
  		flags |= S_IMMUTABLE;
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
178
  	if (ip->i_diskflags & GFS2_DIF_APPENDONLY)
6b124d8db   Steven Whitehouse   [GFS2] Only set i...
179
  		flags |= S_APPEND;
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
180
  	if (ip->i_diskflags & GFS2_DIF_NOATIME)
6b124d8db   Steven Whitehouse   [GFS2] Only set i...
181
  		flags |= S_NOATIME;
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
182
  	if (ip->i_diskflags & GFS2_DIF_SYNC)
6b124d8db   Steven Whitehouse   [GFS2] Only set i...
183
184
185
  		flags |= S_SYNC;
  	inode->i_flags = flags;
  }
71b86f562   Steven Whitehouse   [GFS2] Further up...
186
187
  /* Flags that can be set by user space */
  #define GFS2_FLAGS_USER_SET (GFS2_DIF_JDATA|			\
71b86f562   Steven Whitehouse   [GFS2] Further up...
188
189
190
191
192
  			     GFS2_DIF_IMMUTABLE|		\
  			     GFS2_DIF_APPENDONLY|		\
  			     GFS2_DIF_NOATIME|			\
  			     GFS2_DIF_SYNC|			\
  			     GFS2_DIF_SYSTEM|			\
71b86f562   Steven Whitehouse   [GFS2] Further up...
193
194
195
196
197
198
199
200
201
  			     GFS2_DIF_INHERIT_JDATA)
  
  /**
   * gfs2_set_flags - set flags on an inode
   * @inode: The inode
   * @flags: The flags to set
   * @mask: Indicates which flags are valid
   *
   */
b09e593d7   Steven Whitehouse   [GFS2] Fix a ref ...
202
  static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
71b86f562   Steven Whitehouse   [GFS2] Further up...
203
  {
81454098f   Josef Sipek   [PATCH] struct pa...
204
  	struct inode *inode = filp->f_path.dentry->d_inode;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
205
206
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
71b86f562   Steven Whitehouse   [GFS2] Further up...
207
208
209
  	struct buffer_head *bh;
  	struct gfs2_holder gh;
  	int error;
55eccc6d0   Steven Whitehouse   [GFS2] Finish off...
210
  	u32 new_flags, flags;
71b86f562   Steven Whitehouse   [GFS2] Further up...
211

a561be710   Al Viro   switch a bunch of...
212
  	error = mnt_want_write_file(filp);
52f341cf7   Abhijith Das   [GFS2] gfs2_set_f...
213
  	if (error)
71b86f562   Steven Whitehouse   [GFS2] Further up...
214
  		return error;
f58ba8891   Miklos Szeredi   [GFS2] don't call...
215
216
217
  	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
  	if (error)
  		goto out_drop_write;
7df0e0397   Steven Whitehouse   GFS2: Fix permiss...
218
  	error = -EACCES;
2e1496707   Serge E. Hallyn   userns: rename is...
219
  	if (!inode_owner_or_capable(inode))
7df0e0397   Steven Whitehouse   GFS2: Fix permiss...
220
221
222
  		goto out;
  
  	error = 0;
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
223
  	flags = ip->i_diskflags;
55eccc6d0   Steven Whitehouse   [GFS2] Finish off...
224
  	new_flags = (flags & ~mask) | (reqflags & mask);
71b86f562   Steven Whitehouse   [GFS2] Further up...
225
226
227
228
229
230
  	if ((new_flags ^ flags) == 0)
  		goto out;
  
  	error = -EINVAL;
  	if ((new_flags ^ flags) & ~GFS2_FLAGS_USER_SET)
  		goto out;
71b86f562   Steven Whitehouse   [GFS2] Further up...
231
232
233
234
235
  	error = -EPERM;
  	if (IS_IMMUTABLE(inode) && (new_flags & GFS2_DIF_IMMUTABLE))
  		goto out;
  	if (IS_APPEND(inode) && (new_flags & GFS2_DIF_APPENDONLY))
  		goto out;
907b9bceb   Steven Whitehouse   [GFS2/DLM] Fix tr...
236
  	if (((new_flags ^ flags) & GFS2_DIF_IMMUTABLE) &&
b9cb98131   Steven Whitehouse   [GFS2] Fix attrib...
237
  	    !capable(CAP_LINUX_IMMUTABLE))
71b86f562   Steven Whitehouse   [GFS2] Further up...
238
  		goto out;
b9cb98131   Steven Whitehouse   [GFS2] Fix attrib...
239
  	if (!IS_IMMUTABLE(inode)) {
10556cb21   Al Viro   ->permission() sa...
240
  		error = gfs2_permission(inode, MAY_WRITE);
b9cb98131   Steven Whitehouse   [GFS2] Fix attrib...
241
242
243
  		if (error)
  			goto out;
  	}
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
244
245
246
247
248
249
250
251
252
253
  	if ((flags ^ new_flags) & GFS2_DIF_JDATA) {
  		if (flags & GFS2_DIF_JDATA)
  			gfs2_log_flush(sdp, ip->i_gl);
  		error = filemap_fdatawrite(inode->i_mapping);
  		if (error)
  			goto out;
  		error = filemap_fdatawait(inode->i_mapping);
  		if (error)
  			goto out;
  	}
55eccc6d0   Steven Whitehouse   [GFS2] Finish off...
254
  	error = gfs2_trans_begin(sdp, RES_DINODE, 0);
71b86f562   Steven Whitehouse   [GFS2] Further up...
255
256
  	if (error)
  		goto out;
55eccc6d0   Steven Whitehouse   [GFS2] Finish off...
257
258
259
  	error = gfs2_meta_inode_buffer(ip, &bh);
  	if (error)
  		goto out_trans_end;
71b86f562   Steven Whitehouse   [GFS2] Further up...
260
  	gfs2_trans_add_bh(ip->i_gl, bh, 1);
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
261
  	ip->i_diskflags = new_flags;
539e5d6b7   Steven Whitehouse   [GFS2] Change arg...
262
  	gfs2_dinode_out(ip, bh->b_data);
71b86f562   Steven Whitehouse   [GFS2] Further up...
263
  	brelse(bh);
6b124d8db   Steven Whitehouse   [GFS2] Only set i...
264
  	gfs2_set_inode_flags(inode);
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
265
  	gfs2_set_aops(inode);
55eccc6d0   Steven Whitehouse   [GFS2] Finish off...
266
267
  out_trans_end:
  	gfs2_trans_end(sdp);
71b86f562   Steven Whitehouse   [GFS2] Further up...
268
269
  out:
  	gfs2_glock_dq_uninit(&gh);
f58ba8891   Miklos Szeredi   [GFS2] don't call...
270
  out_drop_write:
2a79f17e4   Al Viro   vfs: mnt_drop_wri...
271
  	mnt_drop_write_file(filp);
71b86f562   Steven Whitehouse   [GFS2] Further up...
272
273
  	return error;
  }
b09e593d7   Steven Whitehouse   [GFS2] Fix a ref ...
274
  static int gfs2_set_flags(struct file *filp, u32 __user *ptr)
71b86f562   Steven Whitehouse   [GFS2] Further up...
275
  {
b9af7ca6d   Steven Whitehouse   [GFS2] Fix settin...
276
  	struct inode *inode = filp->f_path.dentry->d_inode;
128e5ebaf   Steven Whitehouse   [GFS2] Remove ifl...
277
  	u32 fsflags, gfsflags;
7df0e0397   Steven Whitehouse   GFS2: Fix permiss...
278

128e5ebaf   Steven Whitehouse   [GFS2] Remove ifl...
279
  	if (get_user(fsflags, ptr))
71b86f562   Steven Whitehouse   [GFS2] Further up...
280
  		return -EFAULT;
7df0e0397   Steven Whitehouse   GFS2: Fix permiss...
281

128e5ebaf   Steven Whitehouse   [GFS2] Remove ifl...
282
  	gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags);
b9af7ca6d   Steven Whitehouse   [GFS2] Fix settin...
283
284
285
  	if (!S_ISDIR(inode->i_mode)) {
  		if (gfsflags & GFS2_DIF_INHERIT_JDATA)
  			gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA);
b9af7ca6d   Steven Whitehouse   [GFS2] Fix settin...
286
287
288
  		return do_gfs2_set_flags(filp, gfsflags, ~0);
  	}
  	return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA);
71b86f562   Steven Whitehouse   [GFS2] Further up...
289
  }
b09e593d7   Steven Whitehouse   [GFS2] Fix a ref ...
290
  static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
71b86f562   Steven Whitehouse   [GFS2] Further up...
291
292
  {
  	switch(cmd) {
128e5ebaf   Steven Whitehouse   [GFS2] Remove ifl...
293
  	case FS_IOC_GETFLAGS:
b09e593d7   Steven Whitehouse   [GFS2] Fix a ref ...
294
  		return gfs2_get_flags(filp, (u32 __user *)arg);
128e5ebaf   Steven Whitehouse   [GFS2] Remove ifl...
295
  	case FS_IOC_SETFLAGS:
b09e593d7   Steven Whitehouse   [GFS2] Fix a ref ...
296
  		return gfs2_set_flags(filp, (u32 __user *)arg);
71b86f562   Steven Whitehouse   [GFS2] Further up...
297
298
299
  	}
  	return -ENOTTY;
  }
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
  /**
   * gfs2_allocate_page_backing - Use bmap to allocate blocks
   * @page: The (locked) page to allocate backing for
   *
   * We try to allocate all the blocks required for the page in
   * one go. This might fail for various reasons, so we keep
   * trying until all the blocks to back this page are allocated.
   * If some of the blocks are already allocated, thats ok too.
   */
  
  static int gfs2_allocate_page_backing(struct page *page)
  {
  	struct inode *inode = page->mapping->host;
  	struct buffer_head bh;
  	unsigned long size = PAGE_CACHE_SIZE;
  	u64 lblock = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
  
  	do {
  		bh.b_state = 0;
  		bh.b_size = size;
e9e1ef2b6   Bob Peterson   [GFS2] Remove fun...
320
  		gfs2_block_map(inode, lblock, &bh, 1);
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
  		if (!buffer_mapped(&bh))
  			return -EIO;
  		size -= bh.b_size;
  		lblock += (bh.b_size >> inode->i_blkbits);
  	} while(size > 0);
  	return 0;
  }
  
  /**
   * gfs2_page_mkwrite - Make a shared, mmap()ed, page writable
   * @vma: The virtual memory area
   * @page: The page which is about to become writable
   *
   * When the page becomes writable, we need to ensure that we have
   * blocks allocated on disk to back that page.
   */
c2ec175c3   Nick Piggin   mm: page_mkwrite ...
337
  static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
338
  {
c2ec175c3   Nick Piggin   mm: page_mkwrite ...
339
  	struct page *page = vmf->page;
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
340
341
342
343
  	struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
  	unsigned long last_index;
c8f554b94   Benjamin Marzinski   GFS2: Fix typo in...
344
  	u64 pos = page->index << PAGE_CACHE_SHIFT;
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
345
  	unsigned int data_blocks, ind_blocks, rblocks;
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
346
  	struct gfs2_holder gh;
564e12b11   Bob Peterson   GFS2: decouple qu...
347
  	struct gfs2_qadata *qa;
13d921e37   Steven Whitehouse   GFS2: Clean up ->...
348
  	loff_t size;
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
349
  	int ret;
13d921e37   Steven Whitehouse   GFS2: Clean up ->...
350
351
352
353
354
  	/* Wait if fs is frozen. This is racy so we check again later on
  	 * and retry if the fs has been frozen after the page lock has
  	 * been acquired
  	 */
  	vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
719ee3446   Steven Whitehouse   GFS2: high time t...
355
356
  	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
  	ret = gfs2_glock_nq(&gh);
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
357
358
  	if (ret)
  		goto out;
9c538837d   Steven Whitehouse   Fix a minor bug i...
359
360
  	set_bit(GLF_DIRTY, &ip->i_gl->gl_flags);
  	set_bit(GIF_SW_PAGED, &ip->i_flags);
13d921e37   Steven Whitehouse   GFS2: Clean up ->...
361
362
363
364
365
366
  	if (!gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE)) {
  		lock_page(page);
  		if (!PageUptodate(page) || page->mapping != inode->i_mapping) {
  			ret = -EAGAIN;
  			unlock_page(page);
  		}
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
367
  		goto out_unlock;
13d921e37   Steven Whitehouse   GFS2: Clean up ->...
368
  	}
6dbd82248   Steven Whitehouse   [GFS2] Reduce ino...
369
  	ret = -ENOMEM;
564e12b11   Bob Peterson   GFS2: decouple qu...
370
371
  	qa = gfs2_qadata_get(ip);
  	if (qa == NULL)
6dbd82248   Steven Whitehouse   [GFS2] Reduce ino...
372
  		goto out_unlock;
d82661d96   Steven Whitehouse   [GFS2] Streamline...
373
  	ret = gfs2_quota_lock_check(ip);
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
374
375
  	if (ret)
  		goto out_alloc_put;
7ed122e42   Steven Whitehouse   GFS2: Streamline ...
376
  	gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks);
564e12b11   Bob Peterson   GFS2: decouple qu...
377
  	ret = gfs2_inplace_reserve(ip, data_blocks + ind_blocks);
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
378
379
380
381
382
383
  	if (ret)
  		goto out_quota_unlock;
  
  	rblocks = RES_DINODE + ind_blocks;
  	if (gfs2_is_jdata(ip))
  		rblocks += data_blocks ? data_blocks : 1;
bf97b6734   Benjamin Marzinski   GFS2: reserve mor...
384
  	if (ind_blocks || data_blocks) {
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
385
  		rblocks += RES_STATFS + RES_QUOTA;
54335b1fc   Steven Whitehouse   GFS2: Cache the m...
386
  		rblocks += gfs2_rg_blocks(ip);
bf97b6734   Benjamin Marzinski   GFS2: reserve mor...
387
  	}
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
388
389
390
391
392
393
  	ret = gfs2_trans_begin(sdp, rblocks, 0);
  	if (ret)
  		goto out_trans_fail;
  
  	lock_page(page);
  	ret = -EINVAL;
13d921e37   Steven Whitehouse   GFS2: Clean up ->...
394
395
396
397
398
399
400
401
402
403
404
405
406
407
  	size = i_size_read(inode);
  	last_index = (size - 1) >> PAGE_CACHE_SHIFT;
  	/* Check page index against inode size */
  	if (size == 0 || (page->index > last_index))
  		goto out_trans_end;
  
  	ret = -EAGAIN;
  	/* If truncated, we must retry the operation, we may have raced
  	 * with the glock demotion code.
  	 */
  	if (!PageUptodate(page) || page->mapping != inode->i_mapping)
  		goto out_trans_end;
  
  	/* Unstuff, if required, and allocate backing blocks for page */
b7fe2e391   Steven Whitehouse   [GFS2] Fix page_m...
408
  	ret = 0;
13d921e37   Steven Whitehouse   GFS2: Clean up ->...
409
  	if (gfs2_is_stuffed(ip))
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
410
  		ret = gfs2_unstuff_dinode(ip, page);
13d921e37   Steven Whitehouse   GFS2: Clean up ->...
411
412
  	if (ret == 0)
  		ret = gfs2_allocate_page_backing(page);
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
413

13d921e37   Steven Whitehouse   GFS2: Clean up ->...
414
415
416
  out_trans_end:
  	if (ret)
  		unlock_page(page);
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
417
418
419
420
421
422
  	gfs2_trans_end(sdp);
  out_trans_fail:
  	gfs2_inplace_release(ip);
  out_quota_unlock:
  	gfs2_quota_unlock(ip);
  out_alloc_put:
564e12b11   Bob Peterson   GFS2: decouple qu...
423
  	gfs2_qadata_put(ip);
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
424
425
426
427
  out_unlock:
  	gfs2_glock_dq(&gh);
  out:
  	gfs2_holder_uninit(&gh);
13d921e37   Steven Whitehouse   GFS2: Clean up ->...
428
429
430
431
432
433
434
435
436
437
438
  	if (ret == 0) {
  		set_page_dirty(page);
  		/* This check must be post dropping of transaction lock */
  		if (inode->i_sb->s_frozen == SB_UNFROZEN) {
  			wait_on_page_writeback(page);
  		} else {
  			ret = -EAGAIN;
  			unlock_page(page);
  		}
  	}
  	return block_page_mkwrite_return(ret);
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
439
  }
f0f37e2f7   Alexey Dobriyan   const: mark struc...
440
  static const struct vm_operations_struct gfs2_vm_ops = {
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
441
442
443
  	.fault = filemap_fault,
  	.page_mkwrite = gfs2_page_mkwrite,
  };
b3b94faa5   David Teigland   [GFS2] The core o...
444
445
446
447
448
  /**
   * gfs2_mmap -
   * @file: The file to map
   * @vma: The VMA which described the mapping
   *
48bf2b171   Steven Whitehouse   GFS2: Something n...
449
450
451
452
453
   * There is no need to get a lock here unless we should be updating
   * atime. We ignore any locking errors since the only consequence is
   * a missed atime update (which will just be deferred until later).
   *
   * Returns: 0
b3b94faa5   David Teigland   [GFS2] The core o...
454
455
456
457
   */
  
  static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
458
  	struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
b3b94faa5   David Teigland   [GFS2] The core o...
459

b9c93bb7d   Steven Whitehouse   GFS2: Improve clu...
460
461
  	if (!(file->f_flags & O_NOATIME) &&
  	    !IS_NOATIME(&ip->i_inode)) {
48bf2b171   Steven Whitehouse   GFS2: Something n...
462
463
  		struct gfs2_holder i_gh;
  		int error;
b3b94faa5   David Teigland   [GFS2] The core o...
464

b9c93bb7d   Steven Whitehouse   GFS2: Improve clu...
465
  		gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
48bf2b171   Steven Whitehouse   GFS2: Something n...
466
  		error = gfs2_glock_nq(&i_gh);
b9c93bb7d   Steven Whitehouse   GFS2: Improve clu...
467
468
469
470
471
472
473
  		if (error == 0) {
  			file_accessed(file);
  			gfs2_glock_dq(&i_gh);
  		}
  		gfs2_holder_uninit(&i_gh);
  		if (error)
  			return error;
48bf2b171   Steven Whitehouse   GFS2: Something n...
474
  	}
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
475
  	vma->vm_ops = &gfs2_vm_ops;
48bf2b171   Steven Whitehouse   GFS2: Something n...
476
  	vma->vm_flags |= VM_CAN_NONLINEAR;
b3b94faa5   David Teigland   [GFS2] The core o...
477

48bf2b171   Steven Whitehouse   GFS2: Something n...
478
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
479
480
481
482
483
484
485
486
487
488
489
490
  }
  
  /**
   * gfs2_open - open a file
   * @inode: the inode to open
   * @file: the struct file for this opening
   *
   * Returns: errno
   */
  
  static int gfs2_open(struct inode *inode, struct file *file)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
491
  	struct gfs2_inode *ip = GFS2_I(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
492
493
494
  	struct gfs2_holder i_gh;
  	struct gfs2_file *fp;
  	int error;
b3b94faa5   David Teigland   [GFS2] The core o...
495
496
497
  	fp = kzalloc(sizeof(struct gfs2_file), GFP_KERNEL);
  	if (!fp)
  		return -ENOMEM;
f55ab26a8   Steven Whitehouse   [GFS2] Use mutice...
498
  	mutex_init(&fp->f_fl_mutex);
b3b94faa5   David Teigland   [GFS2] The core o...
499

feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
500
  	gfs2_assert_warn(GFS2_SB(inode), !file->private_data);
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
501
  	file->private_data = fp;
b3b94faa5   David Teigland   [GFS2] The core o...
502

b60623c23   Steven Whitehouse   [GFS2] Shrink gfs...
503
  	if (S_ISREG(ip->i_inode.i_mode)) {
b3b94faa5   David Teigland   [GFS2] The core o...
504
505
506
507
508
509
  		error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY,
  					   &i_gh);
  		if (error)
  			goto fail;
  
  		if (!(file->f_flags & O_LARGEFILE) &&
a2e0f7993   Steven Whitehouse   GFS2: Remove i_di...
510
  		    i_size_read(inode) > MAX_NON_LFS) {
a9c62a18a   Alan Cox   fs: correct SuS c...
511
  			error = -EOVERFLOW;
b3b94faa5   David Teigland   [GFS2] The core o...
512
513
  			goto fail_gunlock;
  		}
b3b94faa5   David Teigland   [GFS2] The core o...
514
515
516
517
  		gfs2_glock_dq_uninit(&i_gh);
  	}
  
  	return 0;
420b9e5e4   Steven Whitehouse   [GFS2] Tidy up in...
518
  fail_gunlock:
b3b94faa5   David Teigland   [GFS2] The core o...
519
  	gfs2_glock_dq_uninit(&i_gh);
420b9e5e4   Steven Whitehouse   [GFS2] Tidy up in...
520
  fail:
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
521
  	file->private_data = NULL;
b3b94faa5   David Teigland   [GFS2] The core o...
522
  	kfree(fp);
b3b94faa5   David Teigland   [GFS2] The core o...
523
524
525
526
527
528
529
530
531
532
533
534
535
  	return error;
  }
  
  /**
   * gfs2_close - called to close a struct file
   * @inode: the inode the struct file belongs to
   * @file: the struct file being closed
   *
   * Returns: errno
   */
  
  static int gfs2_close(struct inode *inode, struct file *file)
  {
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
536
  	struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
b3b94faa5   David Teigland   [GFS2] The core o...
537
  	struct gfs2_file *fp;
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
538
539
  	fp = file->private_data;
  	file->private_data = NULL;
b3b94faa5   David Teigland   [GFS2] The core o...
540
541
542
543
544
545
546
547
548
549
550
  
  	if (gfs2_assert_warn(sdp, fp))
  		return -EIO;
  
  	kfree(fp);
  
  	return 0;
  }
  
  /**
   * gfs2_fsync - sync the dirty data for a file (across the cluster)
02c24a821   Josef Bacik   fs: push i_mutex ...
551
552
553
   * @file: the file that points to the dentry
   * @start: the start position in the file to sync
   * @end: the end position in the file to sync
dba898b02   Steven Whitehouse   GFS2: Clean up fs...
554
   * @datasync: set if we can ignore timestamp changes
b3b94faa5   David Teigland   [GFS2] The core o...
555
   *
2f0264d59   Steven Whitehouse   GFS2: Split data ...
556
557
558
559
560
561
562
563
564
565
   * We split the data flushing here so that we don't wait for the data
   * until after we've also sent the metadata to disk. Note that for
   * data=ordered, we will write & wait for the data at the log flush
   * stage anyway, so this is unlikely to make much of a difference
   * except in the data=writeback case.
   *
   * If the fdatawrite fails due to any reason except -EIO, we will
   * continue the remainder of the fsync, although we'll still report
   * the error at the end. This is to match filemap_write_and_wait_range()
   * behaviour.
34126f9f4   Steven Whitehouse   [GFS2] Change gfs...
566
   *
b3b94faa5   David Teigland   [GFS2] The core o...
567
568
   * Returns: errno
   */
02c24a821   Josef Bacik   fs: push i_mutex ...
569
570
  static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
  		      int datasync)
b3b94faa5   David Teigland   [GFS2] The core o...
571
  {
2f0264d59   Steven Whitehouse   GFS2: Split data ...
572
573
  	struct address_space *mapping = file->f_mapping;
  	struct inode *inode = mapping->host;
33c3de328   Steven Whitehouse   [GFS2] Don't flus...
574
  	int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC);
dba898b02   Steven Whitehouse   GFS2: Clean up fs...
575
  	struct gfs2_inode *ip = GFS2_I(inode);
87654896c   Steven Whitehouse   GFS2: More automa...
576
  	int ret = 0, ret1 = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
577

2f0264d59   Steven Whitehouse   GFS2: Split data ...
578
579
580
581
582
  	if (mapping->nrpages) {
  		ret1 = filemap_fdatawrite_range(mapping, start, end);
  		if (ret1 == -EIO)
  			return ret1;
  	}
02c24a821   Josef Bacik   fs: push i_mutex ...
583

dba898b02   Steven Whitehouse   GFS2: Clean up fs...
584
585
  	if (datasync)
  		sync_state &= ~I_DIRTY_SYNC;
b3b94faa5   David Teigland   [GFS2] The core o...
586

dba898b02   Steven Whitehouse   GFS2: Clean up fs...
587
588
  	if (sync_state) {
  		ret = sync_inode_metadata(inode, 1);
b5b24d7ae   Steven Whitehouse   GFS2: Fix AIL flu...
589
  		if (ret)
dba898b02   Steven Whitehouse   GFS2: Clean up fs...
590
  			return ret;
f18185291   Steven Whitehouse   GFS2: Fix bug tra...
591
592
  		if (gfs2_is_jdata(ip))
  			filemap_write_and_wait(mapping);
b5b24d7ae   Steven Whitehouse   GFS2: Fix AIL flu...
593
  		gfs2_ail_flush(ip->i_gl, 1);
33c3de328   Steven Whitehouse   [GFS2] Don't flus...
594
  	}
2f0264d59   Steven Whitehouse   GFS2: Split data ...
595
596
597
598
  	if (mapping->nrpages)
  		ret = filemap_fdatawait_range(mapping, start, end);
  
  	return ret ? ret : ret1;
b3b94faa5   David Teigland   [GFS2] The core o...
599
  }
56aa616a0   Steven Whitehouse   GFS2: Ensure upto...
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
  /**
   * gfs2_file_aio_write - Perform a write to a file
   * @iocb: The io context
   * @iov: The data to write
   * @nr_segs: Number of @iov segments
   * @pos: The file position
   *
   * We have to do a lock/unlock here to refresh the inode size for
   * O_APPEND writes, otherwise we can land up writing at the wrong
   * offset. There is still a race, but provided the app is using its
   * own file locking, this will make O_APPEND work as expected.
   *
   */
  
  static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
  				   unsigned long nr_segs, loff_t pos)
  {
  	struct file *file = iocb->ki_filp;
  
  	if (file->f_flags & O_APPEND) {
  		struct dentry *dentry = file->f_dentry;
  		struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
  		struct gfs2_holder gh;
  		int ret;
  
  		ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
  		if (ret)
  			return ret;
  		gfs2_glock_dq_uninit(&gh);
  	}
  
  	return generic_file_aio_write(iocb, iov, nr_segs, pos);
  }
2fe17c107   Christoph Hellwig   fallocate should ...
633
634
635
636
637
638
  static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len,
  			   int mode)
  {
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct buffer_head *dibh;
  	int error;
64dd153c8   Benjamin Marzinski   GFS2: rewrite fal...
639
640
  	unsigned int nr_blks;
  	sector_t lblock = offset >> inode->i_blkbits;
2fe17c107   Christoph Hellwig   fallocate should ...
641
642
643
  
  	error = gfs2_meta_inode_buffer(ip, &dibh);
  	if (unlikely(error))
64dd153c8   Benjamin Marzinski   GFS2: rewrite fal...
644
  		return error;
2fe17c107   Christoph Hellwig   fallocate should ...
645
646
647
648
649
650
651
652
  
  	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
  
  	if (gfs2_is_stuffed(ip)) {
  		error = gfs2_unstuff_dinode(ip, NULL);
  		if (unlikely(error))
  			goto out;
  	}
64dd153c8   Benjamin Marzinski   GFS2: rewrite fal...
653
654
655
656
  	while (len) {
  		struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 };
  		bh_map.b_size = len;
  		set_buffer_zeronew(&bh_map);
2fe17c107   Christoph Hellwig   fallocate should ...
657

64dd153c8   Benjamin Marzinski   GFS2: rewrite fal...
658
659
660
661
662
663
664
665
666
667
  		error = gfs2_block_map(inode, lblock, &bh_map, 1);
  		if (unlikely(error))
  			goto out;
  		len -= bh_map.b_size;
  		nr_blks = bh_map.b_size >> inode->i_blkbits;
  		lblock += nr_blks;
  		if (!buffer_new(&bh_map))
  			continue;
  		if (unlikely(!buffer_zeronew(&bh_map))) {
  			error = -EIO;
2fe17c107   Christoph Hellwig   fallocate should ...
668
  			goto out;
64dd153c8   Benjamin Marzinski   GFS2: rewrite fal...
669
  		}
2fe17c107   Christoph Hellwig   fallocate should ...
670
  	}
64dd153c8   Benjamin Marzinski   GFS2: rewrite fal...
671
672
  	if (offset + len > inode->i_size && !(mode & FALLOC_FL_KEEP_SIZE))
  		i_size_write(inode, offset + len);
2fe17c107   Christoph Hellwig   fallocate should ...
673

2fe17c107   Christoph Hellwig   fallocate should ...
674
  	mark_inode_dirty(inode);
2fe17c107   Christoph Hellwig   fallocate should ...
675
  out:
64dd153c8   Benjamin Marzinski   GFS2: rewrite fal...
676
  	brelse(dibh);
2fe17c107   Christoph Hellwig   fallocate should ...
677
678
679
680
681
682
683
  	return error;
  }
  
  static void calc_max_reserv(struct gfs2_inode *ip, loff_t max, loff_t *len,
  			    unsigned int *data_blocks, unsigned int *ind_blocks)
  {
  	const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
54335b1fc   Steven Whitehouse   GFS2: Cache the m...
684
  	unsigned int max_blocks = ip->i_rgd->rd_free_clone;
2fe17c107   Christoph Hellwig   fallocate should ...
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
  	unsigned int tmp, max_data = max_blocks - 3 * (sdp->sd_max_height - 1);
  
  	for (tmp = max_data; tmp > sdp->sd_diptrs;) {
  		tmp = DIV_ROUND_UP(tmp, sdp->sd_inptrs);
  		max_data -= tmp;
  	}
  	/* This calculation isn't the exact reverse of gfs2_write_calc_reserve,
  	   so it might end up with fewer data blocks */
  	if (max_data <= *data_blocks)
  		return;
  	*data_blocks = max_data;
  	*ind_blocks = max_blocks - max_data;
  	*len = ((loff_t)max_data - 3) << sdp->sd_sb.sb_bsize_shift;
  	if (*len > max) {
  		*len = max;
  		gfs2_write_calc_reserv(ip, max, data_blocks, ind_blocks);
  	}
  }
  
  static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
  			   loff_t len)
  {
  	struct inode *inode = file->f_path.dentry->d_inode;
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
  	struct gfs2_inode *ip = GFS2_I(inode);
  	unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
  	loff_t bytes, max_bytes;
564e12b11   Bob Peterson   GFS2: decouple qu...
712
  	struct gfs2_qadata *qa;
2fe17c107   Christoph Hellwig   fallocate should ...
713
  	int error;
4442f2e03   Steven Whitehouse   GFS2: O_(D)SYNC s...
714
715
  	const loff_t pos = offset;
  	const loff_t count = len;
6905d9e4d   Benjamin Marzinski   GFS2: make sure f...
716
  	loff_t bsize_mask = ~((loff_t)sdp->sd_sb.sb_bsize - 1);
2fe17c107   Christoph Hellwig   fallocate should ...
717
  	loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift;
64dd153c8   Benjamin Marzinski   GFS2: rewrite fal...
718
  	loff_t max_chunk_size = UINT_MAX & bsize_mask;
2fe17c107   Christoph Hellwig   fallocate should ...
719
720
721
722
723
  	next = (next + 1) << sdp->sd_sb.sb_bsize_shift;
  
  	/* We only support the FALLOC_FL_KEEP_SIZE mode */
  	if (mode & ~FALLOC_FL_KEEP_SIZE)
  		return -EOPNOTSUPP;
6905d9e4d   Benjamin Marzinski   GFS2: make sure f...
724
  	offset &= bsize_mask;
2fe17c107   Christoph Hellwig   fallocate should ...
725
726
727
728
729
  
  	len = next - offset;
  	bytes = sdp->sd_max_rg_data * sdp->sd_sb.sb_bsize / 2;
  	if (!bytes)
  		bytes = UINT_MAX;
6905d9e4d   Benjamin Marzinski   GFS2: make sure f...
730
731
732
  	bytes &= bsize_mask;
  	if (bytes == 0)
  		bytes = sdp->sd_sb.sb_bsize;
2fe17c107   Christoph Hellwig   fallocate should ...
733
734
735
736
737
738
739
740
741
742
743
744
  
  	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh);
  	error = gfs2_glock_nq(&ip->i_gh);
  	if (unlikely(error))
  		goto out_uninit;
  
  	if (!gfs2_write_alloc_required(ip, offset, len))
  		goto out_unlock;
  
  	while (len > 0) {
  		if (len < bytes)
  			bytes = len;
564e12b11   Bob Peterson   GFS2: decouple qu...
745
746
  		qa = gfs2_qadata_get(ip);
  		if (!qa) {
2fe17c107   Christoph Hellwig   fallocate should ...
747
748
749
750
751
752
753
754
755
756
  			error = -ENOMEM;
  			goto out_unlock;
  		}
  
  		error = gfs2_quota_lock_check(ip);
  		if (error)
  			goto out_alloc_put;
  
  retry:
  		gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks);
564e12b11   Bob Peterson   GFS2: decouple qu...
757
  		error = gfs2_inplace_reserve(ip, data_blocks + ind_blocks);
2fe17c107   Christoph Hellwig   fallocate should ...
758
759
760
  		if (error) {
  			if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) {
  				bytes >>= 1;
6905d9e4d   Benjamin Marzinski   GFS2: make sure f...
761
762
763
  				bytes &= bsize_mask;
  				if (bytes == 0)
  					bytes = sdp->sd_sb.sb_bsize;
2fe17c107   Christoph Hellwig   fallocate should ...
764
765
766
767
768
  				goto retry;
  			}
  			goto out_qunlock;
  		}
  		max_bytes = bytes;
64dd153c8   Benjamin Marzinski   GFS2: rewrite fal...
769
770
  		calc_max_reserv(ip, (len > max_chunk_size)? max_chunk_size: len,
  				&max_bytes, &data_blocks, &ind_blocks);
2fe17c107   Christoph Hellwig   fallocate should ...
771
772
  
  		rblocks = RES_DINODE + ind_blocks + RES_STATFS + RES_QUOTA +
54335b1fc   Steven Whitehouse   GFS2: Cache the m...
773
  			  RES_RG_HDR + gfs2_rg_blocks(ip);
2fe17c107   Christoph Hellwig   fallocate should ...
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
  		if (gfs2_is_jdata(ip))
  			rblocks += data_blocks ? data_blocks : 1;
  
  		error = gfs2_trans_begin(sdp, rblocks,
  					 PAGE_CACHE_SIZE/sdp->sd_sb.sb_bsize);
  		if (error)
  			goto out_trans_fail;
  
  		error = fallocate_chunk(inode, offset, max_bytes, mode);
  		gfs2_trans_end(sdp);
  
  		if (error)
  			goto out_trans_fail;
  
  		len -= max_bytes;
  		offset += max_bytes;
  		gfs2_inplace_release(ip);
  		gfs2_quota_unlock(ip);
564e12b11   Bob Peterson   GFS2: decouple qu...
792
  		gfs2_qadata_put(ip);
2fe17c107   Christoph Hellwig   fallocate should ...
793
  	}
4442f2e03   Steven Whitehouse   GFS2: O_(D)SYNC s...
794
795
796
  
  	if (error == 0)
  		error = generic_write_sync(file, pos, count);
2fe17c107   Christoph Hellwig   fallocate should ...
797
798
799
800
801
802
803
  	goto out_unlock;
  
  out_trans_fail:
  	gfs2_inplace_release(ip);
  out_qunlock:
  	gfs2_quota_unlock(ip);
  out_alloc_put:
564e12b11   Bob Peterson   GFS2: decouple qu...
804
  	gfs2_qadata_put(ip);
2fe17c107   Christoph Hellwig   fallocate should ...
805
806
807
808
809
810
  out_unlock:
  	gfs2_glock_dq(&ip->i_gh);
  out_uninit:
  	gfs2_holder_uninit(&ip->i_gh);
  	return error;
  }
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
811
  #ifdef CONFIG_GFS2_FS_LOCKING_DLM
b3b94faa5   David Teigland   [GFS2] The core o...
812
  /**
60446067b   Marc Eshel   gfs2: stop giving...
813
814
815
816
817
   * gfs2_setlease - acquire/release a file lease
   * @file: the file pointer
   * @arg: lease type
   * @fl: file lock
   *
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
818
819
820
821
   * We don't currently have a way to enforce a lease across the whole
   * cluster; until we do, disable leases (by just returning -EINVAL),
   * unless the administrator has requested purely local locking.
   *
b89f43213   Arnd Bergmann   fs/locks.c: prepa...
822
823
   * Locking: called under lock_flocks
   *
60446067b   Marc Eshel   gfs2: stop giving...
824
825
826
827
828
   * Returns: errno
   */
  
  static int gfs2_setlease(struct file *file, long arg, struct file_lock **fl)
  {
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
829
  	return -EINVAL;
da755fdb4   Steven Whitehouse   [GFS2] Remove lm....
830
  }
60446067b   Marc Eshel   gfs2: stop giving...
831
  /**
b3b94faa5   David Teigland   [GFS2] The core o...
832
833
834
835
836
837
838
839
840
841
   * gfs2_lock - acquire/release a posix lock on a file
   * @file: the file pointer
   * @cmd: either modify or retrieve lock state, possibly wait
   * @fl: type and range of lock
   *
   * Returns: errno
   */
  
  static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
842
843
  	struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
  	struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
844
  	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
b3b94faa5   David Teigland   [GFS2] The core o...
845

b3b94faa5   David Teigland   [GFS2] The core o...
846
847
  	if (!(fl->fl_flags & FL_POSIX))
  		return -ENOLCK;
720e77492   Sachin Prabhu   GFS2: Skip check ...
848
  	if (__mandatory_lock(&ip->i_inode) && fl->fl_type != F_UNLCK)
b3b94faa5   David Teigland   [GFS2] The core o...
849
  		return -ENOLCK;
586759f03   Marc Eshel   gfs2: nfs lock su...
850
851
852
853
854
  	if (cmd == F_CANCELLK) {
  		/* Hack: */
  		cmd = F_SETLK;
  		fl->fl_type = F_UNLCK;
  	}
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
855
856
  	if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
  		return -EIO;
b3b94faa5   David Teigland   [GFS2] The core o...
857
  	if (IS_GETLK(cmd))
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
858
  		return dlm_posix_get(ls->ls_dlm, ip->i_no_addr, file, fl);
b3b94faa5   David Teigland   [GFS2] The core o...
859
  	else if (fl->fl_type == F_UNLCK)
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
860
  		return dlm_posix_unlock(ls->ls_dlm, ip->i_no_addr, file, fl);
b3b94faa5   David Teigland   [GFS2] The core o...
861
  	else
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
862
  		return dlm_posix_lock(ls->ls_dlm, ip->i_no_addr, file, cmd, fl);
b3b94faa5   David Teigland   [GFS2] The core o...
863
  }
b3b94faa5   David Teigland   [GFS2] The core o...
864
865
  static int do_flock(struct file *file, int cmd, struct file_lock *fl)
  {
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
866
  	struct gfs2_file *fp = file->private_data;
b3b94faa5   David Teigland   [GFS2] The core o...
867
  	struct gfs2_holder *fl_gh = &fp->f_fl_gh;
81454098f   Josef Sipek   [PATCH] struct pa...
868
  	struct gfs2_inode *ip = GFS2_I(file->f_path.dentry->d_inode);
b3b94faa5   David Teigland   [GFS2] The core o...
869
870
871
872
873
874
  	struct gfs2_glock *gl;
  	unsigned int state;
  	int flags;
  	int error = 0;
  
  	state = (fl->fl_type == F_WRLCK) ? LM_ST_EXCLUSIVE : LM_ST_SHARED;
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
875
  	flags = (IS_SETLKW(cmd) ? 0 : LM_FLAG_TRY) | GL_EXACT | GL_NOCACHE;
b3b94faa5   David Teigland   [GFS2] The core o...
876

f55ab26a8   Steven Whitehouse   [GFS2] Use mutice...
877
  	mutex_lock(&fp->f_fl_mutex);
b3b94faa5   David Teigland   [GFS2] The core o...
878
879
880
881
882
  
  	gl = fl_gh->gh_gl;
  	if (gl) {
  		if (fl_gh->gh_state == state)
  			goto out;
b3b94faa5   David Teigland   [GFS2] The core o...
883
  		flock_lock_file_wait(file,
907b9bceb   Steven Whitehouse   [GFS2/DLM] Fix tr...
884
  				     &(struct file_lock){.fl_type = F_UNLCK});
b4c20166d   Abhijith Das   [GFS2] flocks fro...
885
886
  		gfs2_glock_dq_wait(fl_gh);
  		gfs2_holder_reinit(state, flags, fl_gh);
b3b94faa5   David Teigland   [GFS2] The core o...
887
  	} else {
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
888
889
  		error = gfs2_glock_get(GFS2_SB(&ip->i_inode), ip->i_no_addr,
  				       &gfs2_flock_glops, CREATE, &gl);
b3b94faa5   David Teigland   [GFS2] The core o...
890
891
  		if (error)
  			goto out;
b4c20166d   Abhijith Das   [GFS2] flocks fro...
892
893
  		gfs2_holder_init(gl, state, flags, fl_gh);
  		gfs2_glock_put(gl);
b3b94faa5   David Teigland   [GFS2] The core o...
894
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
895
896
897
898
899
900
901
  	error = gfs2_glock_nq(fl_gh);
  	if (error) {
  		gfs2_holder_uninit(fl_gh);
  		if (error == GLR_TRYFAILED)
  			error = -EAGAIN;
  	} else {
  		error = flock_lock_file_wait(file, fl);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
902
  		gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
b3b94faa5   David Teigland   [GFS2] The core o...
903
  	}
420b9e5e4   Steven Whitehouse   [GFS2] Tidy up in...
904
  out:
f55ab26a8   Steven Whitehouse   [GFS2] Use mutice...
905
  	mutex_unlock(&fp->f_fl_mutex);
b3b94faa5   David Teigland   [GFS2] The core o...
906
907
908
909
910
  	return error;
  }
  
  static void do_unflock(struct file *file, struct file_lock *fl)
  {
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
911
  	struct gfs2_file *fp = file->private_data;
b3b94faa5   David Teigland   [GFS2] The core o...
912
  	struct gfs2_holder *fl_gh = &fp->f_fl_gh;
f55ab26a8   Steven Whitehouse   [GFS2] Use mutice...
913
  	mutex_lock(&fp->f_fl_mutex);
b3b94faa5   David Teigland   [GFS2] The core o...
914
  	flock_lock_file_wait(file, fl);
0a33443b3   Steven Whitehouse   GFS2: Remove pote...
915
916
917
918
  	if (fl_gh->gh_gl) {
  		gfs2_glock_dq_wait(fl_gh);
  		gfs2_holder_uninit(fl_gh);
  	}
f55ab26a8   Steven Whitehouse   [GFS2] Use mutice...
919
  	mutex_unlock(&fp->f_fl_mutex);
b3b94faa5   David Teigland   [GFS2] The core o...
920
921
922
923
924
925
926
927
928
929
930
931
932
  }
  
  /**
   * gfs2_flock - acquire/release a flock lock on a file
   * @file: the file pointer
   * @cmd: either modify or retrieve lock state, possibly wait
   * @fl: type and range of lock
   *
   * Returns: errno
   */
  
  static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl)
  {
b3b94faa5   David Teigland   [GFS2] The core o...
933
934
  	if (!(fl->fl_flags & FL_FLOCK))
  		return -ENOLCK;
a12af1ebe   Abhijith Das   GFS2: smbd procce...
935
936
  	if (fl->fl_type & LOCK_MAND)
  		return -EOPNOTSUPP;
b3b94faa5   David Teigland   [GFS2] The core o...
937

b3b94faa5   David Teigland   [GFS2] The core o...
938
939
940
  	if (fl->fl_type == F_UNLCK) {
  		do_unflock(file, fl);
  		return 0;
d00223f16   Steven Whitehouse   [GFS2] Fix code s...
941
  	} else {
b3b94faa5   David Teigland   [GFS2] The core o...
942
  		return do_flock(file, cmd, fl);
d00223f16   Steven Whitehouse   [GFS2] Fix code s...
943
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
944
  }
10d219880   Christoph Hellwig   GFS2: cleanup fil...
945
  const struct file_operations gfs2_file_fops = {
26c1a5741   Steven Whitehouse   [GFS2] More code ...
946
  	.llseek		= gfs2_llseek,
d00223f16   Steven Whitehouse   [GFS2] Fix code s...
947
  	.read		= do_sync_read,
26c1a5741   Steven Whitehouse   [GFS2] More code ...
948
  	.aio_read	= generic_file_aio_read,
d00223f16   Steven Whitehouse   [GFS2] Fix code s...
949
  	.write		= do_sync_write,
56aa616a0   Steven Whitehouse   GFS2: Ensure upto...
950
  	.aio_write	= gfs2_file_aio_write,
26c1a5741   Steven Whitehouse   [GFS2] More code ...
951
952
953
954
955
956
  	.unlocked_ioctl	= gfs2_ioctl,
  	.mmap		= gfs2_mmap,
  	.open		= gfs2_open,
  	.release	= gfs2_close,
  	.fsync		= gfs2_fsync,
  	.lock		= gfs2_lock,
26c1a5741   Steven Whitehouse   [GFS2] More code ...
957
958
959
  	.flock		= gfs2_flock,
  	.splice_read	= generic_file_splice_read,
  	.splice_write	= generic_file_splice_write,
60446067b   Marc Eshel   gfs2: stop giving...
960
  	.setlease	= gfs2_setlease,
2fe17c107   Christoph Hellwig   fallocate should ...
961
  	.fallocate	= gfs2_fallocate,
b3b94faa5   David Teigland   [GFS2] The core o...
962
  };
10d219880   Christoph Hellwig   GFS2: cleanup fil...
963
  const struct file_operations gfs2_dir_fops = {
26c1a5741   Steven Whitehouse   [GFS2] More code ...
964
965
966
967
968
969
970
  	.readdir	= gfs2_readdir,
  	.unlocked_ioctl	= gfs2_ioctl,
  	.open		= gfs2_open,
  	.release	= gfs2_close,
  	.fsync		= gfs2_fsync,
  	.lock		= gfs2_lock,
  	.flock		= gfs2_flock,
6038f373a   Arnd Bergmann   llseek: automatic...
971
  	.llseek		= default_llseek,
b3b94faa5   David Teigland   [GFS2] The core o...
972
  };
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
973
  #endif /* CONFIG_GFS2_FS_LOCKING_DLM */
10d219880   Christoph Hellwig   GFS2: cleanup fil...
974
  const struct file_operations gfs2_file_fops_nolock = {
c97bfe435   Wendy Cheng   [GFS2] Remove loc...
975
976
977
978
  	.llseek		= gfs2_llseek,
  	.read		= do_sync_read,
  	.aio_read	= generic_file_aio_read,
  	.write		= do_sync_write,
56aa616a0   Steven Whitehouse   GFS2: Ensure upto...
979
  	.aio_write	= gfs2_file_aio_write,
c97bfe435   Wendy Cheng   [GFS2] Remove loc...
980
981
982
983
984
985
986
  	.unlocked_ioctl	= gfs2_ioctl,
  	.mmap		= gfs2_mmap,
  	.open		= gfs2_open,
  	.release	= gfs2_close,
  	.fsync		= gfs2_fsync,
  	.splice_read	= generic_file_splice_read,
  	.splice_write	= generic_file_splice_write,
f057f6cdf   Steven Whitehouse   GFS2: Merge lock_...
987
  	.setlease	= generic_setlease,
2fe17c107   Christoph Hellwig   fallocate should ...
988
  	.fallocate	= gfs2_fallocate,
c97bfe435   Wendy Cheng   [GFS2] Remove loc...
989
  };
10d219880   Christoph Hellwig   GFS2: cleanup fil...
990
  const struct file_operations gfs2_dir_fops_nolock = {
c97bfe435   Wendy Cheng   [GFS2] Remove loc...
991
992
993
994
995
  	.readdir	= gfs2_readdir,
  	.unlocked_ioctl	= gfs2_ioctl,
  	.open		= gfs2_open,
  	.release	= gfs2_close,
  	.fsync		= gfs2_fsync,
6038f373a   Arnd Bergmann   llseek: automatic...
996
  	.llseek		= default_llseek,
c97bfe435   Wendy Cheng   [GFS2] Remove loc...
997
  };