aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2008-02-08 07:20:26 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-08 12:22:34 -0500
commit8b88b0998e35d239e74446cc30f354bdab86df89 (patch)
treec13773b744cf12b1e30ec9336a4acaf21e46c6d9 /fs
parentefae09f3e99fcc1bdead7bc23a508b3bade3f82f (diff)
libfs: allow error return from simple attributes
Sometimes simple attributes might need to return an error, e.g. for acquiring a mutex interruptibly. In fact we have that situation in spufs already which is the original user of the simple attributes. This patch merged the temporarily forked attributes in spufs back into the main ones and allows to return errors. [akpm@linux-foundation.org: build fix] Signed-off-by: Christoph Hellwig <hch@lst.de> Cc: <stefano.brivio@polimi.it> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Greg KH <greg@kroah.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/debugfs/file.c32
-rw-r--r--fs/libfs.c21
2 files changed, 33 insertions, 20 deletions
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index fa6b7f7ff914..fddffe4851f5 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -56,13 +56,15 @@ const struct inode_operations debugfs_link_operations = {
56 .follow_link = debugfs_follow_link, 56 .follow_link = debugfs_follow_link,
57}; 57};
58 58
59static void debugfs_u8_set(void *data, u64 val) 59static int debugfs_u8_set(void *data, u64 val)
60{ 60{
61 *(u8 *)data = val; 61 *(u8 *)data = val;
62 return 0;
62} 63}
63static u64 debugfs_u8_get(void *data) 64static int debugfs_u8_get(void *data, u64 *val)
64{ 65{
65 return *(u8 *)data; 66 *val = *(u8 *)data;
67 return 0;
66} 68}
67DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n"); 69DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n");
68 70
@@ -97,13 +99,15 @@ struct dentry *debugfs_create_u8(const char *name, mode_t mode,
97} 99}
98EXPORT_SYMBOL_GPL(debugfs_create_u8); 100EXPORT_SYMBOL_GPL(debugfs_create_u8);
99 101
100static void debugfs_u16_set(void *data, u64 val) 102static int debugfs_u16_set(void *data, u64 val)
101{ 103{
102 *(u16 *)data = val; 104 *(u16 *)data = val;
105 return 0;
103} 106}
104static u64 debugfs_u16_get(void *data) 107static int debugfs_u16_get(void *data, u64 *val)
105{ 108{
106 return *(u16 *)data; 109 *val = *(u16 *)data;
110 return 0;
107} 111}
108DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n"); 112DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n");
109 113
@@ -138,13 +142,15 @@ struct dentry *debugfs_create_u16(const char *name, mode_t mode,
138} 142}
139EXPORT_SYMBOL_GPL(debugfs_create_u16); 143EXPORT_SYMBOL_GPL(debugfs_create_u16);
140 144
141static void debugfs_u32_set(void *data, u64 val) 145static int debugfs_u32_set(void *data, u64 val)
142{ 146{
143 *(u32 *)data = val; 147 *(u32 *)data = val;
148 return 0;
144} 149}
145static u64 debugfs_u32_get(void *data) 150static int debugfs_u32_get(void *data, u64 *val)
146{ 151{
147 return *(u32 *)data; 152 *val = *(u32 *)data;
153 return 0;
148} 154}
149DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n"); 155DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n");
150 156
@@ -179,14 +185,16 @@ struct dentry *debugfs_create_u32(const char *name, mode_t mode,
179} 185}
180EXPORT_SYMBOL_GPL(debugfs_create_u32); 186EXPORT_SYMBOL_GPL(debugfs_create_u32);
181 187
182static void debugfs_u64_set(void *data, u64 val) 188static int debugfs_u64_set(void *data, u64 val)
183{ 189{
184 *(u64 *)data = val; 190 *(u64 *)data = val;
191 return 0;
185} 192}
186 193
187static u64 debugfs_u64_get(void *data) 194static int debugfs_u64_get(void *data, u64 *val)
188{ 195{
189 return *(u64 *)data; 196 *val = *(u64 *)data;
197 return 0;
190} 198}
191DEFINE_SIMPLE_ATTRIBUTE(fops_u64, debugfs_u64_get, debugfs_u64_set, "%llu\n"); 199DEFINE_SIMPLE_ATTRIBUTE(fops_u64, debugfs_u64_get, debugfs_u64_set, "%llu\n");
192 200
diff --git a/fs/libfs.c b/fs/libfs.c
index 5523bde96387..2319415ddb5e 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -583,8 +583,8 @@ int simple_transaction_release(struct inode *inode, struct file *file)
583/* Simple attribute files */ 583/* Simple attribute files */
584 584
585struct simple_attr { 585struct simple_attr {
586 u64 (*get)(void *); 586 int (*get)(void *, u64 *);
587 void (*set)(void *, u64); 587 int (*set)(void *, u64);
588 char get_buf[24]; /* enough to store a u64 and "\n\0" */ 588 char get_buf[24]; /* enough to store a u64 and "\n\0" */
589 char set_buf[24]; 589 char set_buf[24];
590 void *data; 590 void *data;
@@ -595,7 +595,7 @@ struct simple_attr {
595/* simple_attr_open is called by an actual attribute open file operation 595/* simple_attr_open is called by an actual attribute open file operation
596 * to set the attribute specific access operations. */ 596 * to set the attribute specific access operations. */
597int simple_attr_open(struct inode *inode, struct file *file, 597int simple_attr_open(struct inode *inode, struct file *file,
598 u64 (*get)(void *), void (*set)(void *, u64), 598 int (*get)(void *, u64 *), int (*set)(void *, u64),
599 const char *fmt) 599 const char *fmt)
600{ 600{
601 struct simple_attr *attr; 601 struct simple_attr *attr;
@@ -635,14 +635,20 @@ ssize_t simple_attr_read(struct file *file, char __user *buf,
635 return -EACCES; 635 return -EACCES;
636 636
637 mutex_lock(&attr->mutex); 637 mutex_lock(&attr->mutex);
638 if (*ppos) /* continued read */ 638 if (*ppos) { /* continued read */
639 size = strlen(attr->get_buf); 639 size = strlen(attr->get_buf);
640 else /* first read */ 640 } else { /* first read */
641 u64 val;
642 ret = attr->get(attr->data, &val);
643 if (ret)
644 goto out;
645
641 size = scnprintf(attr->get_buf, sizeof(attr->get_buf), 646 size = scnprintf(attr->get_buf, sizeof(attr->get_buf),
642 attr->fmt, 647 attr->fmt, (unsigned long long)val);
643 (unsigned long long)attr->get(attr->data)); 648 }
644 649
645 ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size); 650 ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size);
651out:
646 mutex_unlock(&attr->mutex); 652 mutex_unlock(&attr->mutex);
647 return ret; 653 return ret;
648} 654}
@@ -657,7 +663,6 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf,
657 ssize_t ret; 663 ssize_t ret;
658 664
659 attr = file->private_data; 665 attr = file->private_data;
660
661 if (!attr->set) 666 if (!attr->set)
662 return -EACCES; 667 return -EACCES;
663 668