Blame view

fs/locks.c 73.9 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

c568d6834   Miklos Szeredi   locks: fix file l...
141
142
143
144
  static inline bool is_remote_lock(struct file *filp)
  {
  	return likely(!(filp->f_path.dentry->d_sb->s_flags & MS_NOREMOTELOCK));
  }
ab83fa4b4   J. Bruce Fields   locks: minor leas...
145
146
  static bool lease_breaking(struct file_lock *fl)
  {
778fc546f   J. Bruce Fields   locks: fix tracki...
147
148
149
150
151
152
153
154
155
156
  	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...
157
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
159
  int leases_enable = 1;
  int lease_break_time = 45;
1c8c601a8   Jeff Layton   locks: protect mo...
160
  /*
7012b02a2   Jeff Layton   locks: move file_...
161
   * The global file_lock_list is only used for displaying /proc/locks, so we
7c3f654d8   Peter Zijlstra   fs/locks: Replace...
162
163
164
165
166
   * 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...
167
   */
7c3f654d8   Peter Zijlstra   fs/locks: Replace...
168
169
170
171
172
  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...
173
  DEFINE_STATIC_PERCPU_RWSEM(file_rwsem);
889746917   Jeff Layton   locks: encapsulat...
174

1c8c601a8   Jeff Layton   locks: protect mo...
175
  /*
48f741865   Jeff Layton   locks: turn the b...
176
   * The blocked_hash is used to find POSIX lock loops for deadlock detection.
7b2296afb   Jeff Layton   locks: give the b...
177
   * It is protected by blocked_lock_lock.
48f741865   Jeff Layton   locks: turn the b...
178
179
180
181
182
183
184
   *
   * 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...
185
   */
48f741865   Jeff Layton   locks: turn the b...
186
187
  #define BLOCKED_HASH_BITS	7
  static DEFINE_HASHTABLE(blocked_hash, BLOCKED_HASH_BITS);
889746917   Jeff Layton   locks: encapsulat...
188

1c8c601a8   Jeff Layton   locks: protect mo...
189
  /*
7b2296afb   Jeff Layton   locks: give the b...
190
191
   * 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...
192
193
194
195
196
197
   *
   * 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...
198
   * we often hold the flc_lock as well. In certain cases, when reading the fields
1c8c601a8   Jeff Layton   locks: protect mo...
199
   * protected by this lock, we can skip acquiring it iff we already hold the
6109c8503   Jeff Layton   locks: add a dedi...
200
   * flc_lock.
1c8c601a8   Jeff Layton   locks: protect mo...
201
202
   *
   * In particular, adding an entry to the fl_block list requires that you hold
6109c8503   Jeff Layton   locks: add a dedi...
203
204
   * both the flc_lock and the blocked_lock_lock (acquired in that order).
   * Deleting an entry from the list however only requires the file_lock_lock.
1c8c601a8   Jeff Layton   locks: protect mo...
205
   */
7b2296afb   Jeff Layton   locks: give the b...
206
  static DEFINE_SPINLOCK(blocked_lock_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207

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

4a075e39c   Jeff Layton   locks: add a new ...
211
  static struct file_lock_context *
5c1c669a1   Jeff Layton   locks: don't allo...
212
  locks_get_lock_context(struct inode *inode, int type)
4a075e39c   Jeff Layton   locks: add a new ...
213
  {
128a37852   Dmitry Vyukov   fs: fix data race...
214
  	struct file_lock_context *ctx;
4a075e39c   Jeff Layton   locks: add a new ...
215

128a37852   Dmitry Vyukov   fs: fix data race...
216
217
218
  	/* paired with cmpxchg() below */
  	ctx = smp_load_acquire(&inode->i_flctx);
  	if (likely(ctx) || type == F_UNLCK)
4a075e39c   Jeff Layton   locks: add a new ...
219
  		goto out;
128a37852   Dmitry Vyukov   fs: fix data race...
220
221
  	ctx = kmem_cache_alloc(flctx_cache, GFP_KERNEL);
  	if (!ctx)
4a075e39c   Jeff Layton   locks: add a new ...
222
  		goto out;
128a37852   Dmitry Vyukov   fs: fix data race...
223
224
225
226
  	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 ...
227
228
229
230
231
  
  	/*
  	 * 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...
232
233
234
235
  	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 ...
236
  out:
1890910fd   Jeff Layton   locks: sprinkle s...
237
  	trace_locks_get_lock_context(inode, type, ctx);
128a37852   Dmitry Vyukov   fs: fix data race...
238
  	return ctx;
4a075e39c   Jeff Layton   locks: add a new ...
239
  }
e24dadab0   Jeff Layton   locks: prink more...
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
  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 ...
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
  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 ...
284
  void
f27a0fe08   Jeff Layton   locks: pass inode...
285
  locks_free_lock_context(struct inode *inode)
4a075e39c   Jeff Layton   locks: add a new ...
286
  {
f27a0fe08   Jeff Layton   locks: pass inode...
287
  	struct file_lock_context *ctx = inode->i_flctx;
e24dadab0   Jeff Layton   locks: prink more...
288
289
  	if (unlikely(ctx)) {
  		locks_check_ctx_lists(inode);
4a075e39c   Jeff Layton   locks: add a new ...
290
291
292
  		kmem_cache_free(flctx_cache, ctx);
  	}
  }
ee19cc406   Miklos Szeredi   fs: locks: remove...
293
  static void locks_init_lock_heads(struct file_lock *fl)
a51cb91d8   Miklos Szeredi   fs: fix lock init...
294
  {
139ca04ee   Jeff Layton   locks: convert fl...
295
  	INIT_HLIST_NODE(&fl->fl_link);
6dee60f69   Jeff Layton   locks: add new st...
296
  	INIT_LIST_HEAD(&fl->fl_list);
ee19cc406   Miklos Szeredi   fs: locks: remove...
297
298
  	INIT_LIST_HEAD(&fl->fl_block);
  	init_waitqueue_head(&fl->fl_wait);
a51cb91d8   Miklos Szeredi   fs: fix lock init...
299
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
  /* Allocate an empty lock structure. */
c5b1f0d92   Arnd Bergmann   locks/nfsd: alloc...
301
  struct file_lock *locks_alloc_lock(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
  {
ee19cc406   Miklos Szeredi   fs: locks: remove...
303
  	struct file_lock *fl = kmem_cache_zalloc(filelock_cache, GFP_KERNEL);
a51cb91d8   Miklos Szeredi   fs: fix lock init...
304
305
  
  	if (fl)
ee19cc406   Miklos Szeredi   fs: locks: remove...
306
  		locks_init_lock_heads(fl);
a51cb91d8   Miklos Szeredi   fs: fix lock init...
307
308
  
  	return fl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
  }
c5b1f0d92   Arnd Bergmann   locks/nfsd: alloc...
310
  EXPORT_SYMBOL_GPL(locks_alloc_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
311

a9e61e25f   Felix Blyakher   lockd: call locks...
312
  void locks_release_private(struct file_lock *fl)
47831f35b   Trond Myklebust   VFS: Fix __posix_...
313
314
315
316
317
318
  {
  	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_...
319

5c97d7b14   Kinglong Mee   locks: New ops in...
320
  	if (fl->fl_lmops) {
cae80b305   Jeff Layton   locks: change lm_...
321
322
323
324
  		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...
325
326
  		fl->fl_lmops = NULL;
  	}
47831f35b   Trond Myklebust   VFS: Fix __posix_...
327
  }
a9e61e25f   Felix Blyakher   lockd: call locks...
328
  EXPORT_SYMBOL_GPL(locks_release_private);
47831f35b   Trond Myklebust   VFS: Fix __posix_...
329

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

47831f35b   Trond Myklebust   VFS: Fix __posix_...
338
  	locks_release_private(fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339
340
  	kmem_cache_free(filelock_cache, fl);
  }
05fa3135f   J. Bruce Fields   locks: fix setlea...
341
  EXPORT_SYMBOL(locks_free_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342

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

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

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

f328296e2   Kinglong Mee   locks: Copy fl_lm...
393
394
395
396
  	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
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
  }
  
  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...
416
417
  static struct file_lock *
  flock_make_lock(struct file *filp, unsigned int cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
418
419
420
  {
  	struct file_lock *fl;
  	int type = flock_translate_cmd(cmd);
6e129d006   Jeff Layton   locks: flock_make...
421

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

128a37852   Dmitry Vyukov   fs: fix data race...
789
  	ctx = smp_load_acquire(&inode->i_flctx);
bd61e0a9c   Jeff Layton   locks: convert po...
790
791
792
793
  	if (!ctx || list_empty_careful(&ctx->flc_posix)) {
  		fl->fl_type = F_UNLCK;
  		return;
  	}
6109c8503   Jeff Layton   locks: add a dedi...
794
  	spin_lock(&ctx->flc_lock);
bd61e0a9c   Jeff Layton   locks: convert po...
795
796
797
  	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...
798
799
  			goto out;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
800
  	}
bd61e0a9c   Jeff Layton   locks: convert po...
801
802
  	fl->fl_type = F_UNLCK;
  out:
6109c8503   Jeff Layton   locks: add a dedi...
803
  	spin_unlock(&ctx->flc_lock);
6d34ac199   J. Bruce Fields   locks: make posix...
804
  	return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
805
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
806
  EXPORT_SYMBOL(posix_test_lock);
b533184fc   J. Bruce Fields   locks: clarify po...
807
808
809
810
811
  /*
   * Deadlock detection:
   *
   * We attempt to detect deadlocks that are due purely to posix file
   * locks.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
812
   *
b533184fc   J. Bruce Fields   locks: clarify po...
813
814
815
816
817
818
819
   * 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
820
   *
b533184fc   J. Bruce Fields   locks: clarify po...
821
822
823
   * 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...
824
   *
b533184fc   J. Bruce Fields   locks: clarify po...
825
826
827
   * 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...
828
   * To handle those cases, we just bail out after a few iterations.
57b65325f   Jeff Layton   locks: skip deadl...
829
   *
cff2fce58   Jeff Layton   locks: rename FL_...
830
   * For FL_OFDLCK locks, the owner is the filp, not the files_struct.
57b65325f   Jeff Layton   locks: skip deadl...
831
832
833
834
   * 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_...
835
   * In principle, we could do a more limited deadlock detection on FL_OFDLCK
57b65325f   Jeff Layton   locks: skip deadl...
836
837
   * 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
838
   */
97855b49b   J. Bruce Fields   locks: fix possib...
839
840
  
  #define MAX_DEADLK_ITERATIONS 10
b533184fc   J. Bruce Fields   locks: clarify po...
841
842
843
844
  /* 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 ...
845
  	hash_for_each_possible(blocked_hash, fl, fl_link, posix_owner_key(block_fl)) {
b533184fc   J. Bruce Fields   locks: clarify po...
846
847
848
849
850
  		if (posix_same_owner(fl, block_fl))
  			return fl->fl_next;
  	}
  	return NULL;
  }
7b2296afb   Jeff Layton   locks: give the b...
851
  /* Must be called with the blocked_lock_lock held! */
b0904e147   Adrian Bunk   [PATCH] fs/locks....
852
  static int posix_locks_deadlock(struct file_lock *caller_fl,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
853
854
  				struct file_lock *block_fl)
  {
97855b49b   J. Bruce Fields   locks: fix possib...
855
  	int i = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
856

663d5af75   Daniel Wagner   locks: Add lockde...
857
  	lockdep_assert_held(&blocked_lock_lock);
57b65325f   Jeff Layton   locks: skip deadl...
858
859
  	/*
  	 * This deadlock detector can't reasonably detect deadlocks with
cff2fce58   Jeff Layton   locks: rename FL_...
860
  	 * FL_OFDLCK locks, since they aren't owned by a process, per-se.
57b65325f   Jeff Layton   locks: skip deadl...
861
  	 */
cff2fce58   Jeff Layton   locks: rename FL_...
862
  	if (IS_OFDLCK(caller_fl))
57b65325f   Jeff Layton   locks: skip deadl...
863
  		return 0;
b533184fc   J. Bruce Fields   locks: clarify po...
864
865
866
867
868
  	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
869
870
871
  	}
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
872
  /* Try to create a FLOCK lock on filp. We always insert new FLOCK locks
02888f41e   J. Bruce Fields   locks: fix flock_...
873
   * after any leases, but before any posix locks.
f475ae957   Trond Myklebust   VFS: Allow caller...
874
875
876
877
   *
   * 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
878
   */
bcd7f78d0   Jeff Layton   locks: have flock...
879
  static int flock_lock_inode(struct inode *inode, struct file_lock *request)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
880
  {
993dfa877   Trond Myklebust   [PATCH] fs/locks....
881
  	struct file_lock *new_fl = NULL;
5263e31e4   Jeff Layton   locks: move flock...
882
883
  	struct file_lock *fl;
  	struct file_lock_context *ctx;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
884
  	int error = 0;
5263e31e4   Jeff Layton   locks: move flock...
885
  	bool found = false;
ed9814d85   Jeff Layton   locks: defer free...
886
  	LIST_HEAD(dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
887

5c1c669a1   Jeff Layton   locks: don't allo...
888
889
890
891
892
893
  	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...
894

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

f475ae957   Trond Myklebust   VFS: Allow caller...
914
915
916
  	if (request->fl_type == F_UNLCK) {
  		if ((request->fl_flags & FL_EXISTS) && !found)
  			error = -ENOENT;
993dfa877   Trond Myklebust   [PATCH] fs/locks....
917
  		goto out;
f475ae957   Trond Myklebust   VFS: Allow caller...
918
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
919

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

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
963
964
965
  	/*
  	 * 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...
966
967
  	 *
  	 * In some cases we can be sure, that no new locks will be needed
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
968
  	 */
39005d022   Miklos Szeredi   [PATCH] locks: do...
969
970
971
972
973
974
  	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
975

87709e28d   Peter Zijlstra   fs/locks: Use per...
976
  	percpu_down_read_preempt_disable(&file_rwsem);
6109c8503   Jeff Layton   locks: add a dedi...
977
  	spin_lock(&ctx->flc_lock);
1cb360125   Jeff Layton   locks: comment cl...
978
979
980
  	/*
  	 * 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...
981
  	 * blocker's list of waiters and the global blocked_hash.
1cb360125   Jeff Layton   locks: comment cl...
982
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
983
  	if (request->fl_type != F_UNLCK) {
bd61e0a9c   Jeff Layton   locks: convert po...
984
  		list_for_each_entry(fl, &ctx->flc_posix, fl_list) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
985
986
  			if (!posix_locks_conflict(request, fl))
  				continue;
5842add2f   Andy Adamson   [PATCH] VFS,fs/lo...
987
  			if (conflock)
3fe0fff18   Kinglong Mee   locks: Rename __l...
988
  				locks_copy_conflock(conflock, fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
989
990
991
  			error = -EAGAIN;
  			if (!(request->fl_flags & FL_SLEEP))
  				goto out;
1c8c601a8   Jeff Layton   locks: protect mo...
992
993
994
995
  			/*
  			 * 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
996
  			error = -EDEADLK;
7b2296afb   Jeff Layton   locks: give the b...
997
  			spin_lock(&blocked_lock_lock);
1c8c601a8   Jeff Layton   locks: protect mo...
998
999
1000
1001
  			if (likely(!posix_locks_deadlock(request, fl))) {
  				error = FILE_LOCK_DEFERRED;
  				__locks_insert_block(fl, request);
  			}
7b2296afb   Jeff Layton   locks: give the b...
1002
  			spin_unlock(&blocked_lock_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1003
1004
1005
1006
1007
1008
1009
1010
  			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...
1011
1012
1013
1014
  	/* 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
1015
  	}
1cb360125   Jeff Layton   locks: comment cl...
1016
  	/* Process locks with this owner. */
bd61e0a9c   Jeff Layton   locks: convert po...
1017
1018
1019
1020
1021
  	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
1022
  		if (request->fl_type == fl->fl_type) {
449231d6d   Olaf Kirch   From: Olaf Kirch ...
1023
1024
1025
1026
  			/* 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
1027
  			if (fl->fl_end < request->fl_start - 1)
bd61e0a9c   Jeff Layton   locks: convert po...
1028
  				continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1029
1030
1031
  			/* 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 ...
1032
  			if (fl->fl_start - 1 > request->fl_end)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
  				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...
1049
  				locks_delete_lock_ctx(fl, &dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1050
1051
1052
  				continue;
  			}
  			request = fl;
b9746ef80   Jeff Layton   locks: make "adde...
1053
  			added = true;
bd61e0a9c   Jeff Layton   locks: convert po...
1054
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1055
1056
1057
1058
  			/* Processing for different lock types is a bit
  			 * more complex.
  			 */
  			if (fl->fl_end < request->fl_start)
bd61e0a9c   Jeff Layton   locks: convert po...
1059
  				continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1060
1061
1062
  			if (fl->fl_start > request->fl_end)
  				break;
  			if (request->fl_type == F_UNLCK)
b9746ef80   Jeff Layton   locks: make "adde...
1063
  				added = true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
  			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...
1078
  					locks_delete_lock_ctx(fl, &dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1079
1080
  					continue;
  				}
b84d49f94   Jeff Layton   locks: don't reus...
1081
1082
1083
1084
1085
1086
  				/*
  				 * 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
1087
  				 */
b84d49f94   Jeff Layton   locks: don't reus...
1088
1089
1090
1091
1092
1093
  				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...
1094
1095
  				locks_insert_lock_ctx(request, &fl->fl_list);
  				locks_delete_lock_ctx(fl, &dispose);
b9746ef80   Jeff Layton   locks: make "adde...
1096
  				added = true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1097
1098
  			}
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1099
  	}
0d9a490ab   Miklos Szeredi   [PATCH] locks: do...
1100
  	/*
1cb360125   Jeff Layton   locks: comment cl...
1101
1102
1103
  	 * 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...
1104
1105
1106
1107
  	 */
  	error = -ENOLCK; /* "no luck" */
  	if (right && left == right && !new_fl2)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1108
1109
  	error = 0;
  	if (!added) {
f475ae957   Trond Myklebust   VFS: Allow caller...
1110
1111
1112
  		if (request->fl_type == F_UNLCK) {
  			if (request->fl_flags & FL_EXISTS)
  				error = -ENOENT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1113
  			goto out;
f475ae957   Trond Myklebust   VFS: Allow caller...
1114
  		}
0d9a490ab   Miklos Szeredi   [PATCH] locks: do...
1115
1116
1117
1118
1119
  
  		if (!new_fl) {
  			error = -ENOLCK;
  			goto out;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1120
  		locks_copy_lock(new_fl, request);
e084c1bd4   Jeff Layton   Revert "locks: ke...
1121
  		locks_insert_lock_ctx(new_fl, &fl->fl_list);
2e2f756f8   Jeff Layton   locks: fix list i...
1122
  		fl = new_fl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
  		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...
1133
  			locks_insert_lock_ctx(left, &fl->fl_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1134
1135
1136
1137
1138
1139
1140
1141
1142
  		}
  		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...
1143
  	spin_unlock(&ctx->flc_lock);
87709e28d   Peter Zijlstra   fs/locks: Use per...
1144
  	percpu_up_read_preempt_enable(&file_rwsem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1145
1146
1147
1148
1149
1150
1151
  	/*
  	 * 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...
1152
  	locks_dispose_list(&dispose);
1890910fd   Jeff Layton   locks: sprinkle s...
1153
  	trace_posix_lock_inode(inode, request, error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1154
1155
1156
1157
1158
1159
1160
  	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...
1161
   * @conflock: Place to return a copy of the conflicting lock, if found.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1162
1163
1164
1165
   *
   * 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...
1166
1167
1168
1169
   *
   * 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
1170
   */
150b39345   Marc Eshel   locks: allow {vfs...
1171
  int posix_lock_file(struct file *filp, struct file_lock *fl,
5842add2f   Andy Adamson   [PATCH] VFS,fs/lo...
1172
1173
  			struct file_lock *conflock)
  {
c568d6834   Miklos Szeredi   locks: fix file l...
1174
  	return posix_lock_inode(locks_inode(filp), fl, conflock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1175
  }
150b39345   Marc Eshel   locks: allow {vfs...
1176
  EXPORT_SYMBOL(posix_lock_file);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1177
1178
  
  /**
29d01b22e   Jeff Layton   locks: new helper...
1179
1180
   * 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
1181
1182
   * @fl: The lock to be applied
   *
616fb38fa   Benjamin Coddington   locks: cleanup po...
1183
   * Apply a POSIX style lock request to an inode.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1184
   */
616fb38fa   Benjamin Coddington   locks: cleanup po...
1185
  static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1186
1187
1188
1189
  {
  	int error;
  	might_sleep ();
  	for (;;) {
b4d629a39   Jeff Layton   locks: rename __p...
1190
  		error = posix_lock_inode(inode, fl, NULL);
bde74e4bc   Miklos Szeredi   locks: add specia...
1191
  		if (error != FILE_LOCK_DEFERRED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
  			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...
1202

9e8925b67   Jeff Layton   locks: Allow disa...
1203
  #ifdef CONFIG_MANDATORY_FILE_LOCKING
29d01b22e   Jeff Layton   locks: new helper...
1204
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1205
   * locks_mandatory_locked - Check for an active lock
d7a06983a   Jeff Layton   locks: fix locks_...
1206
   * @file: the file to check
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1207
1208
1209
1210
   *
   * 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_...
1211
  int locks_mandatory_locked(struct file *file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1212
  {
bd61e0a9c   Jeff Layton   locks: convert po...
1213
  	int ret;
c568d6834   Miklos Szeredi   locks: fix file l...
1214
  	struct inode *inode = locks_inode(file);
bd61e0a9c   Jeff Layton   locks: convert po...
1215
  	struct file_lock_context *ctx;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1216
  	struct file_lock *fl;
128a37852   Dmitry Vyukov   fs: fix data race...
1217
  	ctx = smp_load_acquire(&inode->i_flctx);
bd61e0a9c   Jeff Layton   locks: convert po...
1218
1219
  	if (!ctx || list_empty_careful(&ctx->flc_posix))
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1220
1221
1222
  	/*
  	 * Search the lock list for this inode for any POSIX locks.
  	 */
6109c8503   Jeff Layton   locks: add a dedi...
1223
  	spin_lock(&ctx->flc_lock);
bd61e0a9c   Jeff Layton   locks: convert po...
1224
1225
  	ret = 0;
  	list_for_each_entry(fl, &ctx->flc_posix, fl_list) {
73a8f5f7e   Christoph Hellwig   locks: purge fl_o...
1226
  		if (fl->fl_owner != current->files &&
bd61e0a9c   Jeff Layton   locks: convert po...
1227
1228
  		    fl->fl_owner != file) {
  			ret = -EAGAIN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1229
  			break;
bd61e0a9c   Jeff Layton   locks: convert po...
1230
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1231
  	}
6109c8503   Jeff Layton   locks: add a dedi...
1232
  	spin_unlock(&ctx->flc_lock);
bd61e0a9c   Jeff Layton   locks: convert po...
1233
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1234
1235
1236
1237
  }
  
  /**
   * locks_mandatory_area - Check for a conflicting lock
acc15575e   Christoph Hellwig   locks: new locks_...
1238
   * @inode:	the file to check
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1239
   * @filp:       how the file was opened (if it was)
acc15575e   Christoph Hellwig   locks: new locks_...
1240
1241
1242
   * @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
1243
1244
   *
   * Searches the inode's list of locks to find any POSIX locks which conflict.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1245
   */
acc15575e   Christoph Hellwig   locks: new locks_...
1246
1247
  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
1248
1249
1250
  {
  	struct file_lock fl;
  	int error;
29723adee   Jeff Layton   locks: make locks...
1251
  	bool sleep = false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1252
1253
  
  	locks_init_lock(&fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1254
1255
1256
1257
  	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...
1258
  		sleep = true;
acc15575e   Christoph Hellwig   locks: new locks_...
1259
1260
1261
  	fl.fl_type = type;
  	fl.fl_start = start;
  	fl.fl_end = end;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1262
1263
  
  	for (;;) {
29723adee   Jeff Layton   locks: make locks...
1264
  		if (filp) {
73a8f5f7e   Christoph Hellwig   locks: purge fl_o...
1265
  			fl.fl_owner = filp;
29723adee   Jeff Layton   locks: make locks...
1266
  			fl.fl_flags &= ~FL_SLEEP;
b4d629a39   Jeff Layton   locks: rename __p...
1267
  			error = posix_lock_inode(inode, &fl, NULL);
29723adee   Jeff Layton   locks: make locks...
1268
1269
1270
1271
1272
1273
1274
  			if (!error)
  				break;
  		}
  
  		if (sleep)
  			fl.fl_flags |= FL_SLEEP;
  		fl.fl_owner = current->files;
b4d629a39   Jeff Layton   locks: rename __p...
1275
  		error = posix_lock_inode(inode, &fl, NULL);
bde74e4bc   Miklos Szeredi   locks: add specia...
1276
  		if (error != FILE_LOCK_DEFERRED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1277
1278
1279
1280
1281
1282
1283
  			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...
1284
  			if (__mandatory_lock(inode))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
  				continue;
  		}
  
  		locks_delete_block(&fl);
  		break;
  	}
  
  	return error;
  }
  
  EXPORT_SYMBOL(locks_mandatory_area);
9e8925b67   Jeff Layton   locks: Allow disa...
1296
  #endif /* CONFIG_MANDATORY_FILE_LOCKING */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1297

778fc546f   J. Bruce Fields   locks: fix tracki...
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
  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
1308
  /* We already had a lease on this file; just change its type */
7448cc37b   Jeff Layton   locks: clean up t...
1309
  int lease_modify(struct file_lock *fl, int arg, struct list_head *dispose)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1310
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1311
1312
1313
1314
  	int error = assign_type(fl, arg);
  
  	if (error)
  		return error;
778fc546f   J. Bruce Fields   locks: fix tracki...
1315
  	lease_clear_pending(fl, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1316
  	locks_wake_up_blocks(fl);
3b6e2723f   Filipe Brandenburger   locks: prevent si...
1317
1318
1319
1320
1321
  	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...
1322
1323
1324
1325
1326
1327
  		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...
1328
  		locks_delete_lock_ctx(fl, dispose);
3b6e2723f   Filipe Brandenburger   locks: prevent si...
1329
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1330
1331
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1332
  EXPORT_SYMBOL(lease_modify);
778fc546f   J. Bruce Fields   locks: fix tracki...
1333
1334
1335
1336
1337
1338
1339
  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...
1340
  static void time_out_leases(struct inode *inode, struct list_head *dispose)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1341
  {
8634b51f6   Jeff Layton   locks: convert le...
1342
1343
  	struct file_lock_context *ctx = inode->i_flctx;
  	struct file_lock *fl, *tmp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1344

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

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

8634b51f6   Jeff Layton   locks: convert le...
1370
  	list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
03d12ddf8   Jeff Layton   locks: __break_le...
1371
1372
1373
1374
1375
  		if (leases_conflict(fl, breaker))
  			return true;
  	}
  	return false;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1376
1377
1378
  /**
   *	__break_lease	-	revoke all outstanding leases on file
   *	@inode: the inode of the file to return
df4e8d2c1   J. Bruce Fields   locks: implement ...
1379
1380
1381
1382
   *	@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
1383
   *
87250dd26   david m. richter   leases: minor bre...
1384
1385
1386
   *	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
1387
1388
   *	specified %O_NONBLOCK to your open().
   */
df4e8d2c1   J. Bruce Fields   locks: implement ...
1389
  int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1390
  {
778fc546f   J. Bruce Fields   locks: fix tracki...
1391
  	int error = 0;
128a37852   Dmitry Vyukov   fs: fix data race...
1392
  	struct file_lock_context *ctx;
a901125c6   Yan, Zheng   locks: fix file_l...
1393
  	struct file_lock *new_fl, *fl, *tmp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1394
  	unsigned long break_time;
8737c9305   Al Viro   Switch may_open()...
1395
  	int want_write = (mode & O_ACCMODE) != O_RDONLY;
c45198eda   Jeff Layton   locks: move freei...
1396
  	LIST_HEAD(dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1397

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

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

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

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

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

87709e28d   Peter Zijlstra   fs/locks: Use per...
1463
  	percpu_down_read_preempt_disable(&file_rwsem);
6109c8503   Jeff Layton   locks: add a dedi...
1464
  	spin_lock(&ctx->flc_lock);
62af4f1f7   Jeff Layton   locks: add some t...
1465
  	trace_break_lease_unblock(inode, new_fl);
1c8c601a8   Jeff Layton   locks: protect mo...
1466
  	locks_delete_block(new_fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1467
  	if (error >= 0) {
778fc546f   J. Bruce Fields   locks: fix tracki...
1468
1469
1470
1471
  		/*
  		 * Wait for the next conflicting lease that has not been
  		 * broken yet
  		 */
03d12ddf8   Jeff Layton   locks: __break_le...
1472
1473
1474
1475
  		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
1476
1477
  		error = 0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1478
  out:
6109c8503   Jeff Layton   locks: add a dedi...
1479
  	spin_unlock(&ctx->flc_lock);
87709e28d   Peter Zijlstra   fs/locks: Use per...
1480
  	percpu_up_read_preempt_enable(&file_rwsem);
c45198eda   Jeff Layton   locks: move freei...
1481
  	locks_dispose_list(&dispose);
6d4b9e38d   Linus Torvalds   vfs: fix handling...
1482
  	locks_free_lock(new_fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1483
1484
1485
1486
1487
1488
  	return error;
  }
  
  EXPORT_SYMBOL(__break_lease);
  
  /**
a6b91919e   Randy Dunlap   fs: fix kernel-do...
1489
   *	lease_get_mtime - get the last modified time of an inode
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1490
1491
1492
1493
1494
   *	@inode: the inode
   *      @time:  pointer to a timespec which will contain the last modified time
   *
   * 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...
1495
   * exclusive lease, then they could be modifying it.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1496
1497
1498
   */
  void lease_get_mtime(struct inode *inode, struct timespec *time)
  {
bfe860243   Jeff Layton   locks: close pote...
1499
  	bool has_lease = false;
128a37852   Dmitry Vyukov   fs: fix data race...
1500
  	struct file_lock_context *ctx;
8634b51f6   Jeff Layton   locks: convert le...
1501
  	struct file_lock *fl;
bfe860243   Jeff Layton   locks: close pote...
1502

128a37852   Dmitry Vyukov   fs: fix data race...
1503
  	ctx = smp_load_acquire(&inode->i_flctx);
8634b51f6   Jeff Layton   locks: convert le...
1504
  	if (ctx && !list_empty_careful(&ctx->flc_lease)) {
6109c8503   Jeff Layton   locks: add a dedi...
1505
  		spin_lock(&ctx->flc_lock);
8ace5dfb9   Geliang Tang   locks: use list_f...
1506
1507
1508
1509
  		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...
1510
  		spin_unlock(&ctx->flc_lock);
bfe860243   Jeff Layton   locks: close pote...
1511
1512
1513
  	}
  
  	if (has_lease)
c2050a454   Deepa Dinamani   fs: Replace curre...
1514
  		*time = current_time(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
  	else
  		*time = inode->i_mtime;
  }
  
  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...
1547
  	struct inode *inode = locks_inode(filp);
128a37852   Dmitry Vyukov   fs: fix data race...
1548
  	struct file_lock_context *ctx;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1549
  	int type = F_UNLCK;
c45198eda   Jeff Layton   locks: move freei...
1550
  	LIST_HEAD(dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1551

128a37852   Dmitry Vyukov   fs: fix data race...
1552
  	ctx = smp_load_acquire(&inode->i_flctx);
8634b51f6   Jeff Layton   locks: convert le...
1553
  	if (ctx && !list_empty_careful(&ctx->flc_lease)) {
5f43086bb   Peter Zijlstra   locking, fs/locks...
1554
  		percpu_down_read_preempt_disable(&file_rwsem);
6109c8503   Jeff Layton   locks: add a dedi...
1555
  		spin_lock(&ctx->flc_lock);
c568d6834   Miklos Szeredi   locks: fix file l...
1556
  		time_out_leases(inode, &dispose);
8634b51f6   Jeff Layton   locks: convert le...
1557
1558
1559
  		list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
  			if (fl->fl_file != filp)
  				continue;
778fc546f   J. Bruce Fields   locks: fix tracki...
1560
  			type = target_leasetype(fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1561
1562
  			break;
  		}
6109c8503   Jeff Layton   locks: add a dedi...
1563
  		spin_unlock(&ctx->flc_lock);
5f43086bb   Peter Zijlstra   locking, fs/locks...
1564
  		percpu_up_read_preempt_enable(&file_rwsem);
8634b51f6   Jeff Layton   locks: convert le...
1565
  		locks_dispose_list(&dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1566
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1567
1568
  	return type;
  }
24cbe7845   Jeff Layton   locks: close pote...
1569
1570
1571
1572
1573
1574
  /**
   * 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....
1575
   * @flags:	current lock flags
24cbe7845   Jeff Layton   locks: close pote...
1576
1577
1578
1579
1580
   *
   * 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...
1581
  check_conflicting_open(const struct dentry *dentry, const long arg, int flags)
24cbe7845   Jeff Layton   locks: close pote...
1582
1583
1584
  {
  	int ret = 0;
  	struct inode *inode = dentry->d_inode;
11afe9f76   Christoph Hellwig   fs: add FL_LAYOUT...
1585
1586
  	if (flags & FL_LAYOUT)
  		return 0;
4d0c5ba2f   Miklos Szeredi   vfs: do get_write...
1587
1588
  	if ((arg == F_RDLCK) &&
  	    (atomic_read(&d_real_inode(dentry)->i_writecount) > 0))
24cbe7845   Jeff Layton   locks: close pote...
1589
1590
1591
1592
1593
1594
1595
1596
  		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...
1597
1598
  static int
  generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **priv)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1599
  {
8634b51f6   Jeff Layton   locks: convert le...
1600
  	struct file_lock *fl, *my_fl = NULL, *lease;
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
1601
  	struct dentry *dentry = filp->f_path.dentry;
c568d6834   Miklos Szeredi   locks: fix file l...
1602
  	struct inode *inode = dentry->d_inode;
8634b51f6   Jeff Layton   locks: convert le...
1603
  	struct file_lock_context *ctx;
df4e8d2c1   J. Bruce Fields   locks: implement ...
1604
  	bool is_deleg = (*flp)->fl_flags & FL_DELEG;
c1f24ef4e   J. Bruce Fields   locks: setlease c...
1605
  	int error;
c45198eda   Jeff Layton   locks: move freei...
1606
  	LIST_HEAD(dispose);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1607

096657b65   J. Bruce Fields   locks: fix leaks ...
1608
  	lease = *flp;
62af4f1f7   Jeff Layton   locks: add some t...
1609
  	trace_generic_add_lease(inode, lease);
5c1c669a1   Jeff Layton   locks: don't allo...
1610
1611
  	/* Note that arg is never F_UNLCK here */
  	ctx = locks_get_lock_context(inode, arg);
8634b51f6   Jeff Layton   locks: convert le...
1612
1613
  	if (!ctx)
  		return -ENOMEM;
df4e8d2c1   J. Bruce Fields   locks: implement ...
1614
1615
1616
1617
1618
1619
1620
1621
  	/*
  	 * 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_...
1622
  	if (is_deleg && !inode_trylock(inode))
df4e8d2c1   J. Bruce Fields   locks: implement ...
1623
1624
1625
1626
  		return -EAGAIN;
  
  	if (is_deleg && arg == F_WRLCK) {
  		/* Write delegations are not currently supported: */
5955102c9   Al Viro   wrappers for ->i_...
1627
  		inode_unlock(inode);
df4e8d2c1   J. Bruce Fields   locks: implement ...
1628
1629
1630
  		WARN_ON_ONCE(1);
  		return -EINVAL;
  	}
096657b65   J. Bruce Fields   locks: fix leaks ...
1631

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1639
1640
1641
1642
1643
1644
1645
1646
  	/*
  	 * 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...
1647
  	error = -EAGAIN;
8634b51f6   Jeff Layton   locks: convert le...
1648
  	list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
2ab99ee12   Christoph Hellwig   fs: track fl_owne...
1649
1650
  		if (fl->fl_file == filp &&
  		    fl->fl_owner == lease->fl_owner) {
8634b51f6   Jeff Layton   locks: convert le...
1651
  			my_fl = fl;
c1f24ef4e   J. Bruce Fields   locks: setlease c...
1652
1653
  			continue;
  		}
8634b51f6   Jeff Layton   locks: convert le...
1654

c1f24ef4e   J. Bruce Fields   locks: setlease c...
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
  		/*
  		 * 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
1667
  	}
8634b51f6   Jeff Layton   locks: convert le...
1668
  	if (my_fl != NULL) {
0164bf023   Jeff Layton   locks: fix fasync...
1669
1670
  		lease = my_fl;
  		error = lease->fl_lmops->lm_change(lease, arg, &dispose);
1c7dd2ff4   Jeff Layton   locks: define a l...
1671
1672
1673
  		if (error)
  			goto out;
  		goto out_setup;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1674
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1675
1676
1677
  	error = -EINVAL;
  	if (!leases_enable)
  		goto out;
e084c1bd4   Jeff Layton   Revert "locks: ke...
1678
  	locks_insert_lock_ctx(lease, &ctx->flc_lease);
24cbe7845   Jeff Layton   locks: close pote...
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
  	/*
  	 * 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...
1689
  	error = check_conflicting_open(dentry, arg, lease->fl_flags);
8634b51f6   Jeff Layton   locks: convert le...
1690
  	if (error) {
e084c1bd4   Jeff Layton   Revert "locks: ke...
1691
  		locks_unlink_lock_ctx(lease);
8634b51f6   Jeff Layton   locks: convert le...
1692
1693
  		goto out;
  	}
1c7dd2ff4   Jeff Layton   locks: define a l...
1694
1695
1696
1697
  
  out_setup:
  	if (lease->fl_lmops->lm_setup)
  		lease->fl_lmops->lm_setup(lease, priv);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1698
  out:
6109c8503   Jeff Layton   locks: add a dedi...
1699
  	spin_unlock(&ctx->flc_lock);
87709e28d   Peter Zijlstra   fs/locks: Use per...
1700
  	percpu_up_read_preempt_enable(&file_rwsem);
c45198eda   Jeff Layton   locks: move freei...
1701
  	locks_dispose_list(&dispose);
df4e8d2c1   J. Bruce Fields   locks: implement ...
1702
  	if (is_deleg)
5955102c9   Al Viro   wrappers for ->i_...
1703
  		inode_unlock(inode);
8634b51f6   Jeff Layton   locks: convert le...
1704
  	if (!error && !my_fl)
1c7dd2ff4   Jeff Layton   locks: define a l...
1705
  		*flp = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1706
1707
  	return error;
  }
8335ebd94   J. Bruce Fields   leases: split up ...
1708

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

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

e6f5c7893   Jeff Layton   locks: plumb a "p...
1773
  		return generic_add_lease(filp, arg, flp, priv);
8335ebd94   J. Bruce Fields   leases: split up ...
1774
  	default:
8d657eb3b   Dave Jones   Remove easily use...
1775
  		return -EINVAL;
8335ebd94   J. Bruce Fields   leases: split up ...
1776
1777
  	}
  }
0af1a4504   Christoph Hellwig   rename setlease t...
1778
  EXPORT_SYMBOL(generic_setlease);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1779

b89f43213   Arnd Bergmann   fs/locks.c: prepa...
1780
  /**
e51673aa5   Jeff Layton   locks: clean up v...
1781
   * vfs_setlease        -       sets a lease on an open file
1c7dd2ff4   Jeff Layton   locks: define a l...
1782
1783
1784
1785
1786
   * @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...
1787
1788
1789
   *
   * 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...
1790
1791
   * 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...
1792
   * stack trace).
1c7dd2ff4   Jeff Layton   locks: define a l...
1793
1794
1795
   *
   * 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
1796
   */
e6f5c7893   Jeff Layton   locks: plumb a "p...
1797
1798
  int
  vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1799
  {
c568d6834   Miklos Szeredi   locks: fix file l...
1800
  	if (filp->f_op->setlease && is_remote_lock(filp))
f82b4b678   Jeff Layton   locks: move i_loc...
1801
  		return filp->f_op->setlease(filp, arg, lease, priv);
1c7dd2ff4   Jeff Layton   locks: define a l...
1802
  	else
f82b4b678   Jeff Layton   locks: move i_loc...
1803
  		return generic_setlease(filp, arg, lease, priv);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1804
  }
a9933cea7   J. Bruce Fields   locks: rename lea...
1805
  EXPORT_SYMBOL_GPL(vfs_setlease);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1806

0ceaf6c70   J. Bruce Fields   locks: prevent EN...
1807
  static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1808
  {
1c7dd2ff4   Jeff Layton   locks: define a l...
1809
  	struct file_lock *fl;
f7347ce4e   Linus Torvalds   fasync: re-organi...
1810
  	struct fasync_struct *new;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1811
  	int error;
c5b1f0d92   Arnd Bergmann   locks/nfsd: alloc...
1812
1813
1814
  	fl = lease_alloc(filp, arg);
  	if (IS_ERR(fl))
  		return PTR_ERR(fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1815

f7347ce4e   Linus Torvalds   fasync: re-organi...
1816
1817
1818
1819
1820
  	new = fasync_alloc();
  	if (!new) {
  		locks_free_lock(fl);
  		return -ENOMEM;
  	}
1c7dd2ff4   Jeff Layton   locks: define a l...
1821
  	new->fa_fd = fd;
f7347ce4e   Linus Torvalds   fasync: re-organi...
1822

1c7dd2ff4   Jeff Layton   locks: define a l...
1823
  	error = vfs_setlease(filp, arg, &fl, (void **)&new);
2dfb928f7   Jeff Layton   locks: move locks...
1824
1825
  	if (fl)
  		locks_free_lock(fl);
f7347ce4e   Linus Torvalds   fasync: re-organi...
1826
1827
  	if (new)
  		fasync_free(new);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1828
1829
1830
1831
  	return error;
  }
  
  /**
0ceaf6c70   J. Bruce Fields   locks: prevent EN...
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
   *	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...
1844
  		return vfs_setlease(filp, F_UNLCK, NULL, (void **)&filp);
0ceaf6c70   J. Bruce Fields   locks: prevent EN...
1845
1846
1847
1848
  	return do_fcntl_add_lease(fd, filp, arg);
  }
  
  /**
29d01b22e   Jeff Layton   locks: new helper...
1849
1850
   * 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
1851
1852
   * @fl: The lock to be applied
   *
29d01b22e   Jeff Layton   locks: new helper...
1853
   * Apply a FLOCK style lock request to an inode.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1854
   */
616fb38fa   Benjamin Coddington   locks: cleanup po...
1855
  static int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1856
1857
1858
1859
  {
  	int error;
  	might_sleep();
  	for (;;) {
29d01b22e   Jeff Layton   locks: new helper...
1860
  		error = flock_lock_inode(inode, fl);
bde74e4bc   Miklos Szeredi   locks: add specia...
1861
  		if (error != FILE_LOCK_DEFERRED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
  			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...
1872
  /**
e55c34a66   Benjamin Coddington   locks: introduce ...
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
   * 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
1897
1898
1899
1900
1901
   *	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...
1902
   *	The @cmd can be one of:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1903
   *
80b79dd0e   Mauro Carvalho Chehab   fs: locks: Fix so...
1904
1905
1906
1907
1908
   *	- %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
1909
1910
1911
1912
   *
   *	%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...
1913
  SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1914
  {
2903ff019   Al Viro   switch simple cas...
1915
  	struct fd f = fdget(fd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1916
1917
1918
1919
1920
  	struct file_lock *lock;
  	int can_sleep, unlock;
  	int error;
  
  	error = -EBADF;
2903ff019   Al Viro   switch simple cas...
1921
  	if (!f.file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1922
1923
1924
1925
1926
  		goto out;
  
  	can_sleep = !(cmd & LOCK_NB);
  	cmd &= ~LOCK_NB;
  	unlock = (cmd == LOCK_UN);
aeb5d7270   Al Viro   [PATCH] introduce...
1927
  	if (!unlock && !(cmd & LOCK_MAND) &&
2903ff019   Al Viro   switch simple cas...
1928
  	    !(f.file->f_mode & (FMODE_READ|FMODE_WRITE)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1929
  		goto out_putf;
6e129d006   Jeff Layton   locks: flock_make...
1930
1931
1932
  	lock = flock_make_lock(f.file, cmd);
  	if (IS_ERR(lock)) {
  		error = PTR_ERR(lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1933
  		goto out_putf;
6e129d006   Jeff Layton   locks: flock_make...
1934
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1935
1936
  	if (can_sleep)
  		lock->fl_flags |= FL_SLEEP;
2903ff019   Al Viro   switch simple cas...
1937
  	error = security_file_lock(f.file, lock->fl_type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1938
1939
  	if (error)
  		goto out_free;
c568d6834   Miklos Szeredi   locks: fix file l...
1940
  	if (f.file->f_op->flock && is_remote_lock(f.file))
2903ff019   Al Viro   switch simple cas...
1941
  		error = f.file->f_op->flock(f.file,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1942
1943
1944
  					  (can_sleep) ? F_SETLKW : F_SETLK,
  					  lock);
  	else
4f6563677   Benjamin Coddington   Move locks API us...
1945
  		error = locks_lock_file_wait(f.file, lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1946
1947
  
   out_free:
993dfa877   Trond Myklebust   [PATCH] fs/locks....
1948
  	locks_free_lock(lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1949
1950
  
   out_putf:
2903ff019   Al Viro   switch simple cas...
1951
  	fdput(f);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1952
1953
1954
   out:
  	return error;
  }
3ee17abd1   J. Bruce Fields   locks: factor out...
1955
1956
1957
  /**
   * vfs_test_lock - test file byte range lock
   * @filp: The file to test lock for
6924c5549   J. Bruce Fields   locks: fix vfs_te...
1958
   * @fl: The lock to test; also used to hold result
3ee17abd1   J. Bruce Fields   locks: factor out...
1959
1960
1961
1962
1963
1964
   *
   * 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)
  {
c568d6834   Miklos Szeredi   locks: fix file l...
1965
  	if (filp->f_op->lock && is_remote_lock(filp))
3ee17abd1   J. Bruce Fields   locks: factor out...
1966
1967
1968
1969
1970
  		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 ...
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
  /**
   * 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;
91e30cae8   Konstantin Khorenko   fs/lock: skip loc...
1987
1988
1989
1990
1991
1992
1993
  	/*
  	 * 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 ...
1994
1995
1996
1997
1998
1999
2000
  
  	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...
2001
2002
  static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
  {
9d5b86ac1   Benjamin Coddington   fs/locks: Remove ...
2003
  	flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current));
c2fa1b8a6   J. Bruce Fields   locks: create pos...
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
  #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...
2018
  	flock->l_type = fl->fl_type;
c2fa1b8a6   J. Bruce Fields   locks: create pos...
2019
2020
2021
2022
2023
2024
  	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 ...
2025
  	flock->l_pid = locks_translate_pid(fl, task_active_pid_ns(current));
c2fa1b8a6   J. Bruce Fields   locks: create pos...
2026
2027
2028
2029
2030
2031
2032
  	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
2033
2034
2035
  /* 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...
2036
  int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock *flock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2037
  {
52306e882   Benjamin Coddington   fs/locks: Use all...
2038
  	struct file_lock *fl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2039
  	int error;
52306e882   Benjamin Coddington   fs/locks: Use all...
2040
2041
2042
  	fl = locks_alloc_lock();
  	if (fl == NULL)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2043
  	error = -EINVAL;
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2044
  	if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2045
  		goto out;
52306e882   Benjamin Coddington   fs/locks: Use all...
2046
  	error = flock_to_posix_lock(filp, fl, flock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2047
2048
  	if (error)
  		goto out;
0d3f7a2dd   Jeff Layton   locks: rename fil...
2049
  	if (cmd == F_OFD_GETLK) {
90478939d   Jeff Layton   locks: require th...
2050
  		error = -EINVAL;
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2051
  		if (flock->l_pid != 0)
90478939d   Jeff Layton   locks: require th...
2052
  			goto out;
5d50ffd7c   Jeff Layton   locks: add new fc...
2053
  		cmd = F_GETLK;
52306e882   Benjamin Coddington   fs/locks: Use all...
2054
2055
  		fl->fl_flags |= FL_OFDLCK;
  		fl->fl_owner = filp;
5d50ffd7c   Jeff Layton   locks: add new fc...
2056
  	}
52306e882   Benjamin Coddington   fs/locks: Use all...
2057
  	error = vfs_test_lock(filp, fl);
3ee17abd1   J. Bruce Fields   locks: factor out...
2058
2059
  	if (error)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2060
   
52306e882   Benjamin Coddington   fs/locks: Use all...
2061
2062
2063
  	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...
2064
  		if (error)
52306e882   Benjamin Coddington   fs/locks: Use all...
2065
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2066
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2067
  out:
52306e882   Benjamin Coddington   fs/locks: Use all...
2068
  	locks_free_lock(fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2069
2070
  	return error;
  }
7723ec977   Marc Eshel   locks: factor out...
2071
2072
2073
2074
2075
  /**
   * 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...
2076
2077
2078
2079
2080
2081
2082
2083
   * @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...
2084
2085
2086
2087
   *
   * 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...
2088
   * lm_grant is set. Callers expecting ->lock() to return asynchronously
2beb6614f   Marc Eshel   locks: add fl_gra...
2089
2090
   * 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...
2091
   * it must return FILE_LOCK_DEFERRED, and call ->lm_grant() when the lock
2beb6614f   Marc Eshel   locks: add fl_gra...
2092
2093
   * request completes.
   * If the request is for non-blocking lock the file system should return
bde74e4bc   Miklos Szeredi   locks: add specia...
2094
2095
   * 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...
2096
2097
2098
2099
2100
   * 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...
2101
   * ->lm_grant() before returning to the caller with a FILE_LOCK_DEFERRED
2beb6614f   Marc Eshel   locks: add fl_gra...
2102
   * return code.
7723ec977   Marc Eshel   locks: factor out...
2103
   */
150b39345   Marc Eshel   locks: allow {vfs...
2104
  int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf)
7723ec977   Marc Eshel   locks: factor out...
2105
  {
c568d6834   Miklos Szeredi   locks: fix file l...
2106
  	if (filp->f_op->lock && is_remote_lock(filp))
7723ec977   Marc Eshel   locks: factor out...
2107
2108
  		return filp->f_op->lock(filp, cmd, fl);
  	else
150b39345   Marc Eshel   locks: allow {vfs...
2109
  		return posix_lock_file(filp, fl, conf);
7723ec977   Marc Eshel   locks: factor out...
2110
2111
  }
  EXPORT_SYMBOL_GPL(vfs_lock_file);
b648a6de0   Miklos Szeredi   locks: cleanup co...
2112
2113
2114
2115
2116
2117
2118
2119
  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...
2120
2121
2122
  	for (;;) {
  		error = vfs_lock_file(filp, cmd, fl, NULL);
  		if (error != FILE_LOCK_DEFERRED)
b648a6de0   Miklos Szeredi   locks: cleanup co...
2123
  			break;
764c76b37   Miklos Szeredi   locks: allow ->lo...
2124
2125
2126
2127
2128
2129
  		error = wait_event_interruptible(fl->fl_wait, !fl->fl_next);
  		if (!error)
  			continue;
  
  		locks_delete_block(fl);
  		break;
b648a6de0   Miklos Szeredi   locks: cleanup co...
2130
2131
2132
2133
  	}
  
  	return error;
  }
6ca7d9101   Benjamin Coddington   locks: Use more f...
2134
  /* Ensure that fl->fl_file has compatible f_mode for F_SETLK calls */
cf01f4eef   Jeff Layton   locks: only valid...
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
  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
2149
2150
2151
  /* 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...
2152
  int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2153
  		struct flock *flock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2154
2155
  {
  	struct file_lock *file_lock = locks_alloc_lock();
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2156
  	struct inode *inode = locks_inode(filp);
0b2bac2f1   Al Viro   [PATCH] fix SMP o...
2157
  	struct file *f;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2158
2159
2160
2161
  	int error;
  
  	if (file_lock == NULL)
  		return -ENOLCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2162
2163
2164
  	/* Don't allow mandatory locks on files that may be memory mapped
  	 * and shared.
  	 */
a16877ca9   Pavel Emelyanov   Cleanup macros fo...
2165
  	if (mandatory_lock(inode) && mapping_writably_mapped(filp->f_mapping)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2166
2167
2168
  		error = -EAGAIN;
  		goto out;
  	}
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2169
  	error = flock_to_posix_lock(filp, file_lock, flock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2170
2171
  	if (error)
  		goto out;
5d50ffd7c   Jeff Layton   locks: add new fc...
2172

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

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

c293621bb   Peter Staubach   [PATCH] stale POS...
2203
  	/*
0752ba807   Jeff Layton   locks: don't chec...
2204
2205
2206
  	 * 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...
2207
  	 */
0752ba807   Jeff Layton   locks: don't chec...
2208
2209
  	if (!error && file_lock->fl_type != F_UNLCK &&
  	    !(file_lock->fl_flags & FL_OFDLCK)) {
7f3697e24   Jeff Layton   locks: fix unlock...
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
  		/*
  		 * 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
2224
  	}
c293621bb   Peter Staubach   [PATCH] stale POS...
2225
  out:
1890910fd   Jeff Layton   locks: sprinkle s...
2226
  	trace_fcntl_setlk(inode, file_lock, error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2227
2228
2229
2230
2231
2232
2233
2234
  	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...
2235
  int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 *flock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2236
  {
52306e882   Benjamin Coddington   fs/locks: Use all...
2237
  	struct file_lock *fl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2238
  	int error;
52306e882   Benjamin Coddington   fs/locks: Use all...
2239
2240
2241
  	fl = locks_alloc_lock();
  	if (fl == NULL)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2242
  	error = -EINVAL;
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2243
  	if (flock->l_type != F_RDLCK && flock->l_type != F_WRLCK)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2244
  		goto out;
52306e882   Benjamin Coddington   fs/locks: Use all...
2245
  	error = flock64_to_posix_lock(filp, fl, flock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2246
2247
  	if (error)
  		goto out;
0d3f7a2dd   Jeff Layton   locks: rename fil...
2248
  	if (cmd == F_OFD_GETLK) {
90478939d   Jeff Layton   locks: require th...
2249
  		error = -EINVAL;
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2250
  		if (flock->l_pid != 0)
90478939d   Jeff Layton   locks: require th...
2251
  			goto out;
5d50ffd7c   Jeff Layton   locks: add new fc...
2252
  		cmd = F_GETLK64;
52306e882   Benjamin Coddington   fs/locks: Use all...
2253
2254
  		fl->fl_flags |= FL_OFDLCK;
  		fl->fl_owner = filp;
5d50ffd7c   Jeff Layton   locks: add new fc...
2255
  	}
52306e882   Benjamin Coddington   fs/locks: Use all...
2256
  	error = vfs_test_lock(filp, fl);
3ee17abd1   J. Bruce Fields   locks: factor out...
2257
2258
  	if (error)
  		goto out;
52306e882   Benjamin Coddington   fs/locks: Use all...
2259
2260
2261
  	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...
2262

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2263
  out:
52306e882   Benjamin Coddington   fs/locks: Use all...
2264
  	locks_free_lock(fl);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2265
2266
2267
2268
2269
2270
  	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...
2271
  int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2272
  		struct flock64 *flock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2273
2274
  {
  	struct file_lock *file_lock = locks_alloc_lock();
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2275
  	struct inode *inode = locks_inode(filp);
0b2bac2f1   Al Viro   [PATCH] fix SMP o...
2276
  	struct file *f;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2277
2278
2279
2280
  	int error;
  
  	if (file_lock == NULL)
  		return -ENOLCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2281
2282
2283
  	/* Don't allow mandatory locks on files that may be memory mapped
  	 * and shared.
  	 */
a16877ca9   Pavel Emelyanov   Cleanup macros fo...
2284
  	if (mandatory_lock(inode) && mapping_writably_mapped(filp->f_mapping)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2285
2286
2287
  		error = -EAGAIN;
  		goto out;
  	}
a75d30c77   Christoph Hellwig   fs/locks: pass ke...
2288
  	error = flock64_to_posix_lock(filp, file_lock, flock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2289
2290
  	if (error)
  		goto out;
5d50ffd7c   Jeff Layton   locks: add new fc...
2291

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

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

c293621bb   Peter Staubach   [PATCH] stale POS...
2322
  	/*
0752ba807   Jeff Layton   locks: don't chec...
2323
2324
2325
  	 * 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...
2326
  	 */
0752ba807   Jeff Layton   locks: don't chec...
2327
2328
  	if (!error && file_lock->fl_type != F_UNLCK &&
  	    !(file_lock->fl_flags & FL_OFDLCK)) {
7f3697e24   Jeff Layton   locks: fix unlock...
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
  		/*
  		 * 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
2343
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
  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...
2357
  	int error;
c568d6834   Miklos Szeredi   locks: fix file l...
2358
  	struct inode *inode = locks_inode(filp);
ff7b86b82   Miklos Szeredi   [PATCH] locks: cl...
2359
  	struct file_lock lock;
128a37852   Dmitry Vyukov   fs: fix data race...
2360
  	struct file_lock_context *ctx;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2361
2362
2363
2364
2365
2366
  
  	/*
  	 * 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...
2367
  	ctx =  smp_load_acquire(&inode->i_flctx);
bd61e0a9c   Jeff Layton   locks: convert po...
2368
  	if (!ctx || list_empty(&ctx->flc_posix))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2369
2370
2371
  		return;
  
  	lock.fl_type = F_UNLCK;
75e1fcc0b   Miklos Szeredi   [PATCH] vfs: add ...
2372
  	lock.fl_flags = FL_POSIX | FL_CLOSE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2373
2374
2375
2376
2377
2378
2379
  	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...
2380
  	error = vfs_lock_file(filp, F_SETLK, &lock, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2381

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

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

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

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

9d5b86ac1   Benjamin Coddington   fs/locks: Remove ...
2502
2503
2504
2505
2506
2507
2508
2509
  	fl_pid = locks_translate_pid(fl, proc_pidns);
  	/*
  	 * If there isn't a fl_pid don't display who is waiting on
  	 * the lock if we are called from locks_show, or if we are
  	 * called from __show_fd_info - skip lock entirely
  	 */
  	if (fl_pid == 0)
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2510
2511
  
  	if (fl->fl_file != NULL)
c568d6834   Miklos Szeredi   locks: fix file l...
2512
  		inode = locks_inode(fl->fl_file);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2513

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

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

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

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

7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2592
2593
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2594

6c8c90319   Andrey Vagin   proc: show locks ...
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
  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...
2618
  	struct inode *inode = locks_inode(filp);
6c8c90319   Andrey Vagin   proc: show locks ...
2619
2620
  	struct file_lock_context *ctx;
  	int id = 0;
128a37852   Dmitry Vyukov   fs: fix data race...
2621
  	ctx = smp_load_acquire(&inode->i_flctx);
6c8c90319   Andrey Vagin   proc: show locks ...
2622
2623
2624
2625
2626
2627
2628
2629
2630
  	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...
2631
  static void *locks_start(struct seq_file *f, loff_t *pos)
b03dfdec0   Jeff Layton   locks: add __acqu...
2632
  	__acquires(&blocked_lock_lock)
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2633
  {
7012b02a2   Jeff Layton   locks: move file_...
2634
  	struct locks_iterator *iter = f->private;
99dc82925   Jerome Marchand   procfs: fix numbe...
2635

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

7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2642
2643
  static void *locks_next(struct seq_file *f, void *v, loff_t *pos)
  {
7012b02a2   Jeff Layton   locks: move file_...
2644
2645
2646
  	struct locks_iterator *iter = f->private;
  
  	++iter->li_pos;
7c3f654d8   Peter Zijlstra   fs/locks: Replace...
2647
  	return seq_hlist_next_percpu(v, &file_lock_list.hlist, &iter->li_cpu, pos);
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2648
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2649

7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2650
  static void locks_stop(struct seq_file *f, void *v)
b03dfdec0   Jeff Layton   locks: add __acqu...
2651
  	__releases(&blocked_lock_lock)
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2652
  {
7b2296afb   Jeff Layton   locks: give the b...
2653
  	spin_unlock(&blocked_lock_lock);
aba376607   Peter Zijlstra   fs/locks: Replace...
2654
  	percpu_up_write(&file_rwsem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2655
  }
d8ba7a363   Alexey Dobriyan   proc: move rest o...
2656
  static const struct seq_operations locks_seq_operations = {
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2657
2658
2659
2660
2661
  	.start	= locks_start,
  	.next	= locks_next,
  	.stop	= locks_stop,
  	.show	= locks_show,
  };
d8ba7a363   Alexey Dobriyan   proc: move rest o...
2662
2663
2664
  
  static int locks_open(struct inode *inode, struct file *filp)
  {
7012b02a2   Jeff Layton   locks: move file_...
2665
2666
  	return seq_open_private(filp, &locks_seq_operations,
  					sizeof(struct locks_iterator));
d8ba7a363   Alexey Dobriyan   proc: move rest o...
2667
2668
2669
2670
2671
2672
  }
  
  static const struct file_operations proc_locks_operations = {
  	.open		= locks_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
99dc82925   Jerome Marchand   procfs: fix numbe...
2673
  	.release	= seq_release_private,
d8ba7a363   Alexey Dobriyan   proc: move rest o...
2674
2675
2676
2677
2678
2679
2680
  };
  
  static int __init proc_locks_init(void)
  {
  	proc_create("locks", 0, NULL, &proc_locks_operations);
  	return 0;
  }
918992267   Paul Gortmaker   fs: make locks.c ...
2681
  fs_initcall(proc_locks_init);
7f8ada98d   Pavel Emelyanov   Rework /proc/lock...
2682
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2683
2684
  static int __init filelock_init(void)
  {
7012b02a2   Jeff Layton   locks: move file_...
2685
  	int i;
4a075e39c   Jeff Layton   locks: add a new ...
2686
2687
  	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
2688
  	filelock_cache = kmem_cache_create("file_lock_cache",
ee19cc406   Miklos Szeredi   fs: locks: remove...
2689
  			sizeof(struct file_lock), 0, SLAB_PANIC, NULL);
7012b02a2   Jeff Layton   locks: move file_...
2690

7c3f654d8   Peter Zijlstra   fs/locks: Replace...
2691
2692
2693
2694
2695
2696
  	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_...
2697

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2698
2699
2700
2701
  	return 0;
  }
  
  core_initcall(filelock_init);