Beispiel #1
0
struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
		  const char *dev_name, char *data)
{
	int retval = -EINVAL;
	struct p9_transport *trans;
	struct p9_fid *fid;

	v9ses->name = __getname();
	if (!v9ses->name)
		return ERR_PTR(-ENOMEM);

	v9ses->remotename = __getname();
	if (!v9ses->remotename) {
		__putname(v9ses->name);
		return ERR_PTR(-ENOMEM);
	}

	strcpy(v9ses->name, V9FS_DEFUSER);
	strcpy(v9ses->remotename, V9FS_DEFANAME);

	v9fs_parse_options(data, v9ses);

	switch (v9ses->proto) {
	case PROTO_TCP:
		trans = p9_trans_create_tcp(dev_name, v9ses->port);
		break;
	case PROTO_UNIX:
		trans = p9_trans_create_unix(dev_name);
		*v9ses->remotename = 0;
		break;
	case PROTO_FD:
		trans = p9_trans_create_fd(v9ses->rfdno, v9ses->wfdno);
		*v9ses->remotename = 0;
		break;
#ifdef CONFIG_PCI_9P
	case PROTO_PCI:
		trans = p9pci_trans_create();
		*v9ses->remotename = 0;
		break;
#endif
	default:
		printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto);
		retval = -ENOPROTOOPT;
		goto error;
	};

	if (IS_ERR(trans)) {
		retval = PTR_ERR(trans);
		trans = NULL;
		goto error;
	}

	v9ses->clnt = p9_client_create(trans, v9ses->maxdata + P9_IOHDRSZ,
		v9ses->extended);

	if (IS_ERR(v9ses->clnt)) {
		retval = PTR_ERR(v9ses->clnt);
		v9ses->clnt = NULL;
		P9_DPRINTK(P9_DEBUG_ERROR, "problem initializing 9p client\n");
		goto error;
	}

	fid = p9_client_attach(v9ses->clnt, NULL, v9ses->name,
							v9ses->remotename);
	if (IS_ERR(fid)) {
		retval = PTR_ERR(fid);
		fid = NULL;
		P9_DPRINTK(P9_DEBUG_ERROR, "cannot attach\n");
		goto error;
	}

	return fid;

