aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-15 13:11:39 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-15 13:11:39 -0500
commit8c988ae787af4900bec5410658e8a82844185c85 (patch)
treef289dd00d602c9c5363272e75af9fca04f3e7ddc /fs/ubifs
parentd347efeb16d3d5150cb7f8d50b05f388b572840e (diff)
parent8168b9bba6a88fe8a81be5b5f0937faeb3f6775d (diff)
Merge branch 'for-linus-v3.20' of git://git.infradead.org/linux-ubifs
Pull UBI and UBIFS updates from Richard Weinberger: - cleanups and bug fixes all over UBI and UBIFS - block-mq support for UBI Block - UBI volumes can now be renamed while they are in use - security.* XATTR support for UBIFS - a maintainer update * 'for-linus-v3.20' of git://git.infradead.org/linux-ubifs: UBI: block: Fix checking for NULL instead of IS_ERR() UBI: block: Continue creating ubiblocks after an initialization error UBIFS: return -EINVAL if log head is empty UBI: Block: Explain usage of blk_rq_map_sg() UBI: fix soft lockup in ubi_check_volume() UBI: Fastmap: Care about the protection queue UBIFS: add a couple of extra asserts UBI: do propagate positive error codes up UBI: clean-up printing helpers UBI: extend UBI layer debug/messaging capabilities - cosmetics UBIFS: add ubifs_err() to print error reason UBIFS: Add security.* XATTR support for the UBIFS UBIFS: Add xattr support for symlinks UBI: Block: Add blk-mq support UBI: Add initial support for scatter gather UBI: rename_volumes: Use UBI_METAONLY UBI: Implement UBI_METAONLY Add myself as UBI co-maintainer
Diffstat (limited to 'fs/ubifs')
-rw-r--r--fs/ubifs/debug.c4
-rw-r--r--fs/ubifs/dir.c16
-rw-r--r--fs/ubifs/file.c4
-rw-r--r--fs/ubifs/replay.c19
-rw-r--r--fs/ubifs/super.c1
-rw-r--r--fs/ubifs/ubifs.h4
-rw-r--r--fs/ubifs/xattr.c112
7 files changed, 148 insertions, 12 deletions
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 7ed13e1e216a..4cfb3e82c56f 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -2032,6 +2032,8 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
2032 long long blk_offs; 2032 long long blk_offs;
2033 struct ubifs_data_node *dn = node; 2033 struct ubifs_data_node *dn = node;
2034 2034
2035 ubifs_assert(zbr->len >= UBIFS_DATA_NODE_SZ);
2036
2035 /* 2037 /*
2036 * Search the inode node this data node belongs to and insert 2038 * Search the inode node this data node belongs to and insert
2037 * it to the RB-tree of inodes. 2039 * it to the RB-tree of inodes.
@@ -2060,6 +2062,8 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
2060 struct ubifs_dent_node *dent = node; 2062 struct ubifs_dent_node *dent = node;
2061 struct fsck_inode *fscki1; 2063 struct fsck_inode *fscki1;
2062 2064
2065 ubifs_assert(zbr->len >= UBIFS_DENT_NODE_SZ);
2066
2063 err = ubifs_validate_entry(c, dent); 2067 err = ubifs_validate_entry(c, dent);
2064 if (err) 2068 if (err)
2065 goto out_dump; 2069 goto out_dump;
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index c49b1981ac95..0fa6c803992e 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -270,6 +270,10 @@ static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
270 goto out_budg; 270 goto out_budg;
271 } 271 }
272 272
273 err = ubifs_init_security(dir, inode, &dentry->d_name);
274 if (err)
275 goto out_cancel;
276
273 mutex_lock(&dir_ui->ui_mutex); 277 mutex_lock(&dir_ui->ui_mutex);
274 dir->i_size += sz_change; 278 dir->i_size += sz_change;
275 dir_ui->ui_size = dir->i_size; 279 dir_ui->ui_size = dir->i_size;
@@ -726,6 +730,10 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
726 goto out_budg; 730 goto out_budg;
727 } 731 }
728 732
733 err = ubifs_init_security(dir, inode, &dentry->d_name);
734 if (err)
735 goto out_cancel;
736
729 mutex_lock(&dir_ui->ui_mutex); 737 mutex_lock(&dir_ui->ui_mutex);
730 insert_inode_hash(inode); 738 insert_inode_hash(inode);
731 inc_nlink(inode); 739 inc_nlink(inode);
@@ -806,6 +814,10 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry,
806 ui->data = dev; 814 ui->data = dev;
807 ui->data_len = devlen; 815 ui->data_len = devlen;
808 816
817 err = ubifs_init_security(dir, inode, &dentry->d_name);
818 if (err)
819 goto out_cancel;
820
809 mutex_lock(&dir_ui->ui_mutex); 821 mutex_lock(&dir_ui->ui_mutex);
810 dir->i_size += sz_change; 822 dir->i_size += sz_change;
811 dir_ui->ui_size = dir->i_size; 823 dir_ui->ui_size = dir->i_size;
@@ -882,6 +894,10 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
882 ui->data_len = len; 894 ui->data_len = len;
883 inode->i_size = ubifs_inode(inode)->ui_size = len; 895 inode->i_size = ubifs_inode(inode)->ui_size = len;
884 896
897 err = ubifs_init_security(dir, inode, &dentry->d_name);
898 if (err)
899 goto out_cancel;
900
885 mutex_lock(&dir_ui->ui_mutex); 901 mutex_lock(&dir_ui->ui_mutex);
886 dir->i_size += sz_change; 902 dir->i_size += sz_change;
887 dir_ui->ui_size = dir->i_size; 903 dir_ui->ui_size = dir->i_size;
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 035e51011444..e627c0acf626 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1573,6 +1573,10 @@ const struct inode_operations ubifs_symlink_inode_operations = {
1573 .follow_link = ubifs_follow_link, 1573 .follow_link = ubifs_follow_link,
1574 .setattr = ubifs_setattr, 1574 .setattr = ubifs_setattr,
1575 .getattr = ubifs_getattr, 1575 .getattr = ubifs_getattr,
1576 .setxattr = ubifs_setxattr,
1577 .getxattr = ubifs_getxattr,
1578 .listxattr = ubifs_listxattr,
1579 .removexattr = ubifs_removexattr,
1576}; 1580};
1577 1581
1578const struct file_operations ubifs_file_operations = { 1582const struct file_operations ubifs_file_operations = {
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c
index 3187925e9879..9b40a1c5e160 100644
--- a/fs/ubifs/replay.c
+++ b/fs/ubifs/replay.c
@@ -1028,9 +1028,22 @@ int ubifs_replay_journal(struct ubifs_info *c)
1028 1028
1029 do { 1029 do {
1030 err = replay_log_leb(c, lnum, 0, c->sbuf); 1030 err = replay_log_leb(c, lnum, 0, c->sbuf);
1031 if (err == 1) 1031 if (err == 1) {
1032 /* We hit the end of the log */ 1032 if (lnum != c->lhead_lnum)
1033 break; 1033 /* We hit the end of the log */
1034 break;
1035
1036 /*
1037 * The head of the log must always start with the
1038 * "commit start" node on a properly formatted UBIFS.
1039 * But we found no nodes at all, which means that
1040 * someting went wrong and we cannot proceed mounting
1041 * the file-system.
1042 */
1043 ubifs_err("no UBIFS nodes found at the log head LEB %d:%d, possibly corrupted",
1044 lnum, 0);
1045 err = -EINVAL;
1046 }
1034 if (err) 1047 if (err)
1035 goto out; 1048 goto out;
1036 lnum = ubifs_next_log_lnum(c, lnum); 1049 lnum = ubifs_next_log_lnum(c, lnum);
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 6197154f36ca..93e946561c5c 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2036,6 +2036,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
2036 if (c->max_inode_sz > MAX_LFS_FILESIZE) 2036 if (c->max_inode_sz > MAX_LFS_FILESIZE)
2037 sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE; 2037 sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE;
2038 sb->s_op = &ubifs_super_operations; 2038 sb->s_op = &ubifs_super_operations;
2039 sb->s_xattr = ubifs_xattr_handlers;
2039 2040
2040 mutex_lock(&c->umount_mutex); 2041 mutex_lock(&c->umount_mutex);
2041 err = mount_ubifs(c); 2042 err = mount_ubifs(c);
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index c4fe900c67ab..bc04b9c69891 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -36,6 +36,7 @@
36#include <linux/mtd/ubi.h> 36#include <linux/mtd/ubi.h>
37#include <linux/pagemap.h> 37#include <linux/pagemap.h>
38#include <linux/backing-dev.h> 38#include <linux/backing-dev.h>
39#include <linux/security.h>
39#include "ubifs-media.h" 40#include "ubifs-media.h"
40 41
41/* Version of this UBIFS implementation */ 42/* Version of this UBIFS implementation */
@@ -1465,6 +1466,7 @@ extern spinlock_t ubifs_infos_lock;
1465extern atomic_long_t ubifs_clean_zn_cnt; 1466extern atomic_long_t ubifs_clean_zn_cnt;
1466extern struct kmem_cache *ubifs_inode_slab; 1467extern struct kmem_cache *ubifs_inode_slab;
1467extern const struct super_operations ubifs_super_operations; 1468extern const struct super_operations ubifs_super_operations;
1469extern const struct xattr_handler *ubifs_xattr_handlers[];
1468extern const struct address_space_operations ubifs_file_address_operations; 1470extern const struct address_space_operations ubifs_file_address_operations;
1469extern const struct file_operations ubifs_file_operations; 1471extern const struct file_operations ubifs_file_operations;
1470extern const struct inode_operations ubifs_file_inode_operations; 1472extern const struct inode_operations ubifs_file_inode_operations;
@@ -1754,6 +1756,8 @@ ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf,
1754 size_t size); 1756 size_t size);
1755ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size); 1757ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size);
1756int ubifs_removexattr(struct dentry *dentry, const char *name); 1758int ubifs_removexattr(struct dentry *dentry, const char *name);
1759int ubifs_init_security(struct inode *dentry, struct inode *inode,
1760 const struct qstr *qstr);
1757 1761
1758/* super.c */ 1762/* super.c */
1759struct inode *ubifs_iget(struct super_block *sb, unsigned long inum); 1763struct inode *ubifs_iget(struct super_block *sb, unsigned long inum);
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index 5e0a63b1b0d5..a92be244a6fb 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -100,24 +100,30 @@ static const struct file_operations empty_fops;
100static int create_xattr(struct ubifs_info *c, struct inode *host, 100static int create_xattr(struct ubifs_info *c, struct inode *host,
101 const struct qstr *nm, const void *value, int size) 101 const struct qstr *nm, const void *value, int size)
102{ 102{
103 int err; 103 int err, names_len;
104 struct inode *inode; 104 struct inode *inode;
105 struct ubifs_inode *ui, *host_ui = ubifs_inode(host); 105 struct ubifs_inode *ui, *host_ui = ubifs_inode(host);
106 struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, 106 struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
107 .new_ino_d = ALIGN(size, 8), .dirtied_ino = 1, 107 .new_ino_d = ALIGN(size, 8), .dirtied_ino = 1,
108 .dirtied_ino_d = ALIGN(host_ui->data_len, 8) }; 108 .dirtied_ino_d = ALIGN(host_ui->data_len, 8) };
109 109
110 if (host_ui->xattr_cnt >= MAX_XATTRS_PER_INODE) 110 if (host_ui->xattr_cnt >= MAX_XATTRS_PER_INODE) {
111 ubifs_err("inode %lu already has too many xattrs (%d), cannot create more",
112 host->i_ino, host_ui->xattr_cnt);
111 return -ENOSPC; 113 return -ENOSPC;
114 }
112 /* 115 /*
113 * Linux limits the maximum size of the extended attribute names list 116 * Linux limits the maximum size of the extended attribute names list
114 * to %XATTR_LIST_MAX. This means we should not allow creating more 117 * to %XATTR_LIST_MAX. This means we should not allow creating more
115 * extended attributes if the name list becomes larger. This limitation 118 * extended attributes if the name list becomes larger. This limitation
116 * is artificial for UBIFS, though. 119 * is artificial for UBIFS, though.
117 */ 120 */
118 if (host_ui->xattr_names + host_ui->xattr_cnt + 121 names_len = host_ui->xattr_names + host_ui->xattr_cnt + nm->len + 1;
119 nm->len + 1 > XATTR_LIST_MAX) 122 if (names_len > XATTR_LIST_MAX) {
123 ubifs_err("cannot add one more xattr name to inode %lu, total names length would become %d, max. is %d",
124 host->i_ino, names_len, XATTR_LIST_MAX);
120 return -ENOSPC; 125 return -ENOSPC;
126 }
121 127
122 err = ubifs_budget_space(c, &req); 128 err = ubifs_budget_space(c, &req);
123 if (err) 129 if (err)
@@ -293,18 +299,16 @@ static struct inode *iget_xattr(struct ubifs_info *c, ino_t inum)
293 return ERR_PTR(-EINVAL); 299 return ERR_PTR(-EINVAL);
294} 300}
295 301
296int ubifs_setxattr(struct dentry *dentry, const char *name, 302static int setxattr(struct inode *host, const char *name, const void *value,
297 const void *value, size_t size, int flags) 303 size_t size, int flags)
298{ 304{
299 struct inode *inode, *host = dentry->d_inode; 305 struct inode *inode;
300 struct ubifs_info *c = host->i_sb->s_fs_info; 306 struct ubifs_info *c = host->i_sb->s_fs_info;
301 struct qstr nm = QSTR_INIT(name, strlen(name)); 307 struct qstr nm = QSTR_INIT(name, strlen(name));
302 struct ubifs_dent_node *xent; 308 struct ubifs_dent_node *xent;
303 union ubifs_key key; 309 union ubifs_key key;
304 int err, type; 310 int err, type;
305 311
306 dbg_gen("xattr '%s', host ino %lu ('%pd'), size %zd", name,
307 host->i_ino, dentry, size);
308 ubifs_assert(mutex_is_locked(&host->i_mutex)); 312 ubifs_assert(mutex_is_locked(&host->i_mutex));
309 313
310 if (size > UBIFS_MAX_INO_DATA) 314 if (size > UBIFS_MAX_INO_DATA)
@@ -356,6 +360,15 @@ out_free:
356 return err; 360 return err;
357} 361}
358 362
363int ubifs_setxattr(struct dentry *dentry, const char *name,
364 const void *value, size_t size, int flags)
365{
366 dbg_gen("xattr '%s', host ino %lu ('%pd'), size %zd",
367 name, dentry->d_inode->i_ino, dentry, size);
368
369 return setxattr(dentry->d_inode, name, value, size, flags);
370}
371
359ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf, 372ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf,
360 size_t size) 373 size_t size)
361{ 374{
@@ -568,3 +581,84 @@ out_free:
568 kfree(xent); 581 kfree(xent);
569 return err; 582 return err;
570} 583}
584
585static size_t security_listxattr(struct dentry *d, char *list, size_t list_size,
586 const char *name, size_t name_len, int flags)
587{
588 const int prefix_len = XATTR_SECURITY_PREFIX_LEN;
589 const size_t total_len = prefix_len + name_len + 1;
590
591 if (list && total_len <= list_size) {
592 memcpy(list, XATTR_SECURITY_PREFIX, prefix_len);
593 memcpy(list + prefix_len, name, name_len);
594 list[prefix_len + name_len] = '\0';
595 }
596
597 return total_len;
598}
599
600static int security_getxattr(struct dentry *d, const char *name, void *buffer,
601 size_t size, int flags)
602{
603 return ubifs_getxattr(d, name, buffer, size);
604}
605
606static int security_setxattr(struct dentry *d, const char *name,
607 const void *value, size_t size, int flags,
608 int handler_flags)
609{
610 return ubifs_setxattr(d, name, value, size, flags);
611}
612
613static const struct xattr_handler ubifs_xattr_security_handler = {
614 .prefix = XATTR_SECURITY_PREFIX,
615 .list = security_listxattr,
616 .get = security_getxattr,
617 .set = security_setxattr,
618};
619
620const struct xattr_handler *ubifs_xattr_handlers[] = {
621 &ubifs_xattr_security_handler,
622 NULL,
623};
624
625static int init_xattrs(struct inode *inode, const struct xattr *xattr_array,
626 void *fs_info)
627{
628 const struct xattr *xattr;
629 char *name;
630 int err = 0;
631
632 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
633 name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
634 strlen(xattr->name) + 1, GFP_NOFS);
635 if (!name) {
636 err = -ENOMEM;
637 break;
638 }
639 strcpy(name, XATTR_SECURITY_PREFIX);
640 strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
641 err = setxattr(inode, name, xattr->value, xattr->value_len, 0);
642 kfree(name);
643 if (err < 0)
644 break;
645 }
646
647 return err;
648}
649
650int ubifs_init_security(struct inode *dentry, struct inode *inode,
651 const struct qstr *qstr)
652{
653 int err;
654
655 mutex_lock(&inode->i_mutex);
656 err = security_inode_init_security(inode, dentry, qstr,
657 &init_xattrs, 0);
658 mutex_unlock(&inode->i_mutex);
659
660 if (err)
661 ubifs_err("cannot initialize security for inode %lu, error %d",
662 inode->i_ino, err);
663 return err;
664}