Browse Source

Merge pull request #628 from trapexit/hide-cleanup

fix for unlink race condition
pull/629/head 2.27.1
trapexit 5 years ago
committed by GitHub
parent
commit
9e3331dab4
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      libfuse/include/fuse.h
  2. 41
      libfuse/lib/fuse.c
  3. 3
      src/fuse_prepare_hide.cpp
  4. 3
      src/fuse_prepare_hide.hpp

5
libfuse/include/fuse.h

@ -129,7 +129,7 @@ struct fuse_operations {
* while open. Helps manage the fact the kernel usually does
* not send fh with getattr requests.
*/
int (*prepare_hide)(const char *name_, uint64_t *fh_, int type_);
int (*prepare_hide)(const char *name_, uint64_t *fh_);
int (*free_hide)(const uint64_t fh_);
/** Remove a file */
@ -921,6 +921,9 @@ int fuse_fs_fallocate(struct fuse_fs *fs, const char *path, int mode,
void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn);
void fuse_fs_destroy(struct fuse_fs *fs);
int fuse_fs_prepare_hide(struct fuse_fs *fs, const char *path, uint64_t *fh);
int fuse_fs_free_hide(struct fuse_fs *fs, uint64_t fh);
int fuse_notify_poll(struct fuse_pollhandle *ph);
/**

41
libfuse/lib/fuse.c

@ -438,11 +438,18 @@ static void set_forget_time(struct fuse *f, struct node *node)
curr_time(&lnode->forget_time);
}
static void free_node(struct fuse *f, struct node *node)
static
void
free_node(struct fuse *f_,
struct node *node_)
{
if (node->name != node->inline_name)
free(node->name);
free_node_mem(f, node);
if(node_->name != node_->inline_name)
free(node_->name);
if(node_->is_hidden)
fuse_fs_free_hide(f_->fs,node_->hidden_fh);
free_node_mem(f_,node_);
}
static void node_table_reduce(struct node_table *t)
@ -1529,13 +1536,12 @@ fuse_fs_rename(struct fuse_fs *fs,
int
fuse_fs_prepare_hide(struct fuse_fs *fs_,
const char *path_,
uint64_t *fh_,
int type_)
uint64_t *fh_)
{
fuse_get_context()->private_data = fs_->user_data;
if(fs_->op.prepare_hide)
return fs_->op.prepare_hide(path_,fh_,type_);
return fs_->op.prepare_hide(path_,fh_);
return -ENOSYS;
}
@ -2303,11 +2309,10 @@ int fuse_fs_fallocate(struct fuse_fs *fs, const char *path, int mode,
static
int
node_open_and_visible(const struct node *node_)
node_open(const struct node *node_)
{
return ((node_ != NULL) &&
(node_->open_count > 0) &&
(node_->is_hidden == 0));
(node_->open_count > 0));
}
static int mtime_eq(const struct stat *stbuf, const struct timespec *ts)
@ -2906,15 +2911,18 @@ fuse_lib_unlink(fuse_req_t req,
if(!err)
{
fuse_prepare_interrupt(f,req,&d);
if(node_open_and_visible(wnode))
pthread_mutex_lock(&f->lock);
if(node_open(wnode))
{
err = fuse_fs_prepare_hide(f->fs,path,&wnode->hidden_fh,0);
err = fuse_fs_prepare_hide(f->fs,path,&wnode->hidden_fh);
if(!err)
wnode->is_hidden = 1;
}
pthread_mutex_unlock(&f->lock);
err = fuse_fs_unlink(f->fs,path);
if(!err && !wnode->is_hidden)
if(!err)
remove_node(f,parent,name);
fuse_finish_interrupt(f,req,&d);
@ -2990,12 +2998,15 @@ fuse_lib_rename(fuse_req_t req,
if(!err)
{
fuse_prepare_interrupt(f,req,&d);
if(node_open_and_visible(wnode2))
pthread_mutex_lock(&f->lock);
if(node_open(wnode2))
{
err = fuse_fs_prepare_hide(f->fs,newpath,&wnode2->hidden_fh,1);
err = fuse_fs_prepare_hide(f->fs,newpath,&wnode2->hidden_fh);
if(!err)
wnode2->is_hidden = 1;
}
pthread_mutex_unlock(&f->lock);
err = fuse_fs_rename(f->fs,oldpath,newpath);
if(!err)

3
src/fuse_prepare_hide.cpp

@ -26,8 +26,7 @@ namespace FUSE
{
int
prepare_hide(const char *fusepath_,
uint64_t *fh_,
int type_)
uint64_t *fh_)
{
int rv;
struct fuse_file_info ffi = {0};

3
src/fuse_prepare_hide.hpp

@ -24,6 +24,5 @@ namespace FUSE
{
int
prepare_hide(const char *name_,
uint64_t *fh_,
int type_);
uint64_t *fh_);
}
Loading…
Cancel
Save