forked from Minki/linux
File locking related changes for v3.16
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJTjlWzAAoJEAAOaEEZVoIV4TAP/0EMmOBZLwIxNdj2Tfpx5dko qD+pvC/0udIKbPXeUgb+u84zR37NPBsNFH0cpsheTlmP1rLykNaguCPMru3ngu9o M3oGg8X6jzkknrWvU0NDVtXCIpHSNgKDv3KKAJwRaJHOkLKIzmUugnuNE5WnGfBa ZpZ3UAOe6GCu5RSKPhkmqLV+wrq0dm2NjkoIu+zavK29n3ggnXOT4BOb5OuuyinA pKGOC3irGRERXbcNAqS3LU5wPdA2dQjdZaw38XPsmrQhZlBdVpToRFUoCli+RMLS zmYm2eYQztKkzq8LqOchJAozLgfzhIGvIR54Q/H/gTdbB6kGCpKENAZ+UY4smkJH en6GldjyOIPF7g509bxhuq3Gs68gI5Jwqikgd0pP8U76qrYDS5KBBA0UTSSyJfEc Xn6xn+n4qrQDQt2p/IN8LEYBNL1VAuHLT50Q1ZhbI6hSrbaByDUcY+ikqg6hvTyw xLb1IrtZD9bB4YgYOa/wRk+d1VAdWTgwlRZz4nnP+PRaTqaQ63lOhIF619+sL1xy UVDNrT+LikmFjk5wW0f3o+Xjplbd0FD50Ybhzc03zkdu3Q/MbfGICjYZIhCULDTa 6Dhg7xogwGCsN/fhm0+QXGfQp61mXzbpFM4femwrjsELFM+/VEyO9zE46Kh6luz8 a1syHZ9UsObXD1nBSO0o =lgS1 -----END PGP SIGNATURE----- Merge tag 'locks-v3.16' of git://git.samba.org/jlayton/linux into next Pull file locking changes from Jeff Layton: "Pretty quiet on the file-locking related front this cycle. Just some small cleanups and the addition of some tracepoints in the lease handling code" * tag 'locks-v3.16' of git://git.samba.org/jlayton/linux: locks: add some tracepoints in the lease handling code fs/locks.c: replace seq_printf by seq_puts locks: ensure that fl_owner is always initialized properly in flock and lease codepaths
This commit is contained in:
commit
74efa045f4
@ -2706,20 +2706,15 @@ ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
|
||||
|
||||
ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_FLOCK, 1);
|
||||
|
||||
if (file_lock->fl_flags & FL_FLOCK) {
|
||||
if (file_lock->fl_flags & FL_FLOCK)
|
||||
LASSERT((cmd == F_SETLKW) || (cmd == F_SETLK));
|
||||
/* flocks are whole-file locks */
|
||||
flock.l_flock.end = OFFSET_MAX;
|
||||
/* For flocks owner is determined by the local file descriptor*/
|
||||
flock.l_flock.owner = (unsigned long)file_lock->fl_file;
|
||||
} else if (file_lock->fl_flags & FL_POSIX) {
|
||||
else if (!(file_lock->fl_flags & FL_POSIX))
|
||||
return -EINVAL;
|
||||
|
||||
flock.l_flock.owner = (unsigned long)file_lock->fl_owner;
|
||||
flock.l_flock.pid = file_lock->fl_pid;
|
||||
flock.l_flock.start = file_lock->fl_start;
|
||||
flock.l_flock.end = file_lock->fl_end;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
flock.l_flock.pid = file_lock->fl_pid;
|
||||
|
||||
/* Somewhat ugly workaround for svc lockd.
|
||||
* lockd installs custom fl_lmops->lm_compare_owner that checks
|
||||
|
@ -352,9 +352,6 @@ static int v9fs_file_flock_dotl(struct file *filp, int cmd,
|
||||
invalidate_mapping_pages(&inode->i_data, 0, -1);
|
||||
}
|
||||
/* Convert flock to posix lock */
|
||||
fl->fl_owner = (fl_owner_t)filp;
|
||||
fl->fl_start = 0;
|
||||
fl->fl_end = OFFSET_MAX;
|
||||
fl->fl_flags |= FL_POSIX;
|
||||
fl->fl_flags ^= FL_FLOCK;
|
||||
|
||||
|
@ -555,10 +555,6 @@ int afs_flock(struct file *file, int cmd, struct file_lock *fl)
|
||||
return -ENOLCK;
|
||||
|
||||
/* we're simulating flock() locks using posix locks on the server */
|
||||
fl->fl_owner = (fl_owner_t) file;
|
||||
fl->fl_start = 0;
|
||||
fl->fl_end = OFFSET_MAX;
|
||||
|
||||
if (fl->fl_type == F_UNLCK)
|
||||
return afs_do_unlk(file, fl);
|
||||
return afs_do_setlk(file, fl);
|
||||
|
@ -53,10 +53,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
|
||||
else
|
||||
length = fl->fl_end - fl->fl_start + 1;
|
||||
|
||||
if (lock_type == CEPH_LOCK_FCNTL)
|
||||
owner = secure_addr(fl->fl_owner);
|
||||
else
|
||||
owner = secure_addr(fl->fl_file);
|
||||
|
||||
dout("ceph_lock_message: rule: %d, op: %d, owner: %llx, pid: %llu, "
|
||||
"start: %llu, length: %llu, wait: %d, type: %d", (int)lock_type,
|
||||
@ -314,10 +311,7 @@ int lock_to_ceph_filelock(struct file_lock *lock,
|
||||
cephlock->length = cpu_to_le64(lock->fl_end - lock->fl_start + 1);
|
||||
cephlock->client = cpu_to_le64(0);
|
||||
cephlock->pid = cpu_to_le64((u64)lock->fl_pid);
|
||||
if (lock->fl_flags & FL_POSIX)
|
||||
cephlock->owner = cpu_to_le64(secure_addr(lock->fl_owner));
|
||||
else
|
||||
cephlock->owner = cpu_to_le64(secure_addr(lock->fl_file));
|
||||
|
||||
switch (lock->fl_type) {
|
||||
case F_RDLCK:
|
||||
|
@ -2304,7 +2304,6 @@ static int fuse_file_flock(struct file *file, int cmd, struct file_lock *fl)
|
||||
struct fuse_file *ff = file->private_data;
|
||||
|
||||
/* emulate flock with POSIX locks */
|
||||
fl->fl_owner = (fl_owner_t) file;
|
||||
ff->flock = true;
|
||||
err = fuse_setlk(file, fl, 1);
|
||||
}
|
||||
|
37
fs/locks.c
37
fs/locks.c
@ -130,6 +130,9 @@
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/lglock.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/filelock.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#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,
|
||||
return -ENOMEM;
|
||||
|
||||
fl->fl_file = filp;
|
||||
fl->fl_owner = (fl_owner_t)filp;
|
||||
fl->fl_pid = current->tgid;
|
||||
fl->fl_flags = FL_FLOCK;
|
||||
fl->fl_type = type;
|
||||
@ -427,7 +431,7 @@ static int lease_init(struct file *filp, long type, struct file_lock *fl)
|
||||
if (assign_type(fl, type) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
fl->fl_owner = current->files;
|
||||
fl->fl_owner = (fl_owner_t)filp;
|
||||
fl->fl_pid = current->tgid;
|
||||
|
||||
fl->fl_file = filp;
|
||||
@ -1286,6 +1290,7 @@ static void time_out_leases(struct inode *inode)
|
||||
|
||||
before = &inode->i_flock;
|
||||
while ((fl = *before) && IS_LEASE(fl) && lease_breaking(fl)) {
|
||||
trace_time_out_leases(inode, fl);
|
||||
if (past_time(fl->fl_downgrade_time))
|
||||
lease_modify(before, F_RDLCK);
|
||||
if (past_time(fl->fl_break_time))
|
||||
@ -1373,6 +1378,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
|
||||
}
|
||||
|
||||
if (i_have_this_lease || (mode & O_NONBLOCK)) {
|
||||
trace_break_lease_noblock(inode, new_fl);
|
||||
error = -EWOULDBLOCK;
|
||||
goto out;
|
||||
}
|
||||
@ -1384,10 +1390,12 @@ restart:
|
||||
if (break_time == 0)
|
||||
break_time++;
|
||||
locks_insert_block(flock, new_fl);
|
||||
trace_break_lease_block(inode, new_fl);
|
||||
spin_unlock(&inode->i_lock);
|
||||
error = wait_event_interruptible_timeout(new_fl->fl_wait,
|
||||
!new_fl->fl_next, break_time);
|
||||
spin_lock(&inode->i_lock);
|
||||
trace_break_lease_unblock(inode, new_fl);
|
||||
locks_delete_block(new_fl);
|
||||
if (error >= 0) {
|
||||
if (error == 0)
|
||||
@ -1509,6 +1517,8 @@ static int generic_add_lease(struct file *filp, long arg, struct file_lock **flp
|
||||
int error;
|
||||
|
||||
lease = *flp;
|
||||
trace_generic_add_lease(inode, lease);
|
||||
|
||||
/*
|
||||
* In the delegation case we need mutual exclusion with
|
||||
* 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)
|
||||
struct dentry *dentry = filp->f_path.dentry;
|
||||
struct inode *inode = dentry->d_inode;
|
||||
|
||||
trace_generic_delete_lease(inode, *flp);
|
||||
|
||||
for (before = &inode->i_flock;
|
||||
((fl = *before) != NULL) && IS_LEASE(fl);
|
||||
before = &fl->fl_next) {
|
||||
@ -2316,6 +2328,7 @@ void locks_remove_file(struct file *filp)
|
||||
|
||||
if (filp->f_op->flock) {
|
||||
struct file_lock fl = {
|
||||
.fl_owner = (fl_owner_t)filp,
|
||||
.fl_pid = current->tgid,
|
||||
.fl_file = filp,
|
||||
.fl_flags = FL_FLOCK,
|
||||
@ -2423,31 +2436,31 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
|
||||
seq_printf(f, "%lld:%s ", id, pfx);
|
||||
if (IS_POSIX(fl)) {
|
||||
if (fl->fl_flags & FL_ACCESS)
|
||||
seq_printf(f, "ACCESS");
|
||||
seq_puts(f, "ACCESS");
|
||||
else if (IS_OFDLCK(fl))
|
||||
seq_printf(f, "OFDLCK");
|
||||
seq_puts(f, "OFDLCK");
|
||||
else
|
||||
seq_printf(f, "POSIX ");
|
||||
seq_puts(f, "POSIX ");
|
||||
|
||||
seq_printf(f, " %s ",
|
||||
(inode == NULL) ? "*NOINODE*" :
|
||||
mandatory_lock(inode) ? "MANDATORY" : "ADVISORY ");
|
||||
} else if (IS_FLOCK(fl)) {
|
||||
if (fl->fl_type & LOCK_MAND) {
|
||||
seq_printf(f, "FLOCK MSNFS ");
|
||||
seq_puts(f, "FLOCK MSNFS ");
|
||||
} else {
|
||||
seq_printf(f, "FLOCK ADVISORY ");
|
||||
seq_puts(f, "FLOCK ADVISORY ");
|
||||
}
|
||||
} else if (IS_LEASE(fl)) {
|
||||
seq_printf(f, "LEASE ");
|
||||
seq_puts(f, "LEASE ");
|
||||
if (lease_breaking(fl))
|
||||
seq_printf(f, "BREAKING ");
|
||||
seq_puts(f, "BREAKING ");
|
||||
else if (fl->fl_file)
|
||||
seq_printf(f, "ACTIVE ");
|
||||
seq_puts(f, "ACTIVE ");
|
||||
else
|
||||
seq_printf(f, "BREAKER ");
|
||||
seq_puts(f, "BREAKER ");
|
||||
} else {
|
||||
seq_printf(f, "UNKNOWN UNKNOWN ");
|
||||
seq_puts(f, "UNKNOWN UNKNOWN ");
|
||||
}
|
||||
if (fl->fl_type & LOCK_MAND) {
|
||||
seq_printf(f, "%s ",
|
||||
@ -2479,7 +2492,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
|
||||
else
|
||||
seq_printf(f, "%Ld %Ld\n", fl->fl_start, fl->fl_end);
|
||||
} else {
|
||||
seq_printf(f, "0 EOF\n");
|
||||
seq_puts(f, "0 EOF\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -916,10 +916,6 @@ int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
|
||||
is_local = 1;
|
||||
|
||||
/* We're simulating flock() locks using posix locks on the server */
|
||||
fl->fl_owner = (fl_owner_t)filp;
|
||||
fl->fl_start = 0;
|
||||
fl->fl_end = OFFSET_MAX;
|
||||
|
||||
if (fl->fl_type == F_UNLCK)
|
||||
return do_unlk(filp, cmd, fl, is_local);
|
||||
return do_setlk(filp, cmd, fl, is_local);
|
||||
|
96
include/trace/events/filelock.h
Normal file
96
include/trace/events/filelock.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Events for filesystem locks
|
||||
*
|
||||
* Copyright 2013 Jeff Layton <jlayton@poochiereds.net>
|
||||
*/
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM filelock
|
||||
|
||||
#if !defined(_TRACE_FILELOCK_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define _TRACE_FILELOCK_H
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kdev_t.h>
|
||||
|
||||
#define show_fl_flags(val) \
|
||||
__print_flags(val, "|", \
|
||||
{ FL_POSIX, "FL_POSIX" }, \
|
||||
{ FL_FLOCK, "FL_FLOCK" }, \
|
||||
{ FL_DELEG, "FL_DELEG" }, \
|
||||
{ FL_ACCESS, "FL_ACCESS" }, \
|
||||
{ FL_EXISTS, "FL_EXISTS" }, \
|
||||
{ FL_LEASE, "FL_LEASE" }, \
|
||||
{ FL_CLOSE, "FL_CLOSE" }, \
|
||||
{ FL_SLEEP, "FL_SLEEP" }, \
|
||||
{ FL_DOWNGRADE_PENDING, "FL_DOWNGRADE_PENDING" }, \
|
||||
{ FL_UNLOCK_PENDING, "FL_UNLOCK_PENDING" }, \
|
||||
{ FL_OFDLCK, "FL_OFDLCK" })
|
||||
|
||||
#define show_fl_type(val) \
|
||||
__print_symbolic(val, \
|
||||
{ F_RDLCK, "F_RDLCK" }, \
|
||||
{ F_WRLCK, "F_WRLCK" }, \
|
||||
{ F_UNLCK, "F_UNLCK" })
|
||||
|
||||
DECLARE_EVENT_CLASS(filelock_lease,
|
||||
|
||||
TP_PROTO(struct inode *inode, struct file_lock *fl),
|
||||
|
||||
TP_ARGS(inode, fl),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(struct file_lock *, fl)
|
||||
__field(unsigned long, i_ino)
|
||||
__field(dev_t, s_dev)
|
||||
__field(struct file_lock *, fl_next)
|
||||
__field(fl_owner_t, fl_owner)
|
||||
__field(unsigned int, fl_flags)
|
||||
__field(unsigned char, fl_type)
|
||||
__field(unsigned long, fl_break_time)
|
||||
__field(unsigned long, fl_downgrade_time)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->fl = fl;
|
||||
__entry->s_dev = inode->i_sb->s_dev;
|
||||
__entry->i_ino = inode->i_ino;
|
||||
__entry->fl_next = fl->fl_next;
|
||||
__entry->fl_owner = fl->fl_owner;
|
||||
__entry->fl_flags = fl->fl_flags;
|
||||
__entry->fl_type = fl->fl_type;
|
||||
__entry->fl_break_time = fl->fl_break_time;
|
||||
__entry->fl_downgrade_time = fl->fl_downgrade_time;
|
||||
),
|
||||
|
||||
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",
|
||||
__entry->fl, MAJOR(__entry->s_dev), MINOR(__entry->s_dev),
|
||||
__entry->i_ino, __entry->fl_next, __entry->fl_owner,
|
||||
show_fl_flags(__entry->fl_flags),
|
||||
show_fl_type(__entry->fl_type),
|
||||
__entry->fl_break_time, __entry->fl_downgrade_time)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(filelock_lease, break_lease_noblock, TP_PROTO(struct inode *inode, struct file_lock *fl),
|
||||
TP_ARGS(inode, fl));
|
||||
|
||||
DEFINE_EVENT(filelock_lease, break_lease_block, TP_PROTO(struct inode *inode, struct file_lock *fl),
|
||||
TP_ARGS(inode, fl));
|
||||
|
||||
DEFINE_EVENT(filelock_lease, break_lease_unblock, TP_PROTO(struct inode *inode, struct file_lock *fl),
|
||||
TP_ARGS(inode, fl));
|
||||
|
||||
DEFINE_EVENT(filelock_lease, generic_add_lease, TP_PROTO(struct inode *inode, struct file_lock *fl),
|
||||
TP_ARGS(inode, fl));
|
||||
|
||||
DEFINE_EVENT(filelock_lease, generic_delete_lease, TP_PROTO(struct inode *inode, struct file_lock *fl),
|
||||
TP_ARGS(inode, fl));
|
||||
|
||||
DEFINE_EVENT(filelock_lease, time_out_leases, TP_PROTO(struct inode *inode, struct file_lock *fl),
|
||||
TP_ARGS(inode, fl));
|
||||
|
||||
#endif /* _TRACE_FILELOCK_H */
|
||||
|
||||
/* This part must be outside protection */
|
||||
#include <trace/define_trace.h>
|
Loading…
Reference in New Issue
Block a user