예제 #1
0
struct MountsPublicInterface* mm_mount_byhandle( struct MountsManager *mounts_manager,
                                                 int handle ){
    const struct HandleItem* entry = get_handle_allocator()->entry(handle);
    /*if handle exist and related to opened file*/
    if ( entry && NULL != 
         get_open_files_pool()->entry(entry->open_file_description_id) ) 
	return entry->mount_fs;
    else return NULL;
}
예제 #2
0
int mm_fusemount_add( struct MountsManager *mounts_manager,
                      const char* path, 
                      struct fuse_operations* fuse_mount,
                      char expect_absolute_path,
                      char proxy_mode){
    struct MountsPublicInterface* fs 
	= CONSTRUCT_L(FUSE_OPERATIONS_MOUNT)( get_handle_allocator(),
					      get_open_files_pool(),
					      fuse_mount,
                                              proxy_mode);
    return mm_mount_add( mounts_manager, path, fs, expect_absolute_path );
}
예제 #3
0
struct MountsManager* get_mounts_manager(){
    s_mounts_manager.handle_allocator = get_handle_allocator();
    s_mounts_manager.open_files_pool = get_open_files_pool();
    return &s_mounts_manager;
}
예제 #4
0
static int fuse_operations_mount_open(struct MountsPublicInterface* this_, const char* path, int oflag, uint32_t mode) {
    int ret=-1;
    int fd=-1;
    struct FuseOperationsMount* fs = (struct FuseOperationsMount*)this_;
    struct stat st;
    struct stat st_parent;
    int file_exist;

    CHECK_FUNC_ENSURE_EXIST(fs, open);

    file_exist=fs->fuse_operations->getattr(path, &st);

    /*file exist, do checks of O_CREAT, O_EXCL flags*/
    if ( !file_exist && CHECK_FLAG(oflag, O_CREAT) && CHECK_FLAG(oflag, O_EXCL) ) {
        SET_ERRNO(EEXIST);
        return -1;
    }
    /*truncate existing writable file*/
    if ( !file_exist && CHECK_FLAG(oflag, O_TRUNC) &&
            (CHECK_FLAG(oflag, O_WRONLY) || CHECK_FLAG(oflag, O_RDWR)) ) {
        CHECK_FUNC_ENSURE_EXIST(fs, truncate);
        if ( (ret=fs->fuse_operations->truncate(path, 0)) <0 ) {
            /*truncate error*/
            SET_ERRNO(-ret);
            return -1;
        }
    }

    /*create fuse object, it must be attached into ofd entry or be
      destroyed if zrt would not be able to return file handle*/
    struct fuse_file_info *finfo = calloc(1, sizeof(struct fuse_file_info));
    /*reset flags that should not be passed to fuse's open*/
    finfo->flags = oflag & ~(O_CREAT|O_TRUNC|O_EXCL);

    /*is file exist?*/
    if (!file_exist) {
        if ( (ret=fs->fuse_operations->open(path, finfo)) <0 ) {
            SET_ERRNO(-ret);
        }
    }
    else {
        /*file does not exist, create & open it*/
        if ( CHECK_FLAG(oflag, O_CREAT) ) {
            CHECK_FUNC_ENSURE_EXIST(fs, create);
            if ( (ret=fs->fuse_operations->create(path, mode, finfo)) <0 ) {
                SET_ERRNO(-ret);
            }
        }
    }

    /*if path open/create success*/
    if ( ! ret ) {
        int open_file_description_id;
        if ( fs->proxy_mode == EFuseProxyModeDisabled ) {
            /*in case if fs works in generic mode it use own handles
              stored in finfo->fh, so we need to issue a global fd
              visible across system*/
            open_file_description_id = get_open_files_pool()->getnew_ofd(oflag);
            fd = fs->handle_allocator->allocate_handle(this_,
                    st.st_ino, st_parent.st_ino,
                    open_file_description_id);
            if ( fd < 0 ) {
                /*it's hipotetical but possible case if amount of open files
                  are exceeded an maximum value.*/
                fs->open_files_pool->release_ofd(open_file_description_id);
                SET_ERRNO(ENFILE);
            }
        }
        else if ( fs->proxy_mode == EFuseProxyModeEnabled) {
            /*proxy mode is enabled, so open already returned actual
              fd, therefore do not issue a new one and use returned*/
            fd = finfo->fh;
            const struct HandleItem *hentry = fs->handle_allocator->entry(finfo->fh);
            if (hentry!=NULL)
                open_file_description_id = hentry->open_file_description_id;
            else {
                ZRT_LOG(L_ERROR,
                        "can't open '%s' due to handle=%lld returned from fuse fs has no HandleEntry",
                        path, finfo->fh );
                SET_ERRNO(EINVAL);
            }
        }
        else {
            assert(0);
        }

        /*successfully opened, save fuse data*/
        struct FuseFileOptionalData *fdata = malloc( sizeof(struct FuseFileOptionalData) );
        fs->open_files_pool->set_optional_data( open_file_description_id, (intptr_t)fdata );
        fdata->path = strdup(path);
        fdata->finfo = finfo;

        return fd;
    }
    else {
        free(finfo);
        return -1;
    }
}