aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2019-04-04 18:34:38 -0400
committerRichard Weinberger <richard@nod.at>2019-05-07 15:58:31 -0400
commit9ca2d732644484488db31123ecd3bf122b551566 (patch)
tree11fa3f5849b76e2f47a199a0c2994a99d53002dc
parent988bec41318f3fa897e2f8af271bd456936d6caf (diff)
ubifs: Limit number of xattrs per inode
Since we have to write one deletion inode per xattr into the journal, limit the max number of xattrs. In theory UBIFS supported up to 65535 xattrs per inode. But this never worked correctly, expect no powercuts happened. Now we support only as many xattrs as we can store in 50% of a LEB. Even for tiny flashes this allows dozens of xattrs per inode, which is for an embedded filesystem still fine. In case someone has existing inodes with much more xattrs, it is still possible to delete them. UBIFS will fall back to an non-atomic deletion mode. Reported-by: Stefan Agner <stefan@agner.ch> Fixes: 1e51764a3c2ac ("UBIFS: add new flash file system") Signed-off-by: Richard Weinberger <richard@nod.at>
-rw-r--r--fs/ubifs/dir.c15
-rw-r--r--fs/ubifs/journal.c12
-rw-r--r--fs/ubifs/misc.h8
-rw-r--r--fs/ubifs/super.c2
-rw-r--r--fs/ubifs/ubifs.h1
-rw-r--r--fs/ubifs/xattr.c71
6 files changed, 101 insertions, 8 deletions
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index c3311ea68fe5..d2f5a50f5d83 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -796,6 +796,10 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
796 if (err) 796 if (err)
797 return err; 797 return err;
798 798
799 err = ubifs_purge_xattrs(inode);
800 if (err)
801 return err;
802
799 sz_change = CALC_DENT_SIZE(fname_len(&nm)); 803 sz_change = CALC_DENT_SIZE(fname_len(&nm));
800 804
801 ubifs_assert(c, inode_is_locked(dir)); 805 ubifs_assert(c, inode_is_locked(dir));
@@ -900,6 +904,10 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
900 if (err) 904 if (err)
901 return err; 905 return err;
902 906
907 err = ubifs_purge_xattrs(inode);
908 if (err)
909 return err;
910
903 sz_change = CALC_DENT_SIZE(fname_len(&nm)); 911 sz_change = CALC_DENT_SIZE(fname_len(&nm));
904 912
905 err = ubifs_budget_space(c, &req); 913 err = ubifs_budget_space(c, &req);
@@ -1282,9 +1290,14 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
1282 old_dentry, old_inode->i_ino, old_dir->i_ino, 1290 old_dentry, old_inode->i_ino, old_dir->i_ino,
1283 new_dentry, new_dir->i_ino, flags); 1291 new_dentry, new_dir->i_ino, flags);
1284 1292
1285 if (unlink) 1293 if (unlink) {
1286 ubifs_assert(c, inode_is_locked(new_inode)); 1294 ubifs_assert(c, inode_is_locked(new_inode));
1287 1295
1296 err = ubifs_purge_xattrs(new_inode);
1297 if (err)
1298 return err;
1299 }
1300
1288 if (unlink && is_dir) { 1301 if (unlink && is_dir) {
1289 err = ubifs_check_dir_empty(new_inode); 1302 err = ubifs_check_dir_empty(new_inode);
1290 if (err) 1303 if (err)
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index 4f74d443ca44..74a7306978d0 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -892,6 +892,11 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode)
892 struct inode *xino; 892 struct inode *xino;
893 struct ubifs_dent_node *xent, *pxent = NULL; 893 struct ubifs_dent_node *xent, *pxent = NULL;
894 894
895 if (ui->xattr_cnt >= ubifs_xattr_max_cnt(c)) {
896 ubifs_err(c, "Cannot delete inode, it has too much xattrs!");
897 goto out_release;
898 }
899
895 lowest_xent_key(c, &key, inode->i_ino); 900 lowest_xent_key(c, &key, inode->i_ino);
896 while (1) { 901 while (1) {
897 xent = ubifs_tnc_next_ent(c, &key, &nm); 902 xent = ubifs_tnc_next_ent(c, &key, &nm);
@@ -907,6 +912,13 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode)
907 fname_len(&nm) = le16_to_cpu(xent->nlen); 912 fname_len(&nm) = le16_to_cpu(xent->nlen);
908 913
909 xino = ubifs_iget(c->vfs_sb, xent->inum); 914 xino = ubifs_iget(c->vfs_sb, xent->inum);
915 if (IS_ERR(xino)) {
916 err = PTR_ERR(xino);
917 ubifs_err(c, "dead directory entry '%s', error %d",
918 xent->name, err);
919 ubifs_ro_mode(c, err);
920 goto out_release;
921 }
910 ubifs_assert(c, ubifs_inode(xino)->xattr); 922 ubifs_assert(c, ubifs_inode(xino)->xattr);
911 923
912 clear_nlink(xino); 924 clear_nlink(xino);
diff --git a/fs/ubifs/misc.h b/fs/ubifs/misc.h
index 6f87237fdbf4..78a6e97f846e 100644
--- a/fs/ubifs/misc.h
+++ b/fs/ubifs/misc.h
@@ -288,6 +288,14 @@ static inline int ubifs_next_log_lnum(const struct ubifs_info *c, int lnum)
288 return lnum; 288 return lnum;
289} 289}
290 290
291static inline int ubifs_xattr_max_cnt(struct ubifs_info *c)
292{
293 int max_xattrs = (c->leb_size / 2) / UBIFS_INO_NODE_SZ;
294
295 ubifs_assert(c, max_xattrs < c->max_orphans);
296 return max_xattrs;
297}
298
291const char *ubifs_assert_action_name(struct ubifs_info *c); 299const char *ubifs_assert_action_name(struct ubifs_info *c);
292 300
293#endif /* __UBIFS_MISC_H__ */ 301#endif /* __UBIFS_MISC_H__ */
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 12628184772c..300458a4f518 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -1548,6 +1548,8 @@ static int mount_ubifs(struct ubifs_info *c)
1548 c->bud_bytes, c->bud_bytes >> 10, c->bud_bytes >> 20); 1548 c->bud_bytes, c->bud_bytes >> 10, c->bud_bytes >> 20);
1549 dbg_gen("max. seq. number: %llu", c->max_sqnum); 1549 dbg_gen("max. seq. number: %llu", c->max_sqnum);
1550 dbg_gen("commit number: %llu", c->cmt_no); 1550 dbg_gen("commit number: %llu", c->cmt_no);
1551 dbg_gen("max. xattrs per inode: %d", ubifs_xattr_max_cnt(c));
1552 dbg_gen("max orphans: %d", c->max_orphans);
1551 1553
1552 return 0; 1554 return 0;
1553 1555
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index d28102829f6c..cf4b10f24b6d 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -2017,6 +2017,7 @@ int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
2017 size_t size, int flags, bool check_lock); 2017 size_t size, int flags, bool check_lock);
2018ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf, 2018ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
2019 size_t size); 2019 size_t size);
2020int ubifs_purge_xattrs(struct inode *host);
2020 2021
2021#ifdef CONFIG_UBIFS_FS_XATTR 2022#ifdef CONFIG_UBIFS_FS_XATTR
2022void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum); 2023void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum);
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index f5ad1ede7990..acab3181ab35 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -61,12 +61,6 @@
61#include <linux/xattr.h> 61#include <linux/xattr.h>
62 62
63/* 63/*
64 * Limit the number of extended attributes per inode so that the total size
65 * (@xattr_size) is guaranteeded to fit in an 'unsigned int'.
66 */
67#define MAX_XATTRS_PER_INODE 65535
68
69/*
70 * Extended attribute type constants. 64 * Extended attribute type constants.
71 * 65 *
72 * USER_XATTR: user extended attribute ("user.*") 66 * USER_XATTR: user extended attribute ("user.*")
@@ -106,7 +100,7 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
106 .new_ino_d = ALIGN(size, 8), .dirtied_ino = 1, 100 .new_ino_d = ALIGN(size, 8), .dirtied_ino = 1,
107 .dirtied_ino_d = ALIGN(host_ui->data_len, 8) }; 101 .dirtied_ino_d = ALIGN(host_ui->data_len, 8) };
108 102
109 if (host_ui->xattr_cnt >= MAX_XATTRS_PER_INODE) { 103 if (host_ui->xattr_cnt >= ubifs_xattr_max_cnt(c)) {
110 ubifs_err(c, "inode %lu already has too many xattrs (%d), cannot create more", 104 ubifs_err(c, "inode %lu already has too many xattrs (%d), cannot create more",
111 host->i_ino, host_ui->xattr_cnt); 105 host->i_ino, host_ui->xattr_cnt);
112 return -ENOSPC; 106 return -ENOSPC;
@@ -507,6 +501,69 @@ out_cancel:
507 return err; 501 return err;
508} 502}
509 503
504int ubifs_purge_xattrs(struct inode *host)
505{
506 union ubifs_key key;
507 struct ubifs_info *c = host->i_sb->s_fs_info;
508 struct ubifs_dent_node *xent, *pxent = NULL;
509 struct inode *xino;
510 struct fscrypt_name nm = {0};
511 int err;
512
513 if (ubifs_inode(host)->xattr_cnt < ubifs_xattr_max_cnt(c))
514 return 0;
515
516 ubifs_warn(c, "inode %lu has too many xattrs, doing a non-atomic deletion",
517 host->i_ino);
518
519 lowest_xent_key(c, &key, host->i_ino);
520 while (1) {
521 xent = ubifs_tnc_next_ent(c, &key, &nm);
522 if (IS_ERR(xent)) {
523 err = PTR_ERR(xent);
524 break;
525 }
526
527 fname_name(&nm) = xent->name;
528 fname_len(&nm) = le16_to_cpu(xent->nlen);
529
530 xino = ubifs_iget(c->vfs_sb, xent->inum);
531 if (IS_ERR(xino)) {
532 err = PTR_ERR(xino);
533 ubifs_err(c, "dead directory entry '%s', error %d",
534 xent->name, err);
535 ubifs_ro_mode(c, err);
536 kfree(pxent);
537 return err;
538 }
539
540 ubifs_assert(c, ubifs_inode(xino)->xattr);
541
542 clear_nlink(xino);
543 err = remove_xattr(c, host, xino, &nm);
544 if (err) {
545 kfree(pxent);
546 iput(xino);
547 ubifs_err(c, "cannot remove xattr, error %d", err);
548 return err;
549 }
550
551 iput(xino);
552
553 kfree(pxent);
554 pxent = xent;
555 key_read(c, &xent->key, &key);
556 }
557
558 kfree(pxent);
559 if (err != -ENOENT) {
560 ubifs_err(c, "cannot find next direntry, error %d", err);
561 return err;
562 }
563
564 return 0;
565}
566
510/** 567/**
511 * ubifs_evict_xattr_inode - Evict an xattr inode. 568 * ubifs_evict_xattr_inode - Evict an xattr inode.
512 * @c: UBIFS file-system description object 569 * @c: UBIFS file-system description object