Commit 9ea33c44 authored by Linus Torvalds's avatar Linus Torvalds

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
parents e0f4e013 32fe905c
...@@ -148,11 +148,11 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, ...@@ -148,11 +148,11 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
return err; return err;
} }
if (bytes == 0) { err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL); if (err)
if (err) return err;
return err;
if (bytes == 0) {
err = clear_update_marker(ubi, vol, 0); err = clear_update_marker(ubi, vol, 0);
if (err) if (err)
return err; return err;
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/math64.h> #include <linux/math64.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/ctype.h>
#include "ubifs.h" #include "ubifs.h"
static DEFINE_SPINLOCK(dbg_lock); static DEFINE_SPINLOCK(dbg_lock);
...@@ -286,8 +287,10 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode) ...@@ -286,8 +287,10 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode)
break; break;
} }
pr_err("\t%d: %s (%s)\n", pr_err("\t%d: inode %llu, type %s, len %d\n",
count++, dent->name, get_dent_type(dent->type)); count++, (unsigned long long) le64_to_cpu(dent->inum),
get_dent_type(dent->type),
le16_to_cpu(dent->nlen));
fname_name(&nm) = dent->name; fname_name(&nm) = dent->name;
fname_len(&nm) = le16_to_cpu(dent->nlen); 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,7 +467,8 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node)
pr_err("(bad name length, not printing, bad or corrupted node)"); pr_err("(bad name length, not printing, bad or corrupted node)");
else { else {
for (i = 0; i < nlen && dent->name[i]; i++) for (i = 0; i < nlen && dent->name[i]; i++)
pr_cont("%c", dent->name[i]); pr_cont("%c", isprint(dent->name[i]) ?
dent->name[i] : '?');
} }
pr_cont("\n"); pr_cont("\n");
......
...@@ -606,8 +606,8 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx) ...@@ -606,8 +606,8 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
} }
while (1) { while (1) {
dbg_gen("feed '%s', ino %llu, new f_pos %#x", dbg_gen("ino %llu, new f_pos %#x",
dent->name, (unsigned long long)le64_to_cpu(dent->inum), (unsigned long long)le64_to_cpu(dent->inum),
key_hash_flash(c, &dent->key)); key_hash_flash(c, &dent->key));
ubifs_assert(le64_to_cpu(dent->ch.sqnum) > ubifs_assert(le64_to_cpu(dent->ch.sqnum) >
ubifs_inode(dir)->creat_sqnum); ubifs_inode(dir)->creat_sqnum);
...@@ -748,6 +748,11 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir, ...@@ -748,6 +748,11 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
goto out_fname; goto out_fname;
lock_2_inodes(dir, inode); lock_2_inodes(dir, inode);
/* Handle O_TMPFILE corner case, it is allowed to link a O_TMPFILE. */
if (inode->i_nlink == 0)
ubifs_delete_orphan(c, inode->i_ino);
inc_nlink(inode); inc_nlink(inode);
ihold(inode); ihold(inode);
inode->i_ctime = ubifs_current_time(inode); inode->i_ctime = ubifs_current_time(inode);
...@@ -768,6 +773,8 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir, ...@@ -768,6 +773,8 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
dir->i_size -= sz_change; dir->i_size -= sz_change;
dir_ui->ui_size = dir->i_size; dir_ui->ui_size = dir->i_size;
drop_nlink(inode); drop_nlink(inode);
if (inode->i_nlink == 0)
ubifs_add_orphan(c, inode->i_ino);
unlock_2_inodes(dir, inode); unlock_2_inodes(dir, inode);
ubifs_release_budget(c, &req); ubifs_release_budget(c, &req);
iput(inode); iput(inode);
...@@ -1068,8 +1075,10 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry, ...@@ -1068,8 +1075,10 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry,
} }
err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm); err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
if (err) if (err) {
kfree(dev);
goto out_budg; goto out_budg;
}
sz_change = CALC_DENT_SIZE(fname_len(&nm)); sz_change = CALC_DENT_SIZE(fname_len(&nm));
...@@ -1316,9 +1325,6 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1316,9 +1325,6 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
unsigned int uninitialized_var(saved_nlink); unsigned int uninitialized_var(saved_nlink);
struct fscrypt_name old_nm, new_nm; struct fscrypt_name old_nm, new_nm;
if (flags & ~RENAME_NOREPLACE)
return -EINVAL;
/* /*
* Budget request settings: deletion direntry, new direntry, removing * Budget request settings: deletion direntry, new direntry, removing
* the old inode, and changing old and new parent directory inodes. * the old inode, and changing old and new parent directory inodes.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment