diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-15 13:46:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-15 13:46:14 -0400 |
commit | 966859b9f73de9bcc14dece604ced6c0c562075b (patch) | |
tree | 501b0e17f494dd1642bfbb406795d0d369f32e04 | |
parent | e37a07e0c29cd2cef4633b1e6db5579cc99ba4cd (diff) | |
parent | a6664433d383eeb71cbdeb9aea2c66eeea76e742 (diff) |
Merge tag 'upstream-4.13-rc1' of git://git.infradead.org/linux-ubifs
Pull UBIFS updates from Richard Weinberger:
- Updates and fixes for the file encryption mode
- Minor improvements
- Random fixes
* tag 'upstream-4.13-rc1' of git://git.infradead.org/linux-ubifs:
ubifs: Set double hash cookie also for RENAME_EXCHANGE
ubifs: Massage assert in ubifs_xattr_set() wrt. init_xattrs
ubifs: Don't leak kernel memory to the MTD
ubifs: Change gfp flags in page allocation for bulk read
ubifs: Fix oops when remounting with no_bulk_read.
ubifs: Fail commit if TNC is obviously inconsistent
ubifs: allow userspace to map mounts to volumes
ubifs: Wire-up statx() support
ubifs: Remove dead code from ubifs_get_link()
ubifs: Massage debug prints wrt. fscrypt
ubifs: Add assert to dent_key_init()
ubifs: Fix unlink code wrt. double hash lookups
ubifs: Fix data node size for truncating uncompressed nodes
ubifs: Don't encrypt special files on creation
ubifs: Fix memory leak in RENAME_WHITEOUT error path in do_rename
ubifs: Fix inode data budget in ubifs_mknod
ubifs: Correctly evict xattr inodes
ubifs: Unexport ubifs_inode_slab
ubifs: don't bother checking for encryption key in ->mmap()
ubifs: require key for truncate(2) of encrypted file
-rw-r--r-- | fs/ubifs/crypto.c | 7 | ||||
-rw-r--r-- | fs/ubifs/dir.c | 32 | ||||
-rw-r--r-- | fs/ubifs/file.c | 27 | ||||
-rw-r--r-- | fs/ubifs/journal.c | 36 | ||||
-rw-r--r-- | fs/ubifs/key.h | 1 | ||||
-rw-r--r-- | fs/ubifs/super.c | 11 | ||||
-rw-r--r-- | fs/ubifs/tnc.c | 140 | ||||
-rw-r--r-- | fs/ubifs/tnc_commit.c | 4 | ||||
-rw-r--r-- | fs/ubifs/ubifs.h | 6 | ||||
-rw-r--r-- | fs/ubifs/xattr.c | 39 |
10 files changed, 218 insertions, 85 deletions
diff --git a/fs/ubifs/crypto.c b/fs/ubifs/crypto.c index 382ed428cfd2..114ba455bac3 100644 --- a/fs/ubifs/crypto.c +++ b/fs/ubifs/crypto.c | |||
@@ -9,8 +9,13 @@ static int ubifs_crypt_get_context(struct inode *inode, void *ctx, size_t len) | |||
9 | static int ubifs_crypt_set_context(struct inode *inode, const void *ctx, | 9 | static int ubifs_crypt_set_context(struct inode *inode, const void *ctx, |
10 | size_t len, void *fs_data) | 10 | size_t len, void *fs_data) |
11 | { | 11 | { |
12 | /* | ||
13 | * Creating an encryption context is done unlocked since we | ||
14 | * operate on a new inode which is not visible to other users | ||
15 | * at this point. So, no need to check whether inode is locked. | ||
16 | */ | ||
12 | return ubifs_xattr_set(inode, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT, | 17 | return ubifs_xattr_set(inode, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT, |
13 | ctx, len, 0); | 18 | ctx, len, 0, false); |
14 | } | 19 | } |
15 | 20 | ||
16 | static bool ubifs_crypt_empty_dir(struct inode *inode) | 21 | static bool ubifs_crypt_empty_dir(struct inode *inode) |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 566079d9b402..417fe0b29f23 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
@@ -143,6 +143,7 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir, | |||
143 | case S_IFBLK: | 143 | case S_IFBLK: |
144 | case S_IFCHR: | 144 | case S_IFCHR: |
145 | inode->i_op = &ubifs_file_inode_operations; | 145 | inode->i_op = &ubifs_file_inode_operations; |
146 | encrypted = false; | ||
146 | break; | 147 | break; |
147 | default: | 148 | default: |
148 | BUG(); | 149 | BUG(); |
@@ -1061,7 +1062,6 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry, | |||
1061 | int sz_change; | 1062 | int sz_change; |
1062 | int err, devlen = 0; | 1063 | int err, devlen = 0; |
1063 | struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, | 1064 | struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, |
1064 | .new_ino_d = ALIGN(devlen, 8), | ||
1065 | .dirtied_ino = 1 }; | 1065 | .dirtied_ino = 1 }; |
1066 | struct fscrypt_name nm; | 1066 | struct fscrypt_name nm; |
1067 | 1067 | ||
@@ -1079,6 +1079,7 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry, | |||
1079 | devlen = ubifs_encode_dev(dev, rdev); | 1079 | devlen = ubifs_encode_dev(dev, rdev); |
1080 | } | 1080 | } |
1081 | 1081 | ||
1082 | req.new_ino_d = ALIGN(devlen, 8); | ||
1082 | err = ubifs_budget_space(c, &req); | 1083 | err = ubifs_budget_space(c, &req); |
1083 | if (err) { | 1084 | if (err) { |
1084 | kfree(dev); | 1085 | kfree(dev); |
@@ -1396,17 +1397,14 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1396 | 1397 | ||
1397 | dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS); | 1398 | dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS); |
1398 | if (!dev) { | 1399 | if (!dev) { |
1399 | ubifs_release_budget(c, &req); | 1400 | err = -ENOMEM; |
1400 | ubifs_release_budget(c, &ino_req); | 1401 | goto out_release; |
1401 | return -ENOMEM; | ||
1402 | } | 1402 | } |
1403 | 1403 | ||
1404 | err = do_tmpfile(old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE, &whiteout); | 1404 | err = do_tmpfile(old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE, &whiteout); |
1405 | if (err) { | 1405 | if (err) { |
1406 | ubifs_release_budget(c, &req); | ||
1407 | ubifs_release_budget(c, &ino_req); | ||
1408 | kfree(dev); | 1406 | kfree(dev); |
1409 | return err; | 1407 | goto out_release; |
1410 | } | 1408 | } |
1411 | 1409 | ||
1412 | whiteout->i_state |= I_LINKABLE; | 1410 | whiteout->i_state |= I_LINKABLE; |
@@ -1494,12 +1492,10 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1494 | 1492 | ||
1495 | err = ubifs_budget_space(c, &wht_req); | 1493 | err = ubifs_budget_space(c, &wht_req); |
1496 | if (err) { | 1494 | if (err) { |
1497 | ubifs_release_budget(c, &req); | ||
1498 | ubifs_release_budget(c, &ino_req); | ||
1499 | kfree(whiteout_ui->data); | 1495 | kfree(whiteout_ui->data); |
1500 | whiteout_ui->data_len = 0; | 1496 | whiteout_ui->data_len = 0; |
1501 | iput(whiteout); | 1497 | iput(whiteout); |
1502 | return err; | 1498 | goto out_release; |
1503 | } | 1499 | } |
1504 | 1500 | ||
1505 | inc_nlink(whiteout); | 1501 | inc_nlink(whiteout); |
@@ -1554,6 +1550,7 @@ out_cancel: | |||
1554 | iput(whiteout); | 1550 | iput(whiteout); |
1555 | } | 1551 | } |
1556 | unlock_4_inodes(old_dir, new_dir, new_inode, whiteout); | 1552 | unlock_4_inodes(old_dir, new_dir, new_inode, whiteout); |
1553 | out_release: | ||
1557 | ubifs_release_budget(c, &ino_req); | 1554 | ubifs_release_budget(c, &ino_req); |
1558 | ubifs_release_budget(c, &req); | 1555 | ubifs_release_budget(c, &req); |
1559 | fscrypt_free_filename(&old_nm); | 1556 | fscrypt_free_filename(&old_nm); |
@@ -1647,6 +1644,21 @@ int ubifs_getattr(const struct path *path, struct kstat *stat, | |||
1647 | struct ubifs_inode *ui = ubifs_inode(inode); | 1644 | struct ubifs_inode *ui = ubifs_inode(inode); |
1648 | 1645 | ||
1649 | mutex_lock(&ui->ui_mutex); | 1646 | mutex_lock(&ui->ui_mutex); |
1647 | |||
1648 | if (ui->flags & UBIFS_APPEND_FL) | ||
1649 | stat->attributes |= STATX_ATTR_APPEND; | ||
1650 | if (ui->flags & UBIFS_COMPR_FL) | ||
1651 | stat->attributes |= STATX_ATTR_COMPRESSED; | ||
1652 | if (ui->flags & UBIFS_CRYPT_FL) | ||
1653 | stat->attributes |= STATX_ATTR_ENCRYPTED; | ||
1654 | if (ui->flags & UBIFS_IMMUTABLE_FL) | ||
1655 | stat->attributes |= STATX_ATTR_IMMUTABLE; | ||
1656 | |||
1657 | stat->attributes_mask |= (STATX_ATTR_APPEND | | ||
1658 | STATX_ATTR_COMPRESSED | | ||
1659 | STATX_ATTR_ENCRYPTED | | ||
1660 | STATX_ATTR_IMMUTABLE); | ||
1661 | |||
1650 | generic_fillattr(inode, stat); | 1662 | generic_fillattr(inode, stat); |
1651 | stat->blksize = UBIFS_BLOCK_SIZE; | 1663 | stat->blksize = UBIFS_BLOCK_SIZE; |
1652 | stat->size = ui->ui_size; | 1664 | stat->size = ui->ui_size; |
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 2cda3d67e2d0..8cad0b19b404 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
@@ -735,6 +735,7 @@ static int ubifs_do_bulk_read(struct ubifs_info *c, struct bu_info *bu, | |||
735 | int err, page_idx, page_cnt, ret = 0, n = 0; | 735 | int err, page_idx, page_cnt, ret = 0, n = 0; |
736 | int allocate = bu->buf ? 0 : 1; | 736 | int allocate = bu->buf ? 0 : 1; |
737 | loff_t isize; | 737 | loff_t isize; |
738 | gfp_t ra_gfp_mask = readahead_gfp_mask(mapping) & ~__GFP_FS; | ||
738 | 739 | ||
739 | err = ubifs_tnc_get_bu_keys(c, bu); | 740 | err = ubifs_tnc_get_bu_keys(c, bu); |
740 | if (err) | 741 | if (err) |
@@ -796,8 +797,7 @@ static int ubifs_do_bulk_read(struct ubifs_info *c, struct bu_info *bu, | |||
796 | 797 | ||
797 | if (page_offset > end_index) | 798 | if (page_offset > end_index) |
798 | break; | 799 | break; |
799 | page = find_or_create_page(mapping, page_offset, | 800 | page = find_or_create_page(mapping, page_offset, ra_gfp_mask); |
800 | GFP_NOFS | __GFP_COLD); | ||
801 | if (!page) | 801 | if (!page) |
802 | break; | 802 | break; |
803 | if (!PageUptodate(page)) | 803 | if (!PageUptodate(page)) |
@@ -1284,6 +1284,14 @@ int ubifs_setattr(struct dentry *dentry, struct iattr *attr) | |||
1284 | if (err) | 1284 | if (err) |
1285 | return err; | 1285 | return err; |
1286 | 1286 | ||
1287 | if (ubifs_crypt_is_encrypted(inode) && (attr->ia_valid & ATTR_SIZE)) { | ||
1288 | err = fscrypt_get_encryption_info(inode); | ||
1289 | if (err) | ||
1290 | return err; | ||
1291 | if (!fscrypt_has_encryption_key(inode)) | ||
1292 | return -ENOKEY; | ||
1293 | } | ||
1294 | |||
1287 | if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size < inode->i_size) | 1295 | if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size < inode->i_size) |
1288 | /* Truncation to a smaller size */ | 1296 | /* Truncation to a smaller size */ |
1289 | err = do_truncation(c, inode, attr); | 1297 | err = do_truncation(c, inode, attr); |
@@ -1607,15 +1615,6 @@ static const struct vm_operations_struct ubifs_file_vm_ops = { | |||
1607 | static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma) | 1615 | static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma) |
1608 | { | 1616 | { |
1609 | int err; | 1617 | int err; |
1610 | struct inode *inode = file->f_mapping->host; | ||
1611 | |||
1612 | if (ubifs_crypt_is_encrypted(inode)) { | ||
1613 | err = fscrypt_get_encryption_info(inode); | ||
1614 | if (err) | ||
1615 | return -EACCES; | ||
1616 | if (!fscrypt_has_encryption_key(inode)) | ||
1617 | return -ENOKEY; | ||
1618 | } | ||
1619 | 1618 | ||
1620 | err = generic_file_mmap(file, vma); | 1619 | err = generic_file_mmap(file, vma); |
1621 | if (err) | 1620 | if (err) |
@@ -1698,12 +1697,6 @@ static const char *ubifs_get_link(struct dentry *dentry, | |||
1698 | 1697 | ||
1699 | pstr.name[pstr.len] = '\0'; | 1698 | pstr.name[pstr.len] = '\0'; |
1700 | 1699 | ||
1701 | // XXX this probably won't happen anymore... | ||
1702 | if (pstr.name[0] == '\0') { | ||
1703 | fscrypt_fname_free_buffer(&pstr); | ||
1704 | return ERR_PTR(-ENOENT); | ||
1705 | } | ||
1706 | |||
1707 | set_delayed_call(done, kfree_link, pstr.name); | 1700 | set_delayed_call(done, kfree_link, pstr.name); |
1708 | return pstr.name; | 1701 | return pstr.name; |
1709 | } | 1702 | } |
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index 294519b98874..04c4ec6483e5 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c | |||
@@ -549,8 +549,6 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
549 | struct ubifs_ino_node *ino; | 549 | struct ubifs_ino_node *ino; |
550 | union ubifs_key dent_key, ino_key; | 550 | union ubifs_key dent_key, ino_key; |
551 | 551 | ||
552 | //dbg_jnl("ino %lu, dent '%.*s', data len %d in dir ino %lu", | ||
553 | // inode->i_ino, nm->len, nm->name, ui->data_len, dir->i_ino); | ||
554 | ubifs_assert(mutex_is_locked(&host_ui->ui_mutex)); | 552 | ubifs_assert(mutex_is_locked(&host_ui->ui_mutex)); |
555 | 553 | ||
556 | dlen = UBIFS_DENT_NODE_SZ + fname_len(nm) + 1; | 554 | dlen = UBIFS_DENT_NODE_SZ + fname_len(nm) + 1; |
@@ -574,7 +572,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
574 | /* Make sure to also account for extended attributes */ | 572 | /* Make sure to also account for extended attributes */ |
575 | len += host_ui->data_len; | 573 | len += host_ui->data_len; |
576 | 574 | ||
577 | dent = kmalloc(len, GFP_NOFS); | 575 | dent = kzalloc(len, GFP_NOFS); |
578 | if (!dent) | 576 | if (!dent) |
579 | return -ENOMEM; | 577 | return -ENOMEM; |
580 | 578 | ||
@@ -585,7 +583,10 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
585 | 583 | ||
586 | if (!xent) { | 584 | if (!xent) { |
587 | dent->ch.node_type = UBIFS_DENT_NODE; | 585 | dent->ch.node_type = UBIFS_DENT_NODE; |
588 | dent_key_init(c, &dent_key, dir->i_ino, nm); | 586 | if (nm->hash) |
587 | dent_key_init_hash(c, &dent_key, dir->i_ino, nm->hash); | ||
588 | else | ||
589 | dent_key_init(c, &dent_key, dir->i_ino, nm); | ||
589 | } else { | 590 | } else { |
590 | dent->ch.node_type = UBIFS_XENT_NODE; | 591 | dent->ch.node_type = UBIFS_XENT_NODE; |
591 | xent_key_init(c, &dent_key, dir->i_ino, nm); | 592 | xent_key_init(c, &dent_key, dir->i_ino, nm); |
@@ -629,7 +630,10 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
629 | kfree(dent); | 630 | kfree(dent); |
630 | 631 | ||
631 | if (deletion) { | 632 | if (deletion) { |
632 | err = ubifs_tnc_remove_nm(c, &dent_key, nm); | 633 | if (nm->hash) |
634 | err = ubifs_tnc_remove_dh(c, &dent_key, nm->minor_hash); | ||
635 | else | ||
636 | err = ubifs_tnc_remove_nm(c, &dent_key, nm); | ||
633 | if (err) | 637 | if (err) |
634 | goto out_ro; | 638 | goto out_ro; |
635 | err = ubifs_add_dirt(c, lnum, dlen); | 639 | err = ubifs_add_dirt(c, lnum, dlen); |
@@ -950,9 +954,6 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir, | |||
950 | int twoparents = (fst_dir != snd_dir); | 954 | int twoparents = (fst_dir != snd_dir); |
951 | void *p; | 955 | void *p; |
952 | 956 | ||
953 | //dbg_jnl("dent '%pd' in dir ino %lu between dent '%pd' in dir ino %lu", | ||
954 | // fst_dentry, fst_dir->i_ino, snd_dentry, snd_dir->i_ino); | ||
955 | |||
956 | ubifs_assert(ubifs_inode(fst_dir)->data_len == 0); | 957 | ubifs_assert(ubifs_inode(fst_dir)->data_len == 0); |
957 | ubifs_assert(ubifs_inode(snd_dir)->data_len == 0); | 958 | ubifs_assert(ubifs_inode(snd_dir)->data_len == 0); |
958 | ubifs_assert(mutex_is_locked(&ubifs_inode(fst_dir)->ui_mutex)); | 959 | ubifs_assert(mutex_is_locked(&ubifs_inode(fst_dir)->ui_mutex)); |
@@ -967,7 +968,7 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir, | |||
967 | if (twoparents) | 968 | if (twoparents) |
968 | len += plen; | 969 | len += plen; |
969 | 970 | ||
970 | dent1 = kmalloc(len, GFP_NOFS); | 971 | dent1 = kzalloc(len, GFP_NOFS); |
971 | if (!dent1) | 972 | if (!dent1) |
972 | return -ENOMEM; | 973 | return -ENOMEM; |
973 | 974 | ||
@@ -984,6 +985,7 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir, | |||
984 | dent1->nlen = cpu_to_le16(fname_len(snd_nm)); | 985 | dent1->nlen = cpu_to_le16(fname_len(snd_nm)); |
985 | memcpy(dent1->name, fname_name(snd_nm), fname_len(snd_nm)); | 986 | memcpy(dent1->name, fname_name(snd_nm), fname_len(snd_nm)); |
986 | dent1->name[fname_len(snd_nm)] = '\0'; | 987 | dent1->name[fname_len(snd_nm)] = '\0'; |
988 | set_dent_cookie(c, dent1); | ||
987 | zero_dent_node_unused(dent1); | 989 | zero_dent_node_unused(dent1); |
988 | ubifs_prep_grp_node(c, dent1, dlen1, 0); | 990 | ubifs_prep_grp_node(c, dent1, dlen1, 0); |
989 | 991 | ||
@@ -996,6 +998,7 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir, | |||
996 | dent2->nlen = cpu_to_le16(fname_len(fst_nm)); | 998 | dent2->nlen = cpu_to_le16(fname_len(fst_nm)); |
997 | memcpy(dent2->name, fname_name(fst_nm), fname_len(fst_nm)); | 999 | memcpy(dent2->name, fname_name(fst_nm), fname_len(fst_nm)); |
998 | dent2->name[fname_len(fst_nm)] = '\0'; | 1000 | dent2->name[fname_len(fst_nm)] = '\0'; |
1001 | set_dent_cookie(c, dent2); | ||
999 | zero_dent_node_unused(dent2); | 1002 | zero_dent_node_unused(dent2); |
1000 | ubifs_prep_grp_node(c, dent2, dlen2, 0); | 1003 | ubifs_prep_grp_node(c, dent2, dlen2, 0); |
1001 | 1004 | ||
@@ -1094,8 +1097,6 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
1094 | int move = (old_dir != new_dir); | 1097 | int move = (old_dir != new_dir); |
1095 | struct ubifs_inode *uninitialized_var(new_ui); | 1098 | struct ubifs_inode *uninitialized_var(new_ui); |
1096 | 1099 | ||
1097 | //dbg_jnl("dent '%pd' in dir ino %lu to dent '%pd' in dir ino %lu", | ||
1098 | // old_dentry, old_dir->i_ino, new_dentry, new_dir->i_ino); | ||
1099 | ubifs_assert(ubifs_inode(old_dir)->data_len == 0); | 1100 | ubifs_assert(ubifs_inode(old_dir)->data_len == 0); |
1100 | ubifs_assert(ubifs_inode(new_dir)->data_len == 0); | 1101 | ubifs_assert(ubifs_inode(new_dir)->data_len == 0); |
1101 | ubifs_assert(mutex_is_locked(&ubifs_inode(old_dir)->ui_mutex)); | 1102 | ubifs_assert(mutex_is_locked(&ubifs_inode(old_dir)->ui_mutex)); |
@@ -1117,7 +1118,7 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
1117 | len = aligned_dlen1 + aligned_dlen2 + ALIGN(ilen, 8) + ALIGN(plen, 8); | 1118 | len = aligned_dlen1 + aligned_dlen2 + ALIGN(ilen, 8) + ALIGN(plen, 8); |
1118 | if (move) | 1119 | if (move) |
1119 | len += plen; | 1120 | len += plen; |
1120 | dent = kmalloc(len, GFP_NOFS); | 1121 | dent = kzalloc(len, GFP_NOFS); |
1121 | if (!dent) | 1122 | if (!dent) |
1122 | return -ENOMEM; | 1123 | return -ENOMEM; |
1123 | 1124 | ||
@@ -1298,7 +1299,9 @@ static int truncate_data_node(const struct ubifs_info *c, const struct inode *in | |||
1298 | goto out; | 1299 | goto out; |
1299 | } | 1300 | } |
1300 | 1301 | ||
1301 | if (compr_type != UBIFS_COMPR_NONE) { | 1302 | if (compr_type == UBIFS_COMPR_NONE) { |
1303 | out_len = *new_len; | ||
1304 | } else { | ||
1302 | err = ubifs_decompress(c, &dn->data, dlen, buf, &out_len, compr_type); | 1305 | err = ubifs_decompress(c, &dn->data, dlen, buf, &out_len, compr_type); |
1303 | if (err) | 1306 | if (err) |
1304 | goto out; | 1307 | goto out; |
@@ -1485,9 +1488,6 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, | |||
1485 | int sync = IS_DIRSYNC(host); | 1488 | int sync = IS_DIRSYNC(host); |
1486 | struct ubifs_inode *host_ui = ubifs_inode(host); | 1489 | struct ubifs_inode *host_ui = ubifs_inode(host); |
1487 | 1490 | ||
1488 | //dbg_jnl("host %lu, xattr ino %lu, name '%s', data len %d", | ||
1489 | // host->i_ino, inode->i_ino, nm->name, | ||
1490 | // ubifs_inode(inode)->data_len); | ||
1491 | ubifs_assert(inode->i_nlink == 0); | 1491 | ubifs_assert(inode->i_nlink == 0); |
1492 | ubifs_assert(mutex_is_locked(&host_ui->ui_mutex)); | 1492 | ubifs_assert(mutex_is_locked(&host_ui->ui_mutex)); |
1493 | 1493 | ||
@@ -1500,7 +1500,7 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, | |||
1500 | hlen = host_ui->data_len + UBIFS_INO_NODE_SZ; | 1500 | hlen = host_ui->data_len + UBIFS_INO_NODE_SZ; |
1501 | len = aligned_xlen + UBIFS_INO_NODE_SZ + ALIGN(hlen, 8); | 1501 | len = aligned_xlen + UBIFS_INO_NODE_SZ + ALIGN(hlen, 8); |
1502 | 1502 | ||
1503 | xent = kmalloc(len, GFP_NOFS); | 1503 | xent = kzalloc(len, GFP_NOFS); |
1504 | if (!xent) | 1504 | if (!xent) |
1505 | return -ENOMEM; | 1505 | return -ENOMEM; |
1506 | 1506 | ||
@@ -1607,7 +1607,7 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode, | |||
1607 | aligned_len1 = ALIGN(len1, 8); | 1607 | aligned_len1 = ALIGN(len1, 8); |
1608 | aligned_len = aligned_len1 + ALIGN(len2, 8); | 1608 | aligned_len = aligned_len1 + ALIGN(len2, 8); |
1609 | 1609 | ||
1610 | ino = kmalloc(aligned_len, GFP_NOFS); | 1610 | ino = kzalloc(aligned_len, GFP_NOFS); |
1611 | if (!ino) | 1611 | if (!ino) |
1612 | return -ENOMEM; | 1612 | return -ENOMEM; |
1613 | 1613 | ||
diff --git a/fs/ubifs/key.h b/fs/ubifs/key.h index 7547be512db2..b1f7c0caa3ac 100644 --- a/fs/ubifs/key.h +++ b/fs/ubifs/key.h | |||
@@ -162,6 +162,7 @@ static inline void dent_key_init(const struct ubifs_info *c, | |||
162 | uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm)); | 162 | uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm)); |
163 | 163 | ||
164 | ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); | 164 | ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); |
165 | ubifs_assert(!nm->hash && !nm->minor_hash); | ||
165 | key->u32[0] = inum; | 166 | key->u32[0] = inum; |
166 | key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS); | 167 | key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS); |
167 | } | 168 | } |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index cf4cc99b75b5..bffadbb67e47 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #define UBIFS_KMALLOC_OK (128*1024) | 45 | #define UBIFS_KMALLOC_OK (128*1024) |
46 | 46 | ||
47 | /* Slab cache for UBIFS inodes */ | 47 | /* Slab cache for UBIFS inodes */ |
48 | struct kmem_cache *ubifs_inode_slab; | 48 | static struct kmem_cache *ubifs_inode_slab; |
49 | 49 | ||
50 | /* UBIFS TNC shrinker description */ | 50 | /* UBIFS TNC shrinker description */ |
51 | static struct shrinker ubifs_shrinker_info = { | 51 | static struct shrinker ubifs_shrinker_info = { |
@@ -446,6 +446,8 @@ static int ubifs_show_options(struct seq_file *s, struct dentry *root) | |||
446 | ubifs_compr_name(c->mount_opts.compr_type)); | 446 | ubifs_compr_name(c->mount_opts.compr_type)); |
447 | } | 447 | } |
448 | 448 | ||
449 | seq_printf(s, ",ubi=%d,vol=%d", c->vi.ubi_num, c->vi.vol_id); | ||
450 | |||
449 | return 0; | 451 | return 0; |
450 | } | 452 | } |
451 | 453 | ||
@@ -931,6 +933,7 @@ enum { | |||
931 | Opt_chk_data_crc, | 933 | Opt_chk_data_crc, |
932 | Opt_no_chk_data_crc, | 934 | Opt_no_chk_data_crc, |
933 | Opt_override_compr, | 935 | Opt_override_compr, |
936 | Opt_ignore, | ||
934 | Opt_err, | 937 | Opt_err, |
935 | }; | 938 | }; |
936 | 939 | ||
@@ -942,6 +945,8 @@ static const match_table_t tokens = { | |||
942 | {Opt_chk_data_crc, "chk_data_crc"}, | 945 | {Opt_chk_data_crc, "chk_data_crc"}, |
943 | {Opt_no_chk_data_crc, "no_chk_data_crc"}, | 946 | {Opt_no_chk_data_crc, "no_chk_data_crc"}, |
944 | {Opt_override_compr, "compr=%s"}, | 947 | {Opt_override_compr, "compr=%s"}, |
948 | {Opt_ignore, "ubi=%s"}, | ||
949 | {Opt_ignore, "vol=%s"}, | ||
945 | {Opt_err, NULL}, | 950 | {Opt_err, NULL}, |
946 | }; | 951 | }; |
947 | 952 | ||
@@ -1042,6 +1047,8 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options, | |||
1042 | c->default_compr = c->mount_opts.compr_type; | 1047 | c->default_compr = c->mount_opts.compr_type; |
1043 | break; | 1048 | break; |
1044 | } | 1049 | } |
1050 | case Opt_ignore: | ||
1051 | break; | ||
1045 | default: | 1052 | default: |
1046 | { | 1053 | { |
1047 | unsigned long flag; | 1054 | unsigned long flag; |
@@ -1869,8 +1876,10 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) | |||
1869 | bu_init(c); | 1876 | bu_init(c); |
1870 | else { | 1877 | else { |
1871 | dbg_gen("disable bulk-read"); | 1878 | dbg_gen("disable bulk-read"); |
1879 | mutex_lock(&c->bu_mutex); | ||
1872 | kfree(c->bu.buf); | 1880 | kfree(c->bu.buf); |
1873 | c->bu.buf = NULL; | 1881 | c->bu.buf = NULL; |
1882 | mutex_unlock(&c->bu_mutex); | ||
1874 | } | 1883 | } |
1875 | 1884 | ||
1876 | ubifs_assert(c->lst.taken_empty_lebs > 0); | 1885 | ubifs_assert(c->lst.taken_empty_lebs > 0); |
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 709aa098dd46..0a213dcba2a1 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c | |||
@@ -1812,7 +1812,7 @@ static int do_lookup_nm(struct ubifs_info *c, const union ubifs_key *key, | |||
1812 | int found, n, err; | 1812 | int found, n, err; |
1813 | struct ubifs_znode *znode; | 1813 | struct ubifs_znode *znode; |
1814 | 1814 | ||
1815 | //dbg_tnck(key, "name '%.*s' key ", nm->len, nm->name); | 1815 | dbg_tnck(key, "key "); |
1816 | mutex_lock(&c->tnc_mutex); | 1816 | mutex_lock(&c->tnc_mutex); |
1817 | found = ubifs_lookup_level0(c, key, &znode, &n); | 1817 | found = ubifs_lookup_level0(c, key, &znode, &n); |
1818 | if (!found) { | 1818 | if (!found) { |
@@ -1880,48 +1880,65 @@ int ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key, | |||
1880 | return do_lookup_nm(c, key, node, nm); | 1880 | return do_lookup_nm(c, key, node, nm); |
1881 | } | 1881 | } |
1882 | 1882 | ||
1883 | static int do_lookup_dh(struct ubifs_info *c, const union ubifs_key *key, | 1883 | static int search_dh_cookie(struct ubifs_info *c, const union ubifs_key *key, |
1884 | struct ubifs_dent_node *dent, uint32_t cookie) | 1884 | struct ubifs_dent_node *dent, uint32_t cookie, |
1885 | struct ubifs_znode **zn, int *n) | ||
1885 | { | 1886 | { |
1886 | int n, err, type = key_type(c, key); | 1887 | int err; |
1887 | struct ubifs_znode *znode; | 1888 | struct ubifs_znode *znode = *zn; |
1888 | struct ubifs_zbranch *zbr; | 1889 | struct ubifs_zbranch *zbr; |
1889 | union ubifs_key *dkey, start_key; | 1890 | union ubifs_key *dkey; |
1890 | |||
1891 | ubifs_assert(is_hash_key(c, key)); | ||
1892 | |||
1893 | lowest_dent_key(c, &start_key, key_inum(c, key)); | ||
1894 | |||
1895 | mutex_lock(&c->tnc_mutex); | ||
1896 | err = ubifs_lookup_level0(c, &start_key, &znode, &n); | ||
1897 | if (unlikely(err < 0)) | ||
1898 | goto out_unlock; | ||
1899 | 1891 | ||
1900 | for (;;) { | 1892 | for (;;) { |
1901 | if (!err) { | 1893 | if (!err) { |
1902 | err = tnc_next(c, &znode, &n); | 1894 | err = tnc_next(c, &znode, n); |
1903 | if (err) | 1895 | if (err) |
1904 | goto out_unlock; | 1896 | goto out; |
1905 | } | 1897 | } |
1906 | 1898 | ||
1907 | zbr = &znode->zbranch[n]; | 1899 | zbr = &znode->zbranch[*n]; |
1908 | dkey = &zbr->key; | 1900 | dkey = &zbr->key; |
1909 | 1901 | ||
1910 | if (key_inum(c, dkey) != key_inum(c, key) || | 1902 | if (key_inum(c, dkey) != key_inum(c, key) || |
1911 | key_type(c, dkey) != type) { | 1903 | key_type(c, dkey) != key_type(c, key)) { |
1912 | err = -ENOENT; | 1904 | err = -ENOENT; |
1913 | goto out_unlock; | 1905 | goto out; |
1914 | } | 1906 | } |
1915 | 1907 | ||
1916 | err = tnc_read_hashed_node(c, zbr, dent); | 1908 | err = tnc_read_hashed_node(c, zbr, dent); |
1917 | if (err) | 1909 | if (err) |
1918 | goto out_unlock; | 1910 | goto out; |
1919 | 1911 | ||
1920 | if (key_hash(c, key) == key_hash(c, dkey) && | 1912 | if (key_hash(c, key) == key_hash(c, dkey) && |
1921 | le32_to_cpu(dent->cookie) == cookie) | 1913 | le32_to_cpu(dent->cookie) == cookie) { |
1922 | goto out_unlock; | 1914 | *zn = znode; |
1915 | goto out; | ||
1916 | } | ||
1923 | } | 1917 | } |
1924 | 1918 | ||
1919 | out: | ||
1920 | |||
1921 | return err; | ||
1922 | } | ||
1923 | |||
1924 | static int do_lookup_dh(struct ubifs_info *c, const union ubifs_key *key, | ||
1925 | struct ubifs_dent_node *dent, uint32_t cookie) | ||
1926 | { | ||
1927 | int n, err; | ||
1928 | struct ubifs_znode *znode; | ||
1929 | union ubifs_key start_key; | ||
1930 | |||
1931 | ubifs_assert(is_hash_key(c, key)); | ||
1932 | |||
1933 | lowest_dent_key(c, &start_key, key_inum(c, key)); | ||
1934 | |||
1935 | mutex_lock(&c->tnc_mutex); | ||
1936 | err = ubifs_lookup_level0(c, &start_key, &znode, &n); | ||
1937 | if (unlikely(err < 0)) | ||
1938 | goto out_unlock; | ||
1939 | |||
1940 | err = search_dh_cookie(c, key, dent, cookie, &znode, &n); | ||
1941 | |||
1925 | out_unlock: | 1942 | out_unlock: |
1926 | mutex_unlock(&c->tnc_mutex); | 1943 | mutex_unlock(&c->tnc_mutex); |
1927 | return err; | 1944 | return err; |
@@ -2393,8 +2410,7 @@ int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, | |||
2393 | struct ubifs_znode *znode; | 2410 | struct ubifs_znode *znode; |
2394 | 2411 | ||
2395 | mutex_lock(&c->tnc_mutex); | 2412 | mutex_lock(&c->tnc_mutex); |
2396 | //dbg_tnck(key, "LEB %d:%d, name '%.*s', key ", | 2413 | dbg_tnck(key, "LEB %d:%d, key ", lnum, offs); |
2397 | // lnum, offs, nm->len, nm->name); | ||
2398 | found = lookup_level0_dirty(c, key, &znode, &n); | 2414 | found = lookup_level0_dirty(c, key, &znode, &n); |
2399 | if (found < 0) { | 2415 | if (found < 0) { |
2400 | err = found; | 2416 | err = found; |
@@ -2628,7 +2644,7 @@ int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key, | |||
2628 | struct ubifs_znode *znode; | 2644 | struct ubifs_znode *znode; |
2629 | 2645 | ||
2630 | mutex_lock(&c->tnc_mutex); | 2646 | mutex_lock(&c->tnc_mutex); |
2631 | //dbg_tnck(key, "%.*s, key ", nm->len, nm->name); | 2647 | dbg_tnck(key, "key "); |
2632 | err = lookup_level0_dirty(c, key, &znode, &n); | 2648 | err = lookup_level0_dirty(c, key, &znode, &n); |
2633 | if (err < 0) | 2649 | if (err < 0) |
2634 | goto out_unlock; | 2650 | goto out_unlock; |
@@ -2663,6 +2679,74 @@ out_unlock: | |||
2663 | } | 2679 | } |
2664 | 2680 | ||
2665 | /** | 2681 | /** |
2682 | * ubifs_tnc_remove_dh - remove an index entry for a "double hashed" node. | ||
2683 | * @c: UBIFS file-system description object | ||
2684 | * @key: key of node | ||
2685 | * @cookie: node cookie for collision resolution | ||
2686 | * | ||
2687 | * Returns %0 on success or negative error code on failure. | ||
2688 | */ | ||
2689 | int ubifs_tnc_remove_dh(struct ubifs_info *c, const union ubifs_key *key, | ||
2690 | uint32_t cookie) | ||
2691 | { | ||
2692 | int n, err; | ||
2693 | struct ubifs_znode *znode; | ||
2694 | struct ubifs_dent_node *dent; | ||
2695 | struct ubifs_zbranch *zbr; | ||
2696 | |||
2697 | if (!c->double_hash) | ||
2698 | return -EOPNOTSUPP; | ||
2699 | |||
2700 | mutex_lock(&c->tnc_mutex); | ||
2701 | err = lookup_level0_dirty(c, key, &znode, &n); | ||
2702 | if (err <= 0) | ||
2703 | goto out_unlock; | ||
2704 | |||
2705 | zbr = &znode->zbranch[n]; | ||
2706 | dent = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS); | ||
2707 | if (!dent) { | ||
2708 | err = -ENOMEM; | ||
2709 | goto out_unlock; | ||
2710 | } | ||
2711 | |||
2712 | err = tnc_read_hashed_node(c, zbr, dent); | ||
2713 | if (err) | ||
2714 | goto out_free; | ||
2715 | |||
2716 | /* If the cookie does not match, we're facing a hash collision. */ | ||
2717 | if (le32_to_cpu(dent->cookie) != cookie) { | ||
2718 | union ubifs_key start_key; | ||
2719 | |||
2720 | lowest_dent_key(c, &start_key, key_inum(c, key)); | ||
2721 | |||
2722 | err = ubifs_lookup_level0(c, &start_key, &znode, &n); | ||
2723 | if (unlikely(err < 0)) | ||
2724 | goto out_free; | ||
2725 | |||
2726 | err = search_dh_cookie(c, key, dent, cookie, &znode, &n); | ||
2727 | if (err) | ||
2728 | goto out_free; | ||
2729 | } | ||
2730 | |||
2731 | if (znode->cnext || !ubifs_zn_dirty(znode)) { | ||
2732 | znode = dirty_cow_bottom_up(c, znode); | ||
2733 | if (IS_ERR(znode)) { | ||
2734 | err = PTR_ERR(znode); | ||
2735 | goto out_free; | ||
2736 | } | ||
2737 | } | ||
2738 | err = tnc_delete(c, znode, n); | ||
2739 | |||
2740 | out_free: | ||
2741 | kfree(dent); | ||
2742 | out_unlock: | ||
2743 | if (!err) | ||
2744 | err = dbg_check_tnc(c, 0); | ||
2745 | mutex_unlock(&c->tnc_mutex); | ||
2746 | return err; | ||
2747 | } | ||
2748 | |||
2749 | /** | ||
2666 | * key_in_range - determine if a key falls within a range of keys. | 2750 | * key_in_range - determine if a key falls within a range of keys. |
2667 | * @c: UBIFS file-system description object | 2751 | * @c: UBIFS file-system description object |
2668 | * @key: key to check | 2752 | * @key: key to check |
@@ -2802,6 +2886,8 @@ int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum) | |||
2802 | dbg_tnc("xent '%s', ino %lu", xent->name, | 2886 | dbg_tnc("xent '%s', ino %lu", xent->name, |
2803 | (unsigned long)xattr_inum); | 2887 | (unsigned long)xattr_inum); |
2804 | 2888 | ||
2889 | ubifs_evict_xattr_inode(c, xattr_inum); | ||
2890 | |||
2805 | fname_name(&nm) = xent->name; | 2891 | fname_name(&nm) = xent->name; |
2806 | fname_len(&nm) = le16_to_cpu(xent->nlen); | 2892 | fname_len(&nm) = le16_to_cpu(xent->nlen); |
2807 | err = ubifs_tnc_remove_nm(c, &key1, &nm); | 2893 | err = ubifs_tnc_remove_nm(c, &key1, &nm); |
@@ -2863,7 +2949,7 @@ struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c, | |||
2863 | struct ubifs_zbranch *zbr; | 2949 | struct ubifs_zbranch *zbr; |
2864 | union ubifs_key *dkey; | 2950 | union ubifs_key *dkey; |
2865 | 2951 | ||
2866 | //dbg_tnck(key, "%s ", nm->name ? (char *)nm->name : "(lowest)"); | 2952 | dbg_tnck(key, "key "); |
2867 | ubifs_assert(is_hash_key(c, key)); | 2953 | ubifs_assert(is_hash_key(c, key)); |
2868 | 2954 | ||
2869 | mutex_lock(&c->tnc_mutex); | 2955 | mutex_lock(&c->tnc_mutex); |
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c index 51157da3f76e..aa31f60220ef 100644 --- a/fs/ubifs/tnc_commit.c +++ b/fs/ubifs/tnc_commit.c | |||
@@ -57,6 +57,8 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx, | |||
57 | ubifs_dump_znode(c, znode); | 57 | ubifs_dump_znode(c, znode); |
58 | if (zbr->znode) | 58 | if (zbr->znode) |
59 | ubifs_dump_znode(c, zbr->znode); | 59 | ubifs_dump_znode(c, zbr->znode); |
60 | |||
61 | return -EINVAL; | ||
60 | } | 62 | } |
61 | } | 63 | } |
62 | ubifs_prepare_node(c, idx, len, 0); | 64 | ubifs_prepare_node(c, idx, len, 0); |
@@ -859,6 +861,8 @@ static int write_index(struct ubifs_info *c) | |||
859 | ubifs_dump_znode(c, znode); | 861 | ubifs_dump_znode(c, znode); |
860 | if (zbr->znode) | 862 | if (zbr->znode) |
861 | ubifs_dump_znode(c, zbr->znode); | 863 | ubifs_dump_znode(c, zbr->znode); |
864 | |||
865 | return -EINVAL; | ||
862 | } | 866 | } |
863 | } | 867 | } |
864 | len = ubifs_idx_node_sz(c, znode->child_cnt); | 868 | len = ubifs_idx_node_sz(c, znode->child_cnt); |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 298b4d89eee9..cd43651f1731 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -1451,7 +1451,6 @@ struct ubifs_info { | |||
1451 | extern struct list_head ubifs_infos; | 1451 | extern struct list_head ubifs_infos; |
1452 | extern spinlock_t ubifs_infos_lock; | 1452 | extern spinlock_t ubifs_infos_lock; |
1453 | extern atomic_long_t ubifs_clean_zn_cnt; | 1453 | extern atomic_long_t ubifs_clean_zn_cnt; |
1454 | extern struct kmem_cache *ubifs_inode_slab; | ||
1455 | extern const struct super_operations ubifs_super_operations; | 1454 | extern const struct super_operations ubifs_super_operations; |
1456 | extern const struct address_space_operations ubifs_file_address_operations; | 1455 | extern const struct address_space_operations ubifs_file_address_operations; |
1457 | extern const struct file_operations ubifs_file_operations; | 1456 | extern const struct file_operations ubifs_file_operations; |
@@ -1590,6 +1589,8 @@ int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, | |||
1590 | int ubifs_tnc_remove(struct ubifs_info *c, const union ubifs_key *key); | 1589 | int ubifs_tnc_remove(struct ubifs_info *c, const union ubifs_key *key); |
1591 | int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key, | 1590 | int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key, |
1592 | const struct fscrypt_name *nm); | 1591 | const struct fscrypt_name *nm); |
1592 | int ubifs_tnc_remove_dh(struct ubifs_info *c, const union ubifs_key *key, | ||
1593 | uint32_t cookie); | ||
1593 | int ubifs_tnc_remove_range(struct ubifs_info *c, union ubifs_key *from_key, | 1594 | int ubifs_tnc_remove_range(struct ubifs_info *c, union ubifs_key *from_key, |
1594 | union ubifs_key *to_key); | 1595 | union ubifs_key *to_key); |
1595 | int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum); | 1596 | int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum); |
@@ -1754,9 +1755,10 @@ int ubifs_check_dir_empty(struct inode *dir); | |||
1754 | extern const struct xattr_handler *ubifs_xattr_handlers[]; | 1755 | extern const struct xattr_handler *ubifs_xattr_handlers[]; |
1755 | ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size); | 1756 | ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size); |
1756 | int ubifs_xattr_set(struct inode *host, const char *name, const void *value, | 1757 | int ubifs_xattr_set(struct inode *host, const char *name, const void *value, |
1757 | size_t size, int flags); | 1758 | size_t size, int flags, bool check_lock); |
1758 | ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf, | 1759 | ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf, |
1759 | size_t size); | 1760 | size_t size); |
1761 | void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum); | ||
1760 | 1762 | ||
1761 | #ifdef CONFIG_UBIFS_FS_SECURITY | 1763 | #ifdef CONFIG_UBIFS_FS_SECURITY |
1762 | extern int ubifs_init_security(struct inode *dentry, struct inode *inode, | 1764 | extern int ubifs_init_security(struct inode *dentry, struct inode *inode, |
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index 6c9e62c2ef55..c13eae819cbc 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c | |||
@@ -280,7 +280,7 @@ static struct inode *iget_xattr(struct ubifs_info *c, ino_t inum) | |||
280 | } | 280 | } |
281 | 281 | ||
282 | int ubifs_xattr_set(struct inode *host, const char *name, const void *value, | 282 | int ubifs_xattr_set(struct inode *host, const char *name, const void *value, |
283 | size_t size, int flags) | 283 | size_t size, int flags, bool check_lock) |
284 | { | 284 | { |
285 | struct inode *inode; | 285 | struct inode *inode; |
286 | struct ubifs_info *c = host->i_sb->s_fs_info; | 286 | struct ubifs_info *c = host->i_sb->s_fs_info; |
@@ -289,12 +289,7 @@ int ubifs_xattr_set(struct inode *host, const char *name, const void *value, | |||
289 | union ubifs_key key; | 289 | union ubifs_key key; |
290 | int err; | 290 | int err; |
291 | 291 | ||
292 | /* | 292 | if (check_lock) |
293 | * Creating an encryption context is done unlocked since we | ||
294 | * operate on a new inode which is not visible to other users | ||
295 | * at this point. | ||
296 | */ | ||
297 | if (strcmp(name, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT) != 0) | ||
298 | ubifs_assert(inode_is_locked(host)); | 293 | ubifs_assert(inode_is_locked(host)); |
299 | 294 | ||
300 | if (size > UBIFS_MAX_INO_DATA) | 295 | if (size > UBIFS_MAX_INO_DATA) |
@@ -513,6 +508,28 @@ out_cancel: | |||
513 | return err; | 508 | return err; |
514 | } | 509 | } |
515 | 510 | ||
511 | /** | ||
512 | * ubifs_evict_xattr_inode - Evict an xattr inode. | ||
513 | * @c: UBIFS file-system description object | ||
514 | * @xattr_inum: xattr inode number | ||
515 | * | ||
516 | * When an inode that hosts xattrs is being removed we have to make sure | ||
517 | * that cached inodes of the xattrs also get removed from the inode cache | ||
518 | * otherwise we'd waste memory. This function looks up an inode from the | ||
519 | * inode cache and clears the link counter such that iput() will evict | ||
520 | * the inode. | ||
521 | */ | ||
522 | void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum) | ||
523 | { | ||
524 | struct inode *inode; | ||
525 | |||
526 | inode = ilookup(c->vfs_sb, xattr_inum); | ||
527 | if (inode) { | ||
528 | clear_nlink(inode); | ||
529 | iput(inode); | ||
530 | } | ||
531 | } | ||
532 | |||
516 | static int ubifs_xattr_remove(struct inode *host, const char *name) | 533 | static int ubifs_xattr_remove(struct inode *host, const char *name) |
517 | { | 534 | { |
518 | struct inode *inode; | 535 | struct inode *inode; |
@@ -576,8 +593,12 @@ static int init_xattrs(struct inode *inode, const struct xattr *xattr_array, | |||
576 | } | 593 | } |
577 | strcpy(name, XATTR_SECURITY_PREFIX); | 594 | strcpy(name, XATTR_SECURITY_PREFIX); |
578 | strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name); | 595 | strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name); |
596 | /* | ||
597 | * creating a new inode without holding the inode rwsem, | ||
598 | * no need to check whether inode is locked. | ||
599 | */ | ||
579 | err = ubifs_xattr_set(inode, name, xattr->value, | 600 | err = ubifs_xattr_set(inode, name, xattr->value, |
580 | xattr->value_len, 0); | 601 | xattr->value_len, 0, false); |
581 | kfree(name); | 602 | kfree(name); |
582 | if (err < 0) | 603 | if (err < 0) |
583 | break; | 604 | break; |
@@ -624,7 +645,7 @@ static int xattr_set(const struct xattr_handler *handler, | |||
624 | name = xattr_full_name(handler, name); | 645 | name = xattr_full_name(handler, name); |
625 | 646 | ||
626 | if (value) | 647 | if (value) |
627 | return ubifs_xattr_set(inode, name, value, size, flags); | 648 | return ubifs_xattr_set(inode, name, value, size, flags, true); |
628 | else | 649 | else |
629 | return ubifs_xattr_remove(inode, name); | 650 | return ubifs_xattr_remove(inode, name); |
630 | } | 651 | } |