int v9fs_file_open(struct inode *inode, struct file *file)
{
	int err;
	struct v9fs_inode *v9inode;
	struct v9fs_session_info *v9ses;
	struct p9_fid *fid;
	int omode;

	p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file);
	v9inode = V9FS_I(inode);
	v9ses = v9fs_inode2v9ses(inode);
	if (v9fs_proto_dotl(v9ses))
		omode = v9fs_open_to_dotl_flags(file->f_flags);
	else
		omode = v9fs_uflags2omode(file->f_flags,
					v9fs_proto_dotu(v9ses));
	fid = file->private_data;
	if (!fid) {
		fid = v9fs_fid_clone(file->f_path.dentry);
		if (IS_ERR(fid))
			return PTR_ERR(fid);

		err = p9_client_open(fid, omode);
		if (err < 0) {
			p9_client_clunk(fid);
			return err;
		}
		if ((file->f_flags & O_APPEND) &&
			(!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)))
			generic_file_llseek(file, 0, SEEK_END);
	}

	file->private_data = fid;
	mutex_lock(&v9inode->v_mutex);
	if (v9ses->cache && !v9inode->writeback_fid &&
	    ((file->f_flags & O_ACCMODE) != O_RDONLY)) {
		/*
		 * clone a fid and add it to writeback_fid
		 * we do it during open time instead of
		 * page dirty time via write_begin/page_mkwrite
		 * because we want write after unlink usecase
		 * to work.
		 */
		fid = v9fs_writeback_fid(file->f_path.dentry);
		if (IS_ERR(fid)) {
			err = PTR_ERR(fid);
			mutex_unlock(&v9inode->v_mutex);
			goto out_error;
		}
		v9inode->writeback_fid = (void *) fid;
	}
	mutex_unlock(&v9inode->v_mutex);
	if (v9ses->cache)
		v9fs_cache_inode_set_cookie(inode, file);
	return 0;
out_error:
	p9_client_clunk(file->private_data);
	file->private_data = NULL;
	return err;
}
Ejemplo n.º 2
0
/*
 * v9fs_xattr_set()
 *
 * Create, replace or remove an extended attribute for this inode. Buffer
 * is NULL to remove an existing extended attribute, and non-NULL to
 * either replace an existing extended attribute, or create a new extended
 * attribute. The flags XATTR_REPLACE and XATTR_CREATE
 * specify that an extended attribute must exist and must not exist
 * previous to the call, respectively.
 *
 * Returns 0, or a negative error number on failure.
 */
int v9fs_xattr_set(struct dentry *dentry, const char *name,
                   const void *value, size_t value_len, int flags)
{
    u64 offset = 0;
    int retval, msize, write_count;
    struct p9_fid *fid = NULL;

    P9_DPRINTK(P9_DEBUG_VFS, "%s: name = %s value_len = %zu flags = %d\n",
               __func__, name, value_len, flags);

    fid = v9fs_fid_clone(dentry);
    if (IS_ERR(fid)) {
        retval = PTR_ERR(fid);
        fid = NULL;
        goto error;
    }
    /*
     * On success fid points to xattr
     */
    retval = p9_client_xattrcreate(fid, name, value_len, flags);
    if (retval < 0) {
        P9_DPRINTK(P9_DEBUG_VFS,
                   "p9_client_xattrcreate failed %d\n", retval);
        goto error;
    }
    msize = fid->clnt->msize;;
    while (value_len) {
        if (value_len > (msize - P9_IOHDRSZ))
            write_count = msize - P9_IOHDRSZ;
        else
            write_count = value_len;
        write_count = p9_client_write(fid, ((char *)value)+offset,
                                      NULL, offset, write_count);
        if (write_count < 0) {
            /* error in xattr write */
            retval = write_count;
            goto error;
        }
        offset += write_count;
        value_len -= write_count;
    }
    /* Total read xattr bytes */
    retval = offset;
error:
    if (fid)
        retval = p9_client_clunk(fid);
    return retval;
}
Ejemplo n.º 3
0
int v9fs_file_open(struct inode *inode, struct file *file)
{
	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
	struct v9fs_fid *vfid;
	struct v9fs_fcall *fcall = NULL;
	int omode;
	int err;

	dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file);

	vfid = v9fs_fid_clone(file->f_path.dentry);
	if (IS_ERR(vfid))
		return PTR_ERR(vfid);

	omode = v9fs_uflags2omode(file->f_flags);
	err = v9fs_t_open(v9ses, vfid->fid, omode, &fcall);
	if (err < 0) {
		PRINT_FCALL_ERROR("open failed", fcall);
		goto Clunk_Fid;
	}

	file->private_data = vfid;
	vfid->fidopen = 1;
	vfid->fidclunked = 0;
	vfid->iounit = fcall->params.ropen.iounit;
	vfid->rdir_pos = 0;
	vfid->rdir_fcall = NULL;
	vfid->filp = file;
	kfree(fcall);

	if((vfid->qid.version) && (v9ses->cache)) {
		dprintk(DEBUG_VFS, "cached");
		/* enable cached file options */
		if(file->f_op == &v9fs_file_operations)
			file->f_op = &v9fs_cached_file_operations;
	}

	return 0;

