Blame view

fs/locks.c 73.1 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
  /*
   *  linux/fs/locks.c
   *
   *  Provide support for fcntl()'s F_GETLK, F_SETLK, and F_SETLKW calls.
   *  Doug Evans (dje@spiff.uucp), August 07, 1992
   *
   *  Deadlock detection added.
   *  FIXME: one thing isn't handled yet:
   *	- mandatory locks (requires lots of changes elsewhere)
   *  Kelly Carmichael (kelly@[142.24.8.65]), September 17, 1994.
   *
   *  Miscellaneous edits, and a total rewrite of posix_lock_file() code.
   *  Kai Petzke (wpp@marie.physik.tu-berlin.de), 1994
   *  
   *  Converted file_lock_table to a linked list from an array, which eliminates
   *  the limits on how many active file locks are open.
   *  Chad Page (pageone@netcom.com), November 27, 1994
   * 
   *  Removed dependency on file descriptors. dup()'ed file descriptors now
   *  get the same locks as the original file descriptors, and a close() on
   *  any file descriptor removes ALL the locks on the file for the current
   *  process. Since locks still depend on the process id, locks are inherited
   *  after an exec() but not after a fork(). This agrees with POSIX, and both
   *  BSD and SVR4 practice.
   *  Andy Walker (andy@lysaker.kvaerner.no), February 14, 1995
   *
   *  Scrapped free list which is redundant now that we allocate locks
   *  dynamically with kmalloc()/kfree().
   *  Andy Walker (andy@lysaker.kvaerner.no), February 21, 1995
   *
   *  Implemented two lock personalities - FL_FLOCK and FL_POSIX.
   *
   *  FL_POSIX locks are created with calls to fcntl() and lockf() through the
   *  fcntl() system call. They have the semantics described above.
   *
   *  FL_FLOCK locks are created with calls to flock(), through the flock()
   *  system call, which is new. Old C libraries implement flock() via fcntl()
   *  and will continue to use the old, broken implementation.
   *
   *  FL_FLOCK locks follow the 4.4 BSD flock() semantics. They are associated
   *  with a file pointer (filp). As a result they can be shared by a parent
   *  process and its children after a fork(). They are removed when the last
   *  file descriptor referring to the file pointer is closed (unless explicitly
   *  unlocked). 
   *
   *  FL_FLOCK locks never deadlock, an existing lock is always removed before
   *  upgrading from shared to exclusive (or vice versa). When this happens
   *  any processes blocked by the current lock are woken up and allowed to
   *  run before the new lock is applied.
   *  Andy Walker (andy@lysaker.kvaerner.no), June 09, 1995
   *
   *  Removed some race conditions in flock_lock_file(), marked other possible
   *  races. Just grep for FIXME to see them. 
   *  Dmitry Gorodchanin (pgmdsg@ibi.com), February 09, 1996.
   *
   *  Addressed Dmitry's concerns. Deadlock checking no longer recursive.
   *  Lock allocation changed to GFP_ATOMIC as we can't afford to sleep
   *  once we've checked for blocking and deadlocking.
   *  Andy Walker (andy@lysaker.kvaerner.no), April 03, 1996.
   *
   *  Initial implementation of mandatory locks. SunOS turned out to be
   *  a rotten model, so I implemented the "obvious" semantics.
395cf9691   Paul Bolle   doc: fix broken r...
63
   *  See 'Documentation/filesystems/mandatory-locking.txt' for details.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
   *  Andy Walker (andy@lysaker.kvaerner.no), April 06, 1996.
   *
   *  Don't allow mandatory locks on mmap()'ed files. Added simple functions to
   *  check if a file has mandatory locks, used by mmap(), open() and creat() to
   *  see if system call should be rejected. Ref. HP-UX/SunOS/Solaris Reference
   *  Manual, Section 2.
   *  Andy Walker (andy@lysaker.kvaerner.no), April 09, 1996.
   *
   *  Tidied up block list handling. Added '/proc/locks' interface.
   *  Andy Walker (andy@lysaker.kvaerner.no), April 24, 1996.
   *
   *  Fixed deadlock condition for pathological code that mixes calls to
   *  flock() and fcntl().
   *  Andy Walker (andy@lysaker.kvaerner.no), April 29, 1996.
   *
   *  Allow only one type of locking scheme (FL_POSIX or FL_FLOCK) to be in use
   *  for a given file at a time. Changed the CONFIG_LOCK_MANDATORY scheme to
   *  guarantee sensible behaviour in the case where file system modules might
   *  be compiled with different options than the kernel itself.
   *  Andy Walker (andy@lysaker.kvaerner.no), May 15, 1996.
   *
   *  Added a couple of missing wake_up() calls. Thanks to Thomas Meckel
   *  (Thomas.Meckel@mni.fh-giessen.de) for spotting this.
   *  Andy Walker (andy@lysaker.kvaerner.no), May 15, 1996.
   *
   *  Changed FL_POSIX locks to use the block list in the same way as FL_FLOCK
   *  locks. Changed process synchronisation to avoid dereferencing locks that
   *  have already been freed.
   *  Andy Walker (andy@lysaker.kvaerner.no), Sep 21, 1996.
   *
   *  Made the block list a circular list to minimise searching in the list.
   *  Andy Walker (andy@lysaker.kvaerner.no), Sep 25, 1996.
   *
   *  Made mandatory locking a mount option. Default is not to allow mandatory
   *  locking.
   *  Andy Walker (andy@lysaker.kvaerner.no), Oct 04, 1996.
   *
   *  Some adaptations for NFS support.
   *  Olaf Kirch (okir@monad.swb.de), Dec 1996,
   *
   *  Fixed /proc/locks interface so that we can't overrun the buffer we are handed.
   *  Andy Walker (andy@lysaker.kvaerner.no), May 12, 1997.
   *
   *  Use slab allocator instead of kmalloc/kfree.
   *  Use generic list implementation from <linux/list.h>.
   *  Sped up posix_locks_deadlock by only considering blocked locks.
   *  Matthew Wilcox <willy@debian.org>, March, 2000.
   *
   *  Leases and LOCK_MAND
   *  Matthew Wilcox <willy@debian.org>, June, 2000.
   *  Stephen Rothwell <sfr@canb.auug.org.au>, June, 2000.
   */
  
  #include <linux/capability.h>
  #include <linux/file.h>
9f3acc314   Al Viro   [PATCH] split lin...
119
  #include <linux/fdtable.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
  #include <linux/fs.h>
  #include <linux/init.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
122
123
  #include <linux/security.h>
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
125
  #include <linux/syscalls.h>
  #include <linux/time.h>
4fb3a5386   Dipankar Sarma   [PATCH] files: fi...
126
  #include <linux/rcupdate.h>
ab1f16116   Vitaliy Gusev   pid-namespaces-vs...
127
  #include <linux/pid_namespace.h>
48f741865   Jeff Layton   locks: turn the b...
128
  #include <linux/hashtable.h>
7012b02a2   Jeff Layton   locks: move file_...
129
  #include <linux/percpu.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130

62af4f1f7   Jeff Layton   locks: add some t...
131
132
  #define CREATE_TRACE_POINTS
  #include <trace/events/filelock.h>
7c0f6ba68   Linus Torvalds   Replace <asm/uacc...
133
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
136
  
  #define IS_POSIX(fl)	(fl->fl_flags & FL_POSIX)
  #define IS_FLOCK(fl)	(fl->fl_flags & FL_FLOCK)
11afe9f76   Christoph Hellwig   fs: add FL_LAYOUT...
137
  #define IS_LEASE(fl)	(fl->fl_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT))
cff2fce58   Jeff Layton   locks: rename FL_...
138
  #define IS_OFDLCK(fl)	(fl->fl_flags & FL_OFDLCK)
9d5b86ac1   Benjamin Coddington   fs/locks: Remove ...
139
  #define IS_REMOTELCK(fl)	(fl->fl_pid <= 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140

