diff options
author | Jerome Marchand <jmarchan@redhat.com> | 2010-10-26 17:22:33 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-26 19:52:13 -0400 |
commit | 99dc829256bb8cfcb1f58b7f118893fdbf608e60 (patch) | |
tree | 07c5b353965b1ead7183bd01c0b48903ded0d8af /fs/locks.c | |
parent | 4199ca77cc44c418972e8f30a36be7d26d21a0d2 (diff) |
procfs: fix numbering in /proc/locks
The lock number in /proc/locks (first field) is implemented by a counter
(private field of struct seq_file) which is incremented at each call of
locks_show() and reset to 1 in locks_start() whatever the offset is. It
should be reset according to the actual position in the list. Because of
this, the numbering erratically restarts at 1 several times when reading a
long /proc/locks file.
Moreover, locks_show() can be called twice to print a single line thus
skipping a number. The counter should be incremented in locks_next().
And last, pos is a loff_t, which can be bigger than a pointer, so we don't
use the pointer as an integer anymore, and allocate a loff_t instead.
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
Cc: Pavel Emelyanov <xemul@parallels.com>
Cc: Matthew Wilcox <matthew@wil.cx>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/locks.c')
-rw-r--r-- | fs/locks.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/fs/locks.c b/fs/locks.c index 8b2b6ad56a09..4de3a2666810 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -2109,7 +2109,7 @@ EXPORT_SYMBOL_GPL(vfs_cancel_lock); | |||
2109 | #include <linux/seq_file.h> | 2109 | #include <linux/seq_file.h> |
2110 | 2110 | ||
2111 | static void lock_get_status(struct seq_file *f, struct file_lock *fl, | 2111 | static void lock_get_status(struct seq_file *f, struct file_lock *fl, |
2112 | int id, char *pfx) | 2112 | loff_t id, char *pfx) |
2113 | { | 2113 | { |
2114 | struct inode *inode = NULL; | 2114 | struct inode *inode = NULL; |
2115 | unsigned int fl_pid; | 2115 | unsigned int fl_pid; |
@@ -2122,7 +2122,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl, | |||
2122 | if (fl->fl_file != NULL) | 2122 | if (fl->fl_file != NULL) |
2123 | inode = fl->fl_file->f_path.dentry->d_inode; | 2123 | inode = fl->fl_file->f_path.dentry->d_inode; |
2124 | 2124 | ||
2125 | seq_printf(f, "%d:%s ", id, pfx); | 2125 | seq_printf(f, "%lld:%s ", id, pfx); |
2126 | if (IS_POSIX(fl)) { | 2126 | if (IS_POSIX(fl)) { |
2127 | seq_printf(f, "%6s %s ", | 2127 | seq_printf(f, "%6s %s ", |
2128 | (fl->fl_flags & FL_ACCESS) ? "ACCESS" : "POSIX ", | 2128 | (fl->fl_flags & FL_ACCESS) ? "ACCESS" : "POSIX ", |
@@ -2185,24 +2185,27 @@ static int locks_show(struct seq_file *f, void *v) | |||
2185 | 2185 | ||
2186 | fl = list_entry(v, struct file_lock, fl_link); | 2186 | fl = list_entry(v, struct file_lock, fl_link); |
2187 | 2187 | ||
2188 | lock_get_status(f, fl, (long)f->private, ""); | 2188 | lock_get_status(f, fl, *((loff_t *)f->private), ""); |
2189 | 2189 | ||
2190 | list_for_each_entry(bfl, &fl->fl_block, fl_block) | 2190 | list_for_each_entry(bfl, &fl->fl_block, fl_block) |
2191 | lock_get_status(f, bfl, (long)f->private, " ->"); | 2191 | lock_get_status(f, bfl, *((loff_t *)f->private), " ->"); |
2192 | 2192 | ||
2193 | f->private++; | ||
2194 | return 0; | 2193 | return 0; |
2195 | } | 2194 | } |
2196 | 2195 | ||
2197 | static void *locks_start(struct seq_file *f, loff_t *pos) | 2196 | static void *locks_start(struct seq_file *f, loff_t *pos) |
2198 | { | 2197 | { |
2198 | loff_t *p = f->private; | ||
2199 | |||
2199 | lock_flocks(); | 2200 | lock_flocks(); |
2200 | f->private = (void *)1; | 2201 | *p = (*pos + 1); |
2201 | return seq_list_start(&file_lock_list, *pos); | 2202 | return seq_list_start(&file_lock_list, *pos); |
2202 | } | 2203 | } |
2203 | 2204 | ||
2204 | static void *locks_next(struct seq_file *f, void *v, loff_t *pos) | 2205 | static void *locks_next(struct seq_file *f, void *v, loff_t *pos) |
2205 | { | 2206 | { |
2207 | loff_t *p = f->private; | ||
2208 | ++*p; | ||
2206 | return seq_list_next(v, &file_lock_list, pos); | 2209 | return seq_list_next(v, &file_lock_list, pos); |
2207 | } | 2210 | } |
2208 | 2211 | ||
@@ -2220,14 +2223,14 @@ static const struct seq_operations locks_seq_operations = { | |||
2220 | 2223 | ||
2221 | static int locks_open(struct inode *inode, struct file *filp) | 2224 | static int locks_open(struct inode *inode, struct file *filp) |
2222 | { | 2225 | { |
2223 | return seq_open(filp, &locks_seq_operations); | 2226 | return seq_open_private(filp, &locks_seq_operations, sizeof(loff_t)); |
2224 | } | 2227 | } |
2225 | 2228 | ||
2226 | static const struct file_operations proc_locks_operations = { | 2229 | static const struct file_operations proc_locks_operations = { |
2227 | .open = locks_open, | 2230 | .open = locks_open, |
2228 | .read = seq_read, | 2231 | .read = seq_read, |
2229 | .llseek = seq_lseek, | 2232 | .llseek = seq_lseek, |
2230 | .release = seq_release, | 2233 | .release = seq_release_private, |
2231 | }; | 2234 | }; |
2232 | 2235 | ||
2233 | static int __init proc_locks_init(void) | 2236 | static int __init proc_locks_init(void) |