static void fuse_destroy_inode(struct inode *inode) { struct fuse_inode *fi = get_fuse_inode(inode); if (fi->forget_req) fuse_request_free(fi->forget_req); kmem_cache_free(fuse_inode_cachep, inode); }
static void fuse_destroy_inode(struct inode *inode) { struct fuse_inode *fi = get_fuse_inode(inode); BUG_ON(!list_empty(&fi->write_files)); BUG_ON(!list_empty(&fi->queued_writes)); if (fi->forget_req) fuse_request_free(fi->forget_req); kmem_cache_free(fuse_inode_cachep, inode); }
void fuse_conn_put(struct fuse_conn *fc) { if (atomic_dec_and_test(&fc->count)) { if (fc->destroy_req) fuse_request_free(fc->destroy_req); mutex_destroy(&fc->inst_mutex); kfree(fc); } }
static void free_conn(struct fuse_conn *fc) { while (!list_empty(&fc->unused_list)) { struct fuse_req *req; req = list_entry(fc->unused_list.next, struct fuse_req, list); list_del(&req->list); fuse_request_free(req); } kfree(fc); }
void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) { if (atomic_dec_and_test(&req->count)) { if (req->waiting) atomic_dec(&fc->num_waiting); if (req->stolen_file) put_reserved_req(fc, req); else fuse_request_free(req); } }
void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) { if (atomic_dec_and_test(&req->count)) { if (unlikely(req->background)) { /* * We get here in the unlikely case that a background * request was allocated but not sent */ spin_lock(&fc->lock); if (!fc->blocked) wake_up(&fc->blocked_waitq); spin_unlock(&fc->lock); } if (req->waiting) atomic_dec(&fc->num_waiting); if (req->stolen_file) put_reserved_req(fc, req); else fuse_request_free(req); } }
static int fuse_fill_super(struct super_block *sb, void *data, int silent) { struct fuse_conn *fc; struct inode *root; struct fuse_mount_data d; struct file *file; struct dentry *root_dentry; struct fuse_req *init_req; int err; int is_bdev = sb->s_bdev != NULL; if (sb->s_flags & MS_MANDLOCK) return -EINVAL; if (!parse_fuse_opt((char *) data, &d, is_bdev)) return -EINVAL; if (is_bdev) { #ifdef CONFIG_BLOCK if (!sb_set_blocksize(sb, d.blksize)) return -EINVAL; #endif } else { sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize_bits = PAGE_CACHE_SHIFT; } sb->s_magic = FUSE_SUPER_MAGIC; sb->s_op = &fuse_super_operations; sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_export_op = &fuse_export_operations; file = fget(d.fd); if (!file) return -EINVAL; if (file->f_op != &fuse_dev_operations) return -EINVAL; fc = new_conn(sb); if (!fc) return -ENOMEM; fc->flags = d.flags; fc->user_id = d.user_id; fc->group_id = d.group_id; fc->max_read = max_t(unsigned, 4096, d.max_read); /* Used by get_root_inode() */ sb->s_fs_info = fc; err = -ENOMEM; root = get_root_inode(sb, d.rootmode); if (!root) goto err; root_dentry = d_alloc_root(root); if (!root_dentry) { iput(root); goto err; } init_req = fuse_request_alloc(); if (!init_req) goto err_put_root; if (is_bdev) { fc->destroy_req = fuse_request_alloc(); if (!fc->destroy_req) goto err_free_init_req; } mutex_lock(&fuse_mutex); err = -EINVAL; if (file->private_data) goto err_unlock; err = fuse_ctl_add_conn(fc); if (err) goto err_unlock; list_add_tail(&fc->entry, &fuse_conn_list); sb->s_root = root_dentry; fc->connected = 1; file->private_data = fuse_conn_get(fc); mutex_unlock(&fuse_mutex); /* * atomic_dec_and_test() in fput() provides the necessary * memory barrier for file->private_data to be visible on all * CPUs after this */ fput(file); fuse_send_init(fc, init_req); return 0; err_unlock: mutex_unlock(&fuse_mutex); err_free_init_req: fuse_request_free(init_req); err_put_root: dput(root_dentry); err: fput(file); fuse_conn_put(fc); return err; }
void fuse_file_free(struct fuse_file *ff) { fuse_request_free(ff->release_req); kfree(ff); }