ab83fa4b4   J. Bruce Fields   locks: minor leas...
141
142
  static bool lease_breaking(struct file_lock *fl)
  {
778fc546f   J. Bruce Fields   locks: fix tracki...
143
144
145
146
147
148
149
150
151
152
  	return fl->fl_flags & (FL_UNLOCK_PENDING | FL_DOWNGRADE_PENDING);
  }
  
  static int target_leasetype(struct file_lock *fl)
  {
  	if (fl->fl_flags & FL_UNLOCK_PENDING)
  		return F_UNLCK;
  	if (fl->fl_flags & FL_DOWNGRADE_PENDING)
  		return F_RDLCK;
  	return fl->fl_type;
ab83fa4b4   J. Bruce Fields   locks: minor leas...
153
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
155
  int leases_enable = 1;
  int lease_break_time = 45;
1c8c601a8   Jeff Layton   locks: protect mo...
156
  /*
7012b02a2   Jeff Layton   locks: move file_...
157
   * The global file_lock_list is only used for displaying /proc/locks, so we
7c3f654d8   Peter Zijlstra   fs/locks: Replace...
158
159
160
161
162
   * keep a list on each CPU, with each list protected by its own spinlock.
   * Global serialization is done using file_rwsem.
   *
   * Note that alterations to the list also require that the relevant flc_lock is
   * held.
1c8c601a8   Jeff Layton   locks: protect mo...
163
   */
7c3f654d8   Peter Zijlstra   fs/locks: Replace...
164
165
166
167
168
  struct file_lock_list_struct {
  	spinlock_t		lock;
  	struct hlist_head	hlist;
  };
  static DEFINE_PER_CPU(struct file_lock_list_struct, file_lock_list);
aba376607   Peter Zijlstra   fs/locks: Replace...
169
  DEFINE_STATIC_PERCPU_RWSEM(file_rwsem);
889746917   Jeff Layton   locks: encapsulat...
170

1c8c601a8   Jeff Layton   locks: protect mo...
171
  /*
48f741865   Jeff Layton   locks: turn the b...
172
   * The blocked_hash is used to find POSIX lock loops for deadlock detection.
7b2296afb   Jeff Layton   locks: give the b...
173
   * It is protected by blocked_lock_lock.
48f741865   Jeff Layton   locks: turn the b...
174
175
176
177
178
179
180
   *
   * We hash locks by lockowner in order to optimize searching for the lock a
   * particular lockowner is waiting on.
   *
   * FIXME: make this value scale via some heuristic? We generally will want more
   * buckets when we have more lockowners holding locks, but that's a little
   * difficult to determine without knowing what the workload will look like.
1c8c601a8   Jeff Layton   locks: protect mo...
181
   */
48f741865   Jeff Layton   locks: turn the b...
182
183
  #define BLOCKED_HASH_BITS	7
  static DEFINE_HASHTABLE(blocked_hash, BLOCKED_HASH_BITS);
889746917   Jeff Layton   locks: encapsulat...
184

1c8c601a8   Jeff Layton   locks: protect mo...
185
  /*
7b2296afb   Jeff Layton   locks: give the b...
186
187
   * This lock protects the blocked_hash. Generally, if you're accessing it, you
   * want to be holding this lock.
1c8c601a8   Jeff Layton   locks: protect mo...
188
189
190
191
192
193
   *
   * In addition, it also protects the fl->fl_block list, and the fl->fl_next
   * pointer for file_lock structures that are acting as lock requests (in
   * contrast to those that are acting as records of acquired locks).
   *
   * Note that when we acquire this lock in order to change the above fields,
6109c8503   Jeff Layton   locks: add a dedi...
194
   * we often hold the flc_lock as well. In certain cases, when reading the fields
1c8c601a8   Jeff Layton   locks: protect mo...
195
   * protected by this lock, we can skip acquiring it iff we already hold the
6109c8503   Jeff Layton   locks: add a dedi...
196
   * flc_lock.
1c8c601a8   Jeff Layton   locks: protect mo...
197
   */
7b2296afb   Jeff Layton   locks: give the b...
198
  static DEFINE_SPINLOCK(blocked_lock_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199

4a075e39c   Jeff Layton   locks: add a new ...
200
  static struct kmem_cache *flctx_cache __read_mostly;
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
201
  static struct kmem_cache *filelock_cache __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202

4a075e39c   Jeff Layton   locks: add a new ...
203
  static struct file_lock_context *
5c1c669a1   Jeff Layton   locks: don't allo...
204
  locks_get_lock_context(struct inode *inode, int type)
4a075e39c   Jeff Layton   locks: add a new ...
205
  {
128a37852   Dmitry Vyukov   fs: fix data race...
206
  	struct file_lock_context *ctx;
4a075e39c   Jeff Layton   locks: add a new ...
207

128a37852   Dmitry Vyukov   fs: fix data race...
208
209
210
  	/* paired with cmpxchg() below */
  	ctx = smp_load_acquire(&inode->i_flctx);
  	if (likely(ctx) || type == F_UNLCK)
4a075e39c   Jeff Layton   locks: add a new ...
211
  		goto out;
128a37852   Dmitry Vyukov   fs: fix data race...
212
213
  	ctx = kmem_cache_alloc(flctx_cache, GFP_KERNEL);
  	if (!ctx)
4a075e39c   Jeff Layton   locks: add a new ...
214
  		goto out;
128a37852   Dmitry Vyukov   fs: fix data race...
215
216
217
218
  	spin_lock_init(&ctx->flc_lock);
  	INIT_LIST_HEAD(&ctx->flc_flock);
  	INIT_LIST_HEAD(&ctx->flc_posix);
  	INIT_LIST_HEAD(&ctx->flc_lease);
4a075e39c   Jeff Layton   locks: add a new ...
219
220
221
222
223
  
  	/*
  	 * Assign the pointer if it's not already assigned. If it is, then
  	 * free the context we just allocated.
  	 */
128a37852   Dmitry Vyukov   fs: fix data race...
224
225
226
227
  	if (cmpxchg(&inode->i_flctx, NULL, ctx)) {
  		kmem_cache_free(flctx_cache, ctx);
  		ctx = smp_load_acquire(&inode->i_flctx);
  	}
4a075e39c   Jeff Layton   locks: add a new ...
228
  out:
1890910fd   Jeff Layton   locks: sprinkle s...
229
  	trace_locks_get_lock_context(inode, type, ctx);
128a37852   Dmitry Vyukov   fs: fix data race...
230
  	return ctx;
4a075e39c   Jeff Layton   locks: add a new ...
231
  }
e24dadab0   Jeff Layton   locks: prink more...
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
  static void
  locks_dump_ctx_list(struct list_head *list, char *list_type)
  {
  	struct file_lock *fl;
  
  	list_for_each_entry(fl, list, fl_list) {
  		pr_warn("%s: fl_owner=%p fl_flags=0x%x fl_type=0x%x fl_pid=%u
  ", list_type, fl->fl_owner, fl->fl_flags, fl->fl_type, fl->fl_pid);
  	}
  }
  
  static void
  locks_check_ctx_lists(struct inode *inode)
  {
  	struct file_lock_context *ctx = inode->i_flctx;
  
  	if (unlikely(!list_empty(&ctx->flc_flock) ||
  		     !list_empty(&ctx->flc_posix) ||
  		     !list_empty(&ctx->flc_lease))) {
  		pr_warn("Leaked locks on dev=0x%x:0x%x ino=0x%lx:
  ",
  			MAJOR(inode->i_sb->s_dev), MINOR(inode->i_sb->s_dev),
  			inode->i_ino);
  		locks_dump_ctx_list(&ctx->flc_flock, "FLOCK");
  		locks_dump_ctx_list(&ctx->flc_posix, "POSIX");
  		locks_dump_ctx_list(&ctx->flc_lease, "LEASE");
  	}
  }
3953704fd   Benjamin Coddington   locks: restore a ...
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
  static void
  locks_check_ctx_file_list(struct file *filp, struct list_head *list,
  				char *list_type)
  {
  	struct file_lock *fl;
  	struct inode *inode = locks_inode(filp);
  
  	list_for_each_entry(fl, list, fl_list)
  		if (fl->fl_file == filp)
  			pr_warn("Leaked %s lock on dev=0x%x:0x%x ino=0x%lx "
  				" fl_owner=%p fl_flags=0x%x fl_type=0x%x fl_pid=%u
  ",
  				list_type, MAJOR(inode->i_sb->s_dev),
  				MINOR(inode->i_sb->s_dev), inode->i_ino,
  				fl->fl_owner, fl->fl_flags, fl->fl_type, fl->fl_pid);
  }
4a075e39c   Jeff Layton   locks: add a new ...
276
  void
f27a0fe08   Jeff Layton   locks: pass inode...
277
  locks_free_lock_context(struct inode *inode)
4a075e39c   Jeff Layton   locks: add a new ...
278
  {
f27a0fe08   Jeff Layton   locks: pass inode...
279
  	struct file_lock_context *ctx = inode->i_flctx;
e24dadab0   Jeff Layton   locks: prink more...
280
281
  	if (unlikely(ctx)) {
  		locks_check_ctx_lists(inode);
4a075e39c   Jeff Layton   locks: add a new ...
282
283
284
  		kmem_cache_free(flctx_cache, ctx);
  	}
  }
ee19cc406   Miklos Szeredi   fs: locks: remove...
285
  static void locks_init_lock_heads(struct file_lock *fl)
a51cb91d8   Miklos Szeredi   fs: fix lock init...
286
  {
139ca04ee   Jeff Layton   locks: convert fl...
287
  	INIT_HLIST_NODE(&fl->fl_link);
6dee60f69   Jeff Layton   locks: add new st...
288
  	INIT_LIST_HEAD(&fl->fl_list);
ee19cc406   Miklos Szeredi   fs: locks: remove...
289
290
  	INIT_LIST_HEAD(&fl->fl_block);
  	init_waitqueue_head(&fl->fl_wait);
a51cb91d8   Miklos Szeredi   fs: fix lock init...
291
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
  /* Allocate an empty lock structure. */
c5b1f0d92   Arnd Bergmann   locks/nfsd: alloc...
293
  struct file_lock *locks_alloc_lock(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
  {
ee19cc406   Miklos Szeredi   fs: locks: remove...
295
  	struct file_lock *fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
a51cb91d8   Miklos Szeredi   fs: fix lock init...
296
297
  
  	if (fl)
ee19cc406   Miklos Szeredi   fs: locks: remove...
298
  		locks_init_lock_heads(fl);
a51cb91d8   Miklos Szeredi   fs: fix lock init...
299
300
  
  	return fl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301
  }
c5b1f0d92   Arnd Bergmann   locks/nfsd: alloc...
302
  EXPORT_SYMBOL_GPL(locks_alloc_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303

a9e61e25f   Felix Blyakher   lockd: call locks...
304
  void locks_release_private(struct file_lock *fl)
47831f35b   Trond Myklebust   VFS: Fix __posix_...
305
306
307
308
309
310
  {
  	if (fl->fl_ops) {
  		if (fl->fl_ops->fl_release_private)
  			fl->fl_ops->fl_release_private(fl);
  		fl->fl_ops = NULL;
  	}
47831f35b   Trond Myklebust   VFS: Fix __posix_...
311

5c97d7b14   Kinglong Mee   locks: New ops in...
312
  	if (fl->fl_lmops) {
cae80b305   Jeff Layton   locks: change lm_...
313
314
315
316
  		if (fl->fl_lmops->lm_put_owner) {
  			fl->fl_lmops->lm_put_owner(fl->fl_owner);
  			fl->fl_owner = NULL;
  		}
5c97d7b14   Kinglong Mee   locks: New ops in...
317
318
  		fl->fl_lmops = NULL;
  	}
47831f35b   Trond Myklebust   VFS: Fix __posix_...
319
  }
a9e61e25f   Felix Blyakher   lockd: call locks...
320
  EXPORT_SYMBOL_GPL(locks_release_private);
47831f35b   Trond Myklebust   VFS: Fix __posix_...
321

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
  /* Free a lock which is not in use. */
05fa3135f   J. Bruce Fields   locks: fix setlea...
323
  void locks_free_lock(struct file_lock *fl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324
  {
5ce29646e   Miklos Szeredi   [PATCH] locks: do...
325
  	BUG_ON(waitqueue_active(&fl->fl_wait));
6dee60f69   Jeff Layton   locks: add new st...
326
  	BUG_ON(!list_empty(&fl->fl_list));
5ce29646e   Miklos Szeredi   [PATCH] locks: do...
327
  	BUG_ON(!list_empty(&fl->fl_block));
139ca04ee   Jeff Layton   locks: convert fl...
328
  	BUG_ON(!hlist_unhashed(&fl->fl_link));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329

47831f35b   Trond Myklebust   VFS: Fix __posix_...
330
  	locks_release_private(fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
332
  	kmem_cache_free(filelock_cache, fl);
  }
05fa3135f   J. Bruce Fields   locks: fix setlea...
333
  EXPORT_SYMBOL(locks_free_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334

ed9814d85   Jeff Layton   locks: defer free...
335
336
337
338
339
340
  static void
  locks_dispose_list(struct list_head *dispose)
  {
  	struct file_lock *fl;
  
  	while (!list_empty(dispose)) {
6dee60f69   Jeff Layton   locks: add new st...
341
342
  		fl = list_first_entry(dispose, struct file_lock, fl_list);
  		list_del_init(&fl->fl_list);
ed9814d85   Jeff Layton   locks: defer free...
343
344
345
  		locks_free_lock(fl);
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
346
347
  void locks_init_lock(struct file_lock *fl)
  {
ee19cc406   Miklos Szeredi   fs: locks: remove...
348
349
  	memset(fl, 0, sizeof(struct file_lock));
  	locks_init_lock_heads(fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350
351
352
  }
  
  EXPORT_SYMBOL(locks_init_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
353
354
355
  /*
   * Initialize a new lock from an existing file_lock structure.
   */
3fe0fff18   Kinglong Mee   locks: Rename __l...
356
  void locks_copy_conflock(struct file_lock *new, struct file_lock *fl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
357
358
359
  {
  	new->fl_owner = fl->fl_owner;
  	new->fl_pid = fl->fl_pid;
0996905f9   Trond Myklebust   lockd: posix_test...
360
  	new->fl_file = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
361
362
363
364
  	new->fl_flags = fl->fl_flags;
  	new->fl_type = fl->fl_type;
  	new->fl_start = fl->fl_start;
  	new->fl_end = fl->fl_end;
f328296e2   Kinglong Mee   locks: Copy fl_lm...
365
  	new->fl_lmops = fl->fl_lmops;
0996905f9   Trond Myklebust   lockd: posix_test...
366
  	new->fl_ops = NULL;
f328296e2   Kinglong Mee   locks: Copy fl_lm...
367
368
369
  
  	if (fl->fl_lmops) {
  		if (fl->fl_lmops->lm_get_owner)
cae80b305   Jeff Layton   locks: change lm_...
370
  			fl->fl_lmops->lm_get_owner(fl->fl_owner);
f328296e2   Kinglong Mee   locks: Copy fl_lm...
371
  	}
0996905f9   Trond Myklebust   lockd: posix_test...
372
  }
3fe0fff18   Kinglong Mee   locks: Rename __l...
373
  EXPORT_SYMBOL(locks_copy_conflock);
0996905f9   Trond Myklebust   lockd: posix_test...
374
375
376
  
  void locks_copy_lock(struct file_lock *new, struct file_lock *fl)
  {
566709bd6   Jeff Layton   locks: don't call...
377
378
  	/* "new" must be a freshly-initialized lock */
  	WARN_ON_ONCE(new->fl_ops);
0996905f9   Trond Myklebust   lockd: posix_test...
379

3fe0fff18   Kinglong Mee   locks: Rename __l...
380
  	locks_copy_conflock(new, fl);
f328296e2   Kinglong Mee   locks: Copy fl_lm...
381

0996905f9   Trond Myklebust   lockd: posix_test...
382
  	new->fl_file = fl->fl_file;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
  	new->fl_ops = fl->fl_ops;
47831f35b   Trond Myklebust   VFS: Fix __posix_...
384

f328296e2   Kinglong Mee   locks: Copy fl_lm...
385
386
387
388
  	if (fl->fl_ops) {
  		if (fl->fl_ops->fl_copy_lock)
  			fl->fl_ops->fl_copy_lock(new, fl);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
  }
  
  EXPORT_SYMBOL(locks_copy_lock);
  
  static inline int flock_translate_cmd(int cmd) {
  	if (cmd & LOCK_MAND)
  		return cmd & (LOCK_MAND | LOCK_RW);
  	switch (cmd) {
  	case LOCK_SH:
  		return F_RDLCK;
  	case LOCK_EX:
  		return F_WRLCK;
  	case LOCK_UN:
  		return F_UNLCK;
  	}
  	return -EINVAL;
  }
  
  /* Fill in a file_lock structure with an appropriate FLOCK lock. */
6e129d006   Jeff Layton   locks: flock_make...
408
409
  static struct file_lock *
  flock_make_lock(struct file *filp, unsigned int cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410
411
412
  {
  	struct file_lock *fl;
  	int type = flock_translate_cmd(cmd);
6e129d006   Jeff Layton   locks: flock_make...
413

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
414
  	if (type < 0)
6e129d006   Jeff Layton   locks: flock_make...
415
  		return ERR_PTR(type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
416
417
418
  	
  	fl = locks_alloc_lock();
  	if (fl == NULL)
6e129d006   Jeff Layton   locks: flock_make...
419
  		return ERR_PTR(-ENOMEM);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420
421
  
  	fl->fl_file = filp;
73a8f5f7e   Christoph Hellwig   locks: purge fl_o...
422
  	fl->fl_owner = filp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
424
425
426
427
  	fl->fl_pid = current->tgid;
  	fl->fl_flags = FL_FLOCK;
  	fl->fl_type = type;
  	fl->fl_end = OFFSET_MAX;
  	
6e129d006   Jeff Layton   locks: flock_make...
428
  	return fl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
429
  }
0ec4f431e   J. Bruce Fields   locks: fix checki...
430
  static int assign_type(struct file_lock *fl, long type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
431
432
433
434
435
436
437
438
439
440
441
442
  {
  	switch (type) {
  	case F_RDLCK:
  	case F_WRLCK:
  	case F_UNLCK:
  		fl->fl_type = type;
  		break;
  	default:
  		return -EINVAL;
  	}
  	return 0;
  }
ef12e72a0   J. Bruce Fields   locks: fix posix ...
443
444
  static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,
  				 struct flock64 *l)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446
  	switch (l->l_whence) {
f5579f8c7   Josef 'Jeff' Sipek   [PATCH] VFS: Use ...
447
  	case SEEK_SET:
ef12e72a0   J. Bruce Fields   locks: fix posix ...
448
  		fl->fl_start = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
449
  		break;
f5579f8c7   Josef 'Jeff' Sipek   [PATCH] VFS: Use ...
450
  	case SEEK_CUR:
ef12e72a0   J. Bruce Fields   locks: fix posix ...
451
  		fl->fl_start = filp->f_pos;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
452
  		break;
f5579f8c7   Josef 'Jeff' Sipek   [PATCH] VFS: Use ...
453
  	case SEEK_END:
ef12e72a0   J. Bruce Fields   locks: fix posix ...
454
  		fl->fl_start = i_size_read(file_inode(filp));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
455
456
457
458
  		break;
  	default:
  		return -EINVAL;
  	}
ef12e72a0   J. Bruce Fields   locks: fix posix ...
459
460
461
462
463
  	if (l->l_start > OFFSET_MAX - fl->fl_start)
  		return -EOVERFLOW;
  	fl->fl_start += l->l_start;
  	if (fl->fl_start < 0)
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
464
465
466
  
  	/* POSIX-1996 leaves the case l->l_len < 0 undefined;
  	   POSIX-2001 defines it. */
4c780a468   Trond Myklebust   Fix Connectathon ...
467
  	if (l->l_len > 0) {
ef12e72a0   J. Bruce Fields   locks: fix posix ...
468
469
470
  		if (l->l_len - 1 > OFFSET_MAX - fl->fl_start)
  			return -EOVERFLOW;
  		fl->fl_end = fl->fl_start + l->l_len - 1;
4c780a468   Trond Myklebust   Fix Connectathon ...
471
  	} else if (l->l_len < 0) {
ef12e72a0   J. Bruce Fields   locks: fix posix ...
472
  		if (fl->fl_start + l->l_len < 0)
4c780a468   Trond Myklebust   Fix Connectathon ...
473
  			return -EINVAL;
ef12e72a0   J. Bruce Fields   locks: fix posix ...
474
475
476
477
  		fl->fl_end = fl->fl_start - 1;
  		fl->fl_start += l->l_len;
  	} else
  		fl->fl_end = OFFSET_MAX;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
478
479
480
481
482
483
484
485
486
  	fl->fl_owner = current->files;
  	fl->fl_pid = current->tgid;
  	fl->fl_file = filp;
  	fl->fl_flags = FL_POSIX;
  	fl->fl_ops = NULL;
  	fl->fl_lmops = NULL;
  
  	return assign_type(fl, l->l_type);
  }
ef12e72a0   J. Bruce Fields   locks: fix posix ...
487
488
489
490
491
  /* Verify a "struct flock" and copy it to a "struct file_lock" as a POSIX
   * style lock.
   */
  static int flock_to_posix_lock(struct file *filp, struct file_lock *fl,
  			       struct flock *l)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
  {
ef12e72a0   J. Bruce Fields   locks: fix posix ...
493
494
495
496
497
498
499
500
  	struct flock64 ll = {
  		.l_type = l->l_type,
  		.l_whence = l->l_whence,
  		.l_start = l->l_start,
  		.l_len = l->l_len,
  	};
  
  	return flock64_to_posix_lock(filp, fl, &ll);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502
503
  
  /* default lease lock manager operations */
4d01b7f5e   Jeff Layton   locks: give lm_br...
504
505
  static bool
  lease_break_callback(struct file_lock *fl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
506
507
  {
  	kill_fasync(&fl->fl_fasync, SIGIO, POLL_MSG);
4d01b7f5e   Jeff Layton   locks: give lm_br...
508
  	return false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
509
  }
1c7dd2ff4   Jeff Layton   locks: define a l...
510
511
512
513
514
515
516
517
518
519
520
521
522
  static void
  lease_setup(struct file_lock *fl, void **priv)
  {
  	struct file *filp = fl->fl_file;
  	struct fasync_struct *fa = *priv;
  
  	/*
  	 * fasync_insert_entry() returns the old entry if any. If there was no
  	 * old entry, then it used "priv" and inserted it into the fasync list.
  	 * Clear the pointer to indicate that it shouldn't be freed.
  	 */
  	if (!fasync_insert_entry(fa->fa_fd, filp, &fl->fl_fasync, fa))
  		*priv = NULL;
019191342   Eric W. Biederman   signal: Use PIDTY...
523
  	__f_setown(filp, task_pid(current), PIDTYPE_TGID, 0);
1c7dd2ff4   Jeff Layton   locks: define a l...
524
  }
7b021967c   Alexey Dobriyan   const: make lock_...
525
  static const struct lock_manager_operations lease_manager_ops = {
8fb47a4fb   J. Bruce Fields   locks: rename loc...
526
  	.lm_break = lease_break_callback,
8fb47a4fb   J. Bruce Fields   locks: rename loc...
527
  	.lm_change = lease_modify,
1c7dd2ff4   Jeff Layton   locks: define a l...
528
  	.lm_setup = lease_setup,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
529
530
531
532
533
  };
  
  /*
   * Initialize a lease, use the default lock manager operations
   */
0ec4f431e   J. Bruce Fields   locks: fix checki...
534
  static int lease_init(struct file *filp, long type, struct file_lock *fl)
447a5647c   Joe Perches   treewide: Align f...
535
  {
75dff55af   Trond Myklebust   [PATCH] fs/locks....
536
537
  	if (assign_type(fl, type) != 0)
  		return -EINVAL;
7ca76311f   Jeff Layton   locks: set fl_own...
538
  	fl->fl_owner = filp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539
540
541
542
  	fl->fl_pid = current->tgid;
  
  	fl->fl_file = filp;
  	fl->fl_flags = FL_LEASE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
543
544
545
546
547
548
549
550
  	fl->fl_start = 0;
  	fl->fl_end = OFFSET_MAX;
  	fl->fl_ops = NULL;
  	fl->fl_lmops = &lease_manager_ops;
  	return 0;
  }
  
  /* Allocate a file_lock initialised to this type of lease */
0ec4f431e   J. Bruce Fields   locks: fix checki...
551
  static struct file_lock *lease_alloc(struct file *filp, long type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
552
553
  {
  	struct file_lock *fl = locks_alloc_lock();
75dff55af   Trond Myklebust   [PATCH] fs/locks....
554
  	int error = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
555
556
  
  	if (fl == NULL)
e32b8ee27   J. Bruce Fields   locks: clean up l...
557
  		return ERR_PTR(error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
558
559
  
  	error = lease_init(filp, type, fl);
75dff55af   Trond Myklebust   [PATCH] fs/locks....
560
561
  	if (error) {
  		locks_free_lock(fl);
e32b8ee27   J. Bruce Fields   locks: clean up l...
562
  		return ERR_PTR(error);
75dff55af   Trond Myklebust   [PATCH] fs/locks....
563
  	}
e32b8ee27   J. Bruce Fields   locks: clean up l...
564
  	return fl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
565
566
567
568
569
570
571
572
573
574
575
576
577
  }
  
  /* Check if two locks overlap each other.
   */
  static inline int locks_overlap(struct file_lock *fl1, struct file_lock *fl2)
  {
  	return ((fl1->fl_end >= fl2->fl_start) &&
  		(fl2->fl_end >= fl1->fl_start));
  }
  
  /*
   * Check whether two locks have the same owner.
   */
33443c42f   Matt Mackall   [PATCH] tiny: Uni...
578
  static int posix_same_owner(struct file_lock *fl1, struct file_lock *fl2)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
579
  {
8fb47a4fb   J. Bruce Fields   locks: rename loc...
580
  	if (fl1->fl_lmops && fl1->fl_lmops->lm_compare_owner)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581
  		return fl2->fl_lmops == fl1->fl_lmops &&
8fb47a4fb   J. Bruce Fields   locks: rename loc...
582
  			fl1->fl_lmops->lm_compare_owner(fl1, fl2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
583
584
  	return fl1->fl_owner == fl2->fl_owner;
  }
6109c8503   Jeff Layton   locks: add a dedi...
585
  /* Must be called with the flc_lock held! */
6ca10ed8e   Jeff Layton   locks: remove "in...
586
  static void locks_insert_global_locks(struct file_lock *fl)
889746917   Jeff Layton   locks: encapsulat...
587
  {
7c3f654d8   Peter Zijlstra   fs/locks: Replace...
588
  	struct file_lock_list_struct *fll = this_cpu_ptr(&file_lock_list);
aba376607   Peter Zijlstra   fs/locks: Replace...
589
  	percpu_rwsem_assert_held(&file_rwsem);
7c3f654d8   Peter Zijlstra   fs/locks: Replace...
590
  	spin_lock(&fll->lock);
7012b02a2   Jeff Layton   locks: move file_...
591
  	fl->fl_link_cpu = smp_processor_id();
7c3f654d8   Peter Zijlstra   fs/locks: Replace...
592
593
  	hlist_add_head(&fl->fl_link, &fll->hlist);
  	spin_unlock(&fll->lock);
889746917   Jeff Layton   locks: encapsulat...
594
  }
6109c8503   Jeff Layton   locks: add a dedi...
595
  /* Must be called with the flc_lock held! */
6ca10ed8e   Jeff Layton   locks: remove "in...
596
  static void locks_delete_global_locks(struct file_lock *fl)
889746917   Jeff Layton   locks: encapsulat...
597
  {
7c3f654d8   Peter Zijlstra   fs/locks: Replace...
598
  	struct file_lock_list_struct *fll;
aba376607   Peter Zijlstra   fs/locks: Replace...
599
  	percpu_rwsem_assert_held(&file_rwsem);
7012b02a2   Jeff Layton   locks: move file_...
600
601
  	/*
  	 * Avoid taking lock if already unhashed. This is safe since this check
6109c8503   Jeff Layton   locks: add a dedi...
602
  	 * is done while holding the flc_lock, and new insertions into the list
7012b02a2   Jeff Layton   locks: move file_...
603
604
605
606
  	 * also require that it be held.
  	 */
  	if (hlist_unhashed(&fl->fl_link))
  		return;
7c3f654d8   Peter Zijlstra   fs/locks: Replace...
607
608
609
  
  	fll = per_cpu_ptr(&file_lock_list, fl->fl_link_cpu);
  	spin_lock(&fll->lock);
139ca04ee   Jeff Layton   locks: convert fl...
610
  	hlist_del_init(&fl->fl_link);
7c3f654d8   Peter Zijlstra   fs/locks: Replace...
611
  	spin_unlock(&fll->lock);
889746917   Jeff Layton   locks: encapsulat...
612
  }
3999e4936   Jeff Layton   locks: add a new ...
613
614
615
616
617
618
619
  static unsigned long
  posix_owner_key(struct file_lock *fl)
  {
  	if (fl->fl_lmops && fl->fl_lmops->lm_owner_key)
  		return fl->fl_lmops->lm_owner_key(fl);
  	return (unsigned long)fl->fl_owner;
  }
6ca10ed8e   Jeff Layton   locks: remove "in...
620
  static void locks_insert_global_blocked(struct file_lock *waiter)
889746917   Jeff Layton   locks: encapsulat...
621
  {
663d5af75   Daniel Wagner   locks: Add lockde...
622
  	lockdep_assert_held(&blocked_lock_lock);
3999e4936   Jeff Layton   locks: add a new ...
623
  	hash_add(blocked_hash, &waiter->fl_link, posix_owner_key(waiter));
889746917   Jeff Layton   locks: encapsulat...
624
  }
6ca10ed8e   Jeff Layton   locks: remove "in...
625
  static void locks_delete_global_blocked(struct file_lock *waiter)
889746917   Jeff Layton   locks: encapsulat...
626
  {
663d5af75   Daniel Wagner   locks: Add lockde...
627
  	lockdep_assert_held(&blocked_lock_lock);
48f741865   Jeff Layton   locks: turn the b...
628
  	hash_del(&waiter->fl_link);
889746917   Jeff Layton   locks: encapsulat...
629
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
630
631
  /* Remove waiter from blocker's block list.
   * When blocker ends up pointing to itself then the list is empty.
1c8c601a8   Jeff Layton   locks: protect mo...
632
   *
7b2296afb   Jeff Layton   locks: give the b...
633
   * Must be called with blocked_lock_lock held.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
634
   */
33443c42f   Matt Mackall   [PATCH] tiny: Uni...
635
  static void __locks_delete_block(struct file_lock *waiter)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
636
  {
889746917   Jeff Layton   locks: encapsulat...
637
  	locks_delete_global_blocked(waiter);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638
  	list_del_init(&waiter->fl_block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
639
640
  	waiter->fl_next = NULL;
  }
1a9e64a71   Jeff Layton   cifs: use posix_u...
641
  static void locks_delete_block(struct file_lock *waiter)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
642
  {
7b2296afb   Jeff Layton   locks: give the b...
643
  	spin_lock(&blocked_lock_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
644
  	__locks_delete_block(waiter);
7b2296afb   Jeff Layton   locks: give the b...
645
  	spin_unlock(&blocked_lock_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646
647
648
649
650
651
  }
  
  /* Insert waiter into blocker's block list.
   * We use a circular list so that processes can be easily woken up in
   * the order they blocked. The documentation doesn't require this but
   * it seems like the reasonable thing to do.
1c8c601a8   Jeff Layton   locks: protect mo...
652
   *
6109c8503   Jeff Layton   locks: add a dedi...
653
654
655
656
   * Must be called with both the flc_lock and blocked_lock_lock held. The
   * fl_block list itself is protected by the blocked_lock_lock, but by ensuring
   * that the flc_lock is also held on insertions we can avoid taking the
   * blocked_lock_lock in some cases when we see that the fl_block list is empty.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
657
   */
1c8c601a8   Jeff Layton   locks: protect mo...
658
659
  static void __locks_insert_block(struct file_lock *blocker,
  					struct file_lock *waiter)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
660
  {
6dc0fe8f8   J. Bruce Fields   [PATCH] VFS,fs/lo...
661
  	BUG_ON(!list_empty(&waiter->fl_block));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
  	waiter->fl_next = blocker;
889746917   Jeff Layton   locks: encapsulat...
663
  	list_add_tail(&waiter->fl_block, &blocker->fl_block);
cff2fce58   Jeff Layton   locks: rename FL_...
664
  	if (IS_POSIX(blocker) && !IS_OFDLCK(blocker))
1c8c601a8   Jeff Layton   locks: protect mo...
665
666
  		locks_insert_global_blocked(waiter);
  }
6109c8503   Jeff Layton   locks: add a dedi...
667
  /* Must be called with flc_lock held. */
1c8c601a8   Jeff Layton   locks: protect mo...
668
669
670
  static void locks_insert_block(struct file_lock *blocker,
  					struct file_lock *waiter)
  {
7b2296afb   Jeff Layton   locks: give the b...
671
  	spin_lock(&blocked_lock_lock);
1c8c601a8   Jeff Layton   locks: protect mo...
672
  	__locks_insert_block(blocker, waiter);
7b2296afb   Jeff Layton   locks: give the b...
673
  	spin_unlock(&blocked_lock_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674
  }
1cb360125   Jeff Layton   locks: comment cl...
675
676
677
  /*
   * Wake up processes blocked waiting for blocker.
   *
6109c8503   Jeff Layton   locks: add a dedi...
678
   * Must be called with the inode->flc_lock held!
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
679
680
681
   */
  static void locks_wake_up_blocks(struct file_lock *blocker)
  {
4e8c765d3   Jeff Layton   locks: avoid taki...
682
683
  	/*
  	 * Avoid taking global lock if list is empty. This is safe since new
6109c8503   Jeff Layton   locks: add a dedi...
684
685
686
  	 * blocked requests are only added to the list under the flc_lock, and
  	 * the flc_lock is always held here. Note that removal from the fl_block
  	 * list does not require the flc_lock, so we must recheck list_empty()
7b2296afb   Jeff Layton   locks: give the b...
687
  	 * after acquiring the blocked_lock_lock.
4e8c765d3   Jeff Layton   locks: avoid taki...
688
689
690
  	 */
  	if (list_empty(&blocker->fl_block))
  		return;
7b2296afb   Jeff Layton   locks: give the b...
691
  	spin_lock(&blocked_lock_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
692
  	while (!list_empty(&blocker->fl_block)) {
f0c1cd0ea   Pavel Emelyanov   Use list_first_en...
693
694
695
  		struct file_lock *waiter;
  
  		waiter = list_first_entry(&blocker->fl_block,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
696
697
  				struct file_lock, fl_block);
  		__locks_delete_block(waiter);
8fb47a4fb   J. Bruce Fields   locks: rename loc...
698
699
  		if (waiter->fl_lmops && waiter->fl_lmops->lm_notify)
  			waiter->fl_lmops->lm_notify(waiter);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
700
701
702
  		else
  			wake_up(&waiter->fl_wait);
  	}
7b2296afb   Jeff Layton   locks: give the b...
703
  	spin_unlock(&blocked_lock_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
704
  }
5263e31e4   Jeff Layton   locks: move flock...
705
  static void
e084c1bd4   Jeff Layton   Revert "locks: ke...
706
  locks_insert_lock_ctx(struct file_lock *fl, struct list_head *before)
5263e31e4   Jeff Layton   locks: move flock...
707
  {
5263e31e4   Jeff Layton   locks: move flock...
708
709
710
  	list_add_tail(&fl->fl_list, before);
  	locks_insert_global_locks(fl);
  }
8634b51f6   Jeff Layton   locks: convert le...
711
  static void
e084c1bd4   Jeff Layton   Revert "locks: ke...
712
  locks_unlink_lock_ctx(struct file_lock *fl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
713
  {
889746917   Jeff Layton   locks: encapsulat...
714
  	locks_delete_global_locks(fl);
8634b51f6   Jeff Layton   locks: convert le...
715
  	list_del_init(&fl->fl_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
716
  	locks_wake_up_blocks(fl);
24cbe7845   Jeff Layton   locks: close pote...
717
  }
8634b51f6   Jeff Layton   locks: convert le...
718
  static void
e084c1bd4   Jeff Layton   Revert "locks: ke...
719
  locks_delete_lock_ctx(struct file_lock *fl, struct list_head *dispose)
24cbe7845   Jeff Layton   locks: close pote...
720
  {
e084c1bd4   Jeff Layton   Revert "locks: ke...
721
  	locks_unlink_lock_ctx(fl);
ed9814d85   Jeff Layton   locks: defer free...
722
  	if (dispose)
6dee60f69   Jeff Layton   locks: add new st...
723
  		list_add(&fl->fl_list, dispose);
ed9814d85   Jeff Layton   locks: defer free...
724
725
  	else
  		locks_free_lock(fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
  }
  
  /* Determine if lock sys_fl blocks lock caller_fl. Common functionality
   * checks for shared/exclusive status of overlapping locks.
   */
  static int locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl)
  {
  	if (sys_fl->fl_type == F_WRLCK)
  		return 1;
  	if (caller_fl->fl_type == F_WRLCK)
  		return 1;
  	return 0;
  }
  
  /* Determine if lock sys_fl blocks lock caller_fl. POSIX specific
   * checking before calling the locks_conflict().
   */
  static int posix_locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl)
  {
  	/* POSIX locks owned by the same process do not conflict with
  	 * each other.
  	 */
9b8c86956   Jeff Layton   locks: remove ext...
748
  	if (posix_same_owner(caller_fl, sys_fl))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
  		return (0);
  
  	/* Check whether they overlap */
  	if (!locks_overlap(caller_fl, sys_fl))
  		return 0;
  
  	return (locks_conflict(caller_fl, sys_fl));
  }
  
  /* Determine if lock sys_fl blocks lock caller_fl. FLOCK specific
   * checking before calling the locks_conflict().
   */
  static int flock_locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl)
  {
  	/* FLOCK locks referring to the same filp do not conflict with
  	 * each other.
  	 */
9b8c86956   Jeff Layton   locks: remove ext...
766
  	if (caller_fl->fl_file == sys_fl->fl_file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
767
768
769
770
771
772
  		return (0);
  	if ((caller_fl->fl_type & LOCK_MAND) || (sys_fl->fl_type & LOCK_MAND))
  		return 0;
  
  	return (locks_conflict(caller_fl, sys_fl));
  }
6d34ac199   J. Bruce Fields   locks: make posix...
773
  void
9d6a8c5c2   Marc Eshel   locks: give posix...
774
  posix_test_lock(struct file *filp, struct file_lock *fl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
775
776
  {
  	struct file_lock *cfl;
bd61e0a9c   Jeff Layton   locks: convert po...
777
  	struct file_lock_context *ctx;
c568d6834   Miklos Szeredi   locks: fix file l...
778
  	struct inode *inode = locks_inode(filp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
779

128a37852   Dmitry Vyukov   fs: fix data race...
780
  	ctx = smp_load_acquire(&inode->i_flctx);
bd61e0a9c   Jeff Layton   locks: convert po...
781
782
783
784
  	if (!ctx || list_empty_careful(&ctx->flc_posix)) {
  		fl->fl_type = F_UNLCK;
  		return;
  	}
6109c8503   Jeff Layton   locks: add a dedi...
785
  	spin_lock(&ctx->flc_lock);
bd61e0a9c   Jeff Layton   locks: convert po...
786
787
788
  	list_for_each_entry(cfl, &ctx->flc_posix, fl_list) {
  		if (posix_locks_conflict(fl, cfl)) {
  			locks_copy_conflock(fl, cfl);
bd61e0a9c   Jeff Layton   locks: convert po...
789
790
  			goto out;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
791
  	}
bd61e0a9c   Jeff Layton   locks: convert po...
792
793
  	fl->fl_type = F_UNLCK;
  out:
6109c8503   Jeff Layton   locks: add a dedi...
794
  	spin_unlock(&ctx->flc_lock);
6d34ac199   J. Bruce Fields   locks: make posix...
795
  	return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
796
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
797
  EXPORT_SYMBOL(posix_test_lock);
b533184fc   J. Bruce Fields   locks: clarify po...
798
799
800
801
802
  /*
   * Deadlock detection:
   *
   * We attempt to detect deadlocks that are due purely to posix file
   * locks.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
803
   *
b533184fc   J. Bruce Fields   locks: clarify po...
804
805
806
807
808
809
810
   * We assume that a task can be waiting for at most one lock at a time.
   * So for any acquired lock, the process holding that lock may be
   * waiting on at most one other lock.  That lock in turns may be held by
   * someone waiting for at most one other lock.  Given a requested lock
   * caller_fl which is about to wait for a conflicting lock block_fl, we
   * follow this chain of waiters to ensure we are not about to create a
   * cycle.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
811
   *
b533184fc   J. Bruce Fields   locks: clarify po...
812
813
814
   * Since we do this before we ever put a process to sleep on a lock, we
   * are ensured that there is never a cycle; that is what guarantees that
   * the while() loop in posix_locks_deadlock() eventually completes.
97855b49b   J. Bruce Fields   locks: fix possib...
815
   *
b533184fc   J. Bruce Fields   locks: clarify po...
816
817
818
   * Note: the above assumption may not be true when handling lock
   * requests from a broken NFS client. It may also fail in the presence
   * of tasks (such as posix threads) sharing the same open file table.
b533184fc   J. Bruce Fields   locks: clarify po...
819
   * To handle those cases, we just bail out after a few iterations.
57b65325f   Jeff Layton   locks: skip deadl...
820
   *
cff2fce58   Jeff Layton   locks: rename FL_...
821
   * For FL_OFDLCK locks, the owner is the filp, not the files_struct.
57b65325f   Jeff Layton   locks: skip deadl...
822
823
824
825
   * Because the owner is not even nominally tied to a thread of
   * execution, the deadlock detection below can't reasonably work well. Just
   * skip it for those.
   *
cff2fce58   Jeff Layton   locks: rename FL_...
826
   * In principle, we could do a more limited deadlock detection on FL_OFDLCK
57b65325f   Jeff Layton   locks: skip deadl...
827
828
   * locks that just checks for the case where two tasks are attempting to
   * upgrade from read to write locks on the same inode.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
829
   */
97855b49b   J. Bruce Fields   locks: fix possib...
830
831
  
  #define MAX_DEADLK_ITERATIONS 10
b533184fc   J. Bruce Fields   locks: clarify po...
832
833
834
835
  /* Find a lock that the owner of the given block_fl is blocking on. */
  static struct file_lock *what_owner_is_waiting_for(struct file_lock *block_fl)
  {
  	struct file_lock *fl;
3999e4936   Jeff Layton   locks: add a new ...
836
  	hash_for_each_possible(blocked_hash, fl, fl_link, posix_owner_key(block_fl)) {
b533184fc   J. Bruce Fields   locks: clarify po...
837
838
839
840
841
  		if (posix_same_owner(fl, block_fl))
  			return fl->fl_next;
  	}
  	return NULL;
  }
7b2296afb   Jeff Layton   locks: give the b...
842
  /* Must be called with the blocked_lock_lock held! */
b0904e147   Adrian Bunk   [PATCH] fs/locks....
843
  static int posix_locks_deadlock(struct file_lock *caller_fl,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
844
845
  				struct file_lock *block_fl)
  {
97855b49b   J. Bruce Fields   locks: fix possib...
846
  	int i = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
847

663d5af75   Daniel Wagner   locks: Add lockde...
848
  	lockdep_assert_held(&blocked_lock_lock);
57b65325f   Jeff Layton   locks: skip deadl...
849
850
  	/*
  	 * This deadlock detector can't reasonably detect deadlocks with
cff2fce58   Jeff Layton   locks: rename FL_...
851
  	 * FL_OFDLCK locks, since they aren't owned by a process, per-se.
57b65325f   Jeff Layton   locks: skip deadl...
852
  	 */
cff2fce58   Jeff Layton   locks: rename FL_...
853
  	if (IS_OFDLCK(caller_fl))
57b65325f   Jeff Layton   locks: skip deadl...
854
  		return 0;
b533184fc   J. Bruce Fields   locks: clarify po...
855
856
857
858
859
  	while ((block_fl = what_owner_is_waiting_for(block_fl))) {
  		if (i++ > MAX_DEADLK_ITERATIONS)
  			return 0;
  		if (posix_same_owner(caller_fl, block_fl))
  			return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
860
861
862
  	}
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
863
  /* Try to create a FLOCK lock on filp. We always insert new FLOCK locks
02888f41e   J. Bruce Fields   locks: fix flock_...
864
   * after any leases, but before any posix locks.
f475ae957   Trond Myklebust   VFS: Allow caller...
865
866
867
868
   *
   * Note that if called with an FL_EXISTS argument, the caller may determine
   * whether or not a lock was successfully freed by testing the return
   * value for -ENOENT.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
869
   */
bcd7f78d0   Jeff Layton   locks: have flock...
870
  static int flock_lock_inode(struct inode *inode, struct file_lock *request)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
871
  {
993dfa877   Trond Myklebust   [PATCH] fs/locks....
872
  	struct file_lock *new_fl = NULL;
5263e31e4   Jeff Layton   locks: move flock...
873
874
  	struct file_lock *fl;
  	struct file_lock_context *ctx;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
875
  	int error = 0;
5263e31e4   Jeff Layton   locks: move flock...
876
  	bool found = false;
ed9814d85   Jeff Layton   locks: defer free...
877
  	LIST_HEAD(dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
878

5c1c669a1   Jeff Layton   locks: don't allo...
879
880
881
882
883
884
  	ctx = locks_get_lock_context(inode, request->fl_type);
  	if (!ctx) {
  		if (request->fl_type != F_UNLCK)
  			return -ENOMEM;
  		return (request->fl_flags & FL_EXISTS) ? -ENOENT : 0;
  	}
5263e31e4   Jeff Layton   locks: move flock...
885

b89f43213   Arnd Bergmann   fs/locks.c: prepa...
886
  	if (!(request->fl_flags & FL_ACCESS) && (request->fl_type != F_UNLCK)) {
84d535ade   Pavel Emelyanov   Memory shortage c...
887
  		new_fl = locks_alloc_lock();
b89f43213   Arnd Bergmann   fs/locks.c: prepa...
888
889
  		if (!new_fl)
  			return -ENOMEM;
84d535ade   Pavel Emelyanov   Memory shortage c...
890
  	}
87709e28d   Peter Zijlstra   fs/locks: Use per...
891
  	percpu_down_read_preempt_disable(&file_rwsem);
6109c8503   Jeff Layton   locks: add a dedi...
892
  	spin_lock(&ctx->flc_lock);
b89f43213   Arnd Bergmann   fs/locks.c: prepa...
893
894
  	if (request->fl_flags & FL_ACCESS)
  		goto find_conflict;
5263e31e4   Jeff Layton   locks: move flock...
895
  	list_for_each_entry(fl, &ctx->flc_flock, fl_list) {
bcd7f78d0   Jeff Layton   locks: have flock...
896
  		if (request->fl_file != fl->fl_file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
897
  			continue;
993dfa877   Trond Myklebust   [PATCH] fs/locks....
898
  		if (request->fl_type == fl->fl_type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
899
  			goto out;
5263e31e4   Jeff Layton   locks: move flock...
900
  		found = true;
e084c1bd4   Jeff Layton   Revert "locks: ke...
901
  		locks_delete_lock_ctx(fl, &dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
902
903
  		break;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
904

f475ae957   Trond Myklebust   VFS: Allow caller...
905
906
907
  	if (request->fl_type == F_UNLCK) {
  		if ((request->fl_flags & FL_EXISTS) && !found)
  			error = -ENOENT;
993dfa877   Trond Myklebust   [PATCH] fs/locks....
908
  		goto out;
f475ae957   Trond Myklebust   VFS: Allow caller...
909
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
910

f07f18dd6   Trond Myklebust   VFS: Add support ...
911
  find_conflict:
5263e31e4   Jeff Layton   locks: move flock...
912
  	list_for_each_entry(fl, &ctx->flc_flock, fl_list) {
993dfa877   Trond Myklebust   [PATCH] fs/locks....
913
  		if (!flock_locks_conflict(request, fl))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
914
915
  			continue;
  		error = -EAGAIN;
bde74e4bc   Miklos Szeredi   locks: add specia...
916
917
918
919
  		if (!(request->fl_flags & FL_SLEEP))
  			goto out;
  		error = FILE_LOCK_DEFERRED;
  		locks_insert_block(fl, request);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
920
921
  		goto out;
  	}
f07f18dd6   Trond Myklebust   VFS: Add support ...
922
923
  	if (request->fl_flags & FL_ACCESS)
  		goto out;
993dfa877   Trond Myklebust   [PATCH] fs/locks....
924
  	locks_copy_lock(new_fl, request);
e084c1bd4   Jeff Layton   Revert "locks: ke...
925
  	locks_insert_lock_ctx(new_fl, &ctx->flc_flock);
993dfa877   Trond Myklebust   [PATCH] fs/locks....
926
  	new_fl = NULL;
9cedc194a   Kirill Korotaev   [PATCH] Return er...
927
  	error = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
928
929
  
  out:
6109c8503   Jeff Layton   locks: add a dedi...
930
  	spin_unlock(&ctx->flc_lock);
87709e28d   Peter Zijlstra   fs/locks: Use per...
931
  	percpu_up_read_preempt_enable(&file_rwsem);
993dfa877   Trond Myklebust   [PATCH] fs/locks....
932
933
  	if (new_fl)
  		locks_free_lock(new_fl);
ed9814d85   Jeff Layton   locks: defer free...
934
  	locks_dispose_list(&dispose);
c883da313   Jeff Layton   locks: add tracep...
935
  	trace_flock_lock_inode(inode, request, error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
936
937
  	return error;
  }
b4d629a39   Jeff Layton   locks: rename __p...
938
939
  static int posix_lock_inode(struct inode *inode, struct file_lock *request,
  			    struct file_lock *conflock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
940
  {
bd61e0a9c   Jeff Layton   locks: convert po...
941
  	struct file_lock *fl, *tmp;
39005d022   Miklos Szeredi   [PATCH] locks: do...
942
943
  	struct file_lock *new_fl = NULL;
  	struct file_lock *new_fl2 = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
944
945
  	struct file_lock *left = NULL;
  	struct file_lock *right = NULL;
bd61e0a9c   Jeff Layton   locks: convert po...
946
  	struct file_lock_context *ctx;
b9746ef80   Jeff Layton   locks: make "adde...
947
948
  	int error;
  	bool added = false;
ed9814d85   Jeff Layton   locks: defer free...
949
  	LIST_HEAD(dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
950

5c1c669a1   Jeff Layton   locks: don't allo...
951
  	ctx = locks_get_lock_context(inode, request->fl_type);
bd61e0a9c   Jeff Layton   locks: convert po...
952
  	if (!ctx)
5c1c669a1   Jeff Layton   locks: don't allo...
953
  		return (request->fl_type == F_UNLCK) ? 0 : -ENOMEM;
bd61e0a9c   Jeff Layton   locks: convert po...
954

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
955
956
957
  	/*
  	 * We may need two file_lock structures for this operation,
  	 * so we get them in advance to avoid races.
39005d022   Miklos Szeredi   [PATCH] locks: do...
958
959
  	 *
  	 * In some cases we can be sure, that no new locks will be needed
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
960
  	 */
39005d022   Miklos Szeredi   [PATCH] locks: do...
961
962
963
964
965
966
  	if (!(request->fl_flags & FL_ACCESS) &&
  	    (request->fl_type != F_UNLCK ||
  	     request->fl_start != 0 || request->fl_end != OFFSET_MAX)) {
  		new_fl = locks_alloc_lock();
  		new_fl2 = locks_alloc_lock();
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
967

87709e28d   Peter Zijlstra   fs/locks: Use per...
968
  	percpu_down_read_preempt_disable(&file_rwsem);
6109c8503   Jeff Layton   locks: add a dedi...
969
  	spin_lock(&ctx->flc_lock);
1cb360125   Jeff Layton   locks: comment cl...
970
971
972
  	/*
  	 * New lock request. Walk all POSIX locks and look for conflicts. If
  	 * there are any, either return error or put the request on the
48f741865   Jeff Layton   locks: turn the b...
973
  	 * blocker's list of waiters and the global blocked_hash.
1cb360125   Jeff Layton   locks: comment cl...
974
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
975
  	if (request->fl_type != F_UNLCK) {
bd61e0a9c   Jeff Layton   locks: convert po...
976
  		list_for_each_entry(fl, &ctx->flc_posix, fl_list) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
977
978
  			if (!posix_locks_conflict(request, fl))
  				continue;
5842add2f   Andy Adamson   [PATCH] VFS,fs/lo...
979
  			if (conflock)
3fe0fff18   Kinglong Mee   locks: Rename __l...
980
  				locks_copy_conflock(conflock, fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
981
982
983
  			error = -EAGAIN;
  			if (!(request->fl_flags & FL_SLEEP))
  				goto out;
1c8c601a8   Jeff Layton   locks: protect mo...
984
985
986
987
  			/*
  			 * Deadlock detection and insertion into the blocked
  			 * locks list must be done while holding the same lock!
  			 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
988
  			error = -EDEADLK;
7b2296afb   Jeff Layton   locks: give the b...
989
  			spin_lock(&blocked_lock_lock);
1c8c601a8   Jeff Layton   locks: protect mo...
990
991
992
993
  			if (likely(!posix_locks_deadlock(request, fl))) {
  				error = FILE_LOCK_DEFERRED;
  				__locks_insert_block(fl, request);
  			}
7b2296afb   Jeff Layton   locks: give the b...
994
  			spin_unlock(&blocked_lock_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
995
996
997
998
999
1000
1001
1002
  			goto out;
    		}
    	}
  
  	/* If we're just looking for a conflict, we're done. */
  	error = 0;
  	if (request->fl_flags & FL_ACCESS)
  		goto out;
bd61e0a9c   Jeff Layton   locks: convert po...
1003
1004
1005
1006
  	/* Find the first old lock with the same owner as the new lock */
  	list_for_each_entry(fl, &ctx->flc_posix, fl_list) {
  		if (posix_same_owner(request, fl))
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1007
  	}
1cb360125   Jeff Layton   locks: comment cl...
1008
  	/* Process locks with this owner. */
bd61e0a9c   Jeff Layton   locks: convert po...
1009
1010
1011
1012
1013
  	list_for_each_entry_safe_from(fl, tmp, &ctx->flc_posix, fl_list) {
  		if (!posix_same_owner(request, fl))
  			break;
  
  		/* Detect adjacent or overlapping regions (if same lock type) */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1014
  		if (request->fl_type == fl->fl_type) {
449231d6d   Olaf Kirch   From: Olaf Kirch ...
1015
1016
1017
1018
  			/* In all comparisons of start vs end, use
  			 * "start - 1" rather than "end + 1". If end
  			 * is OFFSET_MAX, end + 1 will become negative.
  			 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1019
  			if (fl->fl_end < request->fl_start - 1)
bd61e0a9c   Jeff Layton   locks: convert po...
1020
  				continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1021
1022
1023
  			/* If the next lock in the list has entirely bigger
  			 * addresses than the new one, insert the lock here.
  			 */
449231d6d   Olaf Kirch   From: Olaf Kirch ...
1024
  			if (fl->fl_start - 1 > request->fl_end)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
  				break;
  
  			/* If we come here, the new and old lock are of the
  			 * same type and adjacent or overlapping. Make one
  			 * lock yielding from the lower start address of both
  			 * locks to the higher end address.
  			 */
  			if (fl->fl_start > request->fl_start)
  				fl->fl_start = request->fl_start;
  			else
  				request->fl_start = fl->fl_start;
  			if (fl->fl_end < request->fl_end)
  				fl->fl_end = request->fl_end;
  			else
  				request->fl_end = fl->fl_end;
  			if (added) {
e084c1bd4   Jeff Layton   Revert "locks: ke...
1041
  				locks_delete_lock_ctx(fl, &dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1042
1043
1044
  				continue;
  			}
  			request = fl;
b9746ef80   Jeff Layton   locks: make "adde...
1045
  			added = true;
bd61e0a9c   Jeff Layton   locks: convert po...
1046
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1047
1048
1049
1050
  			/* Processing for different lock types is a bit
  			 * more complex.
  			 */
  			if (fl->fl_end < request->fl_start)
bd61e0a9c   Jeff Layton   locks: convert po...
1051
  				continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1052
1053
1054
  			if (fl->fl_start > request->fl_end)
  				break;
  			if (request->fl_type == F_UNLCK)
b9746ef80   Jeff Layton   locks: make "adde...
1055
  				added = true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
  			if (fl->fl_start < request->fl_start)
  				left = fl;
  			/* If the next lock in the list has a higher end
  			 * address than the new one, insert the new one here.
  			 */
  			if (fl->fl_end > request->fl_end) {
  				right = fl;
  				break;
  			}
  			if (fl->fl_start >= request->fl_start) {
  				/* The new lock completely replaces an old
  				 * one (This may happen several times).
  				 */
  				if (added) {
e084c1bd4   Jeff Layton   Revert "locks: ke...
1070
  					locks_delete_lock_ctx(fl, &dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1071
1072
  					continue;
  				}
b84d49f94   Jeff Layton   locks: don't reus...
1073
1074
1075
1076
1077
1078
  				/*
  				 * Replace the old lock with new_fl, and
  				 * remove the old one. It's safe to do the
  				 * insert here since we know that we won't be
  				 * using new_fl later, and that the lock is
  				 * just replacing an existing lock.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1079
  				 */
b84d49f94   Jeff Layton   locks: don't reus...
1080
1081
1082
1083
1084
1085
  				error = -ENOLCK;
  				if (!new_fl)
  					goto out;
  				locks_copy_lock(new_fl, request);
  				request = new_fl;
  				new_fl = NULL;
e084c1bd4   Jeff Layton   Revert "locks: ke...
1086
1087
  				locks_insert_lock_ctx(request, &fl->fl_list);
  				locks_delete_lock_ctx(fl, &dispose);
b9746ef80   Jeff Layton   locks: make "adde...
1088
  				added = true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1089
1090
  			}
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1091
  	}
0d9a490ab   Miklos Szeredi   [PATCH] locks: do...
1092
  	/*
1cb360125   Jeff Layton   locks: comment cl...
1093
1094
1095
  	 * The above code only modifies existing locks in case of merging or
  	 * replacing. If new lock(s) need to be inserted all modifications are
  	 * done below this, so it's safe yet to bail out.
0d9a490ab   Miklos Szeredi   [PATCH] locks: do...
1096
1097
1098
1099
  	 */
  	error = -ENOLCK; /* "no luck" */
  	if (right && left == right && !new_fl2)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1100
1101
  	error = 0;
  	if (!added) {
f475ae957   Trond Myklebust   VFS: Allow caller...
1102
1103
1104
  		if (request->fl_type == F_UNLCK) {
  			if (request->fl_flags & FL_EXISTS)
  				error = -ENOENT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1105
  			goto out;
f475ae957   Trond Myklebust   VFS: Allow caller...
1106
  		}
0d9a490ab   Miklos Szeredi   [PATCH] locks: do...
1107
1108
1109
1110
1111
  
  		if (!new_fl) {
  			error = -ENOLCK;
  			goto out;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1112
  		locks_copy_lock(new_fl, request);
e084c1bd4   Jeff Layton   Revert "locks: ke...
1113
  		locks_insert_lock_ctx(new_fl, &fl->fl_list);
2e2f756f8   Jeff Layton   locks: fix list i...
1114
  		fl = new_fl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
  		new_fl = NULL;
  	}
  	if (right) {
  		if (left == right) {
  			/* The new lock breaks the old one in two pieces,
  			 * so we have to use the second new lock.
  			 */
  			left = new_fl2;
  			new_fl2 = NULL;
  			locks_copy_lock(left, right);
e084c1bd4   Jeff Layton   Revert "locks: ke...
1125
  			locks_insert_lock_ctx(left, &fl->fl_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1126
1127
1128
1129
1130
1131
1132
1133
1134
  		}
  		right->fl_start = request->fl_end + 1;
  		locks_wake_up_blocks(right);
  	}
  	if (left) {
  		left->fl_end = request->fl_start - 1;
  		locks_wake_up_blocks(left);
  	}
   out:
6109c8503   Jeff Layton   locks: add a dedi...
1135
  	spin_unlock(&ctx->flc_lock);
87709e28d   Peter Zijlstra   fs/locks: Use per...
1136
  	percpu_up_read_preempt_enable(&file_rwsem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1137
1138
1139
1140
1141
1142
1143
  	/*
  	 * Free any unused locks.
  	 */
  	if (new_fl)
  		locks_free_lock(new_fl);
  	if (new_fl2)
  		locks_free_lock(new_fl2);
ed9814d85   Jeff Layton   locks: defer free...
1144
  	locks_dispose_list(&dispose);
1890910fd   Jeff Layton   locks: sprinkle s...
1145
  	trace_posix_lock_inode(inode, request, error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1146
1147
1148
1149
1150
1151
1152
  	return error;
  }
  
  /**
   * posix_lock_file - Apply a POSIX-style lock to a file
   * @filp: The file to apply the lock to
   * @fl: The lock to be applied
150b39345   Marc Eshel   locks: allow {vfs...
1153
   * @conflock: Place to return a copy of the conflicting lock, if found.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1154
1155
1156
1157
   *
   * Add a POSIX style lock to a file.
   * We merge adjacent & overlapping locks whenever possible.
   * POSIX locks are sorted by owner task, then by starting address
f475ae957   Trond Myklebust   VFS: Allow caller...
1158
1159
1160
1161
   *
   * Note that if called with an FL_EXISTS argument, the caller may determine
   * whether or not a lock was successfully freed by testing the return
   * value for -ENOENT.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1162
   */
150b39345   Marc Eshel   locks: allow {vfs...
1163
  int posix_lock_file(struct file *filp, struct file_lock *fl,
5842add2f   Andy Adamson   [PATCH] VFS,fs/lo...
1164
1165
  			struct file_lock *conflock)
  {
c568d6834   Miklos Szeredi   locks: fix file l...
1166
  	return posix_lock_inode(locks_inode(filp), fl, conflock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1167
  }
150b39345   Marc Eshel   locks: allow {vfs...
1168
  EXPORT_SYMBOL(posix_lock_file);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1169
1170
  
  /**
29d01b22e   Jeff Layton   locks: new helper...
1171
1172
   * posix_lock_inode_wait - Apply a POSIX-style lock to a file
   * @inode: inode of file to which lock request should be applied
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1173
1174
   * @fl: The lock to be applied
   *
616fb38fa   Benjamin Coddington   locks: cleanup po...
1175
   * Apply a POSIX style lock request to an inode.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1176
   */
616fb38fa   Benjamin Coddington   locks: cleanup po...
1177
  static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1178
1179
1180
1181
  {
  	int error;
  	might_sleep ();
  	for (;;) {
b4d629a39   Jeff Layton   locks: rename __p...
1182
  		error = posix_lock_inode(inode, fl, NULL);
bde74e4bc   Miklos Szeredi   locks: add specia...
1183
  		if (error != FILE_LOCK_DEFERRED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
  			break;
  		error = wait_event_interruptible(fl->fl_wait, !fl->fl_next);
  		if (!error)
  			continue;
  
  		locks_delete_block(fl);
  		break;
  	}
  	return error;
  }
29d01b22e   Jeff Layton   locks: new helper...
1194

9e8925b67   Jeff Layton   locks: Allow disa...
1195
  #ifdef CONFIG_MANDATORY_FILE_LOCKING
29d01b22e   Jeff Layton   locks: new helper...
1196
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1197
   * locks_mandatory_locked - Check for an active lock
d7a06983a   Jeff Layton   locks: fix locks_...
1198
   * @file: the file to check
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1199
1200
1201
1202
   *
   * Searches the inode's list of locks to find any POSIX locks which conflict.
   * This function is called from locks_verify_locked() only.
   */
d7a06983a   Jeff Layton   locks: fix locks_...
1203
  int locks_mandatory_locked(struct file *file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1204
  {
bd61e0a9c   Jeff Layton   locks: convert po...
1205
  	int ret;
c568d6834   Miklos Szeredi   locks: fix file l...
1206
  	struct inode *inode = locks_inode(file);
bd61e0a9c   Jeff Layton   locks: convert po...
1207
  	struct file_lock_context *ctx;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1208
  	struct file_lock *fl;
128a37852   Dmitry Vyukov   fs: fix data race...
1209
  	ctx = smp_load_acquire(&inode->i_flctx);
bd61e0a9c   Jeff Layton   locks: convert po...
1210
1211
  	if (!ctx || list_empty_careful(&ctx->flc_posix))
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1212
1213
1214
  	/*
  	 * Search the lock list for this inode for any POSIX locks.
  	 */
6109c8503   Jeff Layton   locks: add a dedi...
1215
  	spin_lock(&ctx->flc_lock);
bd61e0a9c   Jeff Layton   locks: convert po...
1216
1217
  	ret = 0;
  	list_for_each_entry(fl, &ctx->flc_posix, fl_list) {
73a8f5f7e   Christoph Hellwig   locks: purge fl_o...
1218
  		if (fl->fl_owner != current->files &&
bd61e0a9c   Jeff Layton   locks: convert po...
1219
1220
  		    fl->fl_owner != file) {
  			ret = -EAGAIN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1221
  			break;
bd61e0a9c   Jeff Layton   locks: convert po...
1222
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1223
  	}
6109c8503   Jeff Layton   locks: add a dedi...
1224
  	spin_unlock(&ctx->flc_lock);
bd61e0a9c   Jeff Layton   locks: convert po...
1225
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1226
1227
1228
1229
  }
  
  /**
   * locks_mandatory_area - Check for a conflicting lock
acc15575e   Christoph Hellwig   locks: new locks_...
1230
   * @inode:	the file to check
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1231
   * @filp:       how the file was opened (if it was)
acc15575e   Christoph Hellwig   locks: new locks_...
1232
1233
1234
   * @start:	first byte in the file to check
   * @end:	lastbyte in the file to check
   * @type:	%F_WRLCK for a write lock, else %F_RDLCK
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1235
1236
   *
   * Searches the inode's list of locks to find any POSIX locks which conflict.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1237
   */
acc15575e   Christoph Hellwig   locks: new locks_...
1238
1239
  int locks_mandatory_area(struct inode *inode, struct file *filp, loff_t start,
  			 loff_t end, unsigned char type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1240
1241
1242
  {
  	struct file_lock fl;
  	int error;
29723adee   Jeff Layton   locks: make locks...
1243
  	bool sleep = false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1244
1245
  
  	locks_init_lock(&fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1246
1247
1248
1249
  	fl.fl_pid = current->tgid;
  	fl.fl_file = filp;
  	fl.fl_flags = FL_POSIX | FL_ACCESS;
  	if (filp && !(filp->f_flags & O_NONBLOCK))
29723adee   Jeff Layton   locks: make locks...
1250
  		sleep = true;
acc15575e   Christoph Hellwig   locks: new locks_...
1251
1252
1253
  	fl.fl_type = type;
  	fl.fl_start = start;
  	fl.fl_end = end;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1254
1255
  
  	for (;;) {
29723adee   Jeff Layton   locks: make locks...
1256
  		if (filp) {
73a8f5f7e   Christoph Hellwig   locks: purge fl_o...
1257
  			fl.fl_owner = filp;
29723adee   Jeff Layton   locks: make locks...
1258
  			fl.fl_flags &= ~FL_SLEEP;
b4d629a39   Jeff Layton   locks: rename __p...
1259
  			error = posix_lock_inode(inode, &fl, NULL);
29723adee   Jeff Layton   locks: make locks...
1260
1261
1262
1263
1264
1265
1266
  			if (!error)
  				break;
  		}
  
  		if (sleep)
  			fl.fl_flags |= FL_SLEEP;
  		fl.fl_owner = current->files;
b4d629a39   Jeff Layton   locks: rename __p...
1267
  		error = posix_lock_inode(inode, &fl, NULL);
bde74e4bc   Miklos Szeredi   locks: add specia...
1268
  		if (error != FILE_LOCK_DEFERRED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1269
1270
1271
1272
1273
1274
1275
  			break;
  		error = wait_event_interruptible(fl.fl_wait, !fl.fl_next);
  		if (!error) {
  			/*
  			 * If we've been sleeping someone might have
  			 * changed the permissions behind our back.
  			 */
a16877ca9   Pavel Emelyanov   Cleanup macros fo...
1276
  			if (__mandatory_lock(inode))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
  				continue;
  		}
  
  		locks_delete_block(&fl);
  		break;
  	}
  
  	return error;
  }
  
  EXPORT_SYMBOL(locks_mandatory_area);
9e8925b67   Jeff Layton   locks: Allow disa...
1288
  #endif /* CONFIG_MANDATORY_FILE_LOCKING */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1289

778fc546f   J. Bruce Fields   locks: fix tracki...
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
  static void lease_clear_pending(struct file_lock *fl, int arg)
  {
  	switch (arg) {
  	case F_UNLCK:
  		fl->fl_flags &= ~FL_UNLOCK_PENDING;
  		/* fall through: */
  	case F_RDLCK:
  		fl->fl_flags &= ~FL_DOWNGRADE_PENDING;
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1300
  /* We already had a lease on this file; just change its type */
7448cc37b   Jeff Layton   locks: clean up t...
1301
  int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1302
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1303
1304
1305
1306
  	int error = assign_type(fl, arg);
  
  	if (error)
  		return error;
778fc546f   J. Bruce Fields   locks: fix tracki...
1307
  	lease_clear_pending(fl, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1308
  	locks_wake_up_blocks(fl);
3b6e2723f   Filipe Brandenburger   locks: prevent si...
1309
1310
1311
1312
1313
  	if (arg == F_UNLCK) {
  		struct file *filp = fl->fl_file;
  
  		f_delown(filp);
  		filp->f_owner.signum = 0;
96d6d59ce   J. Bruce Fields   locks: move lease...
1314
1315
1316
1317
1318
1319
  		fasync_helper(0, fl->fl_file, 0, &fl->fl_fasync);
  		if (fl->fl_fasync != NULL) {
  			printk(KERN_ERR "locks_delete_lock: fasync == %p
  ", fl->fl_fasync);
  			fl->fl_fasync = NULL;
  		}
e084c1bd4   Jeff Layton   Revert "locks: ke...
1320
  		locks_delete_lock_ctx(fl, dispose);
3b6e2723f   Filipe Brandenburger   locks: prevent si...
1321
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1322
1323
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1324
  EXPORT_SYMBOL(lease_modify);
778fc546f   J. Bruce Fields   locks: fix tracki...
1325
1326
1327
1328
1329
1330
1331
  static bool past_time(unsigned long then)
  {
  	if (!then)
  		/* 0 is a special value meaning "this never expires": */
  		return false;
  	return time_after(jiffies, then);
  }
c45198eda   Jeff Layton   locks: move freei...
1332
  static void time_out_leases(struct inode *inode, struct list_head *dispose)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1333
  {
8634b51f6   Jeff Layton   locks: convert le...
1334
1335
  	struct file_lock_context *ctx = inode->i_flctx;
  	struct file_lock *fl, *tmp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1336

6109c8503   Jeff Layton   locks: add a dedi...
1337
  	lockdep_assert_held(&ctx->flc_lock);
f82b4b678   Jeff Layton   locks: move i_loc...
1338

8634b51f6   Jeff Layton   locks: convert le...
1339
  	list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list) {
62af4f1f7   Jeff Layton   locks: add some t...
1340
  		trace_time_out_leases(inode, fl);
778fc546f   J. Bruce Fields   locks: fix tracki...
1341
  		if (past_time(fl->fl_downgrade_time))
7448cc37b   Jeff Layton   locks: clean up t...
1342
  			lease_modify(fl, F_RDLCK, dispose);
778fc546f   J. Bruce Fields   locks: fix tracki...
1343
  		if (past_time(fl->fl_break_time))
7448cc37b   Jeff Layton   locks: clean up t...
1344
  			lease_modify(fl, F_UNLCK, dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1345
1346
  	}
  }
df4e8d2c1   J. Bruce Fields   locks: implement ...
1347
1348
  static bool leases_conflict(struct file_lock *lease, struct file_lock *breaker)
  {
11afe9f76   Christoph Hellwig   fs: add FL_LAYOUT...
1349
1350
  	if ((breaker->fl_flags & FL_LAYOUT) != (lease->fl_flags & FL_LAYOUT))
  		return false;
df4e8d2c1   J. Bruce Fields   locks: implement ...
1351
1352
1353
1354
  	if ((breaker->fl_flags & FL_DELEG) && (lease->fl_flags & FL_LEASE))
  		return false;
  	return locks_conflict(breaker, lease);
  }
03d12ddf8   Jeff Layton   locks: __break_le...
1355
1356
1357
  static bool
  any_leases_conflict(struct inode *inode, struct file_lock *breaker)
  {
8634b51f6   Jeff Layton   locks: convert le...
1358
  	struct file_lock_context *ctx = inode->i_flctx;
03d12ddf8   Jeff Layton   locks: __break_le...
1359
  	struct file_lock *fl;
6109c8503   Jeff Layton   locks: add a dedi...
1360
  	lockdep_assert_held(&ctx->flc_lock);
03d12ddf8   Jeff Layton   locks: __break_le...
1361

8634b51f6   Jeff Layton   locks: convert le...
1362
  	list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
03d12ddf8   Jeff Layton   locks: __break_le...
1363
1364
1365
1366
1367
  		if (leases_conflict(fl, breaker))
  			return true;
  	}
  	return false;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1368
1369
1370
  /**
   *	__break_lease	-	revoke all outstanding leases on file
   *	@inode: the inode of the file to return
df4e8d2c1   J. Bruce Fields   locks: implement ...
1371
1372
1373
1374
   *	@mode: O_RDONLY: break only write leases; O_WRONLY or O_RDWR:
   *	    break all leases
   *	@type: FL_LEASE: break leases and delegations; FL_DELEG: break
   *	    only delegations
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1375
   *
87250dd26   david m. richter   leases: minor bre...
1376
1377
1378
   *	break_lease (inlined for speed) has checked there already is at least
   *	some kind of lock (maybe a lease) on this file.  Leases are broken on
   *	a call to open() or truncate().  This function can sleep unless you
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1379
1380
   *	specified %O_NONBLOCK to your open().
   */
df4e8d2c1   J. Bruce Fields   locks: implement ...
1381
  int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1382
  {
778fc546f   J. Bruce Fields   locks: fix tracki...
1383
  	int error = 0;
128a37852   Dmitry Vyukov   fs: fix data race...
1384
  	struct file_lock_context *ctx;
a901125c6   Yan, Zheng   locks: fix file_l...
1385
  	struct file_lock *new_fl, *fl, *tmp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1386
  	unsigned long break_time;
8737c9305   Al Viro   Switch may_open()...
1387
  	int want_write = (mode & O_ACCMODE) != O_RDONLY;
c45198eda   Jeff Layton   locks: move freei...
1388
  	LIST_HEAD(dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1389

8737c9305   Al Viro   Switch may_open()...
1390
  	new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK);
6d4b9e38d   Linus Torvalds   vfs: fix handling...
1391
1392
  	if (IS_ERR(new_fl))
  		return PTR_ERR(new_fl);
df4e8d2c1   J. Bruce Fields   locks: implement ...
1393
  	new_fl->fl_flags = type;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1394

8634b51f6   Jeff Layton   locks: convert le...
1395
  	/* typically we will check that ctx is non-NULL before calling */
128a37852   Dmitry Vyukov   fs: fix data race...
1396
  	ctx = smp_load_acquire(&inode->i_flctx);
8634b51f6   Jeff Layton   locks: convert le...
1397
1398
1399
1400
  	if (!ctx) {
  		WARN_ON_ONCE(1);
  		return error;
  	}
87709e28d   Peter Zijlstra   fs/locks: Use per...
1401
  	percpu_down_read_preempt_disable(&file_rwsem);
6109c8503   Jeff Layton   locks: add a dedi...
1402
  	spin_lock(&ctx->flc_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1403

c45198eda   Jeff Layton   locks: move freei...
1404
  	time_out_leases(inode, &dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1405

03d12ddf8   Jeff Layton   locks: __break_le...
1406
  	if (!any_leases_conflict(inode, new_fl))
778fc546f   J. Bruce Fields   locks: fix tracki...
1407
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1408
1409
1410
1411
1412
1413
  	break_time = 0;
  	if (lease_break_time > 0) {
  		break_time = jiffies + lease_break_time * HZ;
  		if (break_time == 0)
  			break_time++;	/* so that 0 means no break time */
  	}
a901125c6   Yan, Zheng   locks: fix file_l...
1414
  	list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list) {
df4e8d2c1   J. Bruce Fields   locks: implement ...
1415
1416
  		if (!leases_conflict(fl, new_fl))
  			continue;
778fc546f   J. Bruce Fields   locks: fix tracki...
1417
1418
1419
1420
  		if (want_write) {
  			if (fl->fl_flags & FL_UNLOCK_PENDING)
  				continue;
  			fl->fl_flags |= FL_UNLOCK_PENDING;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1421
  			fl->fl_break_time = break_time;
778fc546f   J. Bruce Fields   locks: fix tracki...
1422
  		} else {
8634b51f6   Jeff Layton   locks: convert le...
1423
  			if (lease_breaking(fl))
778fc546f   J. Bruce Fields   locks: fix tracki...
1424
1425
1426
  				continue;
  			fl->fl_flags |= FL_DOWNGRADE_PENDING;
  			fl->fl_downgrade_time = break_time;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1427
  		}
4d01b7f5e   Jeff Layton   locks: give lm_br...
1428
  		if (fl->fl_lmops->lm_break(fl))
e084c1bd4   Jeff Layton   Revert "locks: ke...
1429
  			locks_delete_lock_ctx(fl, &dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1430
  	}
8634b51f6   Jeff Layton   locks: convert le...
1431
  	if (list_empty(&ctx->flc_lease))
4d01b7f5e   Jeff Layton   locks: give lm_br...
1432
  		goto out;
843c6b2f4   Jeff Layton   locks: remove i_h...
1433
  	if (mode & O_NONBLOCK) {
62af4f1f7   Jeff Layton   locks: add some t...
1434
  		trace_break_lease_noblock(inode, new_fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1435
1436
1437
1438
1439
  		error = -EWOULDBLOCK;
  		goto out;
  	}
  
  restart:
8634b51f6   Jeff Layton   locks: convert le...
1440
1441
  	fl = list_first_entry(&ctx->flc_lease, struct file_lock, fl_list);
  	break_time = fl->fl_break_time;
f1c6bb2cb   Jeff Layton   locks: allow __br...
1442
  	if (break_time != 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1443
  		break_time -= jiffies;
f1c6bb2cb   Jeff Layton   locks: allow __br...
1444
1445
  	if (break_time == 0)
  		break_time++;
8634b51f6   Jeff Layton   locks: convert le...
1446
  	locks_insert_block(fl, new_fl);
62af4f1f7   Jeff Layton   locks: add some t...
1447
  	trace_break_lease_block(inode, new_fl);
6109c8503   Jeff Layton   locks: add a dedi...
1448
  	spin_unlock(&ctx->flc_lock);
87709e28d   Peter Zijlstra   fs/locks: Use per...
1449
  	percpu_up_read_preempt_enable(&file_rwsem);
aba376607   Peter Zijlstra   fs/locks: Replace...
1450

c45198eda   Jeff Layton   locks: move freei...
1451
  	locks_dispose_list(&dispose);
4321e01e7   Matthew Wilcox   file locks: Use w...
1452
1453
  	error = wait_event_interruptible_timeout(new_fl->fl_wait,
  						!new_fl->fl_next, break_time);
aba376607   Peter Zijlstra   fs/locks: Replace...
1454

87709e28d   Peter Zijlstra   fs/locks: Use per...
1455
  	percpu_down_read_preempt_disable(&file_rwsem);
6109c8503   Jeff Layton   locks: add a dedi...
1456
  	spin_lock(&ctx->flc_lock);
62af4f1f7   Jeff Layton   locks: add some t...
1457
  	trace_break_lease_unblock(inode, new_fl);
1c8c601a8   Jeff Layton   locks: protect mo...
1458
  	locks_delete_block(new_fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1459
  	if (error >= 0) {
778fc546f   J. Bruce Fields   locks: fix tracki...
1460
1461
1462
1463
  		/*
  		 * Wait for the next conflicting lease that has not been
  		 * broken yet
  		 */
03d12ddf8   Jeff Layton   locks: __break_le...
1464
1465
1466
1467
  		if (error == 0)
  			time_out_leases(inode, &dispose);
  		if (any_leases_conflict(inode, new_fl))
  			goto restart;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1468
1469
  		error = 0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1470
  out:
6109c8503   Jeff Layton   locks: add a dedi...
1471
  	spin_unlock(&ctx->flc_lock);
87709e28d   Peter Zijlstra   fs/locks: Use per...
1472
  	percpu_up_read_preempt_enable(&file_rwsem);
c45198eda   Jeff Layton   locks: move freei...
1473
  	locks_dispose_list(&dispose);
6d4b9e38d   Linus Torvalds   vfs: fix handling...
1474
  	locks_free_lock(new_fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1475
1476
1477
1478
1479
1480
  	return error;
  }
  
  EXPORT_SYMBOL(__break_lease);
  
  /**
76c479480   Amir Goldstein   nfsd: encode stat...
1481
   *	lease_get_mtime - update modified time of an inode with exclusive lease
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1482
   *	@inode: the inode
76c479480   Amir Goldstein   nfsd: encode stat...
1483
   *      @time:  pointer to a timespec which contains the last modified time
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1484
1485
1486
   *
   * This is to force NFS clients to flush their caches for files with
   * exclusive leases.  The justification is that if someone has an
a6b91919e   Randy Dunlap   fs: fix kernel-do...
1487
   * exclusive lease, then they could be modifying it.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1488
   */
95582b008   Deepa Dinamani   vfs: change inode...
1489
  void lease_get_mtime(struct inode *inode, struct timespec64 *time)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1490
  {
bfe860243   Jeff Layton   locks: close pote...
1491
  	bool has_lease = false;
128a37852   Dmitry Vyukov   fs: fix data race...
1492
  	struct file_lock_context *ctx;
8634b51f6   Jeff Layton   locks: convert le...
1493
  	struct file_lock *fl;
bfe860243   Jeff Layton   locks: close pote...
1494

128a37852   Dmitry Vyukov   fs: fix data race...
1495
  	ctx = smp_load_acquire(&inode->i_flctx);
8634b51f6   Jeff Layton   locks: convert le...
1496
  	if (ctx && !list_empty_careful(&ctx->flc_lease)) {
6109c8503   Jeff Layton   locks: add a dedi...
1497
  		spin_lock(&ctx->flc_lock);
8ace5dfb9   Geliang Tang   locks: use list_f...
1498
1499
1500
1501
  		fl = list_first_entry_or_null(&ctx->flc_lease,
  					      struct file_lock, fl_list);
  		if (fl && (fl->fl_type == F_WRLCK))
  			has_lease = true;
6109c8503   Jeff Layton   locks: add a dedi...
1502
  		spin_unlock(&ctx->flc_lock);
bfe860243   Jeff Layton   locks: close pote...
1503
1504
1505
  	}
  
  	if (has_lease)
c2050a454   Deepa Dinamani   fs: Replace curre...
1506
  		*time = current_time(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
  }
  
  EXPORT_SYMBOL(lease_get_mtime);
  
  /**
   *	fcntl_getlease - Enquire what lease is currently active
   *	@filp: the file
   *
   *	The value returned by this function will be one of
   *	(if no lease break is pending):
   *
   *	%F_RDLCK to indicate a shared lease is held.
   *
   *	%F_WRLCK to indicate an exclusive lease is held.
   *
   *	%F_UNLCK to indicate no lease is held.
   *
   *	(if a lease break is pending):
   *
   *	%F_RDLCK to indicate an exclusive lease needs to be
   *		changed to a shared lease (or removed).
   *
   *	%F_UNLCK to indicate the lease needs to be removed.
   *
   *	XXX: sfr & willy disagree over whether F_INPROGRESS
   *	should be returned to userspace.
   */
  int fcntl_getlease(struct file *filp)
  {
  	struct file_lock *fl;
c568d6834   Miklos Szeredi   locks: fix file l...
1537
  	struct inode *inode = locks_inode(filp);
128a37852   Dmitry Vyukov   fs: fix data race...
1538
  	struct file_lock_context *ctx;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1539
  	int type = F_UNLCK;
c45198eda   Jeff Layton   locks: move freei...
1540
  	LIST_HEAD(dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1541

128a37852   Dmitry Vyukov   fs: fix data race...
1542
  	ctx = smp_load_acquire(&inode->i_flctx);
8634b51f6   Jeff Layton   locks: convert le...
1543
  	if (ctx && !list_empty_careful(&ctx->flc_lease)) {
5f43086bb   Peter Zijlstra   locking, fs/locks...
1544
  		percpu_down_read_preempt_disable(&file_rwsem);
6109c8503   Jeff Layton   locks: add a dedi...
1545
  		spin_lock(&ctx->flc_lock);
c568d6834   Miklos Szeredi   locks: fix file l...
1546
  		time_out_leases(inode, &dispose);
8634b51f6   Jeff Layton   locks: convert le...
1547
1548
1549
  		list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
  			if (fl->fl_file != filp)
  				continue;
778fc546f   J. Bruce Fields   locks: fix tracki...
1550
  			type = target_leasetype(fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1551
1552
  			break;
  		}
6109c8503   Jeff Layton   locks: add a dedi...
1553
  		spin_unlock(&ctx->flc_lock);
5f43086bb   Peter Zijlstra   locking, fs/locks...
1554
  		percpu_up_read_preempt_enable(&file_rwsem);
8634b51f6   Jeff Layton   locks: convert le...
1555
  		locks_dispose_list(&dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1556
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1557
1558
  	return type;
  }
24cbe7845   Jeff Layton   locks: close pote...
1559
1560
1561
1562
1563
1564
  /**
   * check_conflicting_open - see if the given dentry points to a file that has
   * 			    an existing open that would conflict with the
   * 			    desired lease.
   * @dentry:	dentry to check
   * @arg:	type of lease that we're trying to acquire
7fadc59cc   Randy Dunlap   fs: fix fs/locks....
1565
   * @flags:	current lock flags
24cbe7845   Jeff Layton   locks: close pote...
1566
1567
1568
1569
1570
   *
   * Check to see if there's an existing open fd on this file that would
   * conflict with the lease we're trying to set.
   */
  static int
11afe9f76   Christoph Hellwig   fs: add FL_LAYOUT...
1571
  check_conflicting_open(const struct dentry *dentry, const long arg, int flags)
24cbe7845   Jeff Layton   locks: close pote...
1572
1573
1574
  {
  	int ret = 0;
  	struct inode *inode = dentry->d_inode;
11afe9f76   Christoph Hellwig   fs: add FL_LAYOUT...
1575
1576
  	if (flags & FL_LAYOUT)
  		return 0;
8cf9ee506   Miklos Szeredi   Revert "vfs: do g...
1577
  	if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
24cbe7845   Jeff Layton   locks: close pote...
1578
1579
1580
1581
1582
1583
1584
1585
  		return -EAGAIN;
  
  	if ((arg == F_WRLCK) && ((d_count(dentry) > 1) ||
  	    (atomic_read(&inode->i_count) > 1)))
  		ret = -EAGAIN;
  
  	return ret;
  }
e6f5c7893   Jeff Layton   locks: plumb a "p...
1586
1587
  static int
  generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **priv)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1588
  {
8634b51f6   Jeff Layton   locks: convert le...
1589
  	struct file_lock *fl, *my_fl = NULL, *lease;
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
1590
  	struct dentry *dentry = filp->f_path.dentry;
c568d6834   Miklos Szeredi   locks: fix file l...
1591
  	struct inode *inode = dentry->d_inode;
8634b51f6   Jeff Layton   locks: convert le...
1592
  	struct file_lock_context *ctx;
df4e8d2c1   J. Bruce Fields   locks: implement ...
1593
  	bool is_deleg = (*flp)->fl_flags & FL_DELEG;
c1f24ef4e   J. Bruce Fields   locks: setlease c...
1594
  	int error;
c45198eda   Jeff Layton   locks: move freei...
1595
  	LIST_HEAD(dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1596

096657b65   J. Bruce Fields   locks: fix leaks ...
1597
  	lease = *flp;
62af4f1f7   Jeff Layton   locks: add some t...
1598
  	trace_generic_add_lease(inode, lease);
5c1c669a1   Jeff Layton   locks: don't allo...
1599
1600
  	/* Note that arg is never F_UNLCK here */
  	ctx = locks_get_lock_context(inode, arg);
8634b51f6   Jeff Layton   locks: convert le...
1601
1602
  	if (!ctx)
  		return -ENOMEM;
df4e8d2c1   J. Bruce Fields   locks: implement ...
1603
1604
1605
1606
1607
1608
1609
1610
  	/*
  	 * In the delegation case we need mutual exclusion with
  	 * a number of operations that take the i_mutex.  We trylock
  	 * because delegations are an optional optimization, and if
  	 * there's some chance of a conflict--we'd rather not
  	 * bother, maybe that's a sign this just isn't a good file to
  	 * hand out a delegation on.
  	 */
5955102c9   Al Viro   wrappers for ->i_...
1611
  	if (is_deleg && !inode_trylock(inode))
df4e8d2c1   J. Bruce Fields   locks: implement ...
1612
1613
1614
1615
  		return -EAGAIN;
  
  	if (is_deleg && arg == F_WRLCK) {
  		/* Write delegations are not currently supported: */
5955102c9   Al Viro   wrappers for ->i_...
1616
  		inode_unlock(inode);
df4e8d2c1   J. Bruce Fields   locks: implement ...
1617
1618
1619
  		WARN_ON_ONCE(1);
  		return -EINVAL;
  	}
096657b65   J. Bruce Fields   locks: fix leaks ...
1620

87709e28d   Peter Zijlstra   fs/locks: Use per...
1621
  	percpu_down_read_preempt_disable(&file_rwsem);
6109c8503   Jeff Layton   locks: add a dedi...
1622
  	spin_lock(&ctx->flc_lock);
c45198eda   Jeff Layton   locks: move freei...
1623
  	time_out_leases(inode, &dispose);
11afe9f76   Christoph Hellwig   fs: add FL_LAYOUT...
1624
  	error = check_conflicting_open(dentry, arg, lease->fl_flags);
24cbe7845   Jeff Layton   locks: close pote...
1625
  	if (error)
096657b65   J. Bruce Fields   locks: fix leaks ...
1626
  		goto out;
6d5e8b05c   J. Bruce Fields   locks: share more...
1627

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1628
1629
1630
1631
1632
1633
1634
1635
  	/*
  	 * At this point, we know that if there is an exclusive
  	 * lease on this file, then we hold it on this filp
  	 * (otherwise our open of this file would have blocked).
  	 * And if we are trying to acquire an exclusive lease,
  	 * then the file is not open by anyone (including us)
  	 * except for this filp.
  	 */
c1f24ef4e   J. Bruce Fields   locks: setlease c...
1636
  	error = -EAGAIN;
8634b51f6   Jeff Layton   locks: convert le...
1637
  	list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
2ab99ee12   Christoph Hellwig   fs: track fl_owne...
1638
1639
  		if (fl->fl_file == filp &&
  		    fl->fl_owner == lease->fl_owner) {
8634b51f6   Jeff Layton   locks: convert le...
1640
  			my_fl = fl;
c1f24ef4e   J. Bruce Fields   locks: setlease c...
1641
1642
  			continue;
  		}
8634b51f6   Jeff Layton   locks: convert le...
1643

c1f24ef4e   J. Bruce Fields   locks: setlease c...
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
  		/*
  		 * No exclusive leases if someone else has a lease on
  		 * this file:
  		 */
  		if (arg == F_WRLCK)
  			goto out;
  		/*
  		 * Modifying our existing lease is OK, but no getting a
  		 * new lease if someone else is opening for write:
  		 */
  		if (fl->fl_flags & FL_UNLOCK_PENDING)
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1656
  	}
8634b51f6   Jeff Layton   locks: convert le...
1657
  	if (my_fl != NULL) {
0164bf023   Jeff Layton   locks: fix fasync...
1658
1659
  		lease = my_fl;
  		error = lease->fl_lmops->lm_change(lease, arg, &dispose);
1c7dd2ff4   Jeff Layton   locks: define a l...
1660
1661
1662
  		if (error)
  			goto out;
  		goto out_setup;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1663
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1664
1665
1666
  	error = -EINVAL;
  	if (!leases_enable)
  		goto out;
e084c1bd4   Jeff Layton   Revert "locks: ke...
1667
  	locks_insert_lock_ctx(lease, &ctx->flc_lease);
24cbe7845   Jeff Layton   locks: close pote...
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
  	/*
  	 * The check in break_lease() is lockless. It's possible for another
  	 * open to race in after we did the earlier check for a conflicting
  	 * open but before the lease was inserted. Check again for a
  	 * conflicting open and cancel the lease if there is one.
  	 *
  	 * We also add a barrier here to ensure that the insertion of the lock
  	 * precedes these checks.
  	 */
  	smp_mb();
11afe9f76   Christoph Hellwig   fs: add FL_LAYOUT...
1678
  	error = check_conflicting_open(dentry, arg, lease->fl_flags);
8634b51f6   Jeff Layton   locks: convert le...
1679
  	if (error) {
e084c1bd4   Jeff Layton   Revert "locks: ke...
1680
  		locks_unlink_lock_ctx(lease);
8634b51f6   Jeff Layton   locks: convert le...
1681
1682
  		goto out;
  	}
1c7dd2ff4   Jeff Layton   locks: define a l...
1683
1684
1685
1686
  
  out_setup:
  	if (lease->fl_lmops->lm_setup)
  		lease->fl_lmops->lm_setup(lease, priv);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1687
  out:
6109c8503   Jeff Layton   locks: add a dedi...
1688
  	spin_unlock(&ctx->flc_lock);
87709e28d   Peter Zijlstra   fs/locks: Use per...
1689
  	percpu_up_read_preempt_enable(&file_rwsem);
c45198eda   Jeff Layton   locks: move freei...
1690
  	locks_dispose_list(&dispose);
df4e8d2c1   J. Bruce Fields   locks: implement ...
1691
  	if (is_deleg)
5955102c9   Al Viro   wrappers for ->i_...
1692
  		inode_unlock(inode);
8634b51f6   Jeff Layton   locks: convert le...
1693
  	if (!error && !my_fl)
1c7dd2ff4   Jeff Layton   locks: define a l...
1694
  		*flp = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1695
1696
  	return error;
  }
8335ebd94   J. Bruce Fields   leases: split up ...
1697

2ab99ee12   Christoph Hellwig   fs: track fl_owne...
1698
  static int generic_delete_lease(struct file *filp, void *owner)
8335ebd94   J. Bruce Fields   leases: split up ...
1699
  {
0efaa7e82   Jeff Layton   locks: generic_de...
1700
  	int error = -EAGAIN;
8634b51f6   Jeff Layton   locks: convert le...
1701
  	struct file_lock *fl, *victim = NULL;
c568d6834   Miklos Szeredi   locks: fix file l...
1702
  	struct inode *inode = locks_inode(filp);
128a37852   Dmitry Vyukov   fs: fix data race...
1703
  	struct file_lock_context *ctx;
c45198eda   Jeff Layton   locks: move freei...
1704
  	LIST_HEAD(dispose);
8335ebd94   J. Bruce Fields   leases: split up ...
1705

128a37852   Dmitry Vyukov   fs: fix data race...
1706
  	ctx = smp_load_acquire(&inode->i_flctx);
8634b51f6   Jeff Layton   locks: convert le...
1707
1708
1709
1710
  	if (!ctx) {
  		trace_generic_delete_lease(inode, NULL);
  		return error;
  	}
87709e28d   Peter Zijlstra   fs/locks: Use per...
1711
  	percpu_down_read_preempt_disable(&file_rwsem);
6109c8503   Jeff Layton   locks: add a dedi...
1712
  	spin_lock(&ctx->flc_lock);
8634b51f6   Jeff Layton   locks: convert le...
1713
  	list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
2ab99ee12   Christoph Hellwig   fs: track fl_owne...
1714
1715
  		if (fl->fl_file == filp &&
  		    fl->fl_owner == owner) {
8634b51f6   Jeff Layton   locks: convert le...
1716
  			victim = fl;
0efaa7e82   Jeff Layton   locks: generic_de...
1717
  			break;
8634b51f6   Jeff Layton   locks: convert le...
1718
  		}
8335ebd94   J. Bruce Fields   leases: split up ...
1719
  	}
a9b1b455c   Jeff Layton   locks: fix generi...
1720
  	trace_generic_delete_lease(inode, victim);
8634b51f6   Jeff Layton   locks: convert le...
1721
  	if (victim)
7448cc37b   Jeff Layton   locks: clean up t...
1722
  		error = fl->fl_lmops->lm_change(victim, F_UNLCK, &dispose);
6109c8503   Jeff Layton   locks: add a dedi...
1723
  	spin_unlock(&ctx->flc_lock);
87709e28d   Peter Zijlstra   fs/locks: Use per...
1724
  	percpu_up_read_preempt_enable(&file_rwsem);
c45198eda   Jeff Layton   locks: move freei...
1725
  	locks_dispose_list(&dispose);
0efaa7e82   Jeff Layton   locks: generic_de...
1726
  	return error;
8335ebd94   J. Bruce Fields   leases: split up ...
1727
1728
1729
1730
  }
  
  /**
   *	generic_setlease	-	sets a lease on an open file
1c7dd2ff4   Jeff Layton   locks: define a l...
1731
1732
1733
1734
1735
   *	@filp:	file pointer
   *	@arg:	type of lease to obtain
   *	@flp:	input - file_lock to use, output - file_lock inserted
   *	@priv:	private data for lm_setup (may be NULL if lm_setup
   *		doesn't require it)
8335ebd94   J. Bruce Fields   leases: split up ...
1736
1737
1738
   *
   *	The (input) flp->fl_lmops->lm_break function is required
   *	by break_lease().
8335ebd94   J. Bruce Fields   leases: split up ...
1739
   */
e6f5c7893   Jeff Layton   locks: plumb a "p...
1740
1741
  int generic_setlease(struct file *filp, long arg, struct file_lock **flp,
  			void **priv)
8335ebd94   J. Bruce Fields   leases: split up ...
1742
  {
c568d6834   Miklos Szeredi   locks: fix file l...
1743
  	struct inode *inode = locks_inode(filp);
8335ebd94   J. Bruce Fields   leases: split up ...
1744
  	int error;
8e96e3b7b   Eric W. Biederman   userns: Use uid_e...
1745
  	if ((!uid_eq(current_fsuid(), inode->i_uid)) && !capable(CAP_LEASE))
8335ebd94   J. Bruce Fields   leases: split up ...
1746
1747
1748
1749
1750
1751
  		return -EACCES;
  	if (!S_ISREG(inode->i_mode))
  		return -EINVAL;
  	error = security_file_lock(filp, arg);
  	if (error)
  		return error;
8335ebd94   J. Bruce Fields   leases: split up ...
1752
1753
  	switch (arg) {
  	case F_UNLCK:
2ab99ee12   Christoph Hellwig   fs: track fl_owne...
1754
  		return generic_delete_lease(filp, *priv);
8335ebd94   J. Bruce Fields   leases: split up ...
1755
1756
  	case F_RDLCK:
  	case F_WRLCK:
0efaa7e82   Jeff Layton   locks: generic_de...
1757
1758
1759
1760
  		if (!(*flp)->fl_lmops->lm_break) {
  			WARN_ON_ONCE(1);
  			return -ENOLCK;
  		}
11afe9f76   Christoph Hellwig   fs: add FL_LAYOUT...
1761

e6f5c7893   Jeff Layton   locks: plumb a "p...
1762
  		return generic_add_lease(filp, arg, flp, priv);
8335ebd94   J. Bruce Fields   leases: split up ...
1763
  	default:
8d657eb3b   Dave Jones   Remove easily use...
1764
  		return -EINVAL;
8335ebd94   J. Bruce Fields   leases: split up ...
1765
1766
  	}
  }
0af1a4504   Christoph Hellwig   rename setlease t...
1767
  EXPORT_SYMBOL(generic_setlease);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1768

b89f43213   Arnd Bergmann   fs/locks.c: prepa...
1769
  /**
e51673aa5   Jeff Layton   locks: clean up v...
1770
   * vfs_setlease        -       sets a lease on an open file
1c7dd2ff4   Jeff Layton   locks: define a l...
1771
1772
1773
1774
1775
   * @filp:	file pointer
   * @arg:	type of lease to obtain
   * @lease:	file_lock to use when adding a lease
   * @priv:	private info for lm_setup when adding a lease (may be
   * 		NULL if lm_setup doesn't require it)
e51673aa5   Jeff Layton   locks: clean up v...
1776
1777
1778
   *
   * Call this to establish a lease on the file. The "lease" argument is not
   * used for F_UNLCK requests and may be NULL. For commands that set or alter
80b79dd0e   Mauro Carvalho Chehab   fs: locks: Fix so...
1779
1780
   * an existing lease, the ``(*lease)->fl_lmops->lm_break`` operation must be
   * set; if not, this function will return -ENOLCK (and generate a scary-looking
e51673aa5   Jeff Layton   locks: clean up v...
1781
   * stack trace).
1c7dd2ff4   Jeff Layton   locks: define a l...
1782
1783
1784
   *
   * The "priv" pointer is passed directly to the lm_setup function as-is. It
   * may be NULL if the lm_setup operation doesn't require it.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1785
   */
e6f5c7893   Jeff Layton   locks: plumb a "p...
1786
1787
  int
  vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1788
  {
de2a4a501   Miklos Szeredi   Partially revert ...
1789
  	if (filp->f_op->setlease)
f82b4b678   Jeff Layton   locks: move i_loc...
1790
  		return filp->f_op->setlease(filp, arg, lease, priv);
1c7dd2ff4   Jeff Layton   locks: define a l...
1791
  	else
f82b4b678   Jeff Layton   locks: move i_loc...
1792
  		return generic_setlease(filp, arg, lease, priv);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1793
  }
a9933cea7   J. Bruce Fields   locks: rename lea...
1794
  EXPORT_SYMBOL_GPL(vfs_setlease);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1795

0ceaf6c70   J. Bruce Fields   locks: prevent EN...
1796
  static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1797
  {
1c7dd2ff4   Jeff Layton   locks: define a l...
1798
  	struct file_lock *fl;
f7347ce4e   Linus Torvalds   fasync: re-organi...
1799
  	struct fasync_struct *new;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1800
  	int error;
c5b1f0d92   Arnd Bergmann   locks/nfsd: alloc...
1801
1802
1803
  	fl = lease_alloc(filp, arg);
  	if (IS_ERR(fl))
  		return PTR_ERR(fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1804

f7347ce4e   Linus Torvalds   fasync: re-organi...
1805
1806
1807
1808
1809
  	new = fasync_alloc();
  	if (!new) {
  		locks_free_lock(fl);
  		return -ENOMEM;
  	}
1c7dd2ff4   Jeff Layton   locks: define a l...
1810
  	new->fa_fd = fd;
f7347ce4e   Linus Torvalds   fasync: re-organi...
1811

1c7dd2ff4   Jeff Layton   locks: define a l...
1812
  	error = vfs_setlease(filp, arg, &fl, (void **)&new);
2dfb928f7   Jeff Layton   locks: move locks...
1813
1814
  	if (fl)
  		locks_free_lock(fl);
f7347ce4e   Linus Torvalds   fasync: re-organi...
1815
1816
  	if (new)
  		fasync_free(new);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1817
1818
1819
1820
  	return error;
  }
  
  /**
0ceaf6c70   J. Bruce Fields   locks: prevent EN...
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
   *	fcntl_setlease	-	sets a lease on an open file
   *	@fd: open file descriptor
   *	@filp: file pointer
   *	@arg: type of lease to obtain
   *
   *	Call this fcntl to establish a lease on the file.
   *	Note that you also need to call %F_SETSIG to
   *	receive a signal when the lease is broken.
   */
  int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
  {
  	if (arg == F_UNLCK)
2ab99ee12   Christoph Hellwig   fs: track fl_owne...
1833
  		return vfs_setlease(filp, F_UNLCK, NULL, (void **)&filp);
0ceaf6c70   J. Bruce Fields   locks: prevent EN...
1834
1835
1836
1837
  	return do_fcntl_add_lease(fd, filp, arg);
  }
  
  /**
29d01b22e   Jeff Layton   locks: new helper...
1838
1839
   * flock_lock_inode_wait - Apply a FLOCK-style lock to a file
   * @inode: inode of the file to apply to
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1840
1841
   * @fl: The lock to be applied
   *
29d01b22e   Jeff Layton   locks: new helper...
1842
   * Apply a FLOCK style lock request to an inode.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1843
   */
616fb38fa   Benjamin Coddington   locks: cleanup po...
1844
  static int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1845
1846
1847
1848
  {
  	int error;
  	might_sleep();
  	for (;;) {
29d01b22e   Jeff Layton   locks: new helper...
1849
  		error = flock_lock_inode(inode, fl);
bde74e4bc   Miklos Szeredi   locks: add specia...
1850
  		if (error != FILE_LOCK_DEFERRED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
  			break;
  		error = wait_event_interruptible(fl->fl_wait, !fl->fl_next);
  		if (!error)
  			continue;
  
  		locks_delete_block(fl);
  		break;
  	}
  	return error;
  }
29d01b22e   Jeff Layton   locks: new helper...
1861
  /**
e55c34a66   Benjamin Coddington   locks: introduce ...
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
   * locks_lock_inode_wait - Apply a lock to an inode
   * @inode: inode of the file to apply to
   * @fl: The lock to be applied
   *
   * Apply a POSIX or FLOCK style lock request to an inode.
   */
  int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl)
  {
  	int res = 0;
  	switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) {
  		case FL_POSIX:
  			res = posix_lock_inode_wait(inode, fl);
  			break;
  		case FL_FLOCK:
  			res = flock_lock_inode_wait(inode, fl);
  			break;
  		default:
  			BUG();
  	}
  	return res;
  }
  EXPORT_SYMBOL(locks_lock_inode_wait);
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1886
1887
1888
1889
1890
   *	sys_flock: - flock() system call.
   *	@fd: the file descriptor to lock.
   *	@cmd: the type of lock to apply.
   *
   *	Apply a %FL_FLOCK style lock to an open file descriptor.
80b79dd0e   Mauro Carvalho Chehab   fs: locks: Fix so...
1891
   *	The @cmd can be one of:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1892
   *
80b79dd0e   Mauro Carvalho Chehab   fs: locks: Fix so...
1893
1894
1895
1896
1897
   *	- %LOCK_SH -- a shared lock.
   *	- %LOCK_EX -- an exclusive lock.
   *	- %LOCK_UN -- remove an existing lock.
   *	- %LOCK_MAND -- a 'mandatory' flock.
   *	  This exists to emulate Windows Share Modes.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1898
1899
1900
1901
   *
   *	%LOCK_MAND can be combined with %LOCK_READ or %LOCK_WRITE to allow other
   *	processes read and write access respectively.
   */
002c8976e   Heiko Carstens   [CVE-2009-0029] S...
1902
  SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1903
  {
2903ff019   Al Viro   switch simple cas...
1904
  	struct fd f = fdget(fd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1905
1906
1907
1908
1909
  	struct file_lock *lock;
  	int can_sleep, unlock;
  	int error;
  
  	error = -EBADF;
2903ff019   Al Viro   switch simple cas...
1910
  	if (!f.file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1911
1912
1913
1914
1915
  		goto out;
  
  	can_sleep = !(cmd & LOCK_NB);
  	cmd &= ~LOCK_NB;
  	unlock = (cmd == LOCK_UN);
aeb5d7270   Al Viro   [PATCH] introduce...
1916
  	if (!unlock && !(cmd & LOCK_MAND) &&
2903ff019   Al Viro   switch simple cas...
1917
  	    !(f.file->f_mode & (FMODE_READ|FMODE_WRITE)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1918
  		goto out_putf;
6e129d006   Jeff Layton   locks: flock_make...
1919
1920
1921
  	lock = flock_make_lock(f.file, cmd);
  	if (IS_ERR(lock)) {
  		error = PTR_ERR(lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1922
  		goto out_putf;
6e129d006   Jeff Layton   locks: flock_make...
1923
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1924
1925
  	if (can_sleep)
  		lock->fl_flags |= FL_SLEEP;
2903ff019   Al Viro   switch simple cas...
1926
  	error = security_file_lock(f.file, lock->fl_type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1927
1928
  	if (error)
  		goto out_free;
de2a4a501   Miklos Szeredi   Partially revert ...
1929
  	if (f.file->f_op->flock)
2903ff019   Al Viro   switch simple cas...
1930
  		error = f.file->f_op->flock(f.file,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1931
1932
1933
  					  (can_sleep) ? F_SETLKW : F_SETLK,
  					  lock);
  	else
4f6563677   Benjamin Coddington   Move locks API us...
1934
  		error = locks_lock_file_wait(f.file, lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1935
1936
  
   out_free:
993dfa877   Trond Myklebust   [PATCH] fs/locks....
1937
  	locks_free_lock(lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1938
1939
  
   out_putf:
2903ff019   Al Viro   switch simple cas...
1940
  	fdput(f);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1941
1942
1943
   out:
  	return error;
  }
3ee17abd1   J. Bruce Fields   locks: factor out...
1944
1945
1946
  /**
   * vfs_test_lock - test file byte range lock
   * @filp: The file to test lock for
6924c5549   J. Bruce Fields   locks: fix vfs_te...
1947
   * @fl: The lock to test; also used to hold result
3ee17abd1   J. Bruce Fields   locks: factor out...
1948
1949
1950
1951
1952
1953
   *
   * Returns -ERRNO on failure.  Indicates presence of conflicting lock by
   * setting conf->fl_type to something other than F_UNLCK.
   */
  int vfs_test_lock(struct file *filp, struct file_lock *fl)
  {
de2a4a501   Miklos Szeredi   Partially revert ...
1954
  	if (filp->f_op->lock)
3ee17abd1   J. Bruce Fields   locks: factor out...
1955
1956
1957
1958
1959
  		return filp->f_op->lock(filp, F_GETLK, fl);
  	posix_test_lock(filp, fl);
  	return 0;
  }
  EXPORT_SYMBOL_GPL(vfs_test_lock);
9d5b86ac1   Benjamin Coddington   fs/locks: Remove ...
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
  /**
   * locks_translate_pid - translate a file_lock's fl_pid number into a namespace
   * @fl: The file_lock who's fl_pid should be translated
   * @ns: The namespace into which the pid should be translated
   *
   * Used to tranlate a fl_pid into a namespace virtual pid number
   */
  static pid_t locks_translate_pid(struct file_lock *fl, struct pid_namespace *ns)
  {
  	pid_t vnr;
  	struct pid *pid;
  
  	if (IS_OFDLCK(fl))
  		return -1;
  	if (IS_REMOTELCK(fl))
  		return fl->fl_pid;
826d7bc9f   Konstantin Khorenko   fs/lock: skip loc...
1976
1977
1978
1979
1980
1981
1982
  	/*
  	 * If the flock owner process is dead and its pid has been already
  	 * freed, the translation below won't work, but we still want to show
  	 * flock owner pid number in init pidns.
  	 */
  	if (ns == &init_pid_ns)
  		return (pid_t)fl->fl_pid;
9d5b86ac1   Benjamin Coddington   fs/locks: Remove ...
1983
1984
1985
1986
1987
1988
1989
  
  	rcu_read_lock();
  	pid = find_pid_ns(fl->fl_pid, &init_pid_ns);
  	vnr = pid_nr_ns(pid, ns);
  	rcu_read_unlock();
  	return vnr;
  }
c2fa1b8a6   J. Bruce Fields   locks: create pos...
1990
1991
  static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
  {
9d5b86ac1   Benjamin Coddington   fs/locks: Remove ...
1992
  	flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current));
c2fa1b8a6   J. Bruce Fields   locks: create pos...
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
  #if BITS_PER_LONG == 32
  	/*
  	 * Make sure we can represent the posix lock via
  	 * legacy 32bit flock.
  	 */
  	if (fl->fl_start > OFFT_OFFSET_MAX)
  		return -EOVERFLOW;
  	if (fl->fl_end != OFFSET_MAX && fl->fl_end > OFFT_OFFSET_MAX)
  		return -EOVERFLOW;
  #endif
  	flock->l_start = fl->fl_start;
  	flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
  		fl->fl_end - fl->fl_start + 1;
  	flock->l_whence = 0;
129a84de2   J. Bruce Fields   locks: fix F_GETL...
2007
  	flock->l_type = fl->fl_type;
c2fa1b8a6   J. Bruce Fields   locks: create pos...
2008
2009
2010
2011
2012
2013
  	return 0;
  }
  
  #if BITS_PER_LONG == 32
  static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
  {
9d5b86ac1   Benjamin Coddington   fs/locks: Remove ...
2014
  	flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current));
c2fa1b8a6   J. Bruce Fields   locks: create pos...
2015
2016
2017
2018
2019
2020
2021
  	flock->l_start = fl->fl_start;
  	flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
  		fl->fl_end - fl->fl_start + 1;
  	flock->l_whence = 0;
  	flock->l_type = fl->fl_type;
  }
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2022
2023
2024
  /* Report the first existing lock that would conflict with l.
   * This implements the F_GETLK command of fcntl().
   */
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2025
  int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2026
  {
52306e882   Benjamin Coddington   fs/locks: Use all...
2027
  	struct file_lock *fl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2028
  	int error;
52306e882   Benjamin Coddington   fs/locks: Use all...
2029
2030
2031
  	fl = locks_alloc_lock();
  	if (fl == NULL)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2032
  	error = -EINVAL;
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2033
  	if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2034
  		goto out;
52306e882   Benjamin Coddington   fs/locks: Use all...
2035
  	error = flock_to_posix_lock(filp, fl, flock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2036
2037
  	if (error)
  		goto out;
0d3f7a2dd   Jeff Layton   locks: rename fil...
2038
  	if (cmd == F_OFD_GETLK) {
90478939d   Jeff Layton   locks: require th...
2039
  		error = -EINVAL;
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2040
  		if (flock->l_pid != 0)
90478939d   Jeff Layton   locks: require th...
2041
  			goto out;
5d50ffd7c   Jeff Layton   locks: add new fc...
2042
  		cmd = F_GETLK;
52306e882   Benjamin Coddington   fs/locks: Use all...
2043
2044
  		fl->fl_flags |= FL_OFDLCK;
  		fl->fl_owner = filp;
5d50ffd7c   Jeff Layton   locks: add new fc...
2045
  	}
52306e882   Benjamin Coddington   fs/locks: Use all...
2046
  	error = vfs_test_lock(filp, fl);
3ee17abd1   J. Bruce Fields   locks: factor out...
2047
2048
  	if (error)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2049
   
52306e882   Benjamin Coddington   fs/locks: Use all...
2050
2051
2052
  	flock->l_type = fl->fl_type;
  	if (fl->fl_type != F_UNLCK) {
  		error = posix_lock_to_flock(flock, fl);
c2fa1b8a6   J. Bruce Fields   locks: create pos...
2053
  		if (error)
52306e882   Benjamin Coddington   fs/locks: Use all...
2054
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2055
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2056
  out:
52306e882   Benjamin Coddington   fs/locks: Use all...
2057
  	locks_free_lock(fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2058
2059
  	return error;
  }
7723ec977   Marc Eshel   locks: factor out...
2060
2061
2062
2063
2064
  /**
   * vfs_lock_file - file byte range lock
   * @filp: The file to apply the lock to
   * @cmd: type of locking operation (F_SETLK, F_GETLK, etc.)
   * @fl: The lock to be applied
150b39345   Marc Eshel   locks: allow {vfs...
2065
2066
2067
2068
2069
2070
2071
2072
   * @conf: Place to return a copy of the conflicting lock, if found.
   *
   * A caller that doesn't care about the conflicting lock may pass NULL
   * as the final argument.
   *
   * If the filesystem defines a private ->lock() method, then @conf will
   * be left unchanged; so a caller that cares should initialize it to
   * some acceptable default.
2beb6614f   Marc Eshel   locks: add fl_gra...
2073
2074
2075
2076
   *
   * To avoid blocking kernel daemons, such as lockd, that need to acquire POSIX
   * locks, the ->lock() interface may return asynchronously, before the lock has
   * been granted or denied by the underlying filesystem, if (and only if)
8fb47a4fb   J. Bruce Fields   locks: rename loc...
2077
   * lm_grant is set. Callers expecting ->lock() to return asynchronously
2beb6614f   Marc Eshel   locks: add fl_gra...
2078
2079
   * will only use F_SETLK, not F_SETLKW; they will set FL_SLEEP if (and only if)
   * the request is for a blocking lock. When ->lock() does return asynchronously,
8fb47a4fb   J. Bruce Fields   locks: rename loc...
2080
   * it must return FILE_LOCK_DEFERRED, and call ->lm_grant() when the lock
2beb6614f   Marc Eshel   locks: add fl_gra...
2081
2082
   * request completes.
   * If the request is for non-blocking lock the file system should return
bde74e4bc   Miklos Szeredi   locks: add specia...
2083
2084
   * FILE_LOCK_DEFERRED then try to get the lock and call the callback routine
   * with the result. If the request timed out the callback routine will return a
2beb6614f   Marc Eshel   locks: add fl_gra...
2085
2086
2087
2088
2089
   * nonzero return code and the file system should release the lock. The file
   * system is also responsible to keep a corresponding posix lock when it
   * grants a lock so the VFS can find out which locks are locally held and do
   * the correct lock cleanup when required.
   * The underlying filesystem must not drop the kernel lock or call
8fb47a4fb   J. Bruce Fields   locks: rename loc...
2090
   * ->lm_grant() before returning to the caller with a FILE_LOCK_DEFERRED
2beb6614f   Marc Eshel   locks: add fl_gra...
2091
   * return code.
7723ec977   Marc Eshel   locks: factor out...
2092
   */
150b39345   Marc Eshel   locks: allow {vfs...
2093
  int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf)
7723ec977   Marc Eshel   locks: factor out...
2094
  {
de2a4a501   Miklos Szeredi   Partially revert ...
2095
  	if (filp->f_op->lock)
7723ec977   Marc Eshel   locks: factor out...
2096
2097
  		return filp->f_op->lock(filp, cmd, fl);
  	else
150b39345   Marc Eshel   locks: allow {vfs...
2098
  		return posix_lock_file(filp, fl, conf);
7723ec977   Marc Eshel   locks: factor out...
2099
2100
  }
  EXPORT_SYMBOL_GPL(vfs_lock_file);
b648a6de0   Miklos Szeredi   locks: cleanup co...
2101
2102
2103
2104
2105
2106
2107
2108
  static int do_lock_file_wait(struct file *filp, unsigned int cmd,
  			     struct file_lock *fl)
  {
  	int error;
  
  	error = security_file_lock(filp, fl->fl_type);
  	if (error)
  		return error;
764c76b37   Miklos Szeredi   locks: allow ->lo...
2109
2110
2111
  	for (;;) {
  		error = vfs_lock_file(filp, cmd, fl, NULL);
  		if (error != FILE_LOCK_DEFERRED)
b648a6de0   Miklos Szeredi   locks: cleanup co...
2112
  			break;
764c76b37   Miklos Szeredi   locks: allow ->lo...
2113
2114
2115
2116
2117
2118
  		error = wait_event_interruptible(fl->fl_wait, !fl->fl_next);
  		if (!error)
  			continue;
  
  		locks_delete_block(fl);
  		break;
b648a6de0   Miklos Szeredi   locks: cleanup co...
2119
2120
2121
2122
  	}
  
  	return error;
  }
6ca7d9101   Benjamin Coddington   locks: Use more f...
2123
  /* Ensure that fl->fl_file has compatible f_mode for F_SETLK calls */
cf01f4eef   Jeff Layton   locks: only valid...
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
  static int
  check_fmode_for_setlk(struct file_lock *fl)
  {
  	switch (fl->fl_type) {
  	case F_RDLCK:
  		if (!(fl->fl_file->f_mode & FMODE_READ))
  			return -EBADF;
  		break;
  	case F_WRLCK:
  		if (!(fl->fl_file->f_mode & FMODE_WRITE))
  			return -EBADF;
  	}
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2138
2139
2140
  /* Apply the lock described by l to an open file descriptor.
   * This implements both the F_SETLK and F_SETLKW commands of fcntl().
   */
c293621bb   Peter Staubach   [PATCH] stale POS...
2141
  int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2142
  		struct flock *flock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2143
2144
  {
  	struct file_lock *file_lock = locks_alloc_lock();
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2145
  	struct inode *inode = locks_inode(filp);
0b2bac2f1   Al Viro   [PATCH] fix SMP o...
2146
  	struct file *f;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2147
2148
2149
2150
  	int error;
  
  	if (file_lock == NULL)
  		return -ENOLCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2151
2152
2153
  	/* Don't allow mandatory locks on files that may be memory mapped
  	 * and shared.
  	 */
a16877ca9   Pavel Emelyanov   Cleanup macros fo...
2154
  	if (mandatory_lock(inode) && mapping_writably_mapped(filp->f_mapping)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2155
2156
2157
  		error = -EAGAIN;
  		goto out;
  	}
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2158
  	error = flock_to_posix_lock(filp, file_lock, flock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2159
2160
  	if (error)
  		goto out;
5d50ffd7c   Jeff Layton   locks: add new fc...
2161

cf01f4eef   Jeff Layton   locks: only valid...
2162
2163
2164
  	error = check_fmode_for_setlk(file_lock);
  	if (error)
  		goto out;
5d50ffd7c   Jeff Layton   locks: add new fc...
2165
2166
  	/*
  	 * If the cmd is requesting file-private locks, then set the
cff2fce58   Jeff Layton   locks: rename FL_...
2167
  	 * FL_OFDLCK flag and override the owner.
5d50ffd7c   Jeff Layton   locks: add new fc...
2168
2169
  	 */
  	switch (cmd) {
0d3f7a2dd   Jeff Layton   locks: rename fil...
2170
  	case F_OFD_SETLK:
90478939d   Jeff Layton   locks: require th...
2171
  		error = -EINVAL;
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2172
  		if (flock->l_pid != 0)
90478939d   Jeff Layton   locks: require th...
2173
  			goto out;
5d50ffd7c   Jeff Layton   locks: add new fc...
2174
  		cmd = F_SETLK;
cff2fce58   Jeff Layton   locks: rename FL_...
2175
  		file_lock->fl_flags |= FL_OFDLCK;
73a8f5f7e   Christoph Hellwig   locks: purge fl_o...
2176
  		file_lock->fl_owner = filp;
5d50ffd7c   Jeff Layton   locks: add new fc...
2177
  		break;
0d3f7a2dd   Jeff Layton   locks: rename fil...
2178
  	case F_OFD_SETLKW:
90478939d   Jeff Layton   locks: require th...
2179
  		error = -EINVAL;
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2180
  		if (flock->l_pid != 0)
90478939d   Jeff Layton   locks: require th...
2181
  			goto out;
5d50ffd7c   Jeff Layton   locks: add new fc...
2182
  		cmd = F_SETLKW;
cff2fce58   Jeff Layton   locks: rename FL_...
2183
  		file_lock->fl_flags |= FL_OFDLCK;
73a8f5f7e   Christoph Hellwig   locks: purge fl_o...
2184
  		file_lock->fl_owner = filp;
5d50ffd7c   Jeff Layton   locks: add new fc...
2185
2186
  		/* Fallthrough */
  	case F_SETLKW:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2187
2188
  		file_lock->fl_flags |= FL_SLEEP;
  	}
5d50ffd7c   Jeff Layton   locks: add new fc...
2189

b648a6de0   Miklos Szeredi   locks: cleanup co...
2190
  	error = do_lock_file_wait(filp, cmd, file_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2191

c293621bb   Peter Staubach   [PATCH] stale POS...
2192
  	/*
0752ba807   Jeff Layton   locks: don't chec...
2193
2194
2195
  	 * Attempt to detect a close/fcntl race and recover by releasing the
  	 * lock that was just acquired. There is no need to do that when we're
  	 * unlocking though, or for OFD locks.
c293621bb   Peter Staubach   [PATCH] stale POS...
2196
  	 */
0752ba807   Jeff Layton   locks: don't chec...
2197
2198
  	if (!error && file_lock->fl_type != F_UNLCK &&
  	    !(file_lock->fl_flags & FL_OFDLCK)) {
7f3697e24   Jeff Layton   locks: fix unlock...
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
  		/*
  		 * We need that spin_lock here - it prevents reordering between
  		 * update of i_flctx->flc_posix and check for it done in
  		 * close(). rcu_read_lock() wouldn't do.
  		 */
  		spin_lock(&current->files->file_lock);
  		f = fcheck(fd);
  		spin_unlock(&current->files->file_lock);
  		if (f != filp) {
  			file_lock->fl_type = F_UNLCK;
  			error = do_lock_file_wait(filp, cmd, file_lock);
  			WARN_ON_ONCE(error);
  			error = -EBADF;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2213
  	}
c293621bb   Peter Staubach   [PATCH] stale POS...
2214
  out:
1890910fd   Jeff Layton   locks: sprinkle s...
2215
  	trace_fcntl_setlk(inode, file_lock, error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2216
2217
2218
2219
2220
2221
2222
2223
  	locks_free_lock(file_lock);
  	return error;
  }
  
  #if BITS_PER_LONG == 32
  /* Report the first existing lock that would conflict with l.
   * This implements the F_GETLK command of fcntl().
   */
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2224
  int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2225
  {
52306e882   Benjamin Coddington   fs/locks: Use all...
2226
  	struct file_lock *fl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2227
  	int error;
52306e882   Benjamin Coddington   fs/locks: Use all...
2228
2229
2230
  	fl = locks_alloc_lock();
  	if (fl == NULL)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2231
  	error = -EINVAL;
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2232
  	if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2233
  		goto out;
52306e882   Benjamin Coddington   fs/locks: Use all...
2234
  	error = flock64_to_posix_lock(filp, fl, flock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2235
2236
  	if (error)
  		goto out;
0d3f7a2dd   Jeff Layton   locks: rename fil...
2237
  	if (cmd == F_OFD_GETLK) {
90478939d   Jeff Layton   locks: require th...
2238
  		error = -EINVAL;
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2239
  		if (flock->l_pid != 0)
90478939d   Jeff Layton   locks: require th...
2240
  			goto out;
5d50ffd7c   Jeff Layton   locks: add new fc...
2241
  		cmd = F_GETLK64;
52306e882   Benjamin Coddington   fs/locks: Use all...
2242
2243
  		fl->fl_flags |= FL_OFDLCK;
  		fl->fl_owner = filp;
5d50ffd7c   Jeff Layton   locks: add new fc...
2244
  	}
52306e882   Benjamin Coddington   fs/locks: Use all...
2245
  	error = vfs_test_lock(filp, fl);
3ee17abd1   J. Bruce Fields   locks: factor out...
2246
2247
  	if (error)
  		goto out;
52306e882   Benjamin Coddington   fs/locks: Use all...
2248
2249
2250
  	flock->l_type = fl->fl_type;
  	if (fl->fl_type != F_UNLCK)
  		posix_lock_to_flock64(flock, fl);
f328296e2   Kinglong Mee   locks: Copy fl_lm...
2251

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2252
  out:
52306e882   Benjamin Coddington   fs/locks: Use all...
2253
  	locks_free_lock(fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2254
2255
2256
2257
2258
2259
  	return error;
  }
  
  /* Apply the lock described by l to an open file descriptor.
   * This implements both the F_SETLK and F_SETLKW commands of fcntl().
   */
c293621bb   Peter Staubach   [PATCH] stale POS...
2260
  int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2261
  		struct flock64 *flock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2262
2263
  {
  	struct file_lock *file_lock = locks_alloc_lock();
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2264
  	struct inode *inode = locks_inode(filp);
0b2bac2f1   Al Viro   [PATCH] fix SMP o...
2265
  	struct file *f;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2266
2267
2268
2269
  	int error;
  
  	if (file_lock == NULL)
  		return -ENOLCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2270
2271
2272
  	/* Don't allow mandatory locks on files that may be memory mapped
  	 * and shared.
  	 */
a16877ca9   Pavel Emelyanov   Cleanup macros fo...
2273
  	if (mandatory_lock(inode) && mapping_writably_mapped(filp->f_mapping)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2274
2275
2276
  		error = -EAGAIN;
  		goto out;
  	}
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2277
  	error = flock64_to_posix_lock(filp, file_lock, flock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2278
2279
  	if (error)
  		goto out;
5d50ffd7c   Jeff Layton   locks: add new fc...
2280

cf01f4eef   Jeff Layton   locks: only valid...
2281
2282
2283
  	error = check_fmode_for_setlk(file_lock);
  	if (error)
  		goto out;
5d50ffd7c   Jeff Layton   locks: add new fc...
2284
2285
  	/*
  	 * If the cmd is requesting file-private locks, then set the
cff2fce58   Jeff Layton   locks: rename FL_...
2286
  	 * FL_OFDLCK flag and override the owner.
5d50ffd7c   Jeff Layton   locks: add new fc...
2287
2288
  	 */
  	switch (cmd) {
0d3f7a2dd   Jeff Layton   locks: rename fil...
2289
  	case F_OFD_SETLK:
90478939d   Jeff Layton   locks: require th...
2290
  		error = -EINVAL;
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2291
  		if (flock->l_pid != 0)
90478939d   Jeff Layton   locks: require th...
2292
  			goto out;
5d50ffd7c   Jeff Layton   locks: add new fc...
2293
  		cmd = F_SETLK64;
cff2fce58   Jeff Layton   locks: rename FL_...
2294
  		file_lock->fl_flags |= FL_OFDLCK;
73a8f5f7e   Christoph Hellwig   locks: purge fl_o...
2295
  		file_lock->fl_owner = filp;
5d50ffd7c   Jeff Layton   locks: add new fc...
2296
  		break;
0d3f7a2dd   Jeff Layton   locks: rename fil...
2297
  	case F_OFD_SETLKW:
90478939d   Jeff Layton   locks: require th...
2298
  		error = -EINVAL;
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2299
  		if (flock->l_pid != 0)
90478939d   Jeff Layton   locks: require th...
2300
  			goto out;
5d50ffd7c   Jeff Layton   locks: add new fc...
2301
  		cmd = F_SETLKW64;
cff2fce58   Jeff Layton   locks: rename FL_...
2302
  		file_lock->fl_flags |= FL_OFDLCK;
73a8f5f7e   Christoph Hellwig   locks: purge fl_o...
2303
  		file_lock->fl_owner = filp;
5d50ffd7c   Jeff Layton   locks: add new fc...
2304
2305
  		/* Fallthrough */
  	case F_SETLKW64:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2306
2307
  		file_lock->fl_flags |= FL_SLEEP;
  	}
5d50ffd7c   Jeff Layton   locks: add new fc...
2308

b648a6de0   Miklos Szeredi   locks: cleanup co...
2309
  	error = do_lock_file_wait(filp, cmd, file_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2310

c293621bb   Peter Staubach   [PATCH] stale POS...
2311
  	/*
0752ba807   Jeff Layton   locks: don't chec...
2312
2313
2314
  	 * Attempt to detect a close/fcntl race and recover by releasing the
  	 * lock that was just acquired. There is no need to do that when we're
  	 * unlocking though, or for OFD locks.
c293621bb   Peter Staubach   [PATCH] stale POS...
2315
  	 */
0752ba807   Jeff Layton   locks: don't chec...
2316
2317
  	if (!error && file_lock->fl_type != F_UNLCK &&
  	    !(file_lock->fl_flags & FL_OFDLCK)) {
7f3697e24   Jeff Layton   locks: fix unlock...
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
  		/*
  		 * We need that spin_lock here - it prevents reordering between
  		 * update of i_flctx->flc_posix and check for it done in
  		 * close(). rcu_read_lock() wouldn't do.
  		 */
  		spin_lock(&current->files->file_lock);
  		f = fcheck(fd);
  		spin_unlock(&current->files->file_lock);
  		if (f != filp) {
  			file_lock->fl_type = F_UNLCK;
  			error = do_lock_file_wait(filp, cmd, file_lock);
  			WARN_ON_ONCE(error);
  			error = -EBADF;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2332
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
  out:
  	locks_free_lock(file_lock);
  	return error;
  }
  #endif /* BITS_PER_LONG == 32 */
  
  /*
   * This function is called when the file is being removed
   * from the task's fd array.  POSIX locks belonging to this task
   * are deleted at this time.
   */
  void locks_remove_posix(struct file *filp, fl_owner_t owner)
  {
1890910fd   Jeff Layton   locks: sprinkle s...
2346
  	int error;
c568d6834   Miklos Szeredi   locks: fix file l...
2347
  	struct inode *inode = locks_inode(filp);
ff7b86b82   Miklos Szeredi   [PATCH] locks: cl...
2348
  	struct file_lock lock;
128a37852   Dmitry Vyukov   fs: fix data race...
2349
  	struct file_lock_context *ctx;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2350
2351
2352
2353
2354
2355
  
  	/*
  	 * If there are no locks held on this file, we don't need to call
  	 * posix_lock_file().  Another process could be setting a lock on this
  	 * file at the same time, but we wouldn't remove that lock anyway.
  	 */
c568d6834   Miklos Szeredi   locks: fix file l...
2356
  	ctx =  smp_load_acquire(&inode->i_flctx);
bd61e0a9c   Jeff Layton   locks: convert po...
2357
  	if (!ctx || list_empty(&ctx->flc_posix))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2358
2359
2360
  		return;
  
  	lock.fl_type = F_UNLCK;
75e1fcc0b   Miklos Szeredi   [PATCH] vfs: add ...
2361
  	lock.fl_flags = FL_POSIX | FL_CLOSE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2362
2363
2364
2365
2366
2367
2368
  	lock.fl_start = 0;
  	lock.fl_end = OFFSET_MAX;
  	lock.fl_owner = owner;
  	lock.fl_pid = current->tgid;
  	lock.fl_file = filp;
  	lock.fl_ops = NULL;
  	lock.fl_lmops = NULL;
1890910fd   Jeff Layton   locks: sprinkle s...
2369
  	error = vfs_lock_file(filp, F_SETLK, &lock, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2370

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2371
2372
  	if (lock.fl_ops && lock.fl_ops->fl_release_private)
  		lock.fl_ops->fl_release_private(&lock);
c568d6834   Miklos Szeredi   locks: fix file l...
2373
  	trace_locks_remove_posix(inode, &lock, error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2374
2375
2376
  }
  
  EXPORT_SYMBOL(locks_remove_posix);
3d8e560de   Jeff Layton   locks: consolidat...
2377
  /* The i_flctx must be valid when calling into here */
dd459bb19   Jeff Layton   locks: have locks...
2378
  static void
128a37852   Dmitry Vyukov   fs: fix data race...
2379
  locks_remove_flock(struct file *filp, struct file_lock_context *flctx)
dd459bb19   Jeff Layton   locks: have locks...
2380
2381
2382
2383
2384
  {
  	struct file_lock fl = {
  		.fl_owner = filp,
  		.fl_pid = current->tgid,
  		.fl_file = filp,
50f2112cf   Benjamin Coddington   locks: Set FL_CLO...
2385
  		.fl_flags = FL_FLOCK | FL_CLOSE,
dd459bb19   Jeff Layton   locks: have locks...
2386
2387
2388
  		.fl_type = F_UNLCK,
  		.fl_end = OFFSET_MAX,
  	};
c568d6834   Miklos Szeredi   locks: fix file l...
2389
  	struct inode *inode = locks_inode(filp);
dd459bb19   Jeff Layton   locks: have locks...
2390

3d8e560de   Jeff Layton   locks: consolidat...
2391
  	if (list_empty(&flctx->flc_flock))
dd459bb19   Jeff Layton   locks: have locks...
2392
  		return;
de2a4a501   Miklos Szeredi   Partially revert ...
2393
  	if (filp->f_op->flock)
dd459bb19   Jeff Layton   locks: have locks...
2394
2395
  		filp->f_op->flock(filp, F_SETLKW, &fl);
  	else
bcd7f78d0   Jeff Layton   locks: have flock...
2396
  		flock_lock_inode(inode, &fl);
dd459bb19   Jeff Layton   locks: have locks...
2397
2398
2399
2400
  
  	if (fl.fl_ops && fl.fl_ops->fl_release_private)
  		fl.fl_ops->fl_release_private(&fl);
  }
3d8e560de   Jeff Layton   locks: consolidat...
2401
  /* The i_flctx must be valid when calling into here */
8634b51f6   Jeff Layton   locks: convert le...
2402
  static void
128a37852   Dmitry Vyukov   fs: fix data race...
2403
  locks_remove_lease(struct file *filp, struct file_lock_context *ctx)
8634b51f6   Jeff Layton   locks: convert le...
2404
  {
8634b51f6   Jeff Layton   locks: convert le...
2405
2406
  	struct file_lock *fl, *tmp;
  	LIST_HEAD(dispose);
3d8e560de   Jeff Layton   locks: consolidat...
2407
  	if (list_empty(&ctx->flc_lease))
8634b51f6   Jeff Layton   locks: convert le...
2408
  		return;
5f43086bb   Peter Zijlstra   locking, fs/locks...
2409
  	percpu_down_read_preempt_disable(&file_rwsem);
6109c8503   Jeff Layton   locks: add a dedi...
2410
  	spin_lock(&ctx->flc_lock);
8634b51f6   Jeff Layton   locks: convert le...
2411
  	list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list)
c4e136cda   Jeff Layton   locks: only remov...
2412
2413
  		if (filp == fl->fl_file)
  			lease_modify(fl, F_UNLCK, &dispose);
6109c8503   Jeff Layton   locks: add a dedi...
2414
  	spin_unlock(&ctx->flc_lock);
5f43086bb   Peter Zijlstra   locking, fs/locks...
2415
  	percpu_up_read_preempt_enable(&file_rwsem);
8634b51f6   Jeff Layton   locks: convert le...
2416
2417
  	locks_dispose_list(&dispose);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2418
2419
2420
  /*
   * This function is called on the last close of an open file.
   */
78ed8a133   Jeff Layton   locks: rename loc...
2421
  void locks_remove_file(struct file *filp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2422
  {
128a37852   Dmitry Vyukov   fs: fix data race...
2423
  	struct file_lock_context *ctx;
c568d6834   Miklos Szeredi   locks: fix file l...
2424
  	ctx = smp_load_acquire(&locks_inode(filp)->i_flctx);
128a37852   Dmitry Vyukov   fs: fix data race...
2425
  	if (!ctx)
3d8e560de   Jeff Layton   locks: consolidat...
2426
  		return;
dd459bb19   Jeff Layton   locks: have locks...
2427
  	/* remove any OFD locks */
73a8f5f7e   Christoph Hellwig   locks: purge fl_o...
2428
  	locks_remove_posix(filp, filp);
5d50ffd7c   Jeff Layton   locks: add new fc...
2429

dd459bb19   Jeff Layton   locks: have locks...
2430
  	/* remove flock locks */
128a37852   Dmitry Vyukov   fs: fix data race...
2431
  	locks_remove_flock(filp, ctx);
dd459bb19   Jeff Layton   locks: have locks...
2432

8634b51f6   Jeff Layton   locks: convert le...
2433
  	/* remove any leases */
128a37852   Dmitry Vyukov   fs: fix data race...
2434
  	locks_remove_lease(filp, ctx);
3953704fd   Benjamin Coddington   locks: restore a ...
2435
2436
2437
2438
2439
2440
  
  	spin_lock(&ctx->flc_lock);
  	locks_check_ctx_file_list(filp, &ctx->flc_posix, "POSIX");
  	locks_check_ctx_file_list(filp, &ctx->flc_flock, "FLOCK");
  	locks_check_ctx_file_list(filp, &ctx->flc_lease, "LEASE");
  	spin_unlock(&ctx->flc_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2441
2442
2443
  }
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2444
   *	posix_unblock_lock - stop waiting for a file lock
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2445
2446
2447
2448
   *	@waiter: the lock which was waiting
   *
   *	lockd needs to block waiting for locks.
   */
64a318ee2   J. Bruce Fields   NLM: Further canc...
2449
  int
f891a29f4   Jeff Layton   locks: drop the u...
2450
  posix_unblock_lock(struct file_lock *waiter)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2451
  {
64a318ee2   J. Bruce Fields   NLM: Further canc...
2452
  	int status = 0;
7b2296afb   Jeff Layton   locks: give the b...
2453
  	spin_lock(&blocked_lock_lock);
5996a298d   J. Bruce Fields   NLM: don't unlock...
2454
  	if (waiter->fl_next)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2455
  		__locks_delete_block(waiter);
64a318ee2   J. Bruce Fields   NLM: Further canc...
2456
2457
  	else
  		status = -ENOENT;
7b2296afb   Jeff Layton   locks: give the b...
2458
  	spin_unlock(&blocked_lock_lock);
64a318ee2   J. Bruce Fields   NLM: Further canc...
2459
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2460
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2461
  EXPORT_SYMBOL(posix_unblock_lock);
9b9d2ab41   Marc Eshel   locks: add lock c...
2462
2463
2464
2465
2466
2467
2468
2469
2470
  /**
   * vfs_cancel_lock - file byte range unblock lock
   * @filp: The file to apply the unblock to
   * @fl: The lock to be unblocked
   *
   * Used by lock managers to cancel blocked requests
   */
  int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
  {
de2a4a501   Miklos Szeredi   Partially revert ...
2471
  	if (filp->f_op->lock)
9b9d2ab41   Marc Eshel   locks: add lock c...
2472
2473
2474
2475
2476
  		return filp->f_op->lock(filp, F_CANCELLK, fl);
  	return 0;
  }
  
  EXPORT_SYMBOL_GPL(vfs_cancel_lock);
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2477
  #ifdef CONFIG_PROC_FS
d8ba7a363   Alexey Dobriyan   proc: move rest o...
2478
  #include <linux/proc_fs.h>
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2479
  #include <linux/seq_file.h>
7012b02a2   Jeff Layton   locks: move file_...
2480
2481
2482
2483
  struct locks_iterator {
  	int	li_cpu;
  	loff_t	li_pos;
  };
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2484
  static void lock_get_status(struct seq_file *f, struct file_lock *fl,
99dc82925   Jerome Marchand   procfs: fix numbe...
2485
  			    loff_t id, char *pfx)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2486
2487
  {
  	struct inode *inode = NULL;
ab1f16116   Vitaliy Gusev   pid-namespaces-vs...
2488
  	unsigned int fl_pid;
9d5b86ac1   Benjamin Coddington   fs/locks: Remove ...
2489
  	struct pid_namespace *proc_pidns = file_inode(f->file)->i_sb->s_fs_info;
ab1f16116   Vitaliy Gusev   pid-namespaces-vs...
2490

9d5b86ac1   Benjamin Coddington   fs/locks: Remove ...
2491
2492
  	fl_pid = locks_translate_pid(fl, proc_pidns);
  	/*
1cf8e5de4   Konstantin Khorenko   fs/lock: show loc...
2493
2494
2495
  	 * If lock owner is dead (and pid is freed) or not visible in current
  	 * pidns, zero is shown as a pid value. Check lock info from
  	 * init_pid_ns to get saved lock pid value.
9d5b86ac1   Benjamin Coddington   fs/locks: Remove ...
2496
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2497
2498
  
  	if (fl->fl_file != NULL)
c568d6834   Miklos Szeredi   locks: fix file l...
2499
  		inode = locks_inode(fl->fl_file);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2500

99dc82925   Jerome Marchand   procfs: fix numbe...
2501
  	seq_printf(f, "%lld:%s ", id, pfx);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2502
  	if (IS_POSIX(fl)) {
c918d42a2   Jeff Layton   locks: make /proc...
2503
  		if (fl->fl_flags & FL_ACCESS)
5315c26a6   Fabian Frederick   fs/locks.c: repla...
2504
  			seq_puts(f, "ACCESS");
cff2fce58   Jeff Layton   locks: rename FL_...
2505
  		else if (IS_OFDLCK(fl))
5315c26a6   Fabian Frederick   fs/locks.c: repla...
2506
  			seq_puts(f, "OFDLCK");
c918d42a2   Jeff Layton   locks: make /proc...
2507
  		else
5315c26a6   Fabian Frederick   fs/locks.c: repla...
2508
  			seq_puts(f, "POSIX ");
c918d42a2   Jeff Layton   locks: make /proc...
2509
2510
  
  		seq_printf(f, " %s ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2511
  			     (inode == NULL) ? "*NOINODE*" :
a16877ca9   Pavel Emelyanov   Cleanup macros fo...
2512
  			     mandatory_lock(inode) ? "MANDATORY" : "ADVISORY ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2513
2514
  	} else if (IS_FLOCK(fl)) {
  		if (fl->fl_type & LOCK_MAND) {
5315c26a6   Fabian Frederick   fs/locks.c: repla...
2515
  			seq_puts(f, "FLOCK  MSNFS     ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2516
  		} else {
5315c26a6   Fabian Frederick   fs/locks.c: repla...
2517
  			seq_puts(f, "FLOCK  ADVISORY  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2518
2519
  		}
  	} else if (IS_LEASE(fl)) {
8144f1f69   Jeff Layton   locks: show deleg...
2520
2521
2522
2523
  		if (fl->fl_flags & FL_DELEG)
  			seq_puts(f, "DELEG  ");
  		else
  			seq_puts(f, "LEASE  ");
ab83fa4b4   J. Bruce Fields   locks: minor leas...
2524
  		if (lease_breaking(fl))
5315c26a6   Fabian Frederick   fs/locks.c: repla...
2525
  			seq_puts(f, "BREAKING  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2526
  		else if (fl->fl_file)
5315c26a6   Fabian Frederick   fs/locks.c: repla...
2527
  			seq_puts(f, "ACTIVE    ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2528
  		else
5315c26a6   Fabian Frederick   fs/locks.c: repla...
2529
  			seq_puts(f, "BREAKER   ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2530
  	} else {
5315c26a6   Fabian Frederick   fs/locks.c: repla...
2531
  		seq_puts(f, "UNKNOWN UNKNOWN  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2532
2533
  	}
  	if (fl->fl_type & LOCK_MAND) {
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2534
  		seq_printf(f, "%s ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2535
2536
2537
2538
  			       (fl->fl_type & LOCK_READ)
  			       ? (fl->fl_type & LOCK_WRITE) ? "RW   " : "READ "
  			       : (fl->fl_type & LOCK_WRITE) ? "WRITE" : "NONE ");
  	} else {
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2539
  		seq_printf(f, "%s ",
ab83fa4b4   J. Bruce Fields   locks: minor leas...
2540
  			       (lease_breaking(fl))
0ee5c6d63   Jeff Layton   vfs: don't treat ...
2541
2542
  			       ? (fl->fl_type == F_UNLCK) ? "UNLCK" : "READ "
  			       : (fl->fl_type == F_WRLCK) ? "WRITE" : "READ ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2543
2544
  	}
  	if (inode) {
3648888e9   Jeff Layton   locks: get rid of...
2545
  		/* userspace relies on this representation of dev_t */
ab1f16116   Vitaliy Gusev   pid-namespaces-vs...
2546
  		seq_printf(f, "%d %02x:%02x:%ld ", fl_pid,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2547
2548
  				MAJOR(inode->i_sb->s_dev),
  				MINOR(inode->i_sb->s_dev), inode->i_ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2549
  	} else {
ab1f16116   Vitaliy Gusev   pid-namespaces-vs...
2550
  		seq_printf(f, "%d <none>:0 ", fl_pid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2551
2552
2553
  	}
  	if (IS_POSIX(fl)) {
  		if (fl->fl_end == OFFSET_MAX)
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2554
2555
  			seq_printf(f, "%Ld EOF
  ", fl->fl_start);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2556
  		else
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2557
2558
  			seq_printf(f, "%Ld %Ld
  ", fl->fl_start, fl->fl_end);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2559
  	} else {
5315c26a6   Fabian Frederick   fs/locks.c: repla...
2560
2561
  		seq_puts(f, "0 EOF
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2562
2563
  	}
  }
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2564
  static int locks_show(struct seq_file *f, void *v)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2565
  {
7012b02a2   Jeff Layton   locks: move file_...
2566
  	struct locks_iterator *iter = f->private;
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2567
  	struct file_lock *fl, *bfl;
d67fd44f6   Nikolay Borisov   locks: Filter /pr...
2568
  	struct pid_namespace *proc_pidns = file_inode(f->file)->i_sb->s_fs_info;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2569

139ca04ee   Jeff Layton   locks: convert fl...
2570
  	fl = hlist_entry(v, struct file_lock, fl_link);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2571

9d5b86ac1   Benjamin Coddington   fs/locks: Remove ...
2572
  	if (locks_translate_pid(fl, proc_pidns) == 0)
d67fd44f6   Nikolay Borisov   locks: Filter /pr...
2573
  		return 0;
7012b02a2   Jeff Layton   locks: move file_...
2574
  	lock_get_status(f, fl, iter->li_pos, "");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2575

7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2576
  	list_for_each_entry(bfl, &fl->fl_block, fl_block)
7012b02a2   Jeff Layton   locks: move file_...
2577
  		lock_get_status(f, bfl, iter->li_pos, " ->");
094f28252   Matthias Kaehlcke   fs/locks.c: use l...
2578

7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2579
2580
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2581

6c8c90319   Andrey Vagin   proc: show locks ...
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
  static void __show_fd_locks(struct seq_file *f,
  			struct list_head *head, int *id,
  			struct file *filp, struct files_struct *files)
  {
  	struct file_lock *fl;
  
  	list_for_each_entry(fl, head, fl_list) {
  
  		if (filp != fl->fl_file)
  			continue;
  		if (fl->fl_owner != files &&
  		    fl->fl_owner != filp)
  			continue;
  
  		(*id)++;
  		seq_puts(f, "lock:\t");
  		lock_get_status(f, fl, *id, "");
  	}
  }
  
  void show_fd_locks(struct seq_file *f,
  		  struct file *filp, struct files_struct *files)
  {
c568d6834   Miklos Szeredi   locks: fix file l...
2605
  	struct inode *inode = locks_inode(filp);
6c8c90319   Andrey Vagin   proc: show locks ...
2606
2607
  	struct file_lock_context *ctx;
  	int id = 0;
128a37852   Dmitry Vyukov   fs: fix data race...
2608
  	ctx = smp_load_acquire(&inode->i_flctx);
6c8c90319   Andrey Vagin   proc: show locks ...
2609
2610
2611
2612
2613
2614
2615
2616
2617
  	if (!ctx)
  		return;
  
  	spin_lock(&ctx->flc_lock);
  	__show_fd_locks(f, &ctx->flc_flock, &id, filp, files);
  	__show_fd_locks(f, &ctx->flc_posix, &id, filp, files);
  	__show_fd_locks(f, &ctx->flc_lease, &id, filp, files);
  	spin_unlock(&ctx->flc_lock);
  }
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2618
  static void *locks_start(struct seq_file *f, loff_t *pos)
b03dfdec0   Jeff Layton   locks: add __acqu...
2619
  	__acquires(&blocked_lock_lock)
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2620
  {
7012b02a2   Jeff Layton   locks: move file_...
2621
  	struct locks_iterator *iter = f->private;
99dc82925   Jerome Marchand   procfs: fix numbe...
2622

7012b02a2   Jeff Layton   locks: move file_...
2623
  	iter->li_pos = *pos + 1;
aba376607   Peter Zijlstra   fs/locks: Replace...
2624
  	percpu_down_write(&file_rwsem);
7b2296afb   Jeff Layton   locks: give the b...
2625
  	spin_lock(&blocked_lock_lock);
7c3f654d8   Peter Zijlstra   fs/locks: Replace...
2626
  	return seq_hlist_start_percpu(&file_lock_list.hlist, &iter->li_cpu, *pos);
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2627
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2628

7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2629
2630
  static void *locks_next(struct seq_file *f, void *v, loff_t *pos)
  {
7012b02a2   Jeff Layton   locks: move file_...
2631
2632
2633
  	struct locks_iterator *iter = f->private;
  
  	++iter->li_pos;
7c3f654d8   Peter Zijlstra   fs/locks: Replace...
2634
  	return seq_hlist_next_percpu(v, &file_lock_list.hlist, &iter->li_cpu, pos);
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2635
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2636

7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2637
  static void locks_stop(struct seq_file *f, void *v)
b03dfdec0   Jeff Layton   locks: add __acqu...
2638
  	__releases(&blocked_lock_lock)
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2639
  {
7b2296afb   Jeff Layton   locks: give the b...
2640
  	spin_unlock(&blocked_lock_lock);
aba376607   Peter Zijlstra   fs/locks: Replace...
2641
  	percpu_up_write(&file_rwsem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2642
  }
d8ba7a363   Alexey Dobriyan   proc: move rest o...
2643
  static const struct seq_operations locks_seq_operations = {
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2644
2645
2646
2647
2648
  	.start	= locks_start,
  	.next	= locks_next,
  	.stop	= locks_stop,
  	.show	= locks_show,
  };
d8ba7a363   Alexey Dobriyan   proc: move rest o...
2649

d8ba7a363   Alexey Dobriyan   proc: move rest o...
2650
2651
  static int __init proc_locks_init(void)
  {
44414d82c   Christoph Hellwig   proc: introduce p...
2652
2653
  	proc_create_seq_private("locks", 0, NULL, &locks_seq_operations,
  			sizeof(struct locks_iterator), NULL);
d8ba7a363   Alexey Dobriyan   proc: move rest o...
2654
2655
  	return 0;
  }
918992267   Paul Gortmaker   fs: make locks.c ...
2656
  fs_initcall(proc_locks_init);
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2657
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2658
2659
  static int __init filelock_init(void)
  {
7012b02a2   Jeff Layton   locks: move file_...
2660
  	int i;
4a075e39c   Jeff Layton   locks: add a new ...
2661
2662
  	flctx_cache = kmem_cache_create("file_lock_ctx",
  			sizeof(struct file_lock_context), 0, SLAB_PANIC, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2663
  	filelock_cache = kmem_cache_create("file_lock_cache",
ee19cc406   Miklos Szeredi   fs: locks: remove...
2664
  			sizeof(struct file_lock), 0, SLAB_PANIC, NULL);
7012b02a2   Jeff Layton   locks: move file_...
2665

7c3f654d8   Peter Zijlstra   fs/locks: Replace...
2666
2667
2668
2669
2670
2671
  	for_each_possible_cpu(i) {
  		struct file_lock_list_struct *fll = per_cpu_ptr(&file_lock_list, i);
  
  		spin_lock_init(&fll->lock);
  		INIT_HLIST_HEAD(&fll->hlist);
  	}
7012b02a2   Jeff Layton   locks: move file_...
2672

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2673
2674
2675
2676
  	return 0;
  }
  
  core_initcall(filelock_init);