Commit b53c4d5e authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'upstream-4.12-rc1' of git://git.infradead.org/linux-ubifs

Pull UBI/UBIFS updates from Richard Weinberger:

 - new config option CONFIG_UBIFS_FS_SECURITY

 - minor improvements

 - random fixes

* tag 'upstream-4.12-rc1' of git://git.infradead.org/linux-ubifs:
  ubi: Add debugfs file for tracking PEB state
  ubifs: Fix a typo in comment of ioctl2ubifs & ubifs2ioctl
  ubifs: Remove unnecessary assignment
  ubifs: Fix cut and paste error on sb type comparisons
  ubi: fastmap: Fix slab corruption
  ubifs: Add CONFIG_UBIFS_FS_SECURITY to disable/enable security labels
  ubi: Make mtd parameter readable
  ubi: Fix section mismatch
parents ec059019 7bccd12d
...@@ -74,10 +74,10 @@ struct mtd_dev_param { ...@@ -74,10 +74,10 @@ struct mtd_dev_param {
}; };
/* Numbers of elements set in the @mtd_dev_param array */ /* Numbers of elements set in the @mtd_dev_param array */
static int __initdata mtd_devs; static int mtd_devs;
/* MTD devices specification parameters */ /* MTD devices specification parameters */
static struct mtd_dev_param __initdata mtd_dev_param[UBI_MAX_DEVICES]; static struct mtd_dev_param mtd_dev_param[UBI_MAX_DEVICES];
#ifdef CONFIG_MTD_UBI_FASTMAP #ifdef CONFIG_MTD_UBI_FASTMAP
/* UBI module parameter to enable fastmap automatically on non-fastmap images */ /* UBI module parameter to enable fastmap automatically on non-fastmap images */
static bool fm_autoconvert; static bool fm_autoconvert;
...@@ -1294,7 +1294,7 @@ module_exit(ubi_exit); ...@@ -1294,7 +1294,7 @@ module_exit(ubi_exit);
* This function returns positive resulting integer in case of success and a * This function returns positive resulting integer in case of success and a
* negative error code in case of failure. * negative error code in case of failure.
*/ */
static int __init bytes_str_to_int(const char *str) static int bytes_str_to_int(const char *str)
{ {
char *endp; char *endp;
unsigned long result; unsigned long result;
...@@ -1332,7 +1332,7 @@ static int __init bytes_str_to_int(const char *str) ...@@ -1332,7 +1332,7 @@ static int __init bytes_str_to_int(const char *str)
* This function returns zero in case of success and a negative error code in * This function returns zero in case of success and a negative error code in
* case of error. * case of error.
*/ */
static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) static int ubi_mtd_param_parse(const char *val, struct kernel_param *kp)
{ {
int i, len; int i, len;
struct mtd_dev_param *p; struct mtd_dev_param *p;
...@@ -1413,7 +1413,7 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) ...@@ -1413,7 +1413,7 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp)
return 0; return 0;
} }
module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 000); module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 0400);
MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num]]].\n" MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num]]].\n"
"Multiple \"mtd\" parameters may be specified.\n" "Multiple \"mtd\" parameters may be specified.\n"
"MTD devices may be specified by their number, name, or path to the MTD character device node.\n" "MTD devices may be specified by their number, name, or path to the MTD character device node.\n"
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/seq_file.h>
/** /**
...@@ -386,7 +387,9 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf, ...@@ -386,7 +387,9 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
return count; return count;
} }
/* File operations for all UBI debugfs files */ /* File operations for all UBI debugfs files except
* detailed_erase_block_info
*/
static const struct file_operations dfs_fops = { static const struct file_operations dfs_fops = {
.read = dfs_file_read, .read = dfs_file_read,
.write = dfs_file_write, .write = dfs_file_write,
...@@ -395,6 +398,121 @@ static const struct file_operations dfs_fops = { ...@@ -395,6 +398,121 @@ static const struct file_operations dfs_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
/* As long as the position is less then that total number of erase blocks,
* we still have more to print.
*/
static void *eraseblk_count_seq_start(struct seq_file *s, loff_t *pos)
{
struct ubi_device *ubi = s->private;
if (*pos == 0)
return SEQ_START_TOKEN;
if (*pos < ubi->peb_count)
return pos;
return NULL;
}
/* Since we are using the position as the iterator, we just need to check if we
* are done and increment the position.
*/
static void *eraseblk_count_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
struct ubi_device *ubi = s->private;
if (v == SEQ_START_TOKEN)
return pos;
(*pos)++;
if (*pos < ubi->peb_count)
return pos;
return NULL;
}
static void eraseblk_count_seq_stop(struct seq_file *s, void *v)
{
}
static int eraseblk_count_seq_show(struct seq_file *s, void *iter)
{
struct ubi_device *ubi = s->private;
struct ubi_wl_entry *wl;
int *block_number = iter;
int erase_count = -1;
int err;
/* If this is the start, print a header */
if (iter == SEQ_START_TOKEN) {
seq_puts(s,
"physical_block_number\terase_count\tblock_status\tread_status\n");
return 0;
}
err = ubi_io_is_bad(ubi, *block_number);
if (err)
return err;
spin_lock(&ubi->wl_lock);
wl = ubi->lookuptbl[*block_number];
if (wl)
erase_count = wl->ec;
spin_unlock(&ubi->wl_lock);
if (erase_count < 0)
return 0;
seq_printf(s, "%-22d\t%-11d\n", *block_number, erase_count);
return 0;
}
static const struct seq_operations eraseblk_count_seq_ops = {
.start = eraseblk_count_seq_start,
.next = eraseblk_count_seq_next,
.stop = eraseblk_count_seq_stop,
.show = eraseblk_count_seq_show
};
static int eraseblk_count_open(struct inode *inode, struct file *f)
{
struct seq_file *s;
int err;
err = seq_open(f, &eraseblk_count_seq_ops);
if (err)
return err;
s = f->private_data;
s->private = ubi_get_device((unsigned long)inode->i_private);
if (!s->private)
return -ENODEV;
else
return 0;
}
static int eraseblk_count_release(struct inode *inode, struct file *f)
{
struct seq_file *s = f->private_data;
struct ubi_device *ubi = s->private;
ubi_put_device(ubi);
return seq_release(inode, f);
}
static const struct file_operations eraseblk_count_fops = {
.owner = THIS_MODULE,
.open = eraseblk_count_open,
.read = seq_read,
.llseek = seq_lseek,
.release = eraseblk_count_release,
};
/** /**
* ubi_debugfs_init_dev - initialize debugfs for an UBI device. * ubi_debugfs_init_dev - initialize debugfs for an UBI device.
* @ubi: UBI device description object * @ubi: UBI device description object
...@@ -491,6 +609,12 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) ...@@ -491,6 +609,12 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
goto out_remove; goto out_remove;
d->dfs_power_cut_max = dent; d->dfs_power_cut_max = dent;
fname = "detailed_erase_block_info";
dent = debugfs_create_file(fname, S_IRUSR, d->dfs_dir, (void *)ubi_num,
&eraseblk_count_fops);
if (IS_ERR_OR_NULL(dent))
goto out_remove;
return 0; return 0;
out_remove: out_remove:
......
...@@ -828,6 +828,24 @@ static int find_fm_anchor(struct ubi_attach_info *ai) ...@@ -828,6 +828,24 @@ static int find_fm_anchor(struct ubi_attach_info *ai)
return ret; return ret;
} }
static struct ubi_ainf_peb *clone_aeb(struct ubi_attach_info *ai,
struct ubi_ainf_peb *old)
{
struct ubi_ainf_peb *new;
new = ubi_alloc_aeb(ai, old->pnum, old->ec);
if (!new)
return NULL;
new->vol_id = old->vol_id;
new->sqnum = old->sqnum;
new->lnum = old->lnum;
new->scrub = old->scrub;
new->copy_flag = old->copy_flag;
return new;
}
/** /**
* ubi_scan_fastmap - scan the fastmap. * ubi_scan_fastmap - scan the fastmap.
* @ubi: UBI device object * @ubi: UBI device object
...@@ -847,7 +865,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, ...@@ -847,7 +865,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
struct ubi_vid_hdr *vh; struct ubi_vid_hdr *vh;
struct ubi_ec_hdr *ech; struct ubi_ec_hdr *ech;
struct ubi_fastmap_layout *fm; struct ubi_fastmap_layout *fm;
struct ubi_ainf_peb *tmp_aeb, *aeb; struct ubi_ainf_peb *aeb;
int i, used_blocks, pnum, fm_anchor, ret = 0; int i, used_blocks, pnum, fm_anchor, ret = 0;
size_t fm_size; size_t fm_size;
__be32 crc, tmp_crc; __be32 crc, tmp_crc;
...@@ -857,9 +875,16 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, ...@@ -857,9 +875,16 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
if (fm_anchor < 0) if (fm_anchor < 0)
return UBI_NO_FASTMAP; return UBI_NO_FASTMAP;
/* Move all (possible) fastmap blocks into our new attach structure. */ /* Copy all (possible) fastmap blocks into our new attach structure. */
list_for_each_entry_safe(aeb, tmp_aeb, &scan_ai->fastmap, u.list) list_for_each_entry(aeb, &scan_ai->fastmap, u.list) {
list_move_tail(&aeb->u.list, &ai->fastmap); struct ubi_ainf_peb *new;
new = clone_aeb(ai, aeb);
if (!new)
return -ENOMEM;
list_add(&new->u.list, &ai->fastmap);
}
down_write(&ubi->fm_protect); down_write(&ubi->fm_protect);
memset(ubi->fm_buf, 0, ubi->fm_size); memset(ubi->fm_buf, 0, ubi->fm_size);
......
...@@ -61,3 +61,16 @@ config UBIFS_FS_ENCRYPTION ...@@ -61,3 +61,16 @@ config UBIFS_FS_ENCRYPTION
feature is similar to ecryptfs, but it is more memory feature is similar to ecryptfs, but it is more memory
efficient since it avoids caching the encrypted and efficient since it avoids caching the encrypted and
decrypted pages in the page cache. decrypted pages in the page cache.
config UBIFS_FS_SECURITY
bool "UBIFS Security Labels"
depends on UBIFS_FS
default y
help
Security labels provide an access control facility to support Linux
Security Models (LSMs) accepted by AppArmor, SELinux, Smack and TOMOYO
Linux. This option enables an extended attribute handler for file
security labels in the ubifs filesystem, so that it requires enabling
the extended attribute support in advance.
If you are not using a security module, say N.
...@@ -2391,8 +2391,8 @@ int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head) ...@@ -2391,8 +2391,8 @@ int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head)
ubifs_dump_node(c, sa->node); ubifs_dump_node(c, sa->node);
return -EINVAL; return -EINVAL;
} }
if (sa->type != UBIFS_INO_NODE && sa->type != UBIFS_DENT_NODE && if (sb->type != UBIFS_INO_NODE && sb->type != UBIFS_DENT_NODE &&
sa->type != UBIFS_XENT_NODE) { sb->type != UBIFS_XENT_NODE) {
ubifs_err(c, "bad node type %d", sb->type); ubifs_err(c, "bad node type %d", sb->type);
ubifs_dump_node(c, sb->node); ubifs_dump_node(c, sb->node);
return -EINVAL; return -EINVAL;
......
...@@ -53,7 +53,7 @@ void ubifs_set_inode_flags(struct inode *inode) ...@@ -53,7 +53,7 @@ void ubifs_set_inode_flags(struct inode *inode)
* ioctl2ubifs - convert ioctl inode flags to UBIFS inode flags. * ioctl2ubifs - convert ioctl inode flags to UBIFS inode flags.
* @ioctl_flags: flags to convert * @ioctl_flags: flags to convert
* *
* This function convert ioctl flags (@FS_COMPR_FL, etc) to UBIFS inode flags * This function converts ioctl flags (@FS_COMPR_FL, etc) to UBIFS inode flags
* (@UBIFS_COMPR_FL, etc). * (@UBIFS_COMPR_FL, etc).
*/ */
static int ioctl2ubifs(int ioctl_flags) static int ioctl2ubifs(int ioctl_flags)
...@@ -78,8 +78,8 @@ static int ioctl2ubifs(int ioctl_flags) ...@@ -78,8 +78,8 @@ static int ioctl2ubifs(int ioctl_flags)
* ubifs2ioctl - convert UBIFS inode flags to ioctl inode flags. * ubifs2ioctl - convert UBIFS inode flags to ioctl inode flags.
* @ubifs_flags: flags to convert * @ubifs_flags: flags to convert
* *
* This function convert UBIFS (@UBIFS_COMPR_FL, etc) to ioctl flags * This function converts UBIFS inode flags (@UBIFS_COMPR_FL, etc) to ioctl
* (@FS_COMPR_FL, etc). * flags (@FS_COMPR_FL, etc).
*/ */
static int ubifs2ioctl(int ubifs_flags) static int ubifs2ioctl(int ubifs_flags)
{ {
......
...@@ -442,7 +442,6 @@ static void clean_buf(const struct ubifs_info *c, void **buf, int lnum, ...@@ -442,7 +442,6 @@ static void clean_buf(const struct ubifs_info *c, void **buf, int lnum,
{ {
int empty_offs, pad_len; int empty_offs, pad_len;
lnum = lnum;
dbg_rcvry("cleaning corruption at %d:%d", lnum, *offs); dbg_rcvry("cleaning corruption at %d:%d", lnum, *offs);
ubifs_assert(!(*offs & 7)); ubifs_assert(!(*offs & 7));
......
...@@ -1753,13 +1753,23 @@ int ubifs_check_dir_empty(struct inode *dir); ...@@ -1753,13 +1753,23 @@ int ubifs_check_dir_empty(struct inode *dir);
/* xattr.c */ /* xattr.c */
extern const struct xattr_handler *ubifs_xattr_handlers[]; extern const struct xattr_handler *ubifs_xattr_handlers[];
ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size); ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size);
int ubifs_init_security(struct inode *dentry, struct inode *inode,
const struct qstr *qstr);
int ubifs_xattr_set(struct inode *host, const char *name, const void *value, int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
size_t size, int flags); size_t size, int flags);
ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf, ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
size_t size); size_t size);
#ifdef CONFIG_UBIFS_FS_SECURITY
extern int ubifs_init_security(struct inode *dentry, struct inode *inode,
const struct qstr *qstr);
#else
static inline int ubifs_init_security(struct inode *dentry,
struct inode *inode, const struct qstr *qstr)
{
return 0;
}
#endif
/* super.c */ /* super.c */
struct inode *ubifs_iget(struct super_block *sb, unsigned long inum); struct inode *ubifs_iget(struct super_block *sb, unsigned long inum);
......
...@@ -559,6 +559,7 @@ static int ubifs_xattr_remove(struct inode *host, const char *name) ...@@ -559,6 +559,7 @@ static int ubifs_xattr_remove(struct inode *host, const char *name)
return err; return err;
} }
#ifdef CONFIG_UBIFS_FS_SECURITY
static int init_xattrs(struct inode *inode, const struct xattr *xattr_array, static int init_xattrs(struct inode *inode, const struct xattr *xattr_array,
void *fs_info) void *fs_info)
{ {
...@@ -599,6 +600,7 @@ int ubifs_init_security(struct inode *dentry, struct inode *inode, ...@@ -599,6 +600,7 @@ int ubifs_init_security(struct inode *dentry, struct inode *inode,
} }
return err; return err;
} }
#endif
static int xattr_get(const struct xattr_handler *handler, static int xattr_get(const struct xattr_handler *handler,
struct dentry *dentry, struct inode *inode, struct dentry *dentry, struct inode *inode,
...@@ -639,15 +641,19 @@ static const struct xattr_handler ubifs_trusted_xattr_handler = { ...@@ -639,15 +641,19 @@ static const struct xattr_handler ubifs_trusted_xattr_handler = {
.set = xattr_set, .set = xattr_set,
}; };
#ifdef CONFIG_UBIFS_FS_SECURITY
static const struct xattr_handler ubifs_security_xattr_handler = { static const struct xattr_handler ubifs_security_xattr_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.get = xattr_get, .get = xattr_get,
.set = xattr_set, .set = xattr_set,
}; };
#endif
const struct xattr_handler *ubifs_xattr_handlers[] = { const struct xattr_handler *ubifs_xattr_handlers[] = {
&ubifs_user_xattr_handler, &ubifs_user_xattr_handler,
&ubifs_trusted_xattr_handler, &ubifs_trusted_xattr_handler,
#ifdef CONFIG_UBIFS_FS_SECURITY
&ubifs_security_xattr_handler, &ubifs_security_xattr_handler,
#endif
NULL NULL
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment