diff options
Diffstat (limited to 'net/9p/client.c')
-rw-r--r-- | net/9p/client.c | 183 |
1 files changed, 89 insertions, 94 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index f1a52a7ed724..712d4f336adc 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -36,10 +36,6 @@ | |||
36 | #include <net/9p/client.h> | 36 | #include <net/9p/client.h> |
37 | #include <net/9p/transport.h> | 37 | #include <net/9p/transport.h> |
38 | 38 | ||
39 | static struct p9_fid *p9_fid_create(struct p9_client *clnt); | ||
40 | static void p9_fid_destroy(struct p9_fid *fid); | ||
41 | static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu); | ||
42 | |||
43 | /* | 39 | /* |
44 | * Client Option Parsing (code inspired by NFS code) | 40 | * Client Option Parsing (code inspired by NFS code) |
45 | * - a little lazy - parse all client options | 41 | * - a little lazy - parse all client options |
@@ -124,6 +120,55 @@ static int parse_opts(char *opts, struct p9_client *clnt) | |||
124 | return ret; | 120 | return ret; |
125 | } | 121 | } |
126 | 122 | ||
123 | static struct p9_fid *p9_fid_create(struct p9_client *clnt) | ||
124 | { | ||
125 | int err; | ||
126 | struct p9_fid *fid; | ||
127 | |||
128 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); | ||
129 | fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL); | ||
130 | if (!fid) | ||
131 | return ERR_PTR(-ENOMEM); | ||
132 | |||
133 | fid->fid = p9_idpool_get(clnt->fidpool); | ||
134 | if (fid->fid < 0) { | ||
135 | err = -ENOSPC; | ||
136 | goto error; | ||
137 | } | ||
138 | |||
139 | memset(&fid->qid, 0, sizeof(struct p9_qid)); | ||
140 | fid->mode = -1; | ||
141 | fid->rdir_fpos = 0; | ||
142 | fid->rdir_pos = 0; | ||
143 | fid->rdir_fcall = NULL; | ||
144 | fid->uid = current->fsuid; | ||
145 | fid->clnt = clnt; | ||
146 | fid->aux = NULL; | ||
147 | |||
148 | spin_lock(&clnt->lock); | ||
149 | list_add(&fid->flist, &clnt->fidlist); | ||
150 | spin_unlock(&clnt->lock); | ||
151 | |||
152 | return fid; | ||
153 | |||
154 | error: | ||
155 | kfree(fid); | ||
156 | return ERR_PTR(err); | ||
157 | } | ||
158 | |||
159 | static void p9_fid_destroy(struct p9_fid *fid) | ||
160 | { | ||
161 | struct p9_client *clnt; | ||
162 | |||
163 | P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); | ||
164 | clnt = fid->clnt; | ||
165 | p9_idpool_put(fid->fid, clnt->fidpool); | ||
166 | spin_lock(&clnt->lock); | ||
167 | list_del(&fid->flist); | ||
168 | spin_unlock(&clnt->lock); | ||
169 | kfree(fid->rdir_fcall); | ||
170 | kfree(fid); | ||
171 | } | ||
127 | 172 | ||
128 | /** | 173 | /** |
129 | * p9_client_rpc - sends 9P request and waits until a response is available. | 174 | * p9_client_rpc - sends 9P request and waits until a response is available. |
@@ -815,6 +860,46 @@ int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count) | |||
815 | } | 860 | } |
816 | EXPORT_SYMBOL(p9_client_readn); | 861 | EXPORT_SYMBOL(p9_client_readn); |
817 | 862 | ||
863 | static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu) | ||
864 | { | ||
865 | int n; | ||
866 | char *p; | ||
867 | struct p9_stat *ret; | ||
868 | |||
869 | n = sizeof(struct p9_stat) + st->name.len + st->uid.len + st->gid.len + | ||
870 | st->muid.len; | ||
871 | |||
872 | if (dotu) | ||
873 | n += st->extension.len; | ||
874 | |||
875 | ret = kmalloc(n, GFP_KERNEL); | ||
876 | if (!ret) | ||
877 | return ERR_PTR(-ENOMEM); | ||
878 | |||
879 | memmove(ret, st, sizeof(struct p9_stat)); | ||
880 | p = ((char *) ret) + sizeof(struct p9_stat); | ||
881 | memmove(p, st->name.str, st->name.len); | ||
882 | ret->name.str = p; | ||
883 | p += st->name.len; | ||
884 | memmove(p, st->uid.str, st->uid.len); | ||
885 | ret->uid.str = p; | ||
886 | p += st->uid.len; | ||
887 | memmove(p, st->gid.str, st->gid.len); | ||
888 | ret->gid.str = p; | ||
889 | p += st->gid.len; | ||
890 | memmove(p, st->muid.str, st->muid.len); | ||
891 | ret->muid.str = p; | ||
892 | p += st->muid.len; | ||
893 | |||
894 | if (dotu) { | ||
895 | memmove(p, st->extension.str, st->extension.len); | ||
896 | ret->extension.str = p; | ||
897 | p += st->extension.len; | ||
898 | } | ||
899 | |||
900 | return ret; | ||
901 | } | ||
902 | |||
818 | struct p9_stat *p9_client_stat(struct p9_fid *fid) | 903 | struct p9_stat *p9_client_stat(struct p9_fid *fid) |
819 | { | 904 | { |
820 | int err; | 905 | int err; |
@@ -986,93 +1071,3 @@ error: | |||
986 | return ERR_PTR(err); | 1071 | return ERR_PTR(err); |
987 | } | 1072 | } |
988 | EXPORT_SYMBOL(p9_client_dirread); | 1073 | EXPORT_SYMBOL(p9_client_dirread); |
989 | |||
990 | static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu) | ||
991 | { | ||
992 | int n; | ||
993 | char *p; | ||
994 | struct p9_stat *ret; | ||
995 | |||
996 | n = sizeof(struct p9_stat) + st->name.len + st->uid.len + st->gid.len + | ||
997 | st->muid.len; | ||
998 | |||
999 | if (dotu) | ||
1000 | n += st->extension.len; | ||
1001 | |||
1002 | ret = kmalloc(n, GFP_KERNEL); | ||
1003 | if (!ret) | ||
1004 | return ERR_PTR(-ENOMEM); | ||
1005 | |||
1006 | memmove(ret, st, sizeof(struct p9_stat)); | ||
1007 | p = ((char *) ret) + sizeof(struct p9_stat); | ||
1008 | memmove(p, st->name.str, st->name.len); | ||
1009 | ret->name.str = p; | ||
1010 | p += st->name.len; | ||
1011 | memmove(p, st->uid.str, st->uid.len); | ||
1012 | ret->uid.str = p; | ||
1013 | p += st->uid.len; | ||
1014 | memmove(p, st->gid.str, st->gid.len); | ||
1015 | ret->gid.str = p; | ||
1016 | p += st->gid.len; | ||
1017 | memmove(p, st->muid.str, st->muid.len); | ||
1018 | ret->muid.str = p; | ||
1019 | p += st->muid.len; | ||
1020 | |||
1021 | if (dotu) { | ||
1022 | memmove(p, st->extension.str, st->extension.len); | ||
1023 | ret->extension.str = p; | ||
1024 | p += st->extension.len; | ||
1025 | } | ||
1026 | |||
1027 | return ret; | ||
1028 | } | ||
1029 | |||
1030 | static struct p9_fid *p9_fid_create(struct p9_client *clnt) | ||
1031 | { | ||
1032 | int err; | ||
1033 | struct p9_fid *fid; | ||
1034 | |||
1035 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); | ||
1036 | fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL); | ||
1037 | if (!fid) | ||
1038 | return ERR_PTR(-ENOMEM); | ||
1039 | |||
1040 | fid->fid = p9_idpool_get(clnt->fidpool); | ||
1041 | if (fid->fid < 0) { | ||
1042 | err = -ENOSPC; | ||
1043 | goto error; | ||
1044 | } | ||
1045 | |||
1046 | memset(&fid->qid, 0, sizeof(struct p9_qid)); | ||
1047 | fid->mode = -1; | ||
1048 | fid->rdir_fpos = 0; | ||
1049 | fid->rdir_pos = 0; | ||
1050 | fid->rdir_fcall = NULL; | ||
1051 | fid->uid = current->fsuid; | ||
1052 | fid->clnt = clnt; | ||
1053 | fid->aux = NULL; | ||
1054 | |||
1055 | spin_lock(&clnt->lock); | ||
1056 | list_add(&fid->flist, &clnt->fidlist); | ||
1057 | spin_unlock(&clnt->lock); | ||
1058 | |||
1059 | return fid; | ||
1060 | |||
1061 | error: | ||
1062 | kfree(fid); | ||
1063 | return ERR_PTR(err); | ||
1064 | } | ||
1065 | |||
1066 | static void p9_fid_destroy(struct p9_fid *fid) | ||
1067 | { | ||
1068 | struct p9_client *clnt; | ||
1069 | |||
1070 | P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); | ||
1071 | clnt = fid->clnt; | ||
1072 | p9_idpool_put(fid->fid, clnt->fidpool); | ||
1073 | spin_lock(&clnt->lock); | ||
1074 | list_del(&fid->flist); | ||
1075 | spin_unlock(&clnt->lock); | ||
1076 | kfree(fid->rdir_fcall); | ||
1077 | kfree(fid); | ||
1078 | } | ||