diff options
-rw-r--r-- | fs/locks.c | 122 | ||||
-rw-r--r-- | fs/proc/proc_misc.c | 19 | ||||
-rw-r--r-- | include/linux/fs.h | 1 |
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 | ||
2067 | EXPORT_SYMBOL_GPL(vfs_cancel_lock); | 2067 | EXPORT_SYMBOL_GPL(vfs_cancel_lock); |
2068 | 2068 | ||
2069 | static 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 | |||
2072 | static 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 | ||
2134 | static void move_lock_status(char **p, off_t* pos, off_t offset) | 2137 | static 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 | ||
2164 | int 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) | 2152 | static 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) { | 2159 | static 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) | 2164 | static void locks_stop(struct seq_file *f, void *v) |
2186 | goto done; | 2165 | { |
2187 | } | ||
2188 | } | ||
2189 | done: | ||
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 | ||
2169 | struct 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 *); | |||
66 | extern int get_filesystem_list(char *); | 66 | extern int get_filesystem_list(char *); |
67 | extern int get_exec_domain_list(char *); | 67 | extern int get_exec_domain_list(char *); |
68 | extern int get_dma_list(char *); | 68 | extern int get_dma_list(char *); |
69 | extern int get_locks_status (char *, char **, off_t, int); | ||
70 | 69 | ||
71 | static int proc_calc_metrics(char *page, char **start, off_t off, | 70 | static 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 | ||
620 | static int locks_read_proc(char *page, char **start, off_t off, | 619 | static 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 | ||
624 | static 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 | |||
630 | static int execdomains_read_proc(char *page, char **start, off_t off, | 631 | static 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 **); | |||
883 | extern int lease_modify(struct file_lock **, int); | 883 | extern int lease_modify(struct file_lock **, int); |
884 | extern int lock_may_read(struct inode *, loff_t start, unsigned long count); | 884 | extern int lock_may_read(struct inode *, loff_t start, unsigned long count); |
885 | extern int lock_may_write(struct inode *, loff_t start, unsigned long count); | 885 | extern int lock_may_write(struct inode *, loff_t start, unsigned long count); |
886 | extern struct seq_operations locks_seq_operations; | ||
886 | 887 | ||
887 | struct fasync_struct { | 888 | struct fasync_struct { |
888 | int magic; | 889 | int magic; |