locks: sprinkle some tracepoints around the file locking code
Add some tracepoints around the POSIX locking code. These were useful when tracking down problems when handling the race between setlk and close. Signed-off-by: Jeff Layton <jeff.layton@primarydata.com> Acked-by: "J. Bruce Fields" <bfields@fieldses.org>
This commit is contained in:
parent
0752ba807b
commit
1890910fd0
12
fs/locks.c
12
fs/locks.c
|
@ -229,6 +229,7 @@ locks_get_lock_context(struct inode *inode, int type)
|
||||||
ctx = smp_load_acquire(&inode->i_flctx);
|
ctx = smp_load_acquire(&inode->i_flctx);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
trace_locks_get_lock_context(inode, type, ctx);
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1141,6 +1142,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
|
||||||
if (new_fl2)
|
if (new_fl2)
|
||||||
locks_free_lock(new_fl2);
|
locks_free_lock(new_fl2);
|
||||||
locks_dispose_list(&dispose);
|
locks_dispose_list(&dispose);
|
||||||
|
trace_posix_lock_inode(inode, request, error);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2164,6 +2167,8 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
|
||||||
if (file_lock == NULL)
|
if (file_lock == NULL)
|
||||||
return -ENOLCK;
|
return -ENOLCK;
|
||||||
|
|
||||||
|
inode = file_inode(filp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This might block, so we do it before checking the inode.
|
* This might block, so we do it before checking the inode.
|
||||||
*/
|
*/
|
||||||
|
@ -2171,8 +2176,6 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
|
||||||
if (copy_from_user(&flock, l, sizeof(flock)))
|
if (copy_from_user(&flock, l, sizeof(flock)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
inode = file_inode(filp);
|
|
||||||
|
|
||||||
/* Don't allow mandatory locks on files that may be memory mapped
|
/* Don't allow mandatory locks on files that may be memory mapped
|
||||||
* and shared.
|
* and shared.
|
||||||
*/
|
*/
|
||||||
|
@ -2241,6 +2244,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
trace_fcntl_setlk(inode, file_lock, error);
|
||||||
locks_free_lock(file_lock);
|
locks_free_lock(file_lock);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -2397,6 +2401,7 @@ out:
|
||||||
*/
|
*/
|
||||||
void locks_remove_posix(struct file *filp, fl_owner_t owner)
|
void locks_remove_posix(struct file *filp, fl_owner_t owner)
|
||||||
{
|
{
|
||||||
|
int error;
|
||||||
struct file_lock lock;
|
struct file_lock lock;
|
||||||
struct file_lock_context *ctx;
|
struct file_lock_context *ctx;
|
||||||
|
|
||||||
|
@ -2419,10 +2424,11 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
|
||||||
lock.fl_ops = NULL;
|
lock.fl_ops = NULL;
|
||||||
lock.fl_lmops = NULL;
|
lock.fl_lmops = NULL;
|
||||||
|
|
||||||
vfs_lock_file(filp, F_SETLK, &lock, NULL);
|
error = vfs_lock_file(filp, F_SETLK, &lock, NULL);
|
||||||
|
|
||||||
if (lock.fl_ops && lock.fl_ops->fl_release_private)
|
if (lock.fl_ops && lock.fl_ops->fl_release_private)
|
||||||
lock.fl_ops->fl_release_private(&lock);
|
lock.fl_ops->fl_release_private(&lock);
|
||||||
|
trace_locks_remove_posix(file_inode(filp), &lock, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(locks_remove_posix);
|
EXPORT_SYMBOL(locks_remove_posix);
|
||||||
|
|
|
@ -34,6 +34,83 @@
|
||||||
{ F_WRLCK, "F_WRLCK" }, \
|
{ F_WRLCK, "F_WRLCK" }, \
|
||||||
{ F_UNLCK, "F_UNLCK" })
|
{ F_UNLCK, "F_UNLCK" })
|
||||||
|
|
||||||
|
TRACE_EVENT(locks_get_lock_context,
|
||||||
|
TP_PROTO(struct inode *inode, int type, struct file_lock_context *ctx),
|
||||||
|
|
||||||
|
TP_ARGS(inode, type, ctx),
|
||||||
|
|
||||||
|
TP_STRUCT__entry(
|
||||||
|
__field(unsigned long, i_ino)
|
||||||
|
__field(dev_t, s_dev)
|
||||||
|
__field(unsigned char, type)
|
||||||
|
__field(struct file_lock_context *, ctx)
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
__entry->s_dev = inode->i_sb->s_dev;
|
||||||
|
__entry->i_ino = inode->i_ino;
|
||||||
|
__entry->type = type;
|
||||||
|
__entry->ctx = ctx;
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk("dev=0x%x:0x%x ino=0x%lx type=%s ctx=%p",
|
||||||
|
MAJOR(__entry->s_dev), MINOR(__entry->s_dev),
|
||||||
|
__entry->i_ino, show_fl_type(__entry->type), __entry->ctx)
|
||||||
|
);
|
||||||
|
|
||||||
|
DECLARE_EVENT_CLASS(filelock_lock,
|
||||||
|
TP_PROTO(struct inode *inode, struct file_lock *fl, int ret),
|
||||||
|
|
||||||
|
TP_ARGS(inode, fl, ret),
|
||||||
|
|
||||||
|
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_pid)
|
||||||
|
__field(unsigned int, fl_flags)
|
||||||
|
__field(unsigned char, fl_type)
|
||||||
|
__field(loff_t, fl_start)
|
||||||
|
__field(loff_t, fl_end)
|
||||||
|
__field(int, ret)
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_fast_assign(
|
||||||
|
__entry->fl = fl ? fl : NULL;
|
||||||
|
__entry->s_dev = inode->i_sb->s_dev;
|
||||||
|
__entry->i_ino = inode->i_ino;
|
||||||
|
__entry->fl_next = fl ? fl->fl_next : NULL;
|
||||||
|
__entry->fl_owner = fl ? fl->fl_owner : NULL;
|
||||||
|
__entry->fl_pid = fl ? fl->fl_pid : 0;
|
||||||
|
__entry->fl_flags = fl ? fl->fl_flags : 0;
|
||||||
|
__entry->fl_type = fl ? fl->fl_type : 0;
|
||||||
|
__entry->fl_start = fl ? fl->fl_start : 0;
|
||||||
|
__entry->fl_end = fl ? fl->fl_end : 0;
|
||||||
|
__entry->ret = ret;
|
||||||
|
),
|
||||||
|
|
||||||
|
TP_printk("fl=0x%p dev=0x%x:0x%x ino=0x%lx fl_next=0x%p fl_owner=0x%p fl_pid=%u fl_flags=%s fl_type=%s fl_start=%lld fl_end=%lld ret=%d",
|
||||||
|
__entry->fl, MAJOR(__entry->s_dev), MINOR(__entry->s_dev),
|
||||||
|
__entry->i_ino, __entry->fl_next, __entry->fl_owner,
|
||||||
|
__entry->fl_pid, show_fl_flags(__entry->fl_flags),
|
||||||
|
show_fl_type(__entry->fl_type),
|
||||||
|
__entry->fl_start, __entry->fl_end, __entry->ret)
|
||||||
|
);
|
||||||
|
|
||||||
|
DEFINE_EVENT(filelock_lock, posix_lock_inode,
|
||||||
|
TP_PROTO(struct inode *inode, struct file_lock *fl, int ret),
|
||||||
|
TP_ARGS(inode, fl, ret));
|
||||||
|
|
||||||
|
DEFINE_EVENT(filelock_lock, fcntl_setlk,
|
||||||
|
TP_PROTO(struct inode *inode, struct file_lock *fl, int ret),
|
||||||
|
TP_ARGS(inode, fl, ret));
|
||||||
|
|
||||||
|
DEFINE_EVENT(filelock_lock, locks_remove_posix,
|
||||||
|
TP_PROTO(struct inode *inode, struct file_lock *fl, int ret),
|
||||||
|
TP_ARGS(inode, fl, ret));
|
||||||
|
|
||||||
DECLARE_EVENT_CLASS(filelock_lease,
|
DECLARE_EVENT_CLASS(filelock_lease,
|
||||||
|
|
||||||
TP_PROTO(struct inode *inode, struct file_lock *fl),
|
TP_PROTO(struct inode *inode, struct file_lock *fl),
|
||||||
|
|
Loading…
Reference in New Issue