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 | ||
