diff options
| -rw-r--r-- | fs/9p/9p.h | 375 | ||||
| -rw-r--r-- | fs/9p/Makefile | 6 | ||||
| -rw-r--r-- | fs/9p/conv.h | 50 | ||||
| -rw-r--r-- | fs/9p/debug.h | 77 | ||||
| -rw-r--r-- | fs/9p/error.c | 93 | ||||
| -rw-r--r-- | fs/9p/fcall.c | 427 | ||||
| -rw-r--r-- | fs/9p/fid.c | 168 | ||||
| -rw-r--r-- | fs/9p/fid.h | 43 | ||||
| -rw-r--r-- | fs/9p/trans_fd.c | 308 | ||||
| -rw-r--r-- | fs/9p/v9fs.c | 288 | ||||
| -rw-r--r-- | fs/9p/v9fs.h | 32 | ||||
| -rw-r--r-- | fs/9p/v9fs_vfs.h | 6 | ||||
| -rw-r--r-- | fs/9p/vfs_addr.c | 57 | ||||
| -rw-r--r-- | fs/9p/vfs_dentry.c | 37 | ||||
| -rw-r--r-- | fs/9p/vfs_dir.c | 155 | ||||
| -rw-r--r-- | fs/9p/vfs_file.c | 160 | ||||
| -rw-r--r-- | fs/9p/vfs_inode.c | 753 | ||||
| -rw-r--r-- | fs/9p/vfs_super.c | 91 | ||||
| -rw-r--r-- | fs/Kconfig | 2 | ||||
| -rw-r--r-- | include/net/9p/9p.h | 417 | ||||
| -rw-r--r-- | include/net/9p/client.h | 80 | ||||
| -rw-r--r-- | include/net/9p/conn.h (renamed from fs/9p/mux.h) | 42 | ||||
| -rw-r--r-- | include/net/9p/transport.h (renamed from fs/9p/transport.h) | 28 | ||||
| -rw-r--r-- | net/9p/Kconfig | 21 | ||||
| -rw-r--r-- | net/9p/Makefile | 13 | ||||
| -rw-r--r-- | net/9p/client.c | 965 | ||||
| -rw-r--r-- | net/9p/conv.c (renamed from fs/9p/conv.c) | 424 | ||||
| -rw-r--r-- | net/9p/error.c (renamed from fs/9p/error.h) | 79 | ||||
| -rw-r--r-- | net/9p/fcprint.c (renamed from fs/9p/fcprint.c) | 187 | ||||
| -rw-r--r-- | net/9p/mod.c | 85 | ||||
| -rw-r--r-- | net/9p/mux.c (renamed from fs/9p/mux.c) | 509 | ||||
| -rw-r--r-- | net/9p/sysctl.c | 86 | ||||
| -rw-r--r-- | net/9p/trans_fd.c | 363 | ||||
| -rw-r--r-- | net/9p/util.c | 125 | ||||
| -rw-r--r-- | net/Kconfig | 1 | ||||
| -rw-r--r-- | net/Makefile | 1 |
36 files changed, 3423 insertions, 3131 deletions
diff --git a/fs/9p/9p.h b/fs/9p/9p.h deleted file mode 100644 index 94e2f92ab2e8..000000000000 --- a/fs/9p/9p.h +++ /dev/null | |||
| @@ -1,375 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/fs/9p/9p.h | ||
| 3 | * | ||
| 4 | * 9P protocol definitions. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net> | ||
| 7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
| 8 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 | ||
| 12 | * as published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to: | ||
| 21 | * Free Software Foundation | ||
| 22 | * 51 Franklin Street, Fifth Floor | ||
| 23 | * Boston, MA 02111-1301 USA | ||
| 24 | * | ||
| 25 | */ | ||
| 26 | |||
| 27 | /* Message Types */ | ||
| 28 | enum { | ||
| 29 | TVERSION = 100, | ||
| 30 | RVERSION, | ||
| 31 | TAUTH = 102, | ||
| 32 | RAUTH, | ||
| 33 | TATTACH = 104, | ||
| 34 | RATTACH, | ||
| 35 | TERROR = 106, | ||
| 36 | RERROR, | ||
| 37 | TFLUSH = 108, | ||
| 38 | RFLUSH, | ||
| 39 | TWALK = 110, | ||
| 40 | RWALK, | ||
| 41 | TOPEN = 112, | ||
| 42 | ROPEN, | ||
| 43 | TCREATE = 114, | ||
| 44 | RCREATE, | ||
| 45 | TREAD = 116, | ||
| 46 | RREAD, | ||
| 47 | TWRITE = 118, | ||
| 48 | RWRITE, | ||
| 49 | TCLUNK = 120, | ||
| 50 | RCLUNK, | ||
| 51 | TREMOVE = 122, | ||
| 52 | RREMOVE, | ||
| 53 | TSTAT = 124, | ||
| 54 | RSTAT, | ||
| 55 | TWSTAT = 126, | ||
| 56 | RWSTAT, | ||
| 57 | }; | ||
| 58 | |||
| 59 | /* modes */ | ||
| 60 | enum { | ||
| 61 | V9FS_OREAD = 0x00, | ||
| 62 | V9FS_OWRITE = 0x01, | ||
| 63 | V9FS_ORDWR = 0x02, | ||
| 64 | V9FS_OEXEC = 0x03, | ||
| 65 | V9FS_OEXCL = 0x04, | ||
| 66 | V9FS_OTRUNC = 0x10, | ||
| 67 | V9FS_OREXEC = 0x20, | ||
| 68 | V9FS_ORCLOSE = 0x40, | ||
| 69 | V9FS_OAPPEND = 0x80, | ||
| 70 | }; | ||
| 71 | |||
| 72 | /* permissions */ | ||
| 73 | enum { | ||
| 74 | V9FS_DMDIR = 0x80000000, | ||
| 75 | V9FS_DMAPPEND = 0x40000000, | ||
| 76 | V9FS_DMEXCL = 0x20000000, | ||
| 77 | V9FS_DMMOUNT = 0x10000000, | ||
| 78 | V9FS_DMAUTH = 0x08000000, | ||
| 79 | V9FS_DMTMP = 0x04000000, | ||
| 80 | V9FS_DMSYMLINK = 0x02000000, | ||
| 81 | V9FS_DMLINK = 0x01000000, | ||
| 82 | /* 9P2000.u extensions */ | ||
| 83 | V9FS_DMDEVICE = 0x00800000, | ||
| 84 | V9FS_DMNAMEDPIPE = 0x00200000, | ||
| 85 | V9FS_DMSOCKET = 0x00100000, | ||
| 86 | V9FS_DMSETUID = 0x00080000, | ||
| 87 | V9FS_DMSETGID = 0x00040000, | ||
| 88 | }; | ||
| 89 | |||
| 90 | /* qid.types */ | ||
| 91 | enum { | ||
| 92 | V9FS_QTDIR = 0x80, | ||
| 93 | V9FS_QTAPPEND = 0x40, | ||
| 94 | V9FS_QTEXCL = 0x20, | ||
| 95 | V9FS_QTMOUNT = 0x10, | ||
| 96 | V9FS_QTAUTH = 0x08, | ||
| 97 | V9FS_QTTMP = 0x04, | ||
| 98 | V9FS_QTSYMLINK = 0x02, | ||
| 99 | V9FS_QTLINK = 0x01, | ||
| 100 | V9FS_QTFILE = 0x00, | ||
| 101 | }; | ||
| 102 | |||
| 103 | #define V9FS_NOTAG (u16)(~0) | ||
| 104 | #define V9FS_NOFID (u32)(~0) | ||
| 105 | #define V9FS_MAXWELEM 16 | ||
| 106 | |||
| 107 | /* ample room for Twrite/Rread header (iounit) */ | ||
| 108 | #define V9FS_IOHDRSZ 24 | ||
| 109 | |||
| 110 | struct v9fs_str { | ||
| 111 | u16 len; | ||
| 112 | char *str; | ||
| 113 | }; | ||
| 114 | |||
| 115 | /* qids are the unique ID for a file (like an inode */ | ||
| 116 | struct v9fs_qid { | ||
| 117 | u8 type; | ||
| 118 | u32 version; | ||
| 119 | u64 path; | ||
| 120 | }; | ||
| 121 | |||
| 122 | /* Plan 9 file metadata (stat) structure */ | ||
| 123 | struct v9fs_stat { | ||
| 124 | u16 size; | ||
| 125 | u16 type; | ||
| 126 | u32 dev; | ||
| 127 | struct v9fs_qid qid; | ||
| 128 | u32 mode; | ||
| 129 | u32 atime; | ||
| 130 | u32 mtime; | ||
| 131 | u64 length; | ||
| 132 | struct v9fs_str name; | ||
| 133 | struct v9fs_str uid; | ||
| 134 | struct v9fs_str gid; | ||
| 135 | struct v9fs_str muid; | ||
| 136 | struct v9fs_str extension; /* 9p2000.u extensions */ | ||
| 137 | u32 n_uid; /* 9p2000.u extensions */ | ||
| 138 | u32 n_gid; /* 9p2000.u extensions */ | ||
| 139 | u32 n_muid; /* 9p2000.u extensions */ | ||
| 140 | }; | ||
| 141 | |||
| 142 | /* file metadata (stat) structure used to create Twstat message | ||
| 143 | The is similar to v9fs_stat, but the strings don't point to | ||
| 144 | the same memory block and should be freed separately | ||
| 145 | */ | ||
| 146 | struct v9fs_wstat { | ||
| 147 | u16 size; | ||
| 148 | u16 type; | ||
| 149 | u32 dev; | ||
| 150 | struct v9fs_qid qid; | ||
| 151 | u32 mode; | ||
| 152 | u32 atime; | ||
| 153 | u32 mtime; | ||
| 154 | u64 length; | ||
| 155 | char *name; | ||
| 156 | char *uid; | ||
| 157 | char *gid; | ||
| 158 | char *muid; | ||
| 159 | char *extension; /* 9p2000.u extensions */ | ||
| 160 | u32 n_uid; /* 9p2000.u extensions */ | ||
| 161 | u32 n_gid; /* 9p2000.u extensions */ | ||
| 162 | u32 n_muid; /* 9p2000.u extensions */ | ||
| 163 | }; | ||
| 164 | |||
| 165 | /* Structures for Protocol Operations */ | ||
| 166 | |||
| 167 | struct Tversion { | ||
| 168 | u32 msize; | ||
| 169 | struct v9fs_str version; | ||
| 170 | }; | ||
| 171 | |||
| 172 | struct Rversion { | ||
| 173 | u32 msize; | ||
| 174 | struct v9fs_str version; | ||
| 175 | }; | ||
| 176 | |||
| 177 | struct Tauth { | ||
| 178 | u32 afid; | ||
| 179 | struct v9fs_str uname; | ||
| 180 | struct v9fs_str aname; | ||
| 181 | }; | ||
| 182 | |||
| 183 | struct Rauth { | ||
| 184 | struct v9fs_qid qid; | ||
| 185 | }; | ||
| 186 | |||
| 187 | struct Rerror { | ||
| 188 | struct v9fs_str error; | ||
| 189 | u32 errno; /* 9p2000.u extension */ | ||
| 190 | }; | ||
| 191 | |||
| 192 | struct Tflush { | ||
| 193 | u16 oldtag; | ||
| 194 | }; | ||
| 195 | |||
| 196 | struct Rflush { | ||
| 197 | }; | ||
| 198 | |||
| 199 | struct Tattach { | ||
| 200 | u32 fid; | ||
| 201 | u32 afid; | ||
| 202 | struct v9fs_str uname; | ||
| 203 | struct v9fs_str aname; | ||
| 204 | }; | ||
| 205 | |||
| 206 | struct Rattach { | ||
| 207 | struct v9fs_qid qid; | ||
| 208 | }; | ||
| 209 | |||
| 210 | struct Twalk { | ||
| 211 | u32 fid; | ||
| 212 | u32 newfid; | ||
| 213 | u16 nwname; | ||
| 214 | struct v9fs_str wnames[16]; | ||
| 215 | }; | ||
| 216 | |||
| 217 | struct Rwalk { | ||
| 218 | u16 nwqid; | ||
| 219 | struct v9fs_qid wqids[16]; | ||
| 220 | }; | ||
| 221 | |||
| 222 | struct Topen { | ||
| 223 | u32 fid; | ||
| 224 | u8 mode; | ||
| 225 | }; | ||
| 226 | |||
| 227 | struct Ropen { | ||
| 228 | struct v9fs_qid qid; | ||
| 229 | u32 iounit; | ||
| 230 | }; | ||
| 231 | |||
| 232 | struct Tcreate { | ||
| 233 | u32 fid; | ||
| 234 | struct v9fs_str name; | ||
| 235 | u32 perm; | ||
| 236 | u8 mode; | ||
| 237 | struct v9fs_str extension; | ||
| 238 | }; | ||
| 239 | |||
| 240 | struct Rcreate { | ||
| 241 | struct v9fs_qid qid; | ||
| 242 | u32 iounit; | ||
| 243 | }; | ||
| 244 | |||
| 245 | struct Tread { | ||
| 246 | u32 fid; | ||
| 247 | u64 offset; | ||
| 248 | u32 count; | ||
| 249 | }; | ||
| 250 | |||
| 251 | struct Rread { | ||
| 252 | u32 count; | ||
| 253 | u8 *data; | ||
| 254 | }; | ||
| 255 | |||
| 256 | struct Twrite { | ||
| 257 | u32 fid; | ||
| 258 | u64 offset; | ||
| 259 | u32 count; | ||
| 260 | u8 *data; | ||
| 261 | }; | ||
| 262 | |||
| 263 | struct Rwrite { | ||
| 264 | u32 count; | ||
| 265 | }; | ||
| 266 | |||
| 267 | struct Tclunk { | ||
| 268 | u32 fid; | ||
| 269 | }; | ||
| 270 | |||
| 271 | struct Rclunk { | ||
| 272 | }; | ||
| 273 | |||
| 274 | struct Tremove { | ||
| 275 | u32 fid; | ||
| 276 | }; | ||
| 277 | |||
| 278 | struct Rremove { | ||
| 279 | }; | ||
| 280 | |||
| 281 | struct Tstat { | ||
| 282 | u32 fid; | ||
| 283 | }; | ||
| 284 | |||
| 285 | struct Rstat { | ||
| 286 | struct v9fs_stat stat; | ||
| 287 | }; | ||
| 288 | |||
| 289 | struct Twstat { | ||
| 290 | u32 fid; | ||
| 291 | struct v9fs_stat stat; | ||
| 292 | }; | ||
| 293 | |||
| 294 | struct Rwstat { | ||
| 295 | }; | ||
| 296 | |||
| 297 | /* | ||
| 298 | * fcall is the primary packet structure | ||
| 299 | * | ||
| 300 | */ | ||
| 301 | |||
| 302 | struct v9fs_fcall { | ||
| 303 | u32 size; | ||
| 304 | u8 id; | ||
| 305 | u16 tag; | ||
| 306 | void *sdata; | ||
| 307 | |||
| 308 | union { | ||
| 309 | struct Tversion tversion; | ||
| 310 | struct Rversion rversion; | ||
| 311 | struct Tauth tauth; | ||
| 312 | struct Rauth rauth; | ||
| 313 | struct Rerror rerror; | ||
| 314 | struct Tflush tflush; | ||
| 315 | struct Rflush rflush; | ||
| 316 | struct Tattach tattach; | ||
| 317 | struct Rattach rattach; | ||
| 318 | struct Twalk twalk; | ||
| 319 | struct Rwalk rwalk; | ||
| 320 | struct Topen topen; | ||
| 321 | struct Ropen ropen; | ||
| 322 | struct Tcreate tcreate; | ||
| 323 | struct Rcreate rcreate; | ||
| 324 | struct Tread tread; | ||
| 325 | struct Rread rread; | ||
| 326 | struct Twrite twrite; | ||
| 327 | struct Rwrite rwrite; | ||
| 328 | struct Tclunk tclunk; | ||
| 329 | struct Rclunk rclunk; | ||
| 330 | struct Tremove tremove; | ||
| 331 | struct Rremove rremove; | ||
| 332 | struct Tstat tstat; | ||
| 333 | struct Rstat rstat; | ||
| 334 | struct Twstat twstat; | ||
| 335 | struct Rwstat rwstat; | ||
| 336 | } params; | ||
| 337 | }; | ||
| 338 | |||
| 339 | #define PRINT_FCALL_ERROR(s, fcall) dprintk(DEBUG_ERROR, "%s: %.*s\n", s, \ | ||
| 340 | fcall?fcall->params.rerror.error.len:0, \ | ||
| 341 | fcall?fcall->params.rerror.error.str:""); | ||
| 342 | |||
| 343 | int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize, | ||
| 344 | char *version, struct v9fs_fcall **rcall); | ||
| 345 | |||
| 346 | int v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname, | ||
| 347 | u32 fid, u32 afid, struct v9fs_fcall **rcall); | ||
| 348 | |||
| 349 | int v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid); | ||
| 350 | |||
| 351 | int v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid, | ||
| 352 | struct v9fs_fcall **rcall); | ||
| 353 | |||
| 354 | int v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid, | ||
| 355 | struct v9fs_wstat *wstat, struct v9fs_fcall **rcall); | ||
| 356 | |||
| 357 | int v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid, | ||
| 358 | char *name, struct v9fs_fcall **rcall); | ||
| 359 | |||
| 360 | int v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode, | ||
| 361 | struct v9fs_fcall **rcall); | ||
| 362 | |||
| 363 | int v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid, | ||
| 364 | struct v9fs_fcall **rcall); | ||
| 365 | |||
| 366 | int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, | ||
| 367 | u32 perm, u8 mode, char *extension, struct v9fs_fcall **rcall); | ||
| 368 | |||
| 369 | int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, | ||
| 370 | u64 offset, u32 count, struct v9fs_fcall **rcall); | ||
| 371 | |||
| 372 | int v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset, | ||
| 373 | u32 count, const char __user * data, | ||
| 374 | struct v9fs_fcall **rcall); | ||
| 375 | int v9fs_printfcall(char *, int, struct v9fs_fcall *, int); | ||
diff --git a/fs/9p/Makefile b/fs/9p/Makefile index 87897f84dfb6..bc7f0d1551e6 100644 --- a/fs/9p/Makefile +++ b/fs/9p/Makefile | |||
| @@ -1,18 +1,12 @@ | |||
| 1 | obj-$(CONFIG_9P_FS) := 9p.o | 1 | obj-$(CONFIG_9P_FS) := 9p.o |
| 2 | 2 | ||
| 3 | 9p-objs := \ | 3 | 9p-objs := \ |
| 4 | trans_fd.o \ | ||
| 5 | mux.o \ | ||
| 6 | fcall.o \ | ||
| 7 | conv.o \ | ||
| 8 | vfs_super.o \ | 4 | vfs_super.o \ |
| 9 | vfs_inode.o \ | 5 | vfs_inode.o \ |
| 10 | vfs_addr.o \ | 6 | vfs_addr.o \ |
| 11 | vfs_file.o \ | 7 | vfs_file.o \ |
| 12 | vfs_dir.o \ | 8 | vfs_dir.o \ |
| 13 | vfs_dentry.o \ | 9 | vfs_dentry.o \ |
| 14 | error.o \ | ||
| 15 | v9fs.o \ | 10 | v9fs.o \ |
| 16 | fid.o \ | 11 | fid.o \ |
| 17 | fcprint.o | ||
| 18 | 12 | ||
diff --git a/fs/9p/conv.h b/fs/9p/conv.h deleted file mode 100644 index dd5b6b1b610f..000000000000 --- a/fs/9p/conv.h +++ /dev/null | |||
| @@ -1,50 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/fs/9p/conv.h | ||
| 3 | * | ||
| 4 | * 9P protocol conversion definitions. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net> | ||
| 7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
| 8 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 | ||
| 12 | * as published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to: | ||
| 21 | * Free Software Foundation | ||
| 22 | * 51 Franklin Street, Fifth Floor | ||
| 23 | * Boston, MA 02111-1301 USA | ||
| 24 | * | ||
| 25 | */ | ||
| 26 | |||
| 27 | int v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat, | ||
| 28 | int extended); | ||
| 29 | int v9fs_deserialize_fcall(void *buf, u32 buflen, struct v9fs_fcall *rcall, | ||
| 30 | int extended); | ||
| 31 | |||
| 32 | void v9fs_set_tag(struct v9fs_fcall *fc, u16 tag); | ||
| 33 | |||
| 34 | struct v9fs_fcall *v9fs_create_tversion(u32 msize, char *version); | ||
| 35 | struct v9fs_fcall *v9fs_create_tattach(u32 fid, u32 afid, char *uname, | ||
| 36 | char *aname); | ||
| 37 | struct v9fs_fcall *v9fs_create_tflush(u16 oldtag); | ||
| 38 | struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, | ||
| 39 | char **wnames); | ||
| 40 | struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode); | ||
| 41 | struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, | ||
| 42 | char *extension, int extended); | ||
| 43 | struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count); | ||
| 44 | struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count, | ||
| 45 | const char __user *data); | ||
| 46 | struct v9fs_fcall *v9fs_create_tclunk(u32 fid); | ||
| 47 | struct v9fs_fcall *v9fs_create_tremove(u32 fid); | ||
| 48 | struct v9fs_fcall *v9fs_create_tstat(u32 fid); | ||
| 49 | struct v9fs_fcall *v9fs_create_twstat(u32 fid, struct v9fs_wstat *wstat, | ||
| 50 | int extended); | ||
diff --git a/fs/9p/debug.h b/fs/9p/debug.h deleted file mode 100644 index 4228c0bb3c32..000000000000 --- a/fs/9p/debug.h +++ /dev/null | |||
| @@ -1,77 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/fs/9p/debug.h - V9FS Debug Definitions | ||
| 3 | * | ||
| 4 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
| 5 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 | ||
| 9 | * as published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to: | ||
| 18 | * Free Software Foundation | ||
| 19 | * 51 Franklin Street, Fifth Floor | ||
| 20 | * Boston, MA 02111-1301 USA | ||
| 21 | * | ||
| 22 | */ | ||
| 23 | |||
| 24 | #define DEBUG_ERROR (1<<0) | ||
| 25 | #define DEBUG_CURRENT (1<<1) | ||
| 26 | #define DEBUG_9P (1<<2) | ||
| 27 | #define DEBUG_VFS (1<<3) | ||
| 28 | #define DEBUG_CONV (1<<4) | ||
| 29 | #define DEBUG_MUX (1<<5) | ||
| 30 | #define DEBUG_TRANS (1<<6) | ||
| 31 | #define DEBUG_SLABS (1<<7) | ||
| 32 | #define DEBUG_FCALL (1<<8) | ||
| 33 | |||
| 34 | #define DEBUG_DUMP_PKT 0 | ||
| 35 | |||
| 36 | extern int v9fs_debug_level; | ||
| 37 | |||
| 38 | #define dprintk(level, format, arg...) \ | ||
| 39 | do { \ | ||
| 40 | if((v9fs_debug_level & level)==level) \ | ||
| 41 | printk(KERN_NOTICE "-- %s (%d): " \ | ||
| 42 | format , __FUNCTION__, current->pid , ## arg); \ | ||
| 43 | } while(0) | ||
| 44 | |||
| 45 | #define eprintk(level, format, arg...) \ | ||
| 46 | do { \ | ||
| 47 | printk(level "v9fs: %s (%d): " \ | ||
| 48 | format , __FUNCTION__, current->pid , ## arg); \ | ||
| 49 | } while(0) | ||
| 50 | |||
| 51 | #if DEBUG_DUMP_PKT | ||
| 52 | static inline void dump_data(const unsigned char *data, unsigned int datalen) | ||
| 53 | { | ||
| 54 | int i, n; | ||
| 55 | char buf[5*8]; | ||
| 56 | |||
| 57 | n = 0; | ||
| 58 | i = 0; | ||
| 59 | while (i < datalen) { | ||
| 60 | n += snprintf(buf+n, sizeof(buf)-n, "%02x", data[i++]); | ||
| 61 | if (i%4 == 0) | ||
| 62 | n += snprintf(buf+n, sizeof(buf)-n, " "); | ||
| 63 | |||
| 64 | if (i%16 == 0) { | ||
| 65 | dprintk(DEBUG_ERROR, "%s\n", buf); | ||
| 66 | n = 0; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | dprintk(DEBUG_ERROR, "%s\n", buf); | ||
| 71 | } | ||
| 72 | #else /* DEBUG_DUMP_PKT */ | ||
| 73 | static inline void dump_data(const unsigned char *data, unsigned int datalen) | ||
| 74 | { | ||
| 75 | |||
| 76 | } | ||
| 77 | #endif /* DEBUG_DUMP_PKT */ | ||
diff --git a/fs/9p/error.c b/fs/9p/error.c deleted file mode 100644 index 0d7fa4e08812..000000000000 --- a/fs/9p/error.c +++ /dev/null | |||
| @@ -1,93 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/fs/9p/error.c | ||
| 3 | * | ||
| 4 | * Error string handling | ||
| 5 | * | ||
| 6 | * Plan 9 uses error strings, Unix uses error numbers. These functions | ||
| 7 | * try to help manage that and provide for dynamically adding error | ||
| 8 | * mappings. | ||
| 9 | * | ||
| 10 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
| 11 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or modify | ||
| 14 | * it under the terms of the GNU General Public License version 2 | ||
| 15 | * as published by the Free Software Foundation. | ||
| 16 | * | ||
| 17 | * This program is distributed in the hope that it will be useful, | ||
| 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 20 | * GNU General Public License for more details. | ||
| 21 | * | ||
| 22 | * You should have received a copy of the GNU General Public License | ||
| 23 | * along with this program; if not, write to: | ||
| 24 | * Free Software Foundation | ||
| 25 | * 51 Franklin Street, Fifth Floor | ||
| 26 | * Boston, MA 02111-1301 USA | ||
| 27 | * | ||
| 28 | */ | ||
| 29 | |||
| 30 | #include <linux/module.h> | ||
| 31 | |||
| 32 | #include <linux/list.h> | ||
| 33 | #include <linux/jhash.h> | ||
| 34 | |||
| 35 | #include "debug.h" | ||
| 36 | #include "error.h" | ||
| 37 | |||
| 38 | /** | ||
| 39 | * v9fs_error_init - preload | ||
| 40 | * @errstr: error string | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | |||
| 44 | int v9fs_error_init(void) | ||
| 45 | { | ||
| 46 | struct errormap *c; | ||
| 47 | int bucket; | ||
| 48 | |||
| 49 | /* initialize hash table */ | ||
| 50 | for (bucket = 0; bucket < ERRHASHSZ; bucket++) | ||
| 51 | INIT_HLIST_HEAD(&hash_errmap[bucket]); | ||
| 52 | |||
| 53 | /* load initial error map into hash table */ | ||
| 54 | for (c = errmap; c->name != NULL; c++) { | ||
| 55 | c->namelen = strlen(c->name); | ||
| 56 | bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ; | ||
| 57 | INIT_HLIST_NODE(&c->list); | ||
| 58 | hlist_add_head(&c->list, &hash_errmap[bucket]); | ||
| 59 | } | ||
| 60 | |||
| 61 | return 1; | ||
| 62 | } | ||
| 63 | |||
| 64 | /** | ||
| 65 | * errstr2errno - convert error string to error number | ||
| 66 | * @errstr: error string | ||
| 67 | * | ||
| 68 | */ | ||
| 69 | |||
| 70 | int v9fs_errstr2errno(char *errstr, int len) | ||
| 71 | { | ||
| 72 | int errno = 0; | ||
| 73 | struct hlist_node *p = NULL; | ||
| 74 | struct errormap *c = NULL; | ||
| 75 | int bucket = jhash(errstr, len, 0) % ERRHASHSZ; | ||
| 76 | |||
| 77 | hlist_for_each_entry(c, p, &hash_errmap[bucket], list) { | ||
| 78 | if (c->namelen==len && !memcmp(c->name, errstr, len)) { | ||
| 79 | errno = c->val; | ||
| 80 | break; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | |||
| 84 | if (errno == 0) { | ||
| 85 | /* TODO: if error isn't found, add it dynamically */ | ||
| 86 | errstr[len] = 0; | ||
| 87 | printk(KERN_ERR "%s: errstr :%s: not found\n", __FUNCTION__, | ||
| 88 | errstr); | ||
| 89 | errno = 1; | ||
| 90 | } | ||
| 91 | |||
| 92 | return -errno; | ||
| 93 | } | ||
diff --git a/fs/9p/fcall.c b/fs/9p/fcall.c deleted file mode 100644 index dc336a67592f..000000000000 --- a/fs/9p/fcall.c +++ /dev/null | |||
| @@ -1,427 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/fs/9p/fcall.c | ||
| 3 | * | ||
| 4 | * This file contains functions to perform synchronous 9P calls | ||
| 5 | * | ||
| 6 | * Copyright (C) 2004 by Latchesar Ionkov <lucho@ionkov.net> | ||
| 7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
| 8 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 | ||
| 12 | * as published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to: | ||
| 21 | * Free Software Foundation | ||
| 22 | * 51 Franklin Street, Fifth Floor | ||
| 23 | * Boston, MA 02111-1301 USA | ||
| 24 | * | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/errno.h> | ||
| 29 | #include <linux/fs.h> | ||
| 30 | #include <linux/sched.h> | ||
| 31 | #include <linux/idr.h> | ||
| 32 | |||
| 33 | #include "debug.h" | ||
| 34 | #include "v9fs.h" | ||
| 35 | #include "9p.h" | ||
| 36 | #include "conv.h" | ||
| 37 | #include "mux.h" | ||
| 38 | |||
| 39 | /** | ||
| 40 | * v9fs_t_version - negotiate protocol parameters with sever | ||
| 41 | * @v9ses: 9P2000 session information | ||
| 42 | * @msize: requested max size packet | ||
| 43 | * @version: requested version.extension string | ||
| 44 | * @fcall: pointer to response fcall pointer | ||
| 45 | * | ||
| 46 | */ | ||
| 47 | |||
| 48 | int | ||
| 49 | v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize, | ||
| 50 | char *version, struct v9fs_fcall **rcp) | ||
| 51 | { | ||
| 52 | int ret; | ||
| 53 | struct v9fs_fcall *tc; | ||
| 54 | |||
| 55 | dprintk(DEBUG_9P, "msize: %d version: %s\n", msize, version); | ||
| 56 | tc = v9fs_create_tversion(msize, version); | ||
| 57 | |||
| 58 | if (!IS_ERR(tc)) { | ||
| 59 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
| 60 | kfree(tc); | ||
| 61 | } else | ||
| 62 | ret = PTR_ERR(tc); | ||
| 63 | |||
| 64 | return ret; | ||
| 65 | } | ||
| 66 | |||
| 67 | /** | ||
| 68 | * v9fs_t_attach - mount the server | ||
| 69 | * @v9ses: 9P2000 session information | ||
| 70 | * @uname: user name doing the attach | ||
| 71 | * @aname: remote name being attached to | ||
| 72 | * @fid: mount fid to attatch to root node | ||
| 73 | * @afid: authentication fid (in this case result key) | ||
| 74 | * @fcall: pointer to response fcall pointer | ||
| 75 | * | ||
| 76 | */ | ||
| 77 | |||
| 78 | int | ||
| 79 | v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname, | ||
| 80 | u32 fid, u32 afid, struct v9fs_fcall **rcp) | ||
| 81 | { | ||
| 82 | int ret; | ||
| 83 | struct v9fs_fcall* tc; | ||
| 84 | |||
| 85 | dprintk(DEBUG_9P, "uname '%s' aname '%s' fid %d afid %d\n", uname, | ||
| 86 | aname, fid, afid); | ||
| 87 | |||
| 88 | tc = v9fs_create_tattach(fid, afid, uname, aname); | ||
| 89 | if (!IS_ERR(tc)) { | ||
| 90 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
| 91 | kfree(tc); | ||
| 92 | } else | ||
| 93 | ret = PTR_ERR(tc); | ||
| 94 | |||
| 95 | return ret; | ||
| 96 | } | ||
| 97 | |||
| 98 | static void v9fs_t_clunk_cb(void *a, struct v9fs_fcall *tc, | ||
| 99 | struct v9fs_fcall *rc, int err) | ||
| 100 | { | ||
| 101 | int fid, id; | ||
| 102 | struct v9fs_session_info *v9ses; | ||
| 103 | |||
| 104 | id = 0; | ||
| 105 | fid = tc->params.tclunk.fid; | ||
| 106 | if (rc) | ||
| 107 | id = rc->id; | ||
| 108 | |||
| 109 | kfree(tc); | ||
| 110 | kfree(rc); | ||
| 111 | if (id == RCLUNK) { | ||
| 112 | v9ses = a; | ||
| 113 | v9fs_put_idpool(fid, &v9ses->fidpool); | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | /** | ||
| 118 | * v9fs_t_clunk - release a fid (finish a transaction) | ||
| 119 | * @v9ses: 9P2000 session information | ||
| 120 | * @fid: fid to release | ||
| 121 | * @fcall: pointer to response fcall pointer | ||
| 122 | * | ||
| 123 | */ | ||
| 124 | |||
| 125 | int | ||
| 126 | v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid) | ||
| 127 | { | ||
| 128 | int ret; | ||
| 129 | struct v9fs_fcall *tc, *rc; | ||
| 130 | |||
| 131 | dprintk(DEBUG_9P, "fid %d\n", fid); | ||
| 132 | |||
| 133 | rc = NULL; | ||
| 134 | tc = v9fs_create_tclunk(fid); | ||
| 135 | if (!IS_ERR(tc)) | ||
| 136 | ret = v9fs_mux_rpc(v9ses->mux, tc, &rc); | ||
| 137 | else | ||
| 138 | ret = PTR_ERR(tc); | ||
| 139 | |||
| 140 | if (ret) | ||
| 141 | dprintk(DEBUG_ERROR, "failed fid %d err %d\n", fid, ret); | ||
| 142 | |||
| 143 | v9fs_t_clunk_cb(v9ses, tc, rc, ret); | ||
| 144 | return ret; | ||
| 145 | } | ||
| 146 | |||
| 147 | #if 0 | ||
| 148 | /** | ||
| 149 | * v9fs_v9fs_t_flush - flush a pending transaction | ||
| 150 | * @v9ses: 9P2000 session information | ||
| 151 | * @tag: tag to release | ||
| 152 | * | ||
| 153 | */ | ||
| 154 | int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag) | ||
| 155 | { | ||
| 156 | int ret; | ||
| 157 | struct v9fs_fcall *tc; | ||
| 158 | |||
| 159 | dprintk(DEBUG_9P, "oldtag %d\n", oldtag); | ||
| 160 | |||
| 161 | tc = v9fs_create_tflush(oldtag); | ||
| 162 | if (!IS_ERR(tc)) { | ||
| 163 | ret = v9fs_mux_rpc(v9ses->mux, tc, NULL); | ||
| 164 | kfree(tc); | ||
| 165 | } else | ||
| 166 | ret = PTR_ERR(tc); | ||
| 167 | |||
| 168 | return ret; | ||
| 169 | } | ||
| 170 | #endif | ||
| 171 | |||
| 172 | /** | ||
| 173 | * v9fs_t_stat - read a file's meta-data | ||
| 174 | * @v9ses: 9P2000 session information | ||
| 175 | * @fid: fid pointing to file or directory to get info about | ||
| 176 | * @fcall: pointer to response fcall | ||
| 177 | * | ||
| 178 | */ | ||
| 179 | |||
| 180 | int | ||
| 181 | v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid, struct v9fs_fcall **rcp) | ||
| 182 | { | ||
| 183 | int ret; | ||
| 184 | struct v9fs_fcall *tc; | ||
| 185 | |||
| 186 | dprintk(DEBUG_9P, "fid %d\n", fid); | ||
| 187 | |||
| 188 | ret = -ENOMEM; | ||
| 189 | tc = v9fs_create_tstat(fid); | ||
| 190 | if (!IS_ERR(tc)) { | ||
| 191 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
| 192 | kfree(tc); | ||
| 193 | } else | ||
| 194 | ret = PTR_ERR(tc); | ||
| 195 | |||
| 196 | return ret; | ||
| 197 | } | ||
| 198 | |||
| 199 | /** | ||
| 200 | * v9fs_t_wstat - write a file's meta-data | ||
| 201 | * @v9ses: 9P2000 session information | ||
| 202 | * @fid: fid pointing to file or directory to write info about | ||
| 203 | * @stat: metadata | ||
| 204 | * @fcall: pointer to response fcall | ||
| 205 | * | ||
| 206 | */ | ||
| 207 | |||
| 208 | int | ||
| 209 | v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid, | ||
| 210 | struct v9fs_wstat *wstat, struct v9fs_fcall **rcp) | ||
| 211 | { | ||
| 212 | int ret; | ||
| 213 | struct v9fs_fcall *tc; | ||
| 214 | |||
| 215 | dprintk(DEBUG_9P, "fid %d\n", fid); | ||
| 216 | |||
| 217 | tc = v9fs_create_twstat(fid, wstat, v9ses->extended); | ||
| 218 | if (!IS_ERR(tc)) { | ||
| 219 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
| 220 | kfree(tc); | ||
| 221 | } else | ||
| 222 | ret = PTR_ERR(tc); | ||
| 223 | |||
| 224 | return ret; | ||
| 225 | } | ||
| 226 | |||
| 227 | /** | ||
| 228 | * v9fs_t_walk - walk a fid to a new file or directory | ||
| 229 | * @v9ses: 9P2000 session information | ||
| 230 | * @fid: fid to walk | ||
| 231 | * @newfid: new fid (for clone operations) | ||
| 232 | * @name: path to walk fid to | ||
| 233 | * @fcall: pointer to response fcall | ||
| 234 | * | ||
| 235 | */ | ||
| 236 | |||
| 237 | /* TODO: support multiple walk */ | ||
| 238 | |||
| 239 | int | ||
| 240 | v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid, | ||
| 241 | char *name, struct v9fs_fcall **rcp) | ||
| 242 | { | ||
| 243 | int ret; | ||
| 244 | struct v9fs_fcall *tc; | ||
| 245 | int nwname; | ||
| 246 | |||
| 247 | dprintk(DEBUG_9P, "fid %d newfid %d wname '%s'\n", fid, newfid, name); | ||
| 248 | |||
| 249 | if (name) | ||
| 250 | nwname = 1; | ||
| 251 | else | ||
| 252 | nwname = 0; | ||
| 253 | |||
| 254 | tc = v9fs_create_twalk(fid, newfid, nwname, &name); | ||
| 255 | if (!IS_ERR(tc)) { | ||
| 256 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
| 257 | kfree(tc); | ||
| 258 | } else | ||
| 259 | ret = PTR_ERR(tc); | ||
| 260 | |||
| 261 | return ret; | ||
| 262 | } | ||
| 263 | |||
| 264 | /** | ||
| 265 | * v9fs_t_open - open a file | ||
| 266 | * | ||
| 267 | * @v9ses - 9P2000 session information | ||
| 268 | * @fid - fid to open | ||
| 269 | * @mode - mode to open file (R, RW, etc) | ||
| 270 | * @fcall - pointer to response fcall | ||
| 271 | * | ||
| 272 | */ | ||
| 273 | |||
| 274 | int | ||
| 275 | v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode, | ||
| 276 | struct v9fs_fcall **rcp) | ||
| 277 | { | ||
| 278 | int ret; | ||
| 279 | struct v9fs_fcall *tc; | ||
| 280 | |||
| 281 | dprintk(DEBUG_9P, "fid %d mode %d\n", fid, mode); | ||
| 282 | |||
| 283 | tc = v9fs_create_topen(fid, mode); | ||
| 284 | if (!IS_ERR(tc)) { | ||
| 285 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
| 286 | kfree(tc); | ||
| 287 | } else | ||
| 288 | ret = PTR_ERR(tc); | ||
| 289 | |||
| 290 | return ret; | ||
| 291 | } | ||
| 292 | |||
| 293 | /** | ||
| 294 | * v9fs_t_remove - remove a file or directory | ||
| 295 | * @v9ses: 9P2000 session information | ||
| 296 | * @fid: fid to remove | ||
| 297 | * @fcall: pointer to response fcall | ||
| 298 | * | ||
| 299 | */ | ||
| 300 | |||
| 301 | int | ||
| 302 | v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid, | ||
| 303 | struct v9fs_fcall **rcp) | ||
| 304 | { | ||
| 305 | int ret; | ||
| 306 | struct v9fs_fcall *tc; | ||
| 307 | |||
| 308 | dprintk(DEBUG_9P, "fid %d\n", fid); | ||
| 309 | |||
| 310 | tc = v9fs_create_tremove(fid); | ||
| 311 | if (!IS_ERR(tc)) { | ||
| 312 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
| 313 | kfree(tc); | ||
| 314 | } else | ||
| 315 | ret = PTR_ERR(tc); | ||
| 316 | |||
| 317 | return ret; | ||
| 318 | } | ||
| 319 | |||
| 320 | /** | ||
| 321 | * v9fs_t_create - create a file or directory | ||
| 322 | * @v9ses: 9P2000 session information | ||
| 323 | * @fid: fid to create | ||
| 324 | * @name: name of the file or directory to create | ||
| 325 | * @perm: permissions to create with | ||
| 326 | * @mode: mode to open file (R, RW, etc) | ||
| 327 | * @fcall: pointer to response fcall | ||
| 328 | * | ||
| 329 | */ | ||
| 330 | |||
| 331 | int | ||
| 332 | v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, u32 perm, | ||
| 333 | u8 mode, char *extension, struct v9fs_fcall **rcp) | ||
| 334 | { | ||
| 335 | int ret; | ||
| 336 | struct v9fs_fcall *tc; | ||
| 337 | |||
| 338 | dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n", | ||
| 339 | fid, name, perm, mode); | ||
| 340 | |||
| 341 | tc = v9fs_create_tcreate(fid, name, perm, mode, extension, | ||
| 342 | v9ses->extended); | ||
| 343 | |||
| 344 | if (!IS_ERR(tc)) { | ||
| 345 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
| 346 | kfree(tc); | ||
| 347 | } else | ||
| 348 | ret = PTR_ERR(tc); | ||
| 349 | |||
| 350 | return ret; | ||
| 351 | } | ||
| 352 | |||
| 353 | /** | ||
| 354 | * v9fs_t_read - read data | ||
| 355 | * @v9ses: 9P2000 session information | ||
| 356 | * @fid: fid to read from | ||
| 357 | * @offset: offset to start read at | ||
| 358 | * @count: how many bytes to read | ||
| 359 | * @fcall: pointer to response fcall (with data) | ||
| 360 | * | ||
| 361 | */ | ||
| 362 | |||
| 363 | int | ||
| 364 | v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, u64 offset, | ||
| 365 | u32 count, struct v9fs_fcall **rcp) | ||
| 366 | { | ||
| 367 | int ret; | ||
| 368 | struct v9fs_fcall *tc, *rc; | ||
| 369 | |||
| 370 | dprintk(DEBUG_9P, "fid %d offset 0x%llux count 0x%x\n", fid, | ||
| 371 | (long long unsigned) offset, count); | ||
| 372 | |||
| 373 | tc = v9fs_create_tread(fid, offset, count); | ||
| 374 | if (!IS_ERR(tc)) { | ||
| 375 | ret = v9fs_mux_rpc(v9ses->mux, tc, &rc); | ||
| 376 | if (!ret) | ||
| 377 | ret = rc->params.rread.count; | ||
| 378 | if (rcp) | ||
| 379 | *rcp = rc; | ||
| 380 | else | ||
| 381 | kfree(rc); | ||
| 382 | |||
| 383 | kfree(tc); | ||
| 384 | } else | ||
| 385 | ret = PTR_ERR(tc); | ||
| 386 | |||
| 387 | return ret; | ||
| 388 | } | ||
| 389 | |||
| 390 | /** | ||
| 391 | * v9fs_t_write - write data | ||
| 392 | * @v9ses: 9P2000 session information | ||
| 393 | * @fid: fid to write to | ||
| 394 | * @offset: offset to start write at | ||
| 395 | * @count: how many bytes to write | ||
| 396 | * @fcall: pointer to response fcall | ||
| 397 | * | ||
| 398 | */ | ||
| 399 | |||
| 400 | int | ||
| 401 | v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset, u32 count, | ||
| 402 | const char __user *data, struct v9fs_fcall **rcp) | ||
| 403 | { | ||
| 404 | int ret; | ||
| 405 | struct v9fs_fcall *tc, *rc; | ||
| 406 | |||
| 407 | dprintk(DEBUG_9P, "fid %d offset 0x%llux count 0x%x\n", fid, | ||
| 408 | (long long unsigned) offset, count); | ||
| 409 | |||
| 410 | tc = v9fs_create_twrite(fid, offset, count, data); | ||
| 411 | if (!IS_ERR(tc)) { | ||
| 412 | ret = v9fs_mux_rpc(v9ses->mux, tc, &rc); | ||
| 413 | |||
| 414 | if (!ret) | ||
| 415 | ret = rc->params.rwrite.count; | ||
| 416 | if (rcp) | ||
| 417 | *rcp = rc; | ||
| 418 | else | ||
| 419 | kfree(rc); | ||
| 420 | |||
| 421 | kfree(tc); | ||
| 422 | } else | ||
| 423 | ret = PTR_ERR(tc); | ||
| 424 | |||
| 425 | return ret; | ||
| 426 | } | ||
| 427 | |||
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 90419715c7e9..08fa320b7e6d 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
| @@ -26,10 +26,10 @@ | |||
| 26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
| 27 | #include <linux/idr.h> | 27 | #include <linux/idr.h> |
| 28 | #include <asm/semaphore.h> | 28 | #include <asm/semaphore.h> |
| 29 | #include <net/9p/9p.h> | ||
| 30 | #include <net/9p/client.h> | ||
| 29 | 31 | ||
| 30 | #include "debug.h" | ||
| 31 | #include "v9fs.h" | 32 | #include "v9fs.h" |
| 32 | #include "9p.h" | ||
| 33 | #include "v9fs_vfs.h" | 33 | #include "v9fs_vfs.h" |
| 34 | #include "fid.h" | 34 | #include "fid.h" |
| 35 | 35 | ||
| @@ -40,67 +40,29 @@ | |||
| 40 | * | 40 | * |
| 41 | */ | 41 | */ |
| 42 | 42 | ||
| 43 | int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry) | 43 | int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid) |
| 44 | { | 44 | { |
| 45 | struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; | 45 | struct v9fs_dentry *dent; |
| 46 | dprintk(DEBUG_9P, "fid %d (%p) dentry %s (%p)\n", fid->fid, fid, | ||
| 47 | dentry->d_iname, dentry); | ||
| 48 | if (dentry->d_fsdata == NULL) { | ||
| 49 | dentry->d_fsdata = | ||
| 50 | kmalloc(sizeof(struct list_head), GFP_KERNEL); | ||
| 51 | if (dentry->d_fsdata == NULL) { | ||
| 52 | dprintk(DEBUG_ERROR, "Out of memory\n"); | ||
| 53 | return -ENOMEM; | ||
| 54 | } | ||
| 55 | fid_list = (struct list_head *)dentry->d_fsdata; | ||
| 56 | INIT_LIST_HEAD(fid_list); /* Initialize list head */ | ||
| 57 | } | ||
| 58 | 46 | ||
| 59 | fid->uid = current->uid; | 47 | P9_DPRINTK(P9_DEBUG_VFS, "fid %d dentry %s\n", |
| 60 | list_add(&fid->list, fid_list); | 48 | fid->fid, dentry->d_iname); |
| 61 | return 0; | ||
| 62 | } | ||
| 63 | 49 | ||
| 64 | /** | 50 | dent = dentry->d_fsdata; |
| 65 | * v9fs_fid_create - allocate a FID structure | 51 | if (!dent) { |
| 66 | * @dentry - dentry to link newly created fid to | 52 | dent = kmalloc(sizeof(struct v9fs_dentry), GFP_KERNEL); |
| 67 | * | 53 | if (!dent) |
| 68 | */ | 54 | return -ENOMEM; |
| 69 | |||
| 70 | struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *v9ses, int fid) | ||
| 71 | { | ||
| 72 | struct v9fs_fid *new; | ||
| 73 | 55 | ||
| 74 | dprintk(DEBUG_9P, "fid create fid %d\n", fid); | 56 | spin_lock_init(&dent->lock); |
| 75 | new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); | 57 | INIT_LIST_HEAD(&dent->fidlist); |
| 76 | if (new == NULL) { | 58 | dentry->d_fsdata = dent; |
| 77 | dprintk(DEBUG_ERROR, "Out of Memory\n"); | ||
| 78 | return ERR_PTR(-ENOMEM); | ||
| 79 | } | 59 | } |
| 80 | 60 | ||
| 81 | new->fid = fid; | 61 | spin_lock(&dent->lock); |
| 82 | new->v9ses = v9ses; | 62 | list_add(&fid->dlist, &dent->fidlist); |
| 83 | new->fidopen = 0; | 63 | spin_unlock(&dent->lock); |
| 84 | new->fidclunked = 0; | ||
| 85 | new->iounit = 0; | ||
| 86 | new->rdir_pos = 0; | ||
| 87 | new->rdir_fcall = NULL; | ||
| 88 | init_MUTEX(&new->lock); | ||
| 89 | INIT_LIST_HEAD(&new->list); | ||
| 90 | |||
| 91 | return new; | ||
| 92 | } | ||
| 93 | |||
| 94 | /** | ||
| 95 | * v9fs_fid_destroy - deallocate a FID structure | ||
| 96 | * @fid: fid to destroy | ||
| 97 | * | ||
| 98 | */ | ||
| 99 | 64 | ||
| 100 | void v9fs_fid_destroy(struct v9fs_fid *fid) | 65 | return 0; |
| 101 | { | ||
| 102 | list_del(&fid->list); | ||
| 103 | kfree(fid); | ||
| 104 | } | 66 | } |
| 105 | 67 | ||
| 106 | /** | 68 | /** |
| @@ -114,30 +76,42 @@ void v9fs_fid_destroy(struct v9fs_fid *fid) | |||
| 114 | * | 76 | * |
| 115 | */ | 77 | */ |
| 116 | 78 | ||
| 117 | struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry) | 79 | struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) |
| 118 | { | 80 | { |
| 119 | struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; | 81 | struct v9fs_dentry *dent; |
| 120 | struct v9fs_fid *return_fid = NULL; | 82 | struct p9_fid *fid; |
| 121 | 83 | ||
| 122 | dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry); | 84 | P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); |
| 123 | 85 | dent = dentry->d_fsdata; | |
| 124 | if (fid_list) | 86 | if (dent) |
| 125 | return_fid = list_entry(fid_list->next, struct v9fs_fid, list); | 87 | fid = list_entry(dent->fidlist.next, struct p9_fid, dlist); |
| 88 | else | ||
| 89 | fid = ERR_PTR(-EBADF); | ||
| 90 | |||
| 91 | P9_DPRINTK(P9_DEBUG_VFS, " fid: %p\n", fid); | ||
| 92 | return fid; | ||
| 93 | } | ||
| 126 | 94 | ||
| 127 | if (!return_fid) { | 95 | struct p9_fid *v9fs_fid_lookup_remove(struct dentry *dentry) |
| 128 | dprintk(DEBUG_ERROR, "Couldn't find a fid in dentry\n"); | 96 | { |
| 129 | return_fid = ERR_PTR(-EBADF); | 97 | struct p9_fid *fid; |
| 98 | struct v9fs_dentry *dent; | ||
| 99 | |||
| 100 | dent = dentry->d_fsdata; | ||
| 101 | fid = v9fs_fid_lookup(dentry); | ||
| 102 | if (!IS_ERR(fid)) { | ||
| 103 | spin_lock(&dent->lock); | ||
| 104 | list_del(&fid->dlist); | ||
| 105 | spin_unlock(&dent->lock); | ||
| 130 | } | 106 | } |
| 131 | 107 | ||
| 132 | if(down_interruptible(&return_fid->lock)) | 108 | return fid; |
| 133 | return ERR_PTR(-EINTR); | ||
| 134 | |||
| 135 | return return_fid; | ||
| 136 | } | 109 | } |
| 137 | 110 | ||
| 111 | |||
| 138 | /** | 112 | /** |
| 139 | * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and | 113 | * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and |
| 140 | * release it | 114 | * release it |
| 141 | * @dentry: dentry to look for fid in | 115 | * @dentry: dentry to look for fid in |
| 142 | * | 116 | * |
| 143 | * find a fid in the dentry and then clone to a new private fid | 117 | * find a fid in the dentry and then clone to a new private fid |
| @@ -146,49 +120,15 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry) | |||
| 146 | * | 120 | * |
| 147 | */ | 121 | */ |
| 148 | 122 | ||
| 149 | struct v9fs_fid *v9fs_fid_clone(struct dentry *dentry) | 123 | struct p9_fid *v9fs_fid_clone(struct dentry *dentry) |
| 150 | { | 124 | { |
| 151 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); | 125 | struct p9_fid *ofid, *fid; |
| 152 | struct v9fs_fid *base_fid, *new_fid = ERR_PTR(-EBADF); | ||
| 153 | struct v9fs_fcall *fcall = NULL; | ||
| 154 | int fid, err; | ||
| 155 | |||
| 156 | base_fid = v9fs_fid_lookup(dentry); | ||
| 157 | |||
| 158 | if(IS_ERR(base_fid)) | ||
| 159 | return base_fid; | ||
| 160 | |||
| 161 | if(base_fid) { /* clone fid */ | ||
| 162 | fid = v9fs_get_idpool(&v9ses->fidpool); | ||
| 163 | if (fid < 0) { | ||
| 164 | eprintk(KERN_WARNING, "newfid fails!\n"); | ||
| 165 | new_fid = ERR_PTR(-ENOSPC); | ||
| 166 | goto Release_Fid; | ||
| 167 | } | ||
| 168 | |||
| 169 | err = v9fs_t_walk(v9ses, base_fid->fid, fid, NULL, &fcall); | ||
| 170 | if (err < 0) { | ||
| 171 | dprintk(DEBUG_ERROR, "clone walk didn't work\n"); | ||
| 172 | v9fs_put_idpool(fid, &v9ses->fidpool); | ||
| 173 | new_fid = ERR_PTR(err); | ||
| 174 | goto Free_Fcall; | ||
| 175 | } | ||
| 176 | new_fid = v9fs_fid_create(v9ses, fid); | ||
| 177 | if (new_fid == NULL) { | ||
| 178 | dprintk(DEBUG_ERROR, "out of memory\n"); | ||
| 179 | new_fid = ERR_PTR(-ENOMEM); | ||
| 180 | } | ||
| 181 | Free_Fcall: | ||
| 182 | kfree(fcall); | ||
| 183 | } | ||
| 184 | 126 | ||
| 185 | Release_Fid: | 127 | P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); |
| 186 | up(&base_fid->lock); | 128 | ofid = v9fs_fid_lookup(dentry); |
| 187 | return new_fid; | 129 | if (IS_ERR(ofid)) |
| 188 | } | 130 | return ofid; |
| 189 | 131 | ||
| 190 | void v9fs_fid_clunk(struct v9fs_session_info *v9ses, struct v9fs_fid *fid) | 132 | fid = p9_client_walk(ofid, 0, NULL, 1); |
| 191 | { | 133 | return fid; |
| 192 | v9fs_t_clunk(v9ses, fid->fid); | ||
| 193 | v9fs_fid_destroy(fid); | ||
| 194 | } | 134 | } |
diff --git a/fs/9p/fid.h b/fs/9p/fid.h index 48fc170c26c8..47a0ba742872 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h | |||
| @@ -22,41 +22,12 @@ | |||
| 22 | 22 | ||
| 23 | #include <linux/list.h> | 23 | #include <linux/list.h> |
| 24 | 24 | ||
| 25 | #define FID_OP 0 | 25 | struct v9fs_dentry { |
| 26 | #define FID_WALK 1 | 26 | spinlock_t lock; /* protect fidlist */ |
| 27 | #define FID_CREATE 2 | 27 | struct list_head fidlist; |
| 28 | |||
| 29 | struct v9fs_fid { | ||
| 30 | struct list_head list; /* list of fids associated with a dentry */ | ||
| 31 | struct list_head active; /* XXX - debug */ | ||
| 32 | |||
| 33 | struct semaphore lock; | ||
| 34 | |||
| 35 | u32 fid; | ||
| 36 | unsigned char fidopen; /* set when fid is opened */ | ||
| 37 | unsigned char fidclunked; /* set when fid has already been clunked */ | ||
| 38 | |||
| 39 | struct v9fs_qid qid; | ||
| 40 | u32 iounit; | ||
| 41 | |||
| 42 | /* readdir stuff */ | ||
| 43 | int rdir_fpos; | ||
| 44 | loff_t rdir_pos; | ||
| 45 | struct v9fs_fcall *rdir_fcall; | ||
| 46 | |||
| 47 | /* management stuff */ | ||
| 48 | uid_t uid; /* user associated with this fid */ | ||
| 49 | |||
| 50 | /* private data */ | ||
| 51 | struct file *filp; /* backpointer to File struct for open files */ | ||
| 52 | struct v9fs_session_info *v9ses; /* session info for this FID */ | ||
| 53 | }; | 28 | }; |
| 54 | 29 | ||
| 55 | struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry); | 30 | struct p9_fid *v9fs_fid_lookup(struct dentry *dentry); |
| 56 | struct v9fs_fid *v9fs_fid_get_created(struct dentry *); | 31 | struct p9_fid *v9fs_fid_lookup_remove(struct dentry *dentry); |
| 57 | void v9fs_fid_destroy(struct v9fs_fid *fid); | 32 | struct p9_fid *v9fs_fid_clone(struct dentry *dentry); |
| 58 | struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *, int fid); | 33 | int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid); |
| 59 | int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry); | ||
| 60 | struct v9fs_fid *v9fs_fid_clone(struct dentry *dentry); | ||
| 61 | void v9fs_fid_clunk(struct v9fs_session_info *v9ses, struct v9fs_fid *fid); | ||
| 62 | |||
diff --git a/fs/9p/trans_fd.c b/fs/9p/trans_fd.c deleted file mode 100644 index 34d43355beb7..000000000000 --- a/fs/9p/trans_fd.c +++ /dev/null | |||
| @@ -1,308 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/fs/9p/trans_fd.c | ||
| 3 | * | ||
| 4 | * Fd transport layer. Includes deprecated socket layer. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2006 by Russ Cox <rsc@swtch.com> | ||
| 7 | * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net> | ||
| 8 | * Copyright (C) 2004-2005 by Eric Van Hensbergen <ericvh@gmail.com> | ||
| 9 | * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 | ||
| 13 | * as published by the Free Software Foundation. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to: | ||
| 22 | * Free Software Foundation | ||
| 23 | * 51 Franklin Street, Fifth Floor | ||
| 24 | * Boston, MA 02111-1301 USA | ||
| 25 | * | ||
| 26 | */ | ||
| 27 | |||
| 28 | #include <linux/in.h> | ||
| 29 | #include <linux/module.h> | ||
| 30 | #include <linux/net.h> | ||
| 31 | #include <linux/ipv6.h> | ||
| 32 | #include <linux/errno.h> | ||
| 33 | #include <linux/kernel.h> | ||
| 34 | #include <linux/un.h> | ||
| 35 | #include <asm/uaccess.h> | ||
| 36 | #include <linux/inet.h> | ||
| 37 | #include <linux/idr.h> | ||
| 38 | #include <linux/file.h> | ||
| 39 | |||
| 40 | #include "debug.h" | ||
| 41 | #include "v9fs.h" | ||
| 42 | #include "transport.h" | ||
| 43 | |||
| 44 | #define V9FS_PORT 564 | ||
| 45 | |||
| 46 | struct v9fs_trans_fd { | ||
| 47 | struct file *rd; | ||
| 48 | struct file *wr; | ||
| 49 | }; | ||
| 50 | |||
| 51 | /** | ||
| 52 | * v9fs_fd_read- read from a fd | ||
| 53 | * @v9ses: session information | ||
| 54 | * @v: buffer to receive data into | ||
| 55 | * @len: size of receive buffer | ||
| 56 | * | ||
| 57 | */ | ||
| 58 | static int v9fs_fd_read(struct v9fs_transport *trans, void *v, int len) | ||
| 59 | { | ||
| 60 | int ret; | ||
| 61 | struct v9fs_trans_fd *ts; | ||
| 62 | |||
| 63 | if (!trans || trans->status == Disconnected || !(ts = trans->priv)) | ||
| 64 | return -EREMOTEIO; | ||
| 65 | |||
| 66 | if (!(ts->rd->f_flags & O_NONBLOCK)) | ||
| 67 | dprintk(DEBUG_ERROR, "blocking read ...\n"); | ||
| 68 | |||
| 69 | ret = kernel_read(ts->rd, ts->rd->f_pos, v, len); | ||
| 70 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) | ||
| 71 | trans->status = Disconnected; | ||
| 72 | return ret; | ||
| 73 | } | ||
| 74 | |||
| 75 | /** | ||
| 76 | * v9fs_fd_write - write to a socket | ||
| 77 | * @v9ses: session information | ||
| 78 | * @v: buffer to send data from | ||
| 79 | * @len: size of send buffer | ||
| 80 | * | ||
| 81 | */ | ||
| 82 | static int v9fs_fd_write(struct v9fs_transport *trans, void *v, int len) | ||
| 83 | { | ||
| 84 | int ret; | ||
| 85 | mm_segment_t oldfs; | ||
| 86 | struct v9fs_trans_fd *ts; | ||
| 87 | |||
| 88 | if (!trans || trans->status == Disconnected || !(ts = trans->priv)) | ||
| 89 | return -EREMOTEIO; | ||
| 90 | |||
| 91 | if (!(ts->wr->f_flags & O_NONBLOCK)) | ||
| 92 | dprintk(DEBUG_ERROR, "blocking write ...\n"); | ||
| 93 | |||
| 94 | oldfs = get_fs(); | ||
| 95 | set_fs(get_ds()); | ||
| 96 | /* The cast to a user pointer is valid due to the set_fs() */ | ||
| 97 | ret = vfs_write(ts->wr, (void __user *)v, len, &ts->wr->f_pos); | ||
| 98 | set_fs(oldfs); | ||
| 99 | |||
| 100 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) | ||
| 101 | trans->status = Disconnected; | ||
| 102 | return ret; | ||
| 103 | } | ||
| 104 | |||
| 105 | static unsigned int | ||
| 106 | v9fs_fd_poll(struct v9fs_transport *trans, struct poll_table_struct *pt) | ||
| 107 | { | ||
| 108 | int ret, n; | ||
| 109 | struct v9fs_trans_fd *ts; | ||
| 110 | mm_segment_t oldfs; | ||
| 111 | |||
| 112 | if (!trans || trans->status != Connected || !(ts = trans->priv)) | ||
| 113 | return -EREMOTEIO; | ||
| 114 | |||
| 115 | if (!ts->rd->f_op || !ts->rd->f_op->poll) | ||
| 116 | return -EIO; | ||
| 117 | |||
| 118 | if (!ts->wr->f_op || !ts->wr->f_op->poll) | ||
| 119 | return -EIO; | ||
| 120 | |||
| 121 | oldfs = get_fs(); | ||
| 122 | set_fs(get_ds()); | ||
| 123 | |||
| 124 | ret = ts->rd->f_op->poll(ts->rd, pt); | ||
| 125 | if (ret < 0) | ||
| 126 | goto end; | ||
| 127 | |||
| 128 | if (ts->rd != ts->wr) { | ||
| 129 | n = ts->wr->f_op->poll(ts->wr, pt); | ||
| 130 | if (n < 0) { | ||
| 131 | ret = n; | ||
| 132 | goto end; | ||
| 133 | } | ||
| 134 | ret = (ret & ~POLLOUT) | (n & ~POLLIN); | ||
| 135 | } | ||
| 136 | |||
| 137 | end: | ||
| 138 | set_fs(oldfs); | ||
| 139 | return ret; | ||
| 140 | } | ||
| 141 | |||
| 142 | static int v9fs_fd_open(struct v9fs_session_info *v9ses, int rfd, int wfd) | ||
| 143 | { | ||
| 144 | struct v9fs_transport *trans = v9ses->transport; | ||
| 145 | struct v9fs_trans_fd *ts = kmalloc(sizeof(struct v9fs_trans_fd), | ||
| 146 | GFP_KERNEL); | ||
| 147 | if (!ts) | ||
| 148 | return -ENOMEM; | ||
| 149 | |||
| 150 | ts->rd = fget(rfd); | ||
| 151 | ts->wr = fget(wfd); | ||
| 152 | if (!ts->rd || !ts->wr) { | ||
| 153 | if (ts->rd) | ||
| 154 | fput(ts->rd); | ||
| 155 | if (ts->wr) | ||
| 156 | fput(ts->wr); | ||
| 157 | kfree(ts); | ||
| 158 | return -EIO; | ||
| 159 | } | ||
| 160 | |||
| 161 | trans->priv = ts; | ||
| 162 | trans->status = Connected; | ||
| 163 | |||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | |||
| 167 | static int v9fs_fd_init(struct v9fs_session_info *v9ses, const char *addr, | ||
| 168 | char *data) | ||
| 169 | { | ||
| 170 | if (v9ses->rfdno == ~0 || v9ses->wfdno == ~0) { | ||
| 171 | printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n"); | ||
| 172 | return -ENOPROTOOPT; | ||
| 173 | } | ||
| 174 | |||
| 175 | return v9fs_fd_open(v9ses, v9ses->rfdno, v9ses->wfdno); | ||
| 176 | } | ||
| 177 | |||
| 178 | static int v9fs_socket_open(struct v9fs_session_info *v9ses, | ||
| 179 | struct socket *csocket) | ||
| 180 | { | ||
| 181 | int fd, ret; | ||
| 182 | |||
| 183 | csocket->sk->sk_allocation = GFP_NOIO; | ||
| 184 | if ((fd = sock_map_fd(csocket)) < 0) { | ||
| 185 | eprintk(KERN_ERR, "v9fs_socket_open: failed to map fd\n"); | ||
| 186 | ret = fd; | ||
| 187 | release_csocket: | ||
| 188 | sock_release(csocket); | ||
| 189 | return ret; | ||
| 190 | } | ||
| 191 | |||
| 192 | if ((ret = v9fs_fd_open(v9ses, fd, fd)) < 0) { | ||
| 193 | sockfd_put(csocket); | ||
| 194 | eprintk(KERN_ERR, "v9fs_socket_open: failed to open fd\n"); | ||
| 195 | goto release_csocket; | ||
| 196 | } | ||
| 197 | |||
| 198 | ((struct v9fs_trans_fd *)v9ses->transport->priv)->rd->f_flags |= | ||
| 199 | O_NONBLOCK; | ||
| 200 | return 0; | ||
| 201 | } | ||
| 202 | |||
| 203 | static int v9fs_tcp_init(struct v9fs_session_info *v9ses, const char *addr, | ||
| 204 | char *data) | ||
| 205 | { | ||
| 206 | int ret; | ||
| 207 | struct socket *csocket = NULL; | ||
| 208 | struct sockaddr_in sin_server; | ||
| 209 | |||
| 210 | sin_server.sin_family = AF_INET; | ||
| 211 | sin_server.sin_addr.s_addr = in_aton(addr); | ||
| 212 | sin_server.sin_port = htons(v9ses->port); | ||
| 213 | sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket); | ||
| 214 | |||
| 215 | if (!csocket) { | ||
| 216 | eprintk(KERN_ERR, "v9fs_trans_tcp: problem creating socket\n"); | ||
| 217 | return -1; | ||
| 218 | } | ||
| 219 | |||
| 220 | ret = csocket->ops->connect(csocket, | ||
| 221 | (struct sockaddr *)&sin_server, | ||
| 222 | sizeof(struct sockaddr_in), 0); | ||
| 223 | if (ret < 0) { | ||
| 224 | eprintk(KERN_ERR, | ||
| 225 | "v9fs_trans_tcp: problem connecting socket to %s\n", | ||
| 226 | addr); | ||
| 227 | return ret; | ||
| 228 | } | ||
| 229 | |||
| 230 | return v9fs_socket_open(v9ses, csocket); | ||
| 231 | } | ||
| 232 | |||
| 233 | static int | ||
| 234 | v9fs_unix_init(struct v9fs_session_info *v9ses, const char *addr, char *data) | ||
| 235 | { | ||
| 236 | int ret; | ||
| 237 | struct socket *csocket; | ||
| 238 | struct sockaddr_un sun_server; | ||
| 239 | |||
| 240 | if (strlen(addr) > UNIX_PATH_MAX) { | ||
| 241 | eprintk(KERN_ERR, "v9fs_trans_unix: address too long: %s\n", | ||
| 242 | addr); | ||
| 243 | return -ENAMETOOLONG; | ||
| 244 | } | ||
| 245 | |||
| 246 | sun_server.sun_family = PF_UNIX; | ||
| 247 | strcpy(sun_server.sun_path, addr); | ||
| 248 | sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); | ||
| 249 | ret = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, | ||
| 250 | sizeof(struct sockaddr_un) - 1, 0); | ||
| 251 | if (ret < 0) { | ||
| 252 | eprintk(KERN_ERR, | ||
| 253 | "v9fs_trans_unix: problem connecting socket: %s: %d\n", | ||
| 254 | addr, ret); | ||
| 255 | return ret; | ||
| 256 | } | ||
| 257 | |||
| 258 | return v9fs_socket_open(v9ses, csocket); | ||
| 259 | } | ||
| 260 | |||
| 261 | /** | ||
| 262 | * v9fs_sock_close - shutdown socket | ||
| 263 | * @trans: private socket structure | ||
| 264 | * | ||
| 265 | */ | ||
| 266 | static void v9fs_fd_close(struct v9fs_transport *trans) | ||
| 267 | { | ||
| 268 | struct v9fs_trans_fd *ts; | ||
| 269 | |||
| 270 | if (!trans) | ||
| 271 | return; | ||
| 272 | |||
| 273 | ts = xchg(&trans->priv, NULL); | ||
| 274 | |||
| 275 | if (!ts) | ||
| 276 | return; | ||
| 277 | |||
| 278 | trans->status = Disconnected; | ||
| 279 | if (ts->rd) | ||
| 280 | fput(ts->rd); | ||
| 281 | if (ts->wr) | ||
| 282 | fput(ts->wr); | ||
| 283 | kfree(ts); | ||
| 284 | } | ||
| 285 | |||
| 286 | struct v9fs_transport v9fs_trans_fd = { | ||
| 287 | .init = v9fs_fd_init, | ||
| 288 | .write = v9fs_fd_write, | ||
| 289 | .read = v9fs_fd_read, | ||
| 290 | .close = v9fs_fd_close, | ||
| 291 | .poll = v9fs_fd_poll, | ||
| 292 | }; | ||
| 293 | |||
| 294 | struct v9fs_transport v9fs_trans_tcp = { | ||
| 295 | .init = v9fs_tcp_init, | ||
| 296 | .write = v9fs_fd_write, | ||
| 297 | .read = v9fs_fd_read, | ||
| 298 | .close = v9fs_fd_close, | ||
| 299 | .poll = v9fs_fd_poll, | ||
| 300 | }; | ||
| 301 | |||
| 302 | struct v9fs_transport v9fs_trans_unix = { | ||
| 303 | .init = v9fs_unix_init, | ||
| 304 | .write = v9fs_fd_write, | ||
| 305 | .read = v9fs_fd_read, | ||
| 306 | .close = v9fs_fd_close, | ||
| 307 | .poll = v9fs_fd_poll, | ||
| 308 | }; | ||
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 6ad6f192b6e4..4feb5ae63ecf 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
| @@ -29,16 +29,12 @@ | |||
| 29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
| 30 | #include <linux/parser.h> | 30 | #include <linux/parser.h> |
| 31 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
| 32 | 32 | #include <net/9p/9p.h> | |
| 33 | #include "debug.h" | 33 | #include <net/9p/transport.h> |
| 34 | #include <net/9p/conn.h> | ||
| 35 | #include <net/9p/client.h> | ||
| 34 | #include "v9fs.h" | 36 | #include "v9fs.h" |
| 35 | #include "9p.h" | ||
| 36 | #include "v9fs_vfs.h" | 37 | #include "v9fs_vfs.h" |
| 37 | #include "transport.h" | ||
| 38 | #include "mux.h" | ||
| 39 | |||
| 40 | /* TODO: sysfs or debugfs interface */ | ||
| 41 | int v9fs_debug_level = 0; /* feature-rific global debug level */ | ||
| 42 | 38 | ||
| 43 | /* | 39 | /* |
| 44 | * Option Parsing (code inspired by NFS code) | 40 | * Option Parsing (code inspired by NFS code) |
| @@ -47,12 +43,12 @@ int v9fs_debug_level = 0; /* feature-rific global debug level */ | |||
| 47 | 43 | ||
| 48 | enum { | 44 | enum { |
| 49 | /* Options that take integer arguments */ | 45 | /* Options that take integer arguments */ |
| 50 | Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, Opt_debug, | 46 | Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, |
| 51 | Opt_rfdno, Opt_wfdno, | 47 | Opt_rfdno, Opt_wfdno, |
| 52 | /* String options */ | 48 | /* String options */ |
| 53 | Opt_uname, Opt_remotename, | 49 | Opt_uname, Opt_remotename, |
| 54 | /* Options that take no arguments */ | 50 | /* Options that take no arguments */ |
| 55 | Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd, | 51 | Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd, Opt_pci, |
| 56 | /* Cache options */ | 52 | /* Cache options */ |
| 57 | Opt_cache_loose, | 53 | Opt_cache_loose, |
| 58 | /* Error token */ | 54 | /* Error token */ |
| @@ -67,12 +63,14 @@ static match_table_t tokens = { | |||
| 67 | {Opt_afid, "afid=%u"}, | 63 | {Opt_afid, "afid=%u"}, |
| 68 | {Opt_rfdno, "rfdno=%u"}, | 64 | {Opt_rfdno, "rfdno=%u"}, |
| 69 | {Opt_wfdno, "wfdno=%u"}, | 65 | {Opt_wfdno, "wfdno=%u"}, |
| 70 | {Opt_debug, "debug=%x"}, | ||
| 71 | {Opt_uname, "uname=%s"}, | 66 | {Opt_uname, "uname=%s"}, |
| 72 | {Opt_remotename, "aname=%s"}, | 67 | {Opt_remotename, "aname=%s"}, |
| 73 | {Opt_unix, "proto=unix"}, | 68 | {Opt_unix, "proto=unix"}, |
| 74 | {Opt_tcp, "proto=tcp"}, | 69 | {Opt_tcp, "proto=tcp"}, |
| 75 | {Opt_fd, "proto=fd"}, | 70 | {Opt_fd, "proto=fd"}, |
| 71 | #ifdef CONFIG_PCI_9P | ||
| 72 | {Opt_pci, "proto=pci"}, | ||
| 73 | #endif | ||
| 76 | {Opt_tcp, "tcp"}, | 74 | {Opt_tcp, "tcp"}, |
| 77 | {Opt_unix, "unix"}, | 75 | {Opt_unix, "unix"}, |
| 78 | {Opt_fd, "fd"}, | 76 | {Opt_fd, "fd"}, |
| @@ -83,6 +81,8 @@ static match_table_t tokens = { | |||
| 83 | {Opt_err, NULL} | 81 | {Opt_err, NULL} |
| 84 | }; | 82 | }; |
| 85 | 83 | ||
| 84 | extern struct p9_transport *p9pci_trans_create(void); | ||
| 85 | |||
| 86 | /* | 86 | /* |
| 87 | * Parse option string. | 87 | * Parse option string. |
| 88 | */ | 88 | */ |
| @@ -122,7 +122,7 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses) | |||
| 122 | token = match_token(p, tokens, args); | 122 | token = match_token(p, tokens, args); |
| 123 | if (token < Opt_uname) { | 123 | if (token < Opt_uname) { |
| 124 | if ((ret = match_int(&args[0], &option)) < 0) { | 124 | if ((ret = match_int(&args[0], &option)) < 0) { |
| 125 | dprintk(DEBUG_ERROR, | 125 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 126 | "integer field, but no integer?\n"); | 126 | "integer field, but no integer?\n"); |
| 127 | continue; | 127 | continue; |
| 128 | } | 128 | } |
| @@ -149,15 +149,15 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses) | |||
| 149 | case Opt_wfdno: | 149 | case Opt_wfdno: |
| 150 | v9ses->wfdno = option; | 150 | v9ses->wfdno = option; |
| 151 | break; | 151 | break; |
| 152 | case Opt_debug: | ||
| 153 | v9ses->debug = option; | ||
| 154 | break; | ||
| 155 | case Opt_tcp: | 152 | case Opt_tcp: |
| 156 | v9ses->proto = PROTO_TCP; | 153 | v9ses->proto = PROTO_TCP; |
| 157 | break; | 154 | break; |
| 158 | case Opt_unix: | 155 | case Opt_unix: |
| 159 | v9ses->proto = PROTO_UNIX; | 156 | v9ses->proto = PROTO_UNIX; |
| 160 | break; | 157 | break; |
| 158 | case Opt_pci: | ||
| 159 | v9ses->proto = PROTO_PCI; | ||
| 160 | break; | ||
| 161 | case Opt_fd: | 161 | case Opt_fd: |
| 162 | v9ses->proto = PROTO_FD; | 162 | v9ses->proto = PROTO_FD; |
| 163 | break; | 163 | break; |
| @@ -183,82 +183,6 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses) | |||
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | /** | 185 | /** |
| 186 | * v9fs_inode2v9ses - safely extract v9fs session info from super block | ||
| 187 | * @inode: inode to extract information from | ||
| 188 | * | ||
| 189 | * Paranoid function to extract v9ses information from superblock, | ||
| 190 | * if anything is missing it will report an error. | ||
| 191 | * | ||
| 192 | */ | ||
| 193 | |||
| 194 | struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode) | ||
| 195 | { | ||
| 196 | return (inode->i_sb->s_fs_info); | ||
| 197 | } | ||
| 198 | |||
| 199 | /** | ||
| 200 | * v9fs_get_idpool - allocate numeric id from pool | ||
| 201 | * @p - pool to allocate from | ||
| 202 | * | ||
| 203 | * XXX - This seems to be an awful generic function, should it be in idr.c with | ||
| 204 | * the lock included in struct idr? | ||
| 205 | */ | ||
| 206 | |||
| 207 | int v9fs_get_idpool(struct v9fs_idpool *p) | ||
| 208 | { | ||
| 209 | int i = 0; | ||
| 210 | int error; | ||
| 211 | |||
| 212 | retry: | ||
| 213 | if (idr_pre_get(&p->pool, GFP_KERNEL) == 0) | ||
| 214 | return 0; | ||
| 215 | |||
| 216 | if (down_interruptible(&p->lock) == -EINTR) { | ||
| 217 | eprintk(KERN_WARNING, "Interrupted while locking\n"); | ||
| 218 | return -1; | ||
| 219 | } | ||
| 220 | |||
| 221 | /* no need to store exactly p, we just need something non-null */ | ||
| 222 | error = idr_get_new(&p->pool, p, &i); | ||
| 223 | up(&p->lock); | ||
| 224 | |||
| 225 | if (error == -EAGAIN) | ||
| 226 | goto retry; | ||
| 227 | else if (error) | ||
| 228 | return -1; | ||
| 229 | |||
| 230 | return i; | ||
| 231 | } | ||
| 232 | |||
| 233 | /** | ||
| 234 | * v9fs_put_idpool - release numeric id from pool | ||
| 235 | * @p - pool to allocate from | ||
| 236 | * | ||
| 237 | * XXX - This seems to be an awful generic function, should it be in idr.c with | ||
| 238 | * the lock included in struct idr? | ||
| 239 | */ | ||
| 240 | |||
| 241 | void v9fs_put_idpool(int id, struct v9fs_idpool *p) | ||
| 242 | { | ||
| 243 | if (down_interruptible(&p->lock) == -EINTR) { | ||
| 244 | eprintk(KERN_WARNING, "Interrupted while locking\n"); | ||
| 245 | return; | ||
| 246 | } | ||
| 247 | idr_remove(&p->pool, id); | ||
| 248 | up(&p->lock); | ||
| 249 | } | ||
| 250 | |||
| 251 | /** | ||
| 252 | * v9fs_check_idpool - check if the specified id is available | ||
| 253 | * @id - id to check | ||
| 254 | * @p - pool | ||
| 255 | */ | ||
| 256 | int v9fs_check_idpool(int id, struct v9fs_idpool *p) | ||
| 257 | { | ||
| 258 | return idr_find(&p->pool, id) != NULL; | ||
| 259 | } | ||
| 260 | |||
| 261 | /** | ||
| 262 | * v9fs_session_init - initialize session | 186 | * v9fs_session_init - initialize session |
| 263 | * @v9ses: session information structure | 187 | * @v9ses: session information structure |
| 264 | * @dev_name: device being mounted | 188 | * @dev_name: device being mounted |
| @@ -266,25 +190,21 @@ int v9fs_check_idpool(int id, struct v9fs_idpool *p) | |||
| 266 | * | 190 | * |
| 267 | */ | 191 | */ |
| 268 | 192 | ||
| 269 | int | 193 | struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, |
| 270 | v9fs_session_init(struct v9fs_session_info *v9ses, | ||
| 271 | const char *dev_name, char *data) | 194 | const char *dev_name, char *data) |
| 272 | { | 195 | { |
| 273 | struct v9fs_fcall *fcall = NULL; | ||
| 274 | struct v9fs_transport *trans_proto; | ||
| 275 | int n = 0; | ||
| 276 | int newfid = -1; | ||
| 277 | int retval = -EINVAL; | 196 | int retval = -EINVAL; |
| 278 | struct v9fs_str *version; | 197 | struct p9_transport *trans; |
| 198 | struct p9_fid *fid; | ||
| 279 | 199 | ||
| 280 | v9ses->name = __getname(); | 200 | v9ses->name = __getname(); |
| 281 | if (!v9ses->name) | 201 | if (!v9ses->name) |
| 282 | return -ENOMEM; | 202 | return ERR_PTR(-ENOMEM); |
| 283 | 203 | ||
| 284 | v9ses->remotename = __getname(); | 204 | v9ses->remotename = __getname(); |
| 285 | if (!v9ses->remotename) { | 205 | if (!v9ses->remotename) { |
| 286 | __putname(v9ses->name); | 206 | __putname(v9ses->name); |
| 287 | return -ENOMEM; | 207 | return ERR_PTR(-ENOMEM); |
| 288 | } | 208 | } |
| 289 | 209 | ||
| 290 | strcpy(v9ses->name, V9FS_DEFUSER); | 210 | strcpy(v9ses->name, V9FS_DEFUSER); |
| @@ -292,130 +212,60 @@ v9fs_session_init(struct v9fs_session_info *v9ses, | |||
| 292 | 212 | ||
| 293 | v9fs_parse_options(data, v9ses); | 213 | v9fs_parse_options(data, v9ses); |
| 294 | 214 | ||
| 295 | /* set global debug level */ | ||
| 296 | v9fs_debug_level = v9ses->debug; | ||
| 297 | |||
| 298 | /* id pools that are session-dependent: fids and tags */ | ||
| 299 | idr_init(&v9ses->fidpool.pool); | ||
| 300 | init_MUTEX(&v9ses->fidpool.lock); | ||
| 301 | |||
| 302 | switch (v9ses->proto) { | 215 | switch (v9ses->proto) { |
| 303 | case PROTO_TCP: | 216 | case PROTO_TCP: |
| 304 | trans_proto = &v9fs_trans_tcp; | 217 | trans = p9_trans_create_tcp(dev_name, v9ses->port); |
| 305 | break; | 218 | break; |
| 306 | case PROTO_UNIX: | 219 | case PROTO_UNIX: |
| 307 | trans_proto = &v9fs_trans_unix; | 220 | trans = p9_trans_create_unix(dev_name); |
| 308 | *v9ses->remotename = 0; | 221 | *v9ses->remotename = 0; |
| 309 | break; | 222 | break; |
| 310 | case PROTO_FD: | 223 | case PROTO_FD: |
| 311 | trans_proto = &v9fs_trans_fd; | 224 | trans = p9_trans_create_fd(v9ses->rfdno, v9ses->wfdno); |
| 225 | *v9ses->remotename = 0; | ||
| 226 | break; | ||
| 227 | #ifdef CONFIG_PCI_9P | ||
| 228 | case PROTO_PCI: | ||
| 229 | trans = p9pci_trans_create(); | ||
| 312 | *v9ses->remotename = 0; | 230 | *v9ses->remotename = 0; |
| 313 | break; | 231 | break; |
| 232 | #endif | ||
| 314 | default: | 233 | default: |
| 315 | printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto); | 234 | printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto); |
| 316 | retval = -ENOPROTOOPT; | 235 | retval = -ENOPROTOOPT; |
| 317 | goto SessCleanUp; | 236 | goto error; |
| 318 | }; | 237 | }; |
| 319 | 238 | ||
| 320 | v9ses->transport = kmalloc(sizeof(*v9ses->transport), GFP_KERNEL); | 239 | if (IS_ERR(trans)) { |
| 321 | if (!v9ses->transport) { | 240 | retval = PTR_ERR(trans); |
| 322 | retval = -ENOMEM; | 241 | trans = NULL; |
| 323 | goto SessCleanUp; | 242 | goto error; |
| 324 | } | 243 | } |
| 325 | 244 | ||
| 326 | memmove(v9ses->transport, trans_proto, sizeof(*v9ses->transport)); | 245 | v9ses->clnt = p9_client_create(trans, v9ses->maxdata + P9_IOHDRSZ, |
| 246 | v9ses->extended); | ||
| 327 | 247 | ||
| 328 | if ((retval = v9ses->transport->init(v9ses, dev_name, data)) < 0) { | 248 | if (IS_ERR(v9ses->clnt)) { |
| 329 | eprintk(KERN_ERR, "problem initializing transport\n"); | 249 | retval = PTR_ERR(v9ses->clnt); |
| 330 | goto SessCleanUp; | 250 | v9ses->clnt = NULL; |
| 251 | P9_DPRINTK(P9_DEBUG_ERROR, "problem initializing 9p client\n"); | ||
| 252 | goto error; | ||
| 331 | } | 253 | } |
| 332 | 254 | ||
| 333 | v9ses->inprogress = 0; | 255 | fid = p9_client_attach(v9ses->clnt, NULL, v9ses->name, |
| 334 | v9ses->shutdown = 0; | 256 | v9ses->remotename); |
| 335 | v9ses->session_hung = 0; | 257 | if (IS_ERR(fid)) { |
| 336 | 258 | retval = PTR_ERR(fid); | |
| 337 | v9ses->mux = v9fs_mux_init(v9ses->transport, v9ses->maxdata + V9FS_IOHDRSZ, | 259 | fid = NULL; |
| 338 | &v9ses->extended); | 260 | P9_DPRINTK(P9_DEBUG_ERROR, "cannot attach\n"); |
| 339 | 261 | goto error; | |
| 340 | if (IS_ERR(v9ses->mux)) { | ||
| 341 | retval = PTR_ERR(v9ses->mux); | ||
| 342 | v9ses->mux = NULL; | ||
| 343 | dprintk(DEBUG_ERROR, "problem initializing mux\n"); | ||
| 344 | goto SessCleanUp; | ||
| 345 | } | 262 | } |
| 346 | 263 | ||
| 347 | if (v9ses->afid == ~0) { | 264 | return fid; |
| 348 | if (v9ses->extended) | ||
| 349 | retval = | ||
| 350 | v9fs_t_version(v9ses, v9ses->maxdata, "9P2000.u", | ||
| 351 | &fcall); | ||
| 352 | else | ||
| 353 | retval = v9fs_t_version(v9ses, v9ses->maxdata, "9P2000", | ||
| 354 | &fcall); | ||
| 355 | |||
| 356 | if (retval < 0) { | ||
| 357 | dprintk(DEBUG_ERROR, "v9fs_t_version failed\n"); | ||
| 358 | goto FreeFcall; | ||
| 359 | } | ||
| 360 | |||
| 361 | version = &fcall->params.rversion.version; | ||
| 362 | if (version->len==8 && !memcmp(version->str, "9P2000.u", 8)) { | ||
| 363 | dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n"); | ||
| 364 | v9ses->extended = 1; | ||
| 365 | } else if (version->len==6 && !memcmp(version->str, "9P2000", 6)) { | ||
| 366 | dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n"); | ||
| 367 | v9ses->extended = 0; | ||
| 368 | } else { | ||
| 369 | retval = -EREMOTEIO; | ||
| 370 | goto FreeFcall; | ||
| 371 | } | ||
| 372 | 265 | ||
| 373 | n = fcall->params.rversion.msize; | 266 | error: |
| 374 | kfree(fcall); | ||
| 375 | |||
| 376 | if (n < v9ses->maxdata) | ||
| 377 | v9ses->maxdata = n; | ||
| 378 | } | ||
| 379 | |||
| 380 | newfid = v9fs_get_idpool(&v9ses->fidpool); | ||
| 381 | if (newfid < 0) { | ||
| 382 | eprintk(KERN_WARNING, "couldn't allocate FID\n"); | ||
| 383 | retval = -ENOMEM; | ||
| 384 | goto SessCleanUp; | ||
| 385 | } | ||
| 386 | /* it is a little bit ugly, but we have to prevent newfid */ | ||
| 387 | /* being the same as afid, so if it is, get a new fid */ | ||
| 388 | if (v9ses->afid != ~0 && newfid == v9ses->afid) { | ||
| 389 | newfid = v9fs_get_idpool(&v9ses->fidpool); | ||
| 390 | if (newfid < 0) { | ||
| 391 | eprintk(KERN_WARNING, "couldn't allocate FID\n"); | ||
| 392 | retval = -ENOMEM; | ||
| 393 | goto SessCleanUp; | ||
| 394 | } | ||
| 395 | } | ||
| 396 | |||
| 397 | if ((retval = | ||
| 398 | v9fs_t_attach(v9ses, v9ses->name, v9ses->remotename, newfid, | ||
| 399 | v9ses->afid, NULL)) | ||
| 400 | < 0) { | ||
| 401 | dprintk(DEBUG_ERROR, "cannot attach\n"); | ||
| 402 | goto SessCleanUp; | ||
| 403 | } | ||
| 404 | |||
| 405 | if (v9ses->afid != ~0) { | ||
| 406 | dprintk(DEBUG_ERROR, "afid not equal to ~0\n"); | ||
| 407 | if (v9fs_t_clunk(v9ses, v9ses->afid)) | ||
| 408 | dprintk(DEBUG_ERROR, "clunk failed\n"); | ||
| 409 | } | ||
| 410 | |||
| 411 | return newfid; | ||
| 412 | |||
| 413 | FreeFcall: | ||
| 414 | kfree(fcall); | ||
| 415 | |||
| 416 | SessCleanUp: | ||
| 417 | v9fs_session_close(v9ses); | 267 | v9fs_session_close(v9ses); |
| 418 | return retval; | 268 | return ERR_PTR(retval); |
| 419 | } | 269 | } |
| 420 | 270 | ||
| 421 | /** | 271 | /** |
| @@ -426,15 +276,9 @@ v9fs_session_init(struct v9fs_session_info *v9ses, | |||
| 426 | 276 | ||
| 427 | void v9fs_session_close(struct v9fs_session_info *v9ses) | 277 | void v9fs_session_close(struct v9fs_session_info *v9ses) |
| 428 | { | 278 | { |
| 429 | if (v9ses->mux) { | 279 | if (v9ses->clnt) { |
| 430 | v9fs_mux_destroy(v9ses->mux); | 280 | p9_client_destroy(v9ses->clnt); |
| 431 | v9ses->mux = NULL; | 281 | v9ses->clnt = NULL; |
| 432 | } | ||
| 433 | |||
| 434 | if (v9ses->transport) { | ||
| 435 | v9ses->transport->close(v9ses->transport); | ||
| 436 | kfree(v9ses->transport); | ||
| 437 | v9ses->transport = NULL; | ||
| 438 | } | 282 | } |
| 439 | 283 | ||
| 440 | __putname(v9ses->name); | 284 | __putname(v9ses->name); |
| @@ -446,9 +290,8 @@ void v9fs_session_close(struct v9fs_session_info *v9ses) | |||
| 446 | * and cancel all pending requests. | 290 | * and cancel all pending requests. |
| 447 | */ | 291 | */ |
| 448 | void v9fs_session_cancel(struct v9fs_session_info *v9ses) { | 292 | void v9fs_session_cancel(struct v9fs_session_info *v9ses) { |
| 449 | dprintk(DEBUG_ERROR, "cancel session %p\n", v9ses); | 293 | P9_DPRINTK(P9_DEBUG_ERROR, "cancel session %p\n", v9ses); |
| 450 | v9ses->transport->status = Disconnected; | 294 | p9_client_disconnect(v9ses->clnt); |
| 451 | v9fs_mux_cancel(v9ses->mux, -EIO); | ||
| 452 | } | 295 | } |
| 453 | 296 | ||
| 454 | extern int v9fs_error_init(void); | 297 | extern int v9fs_error_init(void); |
| @@ -460,24 +303,9 @@ extern int v9fs_error_init(void); | |||
| 460 | 303 | ||
| 461 | static int __init init_v9fs(void) | 304 | static int __init init_v9fs(void) |
| 462 | { | 305 | { |
| 463 | int ret; | ||
| 464 | |||
| 465 | v9fs_error_init(); | ||
| 466 | |||
| 467 | printk(KERN_INFO "Installing v9fs 9p2000 file system support\n"); | 306 | printk(KERN_INFO "Installing v9fs 9p2000 file system support\n"); |
| 468 | 307 | ||
| 469 | ret = v9fs_mux_global_init(); | 308 | return register_filesystem(&v9fs_fs_type); |
| 470 | if (ret) { | ||
| 471 | printk(KERN_WARNING "v9fs: starting mux failed\n"); | ||
| 472 | return ret; | ||
| 473 | } | ||
| 474 | ret = register_filesystem(&v9fs_fs_type); | ||
| 475 | if (ret) { | ||
| 476 | printk(KERN_WARNING "v9fs: registering file system failed\n"); | ||
| 477 | v9fs_mux_global_exit(); | ||
| 478 | } | ||
| 479 | |||
| 480 | return ret; | ||
| 481 | } | 309 | } |
| 482 | 310 | ||
| 483 | /** | 311 | /** |
| @@ -487,13 +315,13 @@ static int __init init_v9fs(void) | |||
| 487 | 315 | ||
| 488 | static void __exit exit_v9fs(void) | 316 | static void __exit exit_v9fs(void) |
| 489 | { | 317 | { |
| 490 | v9fs_mux_global_exit(); | ||
| 491 | unregister_filesystem(&v9fs_fs_type); | 318 | unregister_filesystem(&v9fs_fs_type); |
| 492 | } | 319 | } |
| 493 | 320 | ||
| 494 | module_init(init_v9fs) | 321 | module_init(init_v9fs) |
| 495 | module_exit(exit_v9fs) | 322 | module_exit(exit_v9fs) |
| 496 | 323 | ||
| 324 | MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>"); | ||
| 497 | MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>"); | 325 | MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>"); |
| 498 | MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>"); | 326 | MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>"); |
| 499 | MODULE_LICENSE("GPL"); | 327 | MODULE_LICENSE("GPL"); |
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 820bf5ca35d8..abc4b1668ace 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h | |||
| @@ -22,16 +22,6 @@ | |||
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | /* | 24 | /* |
| 25 | * Idpool structure provides lock and id management | ||
| 26 | * | ||
| 27 | */ | ||
| 28 | |||
| 29 | struct v9fs_idpool { | ||
| 30 | struct semaphore lock; | ||
| 31 | struct idr pool; | ||
| 32 | }; | ||
| 33 | |||
| 34 | /* | ||
| 35 | * Session structure provides information for an opened session | 25 | * Session structure provides information for an opened session |
| 36 | * | 26 | * |
| 37 | */ | 27 | */ |
| @@ -54,15 +44,7 @@ struct v9fs_session_info { | |||
| 54 | unsigned int uid; /* default uid/muid for legacy support */ | 44 | unsigned int uid; /* default uid/muid for legacy support */ |
| 55 | unsigned int gid; /* default gid for legacy support */ | 45 | unsigned int gid; /* default gid for legacy support */ |
| 56 | 46 | ||
| 57 | /* book keeping */ | 47 | struct p9_client *clnt; /* 9p client */ |
| 58 | struct v9fs_idpool fidpool; /* The FID pool for file descriptors */ | ||
| 59 | |||
| 60 | struct v9fs_transport *transport; | ||
| 61 | struct v9fs_mux_data *mux; | ||
| 62 | |||
| 63 | int inprogress; /* session in progress => true */ | ||
| 64 | int shutdown; /* session shutting down. no more attaches. */ | ||
| 65 | unsigned char session_hung; | ||
| 66 | struct dentry *debugfs_dir; | 48 | struct dentry *debugfs_dir; |
| 67 | }; | 49 | }; |
| 68 | 50 | ||
| @@ -71,6 +53,7 @@ enum { | |||
| 71 | PROTO_TCP, | 53 | PROTO_TCP, |
| 72 | PROTO_UNIX, | 54 | PROTO_UNIX, |
| 73 | PROTO_FD, | 55 | PROTO_FD, |
| 56 | PROTO_PCI, | ||
| 74 | }; | 57 | }; |
| 75 | 58 | ||
| 76 | /* possible values of ->cache */ | 59 | /* possible values of ->cache */ |
| @@ -82,12 +65,9 @@ enum { | |||
| 82 | 65 | ||
| 83 | extern struct dentry *v9fs_debugfs_root; | 66 | extern struct dentry *v9fs_debugfs_root; |
| 84 | 67 | ||
| 85 | int v9fs_session_init(struct v9fs_session_info *, const char *, char *); | 68 | struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, |
| 86 | struct v9fs_session_info *v9fs_inode2v9ses(struct inode *); | 69 | char *); |
| 87 | void v9fs_session_close(struct v9fs_session_info *v9ses); | 70 | void v9fs_session_close(struct v9fs_session_info *v9ses); |
| 88 | int v9fs_get_idpool(struct v9fs_idpool *p); | ||
| 89 | void v9fs_put_idpool(int id, struct v9fs_idpool *p); | ||
| 90 | int v9fs_check_idpool(int id, struct v9fs_idpool *p); | ||
| 91 | void v9fs_session_cancel(struct v9fs_session_info *v9ses); | 71 | void v9fs_session_cancel(struct v9fs_session_info *v9ses); |
| 92 | 72 | ||
| 93 | #define V9FS_MAGIC 0x01021997 | 73 | #define V9FS_MAGIC 0x01021997 |
| @@ -97,3 +77,7 @@ void v9fs_session_cancel(struct v9fs_session_info *v9ses); | |||
| 97 | #define V9FS_DEFUSER "nobody" | 77 | #define V9FS_DEFUSER "nobody" |
| 98 | #define V9FS_DEFANAME "" | 78 | #define V9FS_DEFANAME "" |
| 99 | 79 | ||
| 80 | static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode) | ||
| 81 | { | ||
| 82 | return (inode->i_sb->s_fs_info); | ||
| 83 | } | ||
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index 6a82d39dc498..fd01d90cada5 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h | |||
| @@ -45,10 +45,10 @@ extern struct dentry_operations v9fs_dentry_operations; | |||
| 45 | extern struct dentry_operations v9fs_cached_dentry_operations; | 45 | extern struct dentry_operations v9fs_cached_dentry_operations; |
| 46 | 46 | ||
| 47 | struct inode *v9fs_get_inode(struct super_block *sb, int mode); | 47 | struct inode *v9fs_get_inode(struct super_block *sb, int mode); |
| 48 | ino_t v9fs_qid2ino(struct v9fs_qid *qid); | 48 | ino_t v9fs_qid2ino(struct p9_qid *qid); |
| 49 | void v9fs_stat2inode(struct v9fs_stat *, struct inode *, struct super_block *); | 49 | void v9fs_stat2inode(struct p9_stat *, struct inode *, struct super_block *); |
| 50 | int v9fs_dir_release(struct inode *inode, struct file *filp); | 50 | int v9fs_dir_release(struct inode *inode, struct file *filp); |
| 51 | int v9fs_file_open(struct inode *inode, struct file *file); | 51 | int v9fs_file_open(struct inode *inode, struct file *file); |
| 52 | void v9fs_inode2stat(struct inode *inode, struct v9fs_stat *stat); | 52 | void v9fs_inode2stat(struct inode *inode, struct p9_stat *stat); |
| 53 | void v9fs_dentry_release(struct dentry *); | 53 | void v9fs_dentry_release(struct dentry *); |
| 54 | int v9fs_uflags2omode(int uflags); | 54 | int v9fs_uflags2omode(int uflags); |
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 9ac4ffe9ac7d..6248f0e727a3 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c | |||
| @@ -33,10 +33,10 @@ | |||
| 33 | #include <linux/pagemap.h> | 33 | #include <linux/pagemap.h> |
| 34 | #include <linux/idr.h> | 34 | #include <linux/idr.h> |
| 35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
| 36 | #include <net/9p/9p.h> | ||
| 37 | #include <net/9p/client.h> | ||
| 36 | 38 | ||
| 37 | #include "debug.h" | ||
| 38 | #include "v9fs.h" | 39 | #include "v9fs.h" |
| 39 | #include "9p.h" | ||
| 40 | #include "v9fs_vfs.h" | 40 | #include "v9fs_vfs.h" |
| 41 | #include "fid.h" | 41 | #include "fid.h" |
| 42 | 42 | ||
| @@ -50,55 +50,26 @@ | |||
| 50 | 50 | ||
| 51 | static int v9fs_vfs_readpage(struct file *filp, struct page *page) | 51 | static int v9fs_vfs_readpage(struct file *filp, struct page *page) |
| 52 | { | 52 | { |
| 53 | char *buffer = NULL; | 53 | int retval; |
| 54 | int retval = -EIO; | 54 | loff_t offset; |
| 55 | loff_t offset = page_offset(page); | 55 | char *buffer; |
| 56 | int count = PAGE_CACHE_SIZE; | 56 | struct p9_fid *fid; |
| 57 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
| 58 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | ||
| 59 | int rsize = v9ses->maxdata - V9FS_IOHDRSZ; | ||
| 60 | struct v9fs_fid *v9f = filp->private_data; | ||
| 61 | struct v9fs_fcall *fcall = NULL; | ||
| 62 | int fid = v9f->fid; | ||
| 63 | int total = 0; | ||
| 64 | int result = 0; | ||
| 65 | |||
| 66 | dprintk(DEBUG_VFS, "\n"); | ||
| 67 | 57 | ||
| 58 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); | ||
| 59 | fid = filp->private_data; | ||
| 68 | buffer = kmap(page); | 60 | buffer = kmap(page); |
| 69 | do { | 61 | offset = page_offset(page); |
| 70 | if (count < rsize) | ||
| 71 | rsize = count; | ||
| 72 | |||
| 73 | result = v9fs_t_read(v9ses, fid, offset, rsize, &fcall); | ||
| 74 | |||
| 75 | if (result < 0) { | ||
| 76 | printk(KERN_ERR "v9fs_t_read returned %d\n", | ||
| 77 | result); | ||
| 78 | |||
| 79 | kfree(fcall); | ||
| 80 | goto UnmapAndUnlock; | ||
| 81 | } else | ||
| 82 | offset += result; | ||
| 83 | |||
| 84 | memcpy(buffer, fcall->params.rread.data, result); | ||
| 85 | |||
| 86 | count -= result; | ||
| 87 | buffer += result; | ||
| 88 | total += result; | ||
| 89 | |||
| 90 | kfree(fcall); | ||
| 91 | 62 | ||
| 92 | if (result < rsize) | 63 | retval = p9_client_readn(fid, buffer, offset, PAGE_CACHE_SIZE); |
| 93 | break; | 64 | if (retval < 0) |
| 94 | } while (count); | 65 | goto done; |
| 95 | 66 | ||
| 96 | memset(buffer, 0, count); | 67 | memset(buffer + retval, 0, PAGE_CACHE_SIZE - retval); |
| 97 | flush_dcache_page(page); | 68 | flush_dcache_page(page); |
| 98 | SetPageUptodate(page); | 69 | SetPageUptodate(page); |
| 99 | retval = 0; | 70 | retval = 0; |
| 100 | 71 | ||
| 101 | UnmapAndUnlock: | 72 | done: |
| 102 | kunmap(page); | 73 | kunmap(page); |
| 103 | unlock_page(page); | 74 | unlock_page(page); |
| 104 | return retval; | 75 | return retval; |
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index d93960429c09..f9534f18df0a 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c | |||
| @@ -34,10 +34,10 @@ | |||
| 34 | #include <linux/namei.h> | 34 | #include <linux/namei.h> |
| 35 | #include <linux/idr.h> | 35 | #include <linux/idr.h> |
| 36 | #include <linux/sched.h> | 36 | #include <linux/sched.h> |
| 37 | #include <net/9p/9p.h> | ||
| 38 | #include <net/9p/client.h> | ||
| 37 | 39 | ||
| 38 | #include "debug.h" | ||
| 39 | #include "v9fs.h" | 40 | #include "v9fs.h" |
| 40 | #include "9p.h" | ||
| 41 | #include "v9fs_vfs.h" | 41 | #include "v9fs_vfs.h" |
| 42 | #include "fid.h" | 42 | #include "fid.h" |
| 43 | 43 | ||
| @@ -52,7 +52,7 @@ | |||
| 52 | 52 | ||
| 53 | static int v9fs_dentry_delete(struct dentry *dentry) | 53 | static int v9fs_dentry_delete(struct dentry *dentry) |
| 54 | { | 54 | { |
| 55 | dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); | 55 | P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); |
| 56 | 56 | ||
| 57 | return 1; | 57 | return 1; |
| 58 | } | 58 | } |
| @@ -69,7 +69,7 @@ static int v9fs_dentry_delete(struct dentry *dentry) | |||
| 69 | static int v9fs_cached_dentry_delete(struct dentry *dentry) | 69 | static int v9fs_cached_dentry_delete(struct dentry *dentry) |
| 70 | { | 70 | { |
| 71 | struct inode *inode = dentry->d_inode; | 71 | struct inode *inode = dentry->d_inode; |
| 72 | dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); | 72 | P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); |
| 73 | 73 | ||
| 74 | if(!inode) | 74 | if(!inode) |
| 75 | return 1; | 75 | return 1; |
| @@ -85,26 +85,19 @@ static int v9fs_cached_dentry_delete(struct dentry *dentry) | |||
| 85 | 85 | ||
| 86 | void v9fs_dentry_release(struct dentry *dentry) | 86 | void v9fs_dentry_release(struct dentry *dentry) |
| 87 | { | 87 | { |
| 88 | int err; | 88 | struct v9fs_dentry *dent; |
| 89 | 89 | struct p9_fid *temp, *current_fid; | |
| 90 | dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); | 90 | |
| 91 | 91 | P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); | |
| 92 | if (dentry->d_fsdata != NULL) { | 92 | dent = dentry->d_fsdata; |
| 93 | struct list_head *fid_list = dentry->d_fsdata; | 93 | if (dent) { |
| 94 | struct v9fs_fid *temp = NULL; | 94 | list_for_each_entry_safe(current_fid, temp, &dent->fidlist, |
| 95 | struct v9fs_fid *current_fid = NULL; | 95 | dlist) { |
| 96 | 96 | p9_client_clunk(current_fid); | |
| 97 | list_for_each_entry_safe(current_fid, temp, fid_list, list) { | ||
| 98 | err = v9fs_t_clunk(current_fid->v9ses, current_fid->fid); | ||
| 99 | |||
| 100 | if (err < 0) | ||
| 101 | dprintk(DEBUG_ERROR, "clunk failed: %d name %s\n", | ||
| 102 | err, dentry->d_iname); | ||
| 103 | |||
| 104 | v9fs_fid_destroy(current_fid); | ||
| 105 | } | 97 | } |
| 106 | 98 | ||
| 107 | kfree(dentry->d_fsdata); /* free the list_head */ | 99 | kfree(dent); |
| 100 | dentry->d_fsdata = NULL; | ||
| 108 | } | 101 | } |
| 109 | } | 102 | } |
| 110 | 103 | ||
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 1dd86ee90bc5..0924d4477da3 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
| @@ -32,11 +32,10 @@ | |||
| 32 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
| 33 | #include <linux/inet.h> | 33 | #include <linux/inet.h> |
| 34 | #include <linux/idr.h> | 34 | #include <linux/idr.h> |
| 35 | #include <net/9p/9p.h> | ||
| 36 | #include <net/9p/client.h> | ||
| 35 | 37 | ||
| 36 | #include "debug.h" | ||
| 37 | #include "v9fs.h" | 38 | #include "v9fs.h" |
| 38 | #include "9p.h" | ||
| 39 | #include "conv.h" | ||
| 40 | #include "v9fs_vfs.h" | 39 | #include "v9fs_vfs.h" |
| 41 | #include "fid.h" | 40 | #include "fid.h" |
| 42 | 41 | ||
| @@ -46,14 +45,14 @@ | |||
| 46 | * | 45 | * |
| 47 | */ | 46 | */ |
| 48 | 47 | ||
| 49 | static inline int dt_type(struct v9fs_stat *mistat) | 48 | static inline int dt_type(struct p9_stat *mistat) |
| 50 | { | 49 | { |
| 51 | unsigned long perm = mistat->mode; | 50 | unsigned long perm = mistat->mode; |
| 52 | int rettype = DT_REG; | 51 | int rettype = DT_REG; |
| 53 | 52 | ||
| 54 | if (perm & V9FS_DMDIR) | 53 | if (perm & P9_DMDIR) |
| 55 | rettype = DT_DIR; | 54 | rettype = DT_DIR; |
| 56 | if (perm & V9FS_DMSYMLINK) | 55 | if (perm & P9_DMSYMLINK) |
| 57 | rettype = DT_LNK; | 56 | rettype = DT_LNK; |
| 58 | 57 | ||
| 59 | return rettype; | 58 | return rettype; |
| @@ -69,106 +68,36 @@ static inline int dt_type(struct v9fs_stat *mistat) | |||
| 69 | 68 | ||
| 70 | static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) | 69 | static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) |
| 71 | { | 70 | { |
| 72 | struct v9fs_fcall *fcall = NULL; | 71 | int over; |
| 73 | struct inode *inode = filp->f_path.dentry->d_inode; | 72 | struct p9_fid *fid; |
| 74 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 73 | struct v9fs_session_info *v9ses; |
| 75 | struct v9fs_fid *file = filp->private_data; | 74 | struct inode *inode; |
| 76 | unsigned int i, n, s; | 75 | struct p9_stat *st; |
| 77 | int fid = -1; | 76 | |
| 78 | int ret = 0; | 77 | P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name); |
| 79 | struct v9fs_stat stat; | 78 | inode = filp->f_path.dentry->d_inode; |
| 80 | int over = 0; | 79 | v9ses = v9fs_inode2v9ses(inode); |
| 81 | 80 | fid = filp->private_data; | |
| 82 | dprintk(DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name); | 81 | while ((st = p9_client_dirread(fid, filp->f_pos)) != NULL) { |
| 83 | 82 | if (IS_ERR(st)) | |
| 84 | fid = file->fid; | 83 | return PTR_ERR(st); |
| 85 | 84 | ||
| 86 | if (file->rdir_fcall && (filp->f_pos != file->rdir_pos)) { | 85 | over = filldir(dirent, st->name.str, st->name.len, filp->f_pos, |
| 87 | kfree(file->rdir_fcall); | 86 | v9fs_qid2ino(&st->qid), dt_type(st)); |
| 88 | file->rdir_fcall = NULL; | 87 | |
| 89 | } | 88 | if (over) |
| 90 | |||
| 91 | if (file->rdir_fcall) { | ||
| 92 | n = file->rdir_fcall->params.rread.count; | ||
| 93 | i = file->rdir_fpos; | ||
| 94 | while (i < n) { | ||
| 95 | s = v9fs_deserialize_stat( | ||
| 96 | file->rdir_fcall->params.rread.data + i, | ||
| 97 | n - i, &stat, v9ses->extended); | ||
| 98 | |||
| 99 | if (s == 0) { | ||
| 100 | dprintk(DEBUG_ERROR, | ||
| 101 | "error while deserializing stat\n"); | ||
| 102 | ret = -EIO; | ||
| 103 | goto FreeStructs; | ||
| 104 | } | ||
| 105 | |||
| 106 | over = filldir(dirent, stat.name.str, stat.name.len, | ||
| 107 | filp->f_pos, v9fs_qid2ino(&stat.qid), | ||
| 108 | dt_type(&stat)); | ||
| 109 | |||
| 110 | if (over) { | ||
| 111 | file->rdir_fpos = i; | ||
| 112 | file->rdir_pos = filp->f_pos; | ||
| 113 | break; | ||
| 114 | } | ||
| 115 | |||
| 116 | i += s; | ||
| 117 | filp->f_pos += s; | ||
| 118 | } | ||
| 119 | |||
| 120 | if (!over) { | ||
| 121 | kfree(file->rdir_fcall); | ||
| 122 | file->rdir_fcall = NULL; | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | while (!over) { | ||
| 127 | ret = v9fs_t_read(v9ses, fid, filp->f_pos, | ||
| 128 | v9ses->maxdata-V9FS_IOHDRSZ, &fcall); | ||
| 129 | if (ret < 0) { | ||
| 130 | dprintk(DEBUG_ERROR, "error while reading: %d: %p\n", | ||
| 131 | ret, fcall); | ||
| 132 | goto FreeStructs; | ||
| 133 | } else if (ret == 0) | ||
| 134 | break; | 89 | break; |
| 135 | 90 | ||
| 136 | n = ret; | 91 | filp->f_pos += st->size; |
| 137 | i = 0; | 92 | kfree(st); |
| 138 | while (i < n) { | 93 | st = NULL; |
| 139 | s = v9fs_deserialize_stat(fcall->params.rread.data + i, | ||
| 140 | n - i, &stat, v9ses->extended); | ||
| 141 | |||
| 142 | if (s == 0) { | ||
| 143 | dprintk(DEBUG_ERROR, | ||
| 144 | "error while deserializing stat\n"); | ||
| 145 | return -EIO; | ||
| 146 | } | ||
| 147 | |||
| 148 | over = filldir(dirent, stat.name.str, stat.name.len, | ||
| 149 | filp->f_pos, v9fs_qid2ino(&stat.qid), | ||
| 150 | dt_type(&stat)); | ||
| 151 | |||
| 152 | if (over) { | ||
| 153 | file->rdir_fcall = fcall; | ||
| 154 | file->rdir_fpos = i; | ||
| 155 | file->rdir_pos = filp->f_pos; | ||
| 156 | fcall = NULL; | ||
| 157 | break; | ||
| 158 | } | ||
| 159 | |||
| 160 | i += s; | ||
| 161 | filp->f_pos += s; | ||
| 162 | } | ||
| 163 | |||
| 164 | kfree(fcall); | ||
| 165 | } | 94 | } |
| 166 | 95 | ||
| 167 | FreeStructs: | 96 | kfree(st); |
| 168 | kfree(fcall); | 97 | return 0; |
| 169 | return ret; | ||
| 170 | } | 98 | } |
| 171 | 99 | ||
| 100 | |||
| 172 | /** | 101 | /** |
| 173 | * v9fs_dir_release - close a directory | 102 | * v9fs_dir_release - close a directory |
| 174 | * @inode: inode of the directory | 103 | * @inode: inode of the directory |
| @@ -178,29 +107,13 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 178 | 107 | ||
| 179 | int v9fs_dir_release(struct inode *inode, struct file *filp) | 108 | int v9fs_dir_release(struct inode *inode, struct file *filp) |
| 180 | { | 109 | { |
| 181 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 110 | struct p9_fid *fid; |
| 182 | struct v9fs_fid *fid = filp->private_data; | ||
| 183 | int fidnum = -1; | ||
| 184 | |||
| 185 | dprintk(DEBUG_VFS, "inode: %p filp: %p fid: %d\n", inode, filp, | ||
| 186 | fid->fid); | ||
| 187 | fidnum = fid->fid; | ||
| 188 | 111 | ||
| 112 | fid = filp->private_data; | ||
| 113 | P9_DPRINTK(P9_DEBUG_VFS, | ||
| 114 | "inode: %p filp: %p fid: %d\n", inode, filp, fid->fid); | ||
| 189 | filemap_write_and_wait(inode->i_mapping); | 115 | filemap_write_and_wait(inode->i_mapping); |
| 190 | 116 | p9_client_clunk(fid); | |
| 191 | if (fidnum >= 0) { | ||
| 192 | dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen, | ||
| 193 | fid->fid); | ||
| 194 | |||
| 195 | if (v9fs_t_clunk(v9ses, fidnum)) | ||
| 196 | dprintk(DEBUG_ERROR, "clunk failed\n"); | ||
| 197 | |||
| 198 | kfree(fid->rdir_fcall); | ||
| 199 | kfree(fid); | ||
| 200 | |||
| 201 | filp->private_data = NULL; | ||
| 202 | } | ||
| 203 | |||
| 204 | return 0; | 117 | return 0; |
| 205 | } | 118 | } |
| 206 | 119 | ||
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 6e7678e4852f..c1f7c027cfeb 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
| @@ -34,10 +34,10 @@ | |||
| 34 | #include <linux/list.h> | 34 | #include <linux/list.h> |
| 35 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
| 36 | #include <linux/idr.h> | 36 | #include <linux/idr.h> |
| 37 | #include <net/9p/9p.h> | ||
| 38 | #include <net/9p/client.h> | ||
| 37 | 39 | ||
| 38 | #include "debug.h" | ||
| 39 | #include "v9fs.h" | 40 | #include "v9fs.h" |
| 40 | #include "9p.h" | ||
| 41 | #include "v9fs_vfs.h" | 41 | #include "v9fs_vfs.h" |
| 42 | #include "fid.h" | 42 | #include "fid.h" |
| 43 | 43 | ||
| @@ -52,48 +52,36 @@ static const struct file_operations v9fs_cached_file_operations; | |||
| 52 | 52 | ||
| 53 | int v9fs_file_open(struct inode *inode, struct file *file) | 53 | int v9fs_file_open(struct inode *inode, struct file *file) |
| 54 | { | 54 | { |
| 55 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | ||
| 56 | struct v9fs_fid *vfid; | ||
| 57 | struct v9fs_fcall *fcall = NULL; | ||
| 58 | int omode; | ||
| 59 | int err; | 55 | int err; |
| 56 | struct v9fs_session_info *v9ses; | ||
| 57 | struct p9_fid *fid; | ||
| 58 | int omode; | ||
| 60 | 59 | ||
| 61 | dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); | 60 | P9_DPRINTK(P9_DEBUG_VFS, "inode: %p file: %p \n", inode, file); |
| 62 | 61 | v9ses = v9fs_inode2v9ses(inode); | |
| 63 | vfid = v9fs_fid_clone(file->f_path.dentry); | ||
| 64 | if (IS_ERR(vfid)) | ||
| 65 | return PTR_ERR(vfid); | ||
| 66 | |||
| 67 | omode = v9fs_uflags2omode(file->f_flags); | 62 | omode = v9fs_uflags2omode(file->f_flags); |
| 68 | err = v9fs_t_open(v9ses, vfid->fid, omode, &fcall); | 63 | fid = file->private_data; |
| 64 | if (!fid) { | ||
| 65 | fid = v9fs_fid_clone(file->f_path.dentry); | ||
| 66 | if (IS_ERR(fid)) | ||
| 67 | return PTR_ERR(fid); | ||
| 68 | |||
| 69 | err = p9_client_open(fid, omode); | ||
| 69 | if (err < 0) { | 70 | if (err < 0) { |
| 70 | PRINT_FCALL_ERROR("open failed", fcall); | 71 | p9_client_clunk(fid); |
| 71 | goto Clunk_Fid; | 72 | return err; |
| 73 | } | ||
| 72 | } | 74 | } |
| 73 | 75 | ||
| 74 | file->private_data = vfid; | 76 | file->private_data = fid; |
| 75 | vfid->fidopen = 1; | 77 | if ((fid->qid.version) && (v9ses->cache)) { |
| 76 | vfid->fidclunked = 0; | 78 | P9_DPRINTK(P9_DEBUG_VFS, "cached"); |
| 77 | vfid->iounit = fcall->params.ropen.iounit; | ||
| 78 | vfid->rdir_pos = 0; | ||
| 79 | vfid->rdir_fcall = NULL; | ||
| 80 | vfid->filp = file; | ||
| 81 | kfree(fcall); | ||
| 82 | |||
| 83 | if((vfid->qid.version) && (v9ses->cache)) { | ||
| 84 | dprintk(DEBUG_VFS, "cached"); | ||
| 85 | /* enable cached file options */ | 79 | /* enable cached file options */ |
| 86 | if(file->f_op == &v9fs_file_operations) | 80 | if(file->f_op == &v9fs_file_operations) |
| 87 | file->f_op = &v9fs_cached_file_operations; | 81 | file->f_op = &v9fs_cached_file_operations; |
| 88 | } | 82 | } |
| 89 | 83 | ||
| 90 | return 0; | 84 | return 0; |
| 91 | |||
| 92 | Clunk_Fid: | ||
| 93 | v9fs_fid_clunk(v9ses, vfid); | ||
| 94 | kfree(fcall); | ||
| 95 | |||
| 96 | return err; | ||
| 97 | } | 85 | } |
| 98 | 86 | ||
| 99 | /** | 87 | /** |
| @@ -110,7 +98,7 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) | |||
| 110 | int res = 0; | 98 | int res = 0; |
| 111 | struct inode *inode = filp->f_path.dentry->d_inode; | 99 | struct inode *inode = filp->f_path.dentry->d_inode; |
| 112 | 100 | ||
| 113 | dprintk(DEBUG_VFS, "filp: %p lock: %p\n", filp, fl); | 101 | P9_DPRINTK(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl); |
| 114 | 102 | ||
| 115 | /* No mandatory locks */ | 103 | /* No mandatory locks */ |
| 116 | if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) | 104 | if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) |
| @@ -136,55 +124,16 @@ static ssize_t | |||
| 136 | v9fs_file_read(struct file *filp, char __user * data, size_t count, | 124 | v9fs_file_read(struct file *filp, char __user * data, size_t count, |
| 137 | loff_t * offset) | 125 | loff_t * offset) |
| 138 | { | 126 | { |
| 139 | struct inode *inode = filp->f_path.dentry->d_inode; | 127 | int ret; |
| 140 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 128 | struct p9_fid *fid; |
| 141 | struct v9fs_fid *v9f = filp->private_data; | ||
| 142 | struct v9fs_fcall *fcall = NULL; | ||
| 143 | int fid = v9f->fid; | ||
| 144 | int rsize = 0; | ||
| 145 | int result = 0; | ||
| 146 | int total = 0; | ||
| 147 | int n; | ||
| 148 | |||
| 149 | dprintk(DEBUG_VFS, "\n"); | ||
| 150 | |||
| 151 | rsize = v9ses->maxdata - V9FS_IOHDRSZ; | ||
| 152 | if (v9f->iounit != 0 && rsize > v9f->iounit) | ||
| 153 | rsize = v9f->iounit; | ||
| 154 | |||
| 155 | do { | ||
| 156 | if (count < rsize) | ||
| 157 | rsize = count; | ||
| 158 | 129 | ||
| 159 | result = v9fs_t_read(v9ses, fid, *offset, rsize, &fcall); | 130 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); |
| 131 | fid = filp->private_data; | ||
| 132 | ret = p9_client_uread(fid, data, *offset, count); | ||
| 133 | if (ret > 0) | ||
| 134 | *offset += ret; | ||
| 160 | 135 | ||
| 161 | if (result < 0) { | 136 | return ret; |
| 162 | printk(KERN_ERR "9P2000: v9fs_t_read returned %d\n", | ||
| 163 | result); | ||
| 164 | |||
| 165 | kfree(fcall); | ||
| 166 | return total; | ||
| 167 | } else | ||
| 168 | *offset += result; | ||
| 169 | |||
| 170 | n = copy_to_user(data, fcall->params.rread.data, result); | ||
| 171 | if (n) { | ||
| 172 | dprintk(DEBUG_ERROR, "Problem copying to user %d\n", n); | ||
| 173 | kfree(fcall); | ||
| 174 | return -EFAULT; | ||
| 175 | } | ||
| 176 | |||
| 177 | count -= result; | ||
| 178 | data += result; | ||
| 179 | total += result; | ||
| 180 | |||
| 181 | kfree(fcall); | ||
| 182 | |||
| 183 | if (result < rsize) | ||
| 184 | break; | ||
| 185 | } while (count); | ||
| 186 | |||
| 187 | return total; | ||
| 188 | } | 137 | } |
| 189 | 138 | ||
| 190 | /** | 139 | /** |
| @@ -200,50 +149,19 @@ static ssize_t | |||
| 200 | v9fs_file_write(struct file *filp, const char __user * data, | 149 | v9fs_file_write(struct file *filp, const char __user * data, |
| 201 | size_t count, loff_t * offset) | 150 | size_t count, loff_t * offset) |
| 202 | { | 151 | { |
| 203 | struct inode *inode = filp->f_path.dentry->d_inode; | 152 | int ret; |
| 204 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 153 | struct p9_fid *fid; |
| 205 | struct v9fs_fid *v9fid = filp->private_data; | ||
| 206 | struct v9fs_fcall *fcall; | ||
| 207 | int fid = v9fid->fid; | ||
| 208 | int result = -EIO; | ||
| 209 | int rsize = 0; | ||
| 210 | int total = 0; | ||
| 211 | |||
| 212 | dprintk(DEBUG_VFS, "data %p count %d offset %x\n", data, (int)count, | ||
| 213 | (int)*offset); | ||
| 214 | rsize = v9ses->maxdata - V9FS_IOHDRSZ; | ||
| 215 | if (v9fid->iounit != 0 && rsize > v9fid->iounit) | ||
| 216 | rsize = v9fid->iounit; | ||
| 217 | |||
| 218 | do { | ||
| 219 | if (count < rsize) | ||
| 220 | rsize = count; | ||
| 221 | 154 | ||
| 222 | result = v9fs_t_write(v9ses, fid, *offset, rsize, data, &fcall); | 155 | P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data, |
| 223 | if (result < 0) { | 156 | (int)count, (int)*offset); |
| 224 | PRINT_FCALL_ERROR("error while writing", fcall); | ||
| 225 | kfree(fcall); | ||
| 226 | return result; | ||
| 227 | } else | ||
| 228 | *offset += result; | ||
| 229 | |||
| 230 | kfree(fcall); | ||
| 231 | fcall = NULL; | ||
| 232 | |||
| 233 | if (result != rsize) { | ||
| 234 | eprintk(KERN_ERR, | ||
| 235 | "short write: v9fs_t_write returned %d\n", | ||
| 236 | result); | ||
| 237 | break; | ||
| 238 | } | ||
| 239 | 157 | ||
| 240 | count -= result; | 158 | fid = filp->private_data; |
| 241 | data += result; | 159 | ret = p9_client_uwrite(fid, data, *offset, count); |
| 242 | total += result; | 160 | if (ret > 0) |
| 243 | } while (count); | 161 | *offset += ret; |
| 244 | 162 | ||
| 245 | invalidate_inode_pages2(inode->i_mapping); | 163 | invalidate_inode_pages2(filp->f_path.dentry->d_inode->i_mapping); |
| 246 | return total; | 164 | return ret; |
| 247 | } | 165 | } |
| 248 | 166 | ||
| 249 | static const struct file_operations v9fs_cached_file_operations = { | 167 | static const struct file_operations v9fs_cached_file_operations = { |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index c76cd8fa3f6c..c602c0e054a2 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
| @@ -34,10 +34,10 @@ | |||
| 34 | #include <linux/namei.h> | 34 | #include <linux/namei.h> |
| 35 | #include <linux/idr.h> | 35 | #include <linux/idr.h> |
| 36 | #include <linux/sched.h> | 36 | #include <linux/sched.h> |
| 37 | #include <net/9p/9p.h> | ||
| 38 | #include <net/9p/client.h> | ||
| 37 | 39 | ||
| 38 | #include "debug.h" | ||
| 39 | #include "v9fs.h" | 40 | #include "v9fs.h" |
| 40 | #include "9p.h" | ||
| 41 | #include "v9fs_vfs.h" | 41 | #include "v9fs_vfs.h" |
| 42 | #include "fid.h" | 42 | #include "fid.h" |
| 43 | 43 | ||
| @@ -58,27 +58,27 @@ static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode) | |||
| 58 | int res; | 58 | int res; |
| 59 | res = mode & 0777; | 59 | res = mode & 0777; |
| 60 | if (S_ISDIR(mode)) | 60 | if (S_ISDIR(mode)) |
| 61 | res |= V9FS_DMDIR; | 61 | res |= P9_DMDIR; |
| 62 | if (v9ses->extended) { | 62 | if (v9ses->extended) { |
| 63 | if (S_ISLNK(mode)) | 63 | if (S_ISLNK(mode)) |
| 64 | res |= V9FS_DMSYMLINK; | 64 | res |= P9_DMSYMLINK; |
| 65 | if (v9ses->nodev == 0) { | 65 | if (v9ses->nodev == 0) { |
| 66 | if (S_ISSOCK(mode)) | 66 | if (S_ISSOCK(mode)) |
| 67 | res |= V9FS_DMSOCKET; | 67 | res |= P9_DMSOCKET; |
| 68 | if (S_ISFIFO(mode)) | 68 | if (S_ISFIFO(mode)) |
| 69 | res |= V9FS_DMNAMEDPIPE; | 69 | res |= P9_DMNAMEDPIPE; |
| 70 | if (S_ISBLK(mode)) | 70 | if (S_ISBLK(mode)) |
| 71 | res |= V9FS_DMDEVICE; | 71 | res |= P9_DMDEVICE; |
| 72 | if (S_ISCHR(mode)) | 72 | if (S_ISCHR(mode)) |
| 73 | res |= V9FS_DMDEVICE; | 73 | res |= P9_DMDEVICE; |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | if ((mode & S_ISUID) == S_ISUID) | 76 | if ((mode & S_ISUID) == S_ISUID) |
| 77 | res |= V9FS_DMSETUID; | 77 | res |= P9_DMSETUID; |
| 78 | if ((mode & S_ISGID) == S_ISGID) | 78 | if ((mode & S_ISGID) == S_ISGID) |
| 79 | res |= V9FS_DMSETGID; | 79 | res |= P9_DMSETGID; |
| 80 | if ((mode & V9FS_DMLINK)) | 80 | if ((mode & P9_DMLINK)) |
| 81 | res |= V9FS_DMLINK; | 81 | res |= P9_DMLINK; |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | return res; | 84 | return res; |
| @@ -97,27 +97,27 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode) | |||
| 97 | 97 | ||
| 98 | res = mode & 0777; | 98 | res = mode & 0777; |
| 99 | 99 | ||
| 100 | if ((mode & V9FS_DMDIR) == V9FS_DMDIR) | 100 | if ((mode & P9_DMDIR) == P9_DMDIR) |
| 101 | res |= S_IFDIR; | 101 | res |= S_IFDIR; |
| 102 | else if ((mode & V9FS_DMSYMLINK) && (v9ses->extended)) | 102 | else if ((mode & P9_DMSYMLINK) && (v9ses->extended)) |
| 103 | res |= S_IFLNK; | 103 | res |= S_IFLNK; |
| 104 | else if ((mode & V9FS_DMSOCKET) && (v9ses->extended) | 104 | else if ((mode & P9_DMSOCKET) && (v9ses->extended) |
| 105 | && (v9ses->nodev == 0)) | 105 | && (v9ses->nodev == 0)) |
| 106 | res |= S_IFSOCK; | 106 | res |= S_IFSOCK; |
| 107 | else if ((mode & V9FS_DMNAMEDPIPE) && (v9ses->extended) | 107 | else if ((mode & P9_DMNAMEDPIPE) && (v9ses->extended) |
| 108 | && (v9ses->nodev == 0)) | 108 | && (v9ses->nodev == 0)) |
| 109 | res |= S_IFIFO; | 109 | res |= S_IFIFO; |
| 110 | else if ((mode & V9FS_DMDEVICE) && (v9ses->extended) | 110 | else if ((mode & P9_DMDEVICE) && (v9ses->extended) |
| 111 | && (v9ses->nodev == 0)) | 111 | && (v9ses->nodev == 0)) |
| 112 | res |= S_IFBLK; | 112 | res |= S_IFBLK; |
| 113 | else | 113 | else |
| 114 | res |= S_IFREG; | 114 | res |= S_IFREG; |
| 115 | 115 | ||
| 116 | if (v9ses->extended) { | 116 | if (v9ses->extended) { |
| 117 | if ((mode & V9FS_DMSETUID) == V9FS_DMSETUID) | 117 | if ((mode & P9_DMSETUID) == P9_DMSETUID) |
| 118 | res |= S_ISUID; | 118 | res |= S_ISUID; |
| 119 | 119 | ||
| 120 | if ((mode & V9FS_DMSETGID) == V9FS_DMSETGID) | 120 | if ((mode & P9_DMSETGID) == P9_DMSETGID) |
| 121 | res |= S_ISGID; | 121 | res |= S_ISGID; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| @@ -132,26 +132,26 @@ int v9fs_uflags2omode(int uflags) | |||
| 132 | switch (uflags&3) { | 132 | switch (uflags&3) { |
| 133 | default: | 133 | default: |
| 134 | case O_RDONLY: | 134 | case O_RDONLY: |
| 135 | ret = V9FS_OREAD; | 135 | ret = P9_OREAD; |
| 136 | break; | 136 | break; |
| 137 | 137 | ||
| 138 | case O_WRONLY: | 138 | case O_WRONLY: |
| 139 | ret = V9FS_OWRITE; | 139 | ret = P9_OWRITE; |
| 140 | break; | 140 | break; |
| 141 | 141 | ||
| 142 | case O_RDWR: | 142 | case O_RDWR: |
| 143 | ret = V9FS_ORDWR; | 143 | ret = P9_ORDWR; |
| 144 | break; | 144 | break; |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | if (uflags & O_EXCL) | 147 | if (uflags & O_EXCL) |
| 148 | ret |= V9FS_OEXCL; | 148 | ret |= P9_OEXCL; |
| 149 | 149 | ||
| 150 | if (uflags & O_TRUNC) | 150 | if (uflags & O_TRUNC) |
| 151 | ret |= V9FS_OTRUNC; | 151 | ret |= P9_OTRUNC; |
| 152 | 152 | ||
| 153 | if (uflags & O_APPEND) | 153 | if (uflags & O_APPEND) |
| 154 | ret |= V9FS_OAPPEND; | 154 | ret |= P9_OAPPEND; |
| 155 | 155 | ||
| 156 | return ret; | 156 | return ret; |
| 157 | } | 157 | } |
| @@ -164,7 +164,7 @@ int v9fs_uflags2omode(int uflags) | |||
| 164 | */ | 164 | */ |
| 165 | 165 | ||
| 166 | static void | 166 | static void |
| 167 | v9fs_blank_wstat(struct v9fs_wstat *wstat) | 167 | v9fs_blank_wstat(struct p9_wstat *wstat) |
| 168 | { | 168 | { |
| 169 | wstat->type = ~0; | 169 | wstat->type = ~0; |
| 170 | wstat->dev = ~0; | 170 | wstat->dev = ~0; |
| @@ -197,7 +197,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
| 197 | struct inode *inode; | 197 | struct inode *inode; |
| 198 | struct v9fs_session_info *v9ses = sb->s_fs_info; | 198 | struct v9fs_session_info *v9ses = sb->s_fs_info; |
| 199 | 199 | ||
| 200 | dprintk(DEBUG_VFS, "super block: %p mode: %o\n", sb, mode); | 200 | P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode); |
| 201 | 201 | ||
| 202 | inode = new_inode(sb); | 202 | inode = new_inode(sb); |
| 203 | if (inode) { | 203 | if (inode) { |
| @@ -215,7 +215,8 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
| 215 | case S_IFCHR: | 215 | case S_IFCHR: |
| 216 | case S_IFSOCK: | 216 | case S_IFSOCK: |
| 217 | if(!v9ses->extended) { | 217 | if(!v9ses->extended) { |
| 218 | dprintk(DEBUG_ERROR, "special files without extended mode\n"); | 218 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 219 | "special files without extended mode\n"); | ||
| 219 | return ERR_PTR(-EINVAL); | 220 | return ERR_PTR(-EINVAL); |
| 220 | } | 221 | } |
| 221 | init_special_inode(inode, inode->i_mode, | 222 | init_special_inode(inode, inode->i_mode, |
| @@ -227,7 +228,8 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
| 227 | break; | 228 | break; |
| 228 | case S_IFLNK: | 229 | case S_IFLNK: |
| 229 | if(!v9ses->extended) { | 230 | if(!v9ses->extended) { |
| 230 | dprintk(DEBUG_ERROR, "extended modes used w/o 9P2000.u\n"); | 231 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 232 | "extended modes used w/o 9P2000.u\n"); | ||
| 231 | return ERR_PTR(-EINVAL); | 233 | return ERR_PTR(-EINVAL); |
| 232 | } | 234 | } |
| 233 | inode->i_op = &v9fs_symlink_inode_operations; | 235 | inode->i_op = &v9fs_symlink_inode_operations; |
| @@ -241,71 +243,19 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
| 241 | inode->i_fop = &v9fs_dir_operations; | 243 | inode->i_fop = &v9fs_dir_operations; |
| 242 | break; | 244 | break; |
| 243 | default: | 245 | default: |
| 244 | dprintk(DEBUG_ERROR, "BAD mode 0x%x S_IFMT 0x%x\n", | 246 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 247 | "BAD mode 0x%x S_IFMT 0x%x\n", | ||
| 245 | mode, mode & S_IFMT); | 248 | mode, mode & S_IFMT); |
| 246 | return ERR_PTR(-EINVAL); | 249 | return ERR_PTR(-EINVAL); |
| 247 | } | 250 | } |
| 248 | } else { | 251 | } else { |
| 249 | eprintk(KERN_WARNING, "Problem allocating inode\n"); | 252 | P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n"); |
| 250 | return ERR_PTR(-ENOMEM); | 253 | return ERR_PTR(-ENOMEM); |
| 251 | } | 254 | } |
| 252 | return inode; | 255 | return inode; |
| 253 | } | 256 | } |
| 254 | 257 | ||
| 255 | static int | 258 | /* |
| 256 | v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm, | ||
| 257 | u8 mode, char *extension, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) | ||
| 258 | { | ||
| 259 | int fid; | ||
| 260 | int err; | ||
| 261 | struct v9fs_fcall *fcall; | ||
| 262 | |||
| 263 | fid = v9fs_get_idpool(&v9ses->fidpool); | ||
| 264 | if (fid < 0) { | ||
| 265 | eprintk(KERN_WARNING, "no free fids available\n"); | ||
| 266 | return -ENOSPC; | ||
| 267 | } | ||
| 268 | |||
| 269 | err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); | ||
| 270 | if (err < 0) { | ||
| 271 | PRINT_FCALL_ERROR("clone error", fcall); | ||
| 272 | if (fcall && fcall->id == RWALK) | ||
| 273 | goto clunk_fid; | ||
| 274 | else | ||
| 275 | goto put_fid; | ||
| 276 | } | ||
| 277 | kfree(fcall); | ||
| 278 | |||
| 279 | err = v9fs_t_create(v9ses, fid, name, perm, mode, extension, &fcall); | ||
| 280 | if (err < 0) { | ||
| 281 | PRINT_FCALL_ERROR("create fails", fcall); | ||
| 282 | goto clunk_fid; | ||
| 283 | } | ||
| 284 | |||
| 285 | if (iounit) | ||
| 286 | *iounit = fcall->params.rcreate.iounit; | ||
| 287 | |||
| 288 | if (qid) | ||
| 289 | *qid = fcall->params.rcreate.qid; | ||
| 290 | |||
| 291 | if (fidp) | ||
| 292 | *fidp = fid; | ||
| 293 | |||
| 294 | kfree(fcall); | ||
| 295 | return 0; | ||
| 296 | |||
| 297 | clunk_fid: | ||
| 298 | v9fs_t_clunk(v9ses, fid); | ||
| 299 | fid = V9FS_NOFID; | ||
| 300 | |||
| 301 | put_fid: | ||
| 302 | if (fid != V9FS_NOFID) | ||
| 303 | v9fs_put_idpool(fid, &v9ses->fidpool); | ||
| 304 | |||
| 305 | kfree(fcall); | ||
| 306 | return err; | ||
| 307 | } | ||
| 308 | |||
| 309 | static struct v9fs_fid* | 259 | static struct v9fs_fid* |
| 310 | v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) | 260 | v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) |
| 311 | { | 261 | { |
| @@ -355,23 +305,25 @@ error: | |||
| 355 | kfree(fcall); | 305 | kfree(fcall); |
| 356 | return ERR_PTR(err); | 306 | return ERR_PTR(err); |
| 357 | } | 307 | } |
| 308 | */ | ||
| 358 | 309 | ||
| 359 | static struct inode * | 310 | static struct inode * |
| 360 | v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid, | 311 | v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, |
| 361 | struct super_block *sb) | 312 | struct super_block *sb) |
| 362 | { | 313 | { |
| 363 | int err, umode; | 314 | int err, umode; |
| 364 | struct inode *ret; | 315 | struct inode *ret; |
| 365 | struct v9fs_fcall *fcall; | 316 | struct p9_stat *st; |
| 366 | 317 | ||
| 367 | ret = NULL; | 318 | ret = NULL; |
| 368 | err = v9fs_t_stat(v9ses, fid, &fcall); | 319 | st = p9_client_stat(fid); |
| 369 | if (err) { | 320 | if (IS_ERR(st)) { |
| 370 | PRINT_FCALL_ERROR("stat error", fcall); | 321 | err = PTR_ERR(st); |
| 322 | st = NULL; | ||
| 371 | goto error; | 323 | goto error; |
| 372 | } | 324 | } |
| 373 | 325 | ||
| 374 | umode = p9mode2unixmode(v9ses, fcall->params.rstat.stat.mode); | 326 | umode = p9mode2unixmode(v9ses, st->mode); |
| 375 | ret = v9fs_get_inode(sb, umode); | 327 | ret = v9fs_get_inode(sb, umode); |
| 376 | if (IS_ERR(ret)) { | 328 | if (IS_ERR(ret)) { |
| 377 | err = PTR_ERR(ret); | 329 | err = PTR_ERR(ret); |
| @@ -379,12 +331,13 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid, | |||
| 379 | goto error; | 331 | goto error; |
| 380 | } | 332 | } |
| 381 | 333 | ||
| 382 | v9fs_stat2inode(&fcall->params.rstat.stat, ret, sb); | 334 | v9fs_stat2inode(st, ret, sb); |
| 383 | kfree(fcall); | 335 | ret->i_ino = v9fs_qid2ino(&st->qid); |
| 336 | kfree(st); | ||
| 384 | return ret; | 337 | return ret; |
| 385 | 338 | ||
| 386 | error: | 339 | error: |
| 387 | kfree(fcall); | 340 | kfree(st); |
| 388 | if (ret) | 341 | if (ret) |
| 389 | iput(ret); | 342 | iput(ret); |
| 390 | 343 | ||
| @@ -401,43 +354,20 @@ error: | |||
| 401 | 354 | ||
| 402 | static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) | 355 | static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) |
| 403 | { | 356 | { |
| 404 | struct v9fs_fcall *fcall = NULL; | 357 | struct inode *file_inode; |
| 405 | struct super_block *sb = NULL; | 358 | struct v9fs_session_info *v9ses; |
| 406 | struct v9fs_session_info *v9ses = NULL; | 359 | struct p9_fid *v9fid; |
| 407 | struct v9fs_fid *v9fid = NULL; | ||
| 408 | struct inode *file_inode = NULL; | ||
| 409 | int fid = -1; | ||
| 410 | int result = 0; | ||
| 411 | 360 | ||
| 412 | dprintk(DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file, | 361 | P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file, |
| 413 | rmdir); | 362 | rmdir); |
| 414 | 363 | ||
| 415 | file_inode = file->d_inode; | 364 | file_inode = file->d_inode; |
| 416 | sb = file_inode->i_sb; | ||
| 417 | v9ses = v9fs_inode2v9ses(file_inode); | 365 | v9ses = v9fs_inode2v9ses(file_inode); |
| 418 | v9fid = v9fs_fid_clone(file); | 366 | v9fid = v9fs_fid_clone(file); |
| 419 | if(IS_ERR(v9fid)) | 367 | if(IS_ERR(v9fid)) |
| 420 | return PTR_ERR(v9fid); | 368 | return PTR_ERR(v9fid); |
| 421 | 369 | ||
| 422 | fid = v9fid->fid; | 370 | return p9_client_remove(v9fid); |
| 423 | if (fid < 0) { | ||
| 424 | dprintk(DEBUG_ERROR, "inode #%lu, no fid!\n", | ||
| 425 | file_inode->i_ino); | ||
| 426 | return -EBADF; | ||
| 427 | } | ||
| 428 | |||
| 429 | result = v9fs_t_remove(v9ses, fid, &fcall); | ||
| 430 | if (result < 0) { | ||
| 431 | PRINT_FCALL_ERROR("remove fails", fcall); | ||
| 432 | goto Error; | ||
| 433 | } | ||
| 434 | |||
| 435 | v9fs_put_idpool(fid, &v9ses->fidpool); | ||
| 436 | v9fs_fid_destroy(v9fid); | ||
| 437 | |||
| 438 | Error: | ||
| 439 | kfree(fcall); | ||
| 440 | return result; | ||
| 441 | } | 371 | } |
| 442 | 372 | ||
| 443 | static int | 373 | static int |
| @@ -446,61 +376,59 @@ v9fs_open_created(struct inode *inode, struct file *file) | |||
| 446 | return 0; | 376 | return 0; |
| 447 | } | 377 | } |
| 448 | 378 | ||
| 379 | |||
| 449 | /** | 380 | /** |
| 450 | * v9fs_vfs_create - VFS hook to create files | 381 | * v9fs_create - Create a file |
| 451 | * @inode: directory inode that is being deleted | 382 | * @dentry: dentry that is being created |
| 452 | * @dentry: dentry that is being deleted | 383 | * @perm: create permissions |
| 453 | * @mode: create permissions | 384 | * @mode: open mode |
| 454 | * @nd: path information | ||
| 455 | * | 385 | * |
| 456 | */ | 386 | */ |
| 457 | 387 | static struct p9_fid * | |
| 458 | static int | 388 | v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, |
| 459 | v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, | 389 | struct dentry *dentry, char *extension, u32 perm, u8 mode) |
| 460 | struct nameidata *nd) | ||
| 461 | { | 390 | { |
| 462 | int err; | 391 | int err; |
| 463 | u32 fid, perm, iounit; | 392 | char *name; |
| 464 | int flags; | 393 | struct p9_fid *dfid, *ofid, *fid; |
| 465 | struct v9fs_session_info *v9ses; | ||
| 466 | struct v9fs_fid *dfid, *vfid, *ffid; | ||
| 467 | struct inode *inode; | 394 | struct inode *inode; |
| 468 | struct v9fs_qid qid; | ||
| 469 | struct file *filp; | ||
| 470 | 395 | ||
| 471 | inode = NULL; | 396 | err = 0; |
| 472 | vfid = NULL; | 397 | ofid = NULL; |
| 473 | v9ses = v9fs_inode2v9ses(dir); | 398 | fid = NULL; |
| 399 | name = (char *) dentry->d_name.name; | ||
| 474 | dfid = v9fs_fid_clone(dentry->d_parent); | 400 | dfid = v9fs_fid_clone(dentry->d_parent); |
| 475 | if(IS_ERR(dfid)) { | 401 | if(IS_ERR(dfid)) { |
| 476 | err = PTR_ERR(dfid); | 402 | err = PTR_ERR(dfid); |
| 403 | dfid = NULL; | ||
| 477 | goto error; | 404 | goto error; |
| 478 | } | 405 | } |
| 479 | 406 | ||
| 480 | perm = unixmode2p9mode(v9ses, mode); | 407 | /* clone a fid to use for creation */ |
| 481 | if (nd && nd->flags & LOOKUP_OPEN) | 408 | ofid = p9_client_walk(dfid, 0, NULL, 1); |
| 482 | flags = nd->intent.open.flags - 1; | 409 | if (IS_ERR(ofid)) { |
| 483 | else | 410 | err = PTR_ERR(ofid); |
| 484 | flags = O_RDWR; | 411 | ofid = NULL; |
| 485 | 412 | goto error; | |
| 486 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, | 413 | } |
| 487 | perm, v9fs_uflags2omode(flags), NULL, &fid, &qid, &iounit); | ||
| 488 | 414 | ||
| 489 | if (err) | 415 | err = p9_client_fcreate(ofid, name, perm, mode, extension); |
| 490 | goto clunk_dfid; | 416 | if (err < 0) |
| 417 | goto error; | ||
| 491 | 418 | ||
| 492 | vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); | 419 | /* now walk from the parent so we can get unopened fid */ |
| 493 | v9fs_fid_clunk(v9ses, dfid); | 420 | fid = p9_client_walk(dfid, 1, &name, 0); |
| 494 | if (IS_ERR(vfid)) { | 421 | if (IS_ERR(fid)) { |
| 495 | err = PTR_ERR(vfid); | 422 | err = PTR_ERR(fid); |
| 496 | vfid = NULL; | 423 | fid = NULL; |
| 497 | goto error; | 424 | goto error; |
| 498 | } | 425 | } else |
| 426 | dfid = NULL; | ||
| 499 | 427 | ||
| 500 | inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); | 428 | /* instantiate inode and assign the unopened fid to the dentry */ |
| 429 | inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); | ||
| 501 | if (IS_ERR(inode)) { | 430 | if (IS_ERR(inode)) { |
| 502 | err = PTR_ERR(inode); | 431 | err = PTR_ERR(inode); |
| 503 | inode = NULL; | ||
| 504 | goto error; | 432 | goto error; |
| 505 | } | 433 | } |
| 506 | 434 | ||
| @@ -508,35 +436,78 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
| 508 | dentry->d_op = &v9fs_cached_dentry_operations; | 436 | dentry->d_op = &v9fs_cached_dentry_operations; |
| 509 | else | 437 | else |
| 510 | dentry->d_op = &v9fs_dentry_operations; | 438 | dentry->d_op = &v9fs_dentry_operations; |
| 439 | |||
| 511 | d_instantiate(dentry, inode); | 440 | d_instantiate(dentry, inode); |
| 441 | v9fs_fid_add(dentry, fid); | ||
| 442 | return ofid; | ||
| 512 | 443 | ||
| 513 | if (nd && nd->flags & LOOKUP_OPEN) { | 444 | error: |
| 514 | ffid = v9fs_fid_create(v9ses, fid); | 445 | if (dfid) |
| 515 | if (!ffid) | 446 | p9_client_clunk(dfid); |
| 516 | return -ENOMEM; | 447 | |
| 448 | if (ofid) | ||
| 449 | p9_client_clunk(ofid); | ||
| 450 | |||
| 451 | if (fid) | ||
| 452 | p9_client_clunk(fid); | ||
| 453 | |||
| 454 | return ERR_PTR(err); | ||
| 455 | } | ||
| 456 | |||
| 457 | /** | ||
| 458 | * v9fs_vfs_create - VFS hook to create files | ||
| 459 | * @inode: directory inode that is being created | ||
| 460 | * @dentry: dentry that is being deleted | ||
| 461 | * @mode: create permissions | ||
| 462 | * @nd: path information | ||
| 463 | * | ||
| 464 | */ | ||
| 517 | 465 | ||
| 466 | static int | ||
| 467 | v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, | ||
| 468 | struct nameidata *nd) | ||
| 469 | { | ||
| 470 | int err; | ||
| 471 | u32 perm; | ||
| 472 | int flags; | ||
| 473 | struct v9fs_session_info *v9ses; | ||
| 474 | struct p9_fid *fid; | ||
| 475 | struct file *filp; | ||
| 476 | |||
| 477 | err = 0; | ||
| 478 | fid = NULL; | ||
| 479 | v9ses = v9fs_inode2v9ses(dir); | ||
| 480 | perm = unixmode2p9mode(v9ses, mode); | ||
| 481 | if (nd && nd->flags & LOOKUP_OPEN) | ||
| 482 | flags = nd->intent.open.flags - 1; | ||
| 483 | else | ||
| 484 | flags = O_RDWR; | ||
| 485 | |||
| 486 | fid = v9fs_create(v9ses, dir, dentry, NULL, perm, | ||
| 487 | v9fs_uflags2omode(flags)); | ||
| 488 | if (IS_ERR(fid)) { | ||
| 489 | err = PTR_ERR(fid); | ||
| 490 | fid = NULL; | ||
| 491 | goto error; | ||
| 492 | } | ||
| 493 | |||
| 494 | /* if we are opening a file, assign the open fid to the file */ | ||
| 495 | if (nd && nd->flags & LOOKUP_OPEN) { | ||
| 518 | filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created); | 496 | filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created); |
| 519 | if (IS_ERR(filp)) { | 497 | if (IS_ERR(filp)) { |
| 520 | v9fs_fid_destroy(ffid); | 498 | err = PTR_ERR(filp); |
| 521 | return PTR_ERR(filp); | 499 | goto error; |
| 522 | } | 500 | } |
| 523 | 501 | ||
| 524 | ffid->rdir_pos = 0; | 502 | filp->private_data = fid; |
| 525 | ffid->rdir_fcall = NULL; | 503 | } else |
| 526 | ffid->fidopen = 1; | 504 | p9_client_clunk(fid); |
| 527 | ffid->iounit = iounit; | ||
| 528 | ffid->filp = filp; | ||
| 529 | filp->private_data = ffid; | ||
| 530 | } | ||
| 531 | 505 | ||
| 532 | return 0; | 506 | return 0; |
| 533 | 507 | ||
| 534 | clunk_dfid: | ||
| 535 | v9fs_fid_clunk(v9ses, dfid); | ||
| 536 | |||
| 537 | error: | 508 | error: |
| 538 | if (vfid) | 509 | if (fid) |
| 539 | v9fs_fid_destroy(vfid); | 510 | p9_client_clunk(fid); |
| 540 | 511 | ||
| 541 | return err; | 512 | return err; |
| 542 | } | 513 | } |
| @@ -552,57 +523,23 @@ error: | |||
| 552 | static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | 523 | static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) |
| 553 | { | 524 | { |
| 554 | int err; | 525 | int err; |
| 555 | u32 fid, perm; | 526 | u32 perm; |
| 556 | struct v9fs_session_info *v9ses; | 527 | struct v9fs_session_info *v9ses; |
| 557 | struct v9fs_fid *dfid, *vfid; | 528 | struct p9_fid *fid; |
| 558 | struct inode *inode; | ||
| 559 | 529 | ||
| 560 | inode = NULL; | 530 | P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); |
| 561 | vfid = NULL; | 531 | err = 0; |
| 562 | v9ses = v9fs_inode2v9ses(dir); | 532 | v9ses = v9fs_inode2v9ses(dir); |
| 563 | dfid = v9fs_fid_clone(dentry->d_parent); | ||
| 564 | if(IS_ERR(dfid)) { | ||
| 565 | err = PTR_ERR(dfid); | ||
| 566 | goto error; | ||
| 567 | } | ||
| 568 | |||
| 569 | perm = unixmode2p9mode(v9ses, mode | S_IFDIR); | 533 | perm = unixmode2p9mode(v9ses, mode | S_IFDIR); |
| 570 | 534 | fid = v9fs_create(v9ses, dir, dentry, NULL, perm, P9_OREAD); | |
| 571 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, | 535 | if (IS_ERR(fid)) { |
| 572 | perm, V9FS_OREAD, NULL, &fid, NULL, NULL); | 536 | err = PTR_ERR(fid); |
| 573 | 537 | fid = NULL; | |
| 574 | if (err) { | ||
| 575 | dprintk(DEBUG_ERROR, "create error %d\n", err); | ||
| 576 | goto clean_up_dfid; | ||
| 577 | } | 538 | } |
| 578 | 539 | ||
| 579 | vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); | 540 | if (fid) |
| 580 | if (IS_ERR(vfid)) { | 541 | p9_client_clunk(fid); |
| 581 | err = PTR_ERR(vfid); | ||
| 582 | vfid = NULL; | ||
| 583 | goto clean_up_dfid; | ||
| 584 | } | ||
| 585 | 542 | ||
| 586 | v9fs_fid_clunk(v9ses, dfid); | ||
| 587 | inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); | ||
| 588 | if (IS_ERR(inode)) { | ||
| 589 | err = PTR_ERR(inode); | ||
| 590 | inode = NULL; | ||
| 591 | v9fs_fid_destroy(vfid); | ||
| 592 | goto error; | ||
| 593 | } | ||
| 594 | |||
| 595 | if(v9ses->cache) | ||
| 596 | dentry->d_op = &v9fs_cached_dentry_operations; | ||
| 597 | else | ||
| 598 | dentry->d_op = &v9fs_dentry_operations; | ||
| 599 | d_instantiate(dentry, inode); | ||
| 600 | return 0; | ||
| 601 | |||
| 602 | clean_up_dfid: | ||
| 603 | v9fs_fid_clunk(v9ses, dfid); | ||
| 604 | |||
| 605 | error: | ||
| 606 | return err; | 543 | return err; |
| 607 | } | 544 | } |
| 608 | 545 | ||
| @@ -619,104 +556,54 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 619 | { | 556 | { |
| 620 | struct super_block *sb; | 557 | struct super_block *sb; |
| 621 | struct v9fs_session_info *v9ses; | 558 | struct v9fs_session_info *v9ses; |
| 622 | struct v9fs_fid *dirfid; | 559 | struct p9_fid *dfid, *fid; |
| 623 | struct v9fs_fid *fid; | ||
| 624 | struct inode *inode; | 560 | struct inode *inode; |
| 625 | struct v9fs_fcall *fcall = NULL; | 561 | char *name; |
| 626 | int dirfidnum = -1; | ||
| 627 | int newfid = -1; | ||
| 628 | int result = 0; | 562 | int result = 0; |
| 629 | 563 | ||
| 630 | dprintk(DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", | 564 | P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", |
| 631 | dir, dentry->d_name.name, dentry, nameidata); | 565 | dir, dentry->d_name.name, dentry, nameidata); |
| 632 | 566 | ||
| 633 | sb = dir->i_sb; | 567 | sb = dir->i_sb; |
| 634 | v9ses = v9fs_inode2v9ses(dir); | 568 | v9ses = v9fs_inode2v9ses(dir); |
| 635 | dirfid = v9fs_fid_lookup(dentry->d_parent); | 569 | dfid = v9fs_fid_lookup(dentry->d_parent); |
| 636 | 570 | if (IS_ERR(dfid)) | |
| 637 | if(IS_ERR(dirfid)) | 571 | return ERR_PTR(PTR_ERR(dfid)); |
| 638 | return ERR_PTR(PTR_ERR(dirfid)); | 572 | |
| 639 | 573 | name = (char *) dentry->d_name.name; | |
| 640 | dirfidnum = dirfid->fid; | 574 | fid = p9_client_walk(dfid, 1, &name, 1); |
| 641 | 575 | if (IS_ERR(fid)) { | |
| 642 | newfid = v9fs_get_idpool(&v9ses->fidpool); | 576 | result = PTR_ERR(fid); |
| 643 | if (newfid < 0) { | ||
| 644 | eprintk(KERN_WARNING, "newfid fails!\n"); | ||
| 645 | result = -ENOSPC; | ||
| 646 | goto Release_Dirfid; | ||
| 647 | } | ||
| 648 | |||
| 649 | result = v9fs_t_walk(v9ses, dirfidnum, newfid, | ||
| 650 | (char *)dentry->d_name.name, &fcall); | ||
| 651 | |||
| 652 | up(&dirfid->lock); | ||
| 653 | |||
| 654 | if (result < 0) { | ||
| 655 | if (fcall && fcall->id == RWALK) | ||
| 656 | v9fs_t_clunk(v9ses, newfid); | ||
| 657 | else | ||
| 658 | v9fs_put_idpool(newfid, &v9ses->fidpool); | ||
| 659 | |||
| 660 | if (result == -ENOENT) { | 577 | if (result == -ENOENT) { |
| 661 | d_add(dentry, NULL); | 578 | d_add(dentry, NULL); |
| 662 | dprintk(DEBUG_VFS, | ||
| 663 | "Return negative dentry %p count %d\n", | ||
| 664 | dentry, atomic_read(&dentry->d_count)); | ||
| 665 | kfree(fcall); | ||
| 666 | return NULL; | 579 | return NULL; |
| 667 | } | 580 | } |
| 668 | dprintk(DEBUG_ERROR, "walk error:%d\n", result); | ||
| 669 | goto FreeFcall; | ||
| 670 | } | ||
| 671 | kfree(fcall); | ||
| 672 | |||
| 673 | result = v9fs_t_stat(v9ses, newfid, &fcall); | ||
| 674 | if (result < 0) { | ||
| 675 | dprintk(DEBUG_ERROR, "stat error\n"); | ||
| 676 | goto FreeFcall; | ||
| 677 | } | ||
| 678 | |||
| 679 | inode = v9fs_get_inode(sb, p9mode2unixmode(v9ses, | ||
| 680 | fcall->params.rstat.stat.mode)); | ||
| 681 | 581 | ||
| 682 | if (IS_ERR(inode) && (PTR_ERR(inode) == -ENOSPC)) { | 582 | return ERR_PTR(result); |
| 683 | eprintk(KERN_WARNING, "inode alloc failes, returns %ld\n", | ||
| 684 | PTR_ERR(inode)); | ||
| 685 | |||
| 686 | result = -ENOSPC; | ||
| 687 | goto FreeFcall; | ||
| 688 | } | 583 | } |
| 689 | 584 | ||
| 690 | inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat.qid); | 585 | inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); |
| 691 | 586 | if (IS_ERR(inode)) { | |
| 692 | fid = v9fs_fid_create(v9ses, newfid); | 587 | result = PTR_ERR(inode); |
| 693 | if (fid == NULL) { | 588 | inode = NULL; |
| 694 | dprintk(DEBUG_ERROR, "couldn't insert\n"); | 589 | goto error; |
| 695 | result = -ENOMEM; | ||
| 696 | goto FreeFcall; | ||
| 697 | } | 590 | } |
| 698 | 591 | ||
| 699 | result = v9fs_fid_insert(fid, dentry); | 592 | result = v9fs_fid_add(dentry, fid); |
| 700 | if (result < 0) | 593 | if (result < 0) |
| 701 | goto FreeFcall; | 594 | goto error; |
| 702 | 595 | ||
| 703 | fid->qid = fcall->params.rstat.stat.qid; | ||
| 704 | v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb); | ||
| 705 | if((fid->qid.version)&&(v9ses->cache)) | 596 | if((fid->qid.version)&&(v9ses->cache)) |
| 706 | dentry->d_op = &v9fs_cached_dentry_operations; | 597 | dentry->d_op = &v9fs_cached_dentry_operations; |
| 707 | else | 598 | else |
| 708 | dentry->d_op = &v9fs_dentry_operations; | 599 | dentry->d_op = &v9fs_dentry_operations; |
| 709 | 600 | ||
| 710 | d_add(dentry, inode); | 601 | d_add(dentry, inode); |
| 711 | kfree(fcall); | ||
| 712 | |||
| 713 | return NULL; | 602 | return NULL; |
| 714 | 603 | ||
| 715 | Release_Dirfid: | 604 | error: |
| 716 | up(&dirfid->lock); | 605 | if (fid) |
| 717 | 606 | p9_client_clunk(fid); | |
| 718 | FreeFcall: | ||
| 719 | kfree(fcall); | ||
| 720 | 607 | ||
| 721 | return ERR_PTR(result); | 608 | return ERR_PTR(result); |
| 722 | } | 609 | } |
| @@ -758,73 +645,54 @@ static int | |||
| 758 | v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | 645 | v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, |
| 759 | struct inode *new_dir, struct dentry *new_dentry) | 646 | struct inode *new_dir, struct dentry *new_dentry) |
| 760 | { | 647 | { |
| 761 | struct inode *old_inode = old_dentry->d_inode; | 648 | struct inode *old_inode; |
| 762 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode); | 649 | struct v9fs_session_info *v9ses; |
| 763 | struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry); | 650 | struct p9_fid *oldfid; |
| 764 | struct v9fs_fid *olddirfid; | 651 | struct p9_fid *olddirfid; |
| 765 | struct v9fs_fid *newdirfid; | 652 | struct p9_fid *newdirfid; |
| 766 | struct v9fs_wstat wstat; | 653 | struct p9_wstat wstat; |
| 767 | struct v9fs_fcall *fcall = NULL; | 654 | int retval; |
| 768 | int fid = -1; | ||
| 769 | int olddirfidnum = -1; | ||
| 770 | int newdirfidnum = -1; | ||
| 771 | int retval = 0; | ||
| 772 | |||
| 773 | dprintk(DEBUG_VFS, "\n"); | ||
| 774 | 655 | ||
| 656 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); | ||
| 657 | retval = 0; | ||
| 658 | old_inode = old_dentry->d_inode; | ||
| 659 | v9ses = v9fs_inode2v9ses(old_inode); | ||
| 660 | oldfid = v9fs_fid_lookup(old_dentry); | ||
| 775 | if(IS_ERR(oldfid)) | 661 | if(IS_ERR(oldfid)) |
| 776 | return PTR_ERR(oldfid); | 662 | return PTR_ERR(oldfid); |
| 777 | 663 | ||
| 778 | olddirfid = v9fs_fid_clone(old_dentry->d_parent); | 664 | olddirfid = v9fs_fid_clone(old_dentry->d_parent); |
| 779 | if(IS_ERR(olddirfid)) { | 665 | if(IS_ERR(olddirfid)) { |
| 780 | retval = PTR_ERR(olddirfid); | 666 | retval = PTR_ERR(olddirfid); |
| 781 | goto Release_lock; | 667 | goto done; |
| 782 | } | 668 | } |
| 783 | 669 | ||
| 784 | newdirfid = v9fs_fid_clone(new_dentry->d_parent); | 670 | newdirfid = v9fs_fid_clone(new_dentry->d_parent); |
| 785 | if(IS_ERR(newdirfid)) { | 671 | if(IS_ERR(newdirfid)) { |
| 786 | retval = PTR_ERR(newdirfid); | 672 | retval = PTR_ERR(newdirfid); |
| 787 | goto Clunk_olddir; | 673 | goto clunk_olddir; |
| 788 | } | 674 | } |
| 789 | 675 | ||
| 790 | /* 9P can only handle file rename in the same directory */ | 676 | /* 9P can only handle file rename in the same directory */ |
| 791 | if (memcmp(&olddirfid->qid, &newdirfid->qid, sizeof(newdirfid->qid))) { | 677 | if (memcmp(&olddirfid->qid, &newdirfid->qid, sizeof(newdirfid->qid))) { |
| 792 | dprintk(DEBUG_ERROR, "old dir and new dir are different\n"); | 678 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 679 | "old dir and new dir are different\n"); | ||
| 793 | retval = -EXDEV; | 680 | retval = -EXDEV; |
| 794 | goto Clunk_newdir; | 681 | goto clunk_newdir; |
| 795 | } | ||
| 796 | |||
| 797 | fid = oldfid->fid; | ||
| 798 | olddirfidnum = olddirfid->fid; | ||
| 799 | newdirfidnum = newdirfid->fid; | ||
| 800 | |||
| 801 | if (fid < 0) { | ||
| 802 | dprintk(DEBUG_ERROR, "no fid for old file #%lu\n", | ||
| 803 | old_inode->i_ino); | ||
| 804 | retval = -EBADF; | ||
| 805 | goto Clunk_newdir; | ||
| 806 | } | 682 | } |
| 807 | 683 | ||
| 808 | v9fs_blank_wstat(&wstat); | 684 | v9fs_blank_wstat(&wstat); |
| 809 | wstat.muid = v9ses->name; | 685 | wstat.muid = v9ses->name; |
| 810 | wstat.name = (char *) new_dentry->d_name.name; | 686 | wstat.name = (char *) new_dentry->d_name.name; |
| 687 | retval = p9_client_wstat(oldfid, &wstat); | ||
| 811 | 688 | ||
| 812 | retval = v9fs_t_wstat(v9ses, fid, &wstat, &fcall); | 689 | clunk_newdir: |
| 690 | p9_client_clunk(olddirfid); | ||
| 813 | 691 | ||
| 814 | if (retval < 0) | 692 | clunk_olddir: |
| 815 | PRINT_FCALL_ERROR("wstat error", fcall); | 693 | p9_client_clunk(newdirfid); |
| 816 | |||
| 817 | kfree(fcall); | ||
| 818 | |||
| 819 | Clunk_newdir: | ||
| 820 | v9fs_fid_clunk(v9ses, newdirfid); | ||
| 821 | |||
| 822 | Clunk_olddir: | ||
| 823 | v9fs_fid_clunk(v9ses, olddirfid); | ||
| 824 | |||
| 825 | Release_lock: | ||
| 826 | up(&oldfid->lock); | ||
| 827 | 694 | ||
| 695 | done: | ||
| 828 | return retval; | 696 | return retval; |
| 829 | } | 697 | } |
| 830 | 698 | ||
| @@ -840,28 +708,27 @@ static int | |||
| 840 | v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | 708 | v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, |
| 841 | struct kstat *stat) | 709 | struct kstat *stat) |
| 842 | { | 710 | { |
| 843 | struct v9fs_fcall *fcall = NULL; | 711 | int err; |
| 844 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); | 712 | struct v9fs_session_info *v9ses; |
| 845 | struct v9fs_fid *fid = v9fs_fid_clone(dentry); | 713 | struct p9_fid *fid; |
| 846 | int err = -EPERM; | 714 | struct p9_stat *st; |
| 847 | 715 | ||
| 848 | dprintk(DEBUG_VFS, "dentry: %p\n", dentry); | 716 | P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); |
| 849 | if(IS_ERR(fid)) | 717 | err = -EPERM; |
| 718 | v9ses = v9fs_inode2v9ses(dentry->d_inode); | ||
| 719 | fid = v9fs_fid_lookup(dentry); | ||
| 720 | if (IS_ERR(fid)) | ||
| 850 | return PTR_ERR(fid); | 721 | return PTR_ERR(fid); |
| 851 | 722 | ||
| 852 | err = v9fs_t_stat(v9ses, fid->fid, &fcall); | 723 | st = p9_client_stat(fid); |
| 724 | if (IS_ERR(st)) | ||
| 725 | return PTR_ERR(st); | ||
| 853 | 726 | ||
| 854 | if (err < 0) | 727 | v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb); |
| 855 | dprintk(DEBUG_ERROR, "stat error\n"); | ||
| 856 | else { | ||
| 857 | v9fs_stat2inode(&fcall->params.rstat.stat, dentry->d_inode, | ||
| 858 | dentry->d_inode->i_sb); | ||
| 859 | generic_fillattr(dentry->d_inode, stat); | 728 | generic_fillattr(dentry->d_inode, stat); |
| 860 | } | ||
| 861 | 729 | ||
| 862 | kfree(fcall); | 730 | kfree(st); |
| 863 | v9fs_fid_clunk(v9ses, fid); | 731 | return 0; |
| 864 | return err; | ||
| 865 | } | 732 | } |
| 866 | 733 | ||
| 867 | /** | 734 | /** |
| @@ -873,13 +740,15 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
| 873 | 740 | ||
| 874 | static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) | 741 | static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) |
| 875 | { | 742 | { |
| 876 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); | 743 | int retval; |
| 877 | struct v9fs_fid *fid = v9fs_fid_clone(dentry); | 744 | struct v9fs_session_info *v9ses; |
| 878 | struct v9fs_fcall *fcall = NULL; | 745 | struct p9_fid *fid; |
| 879 | struct v9fs_wstat wstat; | 746 | struct p9_wstat wstat; |
| 880 | int res = -EPERM; | ||
| 881 | 747 | ||
| 882 | dprintk(DEBUG_VFS, "\n"); | 748 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); |
| 749 | retval = -EPERM; | ||
| 750 | v9ses = v9fs_inode2v9ses(dentry->d_inode); | ||
| 751 | fid = v9fs_fid_lookup(dentry); | ||
| 883 | if(IS_ERR(fid)) | 752 | if(IS_ERR(fid)) |
| 884 | return PTR_ERR(fid); | 753 | return PTR_ERR(fid); |
| 885 | 754 | ||
| @@ -904,17 +773,11 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
| 904 | wstat.n_gid = iattr->ia_gid; | 773 | wstat.n_gid = iattr->ia_gid; |
| 905 | } | 774 | } |
| 906 | 775 | ||
| 907 | res = v9fs_t_wstat(v9ses, fid->fid, &wstat, &fcall); | 776 | retval = p9_client_wstat(fid, &wstat); |
| 777 | if (retval >= 0) | ||
| 778 | retval = inode_setattr(dentry->d_inode, iattr); | ||
| 908 | 779 | ||
| 909 | if (res < 0) | 780 | return retval; |
| 910 | PRINT_FCALL_ERROR("wstat error", fcall); | ||
| 911 | |||
| 912 | kfree(fcall); | ||
| 913 | if (res >= 0) | ||
| 914 | res = inode_setattr(dentry->d_inode, iattr); | ||
| 915 | |||
| 916 | v9fs_fid_clunk(v9ses, fid); | ||
| 917 | return res; | ||
| 918 | } | 781 | } |
| 919 | 782 | ||
| 920 | /** | 783 | /** |
| @@ -926,7 +789,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
| 926 | */ | 789 | */ |
| 927 | 790 | ||
| 928 | void | 791 | void |
| 929 | v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode, | 792 | v9fs_stat2inode(struct p9_stat *stat, struct inode *inode, |
| 930 | struct super_block *sb) | 793 | struct super_block *sb) |
| 931 | { | 794 | { |
| 932 | int n; | 795 | int n; |
| @@ -967,8 +830,9 @@ v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode, | |||
| 967 | case 'b': | 830 | case 'b': |
| 968 | break; | 831 | break; |
| 969 | default: | 832 | default: |
| 970 | dprintk(DEBUG_ERROR, "Unknown special type %c (%.*s)\n", | 833 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 971 | type, stat->extension.len, stat->extension.str); | 834 | "Unknown special type %c (%.*s)\n", type, |
| 835 | stat->extension.len, stat->extension.str); | ||
| 972 | }; | 836 | }; |
| 973 | inode->i_rdev = MKDEV(major, minor); | 837 | inode->i_rdev = MKDEV(major, minor); |
| 974 | } else | 838 | } else |
| @@ -976,8 +840,8 @@ v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode, | |||
| 976 | 840 | ||
| 977 | inode->i_size = stat->length; | 841 | inode->i_size = stat->length; |
| 978 | 842 | ||
| 979 | inode->i_blocks = | 843 | /* not real number of blocks, but 512 byte ones ... */ |
| 980 | (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; | 844 | inode->i_blocks = (inode->i_size + 512 - 1) >> 9; |
| 981 | } | 845 | } |
| 982 | 846 | ||
| 983 | /** | 847 | /** |
| @@ -987,7 +851,7 @@ v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode, | |||
| 987 | * BUG: potential for inode number collisions? | 851 | * BUG: potential for inode number collisions? |
| 988 | */ | 852 | */ |
| 989 | 853 | ||
| 990 | ino_t v9fs_qid2ino(struct v9fs_qid *qid) | 854 | ino_t v9fs_qid2ino(struct p9_qid *qid) |
| 991 | { | 855 | { |
| 992 | u64 path = qid->path + 2; | 856 | u64 path = qid->path + 2; |
| 993 | ino_t i = 0; | 857 | ino_t i = 0; |
| @@ -1010,56 +874,46 @@ ino_t v9fs_qid2ino(struct v9fs_qid *qid) | |||
| 1010 | 874 | ||
| 1011 | static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | 875 | static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) |
| 1012 | { | 876 | { |
| 1013 | int retval = -EPERM; | 877 | int retval; |
| 1014 | 878 | ||
| 1015 | struct v9fs_fcall *fcall = NULL; | 879 | struct v9fs_session_info *v9ses; |
| 1016 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); | 880 | struct p9_fid *fid; |
| 1017 | struct v9fs_fid *fid = v9fs_fid_clone(dentry); | 881 | struct p9_stat *st; |
| 1018 | 882 | ||
| 883 | P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name); | ||
| 884 | retval = -EPERM; | ||
| 885 | v9ses = v9fs_inode2v9ses(dentry->d_inode); | ||
| 886 | fid = v9fs_fid_lookup(dentry); | ||
| 1019 | if(IS_ERR(fid)) | 887 | if(IS_ERR(fid)) |
| 1020 | return PTR_ERR(fid); | 888 | return PTR_ERR(fid); |
| 1021 | 889 | ||
| 1022 | if (!v9ses->extended) { | 890 | if (!v9ses->extended) |
| 1023 | retval = -EBADF; | 891 | return -EBADF; |
| 1024 | dprintk(DEBUG_ERROR, "not extended\n"); | ||
| 1025 | goto ClunkFid; | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | dprintk(DEBUG_VFS, " %s\n", dentry->d_name.name); | ||
| 1029 | retval = v9fs_t_stat(v9ses, fid->fid, &fcall); | ||
| 1030 | |||
| 1031 | if (retval < 0) { | ||
| 1032 | dprintk(DEBUG_ERROR, "stat error\n"); | ||
| 1033 | goto FreeFcall; | ||
| 1034 | } | ||
| 1035 | 892 | ||
| 1036 | if (!fcall) { | 893 | st = p9_client_stat(fid); |
| 1037 | retval = -EIO; | 894 | if (IS_ERR(st)) |
| 1038 | goto ClunkFid; | 895 | return PTR_ERR(st); |
| 1039 | } | ||
| 1040 | 896 | ||
| 1041 | if (!(fcall->params.rstat.stat.mode & V9FS_DMSYMLINK)) { | 897 | if (!(st->mode & P9_DMSYMLINK)) { |
| 1042 | retval = -EINVAL; | 898 | retval = -EINVAL; |
| 1043 | goto FreeFcall; | 899 | goto done; |
| 1044 | } | 900 | } |
| 1045 | 901 | ||
| 1046 | /* copy extension buffer into buffer */ | 902 | /* copy extension buffer into buffer */ |
| 1047 | if (fcall->params.rstat.stat.extension.len < buflen) | 903 | if (st->extension.len < buflen) |
| 1048 | buflen = fcall->params.rstat.stat.extension.len + 1; | 904 | buflen = st->extension.len + 1; |
| 1049 | 905 | ||
| 1050 | memmove(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); | 906 | memmove(buffer, st->extension.str, buflen - 1); |
| 1051 | buffer[buflen-1] = 0; | 907 | buffer[buflen-1] = 0; |
| 1052 | 908 | ||
| 1053 | dprintk(DEBUG_ERROR, "%s -> %.*s (%s)\n", dentry->d_name.name, fcall->params.rstat.stat.extension.len, | 909 | P9_DPRINTK(P9_DEBUG_VFS, |
| 1054 | fcall->params.rstat.stat.extension.str, buffer); | 910 | "%s -> %.*s (%s)\n", dentry->d_name.name, st->extension.len, |
| 1055 | retval = buflen; | 911 | st->extension.str, buffer); |
| 1056 | 912 | ||
| 1057 | FreeFcall: | 913 | retval = buflen; |
| 1058 | kfree(fcall); | ||
| 1059 | |||
| 1060 | ClunkFid: | ||
| 1061 | v9fs_fid_clunk(v9ses, fid); | ||
| 1062 | 914 | ||
| 915 | done: | ||
| 916 | kfree(st); | ||
| 1063 | return retval; | 917 | return retval; |
| 1064 | } | 918 | } |
| 1065 | 919 | ||
| @@ -1084,14 +938,14 @@ static int v9fs_vfs_readlink(struct dentry *dentry, char __user * buffer, | |||
| 1084 | if (buflen > PATH_MAX) | 938 | if (buflen > PATH_MAX) |
| 1085 | buflen = PATH_MAX; | 939 | buflen = PATH_MAX; |
| 1086 | 940 | ||
| 1087 | dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); | 941 | P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); |
| 1088 | 942 | ||
| 1089 | retval = v9fs_readlink(dentry, link, buflen); | 943 | retval = v9fs_readlink(dentry, link, buflen); |
| 1090 | 944 | ||
| 1091 | if (retval > 0) { | 945 | if (retval > 0) { |
| 1092 | if ((ret = copy_to_user(buffer, link, retval)) != 0) { | 946 | if ((ret = copy_to_user(buffer, link, retval)) != 0) { |
| 1093 | dprintk(DEBUG_ERROR, "problem copying to user: %d\n", | 947 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 1094 | ret); | 948 | "problem copying to user: %d\n", ret); |
| 1095 | retval = ret; | 949 | retval = ret; |
| 1096 | } | 950 | } |
| 1097 | } | 951 | } |
| @@ -1112,7 +966,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
| 1112 | int len = 0; | 966 | int len = 0; |
| 1113 | char *link = __getname(); | 967 | char *link = __getname(); |
| 1114 | 968 | ||
| 1115 | dprintk(DEBUG_VFS, "%s n", dentry->d_name.name); | 969 | P9_DPRINTK(P9_DEBUG_VFS, "%s n", dentry->d_name.name); |
| 1116 | 970 | ||
| 1117 | if (!link) | 971 | if (!link) |
| 1118 | link = ERR_PTR(-ENOMEM); | 972 | link = ERR_PTR(-ENOMEM); |
| @@ -1141,7 +995,7 @@ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void | |||
| 1141 | { | 995 | { |
| 1142 | char *s = nd_get_link(nd); | 996 | char *s = nd_get_link(nd); |
| 1143 | 997 | ||
| 1144 | dprintk(DEBUG_VFS, " %s %s\n", dentry->d_name.name, s); | 998 | P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s); |
| 1145 | if (!IS_ERR(s)) | 999 | if (!IS_ERR(s)) |
| 1146 | __putname(s); | 1000 | __putname(s); |
| 1147 | } | 1001 | } |
| @@ -1149,66 +1003,24 @@ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void | |||
| 1149 | static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, | 1003 | static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, |
| 1150 | int mode, const char *extension) | 1004 | int mode, const char *extension) |
| 1151 | { | 1005 | { |
| 1152 | int err; | 1006 | u32 perm; |
| 1153 | u32 fid, perm; | ||
| 1154 | struct v9fs_session_info *v9ses; | 1007 | struct v9fs_session_info *v9ses; |
| 1155 | struct v9fs_fid *dfid, *vfid = NULL; | 1008 | struct p9_fid *fid; |
| 1156 | struct inode *inode = NULL; | ||
| 1157 | 1009 | ||
| 1158 | v9ses = v9fs_inode2v9ses(dir); | 1010 | v9ses = v9fs_inode2v9ses(dir); |
| 1159 | if (!v9ses->extended) { | 1011 | if (!v9ses->extended) { |
| 1160 | dprintk(DEBUG_ERROR, "not extended\n"); | 1012 | P9_DPRINTK(P9_DEBUG_ERROR, "not extended\n"); |
| 1161 | return -EPERM; | 1013 | return -EPERM; |
| 1162 | } | 1014 | } |
| 1163 | 1015 | ||
| 1164 | dfid = v9fs_fid_clone(dentry->d_parent); | ||
| 1165 | if(IS_ERR(dfid)) { | ||
| 1166 | err = PTR_ERR(dfid); | ||
| 1167 | goto error; | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | perm = unixmode2p9mode(v9ses, mode); | 1016 | perm = unixmode2p9mode(v9ses, mode); |
| 1017 | fid = v9fs_create(v9ses, dir, dentry, (char *) extension, perm, | ||
| 1018 | P9_OREAD); | ||
| 1019 | if (IS_ERR(fid)) | ||
| 1020 | return PTR_ERR(fid); | ||
| 1171 | 1021 | ||
| 1172 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, | 1022 | p9_client_clunk(fid); |
| 1173 | perm, V9FS_OREAD, (char *) extension, &fid, NULL, NULL); | ||
| 1174 | |||
| 1175 | if (err) | ||
| 1176 | goto clunk_dfid; | ||
| 1177 | |||
| 1178 | err = v9fs_t_clunk(v9ses, fid); | ||
| 1179 | if (err) | ||
| 1180 | goto clunk_dfid; | ||
| 1181 | |||
| 1182 | vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); | ||
| 1183 | if (IS_ERR(vfid)) { | ||
| 1184 | err = PTR_ERR(vfid); | ||
| 1185 | vfid = NULL; | ||
| 1186 | goto clunk_dfid; | ||
| 1187 | } | ||
| 1188 | |||
| 1189 | inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); | ||
| 1190 | if (IS_ERR(inode)) { | ||
| 1191 | err = PTR_ERR(inode); | ||
| 1192 | inode = NULL; | ||
| 1193 | goto free_vfid; | ||
| 1194 | } | ||
| 1195 | |||
| 1196 | if(v9ses->cache) | ||
| 1197 | dentry->d_op = &v9fs_cached_dentry_operations; | ||
| 1198 | else | ||
| 1199 | dentry->d_op = &v9fs_dentry_operations; | ||
| 1200 | d_instantiate(dentry, inode); | ||
| 1201 | return 0; | 1023 | return 0; |
| 1202 | |||
| 1203 | free_vfid: | ||
| 1204 | v9fs_fid_destroy(vfid); | ||
| 1205 | |||
| 1206 | clunk_dfid: | ||
| 1207 | v9fs_fid_clunk(v9ses, dfid); | ||
| 1208 | |||
| 1209 | error: | ||
| 1210 | return err; | ||
| 1211 | |||
| 1212 | } | 1024 | } |
| 1213 | 1025 | ||
| 1214 | /** | 1026 | /** |
| @@ -1224,8 +1036,8 @@ error: | |||
| 1224 | static int | 1036 | static int |
| 1225 | v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) | 1037 | v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) |
| 1226 | { | 1038 | { |
| 1227 | dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, | 1039 | P9_DPRINTK(P9_DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, |
| 1228 | symname); | 1040 | dentry->d_name.name, symname); |
| 1229 | 1041 | ||
| 1230 | return v9fs_vfs_mkspecial(dir, dentry, S_IFLNK, symname); | 1042 | return v9fs_vfs_mkspecial(dir, dentry, S_IFLNK, symname); |
| 1231 | } | 1043 | } |
| @@ -1247,11 +1059,11 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 1247 | struct dentry *dentry) | 1059 | struct dentry *dentry) |
| 1248 | { | 1060 | { |
| 1249 | int retval; | 1061 | int retval; |
| 1250 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); | 1062 | struct p9_fid *oldfid; |
| 1251 | struct v9fs_fid *oldfid; | ||
| 1252 | char *name; | 1063 | char *name; |
| 1253 | 1064 | ||
| 1254 | dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, | 1065 | P9_DPRINTK(P9_DEBUG_VFS, |
| 1066 | " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, | ||
| 1255 | old_dentry->d_name.name); | 1067 | old_dentry->d_name.name); |
| 1256 | 1068 | ||
| 1257 | oldfid = v9fs_fid_clone(old_dentry); | 1069 | oldfid = v9fs_fid_clone(old_dentry); |
| @@ -1265,11 +1077,11 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 1265 | } | 1077 | } |
| 1266 | 1078 | ||
| 1267 | sprintf(name, "%d\n", oldfid->fid); | 1079 | sprintf(name, "%d\n", oldfid->fid); |
| 1268 | retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name); | 1080 | retval = v9fs_vfs_mkspecial(dir, dentry, P9_DMLINK, name); |
| 1269 | __putname(name); | 1081 | __putname(name); |
| 1270 | 1082 | ||
| 1271 | clunk_fid: | 1083 | clunk_fid: |
| 1272 | v9fs_fid_clunk(v9ses, oldfid); | 1084 | p9_client_clunk(oldfid); |
| 1273 | return retval; | 1085 | return retval; |
| 1274 | } | 1086 | } |
| 1275 | 1087 | ||
| @@ -1288,7 +1100,8 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) | |||
| 1288 | int retval; | 1100 | int retval; |
| 1289 | char *name; | 1101 | char *name; |
| 1290 | 1102 | ||
| 1291 | dprintk(DEBUG_VFS, " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, | 1103 | P9_DPRINTK(P9_DEBUG_VFS, |
| 1104 | " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, | ||
| 1292 | dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); | 1105 | dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); |
| 1293 | 1106 | ||
| 1294 | if (!new_valid_dev(rdev)) | 1107 | if (!new_valid_dev(rdev)) |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 7bdf8b326841..f6a0519ade8c 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
| @@ -37,10 +37,10 @@ | |||
| 37 | #include <linux/mount.h> | 37 | #include <linux/mount.h> |
| 38 | #include <linux/idr.h> | 38 | #include <linux/idr.h> |
| 39 | #include <linux/sched.h> | 39 | #include <linux/sched.h> |
| 40 | #include <net/9p/9p.h> | ||
| 41 | #include <net/9p/client.h> | ||
| 40 | 42 | ||
| 41 | #include "debug.h" | ||
| 42 | #include "v9fs.h" | 43 | #include "v9fs.h" |
| 43 | #include "9p.h" | ||
| 44 | #include "v9fs_vfs.h" | 44 | #include "v9fs_vfs.h" |
| 45 | #include "fid.h" | 45 | #include "fid.h" |
| 46 | 46 | ||
| @@ -107,41 +107,48 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, | |||
| 107 | struct vfsmount *mnt) | 107 | struct vfsmount *mnt) |
| 108 | { | 108 | { |
| 109 | struct super_block *sb = NULL; | 109 | struct super_block *sb = NULL; |
| 110 | struct v9fs_fcall *fcall = NULL; | ||
| 111 | struct inode *inode = NULL; | 110 | struct inode *inode = NULL; |
| 112 | struct dentry *root = NULL; | 111 | struct dentry *root = NULL; |
| 113 | struct v9fs_session_info *v9ses = NULL; | 112 | struct v9fs_session_info *v9ses = NULL; |
| 114 | struct v9fs_fid *root_fid = NULL; | 113 | struct p9_stat *st = NULL; |
| 115 | int mode = S_IRWXUGO | S_ISVTX; | 114 | int mode = S_IRWXUGO | S_ISVTX; |
| 116 | uid_t uid = current->fsuid; | 115 | uid_t uid = current->fsuid; |
| 117 | gid_t gid = current->fsgid; | 116 | gid_t gid = current->fsgid; |
| 118 | int stat_result = 0; | 117 | struct p9_fid *fid; |
| 119 | int newfid = 0; | ||
| 120 | int retval = 0; | 118 | int retval = 0; |
| 121 | 119 | ||
| 122 | dprintk(DEBUG_VFS, " \n"); | 120 | P9_DPRINTK(P9_DEBUG_VFS, " \n"); |
| 123 | 121 | ||
| 124 | v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL); | 122 | v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL); |
| 125 | if (!v9ses) | 123 | if (!v9ses) |
| 126 | return -ENOMEM; | 124 | return -ENOMEM; |
| 127 | 125 | ||
| 128 | if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { | 126 | fid = v9fs_session_init(v9ses, dev_name, data); |
| 129 | dprintk(DEBUG_ERROR, "problem initiating session\n"); | 127 | if (IS_ERR(fid)) { |
| 130 | retval = newfid; | 128 | retval = PTR_ERR(fid); |
| 131 | goto out_free_session; | 129 | fid = NULL; |
| 130 | kfree(v9ses); | ||
| 131 | v9ses = NULL; | ||
| 132 | goto error; | ||
| 133 | } | ||
| 134 | |||
| 135 | st = p9_client_stat(fid); | ||
| 136 | if (IS_ERR(st)) { | ||
| 137 | retval = PTR_ERR(st); | ||
| 138 | goto error; | ||
| 132 | } | 139 | } |
| 133 | 140 | ||
| 134 | sb = sget(fs_type, NULL, v9fs_set_super, v9ses); | 141 | sb = sget(fs_type, NULL, v9fs_set_super, v9ses); |
| 135 | if (IS_ERR(sb)) { | 142 | if (IS_ERR(sb)) { |
| 136 | retval = PTR_ERR(sb); | 143 | retval = PTR_ERR(sb); |
| 137 | goto out_close_session; | 144 | goto error; |
| 138 | } | 145 | } |
| 139 | v9fs_fill_super(sb, v9ses, flags); | 146 | v9fs_fill_super(sb, v9ses, flags); |
| 140 | 147 | ||
| 141 | inode = v9fs_get_inode(sb, S_IFDIR | mode); | 148 | inode = v9fs_get_inode(sb, S_IFDIR | mode); |
| 142 | if (IS_ERR(inode)) { | 149 | if (IS_ERR(inode)) { |
| 143 | retval = PTR_ERR(inode); | 150 | retval = PTR_ERR(inode); |
| 144 | goto put_back_sb; | 151 | goto error; |
| 145 | } | 152 | } |
| 146 | 153 | ||
| 147 | inode->i_uid = uid; | 154 | inode->i_uid = uid; |
| @@ -150,54 +157,30 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, | |||
| 150 | root = d_alloc_root(inode); | 157 | root = d_alloc_root(inode); |
| 151 | if (!root) { | 158 | if (!root) { |
| 152 | retval = -ENOMEM; | 159 | retval = -ENOMEM; |
| 153 | goto put_back_sb; | 160 | goto error; |
| 154 | } | 161 | } |
| 155 | 162 | ||
| 156 | sb->s_root = root; | 163 | sb->s_root = root; |
| 164 | root->d_inode->i_ino = v9fs_qid2ino(&st->qid); | ||
| 165 | v9fs_stat2inode(st, root->d_inode, sb); | ||
| 166 | v9fs_fid_add(root, fid); | ||
| 157 | 167 | ||
| 158 | stat_result = v9fs_t_stat(v9ses, newfid, &fcall); | 168 | return simple_set_mnt(mnt, sb); |
| 159 | if (stat_result < 0) { | ||
| 160 | dprintk(DEBUG_ERROR, "stat error\n"); | ||
| 161 | v9fs_t_clunk(v9ses, newfid); | ||
| 162 | } else { | ||
| 163 | /* Setup the Root Inode */ | ||
| 164 | root_fid = v9fs_fid_create(v9ses, newfid); | ||
| 165 | if (root_fid == NULL) { | ||
| 166 | retval = -ENOMEM; | ||
| 167 | goto put_back_sb; | ||
| 168 | } | ||
| 169 | |||
| 170 | retval = v9fs_fid_insert(root_fid, root); | ||
| 171 | if (retval < 0) { | ||
| 172 | kfree(fcall); | ||
| 173 | goto put_back_sb; | ||
| 174 | } | ||
| 175 | |||
| 176 | root_fid->qid = fcall->params.rstat.stat.qid; | ||
| 177 | root->d_inode->i_ino = | ||
| 178 | v9fs_qid2ino(&fcall->params.rstat.stat.qid); | ||
| 179 | v9fs_stat2inode(&fcall->params.rstat.stat, root->d_inode, sb); | ||
| 180 | } | ||
| 181 | 169 | ||
| 182 | kfree(fcall); | 170 | error: |
| 171 | if (fid) | ||
| 172 | p9_client_clunk(fid); | ||
| 183 | 173 | ||
| 184 | if (stat_result < 0) { | 174 | if (v9ses) { |
| 185 | retval = stat_result; | 175 | v9fs_session_close(v9ses); |
| 186 | goto put_back_sb; | 176 | kfree(v9ses); |
| 187 | } | 177 | } |
| 188 | 178 | ||
| 189 | return simple_set_mnt(mnt, sb); | 179 | if (sb) { |
| 190 | 180 | up_write(&sb->s_umount); | |
| 191 | out_close_session: | 181 | deactivate_super(sb); |
| 192 | v9fs_session_close(v9ses); | 182 | } |
| 193 | out_free_session: | ||
| 194 | kfree(v9ses); | ||
| 195 | return retval; | ||
| 196 | 183 | ||
| 197 | put_back_sb: | ||
| 198 | /* deactivate_super calls v9fs_kill_super which will frees the rest */ | ||
| 199 | up_write(&sb->s_umount); | ||
| 200 | deactivate_super(sb); | ||
| 201 | return retval; | 184 | return retval; |
| 202 | } | 185 | } |
| 203 | 186 | ||
| @@ -211,7 +194,7 @@ static void v9fs_kill_super(struct super_block *s) | |||
| 211 | { | 194 | { |
| 212 | struct v9fs_session_info *v9ses = s->s_fs_info; | 195 | struct v9fs_session_info *v9ses = s->s_fs_info; |
| 213 | 196 | ||
| 214 | dprintk(DEBUG_VFS, " %p\n", s); | 197 | P9_DPRINTK(P9_DEBUG_VFS, " %p\n", s); |
| 215 | 198 | ||
| 216 | v9fs_dentry_release(s->s_root); /* clunk root */ | 199 | v9fs_dentry_release(s->s_root); /* clunk root */ |
| 217 | 200 | ||
| @@ -219,7 +202,7 @@ static void v9fs_kill_super(struct super_block *s) | |||
| 219 | 202 | ||
| 220 | v9fs_session_close(v9ses); | 203 | v9fs_session_close(v9ses); |
| 221 | kfree(v9ses); | 204 | kfree(v9ses); |
| 222 | dprintk(DEBUG_VFS, "exiting kill_super\n"); | 205 | P9_DPRINTK(P9_DEBUG_VFS, "exiting kill_super\n"); |
| 223 | } | 206 | } |
| 224 | 207 | ||
| 225 | /** | 208 | /** |
diff --git a/fs/Kconfig b/fs/Kconfig index 0fa0c1193e81..94b9d861bf9b 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
| @@ -2048,7 +2048,7 @@ config AFS_DEBUG | |||
| 2048 | 2048 | ||
| 2049 | config 9P_FS | 2049 | config 9P_FS |
| 2050 | tristate "Plan 9 Resource Sharing Support (9P2000) (Experimental)" | 2050 | tristate "Plan 9 Resource Sharing Support (9P2000) (Experimental)" |
| 2051 | depends on INET && EXPERIMENTAL | 2051 | depends on INET && NET_9P && EXPERIMENTAL |
| 2052 | help | 2052 | help |
| 2053 | If you say Y here, you will get experimental support for | 2053 | If you say Y here, you will get experimental support for |
| 2054 | Plan 9 resource sharing via the 9P2000 protocol. | 2054 | Plan 9 resource sharing via the 9P2000 protocol. |
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h new file mode 100644 index 000000000000..88884d39f28f --- /dev/null +++ b/include/net/9p/9p.h | |||
| @@ -0,0 +1,417 @@ | |||
| 1 | /* | ||
| 2 | * include/net/9p/9p.h | ||
| 3 | * | ||
| 4 | * 9P protocol definitions. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net> | ||
| 7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
| 8 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 | ||
| 12 | * as published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to: | ||
| 21 | * Free Software Foundation | ||
| 22 | * 51 Franklin Street, Fifth Floor | ||
| 23 | * Boston, MA 02111-1301 USA | ||
| 24 | * | ||
| 25 | */ | ||
| 26 | |||
| 27 | #ifndef NET_9P_H | ||
| 28 | #define NET_9P_H | ||
| 29 | |||
| 30 | #ifdef CONFIG_NET_9P_DEBUG | ||
| 31 | |||
| 32 | #define P9_DEBUG_ERROR (1<<0) | ||
| 33 | #define P9_DEBUG_9P (1<<2) | ||
| 34 | #define P9_DEBUG_VFS (1<<3) | ||
| 35 | #define P9_DEBUG_CONV (1<<4) | ||
| 36 | #define P9_DEBUG_MUX (1<<5) | ||
| 37 | #define P9_DEBUG_TRANS (1<<6) | ||
| 38 | #define P9_DEBUG_SLABS (1<<7) | ||
| 39 | #define P9_DEBUG_FCALL (1<<8) | ||
| 40 | |||
| 41 | extern unsigned int p9_debug_level; | ||
| 42 | |||
| 43 | #define P9_DPRINTK(level, format, arg...) \ | ||
| 44 | do { \ | ||
| 45 | if ((p9_debug_level & level) == level) \ | ||
| 46 | printk(KERN_NOTICE "-- %s (%d): " \ | ||
| 47 | format , __FUNCTION__, current->pid , ## arg); \ | ||
| 48 | } while (0) | ||
| 49 | |||
| 50 | #define PRINT_FCALL_ERROR(s, fcall) P9_DPRINTK(P9_DEBUG_ERROR, \ | ||
| 51 | "%s: %.*s\n", s, fcall?fcall->params.rerror.error.len:0, \ | ||
| 52 | fcall?fcall->params.rerror.error.str:""); | ||
| 53 | |||
| 54 | #else | ||
| 55 | #define P9_DPRINTK(level, format, arg...) do { } while (0) | ||
| 56 | #define PRINT_FCALL_ERROR(s, fcall) do { } while (0) | ||
| 57 | #endif | ||
| 58 | |||
| 59 | #define P9_EPRINTK(level, format, arg...) \ | ||
| 60 | do { \ | ||
| 61 | printk(level "9p: %s (%d): " \ | ||
| 62 | format , __FUNCTION__, current->pid , ## arg); \ | ||
| 63 | } while (0) | ||
| 64 | |||
| 65 | |||
| 66 | /* Message Types */ | ||
| 67 | enum { | ||
| 68 | P9_TVERSION = 100, | ||
| 69 | P9_RVERSION, | ||
| 70 | P9_TAUTH = 102, | ||
| 71 | P9_RAUTH, | ||
| 72 | P9_TATTACH = 104, | ||
| 73 | P9_RATTACH, | ||
| 74 | P9_TERROR = 106, | ||
| 75 | P9_RERROR, | ||
| 76 | P9_TFLUSH = 108, | ||
| 77 | P9_RFLUSH, | ||
| 78 | P9_TWALK = 110, | ||
| 79 | P9_RWALK, | ||
| 80 | P9_TOPEN = 112, | ||
| 81 | P9_ROPEN, | ||
| 82 | P9_TCREATE = 114, | ||
| 83 | P9_RCREATE, | ||
| 84 | P9_TREAD = 116, | ||
| 85 | P9_RREAD, | ||
| 86 | P9_TWRITE = 118, | ||
| 87 | P9_RWRITE, | ||
| 88 | P9_TCLUNK = 120, | ||
| 89 | P9_RCLUNK, | ||
| 90 | P9_TREMOVE = 122, | ||
| 91 | P9_RREMOVE, | ||
| 92 | P9_TSTAT = 124, | ||
| 93 | P9_RSTAT, | ||
| 94 | P9_TWSTAT = 126, | ||
| 95 | P9_RWSTAT, | ||
| 96 | }; | ||
| 97 | |||
| 98 | /* open modes */ | ||
| 99 | enum { | ||
| 100 | P9_OREAD = 0x00, | ||
| 101 | P9_OWRITE = 0x01, | ||
| 102 | P9_ORDWR = 0x02, | ||
| 103 | P9_OEXEC = 0x03, | ||
| 104 | P9_OEXCL = 0x04, | ||
| 105 | P9_OTRUNC = 0x10, | ||
| 106 | P9_OREXEC = 0x20, | ||
| 107 | P9_ORCLOSE = 0x40, | ||
| 108 | P9_OAPPEND = 0x80, | ||
| 109 | }; | ||
| 110 | |||
| 111 | /* permissions */ | ||
| 112 | enum { | ||
| 113 | P9_DMDIR = 0x80000000, | ||
| 114 | P9_DMAPPEND = 0x40000000, | ||
| 115 | P9_DMEXCL = 0x20000000, | ||
| 116 | P9_DMMOUNT = 0x10000000, | ||
| 117 | P9_DMAUTH = 0x08000000, | ||
| 118 | P9_DMTMP = 0x04000000, | ||
| 119 | P9_DMSYMLINK = 0x02000000, | ||
| 120 | P9_DMLINK = 0x01000000, | ||
| 121 | /* 9P2000.u extensions */ | ||
| 122 | P9_DMDEVICE = 0x00800000, | ||
| 123 | P9_DMNAMEDPIPE = 0x00200000, | ||
| 124 | P9_DMSOCKET = 0x00100000, | ||
| 125 | P9_DMSETUID = 0x00080000, | ||
| 126 | P9_DMSETGID = 0x00040000, | ||
| 127 | }; | ||
| 128 | |||
| 129 | /* qid.types */ | ||
| 130 | enum { | ||
| 131 | P9_QTDIR = 0x80, | ||
| 132 | P9_QTAPPEND = 0x40, | ||
| 133 | P9_QTEXCL = 0x20, | ||
| 134 | P9_QTMOUNT = 0x10, | ||
| 135 | P9_QTAUTH = 0x08, | ||
| 136 | P9_QTTMP = 0x04, | ||
| 137 | P9_QTSYMLINK = 0x02, | ||
| 138 | P9_QTLINK = 0x01, | ||
| 139 | P9_QTFILE = 0x00, | ||
| 140 | }; | ||
| 141 | |||
| 142 | #define P9_NOTAG (u16)(~0) | ||
| 143 | #define P9_NOFID (u32)(~0) | ||
| 144 | #define P9_MAXWELEM 16 | ||
| 145 | |||
| 146 | /* ample room for Twrite/Rread header */ | ||
| 147 | #define P9_IOHDRSZ 24 | ||
| 148 | |||
| 149 | struct p9_str { | ||
| 150 | u16 len; | ||
| 151 | char *str; | ||
| 152 | }; | ||
| 153 | |||
| 154 | /* qids are the unique ID for a file (like an inode */ | ||
| 155 | struct p9_qid { | ||
| 156 | u8 type; | ||
| 157 | u32 version; | ||
| 158 | u64 path; | ||
| 159 | }; | ||
| 160 | |||
| 161 | /* Plan 9 file metadata (stat) structure */ | ||
| 162 | struct p9_stat { | ||
| 163 | u16 size; | ||
| 164 | u16 type; | ||
| 165 | u32 dev; | ||
| 166 | struct p9_qid qid; | ||
| 167 | u32 mode; | ||
| 168 | u32 atime; | ||
| 169 | u32 mtime; | ||
| 170 | u64 length; | ||
| 171 | struct p9_str name; | ||
| 172 | struct p9_str uid; | ||
| 173 | struct p9_str gid; | ||
| 174 | struct p9_str muid; | ||
| 175 | struct p9_str extension; /* 9p2000.u extensions */ | ||
| 176 | u32 n_uid; /* 9p2000.u extensions */ | ||
| 177 | u32 n_gid; /* 9p2000.u extensions */ | ||
| 178 | u32 n_muid; /* 9p2000.u extensions */ | ||
| 179 | }; | ||
| 180 | |||
| 181 | /* file metadata (stat) structure used to create Twstat message | ||
| 182 | The is similar to p9_stat, but the strings don't point to | ||
| 183 | the same memory block and should be freed separately | ||
| 184 | */ | ||
| 185 | struct p9_wstat { | ||
| 186 | u16 size; | ||
| 187 | u16 type; | ||
| 188 | u32 dev; | ||
| 189 | struct p9_qid qid; | ||
| 190 | u32 mode; | ||
| 191 | u32 atime; | ||
| 192 | u32 mtime; | ||
| 193 | u64 length; | ||
| 194 | char *name; | ||
| 195 | char *uid; | ||
| 196 | char *gid; | ||
| 197 | char *muid; | ||
| 198 | char *extension; /* 9p2000.u extensions */ | ||
| 199 | u32 n_uid; /* 9p2000.u extensions */ | ||
| 200 | u32 n_gid; /* 9p2000.u extensions */ | ||
| 201 | u32 n_muid; /* 9p2000.u extensions */ | ||
| 202 | }; | ||
| 203 | |||
| 204 | /* Structures for Protocol Operations */ | ||
| 205 | struct p9_tversion { | ||
| 206 | u32 msize; | ||
| 207 | struct p9_str version; | ||
| 208 | }; | ||
| 209 | |||
| 210 | struct p9_rversion { | ||
| 211 | u32 msize; | ||
| 212 | struct p9_str version; | ||
| 213 | }; | ||
| 214 | |||
| 215 | struct p9_tauth { | ||
| 216 | u32 afid; | ||
| 217 | struct p9_str uname; | ||
| 218 | struct p9_str aname; | ||
| 219 | }; | ||
| 220 | |||
| 221 | struct p9_rauth { | ||
| 222 | struct p9_qid qid; | ||
| 223 | }; | ||
| 224 | |||
| 225 | struct p9_rerror { | ||
| 226 | struct p9_str error; | ||
| 227 | u32 errno; /* 9p2000.u extension */ | ||
| 228 | }; | ||
| 229 | |||
| 230 | struct p9_tflush { | ||
| 231 | u16 oldtag; | ||
| 232 | }; | ||
| 233 | |||
| 234 | struct p9_rflush { | ||
| 235 | }; | ||
| 236 | |||
| 237 | struct p9_tattach { | ||
| 238 | u32 fid; | ||
| 239 | u32 afid; | ||
| 240 | struct p9_str uname; | ||
| 241 | struct p9_str aname; | ||
| 242 | }; | ||
| 243 | |||
| 244 | struct p9_rattach { | ||
| 245 | struct p9_qid qid; | ||
| 246 | }; | ||
| 247 | |||
| 248 | struct p9_twalk { | ||
| 249 | u32 fid; | ||
| 250 | u32 newfid; | ||
| 251 | u16 nwname; | ||
| 252 | struct p9_str wnames[16]; | ||
| 253 | }; | ||
| 254 | |||
| 255 | struct p9_rwalk { | ||
| 256 | u16 nwqid; | ||
| 257 | struct p9_qid wqids[16]; | ||
| 258 | }; | ||
| 259 | |||
| 260 | struct p9_topen { | ||
| 261 | u32 fid; | ||
| 262 | u8 mode; | ||
| 263 | }; | ||
| 264 | |||
| 265 | struct p9_ropen { | ||
| 266 | struct p9_qid qid; | ||
| 267 | u32 iounit; | ||
| 268 | }; | ||
| 269 | |||
| 270 | struct p9_tcreate { | ||
| 271 | u32 fid; | ||
| 272 | struct p9_str name; | ||
| 273 | u32 perm; | ||
| 274 | u8 mode; | ||
| 275 | struct p9_str extension; | ||
| 276 | }; | ||
| 277 | |||
| 278 | struct p9_rcreate { | ||
| 279 | struct p9_qid qid; | ||
| 280 | u32 iounit; | ||
| 281 | }; | ||
| 282 | |||
| 283 | struct p9_tread { | ||
| 284 | u32 fid; | ||
| 285 | u64 offset; | ||
| 286 | u32 count; | ||
| 287 | }; | ||
| 288 | |||
| 289 | struct p9_rread { | ||
| 290 | u32 count; | ||
| 291 | u8 *data; | ||
| 292 | }; | ||
| 293 | |||
| 294 | struct p9_twrite { | ||
| 295 | u32 fid; | ||
| 296 | u64 offset; | ||
| 297 | u32 count; | ||
| 298 | u8 *data; | ||
| 299 | }; | ||
| 300 | |||
| 301 | struct p9_rwrite { | ||
| 302 | u32 count; | ||
| 303 | }; | ||
| 304 | |||
| 305 | struct p9_tclunk { | ||
| 306 | u32 fid; | ||
| 307 | }; | ||
| 308 | |||
| 309 | struct p9_rclunk { | ||
| 310 | }; | ||
| 311 | |||
| 312 | struct p9_tremove { | ||
| 313 | u32 fid; | ||
| 314 | }; | ||
| 315 | |||
| 316 | struct p9_rremove { | ||
| 317 | }; | ||
| 318 | |||
| 319 | struct p9_tstat { | ||
| 320 | u32 fid; | ||
| 321 | }; | ||
| 322 | |||
| 323 | struct p9_rstat { | ||
| 324 | struct p9_stat stat; | ||
| 325 | }; | ||
| 326 | |||
| 327 | struct p9_twstat { | ||
| 328 | u32 fid; | ||
| 329 | struct p9_stat stat; | ||
| 330 | }; | ||
| 331 | |||
| 332 | struct p9_rwstat { | ||
| 333 | }; | ||
| 334 | |||
| 335 | /* | ||
| 336 | * fcall is the primary packet structure | ||
| 337 | * | ||
| 338 | */ | ||
| 339 | |||
| 340 | struct p9_fcall { | ||
| 341 | u32 size; | ||
| 342 | u8 id; | ||
| 343 | u16 tag; | ||
| 344 | void *sdata; | ||
| 345 | |||
| 346 | union { | ||
| 347 | struct p9_tversion tversion; | ||
| 348 | struct p9_rversion rversion; | ||
| 349 | struct p9_tauth tauth; | ||
| 350 | struct p9_rauth rauth; | ||
| 351 | struct p9_rerror rerror; | ||
| 352 | struct p9_tflush tflush; | ||
| 353 | struct p9_rflush rflush; | ||
| 354 | struct p9_tattach tattach; | ||
| 355 | struct p9_rattach rattach; | ||
| 356 | struct p9_twalk twalk; | ||
| 357 | struct p9_rwalk rwalk; | ||
| 358 | struct p9_topen topen; | ||
| 359 | struct p9_ropen ropen; | ||
| 360 | struct p9_tcreate tcreate; | ||
| 361 | struct p9_rcreate rcreate; | ||
| 362 | struct p9_tread tread; | ||
| 363 | struct p9_rread rread; | ||
| 364 | struct p9_twrite twrite; | ||
| 365 | struct p9_rwrite rwrite; | ||
| 366 | struct p9_tclunk tclunk; | ||
| 367 | struct p9_rclunk rclunk; | ||
| 368 | struct p9_tremove tremove; | ||
| 369 | struct p9_rremove rremove; | ||
| 370 | struct p9_tstat tstat; | ||
| 371 | struct p9_rstat rstat; | ||
| 372 | struct p9_twstat twstat; | ||
| 373 | struct p9_rwstat rwstat; | ||
| 374 | } params; | ||
| 375 | }; | ||
| 376 | |||
| 377 | struct p9_idpool; | ||
| 378 | |||
| 379 | int p9_deserialize_stat(void *buf, u32 buflen, struct p9_stat *stat, | ||
| 380 | int dotu); | ||
| 381 | int p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *fc, int dotu); | ||
| 382 | void p9_set_tag(struct p9_fcall *fc, u16 tag); | ||
| 383 | struct p9_fcall *p9_create_tversion(u32 msize, char *version); | ||
| 384 | struct p9_fcall *p9_create_tattach(u32 fid, u32 afid, char *uname, | ||
| 385 | char *aname); | ||
| 386 | struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname); | ||
| 387 | struct p9_fcall *p9_create_tflush(u16 oldtag); | ||
| 388 | struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname, | ||
| 389 | char **wnames); | ||
| 390 | struct p9_fcall *p9_create_topen(u32 fid, u8 mode); | ||
| 391 | struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, | ||
| 392 | char *extension, int dotu); | ||
| 393 | struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count); | ||
| 394 | struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count, | ||
| 395 | const char *data); | ||
| 396 | struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count, | ||
| 397 | const char __user *data); | ||
| 398 | struct p9_fcall *p9_create_tclunk(u32 fid); | ||
| 399 | struct p9_fcall *p9_create_tremove(u32 fid); | ||
| 400 | struct p9_fcall *p9_create_tstat(u32 fid); | ||
| 401 | struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat, | ||
| 402 | int dotu); | ||
| 403 | |||
| 404 | int p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int dotu); | ||
| 405 | int p9_errstr2errno(char *errstr, int len); | ||
| 406 | |||
| 407 | struct p9_idpool *p9_idpool_create(void); | ||
| 408 | void p9_idpool_destroy(struct p9_idpool *); | ||
| 409 | int p9_idpool_get(struct p9_idpool *p); | ||
| 410 | void p9_idpool_put(int id, struct p9_idpool *p); | ||
| 411 | int p9_idpool_check(int id, struct p9_idpool *p); | ||
| 412 | |||
| 413 | int p9_error_init(void); | ||
| 414 | int p9_errstr2errno(char *, int); | ||
| 415 | int __init p9_sysctl_register(void); | ||
| 416 | void __exit p9_sysctl_unregister(void); | ||
| 417 | #endif /* NET_9P_H */ | ||
diff --git a/include/net/9p/client.h b/include/net/9p/client.h new file mode 100644 index 000000000000..d65ed7c69063 --- /dev/null +++ b/include/net/9p/client.h | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | /* | ||
| 2 | * include/net/9p/client.h | ||
| 3 | * | ||
| 4 | * 9P Client Definitions | ||
| 5 | * | ||
| 6 | * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 | ||
| 10 | * as published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to: | ||
| 19 | * Free Software Foundation | ||
| 20 | * 51 Franklin Street, Fifth Floor | ||
| 21 | * Boston, MA 02111-1301 USA | ||
| 22 | * | ||
| 23 | */ | ||
| 24 | |||
| 25 | #ifndef NET_9P_CLIENT_H | ||
| 26 | #define NET_9P_CLIENT_H | ||
| 27 | |||
| 28 | struct p9_client { | ||
| 29 | spinlock_t lock; /* protect client structure */ | ||
| 30 | int msize; | ||
| 31 | unsigned char dotu; | ||
| 32 | struct p9_transport *trans; | ||
| 33 | struct p9_conn *conn; | ||
| 34 | |||
| 35 | struct p9_idpool *fidpool; | ||
| 36 | struct list_head fidlist; | ||
| 37 | }; | ||
| 38 | |||
| 39 | struct p9_fid { | ||
| 40 | struct p9_client *clnt; | ||
| 41 | u32 fid; | ||
| 42 | int mode; | ||
| 43 | struct p9_qid qid; | ||
| 44 | u32 iounit; | ||
| 45 | uid_t uid; | ||
| 46 | void *aux; | ||
| 47 | |||
| 48 | int rdir_fpos; | ||
| 49 | int rdir_pos; | ||
| 50 | struct p9_fcall *rdir_fcall; | ||
| 51 | struct list_head flist; | ||
| 52 | struct list_head dlist; /* list of all fids attached to a dentry */ | ||
| 53 | }; | ||
| 54 | |||
| 55 | struct p9_client *p9_client_create(struct p9_transport *trans, int msize, | ||
| 56 | int dotu); | ||
| 57 | void p9_client_destroy(struct p9_client *clnt); | ||
| 58 | void p9_client_disconnect(struct p9_client *clnt); | ||
| 59 | struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, | ||
| 60 | char *uname, char *aname); | ||
| 61 | struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, char *aname); | ||
| 62 | struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, | ||
| 63 | int clone); | ||
| 64 | int p9_client_open(struct p9_fid *fid, int mode); | ||
| 65 | int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode, | ||
| 66 | char *extension); | ||
| 67 | int p9_client_clunk(struct p9_fid *fid); | ||
| 68 | int p9_client_remove(struct p9_fid *fid); | ||
| 69 | int p9_client_read(struct p9_fid *fid, char *data, u64 offset, u32 count); | ||
| 70 | int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count); | ||
| 71 | int p9_client_write(struct p9_fid *fid, char *data, u64 offset, u32 count); | ||
| 72 | int p9_client_uread(struct p9_fid *fid, char __user *data, u64 offset, | ||
| 73 | u32 count); | ||
| 74 | int p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset, | ||
| 75 | u32 count); | ||
| 76 | struct p9_stat *p9_client_stat(struct p9_fid *fid); | ||
| 77 | int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst); | ||
| 78 | struct p9_stat *p9_client_dirread(struct p9_fid *fid, u64 offset); | ||
| 79 | |||
| 80 | #endif /* NET_9P_CLIENT_H */ | ||
diff --git a/fs/9p/mux.h b/include/net/9p/conn.h index fb10c50186a1..583b6a2cb3df 100644 --- a/fs/9p/mux.h +++ b/include/net/9p/conn.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/fs/9p/mux.h | 2 | * include/net/9p/conn.h |
| 3 | * | 3 | * |
| 4 | * Multiplexer Definitions | 4 | * Connection Definitions |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net> | 6 | * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net> |
| 7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | 7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> |
| @@ -23,33 +23,35 @@ | |||
| 23 | * | 23 | * |
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | struct v9fs_mux_data; | 26 | #ifndef NET_9P_CONN_H |
| 27 | struct v9fs_req; | 27 | #define NET_9P_CONN_H |
| 28 | |||
| 29 | #undef P9_NONBLOCK | ||
| 30 | |||
| 31 | struct p9_conn; | ||
| 32 | struct p9_req; | ||
| 28 | 33 | ||
| 29 | /** | 34 | /** |
| 30 | * v9fs_mux_req_callback - callback function that is called when the | 35 | * p9_mux_req_callback - callback function that is called when the |
| 31 | * response of a request is received. The callback is called from | 36 | * response of a request is received. The callback is called from |
| 32 | * a workqueue and shouldn't block. | 37 | * a workqueue and shouldn't block. |
| 33 | * | 38 | * |
| 39 | * @req - request | ||
| 34 | * @a - the pointer that was specified when the request was send to be | 40 | * @a - the pointer that was specified when the request was send to be |
| 35 | * passed to the callback | 41 | * passed to the callback |
| 36 | * @tc - request call | ||
| 37 | * @rc - response call | ||
| 38 | * @err - error code (non-zero if error occured) | ||
| 39 | */ | 42 | */ |
| 40 | typedef void (*v9fs_mux_req_callback)(struct v9fs_req *req, void *a); | 43 | typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a); |
| 41 | 44 | ||
| 42 | int v9fs_mux_global_init(void); | 45 | struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize, |
| 43 | void v9fs_mux_global_exit(void); | 46 | unsigned char *dotu); |
| 47 | void p9_conn_destroy(struct p9_conn *); | ||
| 48 | int p9_conn_rpc(struct p9_conn *m, struct p9_fcall *tc, struct p9_fcall **rc); | ||
| 44 | 49 | ||
| 45 | struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, | 50 | #ifdef P9_NONBLOCK |
| 46 | unsigned char *extended); | 51 | int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc, |
| 47 | void v9fs_mux_destroy(struct v9fs_mux_data *); | 52 | p9_conn_req_callback cb, void *a); |
| 53 | #endif /* P9_NONBLOCK */ | ||
| 48 | 54 | ||
| 49 | int v9fs_mux_send(struct v9fs_mux_data *m, struct v9fs_fcall *tc); | 55 | void p9_conn_cancel(struct p9_conn *m, int err); |
| 50 | struct v9fs_fcall *v9fs_mux_recv(struct v9fs_mux_data *m); | ||
| 51 | int v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, struct v9fs_fcall **rc); | ||
| 52 | 56 | ||
| 53 | void v9fs_mux_flush(struct v9fs_mux_data *m, int sendflush); | 57 | #endif /* NET_9P_CONN_H */ |
| 54 | void v9fs_mux_cancel(struct v9fs_mux_data *m, int err); | ||
| 55 | int v9fs_errstr2errno(char *errstr, int len); | ||
diff --git a/fs/9p/transport.h b/include/net/9p/transport.h index b38a4b8a41ce..462d42279fb0 100644 --- a/fs/9p/transport.h +++ b/include/net/9p/transport.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/fs/9p/transport.h | 2 | * include/net/9p/transport.h |
| 3 | * | 3 | * |
| 4 | * Transport Definition | 4 | * Transport Definition |
| 5 | * | 5 | * |
| @@ -23,23 +23,27 @@ | |||
| 23 | * | 23 | * |
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | enum v9fs_transport_status { | 26 | #ifndef NET_9P_TRANSPORT_H |
| 27 | #define NET_9P_TRANSPORT_H | ||
| 28 | |||
| 29 | enum p9_transport_status { | ||
| 27 | Connected, | 30 | Connected, |
| 28 | Disconnected, | 31 | Disconnected, |
| 29 | Hung, | 32 | Hung, |
| 30 | }; | 33 | }; |
| 31 | 34 | ||
| 32 | struct v9fs_transport { | 35 | struct p9_transport { |
| 33 | enum v9fs_transport_status status; | 36 | enum p9_transport_status status; |
| 34 | void *priv; | 37 | void *priv; |
| 35 | 38 | ||
| 36 | int (*init) (struct v9fs_session_info *, const char *, char *); | 39 | int (*write) (struct p9_transport *, void *, int); |
| 37 | int (*write) (struct v9fs_transport *, void *, int); | 40 | int (*read) (struct p9_transport *, void *, int); |
| 38 | int (*read) (struct v9fs_transport *, void *, int); | 41 | void (*close) (struct p9_transport *); |
| 39 | void (*close) (struct v9fs_transport *); | 42 | unsigned int (*poll)(struct p9_transport *, struct poll_table_struct *); |
| 40 | unsigned int (*poll)(struct v9fs_transport *, struct poll_table_struct *); | ||
| 41 | }; | 43 | }; |
| 42 | 44 | ||
| 43 | extern struct v9fs_transport v9fs_trans_tcp; | 45 | struct p9_transport *p9_trans_create_tcp(const char *addr, int port); |
| 44 | extern struct v9fs_transport v9fs_trans_unix; | 46 | struct p9_transport *p9_trans_create_unix(const char *addr); |
| 45 | extern struct v9fs_transport v9fs_trans_fd; | 47 | struct p9_transport *p9_trans_create_fd(int rfd, int wfd); |
| 48 | |||
| 49 | #endif /* NET_9P_TRANSPORT_H */ | ||
diff --git a/net/9p/Kconfig b/net/9p/Kconfig new file mode 100644 index 000000000000..66821cd64a76 --- /dev/null +++ b/net/9p/Kconfig | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | # | ||
| 2 | # 9P protocol configuration | ||
| 3 | # | ||
| 4 | |||
| 5 | menuconfig NET_9P | ||
| 6 | depends on NET && EXPERIMENTAL | ||
| 7 | tristate "Plan 9 Resource Sharing Support (9P2000) (Experimental)" | ||
| 8 | help | ||
| 9 | If you say Y here, you will get experimental support for | ||
| 10 | Plan 9 resource sharing via the 9P2000 protocol. | ||
| 11 | |||
| 12 | See <http://v9fs.sf.net> for more information. | ||
| 13 | |||
| 14 | If unsure, say N. | ||
| 15 | |||
| 16 | config NET_9P_DEBUG | ||
| 17 | bool "Debug information" | ||
| 18 | depends on NET_9P | ||
| 19 | help | ||
| 20 | Say Y if you want the 9P subsistem to log debug information. | ||
| 21 | |||
diff --git a/net/9p/Makefile b/net/9p/Makefile new file mode 100644 index 000000000000..ac46cb91900d --- /dev/null +++ b/net/9p/Makefile | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | obj-$(CONFIG_NET_9P) := 9p.o | ||
| 2 | |||
| 3 | 9p-objs := \ | ||
| 4 | mod.o \ | ||
| 5 | trans_fd.o \ | ||
| 6 | mux.o \ | ||
| 7 | client.o \ | ||
| 8 | conv.o \ | ||
| 9 | error.o \ | ||
| 10 | fcprint.o \ | ||
| 11 | util.o \ | ||
| 12 | |||
| 13 | 9p-$(CONFIG_SYSCTL) += sysctl.o | ||
diff --git a/net/9p/client.c b/net/9p/client.c new file mode 100644 index 000000000000..bb2b8a3af196 --- /dev/null +++ b/net/9p/client.c | |||
| @@ -0,0 +1,965 @@ | |||
| 1 | /* | ||
| 2 | * net/9p/clnt.c | ||
| 3 | * | ||
| 4 | * 9P Client | ||
| 5 | * | ||
| 6 | * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 | ||
| 10 | * as published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to: | ||
| 19 | * Free Software Foundation | ||
| 20 | * 51 Franklin Street, Fifth Floor | ||
| 21 | * Boston, MA 02111-1301 USA | ||
| 22 | * | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/errno.h> | ||
| 27 | #include <linux/fs.h> | ||
| 28 | #include <linux/idr.h> | ||
| 29 | #include <linux/mutex.h> | ||
| 30 | #include <linux/sched.h> | ||
| 31 | #include <linux/uaccess.h> | ||
| 32 | #include <net/9p/9p.h> | ||
| 33 | #include <net/9p/transport.h> | ||
| 34 | #include <net/9p/conn.h> | ||
| 35 | #include <net/9p/client.h> | ||
| 36 | |||
| 37 | static struct p9_fid *p9_fid_create(struct p9_client *clnt); | ||
| 38 | static void p9_fid_destroy(struct p9_fid *fid); | ||
| 39 | static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu); | ||
| 40 | |||
| 41 | struct p9_client *p9_client_create(struct p9_transport *trans, int msize, | ||
| 42 | int dotu) | ||
| 43 | { | ||
| 44 | int err, n; | ||
| 45 | struct p9_client *clnt; | ||
| 46 | struct p9_fcall *tc, *rc; | ||
| 47 | struct p9_str *version; | ||
| 48 | |||
| 49 | err = 0; | ||
| 50 | tc = NULL; | ||
| 51 | rc = NULL; | ||
| 52 | clnt = kmalloc(sizeof(struct p9_client), GFP_KERNEL); | ||
| 53 | if (!clnt) | ||
| 54 | return ERR_PTR(-ENOMEM); | ||
| 55 | |||
| 56 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p trans %p msize %d dotu %d\n", | ||
| 57 | clnt, trans, msize, dotu); | ||
| 58 | spin_lock_init(&clnt->lock); | ||
| 59 | clnt->trans = trans; | ||
| 60 | clnt->msize = msize; | ||
| 61 | clnt->dotu = dotu; | ||
| 62 | INIT_LIST_HEAD(&clnt->fidlist); | ||
| 63 | clnt->fidpool = p9_idpool_create(); | ||
| 64 | if (!clnt->fidpool) { | ||
| 65 | err = PTR_ERR(clnt->fidpool); | ||
| 66 | clnt->fidpool = NULL; | ||
| 67 | goto error; | ||
| 68 | } | ||
| 69 | |||
| 70 | clnt->conn = p9_conn_create(clnt->trans, clnt->msize, &clnt->dotu); | ||
| 71 | if (IS_ERR(clnt->conn)) { | ||
| 72 | err = PTR_ERR(clnt->conn); | ||
| 73 | clnt->conn = NULL; | ||
| 74 | goto error; | ||
| 75 | } | ||
| 76 | |||
| 77 | tc = p9_create_tversion(clnt->msize, clnt->dotu?"9P2000.u":"9P2000"); | ||
| 78 | if (IS_ERR(tc)) { | ||
| 79 | err = PTR_ERR(tc); | ||
| 80 | tc = NULL; | ||
| 81 | goto error; | ||
| 82 | } | ||
| 83 | |||
| 84 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 85 | if (err) | ||
| 86 | goto error; | ||
| 87 | |||
| 88 | version = &rc->params.rversion.version; | ||
| 89 | if (version->len == 8 && !memcmp(version->str, "9P2000.u", 8)) | ||
| 90 | clnt->dotu = 1; | ||
| 91 | else if (version->len == 6 && !memcmp(version->str, "9P2000", 6)) | ||
| 92 | clnt->dotu = 0; | ||
| 93 | else { | ||
| 94 | err = -EREMOTEIO; | ||
| 95 | goto error; | ||
| 96 | } | ||
| 97 | |||
| 98 | n = rc->params.rversion.msize; | ||
| 99 | if (n < clnt->msize) | ||
| 100 | clnt->msize = n; | ||
| 101 | |||
| 102 | kfree(tc); | ||
| 103 | kfree(rc); | ||
| 104 | return clnt; | ||
| 105 | |||
| 106 | error: | ||
| 107 | kfree(tc); | ||
| 108 | kfree(rc); | ||
| 109 | p9_client_destroy(clnt); | ||
| 110 | return ERR_PTR(err); | ||
| 111 | } | ||
| 112 | EXPORT_SYMBOL(p9_client_create); | ||
| 113 | |||
| 114 | void p9_client_destroy(struct p9_client *clnt) | ||
| 115 | { | ||
| 116 | struct p9_fid *fid, *fidptr; | ||
| 117 | |||
| 118 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); | ||
| 119 | if (clnt->conn) { | ||
| 120 | p9_conn_destroy(clnt->conn); | ||
| 121 | clnt->conn = NULL; | ||
| 122 | } | ||
| 123 | |||
| 124 | if (clnt->trans) { | ||
| 125 | clnt->trans->close(clnt->trans); | ||
| 126 | kfree(clnt->trans); | ||
| 127 | clnt->trans = NULL; | ||
| 128 | } | ||
| 129 | |||
| 130 | if (clnt->fidpool) | ||
| 131 | p9_idpool_destroy(clnt->fidpool); | ||
| 132 | |||
| 133 | list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) | ||
| 134 | p9_fid_destroy(fid); | ||
| 135 | |||
| 136 | kfree(clnt); | ||
| 137 | } | ||
| 138 | EXPORT_SYMBOL(p9_client_destroy); | ||
| 139 | |||
| 140 | void p9_client_disconnect(struct p9_client *clnt) | ||
| 141 | { | ||
| 142 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); | ||
| 143 | clnt->trans->status = Disconnected; | ||
| 144 | p9_conn_cancel(clnt->conn, -EIO); | ||
| 145 | } | ||
| 146 | EXPORT_SYMBOL(p9_client_disconnect); | ||
| 147 | |||
| 148 | struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, | ||
| 149 | char *uname, char *aname) | ||
| 150 | { | ||
| 151 | int err; | ||
| 152 | struct p9_fcall *tc, *rc; | ||
| 153 | struct p9_fid *fid; | ||
| 154 | |||
| 155 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p afid %d uname %s aname %s\n", | ||
| 156 | clnt, afid?afid->fid:-1, uname, aname); | ||
| 157 | err = 0; | ||
| 158 | tc = NULL; | ||
| 159 | rc = NULL; | ||
| 160 | |||
| 161 | fid = p9_fid_create(clnt); | ||
| 162 | if (IS_ERR(fid)) { | ||
| 163 | err = PTR_ERR(fid); | ||
| 164 | fid = NULL; | ||
| 165 | goto error; | ||
| 166 | } | ||
| 167 | |||
| 168 | tc = p9_create_tattach(fid->fid, afid?afid->fid:P9_NOFID, uname, aname); | ||
| 169 | if (IS_ERR(tc)) { | ||
| 170 | err = PTR_ERR(tc); | ||
| 171 | tc = NULL; | ||
| 172 | goto error; | ||
| 173 | } | ||
| 174 | |||
| 175 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 176 | if (err) | ||
| 177 | goto error; | ||
| 178 | |||
| 179 | memmove(&fid->qid, &rc->params.rattach.qid, sizeof(struct p9_qid)); | ||
| 180 | kfree(tc); | ||
| 181 | kfree(rc); | ||
| 182 | return fid; | ||
| 183 | |||
| 184 | error: | ||
| 185 | kfree(tc); | ||
| 186 | kfree(rc); | ||
| 187 | if (fid) | ||
| 188 | p9_fid_destroy(fid); | ||
| 189 | return ERR_PTR(err); | ||
| 190 | } | ||
| 191 | EXPORT_SYMBOL(p9_client_attach); | ||
| 192 | |||
| 193 | struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, char *aname) | ||
| 194 | { | ||
| 195 | int err; | ||
| 196 | struct p9_fcall *tc, *rc; | ||
| 197 | struct p9_fid *fid; | ||
| 198 | |||
| 199 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p uname %s aname %s\n", clnt, uname, | ||
| 200 | aname); | ||
| 201 | err = 0; | ||
| 202 | tc = NULL; | ||
| 203 | rc = NULL; | ||
| 204 | |||
| 205 | fid = p9_fid_create(clnt); | ||
| 206 | if (IS_ERR(fid)) { | ||
| 207 | err = PTR_ERR(fid); | ||
| 208 | fid = NULL; | ||
| 209 | goto error; | ||
| 210 | } | ||
| 211 | |||
| 212 | tc = p9_create_tauth(fid->fid, uname, aname); | ||
| 213 | if (IS_ERR(tc)) { | ||
| 214 | err = PTR_ERR(tc); | ||
| 215 | tc = NULL; | ||
| 216 | goto error; | ||
| 217 | } | ||
| 218 | |||
| 219 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 220 | if (err) | ||
| 221 | goto error; | ||
| 222 | |||
| 223 | memmove(&fid->qid, &rc->params.rauth.qid, sizeof(struct p9_qid)); | ||
| 224 | kfree(tc); | ||
| 225 | kfree(rc); | ||
| 226 | return fid; | ||
| 227 | |||
| 228 | error: | ||
| 229 | kfree(tc); | ||
| 230 | kfree(rc); | ||
| 231 | if (fid) | ||
| 232 | p9_fid_destroy(fid); | ||
| 233 | return ERR_PTR(err); | ||
| 234 | } | ||
| 235 | EXPORT_SYMBOL(p9_client_auth); | ||
| 236 | |||
| 237 | struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, | ||
| 238 | int clone) | ||
| 239 | { | ||
| 240 | int err; | ||
| 241 | struct p9_fcall *tc, *rc; | ||
| 242 | struct p9_client *clnt; | ||
| 243 | struct p9_fid *fid; | ||
| 244 | |||
| 245 | P9_DPRINTK(P9_DEBUG_9P, "fid %d nwname %d wname[0] %s\n", | ||
| 246 | oldfid->fid, nwname, wnames?wnames[0]:NULL); | ||
| 247 | err = 0; | ||
| 248 | tc = NULL; | ||
| 249 | rc = NULL; | ||
| 250 | clnt = oldfid->clnt; | ||
| 251 | if (clone) { | ||
| 252 | fid = p9_fid_create(clnt); | ||
| 253 | if (IS_ERR(fid)) { | ||
| 254 | err = PTR_ERR(fid); | ||
| 255 | fid = NULL; | ||
| 256 | goto error; | ||
| 257 | } | ||
| 258 | |||
| 259 | fid->uid = oldfid->uid; | ||
| 260 | } else | ||
| 261 | fid = oldfid; | ||
| 262 | |||
| 263 | tc = p9_create_twalk(oldfid->fid, fid->fid, nwname, wnames); | ||
| 264 | if (IS_ERR(tc)) { | ||
| 265 | err = PTR_ERR(tc); | ||
| 266 | tc = NULL; | ||
| 267 | goto error; | ||
| 268 | } | ||
| 269 | |||
| 270 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 271 | if (err) { | ||
| 272 | if (rc && rc->id == P9_RWALK) | ||
| 273 | goto clunk_fid; | ||
| 274 | else | ||
| 275 | goto error; | ||
| 276 | } | ||
| 277 | |||
| 278 | if (rc->params.rwalk.nwqid != nwname) { | ||
| 279 | err = -ENOENT; | ||
| 280 | goto clunk_fid; | ||
| 281 | } | ||
| 282 | |||
| 283 | if (nwname) | ||
| 284 | memmove(&fid->qid, | ||
| 285 | &rc->params.rwalk.wqids[rc->params.rwalk.nwqid - 1], | ||
| 286 | sizeof(struct p9_qid)); | ||
| 287 | else | ||
| 288 | fid->qid = oldfid->qid; | ||
| 289 | |||
| 290 | kfree(tc); | ||
| 291 | kfree(rc); | ||
| 292 | return fid; | ||
| 293 | |||
| 294 | clunk_fid: | ||
| 295 | kfree(tc); | ||
| 296 | kfree(rc); | ||
| 297 | rc = NULL; | ||
| 298 | tc = p9_create_tclunk(fid->fid); | ||
| 299 | if (IS_ERR(tc)) { | ||
| 300 | err = PTR_ERR(tc); | ||
| 301 | tc = NULL; | ||
| 302 | goto error; | ||
| 303 | } | ||
| 304 | |||
| 305 | p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 306 | |||
| 307 | error: | ||
| 308 | kfree(tc); | ||
| 309 | kfree(rc); | ||
| 310 | if (fid && (fid != oldfid)) | ||
| 311 | p9_fid_destroy(fid); | ||
| 312 | |||
| 313 | return ERR_PTR(err); | ||
| 314 | } | ||
| 315 | EXPORT_SYMBOL(p9_client_walk); | ||
| 316 | |||
| 317 | int p9_client_open(struct p9_fid *fid, int mode) | ||
| 318 | { | ||
| 319 | int err; | ||
| 320 | struct p9_fcall *tc, *rc; | ||
| 321 | struct p9_client *clnt; | ||
| 322 | |||
| 323 | P9_DPRINTK(P9_DEBUG_9P, "fid %d mode %d\n", fid->fid, mode); | ||
| 324 | err = 0; | ||
| 325 | tc = NULL; | ||
| 326 | rc = NULL; | ||
| 327 | clnt = fid->clnt; | ||
| 328 | |||
| 329 | if (fid->mode != -1) | ||
| 330 | return -EINVAL; | ||
| 331 | |||
| 332 | tc = p9_create_topen(fid->fid, mode); | ||
| 333 | if (IS_ERR(tc)) { | ||
| 334 | err = PTR_ERR(tc); | ||
| 335 | tc = NULL; | ||
| 336 | goto done; | ||
| 337 | } | ||
| 338 | |||
| 339 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 340 | if (err) | ||
| 341 | goto done; | ||
| 342 | |||
| 343 | fid->mode = mode; | ||
| 344 | fid->iounit = rc->params.ropen.iounit; | ||
| 345 | |||
| 346 | done: | ||
| 347 | kfree(tc); | ||
| 348 | kfree(rc); | ||
| 349 | return err; | ||
| 350 | } | ||
| 351 | EXPORT_SYMBOL(p9_client_open); | ||
| 352 | |||
| 353 | int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode, | ||
| 354 | char *extension) | ||
| 355 | { | ||
| 356 | int err; | ||
| 357 | struct p9_fcall *tc, *rc; | ||
| 358 | struct p9_client *clnt; | ||
| 359 | |||
| 360 | P9_DPRINTK(P9_DEBUG_9P, "fid %d name %s perm %d mode %d\n", fid->fid, | ||
| 361 | name, perm, mode); | ||
| 362 | err = 0; | ||
| 363 | tc = NULL; | ||
| 364 | rc = NULL; | ||
| 365 | clnt = fid->clnt; | ||
| 366 | |||
| 367 | if (fid->mode != -1) | ||
| 368 | return -EINVAL; | ||
| 369 | |||
| 370 | tc = p9_create_tcreate(fid->fid, name, perm, mode, extension, | ||
| 371 | clnt->dotu); | ||
| 372 | if (IS_ERR(tc)) { | ||
| 373 | err = PTR_ERR(tc); | ||
| 374 | tc = NULL; | ||
| 375 | goto done; | ||
| 376 | } | ||
| 377 | |||
| 378 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 379 | if (err) | ||
| 380 | goto done; | ||
| 381 | |||
| 382 | fid->mode = mode; | ||
| 383 | fid->iounit = rc->params.ropen.iounit; | ||
| 384 | |||
| 385 | done: | ||
| 386 | kfree(tc); | ||
| 387 | kfree(rc); | ||
| 388 | return err; | ||
| 389 | } | ||
| 390 | EXPORT_SYMBOL(p9_client_fcreate); | ||
| 391 | |||
| 392 | int p9_client_clunk(struct p9_fid *fid) | ||
| 393 | { | ||
| 394 | int err; | ||
| 395 | struct p9_fcall *tc, *rc; | ||
| 396 | struct p9_client *clnt; | ||
| 397 | |||
| 398 | P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); | ||
| 399 | err = 0; | ||
| 400 | tc = NULL; | ||
| 401 | rc = NULL; | ||
| 402 | clnt = fid->clnt; | ||
| 403 | |||
| 404 | tc = p9_create_tclunk(fid->fid); | ||
| 405 | if (IS_ERR(tc)) { | ||
| 406 | err = PTR_ERR(tc); | ||
| 407 | tc = NULL; | ||
| 408 | goto done; | ||
| 409 | } | ||
| 410 | |||
| 411 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 412 | if (err) | ||
| 413 | goto done; | ||
| 414 | |||
| 415 | p9_fid_destroy(fid); | ||
| 416 | |||
| 417 | done: | ||
| 418 | kfree(tc); | ||
| 419 | kfree(rc); | ||
| 420 | return err; | ||
| 421 | } | ||
| 422 | EXPORT_SYMBOL(p9_client_clunk); | ||
| 423 | |||
| 424 | int p9_client_remove(struct p9_fid *fid) | ||
| 425 | { | ||
| 426 | int err; | ||
| 427 | struct p9_fcall *tc, *rc; | ||
| 428 | struct p9_client *clnt; | ||
| 429 | |||
| 430 | P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); | ||
| 431 | err = 0; | ||
| 432 | tc = NULL; | ||
| 433 | rc = NULL; | ||
| 434 | clnt = fid->clnt; | ||
| 435 | |||
| 436 | tc = p9_create_tremove(fid->fid); | ||
| 437 | if (IS_ERR(tc)) { | ||
| 438 | err = PTR_ERR(tc); | ||
| 439 | tc = NULL; | ||
| 440 | goto done; | ||
| 441 | } | ||
| 442 | |||
| 443 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 444 | if (err) | ||
| 445 | goto done; | ||
| 446 | |||
| 447 | p9_fid_destroy(fid); | ||
| 448 | |||
| 449 | done: | ||
| 450 | kfree(tc); | ||
| 451 | kfree(rc); | ||
| 452 | return err; | ||
| 453 | } | ||
| 454 | EXPORT_SYMBOL(p9_client_remove); | ||
| 455 | |||
| 456 | int p9_client_read(struct p9_fid *fid, char *data, u64 offset, u32 count) | ||
| 457 | { | ||
| 458 | int err, n, rsize, total; | ||
| 459 | struct p9_fcall *tc, *rc; | ||
| 460 | struct p9_client *clnt; | ||
| 461 | |||
| 462 | P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu %d\n", fid->fid, | ||
| 463 | (long long unsigned) offset, count); | ||
| 464 | err = 0; | ||
| 465 | tc = NULL; | ||
| 466 | rc = NULL; | ||
| 467 | clnt = fid->clnt; | ||
| 468 | total = 0; | ||
| 469 | |||
| 470 | rsize = fid->iounit; | ||
| 471 | if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) | ||
| 472 | rsize = clnt->msize - P9_IOHDRSZ; | ||
| 473 | |||
| 474 | do { | ||
| 475 | if (count < rsize) | ||
| 476 | rsize = count; | ||
| 477 | |||
| 478 | tc = p9_create_tread(fid->fid, offset, rsize); | ||
| 479 | if (IS_ERR(tc)) { | ||
| 480 | err = PTR_ERR(tc); | ||
| 481 | tc = NULL; | ||
| 482 | goto error; | ||
| 483 | } | ||
| 484 | |||
| 485 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 486 | if (err) | ||
| 487 | goto error; | ||
| 488 | |||
| 489 | n = rc->params.rread.count; | ||
| 490 | if (n > count) | ||
| 491 | n = count; | ||
| 492 | |||
| 493 | memmove(data, rc->params.rread.data, n); | ||
| 494 | count -= n; | ||
| 495 | data += n; | ||
| 496 | offset += n; | ||
| 497 | total += n; | ||
| 498 | kfree(tc); | ||
| 499 | tc = NULL; | ||
| 500 | kfree(rc); | ||
| 501 | rc = NULL; | ||
| 502 | } while (count > 0 && n == rsize); | ||
| 503 | |||
| 504 | return total; | ||
| 505 | |||
| 506 | error: | ||
| 507 | kfree(tc); | ||
| 508 | kfree(rc); | ||
| 509 | return err; | ||
| 510 | } | ||
| 511 | EXPORT_SYMBOL(p9_client_read); | ||
| 512 | |||
| 513 | int p9_client_write(struct p9_fid *fid, char *data, u64 offset, u32 count) | ||
| 514 | { | ||
| 515 | int err, n, rsize, total; | ||
| 516 | struct p9_fcall *tc, *rc; | ||
| 517 | struct p9_client *clnt; | ||
| 518 | |||
| 519 | P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, | ||
| 520 | (long long unsigned) offset, count); | ||
| 521 | err = 0; | ||
| 522 | tc = NULL; | ||
| 523 | rc = NULL; | ||
| 524 | clnt = fid->clnt; | ||
| 525 | total = 0; | ||
| 526 | |||
| 527 | rsize = fid->iounit; | ||
| 528 | if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) | ||
| 529 | rsize = clnt->msize - P9_IOHDRSZ; | ||
| 530 | |||
| 531 | do { | ||
| 532 | if (count < rsize) | ||
| 533 | rsize = count; | ||
| 534 | |||
| 535 | tc = p9_create_twrite(fid->fid, offset, rsize, data); | ||
| 536 | if (IS_ERR(tc)) { | ||
| 537 | err = PTR_ERR(tc); | ||
| 538 | tc = NULL; | ||
| 539 | goto error; | ||
| 540 | } | ||
| 541 | |||
| 542 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 543 | if (err) | ||
| 544 | goto error; | ||
| 545 | |||
| 546 | n = rc->params.rread.count; | ||
| 547 | count -= n; | ||
| 548 | data += n; | ||
| 549 | offset += n; | ||
| 550 | total += n; | ||
| 551 | kfree(tc); | ||
| 552 | tc = NULL; | ||
| 553 | kfree(rc); | ||
| 554 | rc = NULL; | ||
| 555 | } while (count > 0); | ||
| 556 | |||
| 557 | return total; | ||
| 558 | |||
| 559 | error: | ||
| 560 | kfree(tc); | ||
| 561 | kfree(rc); | ||
| 562 | return err; | ||
| 563 | } | ||
| 564 | EXPORT_SYMBOL(p9_client_write); | ||
| 565 | |||
| 566 | int | ||
| 567 | p9_client_uread(struct p9_fid *fid, char __user *data, u64 offset, u32 count) | ||
| 568 | { | ||
| 569 | int err, n, rsize, total; | ||
| 570 | struct p9_fcall *tc, *rc; | ||
| 571 | struct p9_client *clnt; | ||
| 572 | |||
| 573 | P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, | ||
| 574 | (long long unsigned) offset, count); | ||
| 575 | err = 0; | ||
| 576 | tc = NULL; | ||
| 577 | rc = NULL; | ||
| 578 | clnt = fid->clnt; | ||
| 579 | total = 0; | ||
| 580 | |||
| 581 | rsize = fid->iounit; | ||
| 582 | if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) | ||
| 583 | rsize = clnt->msize - P9_IOHDRSZ; | ||
| 584 | |||
| 585 | do { | ||
| 586 | if (count < rsize) | ||
| 587 | rsize = count; | ||
| 588 | |||
| 589 | tc = p9_create_tread(fid->fid, offset, rsize); | ||
| 590 | if (IS_ERR(tc)) { | ||
| 591 | err = PTR_ERR(tc); | ||
| 592 | tc = NULL; | ||
| 593 | goto error; | ||
| 594 | } | ||
| 595 | |||
| 596 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 597 | if (err) | ||
| 598 | goto error; | ||
| 599 | |||
| 600 | n = rc->params.rread.count; | ||
| 601 | if (n > count) | ||
| 602 | n = count; | ||
| 603 | |||
| 604 | err = copy_to_user(data, rc->params.rread.data, n); | ||
| 605 | if (err) { | ||
| 606 | err = -EFAULT; | ||
| 607 | goto error; | ||
| 608 | } | ||
| 609 | |||
| 610 | count -= n; | ||
| 611 | data += n; | ||
| 612 | offset += n; | ||
| 613 | total += n; | ||
| 614 | kfree(tc); | ||
| 615 | tc = NULL; | ||
| 616 | kfree(rc); | ||
| 617 | rc = NULL; | ||
| 618 | } while (count > 0 && n == rsize); | ||
| 619 | |||
| 620 | return total; | ||
| 621 | |||
| 622 | error: | ||
| 623 | kfree(tc); | ||
| 624 | kfree(rc); | ||
| 625 | return err; | ||
| 626 | } | ||
| 627 | EXPORT_SYMBOL(p9_client_uread); | ||
| 628 | |||
| 629 | int | ||
| 630 | p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset, | ||
| 631 | u32 count) | ||
| 632 | { | ||
| 633 | int err, n, rsize, total; | ||
| 634 | struct p9_fcall *tc, *rc; | ||
| 635 | struct p9_client *clnt; | ||
| 636 | |||
| 637 | P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, | ||
| 638 | (long long unsigned) offset, count); | ||
| 639 | err = 0; | ||
| 640 | tc = NULL; | ||
| 641 | rc = NULL; | ||
| 642 | clnt = fid->clnt; | ||
| 643 | total = 0; | ||
| 644 | |||
| 645 | rsize = fid->iounit; | ||
| 646 | if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) | ||
| 647 | rsize = clnt->msize - P9_IOHDRSZ; | ||
| 648 | |||
| 649 | do { | ||
| 650 | if (count < rsize) | ||
| 651 | rsize = count; | ||
| 652 | |||
| 653 | tc = p9_create_twrite_u(fid->fid, offset, rsize, data); | ||
| 654 | if (IS_ERR(tc)) { | ||
| 655 | err = PTR_ERR(tc); | ||
| 656 | tc = NULL; | ||
| 657 | goto error; | ||
| 658 | } | ||
| 659 | |||
| 660 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 661 | if (err) | ||
| 662 | goto error; | ||
| 663 | |||
| 664 | n = rc->params.rread.count; | ||
| 665 | count -= n; | ||
| 666 | data += n; | ||
| 667 | offset += n; | ||
| 668 | total += n; | ||
| 669 | kfree(tc); | ||
| 670 | tc = NULL; | ||
| 671 | kfree(rc); | ||
| 672 | rc = NULL; | ||
| 673 | } while (count > 0); | ||
| 674 | |||
| 675 | return total; | ||
| 676 | |||
| 677 | error: | ||
| 678 | kfree(tc); | ||
| 679 | kfree(rc); | ||
| 680 | return err; | ||
| 681 | } | ||
| 682 | EXPORT_SYMBOL(p9_client_uwrite); | ||
| 683 | |||
| 684 | int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count) | ||
| 685 | { | ||
| 686 | int n, total; | ||
| 687 | |||
| 688 | P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, | ||
| 689 | (long long unsigned) offset, count); | ||
| 690 | n = 0; | ||
| 691 | total = 0; | ||
| 692 | while (count) { | ||
| 693 | n = p9_client_read(fid, data, offset, count); | ||
| 694 | if (n <= 0) | ||
| 695 | break; | ||
| 696 | |||
| 697 | data += n; | ||
| 698 | offset += n; | ||
| 699 | count -= n; | ||
| 700 | total += n; | ||
| 701 | } | ||
| 702 | |||
| 703 | if (n < 0) | ||
| 704 | total = n; | ||
| 705 | |||
| 706 | return total; | ||
| 707 | } | ||
| 708 | EXPORT_SYMBOL(p9_client_readn); | ||
| 709 | |||
| 710 | struct p9_stat *p9_client_stat(struct p9_fid *fid) | ||
| 711 | { | ||
| 712 | int err; | ||
| 713 | struct p9_fcall *tc, *rc; | ||
| 714 | struct p9_client *clnt; | ||
| 715 | struct p9_stat *ret; | ||
| 716 | |||
| 717 | P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); | ||
| 718 | err = 0; | ||
| 719 | tc = NULL; | ||
| 720 | rc = NULL; | ||
| 721 | ret = NULL; | ||
| 722 | clnt = fid->clnt; | ||
| 723 | |||
| 724 | tc = p9_create_tstat(fid->fid); | ||
| 725 | if (IS_ERR(tc)) { | ||
| 726 | err = PTR_ERR(tc); | ||
| 727 | tc = NULL; | ||
| 728 | goto error; | ||
| 729 | } | ||
| 730 | |||
| 731 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 732 | if (err) | ||
| 733 | goto error; | ||
| 734 | |||
| 735 | ret = p9_clone_stat(&rc->params.rstat.stat, clnt->dotu); | ||
| 736 | if (IS_ERR(ret)) { | ||
| 737 | err = PTR_ERR(ret); | ||
| 738 | ret = NULL; | ||
| 739 | goto error; | ||
| 740 | } | ||
| 741 | |||
| 742 | kfree(tc); | ||
| 743 | kfree(rc); | ||
| 744 | return ret; | ||
| 745 | |||
| 746 | error: | ||
| 747 | kfree(tc); | ||
| 748 | kfree(rc); | ||
| 749 | kfree(ret); | ||
| 750 | return ERR_PTR(err); | ||
| 751 | } | ||
| 752 | EXPORT_SYMBOL(p9_client_stat); | ||
| 753 | |||
| 754 | int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst) | ||
| 755 | { | ||
| 756 | int err; | ||
| 757 | struct p9_fcall *tc, *rc; | ||
| 758 | struct p9_client *clnt; | ||
| 759 | |||
| 760 | P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); | ||
| 761 | err = 0; | ||
| 762 | tc = NULL; | ||
| 763 | rc = NULL; | ||
| 764 | clnt = fid->clnt; | ||
| 765 | |||
| 766 | tc = p9_create_twstat(fid->fid, wst, clnt->dotu); | ||
| 767 | if (IS_ERR(tc)) { | ||
| 768 | err = PTR_ERR(tc); | ||
| 769 | tc = NULL; | ||
| 770 | goto done; | ||
| 771 | } | ||
| 772 | |||
| 773 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 774 | |||
| 775 | done: | ||
| 776 | kfree(tc); | ||
| 777 | kfree(rc); | ||
| 778 | return err; | ||
| 779 | } | ||
| 780 | EXPORT_SYMBOL(p9_client_wstat); | ||
| 781 | |||
| 782 | struct p9_stat *p9_client_dirread(struct p9_fid *fid, u64 offset) | ||
| 783 | { | ||
| 784 | int err, n, m; | ||
| 785 | struct p9_fcall *tc, *rc; | ||
| 786 | struct p9_client *clnt; | ||
| 787 | struct p9_stat st, *ret; | ||
| 788 | |||
| 789 | P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu\n", fid->fid, | ||
| 790 | (long long unsigned) offset); | ||
| 791 | err = 0; | ||
| 792 | tc = NULL; | ||
| 793 | rc = NULL; | ||
| 794 | ret = NULL; | ||
| 795 | clnt = fid->clnt; | ||
| 796 | |||
| 797 | /* if the offset is below or above the current response, free it */ | ||
| 798 | if (offset < fid->rdir_fpos || (fid->rdir_fcall && | ||
| 799 | offset >= fid->rdir_fpos+fid->rdir_fcall->params.rread.count)) { | ||
| 800 | fid->rdir_pos = 0; | ||
| 801 | if (fid->rdir_fcall) | ||
| 802 | fid->rdir_fpos += fid->rdir_fcall->params.rread.count; | ||
| 803 | |||
| 804 | kfree(fid->rdir_fcall); | ||
| 805 | fid->rdir_fcall = NULL; | ||
| 806 | if (offset < fid->rdir_fpos) | ||
| 807 | fid->rdir_fpos = 0; | ||
| 808 | } | ||
| 809 | |||
| 810 | if (!fid->rdir_fcall) { | ||
| 811 | n = fid->iounit; | ||
| 812 | if (!n || n > clnt->msize-P9_IOHDRSZ) | ||
| 813 | n = clnt->msize - P9_IOHDRSZ; | ||
| 814 | |||
| 815 | while (1) { | ||
| 816 | if (fid->rdir_fcall) { | ||
| 817 | fid->rdir_fpos += | ||
| 818 | fid->rdir_fcall->params.rread.count; | ||
| 819 | kfree(fid->rdir_fcall); | ||
| 820 | fid->rdir_fcall = NULL; | ||
| 821 | } | ||
| 822 | |||
| 823 | tc = p9_create_tread(fid->fid, fid->rdir_fpos, n); | ||
| 824 | if (IS_ERR(tc)) { | ||
| 825 | err = PTR_ERR(tc); | ||
| 826 | tc = NULL; | ||
| 827 | goto error; | ||
| 828 | } | ||
| 829 | |||
| 830 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
| 831 | if (err) | ||
| 832 | goto error; | ||
| 833 | |||
| 834 | n = rc->params.rread.count; | ||
| 835 | if (n == 0) | ||
| 836 | goto done; | ||
| 837 | |||
| 838 | fid->rdir_fcall = rc; | ||
| 839 | rc = NULL; | ||
| 840 | if (offset >= fid->rdir_fpos && | ||
| 841 | offset < fid->rdir_fpos+n) | ||
| 842 | break; | ||
| 843 | } | ||
| 844 | |||
| 845 | fid->rdir_pos = 0; | ||
| 846 | } | ||
| 847 | |||
| 848 | m = offset - fid->rdir_fpos; | ||
| 849 | if (m < 0) | ||
| 850 | goto done; | ||
| 851 | |||
| 852 | n = p9_deserialize_stat(fid->rdir_fcall->params.rread.data + m, | ||
| 853 | fid->rdir_fcall->params.rread.count - m, &st, clnt->dotu); | ||
| 854 | |||
| 855 | if (!n) { | ||
| 856 | err = -EIO; | ||
| 857 | goto error; | ||
| 858 | } | ||
| 859 | |||
| 860 | fid->rdir_pos += n; | ||
| 861 | st.size = n; | ||
| 862 | ret = p9_clone_stat(&st, clnt->dotu); | ||
| 863 | if (IS_ERR(ret)) { | ||
| 864 | err = PTR_ERR(ret); | ||
| 865 | ret = NULL; | ||
| 866 | goto error; | ||
| 867 | } | ||
| 868 | |||
| 869 | done: | ||
| 870 | kfree(tc); | ||
| 871 | kfree(rc); | ||
| 872 | return ret; | ||
| 873 | |||
| 874 | error: | ||
| 875 | kfree(tc); | ||
| 876 | kfree(rc); | ||
| 877 | kfree(ret); | ||
| 878 | return ERR_PTR(err); | ||
| 879 | } | ||
| 880 | EXPORT_SYMBOL(p9_client_dirread); | ||
| 881 | |||
| 882 | static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu) | ||
| 883 | { | ||
| 884 | int n; | ||
| 885 | char *p; | ||
| 886 | struct p9_stat *ret; | ||
| 887 | |||
| 888 | n = sizeof(struct p9_stat) + st->name.len + st->uid.len + st->gid.len + | ||
| 889 | st->muid.len; | ||
| 890 | |||
| 891 | if (dotu) | ||
| 892 | n += st->extension.len; | ||
| 893 | |||
| 894 | ret = kmalloc(n, GFP_KERNEL); | ||
| 895 | if (!ret) | ||
| 896 | return ERR_PTR(-ENOMEM); | ||
| 897 | |||
| 898 | memmove(ret, st, sizeof(struct p9_stat)); | ||
| 899 | p = ((char *) ret) + sizeof(struct p9_stat); | ||
| 900 | memmove(p, st->name.str, st->name.len); | ||
| 901 | p += st->name.len; | ||
| 902 | memmove(p, st->uid.str, st->uid.len); | ||
| 903 | p += st->uid.len; | ||
| 904 | memmove(p, st->gid.str, st->gid.len); | ||
| 905 | p += st->gid.len; | ||
| 906 | memmove(p, st->muid.str, st->muid.len); | ||
| 907 | p += st->muid.len; | ||
| 908 | |||
| 909 | if (dotu) { | ||
| 910 | memmove(p, st->extension.str, st->extension.len); | ||
| 911 | p += st->extension.len; | ||
| 912 | } | ||
| 913 | |||
| 914 | return ret; | ||
| 915 | } | ||
| 916 | |||
| 917 | static struct p9_fid *p9_fid_create(struct p9_client *clnt) | ||
| 918 | { | ||
| 919 | int err; | ||
| 920 | struct p9_fid *fid; | ||
| 921 | |||
| 922 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); | ||
| 923 | fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL); | ||
| 924 | if (!fid) | ||
| 925 | return ERR_PTR(-ENOMEM); | ||
| 926 | |||
| 927 | fid->fid = p9_idpool_get(clnt->fidpool); | ||
| 928 | if (fid->fid < 0) { | ||
| 929 | err = -ENOSPC; | ||
| 930 | goto error; | ||
| 931 | } | ||
| 932 | |||
| 933 | memset(&fid->qid, 0, sizeof(struct p9_qid)); | ||
| 934 | fid->mode = -1; | ||
| 935 | fid->rdir_fpos = 0; | ||
| 936 | fid->rdir_pos = 0; | ||
| 937 | fid->rdir_fcall = NULL; | ||
| 938 | fid->uid = current->fsuid; | ||
| 939 | fid->clnt = clnt; | ||
| 940 | fid->aux = NULL; | ||
| 941 | |||
| 942 | spin_lock(&clnt->lock); | ||
| 943 | list_add(&fid->flist, &clnt->fidlist); | ||
| 944 | spin_unlock(&clnt->lock); | ||
| 945 | |||
| 946 | return fid; | ||
| 947 | |||
| 948 | error: | ||
| 949 | kfree(fid); | ||
| 950 | return ERR_PTR(err); | ||
| 951 | } | ||
| 952 | |||
| 953 | static void p9_fid_destroy(struct p9_fid *fid) | ||
| 954 | { | ||
| 955 | struct p9_client *clnt; | ||
| 956 | |||
| 957 | P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); | ||
| 958 | clnt = fid->clnt; | ||
| 959 | p9_idpool_put(fid->fid, clnt->fidpool); | ||
| 960 | spin_lock(&clnt->lock); | ||
| 961 | list_del(&fid->flist); | ||
| 962 | spin_unlock(&clnt->lock); | ||
| 963 | kfree(fid->rdir_fcall); | ||
| 964 | kfree(fid); | ||
| 965 | } | ||
diff --git a/fs/9p/conv.c b/net/9p/conv.c index a3ed571eee31..37451178e761 100644 --- a/fs/9p/conv.c +++ b/net/9p/conv.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/fs/9p/conv.c | 2 | * net/9p/conv.c |
| 3 | * | 3 | * |
| 4 | * 9P protocol conversion functions | 4 | * 9P protocol conversion functions |
| 5 | * | 5 | * |
| @@ -29,11 +29,8 @@ | |||
| 29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
| 30 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
| 31 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
| 32 | #include <asm/uaccess.h> | 32 | #include <linux/uaccess.h> |
| 33 | #include "debug.h" | 33 | #include <net/9p/9p.h> |
| 34 | #include "v9fs.h" | ||
| 35 | #include "9p.h" | ||
| 36 | #include "conv.h" | ||
| 37 | 34 | ||
| 38 | /* | 35 | /* |
| 39 | * Buffer to help with string parsing | 36 | * Buffer to help with string parsing |
| @@ -59,8 +56,9 @@ static int buf_check_size(struct cbuf *buf, int len) | |||
| 59 | { | 56 | { |
| 60 | if (buf->p + len > buf->ep) { | 57 | if (buf->p + len > buf->ep) { |
| 61 | if (buf->p < buf->ep) { | 58 | if (buf->p < buf->ep) { |
| 62 | eprintk(KERN_ERR, "buffer overflow: want %d has %d\n", | 59 | P9_EPRINTK(KERN_ERR, |
| 63 | len, (int)(buf->ep - buf->p)); | 60 | "buffer overflow: want %d has %d\n", len, |
| 61 | (int)(buf->ep - buf->p)); | ||
| 64 | dump_stack(); | 62 | dump_stack(); |
| 65 | buf->p = buf->ep + 1; | 63 | buf->p = buf->ep + 1; |
| 66 | } | 64 | } |
| @@ -183,7 +181,7 @@ static u64 buf_get_int64(struct cbuf *buf) | |||
| 183 | return ret; | 181 | return ret; |
| 184 | } | 182 | } |
| 185 | 183 | ||
| 186 | static void buf_get_str(struct cbuf *buf, struct v9fs_str *vstr) | 184 | static void buf_get_str(struct cbuf *buf, struct p9_str *vstr) |
| 187 | { | 185 | { |
| 188 | vstr->len = buf_get_int16(buf); | 186 | vstr->len = buf_get_int16(buf); |
| 189 | if (!buf_check_overflow(buf) && buf_check_size(buf, vstr->len)) { | 187 | if (!buf_check_overflow(buf) && buf_check_size(buf, vstr->len)) { |
| @@ -195,7 +193,7 @@ static void buf_get_str(struct cbuf *buf, struct v9fs_str *vstr) | |||
| 195 | } | 193 | } |
| 196 | } | 194 | } |
| 197 | 195 | ||
| 198 | static void buf_get_qid(struct cbuf *bufp, struct v9fs_qid *qid) | 196 | static void buf_get_qid(struct cbuf *bufp, struct p9_qid *qid) |
| 199 | { | 197 | { |
| 200 | qid->type = buf_get_int8(bufp); | 198 | qid->type = buf_get_int8(bufp); |
| 201 | qid->version = buf_get_int32(bufp); | 199 | qid->version = buf_get_int32(bufp); |
| @@ -203,18 +201,18 @@ static void buf_get_qid(struct cbuf *bufp, struct v9fs_qid *qid) | |||
| 203 | } | 201 | } |
| 204 | 202 | ||
| 205 | /** | 203 | /** |
| 206 | * v9fs_size_wstat - calculate the size of a variable length stat struct | 204 | * p9_size_wstat - calculate the size of a variable length stat struct |
| 207 | * @stat: metadata (stat) structure | 205 | * @stat: metadata (stat) structure |
| 208 | * @extended: non-zero if 9P2000.u | 206 | * @dotu: non-zero if 9P2000.u |
| 209 | * | 207 | * |
| 210 | */ | 208 | */ |
| 211 | 209 | ||
| 212 | static int v9fs_size_wstat(struct v9fs_wstat *wstat, int extended) | 210 | static int p9_size_wstat(struct p9_wstat *wstat, int dotu) |
| 213 | { | 211 | { |
| 214 | int size = 0; | 212 | int size = 0; |
| 215 | 213 | ||
| 216 | if (wstat == NULL) { | 214 | if (wstat == NULL) { |
| 217 | eprintk(KERN_ERR, "v9fs_size_stat: got a NULL stat pointer\n"); | 215 | P9_EPRINTK(KERN_ERR, "p9_size_stat: got a NULL stat pointer\n"); |
| 218 | return 0; | 216 | return 0; |
| 219 | } | 217 | } |
| 220 | 218 | ||
| @@ -239,7 +237,7 @@ static int v9fs_size_wstat(struct v9fs_wstat *wstat, int extended) | |||
| 239 | if (wstat->muid) | 237 | if (wstat->muid) |
| 240 | size += strlen(wstat->muid); | 238 | size += strlen(wstat->muid); |
| 241 | 239 | ||
| 242 | if (extended) { | 240 | if (dotu) { |
| 243 | size += 4 + /* n_uid[4] */ | 241 | size += 4 + /* n_uid[4] */ |
| 244 | 4 + /* n_gid[4] */ | 242 | 4 + /* n_gid[4] */ |
| 245 | 4 + /* n_muid[4] */ | 243 | 4 + /* n_muid[4] */ |
| @@ -255,12 +253,12 @@ static int v9fs_size_wstat(struct v9fs_wstat *wstat, int extended) | |||
| 255 | * buf_get_stat - safely decode a recieved metadata (stat) structure | 253 | * buf_get_stat - safely decode a recieved metadata (stat) structure |
| 256 | * @bufp: buffer to deserialize | 254 | * @bufp: buffer to deserialize |
| 257 | * @stat: metadata (stat) structure | 255 | * @stat: metadata (stat) structure |
| 258 | * @extended: non-zero if 9P2000.u | 256 | * @dotu: non-zero if 9P2000.u |
| 259 | * | 257 | * |
| 260 | */ | 258 | */ |
| 261 | 259 | ||
| 262 | static void | 260 | static void |
| 263 | buf_get_stat(struct cbuf *bufp, struct v9fs_stat *stat, int extended) | 261 | buf_get_stat(struct cbuf *bufp, struct p9_stat *stat, int dotu) |
| 264 | { | 262 | { |
| 265 | stat->size = buf_get_int16(bufp); | 263 | stat->size = buf_get_int16(bufp); |
| 266 | stat->type = buf_get_int16(bufp); | 264 | stat->type = buf_get_int16(bufp); |
| @@ -277,7 +275,7 @@ buf_get_stat(struct cbuf *bufp, struct v9fs_stat *stat, int extended) | |||
| 277 | buf_get_str(bufp, &stat->gid); | 275 | buf_get_str(bufp, &stat->gid); |
| 278 | buf_get_str(bufp, &stat->muid); | 276 | buf_get_str(bufp, &stat->muid); |
| 279 | 277 | ||
| 280 | if (extended) { | 278 | if (dotu) { |
| 281 | buf_get_str(bufp, &stat->extension); | 279 | buf_get_str(bufp, &stat->extension); |
| 282 | stat->n_uid = buf_get_int32(bufp); | 280 | stat->n_uid = buf_get_int32(bufp); |
| 283 | stat->n_gid = buf_get_int32(bufp); | 281 | stat->n_gid = buf_get_int32(bufp); |
| @@ -286,18 +284,18 @@ buf_get_stat(struct cbuf *bufp, struct v9fs_stat *stat, int extended) | |||
| 286 | } | 284 | } |
| 287 | 285 | ||
| 288 | /** | 286 | /** |
| 289 | * v9fs_deserialize_stat - decode a received metadata structure | 287 | * p9_deserialize_stat - decode a received metadata structure |
| 290 | * @buf: buffer to deserialize | 288 | * @buf: buffer to deserialize |
| 291 | * @buflen: length of received buffer | 289 | * @buflen: length of received buffer |
| 292 | * @stat: metadata structure to decode into | 290 | * @stat: metadata structure to decode into |
| 293 | * @extended: non-zero if 9P2000.u | 291 | * @dotu: non-zero if 9P2000.u |
| 294 | * | 292 | * |
| 295 | * Note: stat will point to the buf region. | 293 | * Note: stat will point to the buf region. |
| 296 | */ | 294 | */ |
| 297 | 295 | ||
| 298 | int | 296 | int |
| 299 | v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat, | 297 | p9_deserialize_stat(void *buf, u32 buflen, struct p9_stat *stat, |
| 300 | int extended) | 298 | int dotu) |
| 301 | { | 299 | { |
| 302 | struct cbuf buffer; | 300 | struct cbuf buffer; |
| 303 | struct cbuf *bufp = &buffer; | 301 | struct cbuf *bufp = &buffer; |
| @@ -305,13 +303,14 @@ v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat, | |||
| 305 | 303 | ||
| 306 | buf_init(bufp, buf, buflen); | 304 | buf_init(bufp, buf, buflen); |
| 307 | p = bufp->p; | 305 | p = bufp->p; |
| 308 | buf_get_stat(bufp, stat, extended); | 306 | buf_get_stat(bufp, stat, dotu); |
| 309 | 307 | ||
| 310 | if (buf_check_overflow(bufp)) | 308 | if (buf_check_overflow(bufp)) |
| 311 | return 0; | 309 | return 0; |
| 312 | else | 310 | else |
| 313 | return bufp->p - p; | 311 | return bufp->p - p; |
| 314 | } | 312 | } |
| 313 | EXPORT_SYMBOL(p9_deserialize_stat); | ||
| 315 | 314 | ||
| 316 | /** | 315 | /** |
| 317 | * deserialize_fcall - unmarshal a response | 316 | * deserialize_fcall - unmarshal a response |
| @@ -319,13 +318,13 @@ v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat, | |||
| 319 | * @buflen: length of received buffer | 318 | * @buflen: length of received buffer |
| 320 | * @rcall: fcall structure to populate | 319 | * @rcall: fcall structure to populate |
| 321 | * @rcalllen: length of fcall structure to populate | 320 | * @rcalllen: length of fcall structure to populate |
| 322 | * @extended: non-zero if 9P2000.u | 321 | * @dotu: non-zero if 9P2000.u |
| 323 | * | 322 | * |
| 324 | */ | 323 | */ |
| 325 | 324 | ||
| 326 | int | 325 | int |
| 327 | v9fs_deserialize_fcall(void *buf, u32 buflen, struct v9fs_fcall *rcall, | 326 | p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *rcall, |
| 328 | int extended) | 327 | int dotu) |
| 329 | { | 328 | { |
| 330 | 329 | ||
| 331 | struct cbuf buffer; | 330 | struct cbuf buffer; |
| @@ -338,102 +337,104 @@ v9fs_deserialize_fcall(void *buf, u32 buflen, struct v9fs_fcall *rcall, | |||
| 338 | rcall->id = buf_get_int8(bufp); | 337 | rcall->id = buf_get_int8(bufp); |
| 339 | rcall->tag = buf_get_int16(bufp); | 338 | rcall->tag = buf_get_int16(bufp); |
| 340 | 339 | ||
| 341 | dprintk(DEBUG_CONV, "size %d id %d tag %d\n", rcall->size, rcall->id, | 340 | P9_DPRINTK(P9_DEBUG_CONV, "size %d id %d tag %d\n", rcall->size, |
| 342 | rcall->tag); | 341 | rcall->id, rcall->tag); |
| 343 | 342 | ||
| 344 | switch (rcall->id) { | 343 | switch (rcall->id) { |
| 345 | default: | 344 | default: |
| 346 | eprintk(KERN_ERR, "unknown message type: %d\n", rcall->id); | 345 | P9_EPRINTK(KERN_ERR, "unknown message type: %d\n", rcall->id); |
| 347 | return -EPROTO; | 346 | return -EPROTO; |
| 348 | case RVERSION: | 347 | case P9_RVERSION: |
| 349 | rcall->params.rversion.msize = buf_get_int32(bufp); | 348 | rcall->params.rversion.msize = buf_get_int32(bufp); |
| 350 | buf_get_str(bufp, &rcall->params.rversion.version); | 349 | buf_get_str(bufp, &rcall->params.rversion.version); |
| 351 | break; | 350 | break; |
| 352 | case RFLUSH: | 351 | case P9_RFLUSH: |
| 353 | break; | 352 | break; |
| 354 | case RATTACH: | 353 | case P9_RATTACH: |
| 355 | rcall->params.rattach.qid.type = buf_get_int8(bufp); | 354 | rcall->params.rattach.qid.type = buf_get_int8(bufp); |
| 356 | rcall->params.rattach.qid.version = buf_get_int32(bufp); | 355 | rcall->params.rattach.qid.version = buf_get_int32(bufp); |
| 357 | rcall->params.rattach.qid.path = buf_get_int64(bufp); | 356 | rcall->params.rattach.qid.path = buf_get_int64(bufp); |
| 358 | break; | 357 | break; |
| 359 | case RWALK: | 358 | case P9_RWALK: |
| 360 | rcall->params.rwalk.nwqid = buf_get_int16(bufp); | 359 | rcall->params.rwalk.nwqid = buf_get_int16(bufp); |
| 361 | if (rcall->params.rwalk.nwqid > V9FS_MAXWELEM) { | 360 | if (rcall->params.rwalk.nwqid > P9_MAXWELEM) { |
| 362 | eprintk(KERN_ERR, "Rwalk with more than %d qids: %d\n", | 361 | P9_EPRINTK(KERN_ERR, |
| 363 | V9FS_MAXWELEM, rcall->params.rwalk.nwqid); | 362 | "Rwalk with more than %d qids: %d\n", |
| 363 | P9_MAXWELEM, rcall->params.rwalk.nwqid); | ||
| 364 | return -EPROTO; | 364 | return -EPROTO; |
| 365 | } | 365 | } |
| 366 | 366 | ||
| 367 | for (i = 0; i < rcall->params.rwalk.nwqid; i++) | 367 | for (i = 0; i < rcall->params.rwalk.nwqid; i++) |
| 368 | buf_get_qid(bufp, &rcall->params.rwalk.wqids[i]); | 368 | buf_get_qid(bufp, &rcall->params.rwalk.wqids[i]); |
| 369 | break; | 369 | break; |
| 370 | case ROPEN: | 370 | case P9_ROPEN: |
| 371 | buf_get_qid(bufp, &rcall->params.ropen.qid); | 371 | buf_get_qid(bufp, &rcall->params.ropen.qid); |
| 372 | rcall->params.ropen.iounit = buf_get_int32(bufp); | 372 | rcall->params.ropen.iounit = buf_get_int32(bufp); |
| 373 | break; | 373 | break; |
| 374 | case RCREATE: | 374 | case P9_RCREATE: |
| 375 | buf_get_qid(bufp, &rcall->params.rcreate.qid); | 375 | buf_get_qid(bufp, &rcall->params.rcreate.qid); |
| 376 | rcall->params.rcreate.iounit = buf_get_int32(bufp); | 376 | rcall->params.rcreate.iounit = buf_get_int32(bufp); |
| 377 | break; | 377 | break; |
| 378 | case RREAD: | 378 | case P9_RREAD: |
| 379 | rcall->params.rread.count = buf_get_int32(bufp); | 379 | rcall->params.rread.count = buf_get_int32(bufp); |
| 380 | rcall->params.rread.data = bufp->p; | 380 | rcall->params.rread.data = bufp->p; |
| 381 | buf_check_size(bufp, rcall->params.rread.count); | 381 | buf_check_size(bufp, rcall->params.rread.count); |
| 382 | break; | 382 | break; |
| 383 | case RWRITE: | 383 | case P9_RWRITE: |
| 384 | rcall->params.rwrite.count = buf_get_int32(bufp); | 384 | rcall->params.rwrite.count = buf_get_int32(bufp); |
| 385 | break; | 385 | break; |
| 386 | case RCLUNK: | 386 | case P9_RCLUNK: |
| 387 | break; | 387 | break; |
| 388 | case RREMOVE: | 388 | case P9_RREMOVE: |
| 389 | break; | 389 | break; |
| 390 | case RSTAT: | 390 | case P9_RSTAT: |
| 391 | buf_get_int16(bufp); | 391 | buf_get_int16(bufp); |
| 392 | buf_get_stat(bufp, &rcall->params.rstat.stat, extended); | 392 | buf_get_stat(bufp, &rcall->params.rstat.stat, dotu); |
| 393 | break; | 393 | break; |
| 394 | case RWSTAT: | 394 | case P9_RWSTAT: |
| 395 | break; | 395 | break; |
| 396 | case RERROR: | 396 | case P9_RERROR: |
| 397 | buf_get_str(bufp, &rcall->params.rerror.error); | 397 | buf_get_str(bufp, &rcall->params.rerror.error); |
| 398 | if (extended) | 398 | if (dotu) |
| 399 | rcall->params.rerror.errno = buf_get_int16(bufp); | 399 | rcall->params.rerror.errno = buf_get_int16(bufp); |
| 400 | break; | 400 | break; |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | if (buf_check_overflow(bufp)) { | 403 | if (buf_check_overflow(bufp)) { |
| 404 | dprintk(DEBUG_ERROR, "buffer overflow\n"); | 404 | P9_DPRINTK(P9_DEBUG_ERROR, "buffer overflow\n"); |
| 405 | return -EIO; | 405 | return -EIO; |
| 406 | } | 406 | } |
| 407 | 407 | ||
| 408 | return bufp->p - bufp->sp; | 408 | return bufp->p - bufp->sp; |
| 409 | } | 409 | } |
| 410 | EXPORT_SYMBOL(p9_deserialize_fcall); | ||
| 410 | 411 | ||
| 411 | static inline void v9fs_put_int8(struct cbuf *bufp, u8 val, u8 * p) | 412 | static inline void p9_put_int8(struct cbuf *bufp, u8 val, u8 * p) |
| 412 | { | 413 | { |
| 413 | *p = val; | 414 | *p = val; |
| 414 | buf_put_int8(bufp, val); | 415 | buf_put_int8(bufp, val); |
| 415 | } | 416 | } |
| 416 | 417 | ||
| 417 | static inline void v9fs_put_int16(struct cbuf *bufp, u16 val, u16 * p) | 418 | static inline void p9_put_int16(struct cbuf *bufp, u16 val, u16 * p) |
| 418 | { | 419 | { |
| 419 | *p = val; | 420 | *p = val; |
| 420 | buf_put_int16(bufp, val); | 421 | buf_put_int16(bufp, val); |
| 421 | } | 422 | } |
| 422 | 423 | ||
| 423 | static inline void v9fs_put_int32(struct cbuf *bufp, u32 val, u32 * p) | 424 | static inline void p9_put_int32(struct cbuf *bufp, u32 val, u32 * p) |
| 424 | { | 425 | { |
| 425 | *p = val; | 426 | *p = val; |
| 426 | buf_put_int32(bufp, val); | 427 | buf_put_int32(bufp, val); |
| 427 | } | 428 | } |
| 428 | 429 | ||
| 429 | static inline void v9fs_put_int64(struct cbuf *bufp, u64 val, u64 * p) | 430 | static inline void p9_put_int64(struct cbuf *bufp, u64 val, u64 * p) |
| 430 | { | 431 | { |
| 431 | *p = val; | 432 | *p = val; |
| 432 | buf_put_int64(bufp, val); | 433 | buf_put_int64(bufp, val); |
| 433 | } | 434 | } |
| 434 | 435 | ||
| 435 | static void | 436 | static void |
| 436 | v9fs_put_str(struct cbuf *bufp, char *data, struct v9fs_str *str) | 437 | p9_put_str(struct cbuf *bufp, char *data, struct p9_str *str) |
| 437 | { | 438 | { |
| 438 | int len; | 439 | int len; |
| 439 | char *s; | 440 | char *s; |
| @@ -451,7 +452,16 @@ v9fs_put_str(struct cbuf *bufp, char *data, struct v9fs_str *str) | |||
| 451 | } | 452 | } |
| 452 | 453 | ||
| 453 | static int | 454 | static int |
| 454 | v9fs_put_user_data(struct cbuf *bufp, const char __user * data, int count, | 455 | p9_put_data(struct cbuf *bufp, const char *data, int count, |
| 456 | unsigned char **pdata) | ||
| 457 | { | ||
| 458 | *pdata = buf_alloc(bufp, count); | ||
| 459 | memmove(*pdata, data, count); | ||
| 460 | return count; | ||
| 461 | } | ||
| 462 | |||
| 463 | static int | ||
| 464 | p9_put_user_data(struct cbuf *bufp, const char __user *data, int count, | ||
| 455 | unsigned char **pdata) | 465 | unsigned char **pdata) |
| 456 | { | 466 | { |
| 457 | *pdata = buf_alloc(bufp, count); | 467 | *pdata = buf_alloc(bufp, count); |
| @@ -459,162 +469,167 @@ v9fs_put_user_data(struct cbuf *bufp, const char __user * data, int count, | |||
| 459 | } | 469 | } |
| 460 | 470 | ||
| 461 | static void | 471 | static void |
| 462 | v9fs_put_wstat(struct cbuf *bufp, struct v9fs_wstat *wstat, | 472 | p9_put_wstat(struct cbuf *bufp, struct p9_wstat *wstat, |
| 463 | struct v9fs_stat *stat, int statsz, int extended) | 473 | struct p9_stat *stat, int statsz, int dotu) |
| 464 | { | 474 | { |
| 465 | v9fs_put_int16(bufp, statsz, &stat->size); | 475 | p9_put_int16(bufp, statsz, &stat->size); |
| 466 | v9fs_put_int16(bufp, wstat->type, &stat->type); | 476 | p9_put_int16(bufp, wstat->type, &stat->type); |
| 467 | v9fs_put_int32(bufp, wstat->dev, &stat->dev); | 477 | p9_put_int32(bufp, wstat->dev, &stat->dev); |
| 468 | v9fs_put_int8(bufp, wstat->qid.type, &stat->qid.type); | 478 | p9_put_int8(bufp, wstat->qid.type, &stat->qid.type); |
| 469 | v9fs_put_int32(bufp, wstat->qid.version, &stat->qid.version); | 479 | p9_put_int32(bufp, wstat->qid.version, &stat->qid.version); |
| 470 | v9fs_put_int64(bufp, wstat->qid.path, &stat->qid.path); | 480 | p9_put_int64(bufp, wstat->qid.path, &stat->qid.path); |
| 471 | v9fs_put_int32(bufp, wstat->mode, &stat->mode); | 481 | p9_put_int32(bufp, wstat->mode, &stat->mode); |
| 472 | v9fs_put_int32(bufp, wstat->atime, &stat->atime); | 482 | p9_put_int32(bufp, wstat->atime, &stat->atime); |
| 473 | v9fs_put_int32(bufp, wstat->mtime, &stat->mtime); | 483 | p9_put_int32(bufp, wstat->mtime, &stat->mtime); |
| 474 | v9fs_put_int64(bufp, wstat->length, &stat->length); | 484 | p9_put_int64(bufp, wstat->length, &stat->length); |
| 475 | 485 | ||
| 476 | v9fs_put_str(bufp, wstat->name, &stat->name); | 486 | p9_put_str(bufp, wstat->name, &stat->name); |
| 477 | v9fs_put_str(bufp, wstat->uid, &stat->uid); | 487 | p9_put_str(bufp, wstat->uid, &stat->uid); |
| 478 | v9fs_put_str(bufp, wstat->gid, &stat->gid); | 488 | p9_put_str(bufp, wstat->gid, &stat->gid); |
| 479 | v9fs_put_str(bufp, wstat->muid, &stat->muid); | 489 | p9_put_str(bufp, wstat->muid, &stat->muid); |
| 480 | 490 | ||
| 481 | if (extended) { | 491 | if (dotu) { |
| 482 | v9fs_put_str(bufp, wstat->extension, &stat->extension); | 492 | p9_put_str(bufp, wstat->extension, &stat->extension); |
| 483 | v9fs_put_int32(bufp, wstat->n_uid, &stat->n_uid); | 493 | p9_put_int32(bufp, wstat->n_uid, &stat->n_uid); |
| 484 | v9fs_put_int32(bufp, wstat->n_gid, &stat->n_gid); | 494 | p9_put_int32(bufp, wstat->n_gid, &stat->n_gid); |
| 485 | v9fs_put_int32(bufp, wstat->n_muid, &stat->n_muid); | 495 | p9_put_int32(bufp, wstat->n_muid, &stat->n_muid); |
| 486 | } | 496 | } |
| 487 | } | 497 | } |
| 488 | 498 | ||
| 489 | static struct v9fs_fcall * | 499 | static struct p9_fcall * |
| 490 | v9fs_create_common(struct cbuf *bufp, u32 size, u8 id) | 500 | p9_create_common(struct cbuf *bufp, u32 size, u8 id) |
| 491 | { | 501 | { |
| 492 | struct v9fs_fcall *fc; | 502 | struct p9_fcall *fc; |
| 493 | 503 | ||
| 494 | size += 4 + 1 + 2; /* size[4] id[1] tag[2] */ | 504 | size += 4 + 1 + 2; /* size[4] id[1] tag[2] */ |
| 495 | fc = kmalloc(sizeof(struct v9fs_fcall) + size, GFP_KERNEL); | 505 | fc = kmalloc(sizeof(struct p9_fcall) + size, GFP_KERNEL); |
| 496 | if (!fc) | 506 | if (!fc) |
| 497 | return ERR_PTR(-ENOMEM); | 507 | return ERR_PTR(-ENOMEM); |
| 498 | 508 | ||
| 499 | fc->sdata = (char *)fc + sizeof(*fc); | 509 | fc->sdata = (char *)fc + sizeof(*fc); |
| 500 | 510 | ||
| 501 | buf_init(bufp, (char *)fc->sdata, size); | 511 | buf_init(bufp, (char *)fc->sdata, size); |
| 502 | v9fs_put_int32(bufp, size, &fc->size); | 512 | p9_put_int32(bufp, size, &fc->size); |
| 503 | v9fs_put_int8(bufp, id, &fc->id); | 513 | p9_put_int8(bufp, id, &fc->id); |
| 504 | v9fs_put_int16(bufp, V9FS_NOTAG, &fc->tag); | 514 | p9_put_int16(bufp, P9_NOTAG, &fc->tag); |
| 505 | 515 | ||
| 506 | return fc; | 516 | return fc; |
| 507 | } | 517 | } |
| 508 | 518 | ||
| 509 | void v9fs_set_tag(struct v9fs_fcall *fc, u16 tag) | 519 | void p9_set_tag(struct p9_fcall *fc, u16 tag) |
| 510 | { | 520 | { |
| 511 | fc->tag = tag; | 521 | fc->tag = tag; |
| 512 | *(__le16 *) (fc->sdata + 5) = cpu_to_le16(tag); | 522 | *(__le16 *) (fc->sdata + 5) = cpu_to_le16(tag); |
| 513 | } | 523 | } |
| 524 | EXPORT_SYMBOL(p9_set_tag); | ||
| 514 | 525 | ||
| 515 | struct v9fs_fcall *v9fs_create_tversion(u32 msize, char *version) | 526 | struct p9_fcall *p9_create_tversion(u32 msize, char *version) |
| 516 | { | 527 | { |
| 517 | int size; | 528 | int size; |
| 518 | struct v9fs_fcall *fc; | 529 | struct p9_fcall *fc; |
| 519 | struct cbuf buffer; | 530 | struct cbuf buffer; |
| 520 | struct cbuf *bufp = &buffer; | 531 | struct cbuf *bufp = &buffer; |
| 521 | 532 | ||
| 522 | size = 4 + 2 + strlen(version); /* msize[4] version[s] */ | 533 | size = 4 + 2 + strlen(version); /* msize[4] version[s] */ |
| 523 | fc = v9fs_create_common(bufp, size, TVERSION); | 534 | fc = p9_create_common(bufp, size, P9_TVERSION); |
| 524 | if (IS_ERR(fc)) | 535 | if (IS_ERR(fc)) |
| 525 | goto error; | 536 | goto error; |
| 526 | 537 | ||
| 527 | v9fs_put_int32(bufp, msize, &fc->params.tversion.msize); | 538 | p9_put_int32(bufp, msize, &fc->params.tversion.msize); |
| 528 | v9fs_put_str(bufp, version, &fc->params.tversion.version); | 539 | p9_put_str(bufp, version, &fc->params.tversion.version); |
| 529 | 540 | ||
| 530 | if (buf_check_overflow(bufp)) { | 541 | if (buf_check_overflow(bufp)) { |
| 531 | kfree(fc); | 542 | kfree(fc); |
| 532 | fc = ERR_PTR(-ENOMEM); | 543 | fc = ERR_PTR(-ENOMEM); |
| 533 | } | 544 | } |
| 534 | error: | 545 | error: |
| 535 | return fc; | 546 | return fc; |
| 536 | } | 547 | } |
| 548 | EXPORT_SYMBOL(p9_create_tversion); | ||
| 537 | 549 | ||
| 538 | #if 0 | 550 | struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname) |
| 539 | struct v9fs_fcall *v9fs_create_tauth(u32 afid, char *uname, char *aname) | ||
| 540 | { | 551 | { |
| 541 | int size; | 552 | int size; |
| 542 | struct v9fs_fcall *fc; | 553 | struct p9_fcall *fc; |
| 543 | struct cbuf buffer; | 554 | struct cbuf buffer; |
| 544 | struct cbuf *bufp = &buffer; | 555 | struct cbuf *bufp = &buffer; |
| 545 | 556 | ||
| 546 | size = 4 + 2 + strlen(uname) + 2 + strlen(aname); /* afid[4] uname[s] aname[s] */ | 557 | /* afid[4] uname[s] aname[s] */ |
| 547 | fc = v9fs_create_common(bufp, size, TAUTH); | 558 | size = 4 + 2 + strlen(uname) + 2 + strlen(aname); |
| 559 | fc = p9_create_common(bufp, size, P9_TAUTH); | ||
| 548 | if (IS_ERR(fc)) | 560 | if (IS_ERR(fc)) |
| 549 | goto error; | 561 | goto error; |
| 550 | 562 | ||
| 551 | v9fs_put_int32(bufp, afid, &fc->params.tauth.afid); | 563 | p9_put_int32(bufp, afid, &fc->params.tauth.afid); |
| 552 | v9fs_put_str(bufp, uname, &fc->params.tauth.uname); | 564 | p9_put_str(bufp, uname, &fc->params.tauth.uname); |
| 553 | v9fs_put_str(bufp, aname, &fc->params.tauth.aname); | 565 | p9_put_str(bufp, aname, &fc->params.tauth.aname); |
| 554 | 566 | ||
| 555 | if (buf_check_overflow(bufp)) { | 567 | if (buf_check_overflow(bufp)) { |
| 556 | kfree(fc); | 568 | kfree(fc); |
| 557 | fc = ERR_PTR(-ENOMEM); | 569 | fc = ERR_PTR(-ENOMEM); |
| 558 | } | 570 | } |
| 559 | error: | 571 | error: |
| 560 | return fc; | 572 | return fc; |
| 561 | } | 573 | } |
| 562 | #endif /* 0 */ | 574 | EXPORT_SYMBOL(p9_create_tauth); |
| 563 | 575 | ||
| 564 | struct v9fs_fcall * | 576 | struct p9_fcall * |
| 565 | v9fs_create_tattach(u32 fid, u32 afid, char *uname, char *aname) | 577 | p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname) |
| 566 | { | 578 | { |
| 567 | int size; | 579 | int size; |
| 568 | struct v9fs_fcall *fc; | 580 | struct p9_fcall *fc; |
| 569 | struct cbuf buffer; | 581 | struct cbuf buffer; |
| 570 | struct cbuf *bufp = &buffer; | 582 | struct cbuf *bufp = &buffer; |
| 571 | 583 | ||
| 572 | size = 4 + 4 + 2 + strlen(uname) + 2 + strlen(aname); /* fid[4] afid[4] uname[s] aname[s] */ | 584 | /* fid[4] afid[4] uname[s] aname[s] */ |
| 573 | fc = v9fs_create_common(bufp, size, TATTACH); | 585 | size = 4 + 4 + 2 + strlen(uname) + 2 + strlen(aname); |
| 586 | fc = p9_create_common(bufp, size, P9_TATTACH); | ||
| 574 | if (IS_ERR(fc)) | 587 | if (IS_ERR(fc)) |
| 575 | goto error; | 588 | goto error; |
| 576 | 589 | ||
| 577 | v9fs_put_int32(bufp, fid, &fc->params.tattach.fid); | 590 | p9_put_int32(bufp, fid, &fc->params.tattach.fid); |
| 578 | v9fs_put_int32(bufp, afid, &fc->params.tattach.afid); | 591 | p9_put_int32(bufp, afid, &fc->params.tattach.afid); |
| 579 | v9fs_put_str(bufp, uname, &fc->params.tattach.uname); | 592 | p9_put_str(bufp, uname, &fc->params.tattach.uname); |
| 580 | v9fs_put_str(bufp, aname, &fc->params.tattach.aname); | 593 | p9_put_str(bufp, aname, &fc->params.tattach.aname); |
| 581 | 594 | ||
| 582 | error: | 595 | error: |
| 583 | return fc; | 596 | return fc; |
| 584 | } | 597 | } |
| 598 | EXPORT_SYMBOL(p9_create_tattach); | ||
| 585 | 599 | ||
| 586 | struct v9fs_fcall *v9fs_create_tflush(u16 oldtag) | 600 | struct p9_fcall *p9_create_tflush(u16 oldtag) |
| 587 | { | 601 | { |
| 588 | int size; | 602 | int size; |
| 589 | struct v9fs_fcall *fc; | 603 | struct p9_fcall *fc; |
| 590 | struct cbuf buffer; | 604 | struct cbuf buffer; |
| 591 | struct cbuf *bufp = &buffer; | 605 | struct cbuf *bufp = &buffer; |
| 592 | 606 | ||
| 593 | size = 2; /* oldtag[2] */ | 607 | size = 2; /* oldtag[2] */ |
| 594 | fc = v9fs_create_common(bufp, size, TFLUSH); | 608 | fc = p9_create_common(bufp, size, P9_TFLUSH); |
| 595 | if (IS_ERR(fc)) | 609 | if (IS_ERR(fc)) |
| 596 | goto error; | 610 | goto error; |
| 597 | 611 | ||
| 598 | v9fs_put_int16(bufp, oldtag, &fc->params.tflush.oldtag); | 612 | p9_put_int16(bufp, oldtag, &fc->params.tflush.oldtag); |
| 599 | 613 | ||
| 600 | if (buf_check_overflow(bufp)) { | 614 | if (buf_check_overflow(bufp)) { |
| 601 | kfree(fc); | 615 | kfree(fc); |
| 602 | fc = ERR_PTR(-ENOMEM); | 616 | fc = ERR_PTR(-ENOMEM); |
| 603 | } | 617 | } |
| 604 | error: | 618 | error: |
| 605 | return fc; | 619 | return fc; |
| 606 | } | 620 | } |
| 621 | EXPORT_SYMBOL(p9_create_tflush); | ||
| 607 | 622 | ||
| 608 | struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, | 623 | struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname, |
| 609 | char **wnames) | 624 | char **wnames) |
| 610 | { | 625 | { |
| 611 | int i, size; | 626 | int i, size; |
| 612 | struct v9fs_fcall *fc; | 627 | struct p9_fcall *fc; |
| 613 | struct cbuf buffer; | 628 | struct cbuf buffer; |
| 614 | struct cbuf *bufp = &buffer; | 629 | struct cbuf *bufp = &buffer; |
| 615 | 630 | ||
| 616 | if (nwname > V9FS_MAXWELEM) { | 631 | if (nwname > P9_MAXWELEM) { |
| 617 | dprintk(DEBUG_ERROR, "nwname > %d\n", V9FS_MAXWELEM); | 632 | P9_DPRINTK(P9_DEBUG_ERROR, "nwname > %d\n", P9_MAXWELEM); |
| 618 | return NULL; | 633 | return NULL; |
| 619 | } | 634 | } |
| 620 | 635 | ||
| @@ -623,122 +638,160 @@ struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, | |||
| 623 | size += 2 + strlen(wnames[i]); /* wname[s] */ | 638 | size += 2 + strlen(wnames[i]); /* wname[s] */ |
| 624 | } | 639 | } |
| 625 | 640 | ||
| 626 | fc = v9fs_create_common(bufp, size, TWALK); | 641 | fc = p9_create_common(bufp, size, P9_TWALK); |
| 627 | if (IS_ERR(fc)) | 642 | if (IS_ERR(fc)) |
| 628 | goto error; | 643 | goto error; |
| 629 | 644 | ||
| 630 | v9fs_put_int32(bufp, fid, &fc->params.twalk.fid); | 645 | p9_put_int32(bufp, fid, &fc->params.twalk.fid); |
| 631 | v9fs_put_int32(bufp, newfid, &fc->params.twalk.newfid); | 646 | p9_put_int32(bufp, newfid, &fc->params.twalk.newfid); |
| 632 | v9fs_put_int16(bufp, nwname, &fc->params.twalk.nwname); | 647 | p9_put_int16(bufp, nwname, &fc->params.twalk.nwname); |
| 633 | for (i = 0; i < nwname; i++) { | 648 | for (i = 0; i < nwname; i++) { |
| 634 | v9fs_put_str(bufp, wnames[i], &fc->params.twalk.wnames[i]); | 649 | p9_put_str(bufp, wnames[i], &fc->params.twalk.wnames[i]); |
| 635 | } | 650 | } |
| 636 | 651 | ||
| 637 | if (buf_check_overflow(bufp)) { | 652 | if (buf_check_overflow(bufp)) { |
| 638 | kfree(fc); | 653 | kfree(fc); |
| 639 | fc = ERR_PTR(-ENOMEM); | 654 | fc = ERR_PTR(-ENOMEM); |
| 640 | } | 655 | } |
| 641 | error: | 656 | error: |
| 642 | return fc; | 657 | return fc; |
| 643 | } | 658 | } |
| 659 | EXPORT_SYMBOL(p9_create_twalk); | ||
| 644 | 660 | ||
| 645 | struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode) | 661 | struct p9_fcall *p9_create_topen(u32 fid, u8 mode) |
| 646 | { | 662 | { |
| 647 | int size; | 663 | int size; |
| 648 | struct v9fs_fcall *fc; | 664 | struct p9_fcall *fc; |
| 649 | struct cbuf buffer; | 665 | struct cbuf buffer; |
| 650 | struct cbuf *bufp = &buffer; | 666 | struct cbuf *bufp = &buffer; |
| 651 | 667 | ||
| 652 | size = 4 + 1; /* fid[4] mode[1] */ | 668 | size = 4 + 1; /* fid[4] mode[1] */ |
| 653 | fc = v9fs_create_common(bufp, size, TOPEN); | 669 | fc = p9_create_common(bufp, size, P9_TOPEN); |
| 654 | if (IS_ERR(fc)) | 670 | if (IS_ERR(fc)) |
| 655 | goto error; | 671 | goto error; |
| 656 | 672 | ||
| 657 | v9fs_put_int32(bufp, fid, &fc->params.topen.fid); | 673 | p9_put_int32(bufp, fid, &fc->params.topen.fid); |
| 658 | v9fs_put_int8(bufp, mode, &fc->params.topen.mode); | 674 | p9_put_int8(bufp, mode, &fc->params.topen.mode); |
| 659 | 675 | ||
| 660 | if (buf_check_overflow(bufp)) { | 676 | if (buf_check_overflow(bufp)) { |
| 661 | kfree(fc); | 677 | kfree(fc); |
| 662 | fc = ERR_PTR(-ENOMEM); | 678 | fc = ERR_PTR(-ENOMEM); |
| 663 | } | 679 | } |
| 664 | error: | 680 | error: |
| 665 | return fc; | 681 | return fc; |
| 666 | } | 682 | } |
| 683 | EXPORT_SYMBOL(p9_create_topen); | ||
| 667 | 684 | ||
| 668 | struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, | 685 | struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, |
| 669 | char *extension, int extended) | 686 | char *extension, int dotu) |
| 670 | { | 687 | { |
| 671 | int size; | 688 | int size; |
| 672 | struct v9fs_fcall *fc; | 689 | struct p9_fcall *fc; |
| 673 | struct cbuf buffer; | 690 | struct cbuf buffer; |
| 674 | struct cbuf *bufp = &buffer; | 691 | struct cbuf *bufp = &buffer; |
| 675 | 692 | ||
| 676 | size = 4 + 2 + strlen(name) + 4 + 1; /* fid[4] name[s] perm[4] mode[1] */ | 693 | /* fid[4] name[s] perm[4] mode[1] */ |
| 677 | if (extended) { | 694 | size = 4 + 2 + strlen(name) + 4 + 1; |
| 695 | if (dotu) { | ||
| 678 | size += 2 + /* extension[s] */ | 696 | size += 2 + /* extension[s] */ |
| 679 | (extension == NULL ? 0 : strlen(extension)); | 697 | (extension == NULL ? 0 : strlen(extension)); |
| 680 | } | 698 | } |
| 681 | 699 | ||
| 682 | fc = v9fs_create_common(bufp, size, TCREATE); | 700 | fc = p9_create_common(bufp, size, P9_TCREATE); |
| 683 | if (IS_ERR(fc)) | 701 | if (IS_ERR(fc)) |
| 684 | goto error; | 702 | goto error; |
| 685 | 703 | ||
| 686 | v9fs_put_int32(bufp, fid, &fc->params.tcreate.fid); | 704 | p9_put_int32(bufp, fid, &fc->params.tcreate.fid); |
| 687 | v9fs_put_str(bufp, name, &fc->params.tcreate.name); | 705 | p9_put_str(bufp, name, &fc->params.tcreate.name); |
| 688 | v9fs_put_int32(bufp, perm, &fc->params.tcreate.perm); | 706 | p9_put_int32(bufp, perm, &fc->params.tcreate.perm); |
| 689 | v9fs_put_int8(bufp, mode, &fc->params.tcreate.mode); | 707 | p9_put_int8(bufp, mode, &fc->params.tcreate.mode); |
| 690 | if (extended) | 708 | if (dotu) |
| 691 | v9fs_put_str(bufp, extension, &fc->params.tcreate.extension); | 709 | p9_put_str(bufp, extension, &fc->params.tcreate.extension); |
| 692 | 710 | ||
| 693 | if (buf_check_overflow(bufp)) { | 711 | if (buf_check_overflow(bufp)) { |
| 694 | kfree(fc); | 712 | kfree(fc); |
| 695 | fc = ERR_PTR(-ENOMEM); | 713 | fc = ERR_PTR(-ENOMEM); |
| 696 | } | 714 | } |
| 697 | error: | 715 | error: |
| 698 | return fc; | 716 | return fc; |
| 699 | } | 717 | } |
| 718 | EXPORT_SYMBOL(p9_create_tcreate); | ||
| 700 | 719 | ||
| 701 | struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count) | 720 | struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count) |
| 702 | { | 721 | { |
| 703 | int size; | 722 | int size; |
| 704 | struct v9fs_fcall *fc; | 723 | struct p9_fcall *fc; |
| 705 | struct cbuf buffer; | 724 | struct cbuf buffer; |
| 706 | struct cbuf *bufp = &buffer; | 725 | struct cbuf *bufp = &buffer; |
| 707 | 726 | ||
| 708 | size = 4 + 8 + 4; /* fid[4] offset[8] count[4] */ | 727 | size = 4 + 8 + 4; /* fid[4] offset[8] count[4] */ |
| 709 | fc = v9fs_create_common(bufp, size, TREAD); | 728 | fc = p9_create_common(bufp, size, P9_TREAD); |
| 729 | if (IS_ERR(fc)) | ||
| 730 | goto error; | ||
| 731 | |||
| 732 | p9_put_int32(bufp, fid, &fc->params.tread.fid); | ||
| 733 | p9_put_int64(bufp, offset, &fc->params.tread.offset); | ||
| 734 | p9_put_int32(bufp, count, &fc->params.tread.count); | ||
| 735 | |||
| 736 | if (buf_check_overflow(bufp)) { | ||
| 737 | kfree(fc); | ||
| 738 | fc = ERR_PTR(-ENOMEM); | ||
| 739 | } | ||
| 740 | error: | ||
| 741 | return fc; | ||
| 742 | } | ||
| 743 | EXPORT_SYMBOL(p9_create_tread); | ||
| 744 | |||
| 745 | struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count, | ||
| 746 | const char *data) | ||
| 747 | { | ||
| 748 | int size, err; | ||
| 749 | struct p9_fcall *fc; | ||
| 750 | struct cbuf buffer; | ||
| 751 | struct cbuf *bufp = &buffer; | ||
| 752 | |||
| 753 | /* fid[4] offset[8] count[4] data[count] */ | ||
| 754 | size = 4 + 8 + 4 + count; | ||
| 755 | fc = p9_create_common(bufp, size, P9_TWRITE); | ||
| 710 | if (IS_ERR(fc)) | 756 | if (IS_ERR(fc)) |
| 711 | goto error; | 757 | goto error; |
| 712 | 758 | ||
| 713 | v9fs_put_int32(bufp, fid, &fc->params.tread.fid); | 759 | p9_put_int32(bufp, fid, &fc->params.twrite.fid); |
| 714 | v9fs_put_int64(bufp, offset, &fc->params.tread.offset); | 760 | p9_put_int64(bufp, offset, &fc->params.twrite.offset); |
| 715 | v9fs_put_int32(bufp, count, &fc->params.tread.count); | 761 | p9_put_int32(bufp, count, &fc->params.twrite.count); |
| 762 | err = p9_put_data(bufp, data, count, &fc->params.twrite.data); | ||
| 763 | if (err) { | ||
| 764 | kfree(fc); | ||
| 765 | fc = ERR_PTR(err); | ||
| 766 | } | ||
| 716 | 767 | ||
| 717 | if (buf_check_overflow(bufp)) { | 768 | if (buf_check_overflow(bufp)) { |
| 718 | kfree(fc); | 769 | kfree(fc); |
| 719 | fc = ERR_PTR(-ENOMEM); | 770 | fc = ERR_PTR(-ENOMEM); |
| 720 | } | 771 | } |
| 721 | error: | 772 | error: |
| 722 | return fc; | 773 | return fc; |
| 723 | } | 774 | } |
| 775 | EXPORT_SYMBOL(p9_create_twrite); | ||
| 724 | 776 | ||
| 725 | struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count, | 777 | struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count, |
| 726 | const char __user * data) | 778 | const char __user *data) |
| 727 | { | 779 | { |
| 728 | int size, err; | 780 | int size, err; |
| 729 | struct v9fs_fcall *fc; | 781 | struct p9_fcall *fc; |
| 730 | struct cbuf buffer; | 782 | struct cbuf buffer; |
| 731 | struct cbuf *bufp = &buffer; | 783 | struct cbuf *bufp = &buffer; |
| 732 | 784 | ||
| 733 | size = 4 + 8 + 4 + count; /* fid[4] offset[8] count[4] data[count] */ | 785 | /* fid[4] offset[8] count[4] data[count] */ |
| 734 | fc = v9fs_create_common(bufp, size, TWRITE); | 786 | size = 4 + 8 + 4 + count; |
| 787 | fc = p9_create_common(bufp, size, P9_TWRITE); | ||
| 735 | if (IS_ERR(fc)) | 788 | if (IS_ERR(fc)) |
| 736 | goto error; | 789 | goto error; |
| 737 | 790 | ||
| 738 | v9fs_put_int32(bufp, fid, &fc->params.twrite.fid); | 791 | p9_put_int32(bufp, fid, &fc->params.twrite.fid); |
| 739 | v9fs_put_int64(bufp, offset, &fc->params.twrite.offset); | 792 | p9_put_int64(bufp, offset, &fc->params.twrite.offset); |
| 740 | v9fs_put_int32(bufp, count, &fc->params.twrite.count); | 793 | p9_put_int32(bufp, count, &fc->params.twrite.count); |
| 741 | err = v9fs_put_user_data(bufp, data, count, &fc->params.twrite.data); | 794 | err = p9_put_user_data(bufp, data, count, &fc->params.twrite.data); |
| 742 | if (err) { | 795 | if (err) { |
| 743 | kfree(fc); | 796 | kfree(fc); |
| 744 | fc = ERR_PTR(err); | 797 | fc = ERR_PTR(err); |
| @@ -748,98 +801,103 @@ struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count, | |||
| 748 | kfree(fc); | 801 | kfree(fc); |
| 749 | fc = ERR_PTR(-ENOMEM); | 802 | fc = ERR_PTR(-ENOMEM); |
| 750 | } | 803 | } |
| 751 | error: | 804 | error: |
| 752 | return fc; | 805 | return fc; |
| 753 | } | 806 | } |
| 807 | EXPORT_SYMBOL(p9_create_twrite_u); | ||
| 754 | 808 | ||
| 755 | struct v9fs_fcall *v9fs_create_tclunk(u32 fid) | 809 | struct p9_fcall *p9_create_tclunk(u32 fid) |
| 756 | { | 810 | { |
| 757 | int size; | 811 | int size; |
| 758 | struct v9fs_fcall *fc; | 812 | struct p9_fcall *fc; |
| 759 | struct cbuf buffer; | 813 | struct cbuf buffer; |
| 760 | struct cbuf *bufp = &buffer; | 814 | struct cbuf *bufp = &buffer; |
| 761 | 815 | ||
| 762 | size = 4; /* fid[4] */ | 816 | size = 4; /* fid[4] */ |
| 763 | fc = v9fs_create_common(bufp, size, TCLUNK); | 817 | fc = p9_create_common(bufp, size, P9_TCLUNK); |
| 764 | if (IS_ERR(fc)) | 818 | if (IS_ERR(fc)) |
| 765 | goto error; | 819 | goto error; |
| 766 | 820 | ||
| 767 | v9fs_put_int32(bufp, fid, &fc->params.tclunk.fid); | 821 | p9_put_int32(bufp, fid, &fc->params.tclunk.fid); |
| 768 | 822 | ||
| 769 | if (buf_check_overflow(bufp)) { | 823 | if (buf_check_overflow(bufp)) { |
| 770 | kfree(fc); | 824 | kfree(fc); |
| 771 | fc = ERR_PTR(-ENOMEM); | 825 | fc = ERR_PTR(-ENOMEM); |
| 772 | } | 826 | } |
| 773 | error: | 827 | error: |
| 774 | return fc; | 828 | return fc; |
| 775 | } | 829 | } |
| 830 | EXPORT_SYMBOL(p9_create_tclunk); | ||
| 776 | 831 | ||
| 777 | struct v9fs_fcall *v9fs_create_tremove(u32 fid) | 832 | struct p9_fcall *p9_create_tremove(u32 fid) |
| 778 | { | 833 | { |
| 779 | int size; | 834 | int size; |
| 780 | struct v9fs_fcall *fc; | 835 | struct p9_fcall *fc; |
| 781 | struct cbuf buffer; | 836 | struct cbuf buffer; |
| 782 | struct cbuf *bufp = &buffer; | 837 | struct cbuf *bufp = &buffer; |
| 783 | 838 | ||
| 784 | size = 4; /* fid[4] */ | 839 | size = 4; /* fid[4] */ |
| 785 | fc = v9fs_create_common(bufp, size, TREMOVE); | 840 | fc = p9_create_common(bufp, size, P9_TREMOVE); |
| 786 | if (IS_ERR(fc)) | 841 | if (IS_ERR(fc)) |
| 787 | goto error; | 842 | goto error; |
| 788 | 843 | ||
| 789 | v9fs_put_int32(bufp, fid, &fc->params.tremove.fid); | 844 | p9_put_int32(bufp, fid, &fc->params.tremove.fid); |
| 790 | 845 | ||
| 791 | if (buf_check_overflow(bufp)) { | 846 | if (buf_check_overflow(bufp)) { |
| 792 | kfree(fc); | 847 | kfree(fc); |
| 793 | fc = ERR_PTR(-ENOMEM); | 848 | fc = ERR_PTR(-ENOMEM); |
| 794 | } | 849 | } |
| 795 | error: | 850 | error: |
| 796 | return fc; | 851 | return fc; |
| 797 | } | 852 | } |
| 853 | EXPORT_SYMBOL(p9_create_tremove); | ||
| 798 | 854 | ||
| 799 | struct v9fs_fcall *v9fs_create_tstat(u32 fid) | 855 | struct p9_fcall *p9_create_tstat(u32 fid) |
| 800 | { | 856 | { |
| 801 | int size; | 857 | int size; |
| 802 | struct v9fs_fcall *fc; | 858 | struct p9_fcall *fc; |
| 803 | struct cbuf buffer; | 859 | struct cbuf buffer; |
| 804 | struct cbuf *bufp = &buffer; | 860 | struct cbuf *bufp = &buffer; |
| 805 | 861 | ||
| 806 | size = 4; /* fid[4] */ | 862 | size = 4; /* fid[4] */ |
| 807 | fc = v9fs_create_common(bufp, size, TSTAT); | 863 | fc = p9_create_common(bufp, size, P9_TSTAT); |
| 808 | if (IS_ERR(fc)) | 864 | if (IS_ERR(fc)) |
| 809 | goto error; | 865 | goto error; |
| 810 | 866 | ||
| 811 | v9fs_put_int32(bufp, fid, &fc->params.tstat.fid); | 867 | p9_put_int32(bufp, fid, &fc->params.tstat.fid); |
| 812 | 868 | ||
| 813 | if (buf_check_overflow(bufp)) { | 869 | if (buf_check_overflow(bufp)) { |
| 814 | kfree(fc); | 870 | kfree(fc); |
| 815 | fc = ERR_PTR(-ENOMEM); | 871 | fc = ERR_PTR(-ENOMEM); |
| 816 | } | 872 | } |
| 817 | error: | 873 | error: |
| 818 | return fc; | 874 | return fc; |
| 819 | } | 875 | } |
| 876 | EXPORT_SYMBOL(p9_create_tstat); | ||
| 820 | 877 | ||
| 821 | struct v9fs_fcall *v9fs_create_twstat(u32 fid, struct v9fs_wstat *wstat, | 878 | struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat, |
| 822 | int extended) | 879 | int dotu) |
| 823 | { | 880 | { |
| 824 | int size, statsz; | 881 | int size, statsz; |
| 825 | struct v9fs_fcall *fc; | 882 | struct p9_fcall *fc; |
| 826 | struct cbuf buffer; | 883 | struct cbuf buffer; |
| 827 | struct cbuf *bufp = &buffer; | 884 | struct cbuf *bufp = &buffer; |
| 828 | 885 | ||
| 829 | statsz = v9fs_size_wstat(wstat, extended); | 886 | statsz = p9_size_wstat(wstat, dotu); |
| 830 | size = 4 + 2 + 2 + statsz; /* fid[4] stat[n] */ | 887 | size = 4 + 2 + 2 + statsz; /* fid[4] stat[n] */ |
| 831 | fc = v9fs_create_common(bufp, size, TWSTAT); | 888 | fc = p9_create_common(bufp, size, P9_TWSTAT); |
| 832 | if (IS_ERR(fc)) | 889 | if (IS_ERR(fc)) |
| 833 | goto error; | 890 | goto error; |
| 834 | 891 | ||
| 835 | v9fs_put_int32(bufp, fid, &fc->params.twstat.fid); | 892 | p9_put_int32(bufp, fid, &fc->params.twstat.fid); |
| 836 | buf_put_int16(bufp, statsz + 2); | 893 | buf_put_int16(bufp, statsz + 2); |
| 837 | v9fs_put_wstat(bufp, wstat, &fc->params.twstat.stat, statsz, extended); | 894 | p9_put_wstat(bufp, wstat, &fc->params.twstat.stat, statsz, dotu); |
| 838 | 895 | ||
| 839 | if (buf_check_overflow(bufp)) { | 896 | if (buf_check_overflow(bufp)) { |
| 840 | kfree(fc); | 897 | kfree(fc); |
| 841 | fc = ERR_PTR(-ENOMEM); | 898 | fc = ERR_PTR(-ENOMEM); |
| 842 | } | 899 | } |
| 843 | error: | 900 | error: |
| 844 | return fc; | 901 | return fc; |
| 845 | } | 902 | } |
| 903 | EXPORT_SYMBOL(p9_create_twstat); | ||
diff --git a/fs/9p/error.h b/net/9p/error.c index 5f3ca522b316..ab2458b6c903 100644 --- a/fs/9p/error.h +++ b/net/9p/error.c | |||
| @@ -1,12 +1,11 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/fs/9p/error.h | 2 | * linux/fs/9p/error.c |
| 3 | * | 3 | * |
| 4 | * Huge Nasty Error Table | 4 | * Error string handling |
| 5 | * | 5 | * |
| 6 | * Plan 9 uses error strings, Unix uses error numbers. This table tries to | 6 | * Plan 9 uses error strings, Unix uses error numbers. These functions |
| 7 | * match UNIX strings and Plan 9 strings to unix error numbers. It is used | 7 | * try to help manage that and provide for dynamically adding error |
| 8 | * to preload the dynamic error table which can also track user-specific error | 8 | * mappings. |
| 9 | * strings. | ||
| 10 | * | 9 | * |
| 11 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | 10 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> |
| 12 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | 11 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> |
| @@ -28,8 +27,11 @@ | |||
| 28 | * | 27 | * |
| 29 | */ | 28 | */ |
| 30 | 29 | ||
| 30 | #include <linux/module.h> | ||
| 31 | #include <linux/list.h> | ||
| 32 | #include <linux/jhash.h> | ||
| 31 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
| 32 | #include <asm/errno.h> | 34 | #include <net/9p/9p.h> |
| 33 | 35 | ||
| 34 | struct errormap { | 36 | struct errormap { |
| 35 | char *name; | 37 | char *name; |
| @@ -174,4 +176,65 @@ static struct errormap errmap[] = { | |||
| 174 | {NULL, -1} | 176 | {NULL, -1} |
| 175 | }; | 177 | }; |
| 176 | 178 | ||
| 177 | extern int v9fs_error_init(void); | 179 | /** |
| 180 | * p9_error_init - preload | ||
| 181 | * @errstr: error string | ||
| 182 | * | ||
| 183 | */ | ||
| 184 | |||
| 185 | int p9_error_init(void) | ||
| 186 | { | ||
| 187 | struct errormap *c; | ||
| 188 | int bucket; | ||
| 189 | |||
| 190 | /* initialize hash table */ | ||
| 191 | for (bucket = 0; bucket < ERRHASHSZ; bucket++) | ||
| 192 | INIT_HLIST_HEAD(&hash_errmap[bucket]); | ||
| 193 | |||
| 194 | /* load initial error map into hash table */ | ||
| 195 | for (c = errmap; c->name != NULL; c++) { | ||
| 196 | c->namelen = strlen(c->name); | ||
| 197 | bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ; | ||
| 198 | INIT_HLIST_NODE(&c->list); | ||
| 199 | hlist_add_head(&c->list, &hash_errmap[bucket]); | ||
| 200 | } | ||
| 201 | |||
| 202 | return 1; | ||
| 203 | } | ||
| 204 | EXPORT_SYMBOL(p9_error_init); | ||
| 205 | |||
| 206 | /** | ||
| 207 | * errstr2errno - convert error string to error number | ||
| 208 | * @errstr: error string | ||
| 209 | * | ||
| 210 | */ | ||
| 211 | |||
| 212 | int p9_errstr2errno(char *errstr, int len) | ||
| 213 | { | ||
| 214 | int errno; | ||
| 215 | struct hlist_node *p; | ||
| 216 | struct errormap *c; | ||
| 217 | int bucket; | ||
| 218 | |||
| 219 | errno = 0; | ||
| 220 | p = NULL; | ||
| 221 | c = NULL; | ||
| 222 | bucket = jhash(errstr, len, 0) % ERRHASHSZ; | ||
| 223 | hlist_for_each_entry(c, p, &hash_errmap[bucket], list) { | ||
| 224 | if (c->namelen == len && !memcmp(c->name, errstr, len)) { | ||
| 225 | errno = c->val; | ||
| 226 | break; | ||
| 227 | } | ||
| 228 | } | ||
| 229 | |||
| 230 | if (errno == 0) { | ||
| 231 | /* TODO: if error isn't found, add it dynamically */ | ||
| 232 | errstr[len] = 0; | ||
| 233 | printk(KERN_ERR "%s: errstr :%s: not found\n", __FUNCTION__, | ||
| 234 | errstr); | ||
| 235 | errno = 1; | ||
| 236 | } | ||
| 237 | |||
| 238 | return -errno; | ||
| 239 | } | ||
| 240 | EXPORT_SYMBOL(p9_errstr2errno); | ||
diff --git a/fs/9p/fcprint.c b/net/9p/fcprint.c index 34b96114a28d..b1ae8ec57d54 100644 --- a/fs/9p/fcprint.c +++ b/net/9p/fcprint.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/fs/9p/fcprint.c | 2 | * net/9p/fcprint.c |
| 3 | * | 3 | * |
| 4 | * Print 9P call. | 4 | * Print 9P call. |
| 5 | * | 5 | * |
| @@ -25,61 +25,59 @@ | |||
| 25 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
| 26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
| 27 | #include <linux/idr.h> | 27 | #include <linux/idr.h> |
| 28 | #include <net/9p/9p.h> | ||
| 28 | 29 | ||
| 29 | #include "debug.h" | 30 | #ifdef CONFIG_NET_9P_DEBUG |
| 30 | #include "v9fs.h" | ||
| 31 | #include "9p.h" | ||
| 32 | #include "mux.h" | ||
| 33 | 31 | ||
| 34 | static int | 32 | static int |
| 35 | v9fs_printqid(char *buf, int buflen, struct v9fs_qid *q) | 33 | p9_printqid(char *buf, int buflen, struct p9_qid *q) |
| 36 | { | 34 | { |
| 37 | int n; | 35 | int n; |
| 38 | char b[10]; | 36 | char b[10]; |
| 39 | 37 | ||
| 40 | n = 0; | 38 | n = 0; |
| 41 | if (q->type & V9FS_QTDIR) | 39 | if (q->type & P9_QTDIR) |
| 42 | b[n++] = 'd'; | 40 | b[n++] = 'd'; |
| 43 | if (q->type & V9FS_QTAPPEND) | 41 | if (q->type & P9_QTAPPEND) |
| 44 | b[n++] = 'a'; | 42 | b[n++] = 'a'; |
| 45 | if (q->type & V9FS_QTAUTH) | 43 | if (q->type & P9_QTAUTH) |
| 46 | b[n++] = 'A'; | 44 | b[n++] = 'A'; |
| 47 | if (q->type & V9FS_QTEXCL) | 45 | if (q->type & P9_QTEXCL) |
| 48 | b[n++] = 'l'; | 46 | b[n++] = 'l'; |
| 49 | if (q->type & V9FS_QTTMP) | 47 | if (q->type & P9_QTTMP) |
| 50 | b[n++] = 't'; | 48 | b[n++] = 't'; |
| 51 | if (q->type & V9FS_QTSYMLINK) | 49 | if (q->type & P9_QTSYMLINK) |
| 52 | b[n++] = 'L'; | 50 | b[n++] = 'L'; |
| 53 | b[n] = '\0'; | 51 | b[n] = '\0'; |
| 54 | 52 | ||
| 55 | return scnprintf(buf, buflen, "(%.16llx %x %s)", (long long int) q->path, | 53 | return scnprintf(buf, buflen, "(%.16llx %x %s)", |
| 56 | q->version, b); | 54 | (long long int) q->path, q->version, b); |
| 57 | } | 55 | } |
| 58 | 56 | ||
| 59 | static int | 57 | static int |
| 60 | v9fs_printperm(char *buf, int buflen, int perm) | 58 | p9_printperm(char *buf, int buflen, int perm) |
| 61 | { | 59 | { |
| 62 | int n; | 60 | int n; |
| 63 | char b[15]; | 61 | char b[15]; |
| 64 | 62 | ||
| 65 | n = 0; | 63 | n = 0; |
| 66 | if (perm & V9FS_DMDIR) | 64 | if (perm & P9_DMDIR) |
| 67 | b[n++] = 'd'; | 65 | b[n++] = 'd'; |
| 68 | if (perm & V9FS_DMAPPEND) | 66 | if (perm & P9_DMAPPEND) |
| 69 | b[n++] = 'a'; | 67 | b[n++] = 'a'; |
| 70 | if (perm & V9FS_DMAUTH) | 68 | if (perm & P9_DMAUTH) |
| 71 | b[n++] = 'A'; | 69 | b[n++] = 'A'; |
| 72 | if (perm & V9FS_DMEXCL) | 70 | if (perm & P9_DMEXCL) |
| 73 | b[n++] = 'l'; | 71 | b[n++] = 'l'; |
| 74 | if (perm & V9FS_DMTMP) | 72 | if (perm & P9_DMTMP) |
| 75 | b[n++] = 't'; | 73 | b[n++] = 't'; |
| 76 | if (perm & V9FS_DMDEVICE) | 74 | if (perm & P9_DMDEVICE) |
| 77 | b[n++] = 'D'; | 75 | b[n++] = 'D'; |
| 78 | if (perm & V9FS_DMSOCKET) | 76 | if (perm & P9_DMSOCKET) |
| 79 | b[n++] = 'S'; | 77 | b[n++] = 'S'; |
| 80 | if (perm & V9FS_DMNAMEDPIPE) | 78 | if (perm & P9_DMNAMEDPIPE) |
| 81 | b[n++] = 'P'; | 79 | b[n++] = 'P'; |
| 82 | if (perm & V9FS_DMSYMLINK) | 80 | if (perm & P9_DMSYMLINK) |
| 83 | b[n++] = 'L'; | 81 | b[n++] = 'L'; |
| 84 | b[n] = '\0'; | 82 | b[n] = '\0'; |
| 85 | 83 | ||
| @@ -87,7 +85,7 @@ v9fs_printperm(char *buf, int buflen, int perm) | |||
| 87 | } | 85 | } |
| 88 | 86 | ||
| 89 | static int | 87 | static int |
| 90 | v9fs_printstat(char *buf, int buflen, struct v9fs_stat *st, int extended) | 88 | p9_printstat(char *buf, int buflen, struct p9_stat *st, int extended) |
| 91 | { | 89 | { |
| 92 | int n; | 90 | int n; |
| 93 | 91 | ||
| @@ -105,9 +103,9 @@ v9fs_printstat(char *buf, int buflen, struct v9fs_stat *st, int extended) | |||
| 105 | n += scnprintf(buf+n, buflen-n, "(%d)", st->n_muid); | 103 | n += scnprintf(buf+n, buflen-n, "(%d)", st->n_muid); |
| 106 | 104 | ||
| 107 | n += scnprintf(buf+n, buflen-n, " q "); | 105 | n += scnprintf(buf+n, buflen-n, " q "); |
| 108 | n += v9fs_printqid(buf+n, buflen-n, &st->qid); | 106 | n += p9_printqid(buf+n, buflen-n, &st->qid); |
| 109 | n += scnprintf(buf+n, buflen-n, " m "); | 107 | n += scnprintf(buf+n, buflen-n, " m "); |
| 110 | n += v9fs_printperm(buf+n, buflen-n, st->mode); | 108 | n += p9_printperm(buf+n, buflen-n, st->mode); |
| 111 | n += scnprintf(buf+n, buflen-n, " at %d mt %d l %lld", | 109 | n += scnprintf(buf+n, buflen-n, " at %d mt %d l %lld", |
| 112 | st->atime, st->mtime, (long long int) st->length); | 110 | st->atime, st->mtime, (long long int) st->length); |
| 113 | 111 | ||
| @@ -119,7 +117,7 @@ v9fs_printstat(char *buf, int buflen, struct v9fs_stat *st, int extended) | |||
| 119 | } | 117 | } |
| 120 | 118 | ||
| 121 | static int | 119 | static int |
| 122 | v9fs_dumpdata(char *buf, int buflen, u8 *data, int datalen) | 120 | p9_dumpdata(char *buf, int buflen, u8 *data, int datalen) |
| 123 | { | 121 | { |
| 124 | int i, n; | 122 | int i, n; |
| 125 | 123 | ||
| @@ -139,13 +137,13 @@ v9fs_dumpdata(char *buf, int buflen, u8 *data, int datalen) | |||
| 139 | } | 137 | } |
| 140 | 138 | ||
| 141 | static int | 139 | static int |
| 142 | v9fs_printdata(char *buf, int buflen, u8 *data, int datalen) | 140 | p9_printdata(char *buf, int buflen, u8 *data, int datalen) |
| 143 | { | 141 | { |
| 144 | return v9fs_dumpdata(buf, buflen, data, datalen<16?datalen:16); | 142 | return p9_dumpdata(buf, buflen, data, datalen < 16?datalen:16); |
| 145 | } | 143 | } |
| 146 | 144 | ||
| 147 | int | 145 | int |
| 148 | v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended) | 146 | p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended) |
| 149 | { | 147 | { |
| 150 | int i, ret, type, tag; | 148 | int i, ret, type, tag; |
| 151 | 149 | ||
| @@ -157,21 +155,23 @@ v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended) | |||
| 157 | 155 | ||
| 158 | ret = 0; | 156 | ret = 0; |
| 159 | switch (type) { | 157 | switch (type) { |
| 160 | case TVERSION: | 158 | case P9_TVERSION: |
| 161 | ret += scnprintf(buf+ret, buflen-ret, | 159 | ret += scnprintf(buf+ret, buflen-ret, |
| 162 | "Tversion tag %u msize %u version '%.*s'", tag, | 160 | "Tversion tag %u msize %u version '%.*s'", tag, |
| 163 | fc->params.tversion.msize, fc->params.tversion.version.len, | 161 | fc->params.tversion.msize, |
| 164 | fc->params.tversion.version.str); | 162 | fc->params.tversion.version.len, |
| 163 | fc->params.tversion.version.str); | ||
| 165 | break; | 164 | break; |
| 166 | 165 | ||
| 167 | case RVERSION: | 166 | case P9_RVERSION: |
| 168 | ret += scnprintf(buf+ret, buflen-ret, | 167 | ret += scnprintf(buf+ret, buflen-ret, |
| 169 | "Rversion tag %u msize %u version '%.*s'", tag, | 168 | "Rversion tag %u msize %u version '%.*s'", tag, |
| 170 | fc->params.rversion.msize, fc->params.rversion.version.len, | 169 | fc->params.rversion.msize, |
| 171 | fc->params.rversion.version.str); | 170 | fc->params.rversion.version.len, |
| 171 | fc->params.rversion.version.str); | ||
| 172 | break; | 172 | break; |
| 173 | 173 | ||
| 174 | case TAUTH: | 174 | case P9_TAUTH: |
| 175 | ret += scnprintf(buf+ret, buflen-ret, | 175 | ret += scnprintf(buf+ret, buflen-ret, |
| 176 | "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag, | 176 | "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag, |
| 177 | fc->params.tauth.afid, fc->params.tauth.uname.len, | 177 | fc->params.tauth.afid, fc->params.tauth.uname.len, |
| @@ -179,93 +179,97 @@ v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended) | |||
| 179 | fc->params.tauth.aname.str); | 179 | fc->params.tauth.aname.str); |
| 180 | break; | 180 | break; |
| 181 | 181 | ||
| 182 | case RAUTH: | 182 | case P9_RAUTH: |
| 183 | ret += scnprintf(buf+ret, buflen-ret, "Rauth tag %u qid ", tag); | 183 | ret += scnprintf(buf+ret, buflen-ret, "Rauth tag %u qid ", tag); |
| 184 | v9fs_printqid(buf+ret, buflen-ret, &fc->params.rauth.qid); | 184 | p9_printqid(buf+ret, buflen-ret, &fc->params.rauth.qid); |
| 185 | break; | 185 | break; |
| 186 | 186 | ||
| 187 | case TATTACH: | 187 | case P9_TATTACH: |
| 188 | ret += scnprintf(buf+ret, buflen-ret, | 188 | ret += scnprintf(buf+ret, buflen-ret, |
| 189 | "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'", | 189 | "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'", tag, |
| 190 | tag, fc->params.tattach.fid, fc->params.tattach.afid, | 190 | fc->params.tattach.fid, fc->params.tattach.afid, |
| 191 | fc->params.tattach.uname.len, fc->params.tattach.uname.str, | 191 | fc->params.tattach.uname.len, fc->params.tattach.uname.str, |
| 192 | fc->params.tattach.aname.len, fc->params.tattach.aname.str); | 192 | fc->params.tattach.aname.len, fc->params.tattach.aname.str); |
| 193 | break; | 193 | break; |
| 194 | 194 | ||
| 195 | case RATTACH: | 195 | case P9_RATTACH: |
| 196 | ret += scnprintf(buf+ret, buflen-ret, "Rattach tag %u qid ", tag); | 196 | ret += scnprintf(buf+ret, buflen-ret, "Rattach tag %u qid ", |
| 197 | v9fs_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid); | 197 | tag); |
| 198 | p9_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid); | ||
| 198 | break; | 199 | break; |
| 199 | 200 | ||
| 200 | case RERROR: | 201 | case P9_RERROR: |
| 201 | ret += scnprintf(buf+ret, buflen-ret, "Rerror tag %u ename '%.*s'", | 202 | ret += scnprintf(buf+ret, buflen-ret, |
| 202 | tag, fc->params.rerror.error.len, | 203 | "Rerror tag %u ename '%.*s'", tag, |
| 203 | fc->params.rerror.error.str); | 204 | fc->params.rerror.error.len, |
| 205 | fc->params.rerror.error.str); | ||
| 204 | if (extended) | 206 | if (extended) |
| 205 | ret += scnprintf(buf+ret, buflen-ret, " ecode %d\n", | 207 | ret += scnprintf(buf+ret, buflen-ret, " ecode %d\n", |
| 206 | fc->params.rerror.errno); | 208 | fc->params.rerror.errno); |
| 207 | break; | 209 | break; |
| 208 | 210 | ||
| 209 | case TFLUSH: | 211 | case P9_TFLUSH: |
| 210 | ret += scnprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u", | 212 | ret += scnprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u", |
| 211 | tag, fc->params.tflush.oldtag); | 213 | tag, fc->params.tflush.oldtag); |
| 212 | break; | 214 | break; |
| 213 | 215 | ||
| 214 | case RFLUSH: | 216 | case P9_RFLUSH: |
| 215 | ret += scnprintf(buf+ret, buflen-ret, "Rflush tag %u", tag); | 217 | ret += scnprintf(buf+ret, buflen-ret, "Rflush tag %u", tag); |
| 216 | break; | 218 | break; |
| 217 | 219 | ||
| 218 | case TWALK: | 220 | case P9_TWALK: |
| 219 | ret += scnprintf(buf+ret, buflen-ret, | 221 | ret += scnprintf(buf+ret, buflen-ret, |
| 220 | "Twalk tag %u fid %d newfid %d nwname %d", tag, | 222 | "Twalk tag %u fid %d newfid %d nwname %d", tag, |
| 221 | fc->params.twalk.fid, fc->params.twalk.newfid, | 223 | fc->params.twalk.fid, fc->params.twalk.newfid, |
| 222 | fc->params.twalk.nwname); | 224 | fc->params.twalk.nwname); |
| 223 | for(i = 0; i < fc->params.twalk.nwname; i++) | 225 | for (i = 0; i < fc->params.twalk.nwname; i++) |
| 224 | ret += scnprintf(buf+ret, buflen-ret," '%.*s'", | 226 | ret += scnprintf(buf+ret, buflen-ret, " '%.*s'", |
| 225 | fc->params.twalk.wnames[i].len, | 227 | fc->params.twalk.wnames[i].len, |
| 226 | fc->params.twalk.wnames[i].str); | 228 | fc->params.twalk.wnames[i].str); |
| 227 | break; | 229 | break; |
| 228 | 230 | ||
| 229 | case RWALK: | 231 | case P9_RWALK: |
| 230 | ret += scnprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d", | 232 | ret += scnprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d", |
| 231 | tag, fc->params.rwalk.nwqid); | 233 | tag, fc->params.rwalk.nwqid); |
| 232 | for(i = 0; i < fc->params.rwalk.nwqid; i++) | 234 | for (i = 0; i < fc->params.rwalk.nwqid; i++) |
| 233 | ret += v9fs_printqid(buf+ret, buflen-ret, | 235 | ret += p9_printqid(buf+ret, buflen-ret, |
| 234 | &fc->params.rwalk.wqids[i]); | 236 | &fc->params.rwalk.wqids[i]); |
| 235 | break; | 237 | break; |
| 236 | 238 | ||
| 237 | case TOPEN: | 239 | case P9_TOPEN: |
| 238 | ret += scnprintf(buf+ret, buflen-ret, | 240 | ret += scnprintf(buf+ret, buflen-ret, |
| 239 | "Topen tag %u fid %d mode %d", tag, | 241 | "Topen tag %u fid %d mode %d", tag, |
| 240 | fc->params.topen.fid, fc->params.topen.mode); | 242 | fc->params.topen.fid, fc->params.topen.mode); |
| 241 | break; | 243 | break; |
| 242 | 244 | ||
| 243 | case ROPEN: | 245 | case P9_ROPEN: |
| 244 | ret += scnprintf(buf+ret, buflen-ret, "Ropen tag %u", tag); | 246 | ret += scnprintf(buf+ret, buflen-ret, "Ropen tag %u", tag); |
| 245 | ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid); | 247 | ret += p9_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid); |
| 246 | ret += scnprintf(buf+ret, buflen-ret," iounit %d", | 248 | ret += scnprintf(buf+ret, buflen-ret, " iounit %d", |
| 247 | fc->params.ropen.iounit); | 249 | fc->params.ropen.iounit); |
| 248 | break; | 250 | break; |
| 249 | 251 | ||
| 250 | case TCREATE: | 252 | case P9_TCREATE: |
| 251 | ret += scnprintf(buf+ret, buflen-ret, | 253 | ret += scnprintf(buf+ret, buflen-ret, |
| 252 | "Tcreate tag %u fid %d name '%.*s' perm ", tag, | 254 | "Tcreate tag %u fid %d name '%.*s' perm ", tag, |
| 253 | fc->params.tcreate.fid, fc->params.tcreate.name.len, | 255 | fc->params.tcreate.fid, fc->params.tcreate.name.len, |
| 254 | fc->params.tcreate.name.str); | 256 | fc->params.tcreate.name.str); |
| 255 | 257 | ||
| 256 | ret += v9fs_printperm(buf+ret, buflen-ret, fc->params.tcreate.perm); | 258 | ret += p9_printperm(buf+ret, buflen-ret, |
| 259 | fc->params.tcreate.perm); | ||
| 257 | ret += scnprintf(buf+ret, buflen-ret, " mode %d", | 260 | ret += scnprintf(buf+ret, buflen-ret, " mode %d", |
| 258 | fc->params.tcreate.mode); | 261 | fc->params.tcreate.mode); |
| 259 | break; | 262 | break; |
| 260 | 263 | ||
| 261 | case RCREATE: | 264 | case P9_RCREATE: |
| 262 | ret += scnprintf(buf+ret, buflen-ret, "Rcreate tag %u", tag); | 265 | ret += scnprintf(buf+ret, buflen-ret, "Rcreate tag %u", tag); |
| 263 | ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.rcreate.qid); | 266 | ret += p9_printqid(buf+ret, buflen-ret, |
| 267 | &fc->params.rcreate.qid); | ||
| 264 | ret += scnprintf(buf+ret, buflen-ret, " iounit %d", | 268 | ret += scnprintf(buf+ret, buflen-ret, " iounit %d", |
| 265 | fc->params.rcreate.iounit); | 269 | fc->params.rcreate.iounit); |
| 266 | break; | 270 | break; |
| 267 | 271 | ||
| 268 | case TREAD: | 272 | case P9_TREAD: |
| 269 | ret += scnprintf(buf+ret, buflen-ret, | 273 | ret += scnprintf(buf+ret, buflen-ret, |
| 270 | "Tread tag %u fid %d offset %lld count %u", tag, | 274 | "Tread tag %u fid %d offset %lld count %u", tag, |
| 271 | fc->params.tread.fid, | 275 | fc->params.tread.fid, |
| @@ -273,66 +277,66 @@ v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended) | |||
| 273 | fc->params.tread.count); | 277 | fc->params.tread.count); |
| 274 | break; | 278 | break; |
| 275 | 279 | ||
| 276 | case RREAD: | 280 | case P9_RREAD: |
| 277 | ret += scnprintf(buf+ret, buflen-ret, | 281 | ret += scnprintf(buf+ret, buflen-ret, |
| 278 | "Rread tag %u count %u data ", tag, | 282 | "Rread tag %u count %u data ", tag, |
| 279 | fc->params.rread.count); | 283 | fc->params.rread.count); |
| 280 | ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.rread.data, | 284 | ret += p9_printdata(buf+ret, buflen-ret, fc->params.rread.data, |
| 281 | fc->params.rread.count); | 285 | fc->params.rread.count); |
| 282 | break; | 286 | break; |
| 283 | 287 | ||
| 284 | case TWRITE: | 288 | case P9_TWRITE: |
| 285 | ret += scnprintf(buf+ret, buflen-ret, | 289 | ret += scnprintf(buf+ret, buflen-ret, |
| 286 | "Twrite tag %u fid %d offset %lld count %u data ", | 290 | "Twrite tag %u fid %d offset %lld count %u data ", |
| 287 | tag, fc->params.twrite.fid, | 291 | tag, fc->params.twrite.fid, |
| 288 | (long long int) fc->params.twrite.offset, | 292 | (long long int) fc->params.twrite.offset, |
| 289 | fc->params.twrite.count); | 293 | fc->params.twrite.count); |
| 290 | ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.twrite.data, | 294 | ret += p9_printdata(buf+ret, buflen-ret, fc->params.twrite.data, |
| 291 | fc->params.twrite.count); | 295 | fc->params.twrite.count); |
| 292 | break; | 296 | break; |
| 293 | 297 | ||
| 294 | case RWRITE: | 298 | case P9_RWRITE: |
| 295 | ret += scnprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u", | 299 | ret += scnprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u", |
| 296 | tag, fc->params.rwrite.count); | 300 | tag, fc->params.rwrite.count); |
| 297 | break; | 301 | break; |
| 298 | 302 | ||
| 299 | case TCLUNK: | 303 | case P9_TCLUNK: |
| 300 | ret += scnprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d", | 304 | ret += scnprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d", |
| 301 | tag, fc->params.tclunk.fid); | 305 | tag, fc->params.tclunk.fid); |
| 302 | break; | 306 | break; |
| 303 | 307 | ||
| 304 | case RCLUNK: | 308 | case P9_RCLUNK: |
| 305 | ret += scnprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag); | 309 | ret += scnprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag); |
| 306 | break; | 310 | break; |
| 307 | 311 | ||
| 308 | case TREMOVE: | 312 | case P9_TREMOVE: |
| 309 | ret += scnprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d", | 313 | ret += scnprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d", |
| 310 | tag, fc->params.tremove.fid); | 314 | tag, fc->params.tremove.fid); |
| 311 | break; | 315 | break; |
| 312 | 316 | ||
| 313 | case RREMOVE: | 317 | case P9_RREMOVE: |
| 314 | ret += scnprintf(buf+ret, buflen-ret, "Rremove tag %u", tag); | 318 | ret += scnprintf(buf+ret, buflen-ret, "Rremove tag %u", tag); |
| 315 | break; | 319 | break; |
| 316 | 320 | ||
| 317 | case TSTAT: | 321 | case P9_TSTAT: |
| 318 | ret += scnprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d", | 322 | ret += scnprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d", |
| 319 | tag, fc->params.tstat.fid); | 323 | tag, fc->params.tstat.fid); |
| 320 | break; | 324 | break; |
| 321 | 325 | ||
| 322 | case RSTAT: | 326 | case P9_RSTAT: |
| 323 | ret += scnprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag); | 327 | ret += scnprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag); |
| 324 | ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat, | 328 | ret += p9_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat, |
| 325 | extended); | 329 | extended); |
| 326 | break; | 330 | break; |
| 327 | 331 | ||
| 328 | case TWSTAT: | 332 | case P9_TWSTAT: |
| 329 | ret += scnprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ", | 333 | ret += scnprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ", |
| 330 | tag, fc->params.twstat.fid); | 334 | tag, fc->params.twstat.fid); |
| 331 | ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.twstat.stat, | 335 | ret += p9_printstat(buf+ret, buflen-ret, |
| 332 | extended); | 336 | &fc->params.twstat.stat, extended); |
| 333 | break; | 337 | break; |
| 334 | 338 | ||
| 335 | case RWSTAT: | 339 | case P9_RWSTAT: |
| 336 | ret += scnprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag); | 340 | ret += scnprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag); |
| 337 | break; | 341 | break; |
| 338 | 342 | ||
| @@ -343,3 +347,12 @@ v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended) | |||
| 343 | 347 | ||
| 344 | return ret; | 348 | return ret; |
| 345 | } | 349 | } |
| 350 | |||
| 351 | #else | ||
| 352 | int | ||
| 353 | p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended) | ||
| 354 | { | ||
| 355 | return 0; | ||
| 356 | } | ||
| 357 | EXPORT_SYMBOL(p9_printfcall); | ||
| 358 | #endif /* CONFIG_NET_9P_DEBUG */ | ||
diff --git a/net/9p/mod.c b/net/9p/mod.c new file mode 100644 index 000000000000..4f9e1d2ac257 --- /dev/null +++ b/net/9p/mod.c | |||
| @@ -0,0 +1,85 @@ | |||
| 1 | /* | ||
| 2 | * net/9p/9p.c | ||
| 3 | * | ||
| 4 | * 9P entry point | ||
| 5 | * | ||
| 6 | * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> | ||
| 7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
| 8 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 | ||
| 12 | * as published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to: | ||
| 21 | * Free Software Foundation | ||
| 22 | * 51 Franklin Street, Fifth Floor | ||
| 23 | * Boston, MA 02111-1301 USA | ||
| 24 | * | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/moduleparam.h> | ||
| 29 | #include <net/9p/9p.h> | ||
| 30 | |||
| 31 | #ifdef CONFIG_NET_9P_DEBUG | ||
| 32 | unsigned int p9_debug_level = 0; /* feature-rific global debug level */ | ||
| 33 | EXPORT_SYMBOL(p9_debug_level); | ||
| 34 | module_param_named(debug, p9_debug_level, uint, 0); | ||
| 35 | MODULE_PARM_DESC(debug, "9P debugging level"); | ||
| 36 | #endif | ||
| 37 | |||
| 38 | extern int p9_mux_global_init(void); | ||
| 39 | extern void p9_mux_global_exit(void); | ||
| 40 | extern int p9_sysctl_register(void); | ||
| 41 | extern void p9_sysctl_unregister(void); | ||
| 42 | |||
| 43 | /** | ||
| 44 | * v9fs_init - Initialize module | ||
| 45 | * | ||
| 46 | */ | ||
| 47 | static int __init init_p9(void) | ||
| 48 | { | ||
| 49 | int ret; | ||
| 50 | |||
| 51 | p9_error_init(); | ||
| 52 | printk(KERN_INFO "Installing 9P2000 support\n"); | ||
| 53 | ret = p9_mux_global_init(); | ||
| 54 | if (ret) { | ||
| 55 | printk(KERN_WARNING "9p: starting mux failed\n"); | ||
| 56 | return ret; | ||
| 57 | } | ||
| 58 | |||
| 59 | ret = p9_sysctl_register(); | ||
| 60 | if (ret) { | ||
| 61 | printk(KERN_WARNING "9p: registering sysctl failed\n"); | ||
| 62 | return ret; | ||
| 63 | } | ||
| 64 | |||
| 65 | return ret; | ||
| 66 | } | ||
| 67 | |||
| 68 | /** | ||
| 69 | * v9fs_init - shutdown module | ||
| 70 | * | ||
| 71 | */ | ||
| 72 | |||
| 73 | static void __exit exit_p9(void) | ||
| 74 | { | ||
| 75 | p9_sysctl_unregister(); | ||
| 76 | p9_mux_global_exit(); | ||
| 77 | } | ||
| 78 | |||
| 79 | module_init(init_p9) | ||
| 80 | module_exit(exit_p9) | ||
| 81 | |||
| 82 | MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>"); | ||
| 83 | MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>"); | ||
| 84 | MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>"); | ||
| 85 | MODULE_LICENSE("GPL"); | ||
diff --git a/fs/9p/mux.c b/net/9p/mux.c index c783874a9caf..c3aa87bc8b97 100644 --- a/fs/9p/mux.c +++ b/net/9p/mux.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/fs/9p/mux.c | 2 | * net/9p/mux.c |
| 3 | * | 3 | * |
| 4 | * Protocol Multiplexer | 4 | * Protocol Multiplexer |
| 5 | * | 5 | * |
| @@ -30,13 +30,9 @@ | |||
| 30 | #include <linux/kthread.h> | 30 | #include <linux/kthread.h> |
| 31 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
| 32 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
| 33 | 33 | #include <net/9p/9p.h> | |
| 34 | #include "debug.h" | 34 | #include <net/9p/transport.h> |
| 35 | #include "v9fs.h" | 35 | #include <net/9p/conn.h> |
| 36 | #include "9p.h" | ||
| 37 | #include "conv.h" | ||
| 38 | #include "transport.h" | ||
| 39 | #include "mux.h" | ||
| 40 | 36 | ||
| 41 | #define ERREQFLUSH 1 | 37 | #define ERREQFLUSH 1 |
| 42 | #define SCHED_TIMEOUT 10 | 38 | #define SCHED_TIMEOUT 10 |
| @@ -55,33 +51,33 @@ enum { | |||
| 55 | Flushed, | 51 | Flushed, |
| 56 | }; | 52 | }; |
| 57 | 53 | ||
| 58 | struct v9fs_mux_poll_task; | 54 | struct p9_mux_poll_task; |
| 59 | 55 | ||
| 60 | struct v9fs_req { | 56 | struct p9_req { |
| 61 | spinlock_t lock; | 57 | spinlock_t lock; /* protect request structure */ |
| 62 | int tag; | 58 | int tag; |
| 63 | struct v9fs_fcall *tcall; | 59 | struct p9_fcall *tcall; |
| 64 | struct v9fs_fcall *rcall; | 60 | struct p9_fcall *rcall; |
| 65 | int err; | 61 | int err; |
| 66 | v9fs_mux_req_callback cb; | 62 | p9_conn_req_callback cb; |
| 67 | void *cba; | 63 | void *cba; |
| 68 | int flush; | 64 | int flush; |
| 69 | struct list_head req_list; | 65 | struct list_head req_list; |
| 70 | }; | 66 | }; |
| 71 | 67 | ||
| 72 | struct v9fs_mux_data { | 68 | struct p9_conn { |
| 73 | spinlock_t lock; | 69 | spinlock_t lock; /* protect lock structure */ |
| 74 | struct list_head mux_list; | 70 | struct list_head mux_list; |
| 75 | struct v9fs_mux_poll_task *poll_task; | 71 | struct p9_mux_poll_task *poll_task; |
| 76 | int msize; | 72 | int msize; |
| 77 | unsigned char *extended; | 73 | unsigned char *extended; |
| 78 | struct v9fs_transport *trans; | 74 | struct p9_transport *trans; |
| 79 | struct v9fs_idpool tagpool; | 75 | struct p9_idpool *tagpool; |
| 80 | int err; | 76 | int err; |
| 81 | wait_queue_head_t equeue; | 77 | wait_queue_head_t equeue; |
| 82 | struct list_head req_list; | 78 | struct list_head req_list; |
| 83 | struct list_head unsent_req_list; | 79 | struct list_head unsent_req_list; |
| 84 | struct v9fs_fcall *rcall; | 80 | struct p9_fcall *rcall; |
| 85 | int rpos; | 81 | int rpos; |
| 86 | char *rbuf; | 82 | char *rbuf; |
| 87 | int wpos; | 83 | int wpos; |
| @@ -95,44 +91,44 @@ struct v9fs_mux_data { | |||
| 95 | unsigned long wsched; | 91 | unsigned long wsched; |
| 96 | }; | 92 | }; |
| 97 | 93 | ||
| 98 | struct v9fs_mux_poll_task { | 94 | struct p9_mux_poll_task { |
| 99 | struct task_struct *task; | 95 | struct task_struct *task; |
| 100 | struct list_head mux_list; | 96 | struct list_head mux_list; |
| 101 | int muxnum; | 97 | int muxnum; |
| 102 | }; | 98 | }; |
| 103 | 99 | ||
| 104 | struct v9fs_mux_rpc { | 100 | struct p9_mux_rpc { |
| 105 | struct v9fs_mux_data *m; | 101 | struct p9_conn *m; |
| 106 | int err; | 102 | int err; |
| 107 | struct v9fs_fcall *tcall; | 103 | struct p9_fcall *tcall; |
| 108 | struct v9fs_fcall *rcall; | 104 | struct p9_fcall *rcall; |
| 109 | wait_queue_head_t wqueue; | 105 | wait_queue_head_t wqueue; |
| 110 | }; | 106 | }; |
| 111 | 107 | ||
| 112 | static int v9fs_poll_proc(void *); | 108 | static int p9_poll_proc(void *); |
| 113 | static void v9fs_read_work(struct work_struct *work); | 109 | static void p9_read_work(struct work_struct *work); |
| 114 | static void v9fs_write_work(struct work_struct *work); | 110 | static void p9_write_work(struct work_struct *work); |
| 115 | static void v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address, | 111 | static void p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, |
| 116 | poll_table * p); | 112 | poll_table * p); |
| 117 | static u16 v9fs_mux_get_tag(struct v9fs_mux_data *); | 113 | static u16 p9_mux_get_tag(struct p9_conn *); |
| 118 | static void v9fs_mux_put_tag(struct v9fs_mux_data *, u16); | 114 | static void p9_mux_put_tag(struct p9_conn *, u16); |
| 119 | 115 | ||
| 120 | static DEFINE_MUTEX(v9fs_mux_task_lock); | 116 | static DEFINE_MUTEX(p9_mux_task_lock); |
| 121 | static struct workqueue_struct *v9fs_mux_wq; | 117 | static struct workqueue_struct *p9_mux_wq; |
| 122 | 118 | ||
| 123 | static int v9fs_mux_num; | 119 | static int p9_mux_num; |
| 124 | static int v9fs_mux_poll_task_num; | 120 | static int p9_mux_poll_task_num; |
| 125 | static struct v9fs_mux_poll_task v9fs_mux_poll_tasks[100]; | 121 | static struct p9_mux_poll_task p9_mux_poll_tasks[100]; |
| 126 | 122 | ||
| 127 | int v9fs_mux_global_init(void) | 123 | int p9_mux_global_init(void) |
| 128 | { | 124 | { |
| 129 | int i; | 125 | int i; |
| 130 | 126 | ||
| 131 | for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++) | 127 | for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) |
| 132 | v9fs_mux_poll_tasks[i].task = NULL; | 128 | p9_mux_poll_tasks[i].task = NULL; |
| 133 | 129 | ||
| 134 | v9fs_mux_wq = create_workqueue("v9fs"); | 130 | p9_mux_wq = create_workqueue("v9fs"); |
| 135 | if (!v9fs_mux_wq) { | 131 | if (!p9_mux_wq) { |
| 136 | printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n"); | 132 | printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n"); |
| 137 | return -ENOMEM; | 133 | return -ENOMEM; |
| 138 | } | 134 | } |
| @@ -140,114 +136,117 @@ int v9fs_mux_global_init(void) | |||
| 140 | return 0; | 136 | return 0; |
| 141 | } | 137 | } |
| 142 | 138 | ||
| 143 | void v9fs_mux_global_exit(void) | 139 | void p9_mux_global_exit(void) |
| 144 | { | 140 | { |
| 145 | destroy_workqueue(v9fs_mux_wq); | 141 | destroy_workqueue(p9_mux_wq); |
| 146 | } | 142 | } |
| 147 | 143 | ||
| 148 | /** | 144 | /** |
| 149 | * v9fs_mux_calc_poll_procs - calculates the number of polling procs | 145 | * p9_mux_calc_poll_procs - calculates the number of polling procs |
| 150 | * based on the number of mounted v9fs filesystems. | 146 | * based on the number of mounted v9fs filesystems. |
| 151 | * | 147 | * |
| 152 | * The current implementation returns sqrt of the number of mounts. | 148 | * The current implementation returns sqrt of the number of mounts. |
| 153 | */ | 149 | */ |
| 154 | static int v9fs_mux_calc_poll_procs(int muxnum) | 150 | static int p9_mux_calc_poll_procs(int muxnum) |
| 155 | { | 151 | { |
| 156 | int n; | 152 | int n; |
| 157 | 153 | ||
| 158 | if (v9fs_mux_poll_task_num) | 154 | if (p9_mux_poll_task_num) |
| 159 | n = muxnum / v9fs_mux_poll_task_num + | 155 | n = muxnum / p9_mux_poll_task_num + |
| 160 | (muxnum % v9fs_mux_poll_task_num ? 1 : 0); | 156 | (muxnum % p9_mux_poll_task_num ? 1 : 0); |
| 161 | else | 157 | else |
| 162 | n = 1; | 158 | n = 1; |
| 163 | 159 | ||
| 164 | if (n > ARRAY_SIZE(v9fs_mux_poll_tasks)) | 160 | if (n > ARRAY_SIZE(p9_mux_poll_tasks)) |
| 165 | n = ARRAY_SIZE(v9fs_mux_poll_tasks); | 161 | n = ARRAY_SIZE(p9_mux_poll_tasks); |
| 166 | 162 | ||
| 167 | return n; | 163 | return n; |
| 168 | } | 164 | } |
| 169 | 165 | ||
| 170 | static int v9fs_mux_poll_start(struct v9fs_mux_data *m) | 166 | static int p9_mux_poll_start(struct p9_conn *m) |
| 171 | { | 167 | { |
| 172 | int i, n; | 168 | int i, n; |
| 173 | struct v9fs_mux_poll_task *vpt, *vptlast; | 169 | struct p9_mux_poll_task *vpt, *vptlast; |
| 174 | struct task_struct *pproc; | 170 | struct task_struct *pproc; |
| 175 | 171 | ||
| 176 | dprintk(DEBUG_MUX, "mux %p muxnum %d procnum %d\n", m, v9fs_mux_num, | 172 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p muxnum %d procnum %d\n", m, p9_mux_num, |
| 177 | v9fs_mux_poll_task_num); | 173 | p9_mux_poll_task_num); |
| 178 | mutex_lock(&v9fs_mux_task_lock); | 174 | mutex_lock(&p9_mux_task_lock); |
| 179 | 175 | ||
| 180 | n = v9fs_mux_calc_poll_procs(v9fs_mux_num + 1); | 176 | n = p9_mux_calc_poll_procs(p9_mux_num + 1); |
| 181 | if (n > v9fs_mux_poll_task_num) { | 177 | if (n > p9_mux_poll_task_num) { |
| 182 | for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++) { | 178 | for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) { |
| 183 | if (v9fs_mux_poll_tasks[i].task == NULL) { | 179 | if (p9_mux_poll_tasks[i].task == NULL) { |
| 184 | vpt = &v9fs_mux_poll_tasks[i]; | 180 | vpt = &p9_mux_poll_tasks[i]; |
| 185 | dprintk(DEBUG_MUX, "create proc %p\n", vpt); | 181 | P9_DPRINTK(P9_DEBUG_MUX, "create proc %p\n", |
| 186 | pproc = kthread_create(v9fs_poll_proc, vpt, | 182 | vpt); |
| 187 | "v9fs-poll"); | 183 | pproc = kthread_create(p9_poll_proc, vpt, |
| 184 | "v9fs-poll"); | ||
| 188 | 185 | ||
| 189 | if (!IS_ERR(pproc)) { | 186 | if (!IS_ERR(pproc)) { |
| 190 | vpt->task = pproc; | 187 | vpt->task = pproc; |
| 191 | INIT_LIST_HEAD(&vpt->mux_list); | 188 | INIT_LIST_HEAD(&vpt->mux_list); |
| 192 | vpt->muxnum = 0; | 189 | vpt->muxnum = 0; |
| 193 | v9fs_mux_poll_task_num++; | 190 | p9_mux_poll_task_num++; |
| 194 | wake_up_process(vpt->task); | 191 | wake_up_process(vpt->task); |
| 195 | } | 192 | } |
| 196 | break; | 193 | break; |
| 197 | } | 194 | } |
| 198 | } | 195 | } |
| 199 | 196 | ||
| 200 | if (i >= ARRAY_SIZE(v9fs_mux_poll_tasks)) | 197 | if (i >= ARRAY_SIZE(p9_mux_poll_tasks)) |
| 201 | dprintk(DEBUG_ERROR, "warning: no free poll slots\n"); | 198 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 199 | "warning: no free poll slots\n"); | ||
| 202 | } | 200 | } |
| 203 | 201 | ||
| 204 | n = (v9fs_mux_num + 1) / v9fs_mux_poll_task_num + | 202 | n = (p9_mux_num + 1) / p9_mux_poll_task_num + |
| 205 | ((v9fs_mux_num + 1) % v9fs_mux_poll_task_num ? 1 : 0); | 203 | ((p9_mux_num + 1) % p9_mux_poll_task_num ? 1 : 0); |
| 206 | 204 | ||
| 207 | vptlast = NULL; | 205 | vptlast = NULL; |
| 208 | for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++) { | 206 | for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) { |
| 209 | vpt = &v9fs_mux_poll_tasks[i]; | 207 | vpt = &p9_mux_poll_tasks[i]; |
| 210 | if (vpt->task != NULL) { | 208 | if (vpt->task != NULL) { |
| 211 | vptlast = vpt; | 209 | vptlast = vpt; |
| 212 | if (vpt->muxnum < n) { | 210 | if (vpt->muxnum < n) { |
| 213 | dprintk(DEBUG_MUX, "put in proc %d\n", i); | 211 | P9_DPRINTK(P9_DEBUG_MUX, "put in proc %d\n", i); |
| 214 | list_add(&m->mux_list, &vpt->mux_list); | 212 | list_add(&m->mux_list, &vpt->mux_list); |
| 215 | vpt->muxnum++; | 213 | vpt->muxnum++; |
| 216 | m->poll_task = vpt; | 214 | m->poll_task = vpt; |
| 217 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); | 215 | memset(&m->poll_waddr, 0, |
| 218 | init_poll_funcptr(&m->pt, v9fs_pollwait); | 216 | sizeof(m->poll_waddr)); |
| 217 | init_poll_funcptr(&m->pt, p9_pollwait); | ||
| 219 | break; | 218 | break; |
| 220 | } | 219 | } |
| 221 | } | 220 | } |
| 222 | } | 221 | } |
| 223 | 222 | ||
| 224 | if (i >= ARRAY_SIZE(v9fs_mux_poll_tasks)) { | 223 | if (i >= ARRAY_SIZE(p9_mux_poll_tasks)) { |
| 225 | if (vptlast == NULL) | 224 | if (vptlast == NULL) |
| 226 | return -ENOMEM; | 225 | return -ENOMEM; |
| 227 | 226 | ||
| 228 | dprintk(DEBUG_MUX, "put in proc %d\n", i); | 227 | P9_DPRINTK(P9_DEBUG_MUX, "put in proc %d\n", i); |
| 229 | list_add(&m->mux_list, &vptlast->mux_list); | 228 | list_add(&m->mux_list, &vptlast->mux_list); |
| 230 | vptlast->muxnum++; | 229 | vptlast->muxnum++; |
| 231 | m->poll_task = vptlast; | 230 | m->poll_task = vptlast; |
| 232 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); | 231 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); |
| 233 | init_poll_funcptr(&m->pt, v9fs_pollwait); | 232 | init_poll_funcptr(&m->pt, p9_pollwait); |
| 234 | } | 233 | } |
| 235 | 234 | ||
| 236 | v9fs_mux_num++; | 235 | p9_mux_num++; |
| 237 | mutex_unlock(&v9fs_mux_task_lock); | 236 | mutex_unlock(&p9_mux_task_lock); |
| 238 | 237 | ||
| 239 | return 0; | 238 | return 0; |
| 240 | } | 239 | } |
| 241 | 240 | ||
| 242 | static void v9fs_mux_poll_stop(struct v9fs_mux_data *m) | 241 | static void p9_mux_poll_stop(struct p9_conn *m) |
| 243 | { | 242 | { |
| 244 | int i; | 243 | int i; |
| 245 | struct v9fs_mux_poll_task *vpt; | 244 | struct p9_mux_poll_task *vpt; |
| 246 | 245 | ||
| 247 | mutex_lock(&v9fs_mux_task_lock); | 246 | mutex_lock(&p9_mux_task_lock); |
| 248 | vpt = m->poll_task; | 247 | vpt = m->poll_task; |
| 249 | list_del(&m->mux_list); | 248 | list_del(&m->mux_list); |
| 250 | for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { | 249 | for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { |
| 251 | if (m->poll_waddr[i] != NULL) { | 250 | if (m->poll_waddr[i] != NULL) { |
| 252 | remove_wait_queue(m->poll_waddr[i], &m->poll_wait[i]); | 251 | remove_wait_queue(m->poll_waddr[i], &m->poll_wait[i]); |
| 253 | m->poll_waddr[i] = NULL; | 252 | m->poll_waddr[i] = NULL; |
| @@ -255,31 +254,31 @@ static void v9fs_mux_poll_stop(struct v9fs_mux_data *m) | |||
| 255 | } | 254 | } |
| 256 | vpt->muxnum--; | 255 | vpt->muxnum--; |
| 257 | if (!vpt->muxnum) { | 256 | if (!vpt->muxnum) { |
| 258 | dprintk(DEBUG_MUX, "destroy proc %p\n", vpt); | 257 | P9_DPRINTK(P9_DEBUG_MUX, "destroy proc %p\n", vpt); |
| 259 | kthread_stop(vpt->task); | 258 | kthread_stop(vpt->task); |
| 260 | vpt->task = NULL; | 259 | vpt->task = NULL; |
| 261 | v9fs_mux_poll_task_num--; | 260 | p9_mux_poll_task_num--; |
| 262 | } | 261 | } |
| 263 | v9fs_mux_num--; | 262 | p9_mux_num--; |
| 264 | mutex_unlock(&v9fs_mux_task_lock); | 263 | mutex_unlock(&p9_mux_task_lock); |
| 265 | } | 264 | } |
| 266 | 265 | ||
| 267 | /** | 266 | /** |
| 268 | * v9fs_mux_init - allocate and initialize the per-session mux data | 267 | * p9_conn_create - allocate and initialize the per-session mux data |
| 269 | * Creates the polling task if this is the first session. | 268 | * Creates the polling task if this is the first session. |
| 270 | * | 269 | * |
| 271 | * @trans - transport structure | 270 | * @trans - transport structure |
| 272 | * @msize - maximum message size | 271 | * @msize - maximum message size |
| 273 | * @extended - pointer to the extended flag | 272 | * @extended - pointer to the extended flag |
| 274 | */ | 273 | */ |
| 275 | struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, | 274 | struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize, |
| 276 | unsigned char *extended) | 275 | unsigned char *extended) |
| 277 | { | 276 | { |
| 278 | int i, n; | 277 | int i, n; |
| 279 | struct v9fs_mux_data *m, *mtmp; | 278 | struct p9_conn *m, *mtmp; |
| 280 | 279 | ||
| 281 | dprintk(DEBUG_MUX, "transport %p msize %d\n", trans, msize); | 280 | P9_DPRINTK(P9_DEBUG_MUX, "transport %p msize %d\n", trans, msize); |
| 282 | m = kmalloc(sizeof(struct v9fs_mux_data), GFP_KERNEL); | 281 | m = kmalloc(sizeof(struct p9_conn), GFP_KERNEL); |
| 283 | if (!m) | 282 | if (!m) |
| 284 | return ERR_PTR(-ENOMEM); | 283 | return ERR_PTR(-ENOMEM); |
| 285 | 284 | ||
| @@ -288,8 +287,12 @@ struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, | |||
| 288 | m->msize = msize; | 287 | m->msize = msize; |
| 289 | m->extended = extended; | 288 | m->extended = extended; |
| 290 | m->trans = trans; | 289 | m->trans = trans; |
| 291 | idr_init(&m->tagpool.pool); | 290 | m->tagpool = p9_idpool_create(); |
| 292 | init_MUTEX(&m->tagpool.lock); | 291 | if (!m->tagpool) { |
| 292 | kfree(m); | ||
| 293 | return ERR_PTR(PTR_ERR(m->tagpool)); | ||
| 294 | } | ||
| 295 | |||
| 293 | m->err = 0; | 296 | m->err = 0; |
| 294 | init_waitqueue_head(&m->equeue); | 297 | init_waitqueue_head(&m->equeue); |
| 295 | INIT_LIST_HEAD(&m->req_list); | 298 | INIT_LIST_HEAD(&m->req_list); |
| @@ -299,29 +302,29 @@ struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, | |||
| 299 | m->rbuf = NULL; | 302 | m->rbuf = NULL; |
| 300 | m->wpos = m->wsize = 0; | 303 | m->wpos = m->wsize = 0; |
| 301 | m->wbuf = NULL; | 304 | m->wbuf = NULL; |
| 302 | INIT_WORK(&m->rq, v9fs_read_work); | 305 | INIT_WORK(&m->rq, p9_read_work); |
| 303 | INIT_WORK(&m->wq, v9fs_write_work); | 306 | INIT_WORK(&m->wq, p9_write_work); |
| 304 | m->wsched = 0; | 307 | m->wsched = 0; |
| 305 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); | 308 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); |
| 306 | m->poll_task = NULL; | 309 | m->poll_task = NULL; |
| 307 | n = v9fs_mux_poll_start(m); | 310 | n = p9_mux_poll_start(m); |
| 308 | if (n) | 311 | if (n) |
| 309 | return ERR_PTR(n); | 312 | return ERR_PTR(n); |
| 310 | 313 | ||
| 311 | n = trans->poll(trans, &m->pt); | 314 | n = trans->poll(trans, &m->pt); |
| 312 | if (n & POLLIN) { | 315 | if (n & POLLIN) { |
| 313 | dprintk(DEBUG_MUX, "mux %p can read\n", m); | 316 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p can read\n", m); |
| 314 | set_bit(Rpending, &m->wsched); | 317 | set_bit(Rpending, &m->wsched); |
| 315 | } | 318 | } |
| 316 | 319 | ||
| 317 | if (n & POLLOUT) { | 320 | if (n & POLLOUT) { |
| 318 | dprintk(DEBUG_MUX, "mux %p can write\n", m); | 321 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p can write\n", m); |
| 319 | set_bit(Wpending, &m->wsched); | 322 | set_bit(Wpending, &m->wsched); |
| 320 | } | 323 | } |
| 321 | 324 | ||
| 322 | for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { | 325 | for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { |
| 323 | if (IS_ERR(m->poll_waddr[i])) { | 326 | if (IS_ERR(m->poll_waddr[i])) { |
| 324 | v9fs_mux_poll_stop(m); | 327 | p9_mux_poll_stop(m); |
| 325 | mtmp = (void *)m->poll_waddr; /* the error code */ | 328 | mtmp = (void *)m->poll_waddr; /* the error code */ |
| 326 | kfree(m); | 329 | kfree(m); |
| 327 | m = mtmp; | 330 | m = mtmp; |
| @@ -331,56 +334,58 @@ struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, | |||
| 331 | 334 | ||
| 332 | return m; | 335 | return m; |
| 333 | } | 336 | } |
| 337 | EXPORT_SYMBOL(p9_conn_create); | ||
| 334 | 338 | ||
| 335 | /** | 339 | /** |
| 336 | * v9fs_mux_destroy - cancels all pending requests and frees mux resources | 340 | * p9_mux_destroy - cancels all pending requests and frees mux resources |
| 337 | */ | 341 | */ |
| 338 | void v9fs_mux_destroy(struct v9fs_mux_data *m) | 342 | void p9_conn_destroy(struct p9_conn *m) |
| 339 | { | 343 | { |
| 340 | dprintk(DEBUG_MUX, "mux %p prev %p next %p\n", m, | 344 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m, |
| 341 | m->mux_list.prev, m->mux_list.next); | 345 | m->mux_list.prev, m->mux_list.next); |
| 342 | v9fs_mux_cancel(m, -ECONNRESET); | 346 | p9_conn_cancel(m, -ECONNRESET); |
| 343 | 347 | ||
| 344 | if (!list_empty(&m->req_list)) { | 348 | if (!list_empty(&m->req_list)) { |
| 345 | /* wait until all processes waiting on this session exit */ | 349 | /* wait until all processes waiting on this session exit */ |
| 346 | dprintk(DEBUG_MUX, "mux %p waiting for empty request queue\n", | 350 | P9_DPRINTK(P9_DEBUG_MUX, |
| 347 | m); | 351 | "mux %p waiting for empty request queue\n", m); |
| 348 | wait_event_timeout(m->equeue, (list_empty(&m->req_list)), 5000); | 352 | wait_event_timeout(m->equeue, (list_empty(&m->req_list)), 5000); |
| 349 | dprintk(DEBUG_MUX, "mux %p request queue empty: %d\n", m, | 353 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p request queue empty: %d\n", m, |
| 350 | list_empty(&m->req_list)); | 354 | list_empty(&m->req_list)); |
| 351 | } | 355 | } |
| 352 | 356 | ||
| 353 | v9fs_mux_poll_stop(m); | 357 | p9_mux_poll_stop(m); |
| 354 | m->trans = NULL; | 358 | m->trans = NULL; |
| 355 | 359 | p9_idpool_destroy(m->tagpool); | |
| 356 | kfree(m); | 360 | kfree(m); |
| 357 | } | 361 | } |
| 362 | EXPORT_SYMBOL(p9_conn_destroy); | ||
| 358 | 363 | ||
| 359 | /** | 364 | /** |
| 360 | * v9fs_pollwait - called by files poll operation to add v9fs-poll task | 365 | * p9_pollwait - called by files poll operation to add v9fs-poll task |
| 361 | * to files wait queue | 366 | * to files wait queue |
| 362 | */ | 367 | */ |
| 363 | static void | 368 | static void |
| 364 | v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address, | 369 | p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, |
| 365 | poll_table * p) | 370 | poll_table * p) |
| 366 | { | 371 | { |
| 367 | int i; | 372 | int i; |
| 368 | struct v9fs_mux_data *m; | 373 | struct p9_conn *m; |
| 369 | 374 | ||
| 370 | m = container_of(p, struct v9fs_mux_data, pt); | 375 | m = container_of(p, struct p9_conn, pt); |
| 371 | for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) | 376 | for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) |
| 372 | if (m->poll_waddr[i] == NULL) | 377 | if (m->poll_waddr[i] == NULL) |
| 373 | break; | 378 | break; |
| 374 | 379 | ||
| 375 | if (i >= ARRAY_SIZE(m->poll_waddr)) { | 380 | if (i >= ARRAY_SIZE(m->poll_waddr)) { |
| 376 | dprintk(DEBUG_ERROR, "not enough wait_address slots\n"); | 381 | P9_DPRINTK(P9_DEBUG_ERROR, "not enough wait_address slots\n"); |
| 377 | return; | 382 | return; |
| 378 | } | 383 | } |
| 379 | 384 | ||
| 380 | m->poll_waddr[i] = wait_address; | 385 | m->poll_waddr[i] = wait_address; |
| 381 | 386 | ||
| 382 | if (!wait_address) { | 387 | if (!wait_address) { |
| 383 | dprintk(DEBUG_ERROR, "no wait_address\n"); | 388 | P9_DPRINTK(P9_DEBUG_ERROR, "no wait_address\n"); |
| 384 | m->poll_waddr[i] = ERR_PTR(-EIO); | 389 | m->poll_waddr[i] = ERR_PTR(-EIO); |
| 385 | return; | 390 | return; |
| 386 | } | 391 | } |
| @@ -390,9 +395,9 @@ v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address, | |||
| 390 | } | 395 | } |
| 391 | 396 | ||
| 392 | /** | 397 | /** |
| 393 | * v9fs_poll_mux - polls a mux and schedules read or write works if necessary | 398 | * p9_poll_mux - polls a mux and schedules read or write works if necessary |
| 394 | */ | 399 | */ |
| 395 | static void v9fs_poll_mux(struct v9fs_mux_data *m) | 400 | static void p9_poll_mux(struct p9_conn *m) |
| 396 | { | 401 | { |
| 397 | int n; | 402 | int n; |
| 398 | 403 | ||
| @@ -401,69 +406,69 @@ static void v9fs_poll_mux(struct v9fs_mux_data *m) | |||
| 401 | 406 | ||
| 402 | n = m->trans->poll(m->trans, NULL); | 407 | n = m->trans->poll(m->trans, NULL); |
| 403 | if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) { | 408 | if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) { |
| 404 | dprintk(DEBUG_MUX, "error mux %p err %d\n", m, n); | 409 | P9_DPRINTK(P9_DEBUG_MUX, "error mux %p err %d\n", m, n); |
| 405 | if (n >= 0) | 410 | if (n >= 0) |
| 406 | n = -ECONNRESET; | 411 | n = -ECONNRESET; |
| 407 | v9fs_mux_cancel(m, n); | 412 | p9_conn_cancel(m, n); |
| 408 | } | 413 | } |
| 409 | 414 | ||
| 410 | if (n & POLLIN) { | 415 | if (n & POLLIN) { |
| 411 | set_bit(Rpending, &m->wsched); | 416 | set_bit(Rpending, &m->wsched); |
| 412 | dprintk(DEBUG_MUX, "mux %p can read\n", m); | 417 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p can read\n", m); |
| 413 | if (!test_and_set_bit(Rworksched, &m->wsched)) { | 418 | if (!test_and_set_bit(Rworksched, &m->wsched)) { |
| 414 | dprintk(DEBUG_MUX, "schedule read work mux %p\n", m); | 419 | P9_DPRINTK(P9_DEBUG_MUX, "schedule read work %p\n", m); |
| 415 | queue_work(v9fs_mux_wq, &m->rq); | 420 | queue_work(p9_mux_wq, &m->rq); |
| 416 | } | 421 | } |
| 417 | } | 422 | } |
| 418 | 423 | ||
| 419 | if (n & POLLOUT) { | 424 | if (n & POLLOUT) { |
| 420 | set_bit(Wpending, &m->wsched); | 425 | set_bit(Wpending, &m->wsched); |
| 421 | dprintk(DEBUG_MUX, "mux %p can write\n", m); | 426 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p can write\n", m); |
| 422 | if ((m->wsize || !list_empty(&m->unsent_req_list)) | 427 | if ((m->wsize || !list_empty(&m->unsent_req_list)) |
| 423 | && !test_and_set_bit(Wworksched, &m->wsched)) { | 428 | && !test_and_set_bit(Wworksched, &m->wsched)) { |
| 424 | dprintk(DEBUG_MUX, "schedule write work mux %p\n", m); | 429 | P9_DPRINTK(P9_DEBUG_MUX, "schedule write work %p\n", m); |
| 425 | queue_work(v9fs_mux_wq, &m->wq); | 430 | queue_work(p9_mux_wq, &m->wq); |
| 426 | } | 431 | } |
| 427 | } | 432 | } |
| 428 | } | 433 | } |
| 429 | 434 | ||
| 430 | /** | 435 | /** |
| 431 | * v9fs_poll_proc - polls all v9fs transports for new events and queues | 436 | * p9_poll_proc - polls all v9fs transports for new events and queues |
| 432 | * the appropriate work to the work queue | 437 | * the appropriate work to the work queue |
| 433 | */ | 438 | */ |
| 434 | static int v9fs_poll_proc(void *a) | 439 | static int p9_poll_proc(void *a) |
| 435 | { | 440 | { |
| 436 | struct v9fs_mux_data *m, *mtmp; | 441 | struct p9_conn *m, *mtmp; |
| 437 | struct v9fs_mux_poll_task *vpt; | 442 | struct p9_mux_poll_task *vpt; |
| 438 | 443 | ||
| 439 | vpt = a; | 444 | vpt = a; |
| 440 | dprintk(DEBUG_MUX, "start %p %p\n", current, vpt); | 445 | P9_DPRINTK(P9_DEBUG_MUX, "start %p %p\n", current, vpt); |
| 441 | while (!kthread_should_stop()) { | 446 | while (!kthread_should_stop()) { |
| 442 | set_current_state(TASK_INTERRUPTIBLE); | 447 | set_current_state(TASK_INTERRUPTIBLE); |
| 443 | 448 | ||
| 444 | list_for_each_entry_safe(m, mtmp, &vpt->mux_list, mux_list) { | 449 | list_for_each_entry_safe(m, mtmp, &vpt->mux_list, mux_list) { |
| 445 | v9fs_poll_mux(m); | 450 | p9_poll_mux(m); |
| 446 | } | 451 | } |
| 447 | 452 | ||
| 448 | dprintk(DEBUG_MUX, "sleeping...\n"); | 453 | P9_DPRINTK(P9_DEBUG_MUX, "sleeping...\n"); |
| 449 | schedule_timeout(SCHED_TIMEOUT * HZ); | 454 | schedule_timeout(SCHED_TIMEOUT * HZ); |
| 450 | } | 455 | } |
| 451 | 456 | ||
| 452 | __set_current_state(TASK_RUNNING); | 457 | __set_current_state(TASK_RUNNING); |
| 453 | dprintk(DEBUG_MUX, "finish\n"); | 458 | P9_DPRINTK(P9_DEBUG_MUX, "finish\n"); |
| 454 | return 0; | 459 | return 0; |
| 455 | } | 460 | } |
| 456 | 461 | ||
| 457 | /** | 462 | /** |
| 458 | * v9fs_write_work - called when a transport can send some data | 463 | * p9_write_work - called when a transport can send some data |
| 459 | */ | 464 | */ |
| 460 | static void v9fs_write_work(struct work_struct *work) | 465 | static void p9_write_work(struct work_struct *work) |
| 461 | { | 466 | { |
| 462 | int n, err; | 467 | int n, err; |
| 463 | struct v9fs_mux_data *m; | 468 | struct p9_conn *m; |
| 464 | struct v9fs_req *req; | 469 | struct p9_req *req; |
| 465 | 470 | ||
| 466 | m = container_of(work, struct v9fs_mux_data, wq); | 471 | m = container_of(work, struct p9_conn, wq); |
| 467 | 472 | ||
| 468 | if (m->err < 0) { | 473 | if (m->err < 0) { |
| 469 | clear_bit(Wworksched, &m->wsched); | 474 | clear_bit(Wworksched, &m->wsched); |
| @@ -478,7 +483,7 @@ static void v9fs_write_work(struct work_struct *work) | |||
| 478 | 483 | ||
| 479 | spin_lock(&m->lock); | 484 | spin_lock(&m->lock); |
| 480 | again: | 485 | again: |
| 481 | req = list_entry(m->unsent_req_list.next, struct v9fs_req, | 486 | req = list_entry(m->unsent_req_list.next, struct p9_req, |
| 482 | req_list); | 487 | req_list); |
| 483 | list_move_tail(&req->req_list, &m->req_list); | 488 | list_move_tail(&req->req_list, &m->req_list); |
| 484 | if (req->err == ERREQFLUSH) | 489 | if (req->err == ERREQFLUSH) |
| @@ -487,14 +492,14 @@ again: | |||
| 487 | m->wbuf = req->tcall->sdata; | 492 | m->wbuf = req->tcall->sdata; |
| 488 | m->wsize = req->tcall->size; | 493 | m->wsize = req->tcall->size; |
| 489 | m->wpos = 0; | 494 | m->wpos = 0; |
| 490 | dump_data(m->wbuf, m->wsize); | ||
| 491 | spin_unlock(&m->lock); | 495 | spin_unlock(&m->lock); |
| 492 | } | 496 | } |
| 493 | 497 | ||
| 494 | dprintk(DEBUG_MUX, "mux %p pos %d size %d\n", m, m->wpos, m->wsize); | 498 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p pos %d size %d\n", m, m->wpos, |
| 499 | m->wsize); | ||
| 495 | clear_bit(Wpending, &m->wsched); | 500 | clear_bit(Wpending, &m->wsched); |
| 496 | err = m->trans->write(m->trans, m->wbuf + m->wpos, m->wsize - m->wpos); | 501 | err = m->trans->write(m->trans, m->wbuf + m->wpos, m->wsize - m->wpos); |
| 497 | dprintk(DEBUG_MUX, "mux %p sent %d bytes\n", m, err); | 502 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p sent %d bytes\n", m, err); |
| 498 | if (err == -EAGAIN) { | 503 | if (err == -EAGAIN) { |
| 499 | clear_bit(Wworksched, &m->wsched); | 504 | clear_bit(Wworksched, &m->wsched); |
| 500 | return; | 505 | return; |
| @@ -514,8 +519,8 @@ again: | |||
| 514 | n = m->trans->poll(m->trans, NULL); | 519 | n = m->trans->poll(m->trans, NULL); |
| 515 | 520 | ||
| 516 | if (n & POLLOUT) { | 521 | if (n & POLLOUT) { |
| 517 | dprintk(DEBUG_MUX, "schedule write work mux %p\n", m); | 522 | P9_DPRINTK(P9_DEBUG_MUX, "schedule write work %p\n", m); |
| 518 | queue_work(v9fs_mux_wq, &m->wq); | 523 | queue_work(p9_mux_wq, &m->wq); |
| 519 | } else | 524 | } else |
| 520 | clear_bit(Wworksched, &m->wsched); | 525 | clear_bit(Wworksched, &m->wsched); |
| 521 | } else | 526 | } else |
| @@ -523,27 +528,28 @@ again: | |||
| 523 | 528 | ||
| 524 | return; | 529 | return; |
| 525 | 530 | ||
| 526 | error: | 531 | error: |
| 527 | v9fs_mux_cancel(m, err); | 532 | p9_conn_cancel(m, err); |
| 528 | clear_bit(Wworksched, &m->wsched); | 533 | clear_bit(Wworksched, &m->wsched); |
| 529 | } | 534 | } |
| 530 | 535 | ||
| 531 | static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) | 536 | static void process_request(struct p9_conn *m, struct p9_req *req) |
| 532 | { | 537 | { |
| 533 | int ecode; | 538 | int ecode; |
| 534 | struct v9fs_str *ename; | 539 | struct p9_str *ename; |
| 535 | 540 | ||
| 536 | if (!req->err && req->rcall->id == RERROR) { | 541 | if (!req->err && req->rcall->id == P9_RERROR) { |
| 537 | ecode = req->rcall->params.rerror.errno; | 542 | ecode = req->rcall->params.rerror.errno; |
| 538 | ename = &req->rcall->params.rerror.error; | 543 | ename = &req->rcall->params.rerror.error; |
| 539 | 544 | ||
| 540 | dprintk(DEBUG_MUX, "Rerror %.*s\n", ename->len, ename->str); | 545 | P9_DPRINTK(P9_DEBUG_MUX, "Rerror %.*s\n", ename->len, |
| 546 | ename->str); | ||
| 541 | 547 | ||
| 542 | if (*m->extended) | 548 | if (*m->extended) |
| 543 | req->err = -ecode; | 549 | req->err = -ecode; |
| 544 | 550 | ||
| 545 | if (!req->err) { | 551 | if (!req->err) { |
| 546 | req->err = v9fs_errstr2errno(ename->str, ename->len); | 552 | req->err = p9_errstr2errno(ename->str, ename->len); |
| 547 | 553 | ||
| 548 | if (!req->err) { /* string match failed */ | 554 | if (!req->err) { /* string match failed */ |
| 549 | PRINT_FCALL_ERROR("unknown error", req->rcall); | 555 | PRINT_FCALL_ERROR("unknown error", req->rcall); |
| @@ -553,47 +559,48 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) | |||
| 553 | req->err = -ESERVERFAULT; | 559 | req->err = -ESERVERFAULT; |
| 554 | } | 560 | } |
| 555 | } else if (req->tcall && req->rcall->id != req->tcall->id + 1) { | 561 | } else if (req->tcall && req->rcall->id != req->tcall->id + 1) { |
| 556 | dprintk(DEBUG_ERROR, "fcall mismatch: expected %d, got %d\n", | 562 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 557 | req->tcall->id + 1, req->rcall->id); | 563 | "fcall mismatch: expected %d, got %d\n", |
| 564 | req->tcall->id + 1, req->rcall->id); | ||
| 558 | if (!req->err) | 565 | if (!req->err) |
| 559 | req->err = -EIO; | 566 | req->err = -EIO; |
| 560 | } | 567 | } |
| 561 | } | 568 | } |
| 562 | 569 | ||
| 563 | /** | 570 | /** |
| 564 | * v9fs_read_work - called when there is some data to be read from a transport | 571 | * p9_read_work - called when there is some data to be read from a transport |
| 565 | */ | 572 | */ |
| 566 | static void v9fs_read_work(struct work_struct *work) | 573 | static void p9_read_work(struct work_struct *work) |
| 567 | { | 574 | { |
| 568 | int n, err; | 575 | int n, err; |
| 569 | struct v9fs_mux_data *m; | 576 | struct p9_conn *m; |
| 570 | struct v9fs_req *req, *rptr, *rreq; | 577 | struct p9_req *req, *rptr, *rreq; |
| 571 | struct v9fs_fcall *rcall; | 578 | struct p9_fcall *rcall; |
| 572 | char *rbuf; | 579 | char *rbuf; |
| 573 | 580 | ||
| 574 | m = container_of(work, struct v9fs_mux_data, rq); | 581 | m = container_of(work, struct p9_conn, rq); |
| 575 | 582 | ||
| 576 | if (m->err < 0) | 583 | if (m->err < 0) |
| 577 | return; | 584 | return; |
| 578 | 585 | ||
| 579 | rcall = NULL; | 586 | rcall = NULL; |
| 580 | dprintk(DEBUG_MUX, "start mux %p pos %d\n", m, m->rpos); | 587 | P9_DPRINTK(P9_DEBUG_MUX, "start mux %p pos %d\n", m, m->rpos); |
| 581 | 588 | ||
| 582 | if (!m->rcall) { | 589 | if (!m->rcall) { |
| 583 | m->rcall = | 590 | m->rcall = |
| 584 | kmalloc(sizeof(struct v9fs_fcall) + m->msize, GFP_KERNEL); | 591 | kmalloc(sizeof(struct p9_fcall) + m->msize, GFP_KERNEL); |
| 585 | if (!m->rcall) { | 592 | if (!m->rcall) { |
| 586 | err = -ENOMEM; | 593 | err = -ENOMEM; |
| 587 | goto error; | 594 | goto error; |
| 588 | } | 595 | } |
| 589 | 596 | ||
| 590 | m->rbuf = (char *)m->rcall + sizeof(struct v9fs_fcall); | 597 | m->rbuf = (char *)m->rcall + sizeof(struct p9_fcall); |
| 591 | m->rpos = 0; | 598 | m->rpos = 0; |
| 592 | } | 599 | } |
| 593 | 600 | ||
| 594 | clear_bit(Rpending, &m->wsched); | 601 | clear_bit(Rpending, &m->wsched); |
| 595 | err = m->trans->read(m->trans, m->rbuf + m->rpos, m->msize - m->rpos); | 602 | err = m->trans->read(m->trans, m->rbuf + m->rpos, m->msize - m->rpos); |
| 596 | dprintk(DEBUG_MUX, "mux %p got %d bytes\n", m, err); | 603 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p got %d bytes\n", m, err); |
| 597 | if (err == -EAGAIN) { | 604 | if (err == -EAGAIN) { |
| 598 | clear_bit(Rworksched, &m->wsched); | 605 | clear_bit(Rworksched, &m->wsched); |
| 599 | return; | 606 | return; |
| @@ -606,7 +613,7 @@ static void v9fs_read_work(struct work_struct *work) | |||
| 606 | while (m->rpos > 4) { | 613 | while (m->rpos > 4) { |
| 607 | n = le32_to_cpu(*(__le32 *) m->rbuf); | 614 | n = le32_to_cpu(*(__le32 *) m->rbuf); |
| 608 | if (n >= m->msize) { | 615 | if (n >= m->msize) { |
| 609 | dprintk(DEBUG_ERROR, | 616 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 610 | "requested packet size too big: %d\n", n); | 617 | "requested packet size too big: %d\n", n); |
| 611 | err = -EIO; | 618 | err = -EIO; |
| 612 | goto error; | 619 | goto error; |
| @@ -615,32 +622,33 @@ static void v9fs_read_work(struct work_struct *work) | |||
| 615 | if (m->rpos < n) | 622 | if (m->rpos < n) |
| 616 | break; | 623 | break; |
| 617 | 624 | ||
| 618 | dump_data(m->rbuf, n); | ||
| 619 | err = | 625 | err = |
| 620 | v9fs_deserialize_fcall(m->rbuf, n, m->rcall, *m->extended); | 626 | p9_deserialize_fcall(m->rbuf, n, m->rcall, *m->extended); |
| 621 | if (err < 0) { | 627 | if (err < 0) { |
| 622 | goto error; | 628 | goto error; |
| 623 | } | 629 | } |
| 624 | 630 | ||
| 625 | if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) { | 631 | #ifdef CONFIG_NET_9P_DEBUG |
| 632 | if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) { | ||
| 626 | char buf[150]; | 633 | char buf[150]; |
| 627 | 634 | ||
| 628 | v9fs_printfcall(buf, sizeof(buf), m->rcall, | 635 | p9_printfcall(buf, sizeof(buf), m->rcall, |
| 629 | *m->extended); | 636 | *m->extended); |
| 630 | printk(KERN_NOTICE ">>> %p %s\n", m, buf); | 637 | printk(KERN_NOTICE ">>> %p %s\n", m, buf); |
| 631 | } | 638 | } |
| 639 | #endif | ||
| 632 | 640 | ||
| 633 | rcall = m->rcall; | 641 | rcall = m->rcall; |
| 634 | rbuf = m->rbuf; | 642 | rbuf = m->rbuf; |
| 635 | if (m->rpos > n) { | 643 | if (m->rpos > n) { |
| 636 | m->rcall = kmalloc(sizeof(struct v9fs_fcall) + m->msize, | 644 | m->rcall = kmalloc(sizeof(struct p9_fcall) + m->msize, |
| 637 | GFP_KERNEL); | 645 | GFP_KERNEL); |
| 638 | if (!m->rcall) { | 646 | if (!m->rcall) { |
| 639 | err = -ENOMEM; | 647 | err = -ENOMEM; |
| 640 | goto error; | 648 | goto error; |
| 641 | } | 649 | } |
| 642 | 650 | ||
| 643 | m->rbuf = (char *)m->rcall + sizeof(struct v9fs_fcall); | 651 | m->rbuf = (char *)m->rcall + sizeof(struct p9_fcall); |
| 644 | memmove(m->rbuf, rbuf + n, m->rpos - n); | 652 | memmove(m->rbuf, rbuf + n, m->rpos - n); |
| 645 | m->rpos -= n; | 653 | m->rpos -= n; |
| 646 | } else { | 654 | } else { |
| @@ -649,8 +657,8 @@ static void v9fs_read_work(struct work_struct *work) | |||
| 649 | m->rpos = 0; | 657 | m->rpos = 0; |
| 650 | } | 658 | } |
| 651 | 659 | ||
| 652 | dprintk(DEBUG_MUX, "mux %p fcall id %d tag %d\n", m, rcall->id, | 660 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p fcall id %d tag %d\n", m, |
| 653 | rcall->tag); | 661 | rcall->id, rcall->tag); |
| 654 | 662 | ||
| 655 | req = NULL; | 663 | req = NULL; |
| 656 | spin_lock(&m->lock); | 664 | spin_lock(&m->lock); |
| @@ -677,10 +685,10 @@ static void v9fs_read_work(struct work_struct *work) | |||
| 677 | wake_up(&m->equeue); | 685 | wake_up(&m->equeue); |
| 678 | } | 686 | } |
| 679 | } else { | 687 | } else { |
| 680 | if (err >= 0 && rcall->id != RFLUSH) | 688 | if (err >= 0 && rcall->id != P9_RFLUSH) |
| 681 | dprintk(DEBUG_ERROR, | 689 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 682 | "unexpected response mux %p id %d tag %d\n", | 690 | "unexpected response mux %p id %d tag %d\n", |
| 683 | m, rcall->id, rcall->tag); | 691 | m, rcall->id, rcall->tag); |
| 684 | kfree(rcall); | 692 | kfree(rcall); |
| 685 | } | 693 | } |
| 686 | } | 694 | } |
| @@ -692,8 +700,8 @@ static void v9fs_read_work(struct work_struct *work) | |||
| 692 | n = m->trans->poll(m->trans, NULL); | 700 | n = m->trans->poll(m->trans, NULL); |
| 693 | 701 | ||
| 694 | if (n & POLLIN) { | 702 | if (n & POLLIN) { |
| 695 | dprintk(DEBUG_MUX, "schedule read work mux %p\n", m); | 703 | P9_DPRINTK(P9_DEBUG_MUX, "schedule read work %p\n", m); |
| 696 | queue_work(v9fs_mux_wq, &m->rq); | 704 | queue_work(p9_mux_wq, &m->rq); |
| 697 | } else | 705 | } else |
| 698 | clear_bit(Rworksched, &m->wsched); | 706 | clear_bit(Rworksched, &m->wsched); |
| 699 | } else | 707 | } else |
| @@ -701,13 +709,13 @@ static void v9fs_read_work(struct work_struct *work) | |||
| 701 | 709 | ||
| 702 | return; | 710 | return; |
| 703 | 711 | ||
| 704 | error: | 712 | error: |
| 705 | v9fs_mux_cancel(m, err); | 713 | p9_conn_cancel(m, err); |
| 706 | clear_bit(Rworksched, &m->wsched); | 714 | clear_bit(Rworksched, &m->wsched); |
| 707 | } | 715 | } |
| 708 | 716 | ||
| 709 | /** | 717 | /** |
| 710 | * v9fs_send_request - send 9P request | 718 | * p9_send_request - send 9P request |
| 711 | * The function can sleep until the request is scheduled for sending. | 719 | * The function can sleep until the request is scheduled for sending. |
| 712 | * The function can be interrupted. Return from the function is not | 720 | * The function can be interrupted. Return from the function is not |
| 713 | * a guarantee that the request is sent successfully. Can return errors | 721 | * a guarantee that the request is sent successfully. Can return errors |
| @@ -718,37 +726,40 @@ static void v9fs_read_work(struct work_struct *work) | |||
| 718 | * @cb: callback function to call when response is received | 726 | * @cb: callback function to call when response is received |
| 719 | * @cba: parameter to pass to the callback function | 727 | * @cba: parameter to pass to the callback function |
| 720 | */ | 728 | */ |
| 721 | static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m, | 729 | static struct p9_req *p9_send_request(struct p9_conn *m, |
| 722 | struct v9fs_fcall *tc, | 730 | struct p9_fcall *tc, |
| 723 | v9fs_mux_req_callback cb, void *cba) | 731 | p9_conn_req_callback cb, void *cba) |
| 724 | { | 732 | { |
| 725 | int n; | 733 | int n; |
| 726 | struct v9fs_req *req; | 734 | struct p9_req *req; |
| 727 | 735 | ||
| 728 | dprintk(DEBUG_MUX, "mux %p task %p tcall %p id %d\n", m, current, | 736 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p task %p tcall %p id %d\n", m, current, |
| 729 | tc, tc->id); | 737 | tc, tc->id); |
| 730 | if (m->err < 0) | 738 | if (m->err < 0) |
| 731 | return ERR_PTR(m->err); | 739 | return ERR_PTR(m->err); |
| 732 | 740 | ||
| 733 | req = kmalloc(sizeof(struct v9fs_req), GFP_KERNEL); | 741 | req = kmalloc(sizeof(struct p9_req), GFP_KERNEL); |
| 734 | if (!req) | 742 | if (!req) |
| 735 | return ERR_PTR(-ENOMEM); | 743 | return ERR_PTR(-ENOMEM); |
| 736 | 744 | ||
| 737 | if (tc->id == TVERSION) | 745 | if (tc->id == P9_TVERSION) |
| 738 | n = V9FS_NOTAG; | 746 | n = P9_NOTAG; |
| 739 | else | 747 | else |
| 740 | n = v9fs_mux_get_tag(m); | 748 | n = p9_mux_get_tag(m); |
| 741 | 749 | ||
| 742 | if (n < 0) | 750 | if (n < 0) |
| 743 | return ERR_PTR(-ENOMEM); | 751 | return ERR_PTR(-ENOMEM); |
| 744 | 752 | ||
| 745 | v9fs_set_tag(tc, n); | 753 | p9_set_tag(tc, n); |
| 746 | if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) { | 754 | |
| 755 | #ifdef CONFIG_NET_9P_DEBUG | ||
| 756 | if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) { | ||
| 747 | char buf[150]; | 757 | char buf[150]; |
| 748 | 758 | ||
| 749 | v9fs_printfcall(buf, sizeof(buf), tc, *m->extended); | 759 | p9_printfcall(buf, sizeof(buf), tc, *m->extended); |
| 750 | printk(KERN_NOTICE "<<< %p %s\n", m, buf); | 760 | printk(KERN_NOTICE "<<< %p %s\n", m, buf); |
| 751 | } | 761 | } |
| 762 | #endif | ||
| 752 | 763 | ||
| 753 | spin_lock_init(&req->lock); | 764 | spin_lock_init(&req->lock); |
| 754 | req->tag = n; | 765 | req->tag = n; |
| @@ -769,26 +780,26 @@ static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m, | |||
| 769 | n = m->trans->poll(m->trans, NULL); | 780 | n = m->trans->poll(m->trans, NULL); |
| 770 | 781 | ||
| 771 | if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched)) | 782 | if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched)) |
| 772 | queue_work(v9fs_mux_wq, &m->wq); | 783 | queue_work(p9_mux_wq, &m->wq); |
| 773 | 784 | ||
| 774 | return req; | 785 | return req; |
| 775 | } | 786 | } |
| 776 | 787 | ||
| 777 | static void v9fs_mux_free_request(struct v9fs_mux_data *m, struct v9fs_req *req) | 788 | static void p9_mux_free_request(struct p9_conn *m, struct p9_req *req) |
| 778 | { | 789 | { |
| 779 | v9fs_mux_put_tag(m, req->tag); | 790 | p9_mux_put_tag(m, req->tag); |
| 780 | kfree(req); | 791 | kfree(req); |
| 781 | } | 792 | } |
| 782 | 793 | ||
| 783 | static void v9fs_mux_flush_cb(struct v9fs_req *freq, void *a) | 794 | static void p9_mux_flush_cb(struct p9_req *freq, void *a) |
| 784 | { | 795 | { |
| 785 | v9fs_mux_req_callback cb; | 796 | p9_conn_req_callback cb; |
| 786 | int tag; | 797 | int tag; |
| 787 | struct v9fs_mux_data *m; | 798 | struct p9_conn *m; |
| 788 | struct v9fs_req *req, *rreq, *rptr; | 799 | struct p9_req *req, *rreq, *rptr; |
| 789 | 800 | ||
| 790 | m = a; | 801 | m = a; |
| 791 | dprintk(DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m, | 802 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m, |
| 792 | freq->tcall, freq->rcall, freq->err, | 803 | freq->tcall, freq->rcall, freq->err, |
| 793 | freq->tcall->params.tflush.oldtag); | 804 | freq->tcall->params.tflush.oldtag); |
| 794 | 805 | ||
| @@ -820,22 +831,23 @@ static void v9fs_mux_flush_cb(struct v9fs_req *freq, void *a) | |||
| 820 | 831 | ||
| 821 | kfree(freq->tcall); | 832 | kfree(freq->tcall); |
| 822 | kfree(freq->rcall); | 833 | kfree(freq->rcall); |
| 823 | v9fs_mux_free_request(m, freq); | 834 | p9_mux_free_request(m, freq); |
| 824 | } | 835 | } |
| 825 | 836 | ||
| 826 | static int | 837 | static int |
| 827 | v9fs_mux_flush_request(struct v9fs_mux_data *m, struct v9fs_req *req) | 838 | p9_mux_flush_request(struct p9_conn *m, struct p9_req *req) |
| 828 | { | 839 | { |
| 829 | struct v9fs_fcall *fc; | 840 | struct p9_fcall *fc; |
| 830 | struct v9fs_req *rreq, *rptr; | 841 | struct p9_req *rreq, *rptr; |
| 831 | 842 | ||
| 832 | dprintk(DEBUG_MUX, "mux %p req %p tag %d\n", m, req, req->tag); | 843 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p req %p tag %d\n", m, req, req->tag); |
| 833 | 844 | ||
| 834 | /* if a response was received for a request, do nothing */ | 845 | /* if a response was received for a request, do nothing */ |
| 835 | spin_lock(&req->lock); | 846 | spin_lock(&req->lock); |
| 836 | if (req->rcall || req->err) { | 847 | if (req->rcall || req->err) { |
| 837 | spin_unlock(&req->lock); | 848 | spin_unlock(&req->lock); |
| 838 | dprintk(DEBUG_MUX, "mux %p req %p response already received\n", m, req); | 849 | P9_DPRINTK(P9_DEBUG_MUX, |
| 850 | "mux %p req %p response already received\n", m, req); | ||
| 839 | return 0; | 851 | return 0; |
| 840 | } | 852 | } |
| 841 | 853 | ||
| @@ -846,7 +858,8 @@ v9fs_mux_flush_request(struct v9fs_mux_data *m, struct v9fs_req *req) | |||
| 846 | /* if the request is not sent yet, just remove it from the list */ | 858 | /* if the request is not sent yet, just remove it from the list */ |
| 847 | list_for_each_entry_safe(rreq, rptr, &m->unsent_req_list, req_list) { | 859 | list_for_each_entry_safe(rreq, rptr, &m->unsent_req_list, req_list) { |
| 848 | if (rreq->tag == req->tag) { | 860 | if (rreq->tag == req->tag) { |
| 849 | dprintk(DEBUG_MUX, "mux %p req %p request is not sent yet\n", m, req); | 861 | P9_DPRINTK(P9_DEBUG_MUX, |
| 862 | "mux %p req %p request is not sent yet\n", m, req); | ||
| 850 | list_del(&rreq->req_list); | 863 | list_del(&rreq->req_list); |
| 851 | req->flush = Flushed; | 864 | req->flush = Flushed; |
| 852 | spin_unlock(&m->lock); | 865 | spin_unlock(&m->lock); |
| @@ -858,42 +871,42 @@ v9fs_mux_flush_request(struct v9fs_mux_data *m, struct v9fs_req *req) | |||
| 858 | spin_unlock(&m->lock); | 871 | spin_unlock(&m->lock); |
| 859 | 872 | ||
| 860 | clear_thread_flag(TIF_SIGPENDING); | 873 | clear_thread_flag(TIF_SIGPENDING); |
| 861 | fc = v9fs_create_tflush(req->tag); | 874 | fc = p9_create_tflush(req->tag); |
| 862 | v9fs_send_request(m, fc, v9fs_mux_flush_cb, m); | 875 | p9_send_request(m, fc, p9_mux_flush_cb, m); |
| 863 | return 1; | 876 | return 1; |
| 864 | } | 877 | } |
| 865 | 878 | ||
| 866 | static void | 879 | static void |
| 867 | v9fs_mux_rpc_cb(struct v9fs_req *req, void *a) | 880 | p9_conn_rpc_cb(struct p9_req *req, void *a) |
| 868 | { | 881 | { |
| 869 | struct v9fs_mux_rpc *r; | 882 | struct p9_mux_rpc *r; |
| 870 | 883 | ||
| 871 | dprintk(DEBUG_MUX, "req %p r %p\n", req, a); | 884 | P9_DPRINTK(P9_DEBUG_MUX, "req %p r %p\n", req, a); |
| 872 | r = a; | 885 | r = a; |
| 873 | r->rcall = req->rcall; | 886 | r->rcall = req->rcall; |
| 874 | r->err = req->err; | 887 | r->err = req->err; |
| 875 | 888 | ||
| 876 | if (req->flush!=None && !req->err) | 889 | if (req->flush != None && !req->err) |
| 877 | r->err = -ERESTARTSYS; | 890 | r->err = -ERESTARTSYS; |
| 878 | 891 | ||
| 879 | wake_up(&r->wqueue); | 892 | wake_up(&r->wqueue); |
| 880 | } | 893 | } |
| 881 | 894 | ||
| 882 | /** | 895 | /** |
| 883 | * v9fs_mux_rpc - sends 9P request and waits until a response is available. | 896 | * p9_mux_rpc - sends 9P request and waits until a response is available. |
| 884 | * The function can be interrupted. | 897 | * The function can be interrupted. |
| 885 | * @m: mux data | 898 | * @m: mux data |
| 886 | * @tc: request to be sent | 899 | * @tc: request to be sent |
| 887 | * @rc: pointer where a pointer to the response is stored | 900 | * @rc: pointer where a pointer to the response is stored |
| 888 | */ | 901 | */ |
| 889 | int | 902 | int |
| 890 | v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, | 903 | p9_conn_rpc(struct p9_conn *m, struct p9_fcall *tc, |
| 891 | struct v9fs_fcall **rc) | 904 | struct p9_fcall **rc) |
| 892 | { | 905 | { |
| 893 | int err, sigpending; | 906 | int err, sigpending; |
| 894 | unsigned long flags; | 907 | unsigned long flags; |
| 895 | struct v9fs_req *req; | 908 | struct p9_req *req; |
| 896 | struct v9fs_mux_rpc r; | 909 | struct p9_mux_rpc r; |
| 897 | 910 | ||
| 898 | r.err = 0; | 911 | r.err = 0; |
| 899 | r.tcall = tc; | 912 | r.tcall = tc; |
| @@ -910,10 +923,10 @@ v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, | |||
| 910 | clear_thread_flag(TIF_SIGPENDING); | 923 | clear_thread_flag(TIF_SIGPENDING); |
| 911 | } | 924 | } |
| 912 | 925 | ||
| 913 | req = v9fs_send_request(m, tc, v9fs_mux_rpc_cb, &r); | 926 | req = p9_send_request(m, tc, p9_conn_rpc_cb, &r); |
| 914 | if (IS_ERR(req)) { | 927 | if (IS_ERR(req)) { |
| 915 | err = PTR_ERR(req); | 928 | err = PTR_ERR(req); |
| 916 | dprintk(DEBUG_MUX, "error %d\n", err); | 929 | P9_DPRINTK(P9_DEBUG_MUX, "error %d\n", err); |
| 917 | return err; | 930 | return err; |
| 918 | } | 931 | } |
| 919 | 932 | ||
| @@ -921,15 +934,16 @@ v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, | |||
| 921 | if (r.err < 0) | 934 | if (r.err < 0) |
| 922 | err = r.err; | 935 | err = r.err; |
| 923 | 936 | ||
| 924 | if (err == -ERESTARTSYS && m->trans->status == Connected && m->err == 0) { | 937 | if (err == -ERESTARTSYS && m->trans->status == Connected |
| 925 | if (v9fs_mux_flush_request(m, req)) { | 938 | && m->err == 0) { |
| 939 | if (p9_mux_flush_request(m, req)) { | ||
| 926 | /* wait until we get response of the flush message */ | 940 | /* wait until we get response of the flush message */ |
| 927 | do { | 941 | do { |
| 928 | clear_thread_flag(TIF_SIGPENDING); | 942 | clear_thread_flag(TIF_SIGPENDING); |
| 929 | err = wait_event_interruptible(r.wqueue, | 943 | err = wait_event_interruptible(r.wqueue, |
| 930 | r.rcall || r.err); | 944 | r.rcall || r.err); |
| 931 | } while (!r.rcall && !r.err && err==-ERESTARTSYS && | 945 | } while (!r.rcall && !r.err && err == -ERESTARTSYS && |
| 932 | m->trans->status==Connected && !m->err); | 946 | m->trans->status == Connected && !m->err); |
| 933 | 947 | ||
| 934 | err = -ERESTARTSYS; | 948 | err = -ERESTARTSYS; |
| 935 | } | 949 | } |
| @@ -947,50 +961,52 @@ v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, | |||
| 947 | else | 961 | else |
| 948 | kfree(r.rcall); | 962 | kfree(r.rcall); |
| 949 | 963 | ||
| 950 | v9fs_mux_free_request(m, req); | 964 | p9_mux_free_request(m, req); |
| 951 | if (err > 0) | 965 | if (err > 0) |
| 952 | err = -EIO; | 966 | err = -EIO; |
| 953 | 967 | ||
| 954 | return err; | 968 | return err; |
| 955 | } | 969 | } |
| 970 | EXPORT_SYMBOL(p9_conn_rpc); | ||
| 956 | 971 | ||
| 957 | #if 0 | 972 | #ifdef P9_NONBLOCK |
| 958 | /** | 973 | /** |
| 959 | * v9fs_mux_rpcnb - sends 9P request without waiting for response. | 974 | * p9_conn_rpcnb - sends 9P request without waiting for response. |
| 960 | * @m: mux data | 975 | * @m: mux data |
| 961 | * @tc: request to be sent | 976 | * @tc: request to be sent |
| 962 | * @cb: callback function to be called when response arrives | 977 | * @cb: callback function to be called when response arrives |
| 963 | * @cba: value to pass to the callback function | 978 | * @cba: value to pass to the callback function |
| 964 | */ | 979 | */ |
| 965 | int v9fs_mux_rpcnb(struct v9fs_mux_data *m, struct v9fs_fcall *tc, | 980 | int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc, |
| 966 | v9fs_mux_req_callback cb, void *a) | 981 | p9_conn_req_callback cb, void *a) |
| 967 | { | 982 | { |
| 968 | int err; | 983 | int err; |
| 969 | struct v9fs_req *req; | 984 | struct p9_req *req; |
| 970 | 985 | ||
| 971 | req = v9fs_send_request(m, tc, cb, a); | 986 | req = p9_send_request(m, tc, cb, a); |
| 972 | if (IS_ERR(req)) { | 987 | if (IS_ERR(req)) { |
| 973 | err = PTR_ERR(req); | 988 | err = PTR_ERR(req); |
| 974 | dprintk(DEBUG_MUX, "error %d\n", err); | 989 | P9_DPRINTK(P9_DEBUG_MUX, "error %d\n", err); |
| 975 | return PTR_ERR(req); | 990 | return PTR_ERR(req); |
| 976 | } | 991 | } |
| 977 | 992 | ||
| 978 | dprintk(DEBUG_MUX, "mux %p tc %p tag %d\n", m, tc, req->tag); | 993 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p tc %p tag %d\n", m, tc, req->tag); |
| 979 | return 0; | 994 | return 0; |
| 980 | } | 995 | } |
| 981 | #endif /* 0 */ | 996 | EXPORT_SYMBOL(p9_conn_rpcnb); |
| 997 | #endif /* P9_NONBLOCK */ | ||
| 982 | 998 | ||
| 983 | /** | 999 | /** |
| 984 | * v9fs_mux_cancel - cancel all pending requests with error | 1000 | * p9_conn_cancel - cancel all pending requests with error |
| 985 | * @m: mux data | 1001 | * @m: mux data |
| 986 | * @err: error code | 1002 | * @err: error code |
| 987 | */ | 1003 | */ |
| 988 | void v9fs_mux_cancel(struct v9fs_mux_data *m, int err) | 1004 | void p9_conn_cancel(struct p9_conn *m, int err) |
| 989 | { | 1005 | { |
| 990 | struct v9fs_req *req, *rtmp; | 1006 | struct p9_req *req, *rtmp; |
| 991 | LIST_HEAD(cancel_list); | 1007 | LIST_HEAD(cancel_list); |
| 992 | 1008 | ||
| 993 | dprintk(DEBUG_ERROR, "mux %p err %d\n", m, err); | 1009 | P9_DPRINTK(P9_DEBUG_ERROR, "mux %p err %d\n", m, err); |
| 994 | m->err = err; | 1010 | m->err = err; |
| 995 | spin_lock(&m->lock); | 1011 | spin_lock(&m->lock); |
| 996 | list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) { | 1012 | list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) { |
| @@ -1014,20 +1030,21 @@ void v9fs_mux_cancel(struct v9fs_mux_data *m, int err) | |||
| 1014 | 1030 | ||
| 1015 | wake_up(&m->equeue); | 1031 | wake_up(&m->equeue); |
| 1016 | } | 1032 | } |
| 1033 | EXPORT_SYMBOL(p9_conn_cancel); | ||
| 1017 | 1034 | ||
| 1018 | static u16 v9fs_mux_get_tag(struct v9fs_mux_data *m) | 1035 | static u16 p9_mux_get_tag(struct p9_conn *m) |
| 1019 | { | 1036 | { |
| 1020 | int tag; | 1037 | int tag; |
| 1021 | 1038 | ||
| 1022 | tag = v9fs_get_idpool(&m->tagpool); | 1039 | tag = p9_idpool_get(m->tagpool); |
| 1023 | if (tag < 0) | 1040 | if (tag < 0) |
| 1024 | return V9FS_NOTAG; | 1041 | return P9_NOTAG; |
| 1025 | else | 1042 | else |
| 1026 | return (u16) tag; | 1043 | return (u16) tag; |
| 1027 | } | 1044 | } |
| 1028 | 1045 | ||
| 1029 | static void v9fs_mux_put_tag(struct v9fs_mux_data *m, u16 tag) | 1046 | static void p9_mux_put_tag(struct p9_conn *m, u16 tag) |
| 1030 | { | 1047 | { |
| 1031 | if (tag != V9FS_NOTAG && v9fs_check_idpool(tag, &m->tagpool)) | 1048 | if (tag != P9_NOTAG && p9_idpool_check(tag, m->tagpool)) |
| 1032 | v9fs_put_idpool(tag, &m->tagpool); | 1049 | p9_idpool_put(tag, m->tagpool); |
| 1033 | } | 1050 | } |
diff --git a/net/9p/sysctl.c b/net/9p/sysctl.c new file mode 100644 index 000000000000..e7fe706ab95a --- /dev/null +++ b/net/9p/sysctl.c | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | /* | ||
| 2 | * net/9p/sysctl.c | ||
| 3 | * | ||
| 4 | * 9P sysctl interface | ||
| 5 | * | ||
| 6 | * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 | ||
| 10 | * as published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to: | ||
| 19 | * Free Software Foundation | ||
| 20 | * 51 Franklin Street, Fifth Floor | ||
| 21 | * Boston, MA 02111-1301 USA | ||
| 22 | * | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/kernel.h> | ||
| 26 | #include <linux/mm.h> | ||
| 27 | #include <linux/sysctl.h> | ||
| 28 | #include <linux/init.h> | ||
| 29 | #include <net/9p/9p.h> | ||
| 30 | |||
| 31 | enum { | ||
| 32 | P9_SYSCTL_NET = 487, | ||
| 33 | P9_SYSCTL_DEBUG = 1, | ||
| 34 | }; | ||
| 35 | |||
| 36 | static ctl_table p9_table[] = { | ||
| 37 | #ifdef CONFIG_NET_9P_DEBUG | ||
| 38 | { | ||
| 39 | .ctl_name = P9_SYSCTL_DEBUG, | ||
| 40 | .procname = "debug", | ||
| 41 | .data = &p9_debug_level, | ||
| 42 | .maxlen = sizeof(int), | ||
| 43 | .mode = 0644, | ||
| 44 | .proc_handler = &proc_dointvec | ||
| 45 | }, | ||
| 46 | #endif | ||
| 47 | { .ctl_name = 0 }, | ||
| 48 | }; | ||
| 49 | |||
| 50 | static ctl_table p9_net_table[] = { | ||
| 51 | { | ||
| 52 | .ctl_name = P9_SYSCTL_NET, | ||
| 53 | .procname = "9p", | ||
| 54 | .maxlen = 0, | ||
| 55 | .mode = 0555, | ||
| 56 | .child = p9_table, | ||
| 57 | }, | ||
| 58 | { .ctl_name = 0 }, | ||
| 59 | }; | ||
| 60 | |||
| 61 | static ctl_table p9_ctl_table[] = { | ||
| 62 | { | ||
| 63 | .ctl_name = CTL_NET, | ||
| 64 | .procname = "net", | ||
| 65 | .maxlen = 0, | ||
| 66 | .mode = 0555, | ||
| 67 | .child = p9_net_table, | ||
| 68 | }, | ||
| 69 | { .ctl_name = 0 }, | ||
| 70 | }; | ||
| 71 | |||
| 72 | static struct ctl_table_header *p9_table_header; | ||
| 73 | |||
| 74 | int __init p9_sysctl_register(void) | ||
| 75 | { | ||
| 76 | p9_table_header = register_sysctl_table(p9_ctl_table); | ||
| 77 | if (!p9_table_header) | ||
| 78 | return -ENOMEM; | ||
| 79 | |||
| 80 | return 0; | ||
| 81 | } | ||
| 82 | |||
| 83 | void __exit p9_sysctl_unregister(void) | ||
| 84 | { | ||
| 85 | unregister_sysctl_table(p9_table_header); | ||
| 86 | } | ||
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c new file mode 100644 index 000000000000..fd636e94358f --- /dev/null +++ b/net/9p/trans_fd.c | |||
| @@ -0,0 +1,363 @@ | |||
| 1 | /* | ||
| 2 | * linux/fs/9p/trans_fd.c | ||
| 3 | * | ||
| 4 | * Fd transport layer. Includes deprecated socket layer. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2006 by Russ Cox <rsc@swtch.com> | ||
| 7 | * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net> | ||
| 8 | * Copyright (C) 2004-2005 by Eric Van Hensbergen <ericvh@gmail.com> | ||
| 9 | * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 | ||
| 13 | * as published by the Free Software Foundation. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to: | ||
| 22 | * Free Software Foundation | ||
| 23 | * 51 Franklin Street, Fifth Floor | ||
| 24 | * Boston, MA 02111-1301 USA | ||
| 25 | * | ||
| 26 | */ | ||
| 27 | |||
| 28 | #include <linux/in.h> | ||
| 29 | #include <linux/module.h> | ||
| 30 | #include <linux/net.h> | ||
| 31 | #include <linux/ipv6.h> | ||
| 32 | #include <linux/errno.h> | ||
| 33 | #include <linux/kernel.h> | ||
| 34 | #include <linux/un.h> | ||
| 35 | #include <linux/uaccess.h> | ||
| 36 | #include <linux/inet.h> | ||
| 37 | #include <linux/idr.h> | ||
| 38 | #include <linux/file.h> | ||
| 39 | #include <net/9p/9p.h> | ||
| 40 | #include <net/9p/transport.h> | ||
| 41 | |||
| 42 | #define P9_PORT 564 | ||
| 43 | |||
| 44 | struct p9_trans_fd { | ||
| 45 | struct file *rd; | ||
| 46 | struct file *wr; | ||
| 47 | }; | ||
| 48 | |||
| 49 | static int p9_socket_open(struct p9_transport *trans, struct socket *csocket); | ||
| 50 | static int p9_fd_open(struct p9_transport *trans, int rfd, int wfd); | ||
| 51 | static int p9_fd_read(struct p9_transport *trans, void *v, int len); | ||
| 52 | static int p9_fd_write(struct p9_transport *trans, void *v, int len); | ||
| 53 | static unsigned int p9_fd_poll(struct p9_transport *trans, | ||
| 54 | struct poll_table_struct *pt); | ||
| 55 | static void p9_fd_close(struct p9_transport *trans); | ||
| 56 | |||
| 57 | struct p9_transport *p9_trans_create_tcp(const char *addr, int port) | ||
| 58 | { | ||
| 59 | int err; | ||
| 60 | struct p9_transport *trans; | ||
| 61 | struct socket *csocket; | ||
| 62 | struct sockaddr_in sin_server; | ||
| 63 | |||
| 64 | csocket = NULL; | ||
| 65 | trans = kmalloc(sizeof(struct p9_transport), GFP_KERNEL); | ||
| 66 | if (!trans) | ||
| 67 | return ERR_PTR(-ENOMEM); | ||
| 68 | |||
| 69 | trans->write = p9_fd_write; | ||
| 70 | trans->read = p9_fd_read; | ||
| 71 | trans->close = p9_fd_close; | ||
| 72 | trans->poll = p9_fd_poll; | ||
| 73 | |||
| 74 | sin_server.sin_family = AF_INET; | ||
| 75 | sin_server.sin_addr.s_addr = in_aton(addr); | ||
| 76 | sin_server.sin_port = htons(port); | ||
| 77 | sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket); | ||
| 78 | |||
| 79 | if (!csocket) { | ||
| 80 | P9_EPRINTK(KERN_ERR, "p9_trans_tcp: problem creating socket\n"); | ||
| 81 | err = -EIO; | ||
| 82 | goto error; | ||
| 83 | } | ||
| 84 | |||
| 85 | err = csocket->ops->connect(csocket, | ||
| 86 | (struct sockaddr *)&sin_server, | ||
| 87 | sizeof(struct sockaddr_in), 0); | ||
| 88 | if (err < 0) { | ||
| 89 | P9_EPRINTK(KERN_ERR, | ||
| 90 | "p9_trans_tcp: problem connecting socket to %s\n", | ||
| 91 | addr); | ||
| 92 | goto error; | ||
| 93 | } | ||
| 94 | |||
| 95 | err = p9_socket_open(trans, csocket); | ||
| 96 | if (err < 0) | ||
| 97 | goto error; | ||
| 98 | |||
| 99 | return trans; | ||
| 100 | |||
| 101 | error: | ||
| 102 | if (csocket) | ||
| 103 | sock_release(csocket); | ||
| 104 | |||
| 105 | kfree(trans); | ||
| 106 | return ERR_PTR(err); | ||
| 107 | } | ||
| 108 | EXPORT_SYMBOL(p9_trans_create_tcp); | ||
| 109 | |||
| 110 | struct p9_transport *p9_trans_create_unix(const char *addr) | ||
| 111 | { | ||
| 112 | int err; | ||
| 113 | struct socket *csocket; | ||
| 114 | struct sockaddr_un sun_server; | ||
| 115 | struct p9_transport *trans; | ||
| 116 | |||
| 117 | csocket = NULL; | ||
| 118 | trans = kmalloc(sizeof(struct p9_transport), GFP_KERNEL); | ||
| 119 | if (!trans) | ||
| 120 | return ERR_PTR(-ENOMEM); | ||
| 121 | |||
| 122 | trans->write = p9_fd_write; | ||
| 123 | trans->read = p9_fd_read; | ||
| 124 | trans->close = p9_fd_close; | ||
| 125 | trans->poll = p9_fd_poll; | ||
| 126 | |||
| 127 | if (strlen(addr) > UNIX_PATH_MAX) { | ||
| 128 | P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n", | ||
| 129 | addr); | ||
| 130 | err = -ENAMETOOLONG; | ||
| 131 | goto error; | ||
| 132 | } | ||
| 133 | |||
| 134 | sun_server.sun_family = PF_UNIX; | ||
| 135 | strcpy(sun_server.sun_path, addr); | ||
| 136 | sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); | ||
| 137 | err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, | ||
| 138 | sizeof(struct sockaddr_un) - 1, 0); | ||
| 139 | if (err < 0) { | ||
| 140 | P9_EPRINTK(KERN_ERR, | ||
| 141 | "p9_trans_unix: problem connecting socket: %s: %d\n", | ||
| 142 | addr, err); | ||
| 143 | goto error; | ||
| 144 | } | ||
| 145 | |||
| 146 | err = p9_socket_open(trans, csocket); | ||
| 147 | if (err < 0) | ||
| 148 | goto error; | ||
| 149 | |||
| 150 | return trans; | ||
| 151 | |||
| 152 | error: | ||
| 153 | if (csocket) | ||
| 154 | sock_release(csocket); | ||
| 155 | |||
| 156 | kfree(trans); | ||
| 157 | return ERR_PTR(err); | ||
| 158 | } | ||
| 159 | EXPORT_SYMBOL(p9_trans_create_unix); | ||
| 160 | |||
| 161 | struct p9_transport *p9_trans_create_fd(int rfd, int wfd) | ||
| 162 | { | ||
| 163 | int err; | ||
| 164 | struct p9_transport *trans; | ||
| 165 | |||
| 166 | if (rfd == ~0 || wfd == ~0) { | ||
| 167 | printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n"); | ||
| 168 | return ERR_PTR(-ENOPROTOOPT); | ||
| 169 | } | ||
| 170 | |||
| 171 | trans = kmalloc(sizeof(struct p9_transport), GFP_KERNEL); | ||
| 172 | if (!trans) | ||
| 173 | return ERR_PTR(-ENOMEM); | ||
| 174 | |||
| 175 | trans->write = p9_fd_write; | ||
| 176 | trans->read = p9_fd_read; | ||
| 177 | trans->close = p9_fd_close; | ||
| 178 | trans->poll = p9_fd_poll; | ||
| 179 | |||
| 180 | err = p9_fd_open(trans, rfd, wfd); | ||
| 181 | if (err < 0) | ||
| 182 | goto error; | ||
| 183 | |||
| 184 | return trans; | ||
| 185 | |||
| 186 | error: | ||
| 187 | kfree(trans); | ||
| 188 | return ERR_PTR(err); | ||
| 189 | } | ||
| 190 | EXPORT_SYMBOL(p9_trans_create_fd); | ||
| 191 | |||
| 192 | static int p9_socket_open(struct p9_transport *trans, struct socket *csocket) | ||
| 193 | { | ||
| 194 | int fd, ret; | ||
| 195 | |||
| 196 | csocket->sk->sk_allocation = GFP_NOIO; | ||
| 197 | fd = sock_map_fd(csocket); | ||
| 198 | if (fd < 0) { | ||
| 199 | P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to map fd\n"); | ||
| 200 | return fd; | ||
| 201 | } | ||
| 202 | |||
| 203 | ret = p9_fd_open(trans, fd, fd); | ||
| 204 | if (ret < 0) { | ||
| 205 | P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to open fd\n"); | ||
| 206 | sockfd_put(csocket); | ||
| 207 | return ret; | ||
| 208 | } | ||
| 209 | |||
| 210 | ((struct p9_trans_fd *)trans->priv)->rd->f_flags |= O_NONBLOCK; | ||
| 211 | |||
| 212 | return 0; | ||
| 213 | } | ||
| 214 | |||
| 215 | static int p9_fd_open(struct p9_transport *trans, int rfd, int wfd) | ||
| 216 | { | ||
| 217 | struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd), | ||
| 218 | GFP_KERNEL); | ||
| 219 | if (!ts) | ||
| 220 | return -ENOMEM; | ||
| 221 | |||
| 222 | ts->rd = fget(rfd); | ||
| 223 | ts->wr = fget(wfd); | ||
| 224 | if (!ts->rd || !ts->wr) { | ||
| 225 | if (ts->rd) | ||
| 226 | fput(ts->rd); | ||
| 227 | if (ts->wr) | ||
| 228 | fput(ts->wr); | ||
| 229 | kfree(ts); | ||
| 230 | return -EIO; | ||
| 231 | } | ||
| 232 | |||
| 233 | trans->priv = ts; | ||
| 234 | trans->status = Connected; | ||
| 235 | |||
| 236 | return 0; | ||
| 237 | } | ||
| 238 | |||
| 239 | /** | ||
| 240 | * p9_fd_read- read from a fd | ||
| 241 | * @v9ses: session information | ||
| 242 | * @v: buffer to receive data into | ||
| 243 | * @len: size of receive buffer | ||
| 244 | * | ||
| 245 | */ | ||
| 246 | static int p9_fd_read(struct p9_transport *trans, void *v, int len) | ||
| 247 | { | ||
| 248 | int ret; | ||
| 249 | struct p9_trans_fd *ts = NULL; | ||
| 250 | |||
| 251 | if (trans && trans->status != Disconnected) | ||
| 252 | ts = trans->priv; | ||
| 253 | |||
| 254 | if (!ts) | ||
| 255 | return -EREMOTEIO; | ||
| 256 | |||
| 257 | if (!(ts->rd->f_flags & O_NONBLOCK)) | ||
| 258 | P9_DPRINTK(P9_DEBUG_ERROR, "blocking read ...\n"); | ||
| 259 | |||
| 260 | ret = kernel_read(ts->rd, ts->rd->f_pos, v, len); | ||
| 261 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) | ||
| 262 | trans->status = Disconnected; | ||
| 263 | return ret; | ||
| 264 | } | ||
| 265 | |||
| 266 | /** | ||
| 267 | * p9_fd_write - write to a socket | ||
| 268 | * @v9ses: session information | ||
| 269 | * @v: buffer to send data from | ||
| 270 | * @len: size of send buffer | ||
| 271 | * | ||
| 272 | */ | ||
| 273 | static int p9_fd_write(struct p9_transport *trans, void *v, int len) | ||
| 274 | { | ||
| 275 | int ret; | ||
| 276 | mm_segment_t oldfs; | ||
| 277 | struct p9_trans_fd *ts = NULL; | ||
| 278 | |||
| 279 | if (trans && trans->status != Disconnected) | ||
| 280 | ts = trans->priv; | ||
| 281 | |||
| 282 | if (!ts) | ||
| 283 | return -EREMOTEIO; | ||
| 284 | |||
| 285 | if (!(ts->wr->f_flags & O_NONBLOCK)) | ||
| 286 | P9_DPRINTK(P9_DEBUG_ERROR, "blocking write ...\n"); | ||
| 287 | |||
| 288 | oldfs = get_fs(); | ||
| 289 | set_fs(get_ds()); | ||
| 290 | /* The cast to a user pointer is valid due to the set_fs() */ | ||
| 291 | ret = vfs_write(ts->wr, (void __user *)v, len, &ts->wr->f_pos); | ||
| 292 | set_fs(oldfs); | ||
| 293 | |||
| 294 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) | ||
| 295 | trans->status = Disconnected; | ||
| 296 | return ret; | ||
| 297 | } | ||
| 298 | |||
| 299 | static unsigned int | ||
| 300 | p9_fd_poll(struct p9_transport *trans, struct poll_table_struct *pt) | ||
| 301 | { | ||
| 302 | int ret, n; | ||
| 303 | struct p9_trans_fd *ts = NULL; | ||
| 304 | mm_segment_t oldfs; | ||
| 305 | |||
| 306 | if (trans && trans->status == Connected) | ||
| 307 | ts = trans->priv; | ||
| 308 | |||
| 309 | if (!ts) | ||
| 310 | return -EREMOTEIO; | ||
| 311 | |||
| 312 | if (!ts->rd->f_op || !ts->rd->f_op->poll) | ||
| 313 | return -EIO; | ||
| 314 | |||
| 315 | if (!ts->wr->f_op || !ts->wr->f_op->poll) | ||
| 316 | return -EIO; | ||
| 317 | |||
| 318 | oldfs = get_fs(); | ||
| 319 | set_fs(get_ds()); | ||
| 320 | |||
| 321 | ret = ts->rd->f_op->poll(ts->rd, pt); | ||
| 322 | if (ret < 0) | ||
| 323 | goto end; | ||
| 324 | |||
| 325 | if (ts->rd != ts->wr) { | ||
| 326 | n = ts->wr->f_op->poll(ts->wr, pt); | ||
| 327 | if (n < 0) { | ||
| 328 | ret = n; | ||
| 329 | goto end; | ||
| 330 | } | ||
| 331 | ret = (ret & ~POLLOUT) | (n & ~POLLIN); | ||
| 332 | } | ||
| 333 | |||
| 334 | end: | ||
| 335 | set_fs(oldfs); | ||
| 336 | return ret; | ||
| 337 | } | ||
| 338 | |||
| 339 | /** | ||
| 340 | * p9_sock_close - shutdown socket | ||
| 341 | * @trans: private socket structure | ||
| 342 | * | ||
| 343 | */ | ||
| 344 | static void p9_fd_close(struct p9_transport *trans) | ||
| 345 | { | ||
| 346 | struct p9_trans_fd *ts; | ||
| 347 | |||
| 348 | if (!trans) | ||
| 349 | return; | ||
| 350 | |||
| 351 | ts = xchg(&trans->priv, NULL); | ||
| 352 | |||
| 353 | if (!ts) | ||
| 354 | return; | ||
| 355 | |||
| 356 | trans->status = Disconnected; | ||
| 357 | if (ts->rd) | ||
| 358 | fput(ts->rd); | ||
| 359 | if (ts->wr) | ||
| 360 | fput(ts->wr); | ||
| 361 | kfree(ts); | ||
| 362 | } | ||
| 363 | |||
diff --git a/net/9p/util.c b/net/9p/util.c new file mode 100644 index 000000000000..22077b79395d --- /dev/null +++ b/net/9p/util.c | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | /* | ||
| 2 | * net/9p/util.c | ||
| 3 | * | ||
| 4 | * This file contains some helper functions | ||
| 5 | * | ||
| 6 | * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> | ||
| 7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
| 8 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 | ||
| 12 | * as published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to: | ||
| 21 | * Free Software Foundation | ||
| 22 | * 51 Franklin Street, Fifth Floor | ||
| 23 | * Boston, MA 02111-1301 USA | ||
| 24 | * | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/errno.h> | ||
| 29 | #include <linux/fs.h> | ||
| 30 | #include <linux/sched.h> | ||
| 31 | #include <linux/parser.h> | ||
| 32 | #include <linux/idr.h> | ||
| 33 | #include <net/9p/9p.h> | ||
| 34 | |||
| 35 | struct p9_idpool { | ||
| 36 | struct semaphore lock; | ||
| 37 | struct idr pool; | ||
| 38 | }; | ||
| 39 | |||
| 40 | struct p9_idpool *p9_idpool_create(void) | ||
| 41 | { | ||
| 42 | struct p9_idpool *p; | ||
| 43 | |||
| 44 | p = kmalloc(sizeof(struct p9_idpool), GFP_KERNEL); | ||
| 45 | if (!p) | ||
| 46 | return ERR_PTR(-ENOMEM); | ||
| 47 | |||
| 48 | init_MUTEX(&p->lock); | ||
| 49 | idr_init(&p->pool); | ||
| 50 | |||
| 51 | return p; | ||
| 52 | } | ||
| 53 | EXPORT_SYMBOL(p9_idpool_create); | ||
| 54 | |||
| 55 | void p9_idpool_destroy(struct p9_idpool *p) | ||
| 56 | { | ||
| 57 | idr_destroy(&p->pool); | ||
| 58 | kfree(p); | ||
| 59 | } | ||
| 60 | EXPORT_SYMBOL(p9_idpool_destroy); | ||
| 61 | |||
| 62 | /** | ||
| 63 | * p9_idpool_get - allocate numeric id from pool | ||
| 64 | * @p - pool to allocate from | ||
| 65 | * | ||
| 66 | * XXX - This seems to be an awful generic function, should it be in idr.c with | ||
| 67 | * the lock included in struct idr? | ||
| 68 | */ | ||
| 69 | |||
| 70 | int p9_idpool_get(struct p9_idpool *p) | ||
| 71 | { | ||
| 72 | int i = 0; | ||
| 73 | int error; | ||
| 74 | |||
| 75 | retry: | ||
| 76 | if (idr_pre_get(&p->pool, GFP_KERNEL) == 0) | ||
| 77 | return 0; | ||
| 78 | |||
| 79 | if (down_interruptible(&p->lock) == -EINTR) { | ||
| 80 | P9_EPRINTK(KERN_WARNING, "Interrupted while locking\n"); | ||
| 81 | return -1; | ||
| 82 | } | ||
| 83 | |||
| 84 | /* no need to store exactly p, we just need something non-null */ | ||
| 85 | error = idr_get_new(&p->pool, p, &i); | ||
| 86 | up(&p->lock); | ||
| 87 | |||
| 88 | if (error == -EAGAIN) | ||
| 89 | goto retry; | ||
| 90 | else if (error) | ||
| 91 | return -1; | ||
| 92 | |||
| 93 | return i; | ||
| 94 | } | ||
| 95 | EXPORT_SYMBOL(p9_idpool_get); | ||
| 96 | |||
| 97 | /** | ||
| 98 | * p9_idpool_put - release numeric id from pool | ||
| 99 | * @p - pool to allocate from | ||
| 100 | * | ||
| 101 | * XXX - This seems to be an awful generic function, should it be in idr.c with | ||
| 102 | * the lock included in struct idr? | ||
| 103 | */ | ||
| 104 | |||
| 105 | void p9_idpool_put(int id, struct p9_idpool *p) | ||
| 106 | { | ||
| 107 | if (down_interruptible(&p->lock) == -EINTR) { | ||
| 108 | P9_EPRINTK(KERN_WARNING, "Interrupted while locking\n"); | ||
| 109 | return; | ||
| 110 | } | ||
| 111 | idr_remove(&p->pool, id); | ||
| 112 | up(&p->lock); | ||
| 113 | } | ||
| 114 | EXPORT_SYMBOL(p9_idpool_put); | ||
| 115 | |||
| 116 | /** | ||
| 117 | * p9_idpool_check - check if the specified id is available | ||
| 118 | * @id - id to check | ||
| 119 | * @p - pool | ||
| 120 | */ | ||
| 121 | int p9_idpool_check(int id, struct p9_idpool *p) | ||
| 122 | { | ||
| 123 | return idr_find(&p->pool, id) != NULL; | ||
| 124 | } | ||
| 125 | EXPORT_SYMBOL(p9_idpool_check); | ||
diff --git a/net/Kconfig b/net/Kconfig index f3de72978ab6..cdba08ca2efe 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
| @@ -227,6 +227,7 @@ source "net/ieee80211/Kconfig" | |||
| 227 | endmenu | 227 | endmenu |
| 228 | 228 | ||
| 229 | source "net/rfkill/Kconfig" | 229 | source "net/rfkill/Kconfig" |
| 230 | source "net/9p/Kconfig" | ||
| 230 | 231 | ||
| 231 | endif # if NET | 232 | endif # if NET |
| 232 | endmenu # Networking | 233 | endmenu # Networking |
diff --git a/net/Makefile b/net/Makefile index a87a88963432..bbe7d2a41486 100644 --- a/net/Makefile +++ b/net/Makefile | |||
| @@ -51,6 +51,7 @@ obj-$(CONFIG_TIPC) += tipc/ | |||
| 51 | obj-$(CONFIG_NETLABEL) += netlabel/ | 51 | obj-$(CONFIG_NETLABEL) += netlabel/ |
| 52 | obj-$(CONFIG_IUCV) += iucv/ | 52 | obj-$(CONFIG_IUCV) += iucv/ |
| 53 | obj-$(CONFIG_RFKILL) += rfkill/ | 53 | obj-$(CONFIG_RFKILL) += rfkill/ |
| 54 | obj-$(CONFIG_NET_9P) += 9p/ | ||
| 54 | 55 | ||
| 55 | ifeq ($(CONFIG_NET),y) | 56 | ifeq ($(CONFIG_NET),y) |
| 56 | obj-$(CONFIG_SYSCTL) += sysctl_net.o | 57 | obj-$(CONFIG_SYSCTL) += sysctl_net.o |
