@@ -2001,6 +2001,30 @@ static int lo_do_open(struct lo_data *lo, struct lo_inode *inode,
return 0;
}
+static int do_lo_create(fuse_req_t req, struct lo_inode *parent_inode,
+ const char *name, mode_t mode,
+ struct fuse_file_info *fi, int* open_fd)
+{
+ int err = 0, fd;
+ struct lo_cred old = {};
+ struct lo_data *lo = lo_data(req);
+
+ err = lo_change_cred(req, &old, lo->change_umask);
+ if (err) {
+ return err;
+ }
+
+ /* Try to create a new file but don't open existing files */
+ fd = openat(parent_inode->fd, name, fi->flags | O_CREAT | O_EXCL, mode);
+ if (fd == -1) {
+ err = errno;
+ } else {
+ *open_fd = fd;
+ }
+ lo_restore_cred(&old, lo->change_umask);
+ return err;
+}
+
static void lo_create(fuse_req_t req, fuse_ino_t parent, const char *name,
mode_t mode, struct fuse_file_info *fi)
{
@@ -2010,7 +2034,6 @@ static void lo_create(fuse_req_t req, fuse_ino_t parent, const char *name,
struct lo_inode *inode = NULL;
struct fuse_entry_param e;
int err;
- struct lo_cred old = {};
fuse_log(FUSE_LOG_DEBUG, "lo_create(parent=%" PRIu64 ", name=%s)"
" kill_priv=%d\n", parent, name, fi->kill_priv);
@@ -2026,18 +2049,9 @@ static void lo_create(fuse_req_t req, fuse_ino_t parent, const char *name,
return;
}
- err = lo_change_cred(req, &old, lo->change_umask);
- if (err) {
- goto out;
- }
-
update_open_flags(lo->writeback, lo->allow_direct_io, fi);
- /* Try to create a new file but don't open existing files */
- fd = openat(parent_inode->fd, name, fi->flags | O_CREAT | O_EXCL, mode);
- err = fd == -1 ? errno : 0;
-
- lo_restore_cred(&old, lo->change_umask);
+ err = do_lo_create(req, parent_inode, name, mode, fi, &fd);
/* Ignore the error if file exists and O_EXCL was not given */
if (err && (err != EEXIST || (fi->flags & O_EXCL))) {