error:
	v9fs_session_close(v9ses);
	return ERR_PTR(retval);
}
Beispiel #2
0
int
v9fs_session_init(struct v9fs_session_info *v9ses,
		  const char *dev_name, char *data)
{
	struct v9fs_fcall *fcall = NULL;
	struct v9fs_transport *trans_proto;
	int n = 0;
	int newfid = -1;
	int retval = -EINVAL;
	struct v9fs_str *version;

	v9ses->name = __getname();
	if (!v9ses->name)
		return -ENOMEM;

	v9ses->remotename = __getname();
	if (!v9ses->remotename) {
		__putname(v9ses->name);
		return -ENOMEM;
	}

	strcpy(v9ses->name, V9FS_DEFUSER);
	strcpy(v9ses->remotename, V9FS_DEFANAME);

	v9fs_parse_options(data, v9ses);

	/* set global debug level */
	v9fs_debug_level = v9ses->debug;

	/* id pools that are session-dependent: fids and tags */
	idr_init(&v9ses->fidpool.pool);
	init_MUTEX(&v9ses->fidpool.lock);

	switch (v9ses->proto) {
	case PROTO_TCP:
		trans_proto = &v9fs_trans_tcp;
		break;
	case PROTO_UNIX:
		trans_proto = &v9fs_trans_unix;
		*v9ses->remotename = 0;
		break;
	case PROTO_FD:
		trans_proto = &v9fs_trans_fd;
		*v9ses->remotename = 0;
		break;
	default:
		printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto);
		retval = -ENOPROTOOPT;
		goto SessCleanUp;
	};

	v9ses->transport = kmalloc(sizeof(*v9ses->transport), GFP_KERNEL);
	if (!v9ses->transport) {
		retval = -ENOMEM;
		goto SessCleanUp;
	}

	memmove(v9ses->transport, trans_proto, sizeof(*v9ses->transport));

	if ((retval = v9ses->transport->init(v9ses, dev_name, data)) < 0) {
		eprintk(KERN_ERR, "problem initializing transport\n");
		goto SessCleanUp;
	}

	v9ses->inprogress = 0;
	v9ses->shutdown = 0;
	v9ses->session_hung = 0;

	v9ses->mux = v9fs_mux_init(v9ses->transport, v9ses->maxdata + V9FS_IOHDRSZ,
		&v9ses->extended);

	if (IS_ERR(v9ses->mux)) {
		retval = PTR_ERR(v9ses->mux);
		v9ses->mux = NULL;
		dprintk(DEBUG_ERROR, "problem initializing mux\n");
		goto SessCleanUp;
	}

	if (v9ses->afid == ~0) {
		if (v9ses->extended)
			retval =
			    v9fs_t_version(v9ses, v9ses->maxdata, "9P2000.u",
					   &fcall);
		else
			retval = v9fs_t_version(v9ses, v9ses->maxdata, "9P2000",
						&fcall);

		if (retval < 0) {
			dprintk(DEBUG_ERROR, "v9fs_t_version failed\n");
			goto FreeFcall;
		}

		version = &fcall->params.rversion.version;
		if (version->len==8 && !memcmp(version->str, "9P2000.u", 8)) {
			dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n");
			v9ses->extended = 1;
		} else if (version->len==6 && !memcmp(version->str, "9P2000", 6)) {
			dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n");
			v9ses->extended = 0;
		} else {
			retval = -EREMOTEIO;
			goto FreeFcall;
		}

		n = fcall->params.rversion.msize;
		kfree(fcall);

		if (n < v9ses->maxdata)
			v9ses->maxdata = n;
	}

	newfid = v9fs_get_idpool(&v9ses->fidpool);
	if (newfid < 0) {
		eprintk(KERN_WARNING, "couldn't allocate FID\n");
		retval = -ENOMEM;
		goto SessCleanUp;
	}
	/* it is a little bit ugly, but we have to prevent newfid */
	/* being the same as afid, so if it is, get a new fid     */
	if (v9ses->afid != ~0 && newfid == v9ses->afid) {
		newfid = v9fs_get_idpool(&v9ses->fidpool);
		if (newfid < 0) {
			eprintk(KERN_WARNING, "couldn't allocate FID\n");
			retval = -ENOMEM;
			goto SessCleanUp;
		}
	}

	if ((retval =
	     v9fs_t_attach(v9ses, v9ses->name, v9ses->remotename, newfid,
			   v9ses->afid, NULL))
	    < 0) {
		dprintk(DEBUG_ERROR, "cannot attach\n");
		goto SessCleanUp;
	}

	if (v9ses->afid != ~0) {
		dprintk(DEBUG_ERROR, "afid not equal to ~0\n");
		if (v9fs_t_clunk(v9ses, v9ses->afid))
			dprintk(DEBUG_ERROR, "clunk failed\n");
	}

	return newfid;

      FreeFcall:
	kfree(fcall);

      SessCleanUp:
	v9fs_session_close(v9ses);
	return retval;
}
Beispiel #3
0
struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
          const char *dev_name, char *data)
{
    int retval = -EINVAL;
    struct p9_fid *fid;
    int rc;

    v9ses->uname = __getname();
    if (!v9ses->uname)
        return ERR_PTR(-ENOMEM);

    v9ses->aname = __getname();
    if (!v9ses->aname) {
        __putname(v9ses->uname);
        return ERR_PTR(-ENOMEM);
    }

    v9ses->flags = V9FS_EXTENDED | V9FS_ACCESS_USER;
    strcpy(v9ses->uname, V9FS_DEFUSER);
    strcpy(v9ses->aname, V9FS_DEFANAME);
    v9ses->uid = ~0;
    v9ses->dfltuid = V9FS_DEFUID;
    v9ses->dfltgid = V9FS_DEFGID;
    if (data) {
        v9ses->options = kstrdup(data, GFP_KERNEL);
        if (!v9ses->options) {
            P9_DPRINTK(P9_DEBUG_ERROR,
               "failed to allocate copy of option string\n");
            retval = -ENOMEM;
            goto error;
        }
    }

    rc = v9fs_parse_options(v9ses);
    if (rc < 0) {
        retval = rc;
        goto error;
    }

    v9ses->clnt = p9_client_create(dev_name, v9ses->options);

    if (IS_ERR(v9ses->clnt)) {
        retval = PTR_ERR(v9ses->clnt);
        v9ses->clnt = NULL;
        P9_DPRINTK(P9_DEBUG_ERROR, "problem initializing 9p client\n");
        goto error;
    }

    if (!v9ses->clnt->dotu)
        v9ses->flags &= ~V9FS_EXTENDED;

    v9ses->maxdata = v9ses->clnt->msize;

    /* for legacy mode, fall back to V9FS_ACCESS_ANY */
    if (!v9fs_extended(v9ses) &&
        ((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) {

        v9ses->flags &= ~V9FS_ACCESS_MASK;
        v9ses->flags |= V9FS_ACCESS_ANY;
        v9ses->uid = ~0;
    }

    fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, ~0,
                            v9ses->aname);
    if (IS_ERR(fid)) {
        retval = PTR_ERR(fid);
        fid = NULL;
        P9_DPRINTK(P9_DEBUG_ERROR, "cannot attach\n");
        goto error;
    }

    if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE)
        fid->uid = v9ses->uid;
    else
        fid->uid = ~0;

    return fid;

error:
    return ERR_PTR(retval);
}