Example #1
0
static void initial_cache_load(struct nfs_client *client)
{
    err_t r;
	cache_loading_phase = true;
	cache_lookups_started = 0;
	cache_loaded_counter = 0;
	cache_loading_probs = 0;

	//my_nfs_client
    r = nfs_readdir(client, nfs_root_fh, NFS_READDIR_COOKIE,
                         NFS_READDIR_COOKIEVERF, readdir_callback, NULL);
    assert(r == ERR_OK);
}
Example #2
0
/* NFS Callback for NFS_getdirent */
static
void
getdirent_cb(uintptr_t token, int status, int num_entries, struct nfs_filename *filenames,
		int next_cookie) {
	dprintf(1, "*** nfsfs_dirent_cb: %d, %d, %d, %d\n", token, status, num_entries, next_cookie);

	NFS_DirRequest *rq = (NFS_DirRequest *) get_request(token);
	if (rq == NULL) {
		dprintf(0, "!!! nfsfs: Corrupt dirent callback, no matching token: %d\n", token);
		return;
	}

	Process *p = process_lookup(rq->p.pid);

	if (status != NFS_OK) {
		syscall_reply(process_get_tid(p), status_nfs2vfs(status));
		remove_request((NFS_BaseRequest *) rq);
		return;
	}


	// got it
	if (rq->cpos + num_entries >= rq->pos + 1) {
		dprintf(2, "found file, getting now\n");
		int status = SOS_VFS_ERROR;
		struct nfs_filename *nfile = &filenames[rq->pos - rq->cpos];
		if (nfile->size + 1 <= rq->nbyte) {
			memcpy(rq->buf, nfile->file, nfile->size);
			rq->buf[nfile->size] = '\0';
			status = nfile->size;
		} else {
			dprintf(0, "!!! nfs_getdirent_cb: Filename too big for given buffer! (%d) (%d)\n",
					nfile->size, rq->nbyte);
			status = SOS_VFS_NOMEM;
		}
		syscall_reply(process_get_tid(p), status);
		remove_request((NFS_BaseRequest *) rq);
	}
	// need later directory entry
	else if (next_cookie > 0) {
		dprintf(2, "Need more dir entries to get file\n");
		rq->cpos += num_entries;
		nfs_readdir(&nfs_mnt, next_cookie, IO_MAX_BUFFER, getdirent_cb, rq->p.token);
	}
	// error case, just return SOS_VFS_OK to say nothing read, its not an error just eof
	else {
		dprintf(2, "nfsfs_getdirent: didnt find file (%d)\n", rq->pos);
		syscall_reply(process_get_tid(p), SOS_VFS_EOF);
		remove_request((NFS_BaseRequest *) rq);
	}
}
Example #3
0
File: nfs.c Project: BossKing/vlc
static int
DirRead(access_t *p_access, input_item_node_t *p_node)
{
    access_sys_t *p_sys = p_access->p_sys;
    struct nfsdirent *p_nfsdirent;
    int i_ret = VLC_SUCCESS;
    assert(p_sys->p_nfsdir);

    struct access_fsdir fsdir;
    access_fsdir_init(&fsdir, p_access, p_node);

    while (i_ret == VLC_SUCCESS
        && (p_nfsdirent = nfs_readdir(p_sys->p_nfs, p_sys->p_nfsdir)) != NULL)
    {
        char *psz_name_encoded = vlc_uri_encode(p_nfsdirent->name);
        if (psz_name_encoded == NULL)
        {
            i_ret = VLC_ENOMEM;
            break;
        }
        char *psz_url = NfsGetUrl(&p_sys->encoded_url, psz_name_encoded);
        free(psz_name_encoded);
        if (psz_url == NULL)
        {
            i_ret = VLC_ENOMEM;
            break;
        }

        int i_type;
        switch (p_nfsdirent->type)
        {
        case NF3REG:
            i_type = ITEM_TYPE_FILE;
            break;
        case NF3DIR:
            i_type = ITEM_TYPE_DIRECTORY;
            break;
        default:
            i_type = ITEM_TYPE_UNKNOWN;
        }
        i_ret = access_fsdir_additem(&fsdir, psz_url, p_nfsdirent->name,
                                     i_type, ITEM_NET);
        free(psz_url);
    }

    access_fsdir_finish(&fsdir, i_ret == VLC_SUCCESS);

    return i_ret;
}
Example #4
0
static int fuse_nfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
			 off_t offset, struct fuse_file_info *fi)
{
	struct nfsdir *nfsdir;
	struct nfsdirent *nfsdirent;

	int ret = 0;

	ret = nfs_opendir(nfs, path, &nfsdir);
	if (ret < 0) {
		return ret;
	}
	while ((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) {
		filler(buf, nfsdirent->name, NULL, 0);
	}

	return ret;
}
Example #5
0
static void readdir_callback(void *arg, struct nfs_client *client,
                             READDIR3res *result)
{
    READDIR3resok *resok = &result->READDIR3res_u.resok;
    struct http_cache_entry *ce;
    entry3 *last = NULL;
    err_t r;

    DEBUGPRINT ("readdir_callback came in\n");
    assert(result != NULL && result->status == NFS3_OK);

    // FIXME: start here the measurement of file loading time

    last_ts = rdtsc();
//    lwip_benchmark_control(1, BMS_START_REQUEST, 0, 0);
    // initiate a lookup for every entry
    for (entry3 *e = resok->reply.entries; e != NULL; e = e->nextentry) {
        ++cache_lookups_started;
        printf("Loading the file %s\n", e->name);
        ce = find_cacheline(e->name);
        ce->loading = 1;
        async_load_cache_entry(ce);
        e->name = NULL; // prevent freeing by XDR
        last = e;
    }

    /* more in the directory: repeat call */
    if (!resok->reply.eof) {
        assert(last != NULL);
        r = nfs_readdir(client, nfs_root_fh, last->cookie,
                        resok->cookieverf, readdir_callback, NULL);
        assert(r == ERR_OK);
    } else {
        readdir_complete = true;
        handle_cache_load_done();
    }

    // free arguments
    xdr_READDIR3res(&xdr_free, result);
}
static void workspace_nfs_readdirplus_simple(fuse_req_t req, size_t size, off_t offset, struct workspace_dh_struct *dh)
{
    struct resource_struct *resource=dh->object->resource;
    struct net_nfs_export_struct *nfs_export=(struct net_nfs_export_struct *) resource->data;
    struct nfs_context *nfs_ctx=(struct nfs_context *) nfs_export->data;
    unsigned int error=0;
    char *buff=NULL;
    size_t pos=0;
    size_t dirent_size;
    struct fuse_entry_param e;
    char *name=NULL;
    struct directory_struct *directory=dh->directory;
    struct nfsdir *dir=(struct nfsdir *) dh->handle.data;
    struct entry_struct *entry, *result;
    struct inode_struct *inode;
    struct name_struct xname={NULL, 0, 0};

    memset(&e, 0, sizeof(struct fuse_entry_param));

    e.generation = 1;
    e.attr_timeout = fs_options.attr_timeout;
    e.entry_timeout = fs_options.entry_timeout;

    e.attr.st_blksize=_DEFAULT_BLOCKSIZE;

    buff=malloc(size);

    if (! buff) {

	error=ENOMEM;
	goto error;

    }

    if (lock_directory(directory, _DIRECTORY_LOCK_EXCL)==-1) {

	free(buff);
	buff=NULL;
	error=EAGAIN;
	goto error;

    }

    while (pos<size) {

    	if (offset==0) {

	    inode=dh->parent->inode;

    	    /* the . entry */

	    e.ino = inode->ino;

	    e.attr.st_ino = e.ino;
	    e.attr.st_mode = inode->mode;
	    e.attr.st_nlink = inode->nlink;
	    e.attr.st_uid = inode->uid;
	    e.attr.st_gid = inode->gid;
	    e.attr.st_rdev = inode->rdev;
	    e.attr.st_size = inode->size;
	    e.attr.st_atim.tv_sec = 0;
	    e.attr.st_atim.tv_nsec = 0;
	    e.attr.st_mtim.tv_sec = inode->mtim.tv_sec;
	    e.attr.st_mtim.tv_nsec = inode->mtim.tv_nsec;
	    e.attr.st_ctim.tv_sec = inode->ctim.tv_sec;
	    e.attr.st_ctim.tv_nsec = inode->ctim.tv_nsec;

	    name = (char *) dotname;

	    inode->nlookup++;

    	} else if (offset==1) {

    	    /* the .. entry */

	    if ( ! dh->parent->parent ) {

		inode=dh->parent->inode;

	    } else {

		inode=dh->parent->parent->inode;

	    }

	    e.ino = inode->ino;

	    e.attr.st_ino = e.ino;
	    e.attr.st_mode = inode->mode;
	    e.attr.st_nlink = inode->nlink;
	    e.attr.st_uid = inode->uid;
	    e.attr.st_gid = inode->gid;
	    e.attr.st_rdev = inode->rdev;
	    e.attr.st_size = inode->size;
	    e.attr.st_atim.tv_sec = 0;
	    e.attr.st_atim.tv_nsec = 0;
	    e.attr.st_mtim.tv_sec = inode->mtim.tv_sec;
	    e.attr.st_mtim.tv_nsec = inode->mtim.tv_nsec;
	    e.attr.st_ctim.tv_sec = inode->ctim.tv_sec;
	    e.attr.st_ctim.tv_nsec = inode->ctim.tv_nsec;

	    name = (char *) dotdotname;

	    inode->nlookup++;

    	} else {

	    if (! dh->entry) {
		struct nfsdirent *de;

		readdir:

	        pthread_mutex_lock(&nfs_export->mutex);

		de=nfs_readdir(nfs_ctx, dir);

	        pthread_mutex_unlock(&nfs_export->mutex);

		if (de) {

		    if (strcmp(de->name, ".")==0 || strcmp(de->name, "..")==0) continue;

		    xname.name=de->name;
		    xname.len=strlen(xname.name);
		    calculate_nameindex(&xname);

		} else {

		    dh->mode |= _WORKSPACE_READDIR_MODE_FINISH;
		    break;

		}

		error=0;

		entry=create_entry(dh->parent, &xname);
		inode=create_inode();

		if (entry && inode) {

		    result=insert_entry_batch(directory, entry, &error, 0);

		    if (result==entry) {
			struct workspace_object_struct *export_object=NULL;

			inode->mode = translate_libnfs_type(de->type);
			inode->mode |= de->mode;

			add_inode_hashtable(inode, increase_inodes_workspace, (void *) dh->object->workspace_mount);

			inode->alias=entry;
			entry->inode=inode;

			memcpy(&entry->synctime, &dh->synctime, sizeof(struct timespec));

			inode->nlookup++;
			inode->nlink=2;
			inode->uid=0; /* ?? */
			inode->gid=0; /* ?? */
			inode->size=de->size;

			/* struct timeval convert to timespec */

			inode->mtim.tv_sec=de->mtime.tv_sec;
			inode->mtim.tv_nsec=1000 * de->mtime.tv_usec;

			inode->ctim.tv_sec=de->ctime.tv_sec;
			inode->ctim.tv_nsec=1000 * de->ctime.tv_usec;

			adjust_pathmax(dh->pathinfo.len + 1 + xname.len);

		    } else {

			if (error==EEXIST) {

			    destroy_entry(entry);
			    entry=result;

			    memcpy(&entry->synctime, &dh->synctime, sizeof(struct timespec));

			    free(inode);
			    inode=entry->inode;

			} else {

			    free(buff);
			    destroy_entry(entry);
			    free(inode);

			    goto error;

			}

		    }

		} else {

		    if (entry) {

			destroy_entry(entry);
			entry=NULL;

		    }

		    if (inode) {

			free(inode);
			inode=NULL;

		    }

		    error=ENOMEM;
		    free(buff);

		    goto error;

		}

		name=entry->name.name;
		dh->entry=entry;


	    } else {

		entry=dh->entry;

		inode=entry->inode;
		name=entry->name.name;

	    }

	    e.ino = inode->ino;

	    e.attr.st_ino = e.ino;
	    e.attr.st_mode = inode->mode;
	    e.attr.st_nlink = inode->nlink;
	    e.attr.st_uid = inode->uid;
	    e.attr.st_gid = inode->gid;
	    e.attr.st_rdev = inode->rdev;
	    e.attr.st_size = inode->size;

	    e.attr.st_atim.tv_sec = 0;
	    e.attr.st_atim.tv_nsec = 0;
	    e.attr.st_mtim.tv_sec = inode->mtim.tv_sec;
	    e.attr.st_mtim.tv_nsec = inode->mtim.tv_nsec;
	    e.attr.st_ctim.tv_sec = inode->ctim.tv_sec;
	    e.attr.st_ctim.tv_nsec = inode->ctim.tv_nsec;

	    if (inode->size % e.attr.st_blksize == 0) {

		e.attr.st_blocks=inode->size / e.attr.st_blksize;

	    } else {

		e.attr.st_blocks=1 + inode->size / e.attr.st_blksize;

	    }

	}

    	dirent_size=fuse_add_direntry_plus(req, buff+pos, size-pos, name, &e, offset+1);

	if (pos + dirent_size > size) {

	    dh->offset=offset;
	    break;

	}

	/* increase counter and clear the various fields */

	dh->entry=NULL; /* forget current entry to force readdir */
	offset++;
	pos += dirent_size;

    }

    unlock_directory(directory, _DIRECTORY_LOCK_EXCL);

    fuse_reply_buf(req, buff, pos);

    free(buff);
    buff=NULL;

    return;

    error:

    fuse_reply_err(req, error);

}
static void workspace_nfs_readdir_simple(fuse_req_t req, size_t size, off_t offset, struct workspace_dh_struct *dh)
{
    struct resource_struct *resource=dh->object->resource;
    struct net_nfs_export_struct *nfs_export=(struct net_nfs_export_struct *) resource->data;
    struct nfs_context *nfs_ctx=(struct nfs_context *) nfs_export->data;
    unsigned int error=0;
    char *buff=NULL;
    size_t pos=0;
    size_t dirent_size;
    char *name=NULL;
    struct directory_struct *directory=dh->directory;
    struct nfsdir *dir=(struct nfsdir *) dh->handle.data;
    struct entry_struct *entry, *result;
    struct inode_struct *inode;
    struct name_struct xname={NULL, 0, 0};
    struct stat st;

    memset(&st, 0, sizeof(struct stat));

    buff=malloc(size);

    if (! buff) {

	error=ENOMEM;
	goto error;

    }

    if (lock_directory(directory, _DIRECTORY_LOCK_EXCL)==-1) {

	free(buff);
	buff=NULL;
	error=EAGAIN;
	goto error;

    }

    while (pos<size) {

	if (offset==0) {

	    inode=dh->parent->inode;

    	    /* the . entry */

    	    st.st_ino = inode->ino;
	    st.st_mode = S_IFDIR;
	    name = (char *) dotname;

    	} else if (offset==1) {

    	    /* the .. entry */

	    if (! dh->parent->parent ) {

		inode=dh->parent->inode;
	    	st.st_ino = inode->ino;

	    } else {
		struct entry_struct *parent=dh->parent->parent;

		inode=parent->inode;
	    	st.st_ino=inode->ino;

	    }

	    st.st_mode = S_IFDIR;
	    name = (char *) dotdotname;

    	} else {

	    if (! dh->entry) {
		struct nfsdirent *de;

		readdir:

		pthread_mutex_lock(&nfs_export->mutex);

		de=nfs_readdir(nfs_ctx, dir);

	        pthread_mutex_unlock(&nfs_export->mutex);

		if (de) {

		    if (strcmp(de->name, ".")==0 || strcmp(de->name, "..")==0) continue;

		    xname.name=de->name;
		    xname.len=strlen(xname.name);
		    calculate_nameindex(&xname);

		} else {

		    dh->mode |= _WORKSPACE_READDIR_MODE_FINISH;
		    break;

		}

		error=0;

		entry=create_entry(dh->parent, &xname);
		inode=create_inode();

		if (entry && inode) {

		    result=insert_entry_batch(directory, entry, &error, 0);

		    if (result==entry) {
			struct workspace_object_struct *export_object=NULL;

			inode->mode = translate_libnfs_type(de->type);
			inode->mode |= de->mode;

			add_inode_hashtable(inode, increase_inodes_workspace, (void *) dh->object->workspace_mount);

			inode->alias=entry;
			entry->inode=inode;

			adjust_pathmax(dh->pathinfo.len + 1 + xname.len);

		    } else {

			if (error==EEXIST) {

			    destroy_entry(entry);
			    entry=result;

			    free(inode);
			    inode=entry->inode;

			} else {

			    free(buff);
			    destroy_entry(entry);
			    free(inode);

			    goto error;

			}

		    }

		    st.st_mode=entry->inode->mode;
		    st.st_ino=entry->inode->ino;
		    name=entry->name.name;

		} else {

		    if (entry) {

			destroy_entry(entry);
			entry=NULL;

		    }

		    if (inode) {

			free(inode);
			inode=NULL;

		    }

		    error=ENOMEM;
		    free(buff);

		    goto error;

		}

		dh->entry=entry;

	    } else {

		st.st_ino=dh->entry->inode->ino;
		st.st_mode=dh->entry->inode->mode;
		name=dh->entry->name.name;

	    }

	}

    	dirent_size=fuse_add_direntry(req, buff+pos, size-pos, name, &st, offset+1);

	if (pos + dirent_size > size) {

	    dh->offset = offset + 1;
	    break;

	}

	/* increase counter and clear the various fields */

	dh->entry=NULL; /* forget current entry to force readdir */
	offset++;
	pos += dirent_size;

    }

    unlock_directory(directory, _DIRECTORY_LOCK_EXCL);

    fuse_reply_buf(req, buff, pos);

    free(buff);
    buff=NULL;

    return;

    error:

    fuse_reply_err(req, error);

}
Example #8
0
/* Run a getdirent request */
static
void
rq_dir_run(NFS_DirRequest *rq) {
	dprintf(2, "run NFS getdirent request\n");
	nfs_readdir(&nfs_mnt, 0, IO_MAX_BUFFER, getdirent_cb, rq->p.token);
}