Clunk_Fid:
	v9fs_fid_clunk(v9ses, vfid);
	kfree(fcall);

	return err;
}
Ejemplo n.º 4
0
int v9fs_file_open(struct inode *inode, struct file *file)
{
    int err;
    struct v9fs_session_info *v9ses;
    struct p9_fid *fid;
    int omode;

    P9_DPRINTK(P9_DEBUG_VFS, "inode: %p file: %p \n", inode, file);
    v9ses = v9fs_inode2v9ses(inode);
    omode = v9fs_uflags2omode(file->f_flags, v9fs_proto_dotu(v9ses));
    fid = file->private_data;
    if (!fid) {
        fid = v9fs_fid_clone(file->f_path.dentry);
        if (IS_ERR(fid))
            return PTR_ERR(fid);

        err = p9_client_open(fid, omode);
        if (err < 0) {
            p9_client_clunk(fid);
            return err;
        }
        if (omode & P9_OTRUNC) {
            i_size_write(inode, 0);
            inode->i_blocks = 0;
        }
        if ((file->f_flags & O_APPEND) && (!v9fs_proto_dotu(v9ses)))
            generic_file_llseek(file, 0, SEEK_END);
    }

    file->private_data = fid;
    if ((fid->qid.version) && (v9ses->cache)) {
        P9_DPRINTK(P9_DEBUG_VFS, "cached");
        /* enable cached file options */
        if(file->f_op == &v9fs_file_operations)
            file->f_op = &v9fs_cached_file_operations;

#ifdef CONFIG_9P_FSCACHE
        v9fs_cache_inode_set_cookie(inode, file);
#endif
    }

    return 0;
}
Ejemplo n.º 5
0
int v9fs_file_open(struct inode *inode, struct file *file)
{
	int err;
	struct v9fs_session_info *v9ses;
	struct p9_fid *fid;
	int omode;

	P9_DPRINTK(P9_DEBUG_VFS, "inode: %p file: %p \n", inode, file);
	v9ses = v9fs_inode2v9ses(inode);
	omode = v9fs_uflags2omode(file->f_flags);
	fid = file->private_data;
	if (!fid) {
		fid = v9fs_fid_clone(file->f_path.dentry);
		if (IS_ERR(fid))
			return PTR_ERR(fid);

		err = p9_client_open(fid, omode);
		if (err < 0) {
			p9_client_clunk(fid);
			return err;
		}
		if (omode & P9_OTRUNC) {
			inode->i_size = 0;
			inode->i_blocks = 0;
		}
	}

	file->private_data = fid;
	if ((fid->qid.version) && (v9ses->cache)) {
		P9_DPRINTK(P9_DEBUG_VFS, "cached");
		/* enable cached file options */
		if(file->f_op == &v9fs_file_operations)
			file->f_op = &v9fs_cached_file_operations;
	}

	return 0;
}