aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/proc.txt4
-rw-r--r--fs/locks.c38
-rw-r--r--fs/proc/fd.c27
-rw-r--r--include/linux/fs.h7
4 files changed, 66 insertions, 10 deletions
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 6d370622fdfe..8e36c7e3c345 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -1709,6 +1709,10 @@ A typical output is
1709 flags: 0100002 1709 flags: 0100002
1710 mnt_id: 19 1710 mnt_id: 19
1711 1711
1712All locks associated with a file descriptor are shown in its fdinfo too.
1713
1714lock: 1: FLOCK ADVISORY WRITE 359 00:13:11691 0 EOF
1715
1712The files such as eventfd, fsnotify, signalfd, epoll among the regular pos/flags 1716The files such as eventfd, fsnotify, signalfd, epoll among the regular pos/flags
1713pair provide additional information particular to the objects they represent. 1717pair provide additional information particular to the objects they represent.
1714 1718
diff --git a/fs/locks.c b/fs/locks.c
index 52b780fb5258..653faabb07f4 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -2590,6 +2590,44 @@ static int locks_show(struct seq_file *f, void *v)
2590 return 0; 2590 return 0;
2591} 2591}
2592 2592
2593static void __show_fd_locks(struct seq_file *f,
2594 struct list_head *head, int *id,
2595 struct file *filp, struct files_struct *files)
2596{
2597 struct file_lock *fl;
2598
2599 list_for_each_entry(fl, head, fl_list) {
2600
2601 if (filp != fl->fl_file)
2602 continue;
2603 if (fl->fl_owner != files &&
2604 fl->fl_owner != filp)
2605 continue;
2606
2607 (*id)++;
2608 seq_puts(f, "lock:\t");
2609 lock_get_status(f, fl, *id, "");
2610 }
2611}
2612
2613void show_fd_locks(struct seq_file *f,
2614 struct file *filp, struct files_struct *files)
2615{
2616 struct inode *inode = file_inode(filp);
2617 struct file_lock_context *ctx;
2618 int id = 0;
2619
2620 ctx = inode->i_flctx;
2621 if (!ctx)
2622 return;
2623
2624 spin_lock(&ctx->flc_lock);
2625 __show_fd_locks(f, &ctx->flc_flock, &id, filp, files);
2626 __show_fd_locks(f, &ctx->flc_posix, &id, filp, files);
2627 __show_fd_locks(f, &ctx->flc_lease, &id, filp, files);
2628 spin_unlock(&ctx->flc_lock);
2629}
2630
2593static void *locks_start(struct seq_file *f, loff_t *pos) 2631static void *locks_start(struct seq_file *f, loff_t *pos)
2594 __acquires(&blocked_lock_lock) 2632 __acquires(&blocked_lock_lock)
2595{ 2633{
diff --git a/fs/proc/fd.c b/fs/proc/fd.c
index 8e5ad83b629a..af84ad04df77 100644
--- a/fs/proc/fd.c
+++ b/fs/proc/fd.c
@@ -8,6 +8,7 @@
8#include <linux/security.h> 8#include <linux/security.h>
9#include <linux/file.h> 9#include <linux/file.h>
10#include <linux/seq_file.h> 10#include <linux/seq_file.h>
11#include <linux/fs.h>
11 12
12#include <linux/proc_fs.h> 13#include <linux/proc_fs.h>
13 14
@@ -48,17 +49,23 @@ static int seq_show(struct seq_file *m, void *v)
48 put_files_struct(files); 49 put_files_struct(files);
49 } 50 }
50 51
51 if (!ret) { 52 if (ret)
52 seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\n", 53 return ret;
53 (long long)file->f_pos, f_flags,
54 real_mount(file->f_path.mnt)->mnt_id);
55 if (file->f_op->show_fdinfo)
56 file->f_op->show_fdinfo(m, file);
57 ret = seq_has_overflowed(m);
58 fput(file);
59 }
60 54
61 return ret; 55 seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\n",
56 (long long)file->f_pos, f_flags,
57 real_mount(file->f_path.mnt)->mnt_id);
58
59 show_fd_locks(m, file, files);
60 if (seq_has_overflowed(m))
61 goto out;
62
63 if (file->f_op->show_fdinfo)
64 file->f_op->show_fdinfo(m, file);
65
66out:
67 fput(file);
68 return 0;
62} 69}
63 70
64static int seq_fdinfo_open(struct inode *inode, struct file *file) 71static int seq_fdinfo_open(struct inode *inode, struct file *file)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6bf7ab7c1573..c4e927358503 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1042,6 +1042,9 @@ extern void lease_get_mtime(struct inode *, struct timespec *time);
1042extern int generic_setlease(struct file *, long, struct file_lock **, void **priv); 1042extern int generic_setlease(struct file *, long, struct file_lock **, void **priv);
1043extern int vfs_setlease(struct file *, long, struct file_lock **, void **); 1043extern int vfs_setlease(struct file *, long, struct file_lock **, void **);
1044extern int lease_modify(struct file_lock *, int, struct list_head *); 1044extern int lease_modify(struct file_lock *, int, struct list_head *);
1045struct files_struct;
1046extern void show_fd_locks(struct seq_file *f,
1047 struct file *filp, struct files_struct *files);
1045#else /* !CONFIG_FILE_LOCKING */ 1048#else /* !CONFIG_FILE_LOCKING */
1046static inline int fcntl_getlk(struct file *file, unsigned int cmd, 1049static inline int fcntl_getlk(struct file *file, unsigned int cmd,
1047 struct flock __user *user) 1050 struct flock __user *user)
@@ -1178,6 +1181,10 @@ static inline int lease_modify(struct file_lock *fl, int arg,
1178{ 1181{
1179 return -EINVAL; 1182 return -EINVAL;
1180} 1183}
1184
1185struct files_struct;
1186static inline void show_fd_locks(struct seq_file *f,
1187 struct file *filp, struct files_struct *files) {}
1181#endif /* !CONFIG_FILE_LOCKING */ 1188#endif /* !CONFIG_FILE_LOCKING */
1182 1189
1183 1190