diff options
-rw-r--r-- | Documentation/filesystems/proc.txt | 4 | ||||
-rw-r--r-- | fs/locks.c | 38 | ||||
-rw-r--r-- | fs/proc/fd.c | 27 | ||||
-rw-r--r-- | include/linux/fs.h | 7 |
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 | ||
1712 | All locks associated with a file descriptor are shown in its fdinfo too. | ||
1713 | |||
1714 | lock: 1: FLOCK ADVISORY WRITE 359 00:13:11691 0 EOF | ||
1715 | |||
1712 | The files such as eventfd, fsnotify, signalfd, epoll among the regular pos/flags | 1716 | The files such as eventfd, fsnotify, signalfd, epoll among the regular pos/flags |
1713 | pair provide additional information particular to the objects they represent. | 1717 | pair 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 | ||
2593 | static 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 | |||
2613 | void 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 | |||
2593 | static void *locks_start(struct seq_file *f, loff_t *pos) | 2631 | static 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 | |||
66 | out: | ||
67 | fput(file); | ||
68 | return 0; | ||
62 | } | 69 | } |
63 | 70 | ||
64 | static int seq_fdinfo_open(struct inode *inode, struct file *file) | 71 | static 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); | |||
1042 | extern int generic_setlease(struct file *, long, struct file_lock **, void **priv); | 1042 | extern int generic_setlease(struct file *, long, struct file_lock **, void **priv); |
1043 | extern int vfs_setlease(struct file *, long, struct file_lock **, void **); | 1043 | extern int vfs_setlease(struct file *, long, struct file_lock **, void **); |
1044 | extern int lease_modify(struct file_lock *, int, struct list_head *); | 1044 | extern int lease_modify(struct file_lock *, int, struct list_head *); |
1045 | struct files_struct; | ||
1046 | extern 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 */ |
1046 | static inline int fcntl_getlk(struct file *file, unsigned int cmd, | 1049 | static 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 | |||
1185 | struct files_struct; | ||
1186 | static 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 | ||