diff options
Diffstat (limited to 'target/linux/generic/pending-4.4/052-01-ubifs-Implement-O_TMPFILE.patch')
-rw-r--r-- | target/linux/generic/pending-4.4/052-01-ubifs-Implement-O_TMPFILE.patch | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/target/linux/generic/pending-4.4/052-01-ubifs-Implement-O_TMPFILE.patch b/target/linux/generic/pending-4.4/052-01-ubifs-Implement-O_TMPFILE.patch new file mode 100644 index 0000000000..1c55a89acf --- /dev/null +++ b/target/linux/generic/pending-4.4/052-01-ubifs-Implement-O_TMPFILE.patch @@ -0,0 +1,99 @@ +From: Richard Weinberger <richard@nod.at> +Date: Tue, 13 Sep 2016 16:18:55 +0200 +Subject: [PATCH] ubifs: Implement O_TMPFILE + +This patchs adds O_TMPFILE support to UBIFS. +A temp file is a reference to an unlinked inode, a user +holding the reference can use it. As soon it is being closed +all data vanishes. + +Signed-off-by: Richard Weinberger <richard@nod.at> +--- + +--- a/fs/ubifs/dir.c ++++ b/fs/ubifs/dir.c +@@ -301,6 +301,76 @@ out_budg: + return err; + } + ++static int ubifs_tmpfile(struct inode *dir, struct dentry *dentry, ++ umode_t mode) ++{ ++ struct inode *inode; ++ struct ubifs_info *c = dir->i_sb->s_fs_info; ++ struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1}; ++ struct ubifs_budget_req ino_req = { .dirtied_ino = 1 }; ++ struct ubifs_inode *ui, *dir_ui = ubifs_inode(dir); ++ int err, instantiated = 0; ++ ++ /* ++ * Budget request settings: new dirty inode, new direntry, ++ * budget for dirtied inode will be released via writeback. ++ */ ++ ++ dbg_gen("dent '%pd', mode %#hx in dir ino %lu", ++ dentry, mode, dir->i_ino); ++ ++ err = ubifs_budget_space(c, &req); ++ if (err) ++ return err; ++ ++ err = ubifs_budget_space(c, &ino_req); ++ if (err) { ++ ubifs_release_budget(c, &req); ++ return err; ++ } ++ ++ inode = ubifs_new_inode(c, dir, mode); ++ if (IS_ERR(inode)) { ++ err = PTR_ERR(inode); ++ goto out_budg; ++ } ++ ui = ubifs_inode(inode); ++ ++ err = ubifs_init_security(dir, inode, &dentry->d_name); ++ if (err) ++ goto out_inode; ++ ++ mutex_lock(&ui->ui_mutex); ++ insert_inode_hash(inode); ++ d_tmpfile(dentry, inode); ++ ubifs_assert(ui->dirty); ++ instantiated = 1; ++ mutex_unlock(&ui->ui_mutex); ++ ++ mutex_lock(&dir_ui->ui_mutex); ++ err = ubifs_jnl_update(c, dir, &dentry->d_name, inode, 1, 0); ++ if (err) ++ goto out_cancel; ++ mutex_unlock(&dir_ui->ui_mutex); ++ ++ ubifs_release_budget(c, &req); ++ ++ return 0; ++ ++out_cancel: ++ mutex_unlock(&dir_ui->ui_mutex); ++out_inode: ++ make_bad_inode(inode); ++ if (!instantiated) ++ iput(inode); ++out_budg: ++ ubifs_release_budget(c, &req); ++ if (!instantiated) ++ ubifs_release_budget(c, &ino_req); ++ ubifs_err(c, "cannot create temporary file, error %d", err); ++ return err; ++} ++ + /** + * vfs_dent_type - get VFS directory entry type. + * @type: UBIFS directory entry type +@@ -1195,6 +1265,7 @@ const struct inode_operations ubifs_dir_ + #ifdef CONFIG_UBIFS_ATIME_SUPPORT + .update_time = ubifs_update_time, + #endif ++ .tmpfile = ubifs_tmpfile, + }; + + const struct file_operations ubifs_dir_operations = { |