]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/9p/client.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/cpupowerutils
[mv-sheeva.git] / net / 9p / client.c
index 332f97e0385e86c126a92744990eb2aedbdaece6..0505a03c374c1599cac7bffbf1ec6d0af311910e 100644 (file)
@@ -72,23 +72,22 @@ inline int p9_is_proto_dotu(struct p9_client *clnt)
 EXPORT_SYMBOL(p9_is_proto_dotu);
 
 /* Interpret mount option for protocol version */
-static int get_protocol_version(const substring_t *name)
+static int get_protocol_version(char *s)
 {
        int version = -EINVAL;
 
-       if (!strncmp("9p2000", name->from, name->to-name->from)) {
+       if (!strcmp(s, "9p2000")) {
                version = p9_proto_legacy;
                P9_DPRINTK(P9_DEBUG_9P, "Protocol version: Legacy\n");
-       } else if (!strncmp("9p2000.u", name->from, name->to-name->from)) {
+       } else if (!strcmp(s, "9p2000.u")) {
                version = p9_proto_2000u;
                P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.u\n");
-       } else if (!strncmp("9p2000.L", name->from, name->to-name->from)) {
+       } else if (!strcmp(s, "9p2000.L")) {
                version = p9_proto_2000L;
                P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.L\n");
-       } else {
-               P9_DPRINTK(P9_DEBUG_ERROR, "Unknown protocol version %s. ",
-                                                       name->from);
-       }
+       } else
+               printk(KERN_INFO "9p: Unknown protocol version %s.\n", s);
+
        return version;
 }
 
@@ -106,6 +105,7 @@ static int parse_opts(char *opts, struct p9_client *clnt)
        char *p;
        substring_t args[MAX_OPT_ARGS];
        int option;
+       char *s;
        int ret = 0;
 
        clnt->proto_version = p9_proto_2000u;
@@ -141,22 +141,41 @@ static int parse_opts(char *opts, struct p9_client *clnt)
                        clnt->msize = option;
                        break;
                case Opt_trans:
-                       clnt->trans_mod = v9fs_get_trans_by_name(&args[0]);
-                       if(clnt->trans_mod == NULL) {
+                       s = match_strdup(&args[0]);
+                       if (!s) {
+                               ret = -ENOMEM;
                                P9_DPRINTK(P9_DEBUG_ERROR,
-                                  "Could not find request transport: %s\n",
-                                  (char *) &args[0]);
+                                       "problem allocating copy of trans arg\n");
+                               goto free_and_return;
+                        }
+                       clnt->trans_mod = v9fs_get_trans_by_name(s);
+                       if (clnt->trans_mod == NULL) {
+                               printk(KERN_INFO
+                                       "9p: Could not find "
+                                       "request transport: %s\n", s);
                                ret = -EINVAL;
+                               kfree(s);
                                goto free_and_return;
                        }
+                       kfree(s);
                        break;
                case Opt_legacy:
                        clnt->proto_version = p9_proto_legacy;
                        break;
                case Opt_version:
-                       ret = get_protocol_version(&args[0]);
-                       if (ret == -EINVAL)
+                       s = match_strdup(&args[0]);
+                       if (!s) {
+                               ret = -ENOMEM;
+                               P9_DPRINTK(P9_DEBUG_ERROR,
+                                       "problem allocating copy of version arg\n");
                                goto free_and_return;
+                       }
+                       ret = get_protocol_version(s);
+                       if (ret == -EINVAL) {
+                               kfree(s);
+                               goto free_and_return;
+                       }
+                       kfree(s);
                        clnt->proto_version = ret;
                        break;
                default:
@@ -822,8 +841,8 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
        if (err)
                goto destroy_fidpool;
 
-       if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize)
-               clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ;
+       if (clnt->msize > clnt->trans_mod->maxsize)
+               clnt->msize = clnt->trans_mod->maxsize;
 
        err = p9_client_version(clnt);
        if (err)
@@ -1250,9 +1269,11 @@ int p9_client_clunk(struct p9_fid *fid)
        P9_DPRINTK(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid);
 
        p9_free_req(clnt, req);
-       p9_fid_destroy(fid);
-
 error:
+       /*
+        * Fid is not valid even after a failed clunk
+        */
+       p9_fid_destroy(fid);
        return err;
 }
 EXPORT_SYMBOL(p9_client_clunk);
@@ -1282,6 +1303,29 @@ error:
 }
 EXPORT_SYMBOL(p9_client_remove);
 
+int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags)
+{
+       int err = 0;
+       struct p9_req_t *req;
+       struct p9_client *clnt;
+
+       P9_DPRINTK(P9_DEBUG_9P, ">>> TUNLINKAT fid %d %s %d\n",
+                  dfid->fid, name, flags);
+
+       clnt = dfid->clnt;
+       req = p9_client_rpc(clnt, P9_TUNLINKAT, "dsd", dfid->fid, name, flags);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto error;
+       }
+       P9_DPRINTK(P9_DEBUG_9P, "<<< RUNLINKAT fid %d %s\n", dfid->fid, name);
+
+       p9_free_req(clnt, req);
+error:
+       return err;
+}
+EXPORT_SYMBOL(p9_client_unlinkat);
+
 int
 p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
                                                                u32 count)
@@ -1645,7 +1689,8 @@ error:
 }
 EXPORT_SYMBOL(p9_client_statfs);
 
-int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, char *name)
+int p9_client_rename(struct p9_fid *fid,
+                    struct p9_fid *newdirfid, const char *name)
 {
        int err;
        struct p9_req_t *req;
@@ -1672,6 +1717,36 @@ error:
 }
 EXPORT_SYMBOL(p9_client_rename);
 
+int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
+                      struct p9_fid *newdirfid, const char *new_name)
+{
+       int err;
+       struct p9_req_t *req;
+       struct p9_client *clnt;
+
+       err = 0;
+       clnt = olddirfid->clnt;
+
+       P9_DPRINTK(P9_DEBUG_9P, ">>> TRENAMEAT olddirfid %d old name %s"
+                  " newdirfid %d new name %s\n", olddirfid->fid, old_name,
+                  newdirfid->fid, new_name);
+
+       req = p9_client_rpc(clnt, P9_TRENAMEAT, "dsds", olddirfid->fid,
+                           old_name, newdirfid->fid, new_name);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto error;
+       }
+
+       P9_DPRINTK(P9_DEBUG_9P, "<<< RRENAMEAT newdirfid %d new name %s\n",
+                  newdirfid->fid, new_name);
+
+       p9_free_req(clnt, req);
+error:
+       return err;
+}
+EXPORT_SYMBOL(p9_client_renameat);
+
 /*
  * An xattrwalk without @attr_name gives the fid for the lisxattr namespace
  */