diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-04-23 19:49:16 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-04-23 19:49:16 -0400 |
| commit | 9ea33c44fb19e6cbacf65021628f8ce393ba9f34 (patch) | |
| tree | 233e372db305223b2b94cdbbe6757f392dca4423 | |
| parent | e0f4e0134a796f0e48403adf22db48a0dffdde1d (diff) | |
| parent | 32fe905c17f001c0eee13c59afddd0bf2eed509c (diff) | |
Merge tag 'upstream-4.11-rc7' of git://git.infradead.org/linux-ubifs
Pull UBI/UBIFS fixes from Richard Weinberger:
"This contains fixes for issues in both UBI and UBIFS:
- more O_TMPFILE fallout
- RENAME_WHITEOUT regression due to a mis-merge
- memory leak in ubifs_mknod()
- power-cut problem in UBI's update volume feature"
* tag 'upstream-4.11-rc7' of git://git.infradead.org/linux-ubifs:
ubifs: Fix O_TMPFILE corner case in ubifs_link()
ubifs: Fix RENAME_WHITEOUT support
ubifs: Fix debug messages for an invalid filename in ubifs_dump_inode
ubifs: Fix debug messages for an invalid filename in ubifs_dump_node
ubifs: Remove filename from debug messages in ubifs_readdir
ubifs: Fix memory leak in error path in ubifs_mknod
ubi/upd: Always flush after prepared for an update
| -rw-r--r-- | drivers/mtd/ubi/upd.c | 8 | ||||
| -rw-r--r-- | fs/ubifs/debug.c | 10 | ||||
| -rw-r--r-- | fs/ubifs/dir.c | 18 |
3 files changed, 23 insertions, 13 deletions
diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c index 0134ba32a057..39712560b4c1 100644 --- a/drivers/mtd/ubi/upd.c +++ b/drivers/mtd/ubi/upd.c | |||
| @@ -148,11 +148,11 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, | |||
| 148 | return err; | 148 | return err; |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | if (bytes == 0) { | 151 | err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL); |
| 152 | err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL); | 152 | if (err) |
| 153 | if (err) | 153 | return err; |
| 154 | return err; | ||
| 155 | 154 | ||
| 155 | if (bytes == 0) { | ||
| 156 | err = clear_update_marker(ubi, vol, 0); | 156 | err = clear_update_marker(ubi, vol, 0); |
| 157 | if (err) | 157 | if (err) |
| 158 | return err; | 158 | return err; |
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 1e712a364680..718b749fa11a 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/math64.h> | 32 | #include <linux/math64.h> |
| 33 | #include <linux/uaccess.h> | 33 | #include <linux/uaccess.h> |
| 34 | #include <linux/random.h> | 34 | #include <linux/random.h> |
| 35 | #include <linux/ctype.h> | ||
| 35 | #include "ubifs.h" | 36 | #include "ubifs.h" |
| 36 | 37 | ||
| 37 | static DEFINE_SPINLOCK(dbg_lock); | 38 | static DEFINE_SPINLOCK(dbg_lock); |
| @@ -286,8 +287,10 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode) | |||
| 286 | break; | 287 | break; |
| 287 | } | 288 | } |
| 288 | 289 | ||
| 289 | pr_err("\t%d: %s (%s)\n", | 290 | pr_err("\t%d: inode %llu, type %s, len %d\n", |
| 290 | count++, dent->name, get_dent_type(dent->type)); | 291 | count++, (unsigned long long) le64_to_cpu(dent->inum), |
| 292 | get_dent_type(dent->type), | ||
| 293 | le16_to_cpu(dent->nlen)); | ||
| 291 | 294 | ||
| 292 | fname_name(&nm) = dent->name; | 295 | fname_name(&nm) = dent->name; |
| 293 | fname_len(&nm) = le16_to_cpu(dent->nlen); | 296 | fname_len(&nm) = le16_to_cpu(dent->nlen); |
| @@ -464,7 +467,8 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node) | |||
| 464 | pr_err("(bad name length, not printing, bad or corrupted node)"); | 467 | pr_err("(bad name length, not printing, bad or corrupted node)"); |
| 465 | else { | 468 | else { |
| 466 | for (i = 0; i < nlen && dent->name[i]; i++) | 469 | for (i = 0; i < nlen && dent->name[i]; i++) |
| 467 | pr_cont("%c", dent->name[i]); | 470 | pr_cont("%c", isprint(dent->name[i]) ? |
| 471 | dent->name[i] : '?'); | ||
| 468 | } | 472 | } |
| 469 | pr_cont("\n"); | 473 | pr_cont("\n"); |
| 470 | 474 | ||
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 30825d882aa9..b777bddaa1dd 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
| @@ -606,8 +606,8 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx) | |||
| 606 | } | 606 | } |
| 607 | 607 | ||
| 608 | while (1) { | 608 | while (1) { |
| 609 | dbg_gen("feed '%s', ino %llu, new f_pos %#x", | 609 | dbg_gen("ino %llu, new f_pos %#x", |
| 610 | dent->name, (unsigned long long)le64_to_cpu(dent->inum), | 610 | (unsigned long long)le64_to_cpu(dent->inum), |
| 611 | key_hash_flash(c, &dent->key)); | 611 | key_hash_flash(c, &dent->key)); |
| 612 | ubifs_assert(le64_to_cpu(dent->ch.sqnum) > | 612 | ubifs_assert(le64_to_cpu(dent->ch.sqnum) > |
| 613 | ubifs_inode(dir)->creat_sqnum); | 613 | ubifs_inode(dir)->creat_sqnum); |
| @@ -748,6 +748,11 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 748 | goto out_fname; | 748 | goto out_fname; |
| 749 | 749 | ||
| 750 | lock_2_inodes(dir, inode); | 750 | lock_2_inodes(dir, inode); |
| 751 | |||
| 752 | /* Handle O_TMPFILE corner case, it is allowed to link a O_TMPFILE. */ | ||
| 753 | if (inode->i_nlink == 0) | ||
| 754 | ubifs_delete_orphan(c, inode->i_ino); | ||
| 755 | |||
| 751 | inc_nlink(inode); | 756 | inc_nlink(inode); |
| 752 | ihold(inode); | 757 | ihold(inode); |
| 753 | inode->i_ctime = ubifs_current_time(inode); | 758 | inode->i_ctime = ubifs_current_time(inode); |
| @@ -768,6 +773,8 @@ out_cancel: | |||
| 768 | dir->i_size -= sz_change; | 773 | dir->i_size -= sz_change; |
| 769 | dir_ui->ui_size = dir->i_size; | 774 | dir_ui->ui_size = dir->i_size; |
| 770 | drop_nlink(inode); | 775 | drop_nlink(inode); |
| 776 | if (inode->i_nlink == 0) | ||
| 777 | ubifs_add_orphan(c, inode->i_ino); | ||
| 771 | unlock_2_inodes(dir, inode); | 778 | unlock_2_inodes(dir, inode); |
| 772 | ubifs_release_budget(c, &req); | 779 | ubifs_release_budget(c, &req); |
| 773 | iput(inode); | 780 | iput(inode); |
| @@ -1068,8 +1075,10 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry, | |||
| 1068 | } | 1075 | } |
| 1069 | 1076 | ||
| 1070 | err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm); | 1077 | err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm); |
| 1071 | if (err) | 1078 | if (err) { |
| 1079 | kfree(dev); | ||
| 1072 | goto out_budg; | 1080 | goto out_budg; |
| 1081 | } | ||
| 1073 | 1082 | ||
| 1074 | sz_change = CALC_DENT_SIZE(fname_len(&nm)); | 1083 | sz_change = CALC_DENT_SIZE(fname_len(&nm)); |
| 1075 | 1084 | ||
| @@ -1316,9 +1325,6 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 1316 | unsigned int uninitialized_var(saved_nlink); | 1325 | unsigned int uninitialized_var(saved_nlink); |
| 1317 | struct fscrypt_name old_nm, new_nm; | 1326 | struct fscrypt_name old_nm, new_nm; |
| 1318 | 1327 | ||
| 1319 | if (flags & ~RENAME_NOREPLACE) | ||
| 1320 | return -EINVAL; | ||
| 1321 | |||
| 1322 | /* | 1328 | /* |
| 1323 | * Budget request settings: deletion direntry, new direntry, removing | 1329 | * Budget request settings: deletion direntry, new direntry, removing |
| 1324 | * the old inode, and changing old and new parent directory inodes. | 1330 | * the old inode, and changing old and new parent directory inodes. |
