aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/locks.c122
-rw-r--r--fs/proc/proc_misc.c19
-rw-r--r--include/linux/fs.h1
3 files changed, 62 insertions, 80 deletions
diff --git a/fs/locks.c b/fs/locks.c
index c17bc00b1e8d..7f9a3ea47418 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -2066,134 +2066,114 @@ int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
2066 2066
2067EXPORT_SYMBOL_GPL(vfs_cancel_lock); 2067EXPORT_SYMBOL_GPL(vfs_cancel_lock);
2068 2068
2069static void lock_get_status(char* out, struct file_lock *fl, int id, char *pfx) 2069#ifdef CONFIG_PROC_FS
2070#include <linux/seq_file.h>
2071
2072static void lock_get_status(struct seq_file *f, struct file_lock *fl,
2073 int id, char *pfx)
2070{ 2074{
2071 struct inode *inode = NULL; 2075 struct inode *inode = NULL;
2072 2076
2073 if (fl->fl_file != NULL) 2077 if (fl->fl_file != NULL)
2074 inode = fl->fl_file->f_path.dentry->d_inode; 2078 inode = fl->fl_file->f_path.dentry->d_inode;
2075 2079
2076 out += sprintf(out, "%d:%s ", id, pfx); 2080 seq_printf(f, "%d:%s ", id, pfx);
2077 if (IS_POSIX(fl)) { 2081 if (IS_POSIX(fl)) {
2078 out += sprintf(out, "%6s %s ", 2082 seq_printf(f, "%6s %s ",
2079 (fl->fl_flags & FL_ACCESS) ? "ACCESS" : "POSIX ", 2083 (fl->fl_flags & FL_ACCESS) ? "ACCESS" : "POSIX ",
2080 (inode == NULL) ? "*NOINODE*" : 2084 (inode == NULL) ? "*NOINODE*" :
2081 mandatory_lock(inode) ? "MANDATORY" : "ADVISORY "); 2085 mandatory_lock(inode) ? "MANDATORY" : "ADVISORY ");
2082 } else if (IS_FLOCK(fl)) { 2086 } else if (IS_FLOCK(fl)) {
2083 if (fl->fl_type & LOCK_MAND) { 2087 if (fl->fl_type & LOCK_MAND) {
2084 out += sprintf(out, "FLOCK MSNFS "); 2088 seq_printf(f, "FLOCK MSNFS ");
2085 } else { 2089 } else {
2086 out += sprintf(out, "FLOCK ADVISORY "); 2090 seq_printf(f, "FLOCK ADVISORY ");
2087 } 2091 }
2088 } else if (IS_LEASE(fl)) { 2092 } else if (IS_LEASE(fl)) {
2089 out += sprintf(out, "LEASE "); 2093 seq_printf(f, "LEASE ");
2090 if (fl->fl_type & F_INPROGRESS) 2094 if (fl->fl_type & F_INPROGRESS)
2091 out += sprintf(out, "BREAKING "); 2095 seq_printf(f, "BREAKING ");
2092 else if (fl->fl_file) 2096 else if (fl->fl_file)
2093 out += sprintf(out, "ACTIVE "); 2097 seq_printf(f, "ACTIVE ");
2094 else 2098 else
2095 out += sprintf(out, "BREAKER "); 2099 seq_printf(f, "BREAKER ");
2096 } else { 2100 } else {
2097 out += sprintf(out, "UNKNOWN UNKNOWN "); 2101 seq_printf(f, "UNKNOWN UNKNOWN ");
2098 } 2102 }
2099 if (fl->fl_type & LOCK_MAND) { 2103 if (fl->fl_type & LOCK_MAND) {
2100 out += sprintf(out, "%s ", 2104 seq_printf(f, "%s ",
2101 (fl->fl_type & LOCK_READ) 2105 (fl->fl_type & LOCK_READ)
2102 ? (fl->fl_type & LOCK_WRITE) ? "RW " : "READ " 2106 ? (fl->fl_type & LOCK_WRITE) ? "RW " : "READ "
2103 : (fl->fl_type & LOCK_WRITE) ? "WRITE" : "NONE "); 2107 : (fl->fl_type & LOCK_WRITE) ? "WRITE" : "NONE ");
2104 } else { 2108 } else {
2105 out += sprintf(out, "%s ", 2109 seq_printf(f, "%s ",
2106 (fl->fl_type & F_INPROGRESS) 2110 (fl->fl_type & F_INPROGRESS)
2107 ? (fl->fl_type & F_UNLCK) ? "UNLCK" : "READ " 2111 ? (fl->fl_type & F_UNLCK) ? "UNLCK" : "READ "
2108 : (fl->fl_type & F_WRLCK) ? "WRITE" : "READ "); 2112 : (fl->fl_type & F_WRLCK) ? "WRITE" : "READ ");
2109 } 2113 }
2110 if (inode) { 2114 if (inode) {
2111#ifdef WE_CAN_BREAK_LSLK_NOW 2115#ifdef WE_CAN_BREAK_LSLK_NOW
2112 out += sprintf(out, "%d %s:%ld ", fl->fl_pid, 2116 seq_printf(f, "%d %s:%ld ", fl->fl_pid,
2113 inode->i_sb->s_id, inode->i_ino); 2117 inode->i_sb->s_id, inode->i_ino);
2114#else 2118#else
2115 /* userspace relies on this representation of dev_t ;-( */ 2119 /* userspace relies on this representation of dev_t ;-( */
2116 out += sprintf(out, "%d %02x:%02x:%ld ", fl->fl_pid, 2120 seq_printf(f, "%d %02x:%02x:%ld ", fl->fl_pid,
2117 MAJOR(inode->i_sb->s_dev), 2121 MAJOR(inode->i_sb->s_dev),
2118 MINOR(inode->i_sb->s_dev), inode->i_ino); 2122 MINOR(inode->i_sb->s_dev), inode->i_ino);
2119#endif 2123#endif
2120 } else { 2124 } else {
2121 out += sprintf(out, "%d <none>:0 ", fl->fl_pid); 2125 seq_printf(f, "%d <none>:0 ", fl->fl_pid);
2122 } 2126 }
2123 if (IS_POSIX(fl)) { 2127 if (IS_POSIX(fl)) {
2124 if (fl->fl_end == OFFSET_MAX) 2128 if (fl->fl_end == OFFSET_MAX)
2125 out += sprintf(out, "%Ld EOF\n", fl->fl_start); 2129 seq_printf(f, "%Ld EOF\n", fl->fl_start);
2126 else 2130 else
2127 out += sprintf(out, "%Ld %Ld\n", fl->fl_start, 2131 seq_printf(f, "%Ld %Ld\n", fl->fl_start, fl->fl_end);
2128 fl->fl_end);
2129 } else { 2132 } else {
2130 out += sprintf(out, "0 EOF\n"); 2133 seq_printf(f, "0 EOF\n");
2131 } 2134 }
2132} 2135}
2133 2136
2134static void move_lock_status(char **p, off_t* pos, off_t offset) 2137static int locks_show(struct seq_file *f, void *v)
2135{ 2138{
2136 int len; 2139 struct file_lock *fl, *bfl;
2137 len = strlen(*p);
2138 if(*pos >= offset) {
2139 /* the complete line is valid */
2140 *p += len;
2141 *pos += len;
2142 return;
2143 }
2144 if(*pos+len > offset) {
2145 /* use the second part of the line */
2146 int i = offset-*pos;
2147 memmove(*p,*p+i,len-i);
2148 *p += len-i;
2149 *pos += len;
2150 return;
2151 }
2152 /* discard the complete line */
2153 *pos += len;
2154}
2155 2140
2156/** 2141 fl = list_entry(v, struct file_lock, fl_link);
2157 * get_locks_status - reports lock usage in /proc/locks
2158 * @buffer: address in userspace to write into
2159 * @start: ?
2160 * @offset: how far we are through the buffer
2161 * @length: how much to read
2162 */
2163 2142
2164int get_locks_status(char *buffer, char **start, off_t offset, int length) 2143 lock_get_status(f, fl, (long)f->private, "");
2165{
2166 struct file_lock *fl;
2167 char *q = buffer;
2168 off_t pos = 0;
2169 int i = 0;
2170 2144
2171 lock_kernel(); 2145 list_for_each_entry(bfl, &fl->fl_block, fl_block)
2172 list_for_each_entry(fl, &file_lock_list, fl_link) { 2146 lock_get_status(f, bfl, (long)f->private, " ->");
2173 struct file_lock *bfl;
2174 2147
2175 lock_get_status(q, fl, ++i, ""); 2148 f->private++;
2176 move_lock_status(&q, &pos, offset); 2149 return 0;
2150}
2177 2151
2178 if(pos >= offset+length) 2152static void *locks_start(struct seq_file *f, loff_t *pos)
2179 goto done; 2153{
2154 lock_kernel();
2155 f->private = (void *)1;
2156 return seq_list_start(&file_lock_list, *pos);
2157}
2180 2158
2181 list_for_each_entry(bfl, &fl->fl_block, fl_block) { 2159static void *locks_next(struct seq_file *f, void *v, loff_t *pos)
2182 lock_get_status(q, bfl, i, " ->"); 2160{
2183 move_lock_status(&q, &pos, offset); 2161 return seq_list_next(v, &file_lock_list, pos);
2162}
2184 2163
2185 if(pos >= offset+length) 2164static void locks_stop(struct seq_file *f, void *v)
2186 goto done; 2165{
2187 }
2188 }
2189done:
2190 unlock_kernel(); 2166 unlock_kernel();
2191 *start = buffer;
2192 if(q-buffer < length)
2193 return (q-buffer);
2194 return length;
2195} 2167}
2196 2168
2169struct seq_operations locks_seq_operations = {
2170 .start = locks_start,
2171 .next = locks_next,
2172 .stop = locks_stop,
2173 .show = locks_show,
2174};
2175#endif
2176
2197/** 2177/**
2198 * lock_may_read - checks that the region is free of locks 2178 * lock_may_read - checks that the region is free of locks
2199 * @inode: the inode that is being read 2179 * @inode: the inode that is being read
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index bee251cb87c8..c9d6d5f400ad 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -66,7 +66,6 @@ extern int get_stram_list(char *);
66extern int get_filesystem_list(char *); 66extern int get_filesystem_list(char *);
67extern int get_exec_domain_list(char *); 67extern int get_exec_domain_list(char *);
68extern int get_dma_list(char *); 68extern int get_dma_list(char *);
69extern int get_locks_status (char *, char **, off_t, int);
70 69
71static int proc_calc_metrics(char *page, char **start, off_t off, 70static int proc_calc_metrics(char *page, char **start, off_t off,
72 int count, int *eof, int len) 71 int count, int *eof, int len)
@@ -617,16 +616,18 @@ static int cmdline_read_proc(char *page, char **start, off_t off,
617 return proc_calc_metrics(page, start, off, count, eof, len); 616 return proc_calc_metrics(page, start, off, count, eof, len);
618} 617}
619 618
620static int locks_read_proc(char *page, char **start, off_t off, 619static int locks_open(struct inode *inode, struct file *filp)
621 int count, int *eof, void *data)
622{ 620{
623 int len = get_locks_status(page, start, off, count); 621 return seq_open(filp, &locks_seq_operations);
624
625 if (len < count)
626 *eof = 1;
627 return len;
628} 622}
629 623
624static const struct file_operations proc_locks_operations = {
625 .open = locks_open,
626 .read = seq_read,
627 .llseek = seq_lseek,
628 .release = seq_release,
629};
630
630static int execdomains_read_proc(char *page, char **start, off_t off, 631static int execdomains_read_proc(char *page, char **start, off_t off,
631 int count, int *eof, void *data) 632 int count, int *eof, void *data)
632{ 633{
@@ -684,7 +685,6 @@ void __init proc_misc_init(void)
684#endif 685#endif
685 {"filesystems", filesystems_read_proc}, 686 {"filesystems", filesystems_read_proc},
686 {"cmdline", cmdline_read_proc}, 687 {"cmdline", cmdline_read_proc},
687 {"locks", locks_read_proc},
688 {"execdomains", execdomains_read_proc}, 688 {"execdomains", execdomains_read_proc},
689 {NULL,} 689 {NULL,}
690 }; 690 };
@@ -702,6 +702,7 @@ void __init proc_misc_init(void)
702 entry->proc_fops = &proc_kmsg_operations; 702 entry->proc_fops = &proc_kmsg_operations;
703 } 703 }
704#endif 704#endif
705 create_seq_entry("locks", 0, &proc_locks_operations);
705 create_seq_entry("devices", 0, &proc_devinfo_operations); 706 create_seq_entry("devices", 0, &proc_devinfo_operations);
706 create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); 707 create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
707#ifdef CONFIG_BLOCK 708#ifdef CONFIG_BLOCK
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f5075e0e7301..4f1e8cebea78 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -883,6 +883,7 @@ extern int vfs_setlease(struct file *, long, struct file_lock **);
883extern int lease_modify(struct file_lock **, int); 883extern int lease_modify(struct file_lock **, int);
884extern int lock_may_read(struct inode *, loff_t start, unsigned long count); 884extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
885extern int lock_may_write(struct inode *, loff_t start, unsigned long count); 885extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
886extern struct seq_operations locks_seq_operations;
886 887
887struct fasync_struct { 888struct fasync_struct {
888 int magic; 889 int magic;