]> Pileus Git - ~andy/linux/blobdiff - net/9p/client.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
[~andy/linux] / net / 9p / client.c
index 30c4a1b224fb55c5acda6e30b6cf2376b9dd965e..a848bca9fbffcd89e659e0d998bf830b83920765 100644 (file)
@@ -579,11 +579,14 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
        va_start(ap, fmt);
        err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap);
        va_end(ap);
+       if (err)
+               goto reterr;
        p9pdu_finalize(req->tc);
 
        err = c->trans_mod->request(c, req);
        if (err < 0) {
-               c->status = Disconnected;
+               if (err != -ERESTARTSYS)
+                       c->status = Disconnected;
                goto reterr;
        }
 
@@ -1162,17 +1165,18 @@ int p9_client_link(struct p9_fid *dfid, struct p9_fid *oldfid, char *newname)
 }
 EXPORT_SYMBOL(p9_client_link);
 
-int p9_client_fsync(struct p9_fid *fid)
+int p9_client_fsync(struct p9_fid *fid, int datasync)
 {
        int err;
        struct p9_client *clnt;
        struct p9_req_t *req;
 
-       P9_DPRINTK(P9_DEBUG_9P, ">>> TFSYNC fid %d\n", fid->fid);
+       P9_DPRINTK(P9_DEBUG_9P, ">>> TFSYNC fid %d datasync:%d\n",
+                       fid->fid, datasync);
        err = 0;
        clnt = fid->clnt;
 
-       req = p9_client_rpc(clnt, P9_TFSYNC, "d", fid->fid);
+       req = p9_client_rpc(clnt, P9_TFSYNC, "dd", fid->fid, datasync);
        if (IS_ERR(req)) {
                err = PTR_ERR(req);
                goto error;
@@ -1282,16 +1286,13 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
 
        if (data) {
                memmove(data, dataptr, count);
-       }
-
-       if (udata) {
+       } else {
                err = copy_to_user(udata, dataptr, count);
                if (err) {
                        err = -EFAULT;
                        goto free_and_error;
                }
        }
-
        p9_free_req(clnt, req);
        return count;
 
@@ -1803,3 +1804,96 @@ error:
 
 }
 EXPORT_SYMBOL(p9_client_mkdir_dotl);
+
+int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status)
+{
+       int err;
+       struct p9_client *clnt;
+       struct p9_req_t *req;
+
+       err = 0;
+       clnt = fid->clnt;
+       P9_DPRINTK(P9_DEBUG_9P, ">>> TLOCK fid %d type %i flags %d "
+                       "start %lld length %lld proc_id %d client_id %s\n",
+                       fid->fid, flock->type, flock->flags, flock->start,
+                       flock->length, flock->proc_id, flock->client_id);
+
+       req = p9_client_rpc(clnt, P9_TLOCK, "dbdqqds", fid->fid, flock->type,
+                               flock->flags, flock->start, flock->length,
+                                       flock->proc_id, flock->client_id);
+
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+
+       err = p9pdu_readf(req->rc, clnt->proto_version, "b", status);
+       if (err) {
+               p9pdu_dump(1, req->rc);
+               goto error;
+       }
+       P9_DPRINTK(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status);
+error:
+       p9_free_req(clnt, req);
+       return err;
+
+}
+EXPORT_SYMBOL(p9_client_lock_dotl);
+
+int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock)
+{
+       int err;
+       struct p9_client *clnt;
+       struct p9_req_t *req;
+
+       err = 0;
+       clnt = fid->clnt;
+       P9_DPRINTK(P9_DEBUG_9P, ">>> TGETLOCK fid %d, type %i start %lld "
+               "length %lld proc_id %d client_id %s\n", fid->fid, glock->type,
+               glock->start, glock->length, glock->proc_id, glock->client_id);
+
+       req = p9_client_rpc(clnt, P9_TGETLOCK, "dbqqds", fid->fid,  glock->type,
+               glock->start, glock->length, glock->proc_id, glock->client_id);
+
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+
+       err = p9pdu_readf(req->rc, clnt->proto_version, "bqqds", &glock->type,
+                       &glock->start, &glock->length, &glock->proc_id,
+                       &glock->client_id);
+       if (err) {
+               p9pdu_dump(1, req->rc);
+               goto error;
+       }
+       P9_DPRINTK(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld "
+               "proc_id %d client_id %s\n", glock->type, glock->start,
+               glock->length, glock->proc_id, glock->client_id);
+error:
+       p9_free_req(clnt, req);
+       return err;
+}
+EXPORT_SYMBOL(p9_client_getlock_dotl);
+
+int p9_client_readlink(struct p9_fid *fid, char **target)
+{
+       int err;
+       struct p9_client *clnt;
+       struct p9_req_t *req;
+
+       err = 0;
+       clnt = fid->clnt;
+       P9_DPRINTK(P9_DEBUG_9P, ">>> TREADLINK fid %d\n", fid->fid);
+
+       req = p9_client_rpc(clnt, P9_TREADLINK, "d", fid->fid);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+
+       err = p9pdu_readf(req->rc, clnt->proto_version, "s", target);
+       if (err) {
+               p9pdu_dump(1, req->rc);
+               goto error;
+       }
+       P9_DPRINTK(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target);
+error:
+       p9_free_req(clnt, req);
+       return err;
+}
+EXPORT_SYMBOL(p9_client_readlink);