debugfs: fix error when writing negative value to atomic_t debugfs file
[sfrench/cifs-2.6.git] / fs / debugfs / file.c
index ddb3fc258df94eace1fac2db0bbdd81ff684f108..b54f470e0d0318ade70a1e9e692e051fa6a35f75 100644 (file)
@@ -378,8 +378,8 @@ ssize_t debugfs_attr_read(struct file *file, char __user *buf,
 }
 EXPORT_SYMBOL_GPL(debugfs_attr_read);
 
-ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
-                        size_t len, loff_t *ppos)
+static ssize_t debugfs_attr_write_xsigned(struct file *file, const char __user *buf,
+                        size_t len, loff_t *ppos, bool is_signed)
 {
        struct dentry *dentry = F_DENTRY(file);
        ssize_t ret;
@@ -387,12 +387,28 @@ ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
        ret = debugfs_file_get(dentry);
        if (unlikely(ret))
                return ret;
-       ret = simple_attr_write(file, buf, len, ppos);
+       if (is_signed)
+               ret = simple_attr_write_signed(file, buf, len, ppos);
+       else
+               ret = simple_attr_write(file, buf, len, ppos);
        debugfs_file_put(dentry);
        return ret;
 }
+
+ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
+                        size_t len, loff_t *ppos)
+{
+       return debugfs_attr_write_xsigned(file, buf, len, ppos, false);
+}
 EXPORT_SYMBOL_GPL(debugfs_attr_write);
 
+ssize_t debugfs_attr_write_signed(struct file *file, const char __user *buf,
+                        size_t len, loff_t *ppos)
+{
+       return debugfs_attr_write_xsigned(file, buf, len, ppos, true);
+}
+EXPORT_SYMBOL_GPL(debugfs_attr_write_signed);
+
 static struct dentry *debugfs_create_mode_unsafe(const char *name, umode_t mode,
                                        struct dentry *parent, void *value,
                                        const struct file_operations *fops,
@@ -738,11 +754,11 @@ static int debugfs_atomic_t_get(void *data, u64 *val)
        *val = atomic_read((atomic_t *)data);
        return 0;
 }
-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get,
+DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t, debugfs_atomic_t_get,
                        debugfs_atomic_t_set, "%lld\n");
-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_ro, debugfs_atomic_t_get, NULL,
+DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t_ro, debugfs_atomic_t_get, NULL,
                        "%lld\n");
-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set,
+DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t_wo, NULL, debugfs_atomic_t_set,
                        "%lld\n");
 
 /**