aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/lustre/lustre/llite/file.c17
-rw-r--r--fs/9p/vfs_file.c3
-rw-r--r--fs/afs/flock.c4
-rw-r--r--fs/ceph/locks.c10
-rw-r--r--fs/fuse/file.c1
-rw-r--r--fs/locks.c37
-rw-r--r--fs/nfs/file.c4
-rw-r--r--include/trace/events/filelock.h96
8 files changed, 129 insertions, 43 deletions
diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c
index d87f96d9e0fa..c4ddec2b3589 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -2706,20 +2706,15 @@ ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
2706 2706
2707 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_FLOCK, 1); 2707 ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_FLOCK, 1);
2708 2708
2709 if (file_lock->fl_flags & FL_FLOCK) { 2709 if (file_lock->fl_flags & FL_FLOCK)
2710 LASSERT((cmd == F_SETLKW) || (cmd == F_SETLK)); 2710 LASSERT((cmd == F_SETLKW) || (cmd == F_SETLK));
2711 /* flocks are whole-file locks */ 2711 else if (!(file_lock->fl_flags & FL_POSIX))
2712 flock.l_flock.end = OFFSET_MAX;
2713 /* For flocks owner is determined by the local file descriptor*/
2714 flock.l_flock.owner = (unsigned long)file_lock->fl_file;
2715 } else if (file_lock->fl_flags & FL_POSIX) {
2716 flock.l_flock.owner = (unsigned long)file_lock->fl_owner;
2717 flock.l_flock.start = file_lock->fl_start;
2718 flock.l_flock.end = file_lock->fl_end;
2719 } else {
2720 return -EINVAL; 2712 return -EINVAL;
2721 } 2713
2714 flock.l_flock.owner = (unsigned long)file_lock->fl_owner;
2722 flock.l_flock.pid = file_lock->fl_pid; 2715 flock.l_flock.pid = file_lock->fl_pid;
2716 flock.l_flock.start = file_lock->fl_start;
2717 flock.l_flock.end = file_lock->fl_end;
2723 2718
2724 /* Somewhat ugly workaround for svc lockd. 2719 /* Somewhat ugly workaround for svc lockd.
2725 * lockd installs custom fl_lmops->lm_compare_owner that checks 2720 * lockd installs custom fl_lmops->lm_compare_owner that checks
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index d8223209d4b1..59e3fe3d56c0 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -352,9 +352,6 @@ static int v9fs_file_flock_dotl(struct file *filp, int cmd,
352 invalidate_mapping_pages(&inode->i_data, 0, -1); 352 invalidate_mapping_pages(&inode->i_data, 0, -1);
353 } 353 }
354 /* Convert flock to posix lock */ 354 /* Convert flock to posix lock */
355 fl->fl_owner = (fl_owner_t)filp;
356 fl->fl_start = 0;
357 fl->fl_end = OFFSET_MAX;
358 fl->fl_flags |= FL_POSIX; 355 fl->fl_flags |= FL_POSIX;
359 fl->fl_flags ^= FL_FLOCK; 356 fl->fl_flags ^= FL_FLOCK;
360 357
diff --git a/fs/afs/flock.c b/fs/afs/flock.c
index a8cf2cff836c..4baf1d2b39e4 100644
--- a/fs/afs/flock.c
+++ b/fs/afs/flock.c
@@ -555,10 +555,6 @@ int afs_flock(struct file *file, int cmd, struct file_lock *fl)
555 return -ENOLCK; 555 return -ENOLCK;
556 556
557 /* we're simulating flock() locks using posix locks on the server */ 557 /* we're simulating flock() locks using posix locks on the server */
558 fl->fl_owner = (fl_owner_t) file;
559 fl->fl_start = 0;
560 fl->fl_end = OFFSET_MAX;
561
562 if (fl->fl_type == F_UNLCK) 558 if (fl->fl_type == F_UNLCK)
563 return afs_do_unlk(file, fl); 559 return afs_do_unlk(file, fl);
564 return afs_do_setlk(file, fl); 560 return afs_do_setlk(file, fl);
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c
index 191398852a2e..fbc39c47bacd 100644
--- a/fs/ceph/locks.c
+++ b/fs/ceph/locks.c
@@ -53,10 +53,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
53 else 53 else
54 length = fl->fl_end - fl->fl_start + 1; 54 length = fl->fl_end - fl->fl_start + 1;
55 55
56 if (lock_type == CEPH_LOCK_FCNTL) 56 owner = secure_addr(fl->fl_owner);
57 owner = secure_addr(fl->fl_owner);
58 else
59 owner = secure_addr(fl->fl_file);
60 57
61 dout("ceph_lock_message: rule: %d, op: %d, owner: %llx, pid: %llu, " 58 dout("ceph_lock_message: rule: %d, op: %d, owner: %llx, pid: %llu, "
62 "start: %llu, length: %llu, wait: %d, type: %d", (int)lock_type, 59 "start: %llu, length: %llu, wait: %d, type: %d", (int)lock_type,
@@ -314,10 +311,7 @@ int lock_to_ceph_filelock(struct file_lock *lock,
314 cephlock->length = cpu_to_le64(lock->fl_end - lock->fl_start + 1); 311 cephlock->length = cpu_to_le64(lock->fl_end - lock->fl_start + 1);
315 cephlock->client = cpu_to_le64(0); 312 cephlock->client = cpu_to_le64(0);
316 cephlock->pid = cpu_to_le64((u64)lock->fl_pid); 313 cephlock->pid = cpu_to_le64((u64)lock->fl_pid);
317 if (lock->fl_flags & FL_POSIX) 314 cephlock->owner = cpu_to_le64(secure_addr(lock->fl_owner));
318 cephlock->owner = cpu_to_le64(secure_addr(lock->fl_owner));
319 else
320 cephlock->owner = cpu_to_le64(secure_addr(lock->fl_file));
321 315
322 switch (lock->fl_type) { 316 switch (lock->fl_type) {
323 case F_RDLCK: 317 case F_RDLCK:
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 96d513e01a5d..f680d2c44e97 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -2304,7 +2304,6 @@ static int fuse_file_flock(struct file *file, int cmd, struct file_lock *fl)
2304 struct fuse_file *ff = file->private_data; 2304 struct fuse_file *ff = file->private_data;
2305 2305
2306 /* emulate flock with POSIX locks */ 2306 /* emulate flock with POSIX locks */
2307 fl->fl_owner = (fl_owner_t) file;
2308 ff->flock = true; 2307 ff->flock = true;
2309 err = fuse_setlk(file, fl, 1); 2308 err = fuse_setlk(file, fl, 1);
2310 } 2309 }
diff --git a/fs/locks.c b/fs/locks.c
index e390bd9ae068..da57c9b7e844 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -130,6 +130,9 @@
130#include <linux/percpu.h> 130#include <linux/percpu.h>
131#include <linux/lglock.h> 131#include <linux/lglock.h>
132 132
133#define CREATE_TRACE_POINTS
134#include <trace/events/filelock.h>
135
133#include <asm/uaccess.h> 136#include <asm/uaccess.h>
134 137
135#define IS_POSIX(fl) (fl->fl_flags & FL_POSIX) 138#define IS_POSIX(fl) (fl->fl_flags & FL_POSIX)
@@ -322,6 +325,7 @@ static int flock_make_lock(struct file *filp, struct file_lock **lock,
322 return -ENOMEM; 325 return -ENOMEM;
323 326
324 fl->fl_file = filp; 327 fl->fl_file = filp;
328 fl->fl_owner = (fl_owner_t)filp;
325 fl->fl_pid = current->tgid; 329 fl->fl_pid = current->tgid;
326 fl->fl_flags = FL_FLOCK; 330 fl->fl_flags = FL_FLOCK;
327 fl->fl_type = type; 331 fl->fl_type = type;
@@ -427,7 +431,7 @@ static int lease_init(struct file *filp, long type, struct file_lock *fl)
427 if (assign_type(fl, type) != 0) 431 if (assign_type(fl, type) != 0)
428 return -EINVAL; 432 return -EINVAL;
429 433
430 fl->fl_owner = current->files; 434 fl->fl_owner = (fl_owner_t)filp;
431 fl->fl_pid = current->tgid; 435 fl->fl_pid = current->tgid;
432 436
433 fl->fl_file = filp; 437 fl->fl_file = filp;
@@ -1286,6 +1290,7 @@ static void time_out_leases(struct inode *inode)
1286 1290
1287 before = &inode->i_flock; 1291 before = &inode->i_flock;
1288 while ((fl = *before) && IS_LEASE(fl) && lease_breaking(fl)) { 1292 while ((fl = *before) && IS_LEASE(fl) && lease_breaking(fl)) {
1293 trace_time_out_leases(inode, fl);
1289 if (past_time(fl->fl_downgrade_time)) 1294 if (past_time(fl->fl_downgrade_time))
1290 lease_modify(before, F_RDLCK); 1295 lease_modify(before, F_RDLCK);
1291 if (past_time(fl->fl_break_time)) 1296 if (past_time(fl->fl_break_time))
@@ -1373,6 +1378,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
1373 } 1378 }
1374 1379
1375 if (i_have_this_lease || (mode & O_NONBLOCK)) { 1380 if (i_have_this_lease || (mode & O_NONBLOCK)) {
1381 trace_break_lease_noblock(inode, new_fl);
1376 error = -EWOULDBLOCK; 1382 error = -EWOULDBLOCK;
1377 goto out; 1383 goto out;
1378 } 1384 }
@@ -1384,10 +1390,12 @@ restart:
1384 if (break_time == 0) 1390 if (break_time == 0)
1385 break_time++; 1391 break_time++;
1386 locks_insert_block(flock, new_fl); 1392 locks_insert_block(flock, new_fl);
1393 trace_break_lease_block(inode, new_fl);
1387 spin_unlock(&inode->i_lock); 1394 spin_unlock(&inode->i_lock);
1388 error = wait_event_interruptible_timeout(new_fl->fl_wait, 1395 error = wait_event_interruptible_timeout(new_fl->fl_wait,
1389 !new_fl->fl_next, break_time); 1396 !new_fl->fl_next, break_time);
1390 spin_lock(&inode->i_lock); 1397 spin_lock(&inode->i_lock);
1398 trace_break_lease_unblock(inode, new_fl);
1391 locks_delete_block(new_fl); 1399 locks_delete_block(new_fl);
1392 if (error >= 0) { 1400 if (error >= 0) {
1393 if (error == 0) 1401 if (error == 0)
@@ -1509,6 +1517,8 @@ static int generic_add_lease(struct file *filp, long arg, struct file_lock **flp
1509 int error; 1517 int error;
1510 1518
1511 lease = *flp; 1519 lease = *flp;
1520 trace_generic_add_lease(inode, lease);
1521
1512 /* 1522 /*
1513 * In the delegation case we need mutual exclusion with 1523 * In the delegation case we need mutual exclusion with
1514 * a number of operations that take the i_mutex. We trylock 1524 * a number of operations that take the i_mutex. We trylock
@@ -1598,6 +1608,8 @@ static int generic_delete_lease(struct file *filp, struct file_lock **flp)
1598 struct dentry *dentry = filp->f_path.dentry; 1608 struct dentry *dentry = filp->f_path.dentry;
1599 struct inode *inode = dentry->d_inode; 1609 struct inode *inode = dentry->d_inode;
1600 1610
1611 trace_generic_delete_lease(inode, *flp);
1612
1601 for (before = &inode->i_flock; 1613 for (before = &inode->i_flock;
1602 ((fl = *before) != NULL) && IS_LEASE(fl); 1614 ((fl = *before) != NULL) && IS_LEASE(fl);
1603 before = &fl->fl_next) { 1615 before = &fl->fl_next) {
@@ -2316,6 +2328,7 @@ void locks_remove_file(struct file *filp)
2316 2328
2317 if (filp->f_op->flock) { 2329 if (filp->f_op->flock) {
2318 struct file_lock fl = { 2330 struct file_lock fl = {
2331 .fl_owner = (fl_owner_t)filp,
2319 .fl_pid = current->tgid, 2332 .fl_pid = current->tgid,
2320 .fl_file = filp, 2333 .fl_file = filp,
2321 .fl_flags = FL_FLOCK, 2334 .fl_flags = FL_FLOCK,
@@ -2423,31 +2436,31 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
2423 seq_printf(f, "%lld:%s ", id, pfx); 2436 seq_printf(f, "%lld:%s ", id, pfx);
2424 if (IS_POSIX(fl)) { 2437 if (IS_POSIX(fl)) {
2425 if (fl->fl_flags & FL_ACCESS) 2438 if (fl->fl_flags & FL_ACCESS)
2426 seq_printf(f, "ACCESS"); 2439 seq_puts(f, "ACCESS");
2427 else if (IS_OFDLCK(fl)) 2440 else if (IS_OFDLCK(fl))
2428 seq_printf(f, "OFDLCK"); 2441 seq_puts(f, "OFDLCK");
2429 else 2442 else
2430 seq_printf(f, "POSIX "); 2443 seq_puts(f, "POSIX ");
2431 2444
2432 seq_printf(f, " %s ", 2445 seq_printf(f, " %s ",
2433 (inode == NULL) ? "*NOINODE*" : 2446 (inode == NULL) ? "*NOINODE*" :
2434 mandatory_lock(inode) ? "MANDATORY" : "ADVISORY "); 2447 mandatory_lock(inode) ? "MANDATORY" : "ADVISORY ");
2435 } else if (IS_FLOCK(fl)) { 2448 } else if (IS_FLOCK(fl)) {
2436 if (fl->fl_type & LOCK_MAND) { 2449 if (fl->fl_type & LOCK_MAND) {
2437 seq_printf(f, "FLOCK MSNFS "); 2450 seq_puts(f, "FLOCK MSNFS ");
2438 } else { 2451 } else {
2439 seq_printf(f, "FLOCK ADVISORY "); 2452 seq_puts(f, "FLOCK ADVISORY ");
2440 } 2453 }
2441 } else if (IS_LEASE(fl)) { 2454 } else if (IS_LEASE(fl)) {
2442 seq_printf(f, "LEASE "); 2455 seq_puts(f, "LEASE ");
2443 if (lease_breaking(fl)) 2456 if (lease_breaking(fl))
2444 seq_printf(f, "BREAKING "); 2457 seq_puts(f, "BREAKING ");
2445 else if (fl->fl_file) 2458 else if (fl->fl_file)
2446 seq_printf(f, "ACTIVE "); 2459 seq_puts(f, "ACTIVE ");
2447 else 2460 else
2448 seq_printf(f, "BREAKER "); 2461 seq_puts(f, "BREAKER ");
2449 } else { 2462 } else {
2450 seq_printf(f, "UNKNOWN UNKNOWN "); 2463 seq_puts(f, "UNKNOWN UNKNOWN ");
2451 } 2464 }
2452 if (fl->fl_type & LOCK_MAND) { 2465 if (fl->fl_type & LOCK_MAND) {
2453 seq_printf(f, "%s ", 2466 seq_printf(f, "%s ",
@@ -2479,7 +2492,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
2479 else 2492 else
2480 seq_printf(f, "%Ld %Ld\n", fl->fl_start, fl->fl_end); 2493 seq_printf(f, "%Ld %Ld\n", fl->fl_start, fl->fl_end);
2481 } else { 2494 } else {
2482 seq_printf(f, "0 EOF\n"); 2495 seq_puts(f, "0 EOF\n");
2483 } 2496 }
2484} 2497}
2485 2498
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 284ca901fe16..c1edf7336315 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -916,10 +916,6 @@ int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
916 is_local = 1; 916 is_local = 1;
917 917
918 /* We're simulating flock() locks using posix locks on the server */ 918 /* We're simulating flock() locks using posix locks on the server */
919 fl->fl_owner = (fl_owner_t)filp;
920 fl->fl_start = 0;
921 fl->fl_end = OFFSET_MAX;
922
923 if (fl->fl_type == F_UNLCK) 919 if (fl->fl_type == F_UNLCK)
924 return do_unlk(filp, cmd, fl, is_local); 920 return do_unlk(filp, cmd, fl, is_local);
925 return do_setlk(filp, cmd, fl, is_local); 921 return do_setlk(filp, cmd, fl, is_local);
diff --git a/include/trace/events/filelock.h b/include/trace/events/filelock.h
new file mode 100644
index 000000000000..59d11c22f076
--- /dev/null
+++ b/include/trace/events/filelock.h
@@ -0,0 +1,96 @@
1/*
2 * Events for filesystem locks
3 *
4 * Copyright 2013 Jeff Layton <jlayton@poochiereds.net>
5 */
6#undef TRACE_SYSTEM
7#define TRACE_SYSTEM filelock
8
9#if !defined(_TRACE_FILELOCK_H) || defined(TRACE_HEADER_MULTI_READ)
10#define _TRACE_FILELOCK_H
11
12#include <linux/tracepoint.h>
13#include <linux/fs.h>
14#include <linux/device.h>
15#include <linux/kdev_t.h>
16
17#define show_fl_flags(val) \
18 __print_flags(val, "|", \
19 { FL_POSIX, "FL_POSIX" }, \
20 { FL_FLOCK, "FL_FLOCK" }, \
21 { FL_DELEG, "FL_DELEG" }, \
22 { FL_ACCESS, "FL_ACCESS" }, \
23 { FL_EXISTS, "FL_EXISTS" }, \
24 { FL_LEASE, "FL_LEASE" }, \
25 { FL_CLOSE, "FL_CLOSE" }, \
26 { FL_SLEEP, "FL_SLEEP" }, \
27 { FL_DOWNGRADE_PENDING, "FL_DOWNGRADE_PENDING" }, \
28 { FL_UNLOCK_PENDING, "FL_UNLOCK_PENDING" }, \
29 { FL_OFDLCK, "FL_OFDLCK" })
30
31#define show_fl_type(val) \
32 __print_symbolic(val, \
33 { F_RDLCK, "F_RDLCK" }, \
34 { F_WRLCK, "F_WRLCK" }, \
35 { F_UNLCK, "F_UNLCK" })
36
37DECLARE_EVENT_CLASS(filelock_lease,
38
39 TP_PROTO(struct inode *inode, struct file_lock *fl),
40
41 TP_ARGS(inode, fl),
42
43 TP_STRUCT__entry(
44 __field(struct file_lock *, fl)
45 __field(unsigned long, i_ino)
46 __field(dev_t, s_dev)
47 __field(struct file_lock *, fl_next)
48 __field(fl_owner_t, fl_owner)
49 __field(unsigned int, fl_flags)
50 __field(unsigned char, fl_type)
51 __field(unsigned long, fl_break_time)
52 __field(unsigned long, fl_downgrade_time)
53 ),
54
55 TP_fast_assign(
56 __entry->fl = fl;
57 __entry->s_dev = inode->i_sb->s_dev;
58 __entry->i_ino = inode->i_ino;
59 __entry->fl_next = fl->fl_next;
60 __entry->fl_owner = fl->fl_owner;
61 __entry->fl_flags = fl->fl_flags;
62 __entry->fl_type = fl->fl_type;
63 __entry->fl_break_time = fl->fl_break_time;
64 __entry->fl_downgrade_time = fl->fl_downgrade_time;
65 ),
66
67 TP_printk("fl=0x%p dev=0x%x:0x%x ino=0x%lx fl_next=0x%p fl_owner=0x%p fl_flags=%s fl_type=%s fl_break_time=%lu fl_downgrade_time=%lu",
68 __entry->fl, MAJOR(__entry->s_dev), MINOR(__entry->s_dev),
69 __entry->i_ino, __entry->fl_next, __entry->fl_owner,
70 show_fl_flags(__entry->fl_flags),
71 show_fl_type(__entry->fl_type),
72 __entry->fl_break_time, __entry->fl_downgrade_time)
73);
74
75DEFINE_EVENT(filelock_lease, break_lease_noblock, TP_PROTO(struct inode *inode, struct file_lock *fl),
76 TP_ARGS(inode, fl));
77
78DEFINE_EVENT(filelock_lease, break_lease_block, TP_PROTO(struct inode *inode, struct file_lock *fl),
79 TP_ARGS(inode, fl));
80
81DEFINE_EVENT(filelock_lease, break_lease_unblock, TP_PROTO(struct inode *inode, struct file_lock *fl),
82 TP_ARGS(inode, fl));
83
84DEFINE_EVENT(filelock_lease, generic_add_lease, TP_PROTO(struct inode *inode, struct file_lock *fl),
85 TP_ARGS(inode, fl));
86
87DEFINE_EVENT(filelock_lease, generic_delete_lease, TP_PROTO(struct inode *inode, struct file_lock *fl),
88 TP_ARGS(inode, fl));
89
90DEFINE_EVENT(filelock_lease, time_out_leases, TP_PROTO(struct inode *inode, struct file_lock *fl),
91 TP_ARGS(inode, fl));
92
93#endif /* _TRACE_FILELOCK_H */
94
95/* This part must be outside protection */
96#include <trace/define_trace.h>