Skip to content

Commit

Permalink
fix renaming over open unlinked file
Browse files Browse the repository at this point in the history
  • Loading branch information
trapexit committed May 16, 2019
1 parent 1ad7906 commit c21aa34
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 20 deletions.
44 changes: 24 additions & 20 deletions libfuse/lib/fuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1513,18 +1513,17 @@ int fuse_fs_fgetattr(struct fuse_fs *fs, const char *path, struct stat *buf,
}
}

int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath,
const char *newpath)
int
fuse_fs_rename(struct fuse_fs *fs,
const char *oldpath,
const char *newpath)
{
fuse_get_context()->private_data = fs->user_data;
if (fs->op.rename) {
if (fs->debug)
fprintf(stderr, "rename %s %s\n", oldpath, newpath);
fuse_get_context()->private_data = fs->user_data;

return fs->op.rename(oldpath, newpath);
} else {
return -ENOSYS;
}
if(fs->op.rename)
return fs->op.rename(oldpath, newpath);

return -ENOSYS;
}

int
Expand Down Expand Up @@ -2304,9 +2303,11 @@ int fuse_fs_fallocate(struct fuse_fs *fs, const char *path, int mode,

static
int
is_node_open(const struct node *node_)
node_open_and_visible(const struct node *node_)
{
return (node_ && (node_->open_count > 0));
return ((node_ != NULL) &&
(node_->open_count > 0) &&
(node_->is_hidden == 0));
}

static int mtime_eq(const struct stat *stbuf, const struct timespec *ts)
Expand Down Expand Up @@ -2901,8 +2902,7 @@ static void fuse_lib_unlink(fuse_req_t req, fuse_ino_t parent,
struct fuse_intr_data d;

fuse_prepare_interrupt(f, req, &d);

if(is_node_open(wnode))
if(node_open_and_visible(wnode))
{
err = fuse_fs_prepare_hide(f->fs, path, &wnode->hidden_fh, 0);
if(!err)
Expand Down Expand Up @@ -2975,17 +2975,21 @@ static void fuse_lib_rename(fuse_req_t req, fuse_ino_t olddir,

err = get_path2(f, olddir, oldname, newdir, newname,
&oldpath, &newpath, &wnode1, &wnode2);

if (!err) {
struct fuse_intr_data d;
err = 0;
fuse_prepare_interrupt(f, req, &d);
if (is_node_open(wnode2))
if(node_open_and_visible(wnode2))
err = fuse_fs_prepare_hide(f->fs, newpath, &wnode2->hidden_fh, 1);
if (!err) {
err = fuse_fs_rename(f->fs, oldpath, newpath);
if (!err)
err = rename_node(f, olddir, oldname, newdir, newname);
}

if (!err)
{
err = fuse_fs_rename(f->fs, oldpath, newpath);
if (!err)
err = rename_node(f, olddir, oldname, newdir, newname);
}

fuse_finish_interrupt(f, req, &d);
free_path2(f, olddir, newdir, wnode1, wnode2, oldpath, newpath);
}
Expand Down
14 changes: 14 additions & 0 deletions tests/TEST_unlink_rename
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env python3

import os
import sys
import tempfile

(srcfd,src) = tempfile.mkstemp(dir=sys.argv[1])
(tgtfd,tgt) = tempfile.mkstemp(dir=sys.argv[1])

os.unlink(tgt)
os.rename(src,tgt)

os.close(srcfd)
os.close(tgtfd)

0 comments on commit c21aa34

Please sign in to comment.