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. |