Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs:
9p: fix a race condition bug in umount which caused a segfault
9p: re-enable mount time debug option
9p: cache meta-data when cache=loose
net/9p: set error to EREMOTEIO if trans->write returns zero
net/9p: change net/9p module name to 9pnet
9p: Reorganization of 9p file system code

+3444 -3130
-375
fs/9p/9p.h
··· 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);
-6
fs/9p/Makefile
··· 1 1 obj-$(CONFIG_9P_FS) := 9p.o 2 2 3 3 9p-objs := \ 4 - trans_fd.o \ 5 - mux.o \ 6 - fcall.o \ 7 - conv.o \ 8 4 vfs_super.o \ 9 5 vfs_inode.o \ 10 6 vfs_addr.o \ 11 7 vfs_file.o \ 12 8 vfs_dir.o \ 13 9 vfs_dentry.o \ 14 - error.o \ 15 10 v9fs.o \ 16 11 fid.o \ 17 - fcprint.o 18 12
+243 -185
fs/9p/conv.c net/9p/conv.c
··· 1 1 /* 2 - * linux/fs/9p/conv.c 2 + * net/9p/conv.c 3 3 * 4 4 * 9P protocol conversion functions 5 5 * ··· 29 29 #include <linux/fs.h> 30 30 #include <linux/sched.h> 31 31 #include <linux/idr.h> 32 - #include <asm/uaccess.h> 33 - #include "debug.h" 34 - #include "v9fs.h" 35 - #include "9p.h" 36 - #include "conv.h" 32 + #include <linux/uaccess.h> 33 + #include <net/9p/9p.h> 37 34 38 35 /* 39 36 * Buffer to help with string parsing ··· 56 59 { 57 60 if (buf->p + len > buf->ep) { 58 61 if (buf->p < buf->ep) { 59 - eprintk(KERN_ERR, "buffer overflow: want %d has %d\n", 60 - len, (int)(buf->ep - buf->p)); 62 + P9_EPRINTK(KERN_ERR, 63 + "buffer overflow: want %d has %d\n", len, 64 + (int)(buf->ep - buf->p)); 61 65 dump_stack(); 62 66 buf->p = buf->ep + 1; 63 67 } ··· 181 183 return ret; 182 184 } 183 185 184 - static void buf_get_str(struct cbuf *buf, struct v9fs_str *vstr) 186 + static void buf_get_str(struct cbuf *buf, struct p9_str *vstr) 185 187 { 186 188 vstr->len = buf_get_int16(buf); 187 189 if (!buf_check_overflow(buf) && buf_check_size(buf, vstr->len)) { ··· 193 195 } 194 196 } 195 197 196 - static void buf_get_qid(struct cbuf *bufp, struct v9fs_qid *qid) 198 + static void buf_get_qid(struct cbuf *bufp, struct p9_qid *qid) 197 199 { 198 200 qid->type = buf_get_int8(bufp); 199 201 qid->version = buf_get_int32(bufp); ··· 201 203 } 202 204 203 205 /** 204 - * v9fs_size_wstat - calculate the size of a variable length stat struct 206 + * p9_size_wstat - calculate the size of a variable length stat struct 205 207 * @stat: metadata (stat) structure 206 - * @extended: non-zero if 9P2000.u 208 + * @dotu: non-zero if 9P2000.u 207 209 * 208 210 */ 209 211 210 - static int v9fs_size_wstat(struct v9fs_wstat *wstat, int extended) 212 + static int p9_size_wstat(struct p9_wstat *wstat, int dotu) 211 213 { 212 214 int size = 0; 213 215 214 216 if (wstat == NULL) { 215 - eprintk(KERN_ERR, "v9fs_size_stat: got a NULL stat pointer\n"); 217 + P9_EPRINTK(KERN_ERR, "p9_size_stat: got a NULL stat pointer\n"); 216 218 return 0; 217 219 } 218 220 ··· 237 239 if (wstat->muid) 238 240 size += strlen(wstat->muid); 239 241 240 - if (extended) { 242 + if (dotu) { 241 243 size += 4 + /* n_uid[4] */ 242 244 4 + /* n_gid[4] */ 243 245 4 + /* n_muid[4] */ ··· 253 255 * buf_get_stat - safely decode a recieved metadata (stat) structure 254 256 * @bufp: buffer to deserialize 255 257 * @stat: metadata (stat) structure 256 - * @extended: non-zero if 9P2000.u 258 + * @dotu: non-zero if 9P2000.u 257 259 * 258 260 */ 259 261 260 262 static void 261 - buf_get_stat(struct cbuf *bufp, struct v9fs_stat *stat, int extended) 263 + buf_get_stat(struct cbuf *bufp, struct p9_stat *stat, int dotu) 262 264 { 263 265 stat->size = buf_get_int16(bufp); 264 266 stat->type = buf_get_int16(bufp); ··· 275 277 buf_get_str(bufp, &stat->gid); 276 278 buf_get_str(bufp, &stat->muid); 277 279 278 - if (extended) { 280 + if (dotu) { 279 281 buf_get_str(bufp, &stat->extension); 280 282 stat->n_uid = buf_get_int32(bufp); 281 283 stat->n_gid = buf_get_int32(bufp); ··· 284 286 } 285 287 286 288 /** 287 - * v9fs_deserialize_stat - decode a received metadata structure 289 + * p9_deserialize_stat - decode a received metadata structure 288 290 * @buf: buffer to deserialize 289 291 * @buflen: length of received buffer 290 292 * @stat: metadata structure to decode into 291 - * @extended: non-zero if 9P2000.u 293 + * @dotu: non-zero if 9P2000.u 292 294 * 293 295 * Note: stat will point to the buf region. 294 296 */ 295 297 296 298 int 297 - v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat, 298 - int extended) 299 + p9_deserialize_stat(void *buf, u32 buflen, struct p9_stat *stat, 300 + int dotu) 299 301 { 300 302 struct cbuf buffer; 301 303 struct cbuf *bufp = &buffer; ··· 303 305 304 306 buf_init(bufp, buf, buflen); 305 307 p = bufp->p; 306 - buf_get_stat(bufp, stat, extended); 308 + buf_get_stat(bufp, stat, dotu); 307 309 308 310 if (buf_check_overflow(bufp)) 309 311 return 0; 310 312 else 311 313 return bufp->p - p; 312 314 } 315 + EXPORT_SYMBOL(p9_deserialize_stat); 313 316 314 317 /** 315 318 * deserialize_fcall - unmarshal a response ··· 318 319 * @buflen: length of received buffer 319 320 * @rcall: fcall structure to populate 320 321 * @rcalllen: length of fcall structure to populate 321 - * @extended: non-zero if 9P2000.u 322 + * @dotu: non-zero if 9P2000.u 322 323 * 323 324 */ 324 325 325 326 int 326 - v9fs_deserialize_fcall(void *buf, u32 buflen, struct v9fs_fcall *rcall, 327 - int extended) 327 + p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *rcall, 328 + int dotu) 328 329 { 329 330 330 331 struct cbuf buffer; ··· 337 338 rcall->id = buf_get_int8(bufp); 338 339 rcall->tag = buf_get_int16(bufp); 339 340 340 - dprintk(DEBUG_CONV, "size %d id %d tag %d\n", rcall->size, rcall->id, 341 - rcall->tag); 341 + P9_DPRINTK(P9_DEBUG_CONV, "size %d id %d tag %d\n", rcall->size, 342 + rcall->id, rcall->tag); 342 343 343 344 switch (rcall->id) { 344 345 default: 345 - eprintk(KERN_ERR, "unknown message type: %d\n", rcall->id); 346 + P9_EPRINTK(KERN_ERR, "unknown message type: %d\n", rcall->id); 346 347 return -EPROTO; 347 - case RVERSION: 348 + case P9_RVERSION: 348 349 rcall->params.rversion.msize = buf_get_int32(bufp); 349 350 buf_get_str(bufp, &rcall->params.rversion.version); 350 351 break; 351 - case RFLUSH: 352 + case P9_RFLUSH: 352 353 break; 353 - case RATTACH: 354 + case P9_RATTACH: 354 355 rcall->params.rattach.qid.type = buf_get_int8(bufp); 355 356 rcall->params.rattach.qid.version = buf_get_int32(bufp); 356 357 rcall->params.rattach.qid.path = buf_get_int64(bufp); 357 358 break; 358 - case RWALK: 359 + case P9_RWALK: 359 360 rcall->params.rwalk.nwqid = buf_get_int16(bufp); 360 - if (rcall->params.rwalk.nwqid > V9FS_MAXWELEM) { 361 - eprintk(KERN_ERR, "Rwalk with more than %d qids: %d\n", 362 - V9FS_MAXWELEM, rcall->params.rwalk.nwqid); 361 + if (rcall->params.rwalk.nwqid > P9_MAXWELEM) { 362 + P9_EPRINTK(KERN_ERR, 363 + "Rwalk with more than %d qids: %d\n", 364 + P9_MAXWELEM, rcall->params.rwalk.nwqid); 363 365 return -EPROTO; 364 366 } 365 367 366 368 for (i = 0; i < rcall->params.rwalk.nwqid; i++) 367 369 buf_get_qid(bufp, &rcall->params.rwalk.wqids[i]); 368 370 break; 369 - case ROPEN: 371 + case P9_ROPEN: 370 372 buf_get_qid(bufp, &rcall->params.ropen.qid); 371 373 rcall->params.ropen.iounit = buf_get_int32(bufp); 372 374 break; 373 - case RCREATE: 375 + case P9_RCREATE: 374 376 buf_get_qid(bufp, &rcall->params.rcreate.qid); 375 377 rcall->params.rcreate.iounit = buf_get_int32(bufp); 376 378 break; 377 - case RREAD: 379 + case P9_RREAD: 378 380 rcall->params.rread.count = buf_get_int32(bufp); 379 381 rcall->params.rread.data = bufp->p; 380 382 buf_check_size(bufp, rcall->params.rread.count); 381 383 break; 382 - case RWRITE: 384 + case P9_RWRITE: 383 385 rcall->params.rwrite.count = buf_get_int32(bufp); 384 386 break; 385 - case RCLUNK: 387 + case P9_RCLUNK: 386 388 break; 387 - case RREMOVE: 389 + case P9_RREMOVE: 388 390 break; 389 - case RSTAT: 391 + case P9_RSTAT: 390 392 buf_get_int16(bufp); 391 - buf_get_stat(bufp, &rcall->params.rstat.stat, extended); 393 + buf_get_stat(bufp, &rcall->params.rstat.stat, dotu); 392 394 break; 393 - case RWSTAT: 395 + case P9_RWSTAT: 394 396 break; 395 - case RERROR: 397 + case P9_RERROR: 396 398 buf_get_str(bufp, &rcall->params.rerror.error); 397 - if (extended) 399 + if (dotu) 398 400 rcall->params.rerror.errno = buf_get_int16(bufp); 399 401 break; 400 402 } 401 403 402 404 if (buf_check_overflow(bufp)) { 403 - dprintk(DEBUG_ERROR, "buffer overflow\n"); 405 + P9_DPRINTK(P9_DEBUG_ERROR, "buffer overflow\n"); 404 406 return -EIO; 405 407 } 406 408 407 409 return bufp->p - bufp->sp; 408 410 } 411 + EXPORT_SYMBOL(p9_deserialize_fcall); 409 412 410 - static inline void v9fs_put_int8(struct cbuf *bufp, u8 val, u8 * p) 413 + static inline void p9_put_int8(struct cbuf *bufp, u8 val, u8 * p) 411 414 { 412 415 *p = val; 413 416 buf_put_int8(bufp, val); 414 417 } 415 418 416 - static inline void v9fs_put_int16(struct cbuf *bufp, u16 val, u16 * p) 419 + static inline void p9_put_int16(struct cbuf *bufp, u16 val, u16 * p) 417 420 { 418 421 *p = val; 419 422 buf_put_int16(bufp, val); 420 423 } 421 424 422 - static inline void v9fs_put_int32(struct cbuf *bufp, u32 val, u32 * p) 425 + static inline void p9_put_int32(struct cbuf *bufp, u32 val, u32 * p) 423 426 { 424 427 *p = val; 425 428 buf_put_int32(bufp, val); 426 429 } 427 430 428 - static inline void v9fs_put_int64(struct cbuf *bufp, u64 val, u64 * p) 431 + static inline void p9_put_int64(struct cbuf *bufp, u64 val, u64 * p) 429 432 { 430 433 *p = val; 431 434 buf_put_int64(bufp, val); 432 435 } 433 436 434 437 static void 435 - v9fs_put_str(struct cbuf *bufp, char *data, struct v9fs_str *str) 438 + p9_put_str(struct cbuf *bufp, char *data, struct p9_str *str) 436 439 { 437 440 int len; 438 441 char *s; ··· 452 451 } 453 452 454 453 static int 455 - v9fs_put_user_data(struct cbuf *bufp, const char __user * data, int count, 454 + p9_put_data(struct cbuf *bufp, const char *data, int count, 455 + unsigned char **pdata) 456 + { 457 + *pdata = buf_alloc(bufp, count); 458 + memmove(*pdata, data, count); 459 + return count; 460 + } 461 + 462 + static int 463 + p9_put_user_data(struct cbuf *bufp, const char __user *data, int count, 456 464 unsigned char **pdata) 457 465 { 458 466 *pdata = buf_alloc(bufp, count); ··· 469 459 } 470 460 471 461 static void 472 - v9fs_put_wstat(struct cbuf *bufp, struct v9fs_wstat *wstat, 473 - struct v9fs_stat *stat, int statsz, int extended) 462 + p9_put_wstat(struct cbuf *bufp, struct p9_wstat *wstat, 463 + struct p9_stat *stat, int statsz, int dotu) 474 464 { 475 - v9fs_put_int16(bufp, statsz, &stat->size); 476 - v9fs_put_int16(bufp, wstat->type, &stat->type); 477 - v9fs_put_int32(bufp, wstat->dev, &stat->dev); 478 - v9fs_put_int8(bufp, wstat->qid.type, &stat->qid.type); 479 - v9fs_put_int32(bufp, wstat->qid.version, &stat->qid.version); 480 - v9fs_put_int64(bufp, wstat->qid.path, &stat->qid.path); 481 - v9fs_put_int32(bufp, wstat->mode, &stat->mode); 482 - v9fs_put_int32(bufp, wstat->atime, &stat->atime); 483 - v9fs_put_int32(bufp, wstat->mtime, &stat->mtime); 484 - v9fs_put_int64(bufp, wstat->length, &stat->length); 465 + p9_put_int16(bufp, statsz, &stat->size); 466 + p9_put_int16(bufp, wstat->type, &stat->type); 467 + p9_put_int32(bufp, wstat->dev, &stat->dev); 468 + p9_put_int8(bufp, wstat->qid.type, &stat->qid.type); 469 + p9_put_int32(bufp, wstat->qid.version, &stat->qid.version); 470 + p9_put_int64(bufp, wstat->qid.path, &stat->qid.path); 471 + p9_put_int32(bufp, wstat->mode, &stat->mode); 472 + p9_put_int32(bufp, wstat->atime, &stat->atime); 473 + p9_put_int32(bufp, wstat->mtime, &stat->mtime); 474 + p9_put_int64(bufp, wstat->length, &stat->length); 485 475 486 - v9fs_put_str(bufp, wstat->name, &stat->name); 487 - v9fs_put_str(bufp, wstat->uid, &stat->uid); 488 - v9fs_put_str(bufp, wstat->gid, &stat->gid); 489 - v9fs_put_str(bufp, wstat->muid, &stat->muid); 476 + p9_put_str(bufp, wstat->name, &stat->name); 477 + p9_put_str(bufp, wstat->uid, &stat->uid); 478 + p9_put_str(bufp, wstat->gid, &stat->gid); 479 + p9_put_str(bufp, wstat->muid, &stat->muid); 490 480 491 - if (extended) { 492 - v9fs_put_str(bufp, wstat->extension, &stat->extension); 493 - v9fs_put_int32(bufp, wstat->n_uid, &stat->n_uid); 494 - v9fs_put_int32(bufp, wstat->n_gid, &stat->n_gid); 495 - v9fs_put_int32(bufp, wstat->n_muid, &stat->n_muid); 481 + if (dotu) { 482 + p9_put_str(bufp, wstat->extension, &stat->extension); 483 + p9_put_int32(bufp, wstat->n_uid, &stat->n_uid); 484 + p9_put_int32(bufp, wstat->n_gid, &stat->n_gid); 485 + p9_put_int32(bufp, wstat->n_muid, &stat->n_muid); 496 486 } 497 487 } 498 488 499 - static struct v9fs_fcall * 500 - v9fs_create_common(struct cbuf *bufp, u32 size, u8 id) 489 + static struct p9_fcall * 490 + p9_create_common(struct cbuf *bufp, u32 size, u8 id) 501 491 { 502 - struct v9fs_fcall *fc; 492 + struct p9_fcall *fc; 503 493 504 494 size += 4 + 1 + 2; /* size[4] id[1] tag[2] */ 505 - fc = kmalloc(sizeof(struct v9fs_fcall) + size, GFP_KERNEL); 495 + fc = kmalloc(sizeof(struct p9_fcall) + size, GFP_KERNEL); 506 496 if (!fc) 507 497 return ERR_PTR(-ENOMEM); 508 498 509 499 fc->sdata = (char *)fc + sizeof(*fc); 510 500 511 501 buf_init(bufp, (char *)fc->sdata, size); 512 - v9fs_put_int32(bufp, size, &fc->size); 513 - v9fs_put_int8(bufp, id, &fc->id); 514 - v9fs_put_int16(bufp, V9FS_NOTAG, &fc->tag); 502 + p9_put_int32(bufp, size, &fc->size); 503 + p9_put_int8(bufp, id, &fc->id); 504 + p9_put_int16(bufp, P9_NOTAG, &fc->tag); 515 505 516 506 return fc; 517 507 } 518 508 519 - void v9fs_set_tag(struct v9fs_fcall *fc, u16 tag) 509 + void p9_set_tag(struct p9_fcall *fc, u16 tag) 520 510 { 521 511 fc->tag = tag; 522 512 *(__le16 *) (fc->sdata + 5) = cpu_to_le16(tag); 523 513 } 514 + EXPORT_SYMBOL(p9_set_tag); 524 515 525 - struct v9fs_fcall *v9fs_create_tversion(u32 msize, char *version) 516 + struct p9_fcall *p9_create_tversion(u32 msize, char *version) 526 517 { 527 518 int size; 528 - struct v9fs_fcall *fc; 519 + struct p9_fcall *fc; 529 520 struct cbuf buffer; 530 521 struct cbuf *bufp = &buffer; 531 522 532 523 size = 4 + 2 + strlen(version); /* msize[4] version[s] */ 533 - fc = v9fs_create_common(bufp, size, TVERSION); 524 + fc = p9_create_common(bufp, size, P9_TVERSION); 534 525 if (IS_ERR(fc)) 535 526 goto error; 536 527 537 - v9fs_put_int32(bufp, msize, &fc->params.tversion.msize); 538 - v9fs_put_str(bufp, version, &fc->params.tversion.version); 528 + p9_put_int32(bufp, msize, &fc->params.tversion.msize); 529 + p9_put_str(bufp, version, &fc->params.tversion.version); 539 530 540 531 if (buf_check_overflow(bufp)) { 541 532 kfree(fc); 542 533 fc = ERR_PTR(-ENOMEM); 543 534 } 544 - error: 535 + error: 545 536 return fc; 546 537 } 538 + EXPORT_SYMBOL(p9_create_tversion); 547 539 548 - #if 0 549 - struct v9fs_fcall *v9fs_create_tauth(u32 afid, char *uname, char *aname) 540 + struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname) 550 541 { 551 542 int size; 552 - struct v9fs_fcall *fc; 543 + struct p9_fcall *fc; 553 544 struct cbuf buffer; 554 545 struct cbuf *bufp = &buffer; 555 546 556 - size = 4 + 2 + strlen(uname) + 2 + strlen(aname); /* afid[4] uname[s] aname[s] */ 557 - fc = v9fs_create_common(bufp, size, TAUTH); 547 + /* afid[4] uname[s] aname[s] */ 548 + size = 4 + 2 + strlen(uname) + 2 + strlen(aname); 549 + fc = p9_create_common(bufp, size, P9_TAUTH); 558 550 if (IS_ERR(fc)) 559 551 goto error; 560 552 561 - v9fs_put_int32(bufp, afid, &fc->params.tauth.afid); 562 - v9fs_put_str(bufp, uname, &fc->params.tauth.uname); 563 - v9fs_put_str(bufp, aname, &fc->params.tauth.aname); 553 + p9_put_int32(bufp, afid, &fc->params.tauth.afid); 554 + p9_put_str(bufp, uname, &fc->params.tauth.uname); 555 + p9_put_str(bufp, aname, &fc->params.tauth.aname); 564 556 565 557 if (buf_check_overflow(bufp)) { 566 558 kfree(fc); 567 559 fc = ERR_PTR(-ENOMEM); 568 560 } 569 - error: 561 + error: 570 562 return fc; 571 563 } 572 - #endif /* 0 */ 564 + EXPORT_SYMBOL(p9_create_tauth); 573 565 574 - struct v9fs_fcall * 575 - v9fs_create_tattach(u32 fid, u32 afid, char *uname, char *aname) 566 + struct p9_fcall * 567 + p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname) 576 568 { 577 569 int size; 578 - struct v9fs_fcall *fc; 570 + struct p9_fcall *fc; 579 571 struct cbuf buffer; 580 572 struct cbuf *bufp = &buffer; 581 573 582 - size = 4 + 4 + 2 + strlen(uname) + 2 + strlen(aname); /* fid[4] afid[4] uname[s] aname[s] */ 583 - fc = v9fs_create_common(bufp, size, TATTACH); 574 + /* fid[4] afid[4] uname[s] aname[s] */ 575 + size = 4 + 4 + 2 + strlen(uname) + 2 + strlen(aname); 576 + fc = p9_create_common(bufp, size, P9_TATTACH); 584 577 if (IS_ERR(fc)) 585 578 goto error; 586 579 587 - v9fs_put_int32(bufp, fid, &fc->params.tattach.fid); 588 - v9fs_put_int32(bufp, afid, &fc->params.tattach.afid); 589 - v9fs_put_str(bufp, uname, &fc->params.tattach.uname); 590 - v9fs_put_str(bufp, aname, &fc->params.tattach.aname); 580 + p9_put_int32(bufp, fid, &fc->params.tattach.fid); 581 + p9_put_int32(bufp, afid, &fc->params.tattach.afid); 582 + p9_put_str(bufp, uname, &fc->params.tattach.uname); 583 + p9_put_str(bufp, aname, &fc->params.tattach.aname); 591 584 592 - error: 585 + error: 593 586 return fc; 594 587 } 588 + EXPORT_SYMBOL(p9_create_tattach); 595 589 596 - struct v9fs_fcall *v9fs_create_tflush(u16 oldtag) 590 + struct p9_fcall *p9_create_tflush(u16 oldtag) 597 591 { 598 592 int size; 599 - struct v9fs_fcall *fc; 593 + struct p9_fcall *fc; 600 594 struct cbuf buffer; 601 595 struct cbuf *bufp = &buffer; 602 596 603 597 size = 2; /* oldtag[2] */ 604 - fc = v9fs_create_common(bufp, size, TFLUSH); 598 + fc = p9_create_common(bufp, size, P9_TFLUSH); 605 599 if (IS_ERR(fc)) 606 600 goto error; 607 601 608 - v9fs_put_int16(bufp, oldtag, &fc->params.tflush.oldtag); 602 + p9_put_int16(bufp, oldtag, &fc->params.tflush.oldtag); 609 603 610 604 if (buf_check_overflow(bufp)) { 611 605 kfree(fc); 612 606 fc = ERR_PTR(-ENOMEM); 613 607 } 614 - error: 608 + error: 615 609 return fc; 616 610 } 611 + EXPORT_SYMBOL(p9_create_tflush); 617 612 618 - struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, 613 + struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname, 619 614 char **wnames) 620 615 { 621 616 int i, size; 622 - struct v9fs_fcall *fc; 617 + struct p9_fcall *fc; 623 618 struct cbuf buffer; 624 619 struct cbuf *bufp = &buffer; 625 620 626 - if (nwname > V9FS_MAXWELEM) { 627 - dprintk(DEBUG_ERROR, "nwname > %d\n", V9FS_MAXWELEM); 621 + if (nwname > P9_MAXWELEM) { 622 + P9_DPRINTK(P9_DEBUG_ERROR, "nwname > %d\n", P9_MAXWELEM); 628 623 return NULL; 629 624 } 630 625 ··· 638 623 size += 2 + strlen(wnames[i]); /* wname[s] */ 639 624 } 640 625 641 - fc = v9fs_create_common(bufp, size, TWALK); 626 + fc = p9_create_common(bufp, size, P9_TWALK); 642 627 if (IS_ERR(fc)) 643 628 goto error; 644 629 645 - v9fs_put_int32(bufp, fid, &fc->params.twalk.fid); 646 - v9fs_put_int32(bufp, newfid, &fc->params.twalk.newfid); 647 - v9fs_put_int16(bufp, nwname, &fc->params.twalk.nwname); 630 + p9_put_int32(bufp, fid, &fc->params.twalk.fid); 631 + p9_put_int32(bufp, newfid, &fc->params.twalk.newfid); 632 + p9_put_int16(bufp, nwname, &fc->params.twalk.nwname); 648 633 for (i = 0; i < nwname; i++) { 649 - v9fs_put_str(bufp, wnames[i], &fc->params.twalk.wnames[i]); 634 + p9_put_str(bufp, wnames[i], &fc->params.twalk.wnames[i]); 650 635 } 651 636 652 637 if (buf_check_overflow(bufp)) { 653 638 kfree(fc); 654 639 fc = ERR_PTR(-ENOMEM); 655 640 } 656 - error: 641 + error: 657 642 return fc; 658 643 } 644 + EXPORT_SYMBOL(p9_create_twalk); 659 645 660 - struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode) 646 + struct p9_fcall *p9_create_topen(u32 fid, u8 mode) 661 647 { 662 648 int size; 663 - struct v9fs_fcall *fc; 649 + struct p9_fcall *fc; 664 650 struct cbuf buffer; 665 651 struct cbuf *bufp = &buffer; 666 652 667 653 size = 4 + 1; /* fid[4] mode[1] */ 668 - fc = v9fs_create_common(bufp, size, TOPEN); 654 + fc = p9_create_common(bufp, size, P9_TOPEN); 669 655 if (IS_ERR(fc)) 670 656 goto error; 671 657 672 - v9fs_put_int32(bufp, fid, &fc->params.topen.fid); 673 - v9fs_put_int8(bufp, mode, &fc->params.topen.mode); 658 + p9_put_int32(bufp, fid, &fc->params.topen.fid); 659 + p9_put_int8(bufp, mode, &fc->params.topen.mode); 674 660 675 661 if (buf_check_overflow(bufp)) { 676 662 kfree(fc); 677 663 fc = ERR_PTR(-ENOMEM); 678 664 } 679 - error: 665 + error: 680 666 return fc; 681 667 } 668 + EXPORT_SYMBOL(p9_create_topen); 682 669 683 - struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, 684 - char *extension, int extended) 670 + struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, 671 + char *extension, int dotu) 685 672 { 686 673 int size; 687 - struct v9fs_fcall *fc; 674 + struct p9_fcall *fc; 688 675 struct cbuf buffer; 689 676 struct cbuf *bufp = &buffer; 690 677 691 - size = 4 + 2 + strlen(name) + 4 + 1; /* fid[4] name[s] perm[4] mode[1] */ 692 - if (extended) { 678 + /* fid[4] name[s] perm[4] mode[1] */ 679 + size = 4 + 2 + strlen(name) + 4 + 1; 680 + if (dotu) { 693 681 size += 2 + /* extension[s] */ 694 682 (extension == NULL ? 0 : strlen(extension)); 695 683 } 696 684 697 - fc = v9fs_create_common(bufp, size, TCREATE); 685 + fc = p9_create_common(bufp, size, P9_TCREATE); 698 686 if (IS_ERR(fc)) 699 687 goto error; 700 688 701 - v9fs_put_int32(bufp, fid, &fc->params.tcreate.fid); 702 - v9fs_put_str(bufp, name, &fc->params.tcreate.name); 703 - v9fs_put_int32(bufp, perm, &fc->params.tcreate.perm); 704 - v9fs_put_int8(bufp, mode, &fc->params.tcreate.mode); 705 - if (extended) 706 - v9fs_put_str(bufp, extension, &fc->params.tcreate.extension); 689 + p9_put_int32(bufp, fid, &fc->params.tcreate.fid); 690 + p9_put_str(bufp, name, &fc->params.tcreate.name); 691 + p9_put_int32(bufp, perm, &fc->params.tcreate.perm); 692 + p9_put_int8(bufp, mode, &fc->params.tcreate.mode); 693 + if (dotu) 694 + p9_put_str(bufp, extension, &fc->params.tcreate.extension); 707 695 708 696 if (buf_check_overflow(bufp)) { 709 697 kfree(fc); 710 698 fc = ERR_PTR(-ENOMEM); 711 699 } 712 - error: 700 + error: 713 701 return fc; 714 702 } 703 + EXPORT_SYMBOL(p9_create_tcreate); 715 704 716 - struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count) 705 + struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count) 717 706 { 718 707 int size; 719 - struct v9fs_fcall *fc; 708 + struct p9_fcall *fc; 720 709 struct cbuf buffer; 721 710 struct cbuf *bufp = &buffer; 722 711 723 712 size = 4 + 8 + 4; /* fid[4] offset[8] count[4] */ 724 - fc = v9fs_create_common(bufp, size, TREAD); 713 + fc = p9_create_common(bufp, size, P9_TREAD); 725 714 if (IS_ERR(fc)) 726 715 goto error; 727 716 728 - v9fs_put_int32(bufp, fid, &fc->params.tread.fid); 729 - v9fs_put_int64(bufp, offset, &fc->params.tread.offset); 730 - v9fs_put_int32(bufp, count, &fc->params.tread.count); 717 + p9_put_int32(bufp, fid, &fc->params.tread.fid); 718 + p9_put_int64(bufp, offset, &fc->params.tread.offset); 719 + p9_put_int32(bufp, count, &fc->params.tread.count); 731 720 732 721 if (buf_check_overflow(bufp)) { 733 722 kfree(fc); 734 723 fc = ERR_PTR(-ENOMEM); 735 724 } 736 - error: 725 + error: 737 726 return fc; 738 727 } 728 + EXPORT_SYMBOL(p9_create_tread); 739 729 740 - struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count, 741 - const char __user * data) 730 + struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count, 731 + const char *data) 742 732 { 743 733 int size, err; 744 - struct v9fs_fcall *fc; 734 + struct p9_fcall *fc; 745 735 struct cbuf buffer; 746 736 struct cbuf *bufp = &buffer; 747 737 748 - size = 4 + 8 + 4 + count; /* fid[4] offset[8] count[4] data[count] */ 749 - fc = v9fs_create_common(bufp, size, TWRITE); 738 + /* fid[4] offset[8] count[4] data[count] */ 739 + size = 4 + 8 + 4 + count; 740 + fc = p9_create_common(bufp, size, P9_TWRITE); 750 741 if (IS_ERR(fc)) 751 742 goto error; 752 743 753 - v9fs_put_int32(bufp, fid, &fc->params.twrite.fid); 754 - v9fs_put_int64(bufp, offset, &fc->params.twrite.offset); 755 - v9fs_put_int32(bufp, count, &fc->params.twrite.count); 756 - err = v9fs_put_user_data(bufp, data, count, &fc->params.twrite.data); 744 + p9_put_int32(bufp, fid, &fc->params.twrite.fid); 745 + p9_put_int64(bufp, offset, &fc->params.twrite.offset); 746 + p9_put_int32(bufp, count, &fc->params.twrite.count); 747 + err = p9_put_data(bufp, data, count, &fc->params.twrite.data); 757 748 if (err) { 758 749 kfree(fc); 759 750 fc = ERR_PTR(err); ··· 769 748 kfree(fc); 770 749 fc = ERR_PTR(-ENOMEM); 771 750 } 772 - error: 751 + error: 773 752 return fc; 774 753 } 754 + EXPORT_SYMBOL(p9_create_twrite); 775 755 776 - struct v9fs_fcall *v9fs_create_tclunk(u32 fid) 756 + struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count, 757 + const char __user *data) 777 758 { 778 - int size; 779 - struct v9fs_fcall *fc; 759 + int size, err; 760 + struct p9_fcall *fc; 780 761 struct cbuf buffer; 781 762 struct cbuf *bufp = &buffer; 782 763 783 - size = 4; /* fid[4] */ 784 - fc = v9fs_create_common(bufp, size, TCLUNK); 764 + /* fid[4] offset[8] count[4] data[count] */ 765 + size = 4 + 8 + 4 + count; 766 + fc = p9_create_common(bufp, size, P9_TWRITE); 785 767 if (IS_ERR(fc)) 786 768 goto error; 787 769 788 - v9fs_put_int32(bufp, fid, &fc->params.tclunk.fid); 770 + p9_put_int32(bufp, fid, &fc->params.twrite.fid); 771 + p9_put_int64(bufp, offset, &fc->params.twrite.offset); 772 + p9_put_int32(bufp, count, &fc->params.twrite.count); 773 + err = p9_put_user_data(bufp, data, count, &fc->params.twrite.data); 774 + if (err) { 775 + kfree(fc); 776 + fc = ERR_PTR(err); 777 + } 789 778 790 779 if (buf_check_overflow(bufp)) { 791 780 kfree(fc); 792 781 fc = ERR_PTR(-ENOMEM); 793 782 } 794 - error: 783 + error: 795 784 return fc; 796 785 } 786 + EXPORT_SYMBOL(p9_create_twrite_u); 797 787 798 - struct v9fs_fcall *v9fs_create_tremove(u32 fid) 788 + struct p9_fcall *p9_create_tclunk(u32 fid) 799 789 { 800 790 int size; 801 - struct v9fs_fcall *fc; 791 + struct p9_fcall *fc; 802 792 struct cbuf buffer; 803 793 struct cbuf *bufp = &buffer; 804 794 805 795 size = 4; /* fid[4] */ 806 - fc = v9fs_create_common(bufp, size, TREMOVE); 796 + fc = p9_create_common(bufp, size, P9_TCLUNK); 807 797 if (IS_ERR(fc)) 808 798 goto error; 809 799 810 - v9fs_put_int32(bufp, fid, &fc->params.tremove.fid); 800 + p9_put_int32(bufp, fid, &fc->params.tclunk.fid); 811 801 812 802 if (buf_check_overflow(bufp)) { 813 803 kfree(fc); 814 804 fc = ERR_PTR(-ENOMEM); 815 805 } 816 - error: 806 + error: 817 807 return fc; 818 808 } 809 + EXPORT_SYMBOL(p9_create_tclunk); 819 810 820 - struct v9fs_fcall *v9fs_create_tstat(u32 fid) 811 + struct p9_fcall *p9_create_tremove(u32 fid) 821 812 { 822 813 int size; 823 - struct v9fs_fcall *fc; 814 + struct p9_fcall *fc; 824 815 struct cbuf buffer; 825 816 struct cbuf *bufp = &buffer; 826 817 827 818 size = 4; /* fid[4] */ 828 - fc = v9fs_create_common(bufp, size, TSTAT); 819 + fc = p9_create_common(bufp, size, P9_TREMOVE); 829 820 if (IS_ERR(fc)) 830 821 goto error; 831 822 832 - v9fs_put_int32(bufp, fid, &fc->params.tstat.fid); 823 + p9_put_int32(bufp, fid, &fc->params.tremove.fid); 833 824 834 825 if (buf_check_overflow(bufp)) { 835 826 kfree(fc); 836 827 fc = ERR_PTR(-ENOMEM); 837 828 } 838 - error: 829 + error: 839 830 return fc; 840 831 } 832 + EXPORT_SYMBOL(p9_create_tremove); 841 833 842 - struct v9fs_fcall *v9fs_create_twstat(u32 fid, struct v9fs_wstat *wstat, 843 - int extended) 834 + struct p9_fcall *p9_create_tstat(u32 fid) 835 + { 836 + int size; 837 + struct p9_fcall *fc; 838 + struct cbuf buffer; 839 + struct cbuf *bufp = &buffer; 840 + 841 + size = 4; /* fid[4] */ 842 + fc = p9_create_common(bufp, size, P9_TSTAT); 843 + if (IS_ERR(fc)) 844 + goto error; 845 + 846 + p9_put_int32(bufp, fid, &fc->params.tstat.fid); 847 + 848 + if (buf_check_overflow(bufp)) { 849 + kfree(fc); 850 + fc = ERR_PTR(-ENOMEM); 851 + } 852 + error: 853 + return fc; 854 + } 855 + EXPORT_SYMBOL(p9_create_tstat); 856 + 857 + struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat, 858 + int dotu) 844 859 { 845 860 int size, statsz; 846 - struct v9fs_fcall *fc; 861 + struct p9_fcall *fc; 847 862 struct cbuf buffer; 848 863 struct cbuf *bufp = &buffer; 849 864 850 - statsz = v9fs_size_wstat(wstat, extended); 865 + statsz = p9_size_wstat(wstat, dotu); 851 866 size = 4 + 2 + 2 + statsz; /* fid[4] stat[n] */ 852 - fc = v9fs_create_common(bufp, size, TWSTAT); 867 + fc = p9_create_common(bufp, size, P9_TWSTAT); 853 868 if (IS_ERR(fc)) 854 869 goto error; 855 870 856 - v9fs_put_int32(bufp, fid, &fc->params.twstat.fid); 871 + p9_put_int32(bufp, fid, &fc->params.twstat.fid); 857 872 buf_put_int16(bufp, statsz + 2); 858 - v9fs_put_wstat(bufp, wstat, &fc->params.twstat.stat, statsz, extended); 873 + p9_put_wstat(bufp, wstat, &fc->params.twstat.stat, statsz, dotu); 859 874 860 875 if (buf_check_overflow(bufp)) { 861 876 kfree(fc); 862 877 fc = ERR_PTR(-ENOMEM); 863 878 } 864 - error: 879 + error: 865 880 return fc; 866 881 } 882 + EXPORT_SYMBOL(p9_create_twstat);
-50
fs/9p/conv.h
··· 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);
-77
fs/9p/debug.h
··· 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 */
-93
fs/9p/error.c
··· 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 - }
+71 -8
fs/9p/error.h net/9p/error.c
··· 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 7 - * match UNIX strings and Plan 9 strings to unix error numbers. It is used 8 - * to preload the dynamic error table which can also track user-specific error 9 - * strings. 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. 10 9 * 11 10 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 12 11 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> ··· 27 28 * 28 29 */ 29 30 31 + #include <linux/module.h> 32 + #include <linux/list.h> 33 + #include <linux/jhash.h> 30 34 #include <linux/errno.h> 31 - #include <asm/errno.h> 35 + #include <net/9p/9p.h> 32 36 33 37 struct errormap { 34 38 char *name; ··· 176 174 {NULL, -1} 177 175 }; 178 176 179 - extern int v9fs_error_init(void); 177 + /** 178 + * p9_error_init - preload 179 + * @errstr: error string 180 + * 181 + */ 182 + 183 + int p9_error_init(void) 184 + { 185 + struct errormap *c; 186 + int bucket; 187 + 188 + /* initialize hash table */ 189 + for (bucket = 0; bucket < ERRHASHSZ; bucket++) 190 + INIT_HLIST_HEAD(&hash_errmap[bucket]); 191 + 192 + /* load initial error map into hash table */ 193 + for (c = errmap; c->name != NULL; c++) { 194 + c->namelen = strlen(c->name); 195 + bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ; 196 + INIT_HLIST_NODE(&c->list); 197 + hlist_add_head(&c->list, &hash_errmap[bucket]); 198 + } 199 + 200 + return 1; 201 + } 202 + EXPORT_SYMBOL(p9_error_init); 203 + 204 + /** 205 + * errstr2errno - convert error string to error number 206 + * @errstr: error string 207 + * 208 + */ 209 + 210 + int p9_errstr2errno(char *errstr, int len) 211 + { 212 + int errno; 213 + struct hlist_node *p; 214 + struct errormap *c; 215 + int bucket; 216 + 217 + errno = 0; 218 + p = NULL; 219 + c = NULL; 220 + bucket = jhash(errstr, len, 0) % ERRHASHSZ; 221 + hlist_for_each_entry(c, p, &hash_errmap[bucket], list) { 222 + if (c->namelen == len && !memcmp(c->name, errstr, len)) { 223 + errno = c->val; 224 + break; 225 + } 226 + } 227 + 228 + if (errno == 0) { 229 + /* TODO: if error isn't found, add it dynamically */ 230 + errstr[len] = 0; 231 + printk(KERN_ERR "%s: errstr :%s: not found\n", __FUNCTION__, 232 + errstr); 233 + errno = 1; 234 + } 235 + 236 + return -errno; 237 + } 238 + EXPORT_SYMBOL(p9_errstr2errno);
-427
fs/9p/fcall.c
··· 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 -
+100 -87
fs/9p/fcprint.c net/9p/fcprint.c
··· 1 1 /* 2 - * linux/fs/9p/fcprint.c 2 + * net/9p/fcprint.c 3 3 * 4 4 * Print 9P call. 5 5 * ··· 25 25 #include <linux/errno.h> 26 26 #include <linux/fs.h> 27 27 #include <linux/idr.h> 28 + #include <net/9p/9p.h> 28 29 29 - #include "debug.h" 30 - #include "v9fs.h" 31 - #include "9p.h" 32 - #include "mux.h" 30 + #ifdef CONFIG_NET_9P_DEBUG 33 31 34 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 35 int n; 38 36 char b[10]; 39 37 40 38 n = 0; 41 - if (q->type & V9FS_QTDIR) 39 + if (q->type & P9_QTDIR) 42 40 b[n++] = 'd'; 43 - if (q->type & V9FS_QTAPPEND) 41 + if (q->type & P9_QTAPPEND) 44 42 b[n++] = 'a'; 45 - if (q->type & V9FS_QTAUTH) 43 + if (q->type & P9_QTAUTH) 46 44 b[n++] = 'A'; 47 - if (q->type & V9FS_QTEXCL) 45 + if (q->type & P9_QTEXCL) 48 46 b[n++] = 'l'; 49 - if (q->type & V9FS_QTTMP) 47 + if (q->type & P9_QTTMP) 50 48 b[n++] = 't'; 51 - if (q->type & V9FS_QTSYMLINK) 49 + if (q->type & P9_QTSYMLINK) 52 50 b[n++] = 'L'; 53 51 b[n] = '\0'; 54 52 55 - return scnprintf(buf, buflen, "(%.16llx %x %s)", (long long int) q->path, 56 - q->version, b); 53 + return scnprintf(buf, buflen, "(%.16llx %x %s)", 54 + (long long int) q->path, q->version, b); 57 55 } 58 56 59 57 static int 60 - v9fs_printperm(char *buf, int buflen, int perm) 58 + p9_printperm(char *buf, int buflen, int perm) 61 59 { 62 60 int n; 63 61 char b[15]; 64 62 65 63 n = 0; 66 - if (perm & V9FS_DMDIR) 64 + if (perm & P9_DMDIR) 67 65 b[n++] = 'd'; 68 - if (perm & V9FS_DMAPPEND) 66 + if (perm & P9_DMAPPEND) 69 67 b[n++] = 'a'; 70 - if (perm & V9FS_DMAUTH) 68 + if (perm & P9_DMAUTH) 71 69 b[n++] = 'A'; 72 - if (perm & V9FS_DMEXCL) 70 + if (perm & P9_DMEXCL) 73 71 b[n++] = 'l'; 74 - if (perm & V9FS_DMTMP) 72 + if (perm & P9_DMTMP) 75 73 b[n++] = 't'; 76 - if (perm & V9FS_DMDEVICE) 74 + if (perm & P9_DMDEVICE) 77 75 b[n++] = 'D'; 78 - if (perm & V9FS_DMSOCKET) 76 + if (perm & P9_DMSOCKET) 79 77 b[n++] = 'S'; 80 - if (perm & V9FS_DMNAMEDPIPE) 78 + if (perm & P9_DMNAMEDPIPE) 81 79 b[n++] = 'P'; 82 - if (perm & V9FS_DMSYMLINK) 80 + if (perm & P9_DMSYMLINK) 83 81 b[n++] = 'L'; 84 82 b[n] = '\0'; 85 83 ··· 85 87 } 86 88 87 89 static int 88 - v9fs_printstat(char *buf, int buflen, struct v9fs_stat *st, int extended) 90 + p9_printstat(char *buf, int buflen, struct p9_stat *st, int extended) 89 91 { 90 92 int n; 91 93 ··· 103 105 n += scnprintf(buf+n, buflen-n, "(%d)", st->n_muid); 104 106 105 107 n += scnprintf(buf+n, buflen-n, " q "); 106 - n += v9fs_printqid(buf+n, buflen-n, &st->qid); 108 + n += p9_printqid(buf+n, buflen-n, &st->qid); 107 109 n += scnprintf(buf+n, buflen-n, " m "); 108 - n += v9fs_printperm(buf+n, buflen-n, st->mode); 110 + n += p9_printperm(buf+n, buflen-n, st->mode); 109 111 n += scnprintf(buf+n, buflen-n, " at %d mt %d l %lld", 110 112 st->atime, st->mtime, (long long int) st->length); 111 113 ··· 117 119 } 118 120 119 121 static int 120 - v9fs_dumpdata(char *buf, int buflen, u8 *data, int datalen) 122 + p9_dumpdata(char *buf, int buflen, u8 *data, int datalen) 121 123 { 122 124 int i, n; 123 125 ··· 137 139 } 138 140 139 141 static int 140 - v9fs_printdata(char *buf, int buflen, u8 *data, int datalen) 142 + p9_printdata(char *buf, int buflen, u8 *data, int datalen) 141 143 { 142 - return v9fs_dumpdata(buf, buflen, data, datalen<16?datalen:16); 144 + return p9_dumpdata(buf, buflen, data, datalen < 16?datalen:16); 143 145 } 144 146 145 147 int 146 - v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended) 148 + p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended) 147 149 { 148 150 int i, ret, type, tag; 149 151 ··· 155 157 156 158 ret = 0; 157 159 switch (type) { 158 - case TVERSION: 160 + case P9_TVERSION: 159 161 ret += scnprintf(buf+ret, buflen-ret, 160 - "Tversion tag %u msize %u version '%.*s'", tag, 161 - fc->params.tversion.msize, fc->params.tversion.version.len, 162 - fc->params.tversion.version.str); 162 + "Tversion tag %u msize %u version '%.*s'", tag, 163 + fc->params.tversion.msize, 164 + fc->params.tversion.version.len, 165 + fc->params.tversion.version.str); 163 166 break; 164 167 165 - case RVERSION: 168 + case P9_RVERSION: 166 169 ret += scnprintf(buf+ret, buflen-ret, 167 - "Rversion tag %u msize %u version '%.*s'", tag, 168 - fc->params.rversion.msize, fc->params.rversion.version.len, 169 - fc->params.rversion.version.str); 170 + "Rversion tag %u msize %u version '%.*s'", tag, 171 + fc->params.rversion.msize, 172 + fc->params.rversion.version.len, 173 + fc->params.rversion.version.str); 170 174 break; 171 175 172 - case TAUTH: 176 + case P9_TAUTH: 173 177 ret += scnprintf(buf+ret, buflen-ret, 174 178 "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag, 175 179 fc->params.tauth.afid, fc->params.tauth.uname.len, ··· 179 179 fc->params.tauth.aname.str); 180 180 break; 181 181 182 - case RAUTH: 182 + case P9_RAUTH: 183 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 185 break; 186 186 187 - case TATTACH: 187 + case P9_TATTACH: 188 188 ret += scnprintf(buf+ret, buflen-ret, 189 - "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'", 190 - tag, fc->params.tattach.fid, fc->params.tattach.afid, 191 - fc->params.tattach.uname.len, fc->params.tattach.uname.str, 192 - fc->params.tattach.aname.len, fc->params.tattach.aname.str); 189 + "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'", tag, 190 + fc->params.tattach.fid, fc->params.tattach.afid, 191 + fc->params.tattach.uname.len, fc->params.tattach.uname.str, 192 + fc->params.tattach.aname.len, fc->params.tattach.aname.str); 193 193 break; 194 194 195 - case RATTACH: 196 - ret += scnprintf(buf+ret, buflen-ret, "Rattach tag %u qid ", tag); 197 - v9fs_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid); 195 + case P9_RATTACH: 196 + ret += scnprintf(buf+ret, buflen-ret, "Rattach tag %u qid ", 197 + tag); 198 + p9_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid); 198 199 break; 199 200 200 - case RERROR: 201 - ret += scnprintf(buf+ret, buflen-ret, "Rerror tag %u ename '%.*s'", 202 - tag, fc->params.rerror.error.len, 203 - fc->params.rerror.error.str); 201 + case P9_RERROR: 202 + ret += scnprintf(buf+ret, buflen-ret, 203 + "Rerror tag %u ename '%.*s'", tag, 204 + fc->params.rerror.error.len, 205 + fc->params.rerror.error.str); 204 206 if (extended) 205 207 ret += scnprintf(buf+ret, buflen-ret, " ecode %d\n", 206 208 fc->params.rerror.errno); 207 209 break; 208 210 209 - case TFLUSH: 211 + case P9_TFLUSH: 210 212 ret += scnprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u", 211 213 tag, fc->params.tflush.oldtag); 212 214 break; 213 215 214 - case RFLUSH: 216 + case P9_RFLUSH: 215 217 ret += scnprintf(buf+ret, buflen-ret, "Rflush tag %u", tag); 216 218 break; 217 219 218 - case TWALK: 220 + case P9_TWALK: 219 221 ret += scnprintf(buf+ret, buflen-ret, 220 222 "Twalk tag %u fid %d newfid %d nwname %d", tag, 221 223 fc->params.twalk.fid, fc->params.twalk.newfid, 222 224 fc->params.twalk.nwname); 223 - for(i = 0; i < fc->params.twalk.nwname; i++) 224 - ret += scnprintf(buf+ret, buflen-ret," '%.*s'", 225 + for (i = 0; i < fc->params.twalk.nwname; i++) 226 + ret += scnprintf(buf+ret, buflen-ret, " '%.*s'", 225 227 fc->params.twalk.wnames[i].len, 226 228 fc->params.twalk.wnames[i].str); 227 229 break; 228 230 229 - case RWALK: 231 + case P9_RWALK: 230 232 ret += scnprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d", 231 233 tag, fc->params.rwalk.nwqid); 232 - for(i = 0; i < fc->params.rwalk.nwqid; i++) 233 - ret += v9fs_printqid(buf+ret, buflen-ret, 234 + for (i = 0; i < fc->params.rwalk.nwqid; i++) 235 + ret += p9_printqid(buf+ret, buflen-ret, 234 236 &fc->params.rwalk.wqids[i]); 235 237 break; 236 238 237 - case TOPEN: 239 + case P9_TOPEN: 238 240 ret += scnprintf(buf+ret, buflen-ret, 239 241 "Topen tag %u fid %d mode %d", tag, 240 242 fc->params.topen.fid, fc->params.topen.mode); 241 243 break; 242 244 243 - case ROPEN: 245 + case P9_ROPEN: 244 246 ret += scnprintf(buf+ret, buflen-ret, "Ropen tag %u", tag); 245 - ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid); 246 - ret += scnprintf(buf+ret, buflen-ret," iounit %d", 247 + ret += p9_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid); 248 + ret += scnprintf(buf+ret, buflen-ret, " iounit %d", 247 249 fc->params.ropen.iounit); 248 250 break; 249 251 250 - case TCREATE: 252 + case P9_TCREATE: 251 253 ret += scnprintf(buf+ret, buflen-ret, 252 254 "Tcreate tag %u fid %d name '%.*s' perm ", tag, 253 255 fc->params.tcreate.fid, fc->params.tcreate.name.len, 254 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 260 ret += scnprintf(buf+ret, buflen-ret, " mode %d", 258 261 fc->params.tcreate.mode); 259 262 break; 260 263 261 - case RCREATE: 264 + case P9_RCREATE: 262 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 268 ret += scnprintf(buf+ret, buflen-ret, " iounit %d", 265 269 fc->params.rcreate.iounit); 266 270 break; 267 271 268 - case TREAD: 272 + case P9_TREAD: 269 273 ret += scnprintf(buf+ret, buflen-ret, 270 274 "Tread tag %u fid %d offset %lld count %u", tag, 271 275 fc->params.tread.fid, ··· 277 273 fc->params.tread.count); 278 274 break; 279 275 280 - case RREAD: 276 + case P9_RREAD: 281 277 ret += scnprintf(buf+ret, buflen-ret, 282 278 "Rread tag %u count %u data ", tag, 283 279 fc->params.rread.count); 284 - ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.rread.data, 280 + ret += p9_printdata(buf+ret, buflen-ret, fc->params.rread.data, 285 281 fc->params.rread.count); 286 282 break; 287 283 288 - case TWRITE: 284 + case P9_TWRITE: 289 285 ret += scnprintf(buf+ret, buflen-ret, 290 286 "Twrite tag %u fid %d offset %lld count %u data ", 291 287 tag, fc->params.twrite.fid, 292 288 (long long int) fc->params.twrite.offset, 293 289 fc->params.twrite.count); 294 - ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.twrite.data, 290 + ret += p9_printdata(buf+ret, buflen-ret, fc->params.twrite.data, 295 291 fc->params.twrite.count); 296 292 break; 297 293 298 - case RWRITE: 294 + case P9_RWRITE: 299 295 ret += scnprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u", 300 296 tag, fc->params.rwrite.count); 301 297 break; 302 298 303 - case TCLUNK: 299 + case P9_TCLUNK: 304 300 ret += scnprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d", 305 301 tag, fc->params.tclunk.fid); 306 302 break; 307 303 308 - case RCLUNK: 304 + case P9_RCLUNK: 309 305 ret += scnprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag); 310 306 break; 311 307 312 - case TREMOVE: 308 + case P9_TREMOVE: 313 309 ret += scnprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d", 314 310 tag, fc->params.tremove.fid); 315 311 break; 316 312 317 - case RREMOVE: 313 + case P9_RREMOVE: 318 314 ret += scnprintf(buf+ret, buflen-ret, "Rremove tag %u", tag); 319 315 break; 320 316 321 - case TSTAT: 317 + case P9_TSTAT: 322 318 ret += scnprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d", 323 319 tag, fc->params.tstat.fid); 324 320 break; 325 321 326 - case RSTAT: 322 + case P9_RSTAT: 327 323 ret += scnprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag); 328 - ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat, 324 + ret += p9_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat, 329 325 extended); 330 326 break; 331 327 332 - case TWSTAT: 328 + case P9_TWSTAT: 333 329 ret += scnprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ", 334 330 tag, fc->params.twstat.fid); 335 - ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.twstat.stat, 336 - extended); 331 + ret += p9_printstat(buf+ret, buflen-ret, 332 + &fc->params.twstat.stat, extended); 337 333 break; 338 334 339 - case RWSTAT: 335 + case P9_RWSTAT: 340 336 ret += scnprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag); 341 337 break; 342 338 ··· 347 343 348 344 return ret; 349 345 } 346 + 347 + #else 348 + int 349 + p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended) 350 + { 351 + return 0; 352 + } 353 + EXPORT_SYMBOL(p9_printfcall); 354 + #endif /* CONFIG_NET_9P_DEBUG */
+54 -114
fs/9p/fid.c
··· 26 26 #include <linux/sched.h> 27 27 #include <linux/idr.h> 28 28 #include <asm/semaphore.h> 29 + #include <net/9p/9p.h> 30 + #include <net/9p/client.h> 29 31 30 - #include "debug.h" 31 32 #include "v9fs.h" 32 - #include "9p.h" 33 33 #include "v9fs_vfs.h" 34 34 #include "fid.h" 35 35 ··· 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; 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"); 45 + struct v9fs_dentry *dent; 46 + 47 + P9_DPRINTK(P9_DEBUG_VFS, "fid %d dentry %s\n", 48 + fid->fid, dentry->d_iname); 49 + 50 + dent = dentry->d_fsdata; 51 + if (!dent) { 52 + dent = kmalloc(sizeof(struct v9fs_dentry), GFP_KERNEL); 53 + if (!dent) 53 54 return -ENOMEM; 54 - } 55 - fid_list = (struct list_head *)dentry->d_fsdata; 56 - INIT_LIST_HEAD(fid_list); /* Initialize list head */ 55 + 56 + spin_lock_init(&dent->lock); 57 + INIT_LIST_HEAD(&dent->fidlist); 58 + dentry->d_fsdata = dent; 57 59 } 58 60 59 - fid->uid = current->uid; 60 - list_add(&fid->list, fid_list); 61 + spin_lock(&dent->lock); 62 + list_add(&fid->dlist, &dent->fidlist); 63 + spin_unlock(&dent->lock); 64 + 61 65 return 0; 62 - } 63 - 64 - /** 65 - * v9fs_fid_create - allocate a FID structure 66 - * @dentry - dentry to link newly created fid to 67 - * 68 - */ 69 - 70 - struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *v9ses, int fid) 71 - { 72 - struct v9fs_fid *new; 73 - 74 - dprintk(DEBUG_9P, "fid create fid %d\n", fid); 75 - new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); 76 - if (new == NULL) { 77 - dprintk(DEBUG_ERROR, "Out of Memory\n"); 78 - return ERR_PTR(-ENOMEM); 79 - } 80 - 81 - new->fid = fid; 82 - new->v9ses = v9ses; 83 - new->fidopen = 0; 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 - 100 - void v9fs_fid_destroy(struct v9fs_fid *fid) 101 - { 102 - list_del(&fid->list); 103 - kfree(fid); 104 66 } 105 67 106 68 /** ··· 76 114 * 77 115 */ 78 116 79 - struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry) 117 + struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) 80 118 { 81 - struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; 82 - struct v9fs_fid *return_fid = NULL; 119 + struct v9fs_dentry *dent; 120 + struct p9_fid *fid; 83 121 84 - dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry); 122 + P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); 123 + dent = dentry->d_fsdata; 124 + if (dent) 125 + fid = list_entry(dent->fidlist.next, struct p9_fid, dlist); 126 + else 127 + fid = ERR_PTR(-EBADF); 85 128 86 - if (fid_list) 87 - return_fid = list_entry(fid_list->next, struct v9fs_fid, list); 129 + P9_DPRINTK(P9_DEBUG_VFS, " fid: %p\n", fid); 130 + return fid; 131 + } 88 132 89 - if (!return_fid) { 90 - dprintk(DEBUG_ERROR, "Couldn't find a fid in dentry\n"); 91 - return_fid = ERR_PTR(-EBADF); 133 + struct p9_fid *v9fs_fid_lookup_remove(struct dentry *dentry) 134 + { 135 + struct p9_fid *fid; 136 + struct v9fs_dentry *dent; 137 + 138 + dent = dentry->d_fsdata; 139 + fid = v9fs_fid_lookup(dentry); 140 + if (!IS_ERR(fid)) { 141 + spin_lock(&dent->lock); 142 + list_del(&fid->dlist); 143 + spin_unlock(&dent->lock); 92 144 } 93 145 94 - if(down_interruptible(&return_fid->lock)) 95 - return ERR_PTR(-EINTR); 96 - 97 - return return_fid; 146 + return fid; 98 147 } 148 + 99 149 100 150 /** 101 151 * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and 102 - * release it 152 + * release it 103 153 * @dentry: dentry to look for fid in 104 154 * 105 155 * find a fid in the dentry and then clone to a new private fid ··· 120 146 * 121 147 */ 122 148 123 - struct v9fs_fid *v9fs_fid_clone(struct dentry *dentry) 149 + struct p9_fid *v9fs_fid_clone(struct dentry *dentry) 124 150 { 125 - struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); 126 - struct v9fs_fid *base_fid, *new_fid = ERR_PTR(-EBADF); 127 - struct v9fs_fcall *fcall = NULL; 128 - int fid, err; 151 + struct p9_fid *ofid, *fid; 129 152 130 - base_fid = v9fs_fid_lookup(dentry); 153 + P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); 154 + ofid = v9fs_fid_lookup(dentry); 155 + if (IS_ERR(ofid)) 156 + return ofid; 131 157 132 - if(IS_ERR(base_fid)) 133 - return base_fid; 134 - 135 - if(base_fid) { /* clone fid */ 136 - fid = v9fs_get_idpool(&v9ses->fidpool); 137 - if (fid < 0) { 138 - eprintk(KERN_WARNING, "newfid fails!\n"); 139 - new_fid = ERR_PTR(-ENOSPC); 140 - goto Release_Fid; 141 - } 142 - 143 - err = v9fs_t_walk(v9ses, base_fid->fid, fid, NULL, &fcall); 144 - if (err < 0) { 145 - dprintk(DEBUG_ERROR, "clone walk didn't work\n"); 146 - v9fs_put_idpool(fid, &v9ses->fidpool); 147 - new_fid = ERR_PTR(err); 148 - goto Free_Fcall; 149 - } 150 - new_fid = v9fs_fid_create(v9ses, fid); 151 - if (new_fid == NULL) { 152 - dprintk(DEBUG_ERROR, "out of memory\n"); 153 - new_fid = ERR_PTR(-ENOMEM); 154 - } 155 - Free_Fcall: 156 - kfree(fcall); 157 - } 158 - 159 - Release_Fid: 160 - up(&base_fid->lock); 161 - return new_fid; 162 - } 163 - 164 - void v9fs_fid_clunk(struct v9fs_session_info *v9ses, struct v9fs_fid *fid) 165 - { 166 - v9fs_t_clunk(v9ses, fid->fid); 167 - v9fs_fid_destroy(fid); 158 + fid = p9_client_walk(ofid, 0, NULL, 1); 159 + return fid; 168 160 }
+7 -36
fs/9p/fid.h
··· 22 22 23 23 #include <linux/list.h> 24 24 25 - #define FID_OP 0 26 - #define FID_WALK 1 27 - #define FID_CREATE 2 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 */ 25 + struct v9fs_dentry { 26 + spinlock_t lock; /* protect fidlist */ 27 + struct list_head fidlist; 53 28 }; 54 29 55 - struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry); 56 - struct v9fs_fid *v9fs_fid_get_created(struct dentry *); 57 - void v9fs_fid_destroy(struct v9fs_fid *fid); 58 - struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *, int 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 - 30 + struct p9_fid *v9fs_fid_lookup(struct dentry *dentry); 31 + struct p9_fid *v9fs_fid_lookup_remove(struct dentry *dentry); 32 + struct p9_fid *v9fs_fid_clone(struct dentry *dentry); 33 + int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid);
+268 -247
fs/9p/mux.c net/9p/mux.c
··· 1 1 /* 2 - * linux/fs/9p/mux.c 2 + * net/9p/mux.c 3 3 * 4 4 * Protocol Multiplexer 5 5 * ··· 30 30 #include <linux/kthread.h> 31 31 #include <linux/idr.h> 32 32 #include <linux/mutex.h> 33 - 34 - #include "debug.h" 35 - #include "v9fs.h" 36 - #include "9p.h" 37 - #include "conv.h" 38 - #include "transport.h" 39 - #include "mux.h" 33 + #include <net/9p/9p.h> 34 + #include <net/9p/transport.h> 35 + #include <net/9p/conn.h> 40 36 41 37 #define ERREQFLUSH 1 42 38 #define SCHED_TIMEOUT 10 ··· 51 55 Flushed, 52 56 }; 53 57 54 - struct v9fs_mux_poll_task; 58 + struct p9_mux_poll_task; 55 59 56 - struct v9fs_req { 57 - spinlock_t lock; 60 + struct p9_req { 61 + spinlock_t lock; /* protect request structure */ 58 62 int tag; 59 - struct v9fs_fcall *tcall; 60 - struct v9fs_fcall *rcall; 63 + struct p9_fcall *tcall; 64 + struct p9_fcall *rcall; 61 65 int err; 62 - v9fs_mux_req_callback cb; 66 + p9_conn_req_callback cb; 63 67 void *cba; 64 68 int flush; 65 69 struct list_head req_list; 66 70 }; 67 71 68 - struct v9fs_mux_data { 69 - spinlock_t lock; 72 + struct p9_conn { 73 + spinlock_t lock; /* protect lock structure */ 70 74 struct list_head mux_list; 71 - struct v9fs_mux_poll_task *poll_task; 75 + struct p9_mux_poll_task *poll_task; 72 76 int msize; 73 77 unsigned char *extended; 74 - struct v9fs_transport *trans; 75 - struct v9fs_idpool tagpool; 78 + struct p9_transport *trans; 79 + struct p9_idpool *tagpool; 76 80 int err; 77 81 wait_queue_head_t equeue; 78 82 struct list_head req_list; 79 83 struct list_head unsent_req_list; 80 - struct v9fs_fcall *rcall; 84 + struct p9_fcall *rcall; 81 85 int rpos; 82 86 char *rbuf; 83 87 int wpos; ··· 91 95 unsigned long wsched; 92 96 }; 93 97 94 - struct v9fs_mux_poll_task { 98 + struct p9_mux_poll_task { 95 99 struct task_struct *task; 96 100 struct list_head mux_list; 97 101 int muxnum; 98 102 }; 99 103 100 - struct v9fs_mux_rpc { 101 - struct v9fs_mux_data *m; 104 + struct p9_mux_rpc { 105 + struct p9_conn *m; 102 106 int err; 103 - struct v9fs_fcall *tcall; 104 - struct v9fs_fcall *rcall; 107 + struct p9_fcall *tcall; 108 + struct p9_fcall *rcall; 105 109 wait_queue_head_t wqueue; 106 110 }; 107 111 108 - static int v9fs_poll_proc(void *); 109 - static void v9fs_read_work(struct work_struct *work); 110 - static void v9fs_write_work(struct work_struct *work); 111 - static void v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address, 112 + static int p9_poll_proc(void *); 113 + static void p9_read_work(struct work_struct *work); 114 + static void p9_write_work(struct work_struct *work); 115 + static void p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, 112 116 poll_table * p); 113 - static u16 v9fs_mux_get_tag(struct v9fs_mux_data *); 114 - static void v9fs_mux_put_tag(struct v9fs_mux_data *, u16); 117 + static u16 p9_mux_get_tag(struct p9_conn *); 118 + static void p9_mux_put_tag(struct p9_conn *, u16); 115 119 116 - static DEFINE_MUTEX(v9fs_mux_task_lock); 117 - static struct workqueue_struct *v9fs_mux_wq; 120 + static DEFINE_MUTEX(p9_mux_task_lock); 121 + static struct workqueue_struct *p9_mux_wq; 118 122 119 - static int v9fs_mux_num; 120 - static int v9fs_mux_poll_task_num; 121 - static struct v9fs_mux_poll_task v9fs_mux_poll_tasks[100]; 123 + static int p9_mux_num; 124 + static int p9_mux_poll_task_num; 125 + static struct p9_mux_poll_task p9_mux_poll_tasks[100]; 122 126 123 - int v9fs_mux_global_init(void) 127 + int p9_mux_global_init(void) 124 128 { 125 129 int i; 126 130 127 - for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++) 128 - v9fs_mux_poll_tasks[i].task = NULL; 131 + for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) 132 + p9_mux_poll_tasks[i].task = NULL; 129 133 130 - v9fs_mux_wq = create_workqueue("v9fs"); 131 - if (!v9fs_mux_wq) { 134 + p9_mux_wq = create_workqueue("v9fs"); 135 + if (!p9_mux_wq) { 132 136 printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n"); 133 137 return -ENOMEM; 134 138 } ··· 136 140 return 0; 137 141 } 138 142 139 - void v9fs_mux_global_exit(void) 143 + void p9_mux_global_exit(void) 140 144 { 141 - destroy_workqueue(v9fs_mux_wq); 145 + destroy_workqueue(p9_mux_wq); 142 146 } 143 147 144 148 /** 145 - * v9fs_mux_calc_poll_procs - calculates the number of polling procs 149 + * p9_mux_calc_poll_procs - calculates the number of polling procs 146 150 * based on the number of mounted v9fs filesystems. 147 151 * 148 152 * The current implementation returns sqrt of the number of mounts. 149 153 */ 150 - static int v9fs_mux_calc_poll_procs(int muxnum) 154 + static int p9_mux_calc_poll_procs(int muxnum) 151 155 { 152 156 int n; 153 157 154 - if (v9fs_mux_poll_task_num) 155 - n = muxnum / v9fs_mux_poll_task_num + 156 - (muxnum % v9fs_mux_poll_task_num ? 1 : 0); 158 + if (p9_mux_poll_task_num) 159 + n = muxnum / p9_mux_poll_task_num + 160 + (muxnum % p9_mux_poll_task_num ? 1 : 0); 157 161 else 158 162 n = 1; 159 163 160 - if (n > ARRAY_SIZE(v9fs_mux_poll_tasks)) 161 - n = ARRAY_SIZE(v9fs_mux_poll_tasks); 164 + if (n > ARRAY_SIZE(p9_mux_poll_tasks)) 165 + n = ARRAY_SIZE(p9_mux_poll_tasks); 162 166 163 167 return n; 164 168 } 165 169 166 - static int v9fs_mux_poll_start(struct v9fs_mux_data *m) 170 + static int p9_mux_poll_start(struct p9_conn *m) 167 171 { 168 172 int i, n; 169 - struct v9fs_mux_poll_task *vpt, *vptlast; 173 + struct p9_mux_poll_task *vpt, *vptlast; 170 174 struct task_struct *pproc; 171 175 172 - dprintk(DEBUG_MUX, "mux %p muxnum %d procnum %d\n", m, v9fs_mux_num, 173 - v9fs_mux_poll_task_num); 174 - mutex_lock(&v9fs_mux_task_lock); 176 + P9_DPRINTK(P9_DEBUG_MUX, "mux %p muxnum %d procnum %d\n", m, p9_mux_num, 177 + p9_mux_poll_task_num); 178 + mutex_lock(&p9_mux_task_lock); 175 179 176 - n = v9fs_mux_calc_poll_procs(v9fs_mux_num + 1); 177 - if (n > v9fs_mux_poll_task_num) { 178 - for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++) { 179 - if (v9fs_mux_poll_tasks[i].task == NULL) { 180 - vpt = &v9fs_mux_poll_tasks[i]; 181 - dprintk(DEBUG_MUX, "create proc %p\n", vpt); 182 - pproc = kthread_create(v9fs_poll_proc, vpt, 183 - "v9fs-poll"); 180 + n = p9_mux_calc_poll_procs(p9_mux_num + 1); 181 + if (n > p9_mux_poll_task_num) { 182 + for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) { 183 + if (p9_mux_poll_tasks[i].task == NULL) { 184 + vpt = &p9_mux_poll_tasks[i]; 185 + P9_DPRINTK(P9_DEBUG_MUX, "create proc %p\n", 186 + vpt); 187 + pproc = kthread_create(p9_poll_proc, vpt, 188 + "v9fs-poll"); 184 189 185 190 if (!IS_ERR(pproc)) { 186 191 vpt->task = pproc; 187 192 INIT_LIST_HEAD(&vpt->mux_list); 188 193 vpt->muxnum = 0; 189 - v9fs_mux_poll_task_num++; 194 + p9_mux_poll_task_num++; 190 195 wake_up_process(vpt->task); 191 196 } 192 197 break; 193 198 } 194 199 } 195 200 196 - if (i >= ARRAY_SIZE(v9fs_mux_poll_tasks)) 197 - dprintk(DEBUG_ERROR, "warning: no free poll slots\n"); 201 + if (i >= ARRAY_SIZE(p9_mux_poll_tasks)) 202 + P9_DPRINTK(P9_DEBUG_ERROR, 203 + "warning: no free poll slots\n"); 198 204 } 199 205 200 - n = (v9fs_mux_num + 1) / v9fs_mux_poll_task_num + 201 - ((v9fs_mux_num + 1) % v9fs_mux_poll_task_num ? 1 : 0); 206 + n = (p9_mux_num + 1) / p9_mux_poll_task_num + 207 + ((p9_mux_num + 1) % p9_mux_poll_task_num ? 1 : 0); 202 208 203 209 vptlast = NULL; 204 - for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++) { 205 - vpt = &v9fs_mux_poll_tasks[i]; 210 + for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) { 211 + vpt = &p9_mux_poll_tasks[i]; 206 212 if (vpt->task != NULL) { 207 213 vptlast = vpt; 208 214 if (vpt->muxnum < n) { 209 - dprintk(DEBUG_MUX, "put in proc %d\n", i); 215 + P9_DPRINTK(P9_DEBUG_MUX, "put in proc %d\n", i); 210 216 list_add(&m->mux_list, &vpt->mux_list); 211 217 vpt->muxnum++; 212 218 m->poll_task = vpt; 213 - memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); 214 - init_poll_funcptr(&m->pt, v9fs_pollwait); 219 + memset(&m->poll_waddr, 0, 220 + sizeof(m->poll_waddr)); 221 + init_poll_funcptr(&m->pt, p9_pollwait); 215 222 break; 216 223 } 217 224 } 218 225 } 219 226 220 - if (i >= ARRAY_SIZE(v9fs_mux_poll_tasks)) { 227 + if (i >= ARRAY_SIZE(p9_mux_poll_tasks)) { 221 228 if (vptlast == NULL) 222 229 return -ENOMEM; 223 230 224 - dprintk(DEBUG_MUX, "put in proc %d\n", i); 231 + P9_DPRINTK(P9_DEBUG_MUX, "put in proc %d\n", i); 225 232 list_add(&m->mux_list, &vptlast->mux_list); 226 233 vptlast->muxnum++; 227 234 m->poll_task = vptlast; 228 235 memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); 229 - init_poll_funcptr(&m->pt, v9fs_pollwait); 236 + init_poll_funcptr(&m->pt, p9_pollwait); 230 237 } 231 238 232 - v9fs_mux_num++; 233 - mutex_unlock(&v9fs_mux_task_lock); 239 + p9_mux_num++; 240 + mutex_unlock(&p9_mux_task_lock); 234 241 235 242 return 0; 236 243 } 237 244 238 - static void v9fs_mux_poll_stop(struct v9fs_mux_data *m) 245 + static void p9_mux_poll_stop(struct p9_conn *m) 239 246 { 240 247 int i; 241 - struct v9fs_mux_poll_task *vpt; 248 + struct p9_mux_poll_task *vpt; 242 249 243 - mutex_lock(&v9fs_mux_task_lock); 250 + mutex_lock(&p9_mux_task_lock); 244 251 vpt = m->poll_task; 245 252 list_del(&m->mux_list); 246 - for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { 253 + for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { 247 254 if (m->poll_waddr[i] != NULL) { 248 255 remove_wait_queue(m->poll_waddr[i], &m->poll_wait[i]); 249 256 m->poll_waddr[i] = NULL; ··· 254 255 } 255 256 vpt->muxnum--; 256 257 if (!vpt->muxnum) { 257 - dprintk(DEBUG_MUX, "destroy proc %p\n", vpt); 258 + P9_DPRINTK(P9_DEBUG_MUX, "destroy proc %p\n", vpt); 258 259 kthread_stop(vpt->task); 259 260 vpt->task = NULL; 260 - v9fs_mux_poll_task_num--; 261 + p9_mux_poll_task_num--; 261 262 } 262 - v9fs_mux_num--; 263 - mutex_unlock(&v9fs_mux_task_lock); 263 + p9_mux_num--; 264 + mutex_unlock(&p9_mux_task_lock); 264 265 } 265 266 266 267 /** 267 - * v9fs_mux_init - allocate and initialize the per-session mux data 268 + * p9_conn_create - allocate and initialize the per-session mux data 268 269 * Creates the polling task if this is the first session. 269 270 * 270 271 * @trans - transport structure 271 272 * @msize - maximum message size 272 273 * @extended - pointer to the extended flag 273 274 */ 274 - struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, 275 + struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize, 275 276 unsigned char *extended) 276 277 { 277 278 int i, n; 278 - struct v9fs_mux_data *m, *mtmp; 279 + struct p9_conn *m, *mtmp; 279 280 280 - dprintk(DEBUG_MUX, "transport %p msize %d\n", trans, msize); 281 - m = kmalloc(sizeof(struct v9fs_mux_data), GFP_KERNEL); 281 + P9_DPRINTK(P9_DEBUG_MUX, "transport %p msize %d\n", trans, msize); 282 + m = kmalloc(sizeof(struct p9_conn), GFP_KERNEL); 282 283 if (!m) 283 284 return ERR_PTR(-ENOMEM); 284 285 ··· 287 288 m->msize = msize; 288 289 m->extended = extended; 289 290 m->trans = trans; 290 - idr_init(&m->tagpool.pool); 291 - init_MUTEX(&m->tagpool.lock); 291 + m->tagpool = p9_idpool_create(); 292 + if (!m->tagpool) { 293 + kfree(m); 294 + return ERR_PTR(PTR_ERR(m->tagpool)); 295 + } 296 + 292 297 m->err = 0; 293 298 init_waitqueue_head(&m->equeue); 294 299 INIT_LIST_HEAD(&m->req_list); ··· 302 299 m->rbuf = NULL; 303 300 m->wpos = m->wsize = 0; 304 301 m->wbuf = NULL; 305 - INIT_WORK(&m->rq, v9fs_read_work); 306 - INIT_WORK(&m->wq, v9fs_write_work); 302 + INIT_WORK(&m->rq, p9_read_work); 303 + INIT_WORK(&m->wq, p9_write_work); 307 304 m->wsched = 0; 308 305 memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); 309 306 m->poll_task = NULL; 310 - n = v9fs_mux_poll_start(m); 307 + n = p9_mux_poll_start(m); 311 308 if (n) 312 309 return ERR_PTR(n); 313 310 314 311 n = trans->poll(trans, &m->pt); 315 312 if (n & POLLIN) { 316 - dprintk(DEBUG_MUX, "mux %p can read\n", m); 313 + P9_DPRINTK(P9_DEBUG_MUX, "mux %p can read\n", m); 317 314 set_bit(Rpending, &m->wsched); 318 315 } 319 316 320 317 if (n & POLLOUT) { 321 - dprintk(DEBUG_MUX, "mux %p can write\n", m); 318 + P9_DPRINTK(P9_DEBUG_MUX, "mux %p can write\n", m); 322 319 set_bit(Wpending, &m->wsched); 323 320 } 324 321 325 - for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { 322 + for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { 326 323 if (IS_ERR(m->poll_waddr[i])) { 327 - v9fs_mux_poll_stop(m); 324 + p9_mux_poll_stop(m); 328 325 mtmp = (void *)m->poll_waddr; /* the error code */ 329 326 kfree(m); 330 327 m = mtmp; ··· 334 331 335 332 return m; 336 333 } 334 + EXPORT_SYMBOL(p9_conn_create); 337 335 338 336 /** 339 - * v9fs_mux_destroy - cancels all pending requests and frees mux resources 337 + * p9_mux_destroy - cancels all pending requests and frees mux resources 340 338 */ 341 - void v9fs_mux_destroy(struct v9fs_mux_data *m) 339 + void p9_conn_destroy(struct p9_conn *m) 342 340 { 343 - dprintk(DEBUG_MUX, "mux %p prev %p next %p\n", m, 341 + P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m, 344 342 m->mux_list.prev, m->mux_list.next); 345 - v9fs_mux_cancel(m, -ECONNRESET); 343 + p9_conn_cancel(m, -ECONNRESET); 346 344 347 345 if (!list_empty(&m->req_list)) { 348 346 /* wait until all processes waiting on this session exit */ 349 - dprintk(DEBUG_MUX, "mux %p waiting for empty request queue\n", 350 - m); 347 + P9_DPRINTK(P9_DEBUG_MUX, 348 + "mux %p waiting for empty request queue\n", m); 351 349 wait_event_timeout(m->equeue, (list_empty(&m->req_list)), 5000); 352 - dprintk(DEBUG_MUX, "mux %p request queue empty: %d\n", m, 350 + P9_DPRINTK(P9_DEBUG_MUX, "mux %p request queue empty: %d\n", m, 353 351 list_empty(&m->req_list)); 354 352 } 355 353 356 - v9fs_mux_poll_stop(m); 354 + p9_mux_poll_stop(m); 357 355 m->trans = NULL; 358 - 356 + p9_idpool_destroy(m->tagpool); 359 357 kfree(m); 360 358 } 359 + EXPORT_SYMBOL(p9_conn_destroy); 361 360 362 361 /** 363 - * v9fs_pollwait - called by files poll operation to add v9fs-poll task 362 + * p9_pollwait - called by files poll operation to add v9fs-poll task 364 363 * to files wait queue 365 364 */ 366 365 static void 367 - v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address, 366 + p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, 368 367 poll_table * p) 369 368 { 370 369 int i; 371 - struct v9fs_mux_data *m; 370 + struct p9_conn *m; 372 371 373 - m = container_of(p, struct v9fs_mux_data, pt); 374 - for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) 372 + m = container_of(p, struct p9_conn, pt); 373 + for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) 375 374 if (m->poll_waddr[i] == NULL) 376 375 break; 377 376 378 377 if (i >= ARRAY_SIZE(m->poll_waddr)) { 379 - dprintk(DEBUG_ERROR, "not enough wait_address slots\n"); 378 + P9_DPRINTK(P9_DEBUG_ERROR, "not enough wait_address slots\n"); 380 379 return; 381 380 } 382 381 383 382 m->poll_waddr[i] = wait_address; 384 383 385 384 if (!wait_address) { 386 - dprintk(DEBUG_ERROR, "no wait_address\n"); 385 + P9_DPRINTK(P9_DEBUG_ERROR, "no wait_address\n"); 387 386 m->poll_waddr[i] = ERR_PTR(-EIO); 388 387 return; 389 388 } ··· 395 390 } 396 391 397 392 /** 398 - * v9fs_poll_mux - polls a mux and schedules read or write works if necessary 393 + * p9_poll_mux - polls a mux and schedules read or write works if necessary 399 394 */ 400 - static void v9fs_poll_mux(struct v9fs_mux_data *m) 395 + static void p9_poll_mux(struct p9_conn *m) 401 396 { 402 397 int n; 403 398 ··· 406 401 407 402 n = m->trans->poll(m->trans, NULL); 408 403 if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) { 409 - dprintk(DEBUG_MUX, "error mux %p err %d\n", m, n); 404 + P9_DPRINTK(P9_DEBUG_MUX, "error mux %p err %d\n", m, n); 410 405 if (n >= 0) 411 406 n = -ECONNRESET; 412 - v9fs_mux_cancel(m, n); 407 + p9_conn_cancel(m, n); 413 408 } 414 409 415 410 if (n & POLLIN) { 416 411 set_bit(Rpending, &m->wsched); 417 - dprintk(DEBUG_MUX, "mux %p can read\n", m); 412 + P9_DPRINTK(P9_DEBUG_MUX, "mux %p can read\n", m); 418 413 if (!test_and_set_bit(Rworksched, &m->wsched)) { 419 - dprintk(DEBUG_MUX, "schedule read work mux %p\n", m); 420 - queue_work(v9fs_mux_wq, &m->rq); 414 + P9_DPRINTK(P9_DEBUG_MUX, "schedule read work %p\n", m); 415 + queue_work(p9_mux_wq, &m->rq); 421 416 } 422 417 } 423 418 424 419 if (n & POLLOUT) { 425 420 set_bit(Wpending, &m->wsched); 426 - dprintk(DEBUG_MUX, "mux %p can write\n", m); 421 + P9_DPRINTK(P9_DEBUG_MUX, "mux %p can write\n", m); 427 422 if ((m->wsize || !list_empty(&m->unsent_req_list)) 428 423 && !test_and_set_bit(Wworksched, &m->wsched)) { 429 - dprintk(DEBUG_MUX, "schedule write work mux %p\n", m); 430 - queue_work(v9fs_mux_wq, &m->wq); 424 + P9_DPRINTK(P9_DEBUG_MUX, "schedule write work %p\n", m); 425 + queue_work(p9_mux_wq, &m->wq); 431 426 } 432 427 } 433 428 } 434 429 435 430 /** 436 - * v9fs_poll_proc - polls all v9fs transports for new events and queues 431 + * p9_poll_proc - polls all v9fs transports for new events and queues 437 432 * the appropriate work to the work queue 438 433 */ 439 - static int v9fs_poll_proc(void *a) 434 + static int p9_poll_proc(void *a) 440 435 { 441 - struct v9fs_mux_data *m, *mtmp; 442 - struct v9fs_mux_poll_task *vpt; 436 + struct p9_conn *m, *mtmp; 437 + struct p9_mux_poll_task *vpt; 443 438 444 439 vpt = a; 445 - dprintk(DEBUG_MUX, "start %p %p\n", current, vpt); 440 + P9_DPRINTK(P9_DEBUG_MUX, "start %p %p\n", current, vpt); 446 441 while (!kthread_should_stop()) { 447 442 set_current_state(TASK_INTERRUPTIBLE); 448 443 449 444 list_for_each_entry_safe(m, mtmp, &vpt->mux_list, mux_list) { 450 - v9fs_poll_mux(m); 445 + p9_poll_mux(m); 451 446 } 452 447 453 - dprintk(DEBUG_MUX, "sleeping...\n"); 448 + P9_DPRINTK(P9_DEBUG_MUX, "sleeping...\n"); 454 449 schedule_timeout(SCHED_TIMEOUT * HZ); 455 450 } 456 451 457 452 __set_current_state(TASK_RUNNING); 458 - dprintk(DEBUG_MUX, "finish\n"); 453 + P9_DPRINTK(P9_DEBUG_MUX, "finish\n"); 459 454 return 0; 460 455 } 461 456 462 457 /** 463 - * v9fs_write_work - called when a transport can send some data 458 + * p9_write_work - called when a transport can send some data 464 459 */ 465 - static void v9fs_write_work(struct work_struct *work) 460 + static void p9_write_work(struct work_struct *work) 466 461 { 467 462 int n, err; 468 - struct v9fs_mux_data *m; 469 - struct v9fs_req *req; 463 + struct p9_conn *m; 464 + struct p9_req *req; 470 465 471 - m = container_of(work, struct v9fs_mux_data, wq); 466 + m = container_of(work, struct p9_conn, wq); 472 467 473 468 if (m->err < 0) { 474 469 clear_bit(Wworksched, &m->wsched); ··· 483 478 484 479 spin_lock(&m->lock); 485 480 again: 486 - req = list_entry(m->unsent_req_list.next, struct v9fs_req, 481 + req = list_entry(m->unsent_req_list.next, struct p9_req, 487 482 req_list); 488 483 list_move_tail(&req->req_list, &m->req_list); 489 484 if (req->err == ERREQFLUSH) ··· 492 487 m->wbuf = req->tcall->sdata; 493 488 m->wsize = req->tcall->size; 494 489 m->wpos = 0; 495 - dump_data(m->wbuf, m->wsize); 496 490 spin_unlock(&m->lock); 497 491 } 498 492 499 - dprintk(DEBUG_MUX, "mux %p pos %d size %d\n", m, m->wpos, m->wsize); 493 + P9_DPRINTK(P9_DEBUG_MUX, "mux %p pos %d size %d\n", m, m->wpos, 494 + m->wsize); 500 495 clear_bit(Wpending, &m->wsched); 501 496 err = m->trans->write(m->trans, m->wbuf + m->wpos, m->wsize - m->wpos); 502 - dprintk(DEBUG_MUX, "mux %p sent %d bytes\n", m, err); 497 + P9_DPRINTK(P9_DEBUG_MUX, "mux %p sent %d bytes\n", m, err); 503 498 if (err == -EAGAIN) { 504 499 clear_bit(Wworksched, &m->wsched); 505 500 return; 506 501 } 507 502 508 - if (err <= 0) 503 + if (err < 0) 509 504 goto error; 505 + else if (err == 0) { 506 + err = -EREMOTEIO; 507 + goto error; 508 + } 510 509 511 510 m->wpos += err; 512 511 if (m->wpos == m->wsize) ··· 523 514 n = m->trans->poll(m->trans, NULL); 524 515 525 516 if (n & POLLOUT) { 526 - dprintk(DEBUG_MUX, "schedule write work mux %p\n", m); 527 - queue_work(v9fs_mux_wq, &m->wq); 517 + P9_DPRINTK(P9_DEBUG_MUX, "schedule write work %p\n", m); 518 + queue_work(p9_mux_wq, &m->wq); 528 519 } else 529 520 clear_bit(Wworksched, &m->wsched); 530 521 } else ··· 532 523 533 524 return; 534 525 535 - error: 536 - v9fs_mux_cancel(m, err); 526 + error: 527 + p9_conn_cancel(m, err); 537 528 clear_bit(Wworksched, &m->wsched); 538 529 } 539 530 540 - static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) 531 + static void process_request(struct p9_conn *m, struct p9_req *req) 541 532 { 542 533 int ecode; 543 - struct v9fs_str *ename; 534 + struct p9_str *ename; 544 535 545 - if (!req->err && req->rcall->id == RERROR) { 536 + if (!req->err && req->rcall->id == P9_RERROR) { 546 537 ecode = req->rcall->params.rerror.errno; 547 538 ename = &req->rcall->params.rerror.error; 548 539 549 - dprintk(DEBUG_MUX, "Rerror %.*s\n", ename->len, ename->str); 540 + P9_DPRINTK(P9_DEBUG_MUX, "Rerror %.*s\n", ename->len, 541 + ename->str); 550 542 551 543 if (*m->extended) 552 544 req->err = -ecode; 553 545 554 546 if (!req->err) { 555 - req->err = v9fs_errstr2errno(ename->str, ename->len); 547 + req->err = p9_errstr2errno(ename->str, ename->len); 556 548 557 549 if (!req->err) { /* string match failed */ 558 550 PRINT_FCALL_ERROR("unknown error", req->rcall); ··· 563 553 req->err = -ESERVERFAULT; 564 554 } 565 555 } else if (req->tcall && req->rcall->id != req->tcall->id + 1) { 566 - dprintk(DEBUG_ERROR, "fcall mismatch: expected %d, got %d\n", 567 - req->tcall->id + 1, req->rcall->id); 556 + P9_DPRINTK(P9_DEBUG_ERROR, 557 + "fcall mismatch: expected %d, got %d\n", 558 + req->tcall->id + 1, req->rcall->id); 568 559 if (!req->err) 569 560 req->err = -EIO; 570 561 } 571 562 } 572 563 573 564 /** 574 - * v9fs_read_work - called when there is some data to be read from a transport 565 + * p9_read_work - called when there is some data to be read from a transport 575 566 */ 576 - static void v9fs_read_work(struct work_struct *work) 567 + static void p9_read_work(struct work_struct *work) 577 568 { 578 569 int n, err; 579 - struct v9fs_mux_data *m; 580 - struct v9fs_req *req, *rptr, *rreq; 581 - struct v9fs_fcall *rcall; 570 + struct p9_conn *m; 571 + struct p9_req *req, *rptr, *rreq; 572 + struct p9_fcall *rcall; 582 573 char *rbuf; 583 574 584 - m = container_of(work, struct v9fs_mux_data, rq); 575 + m = container_of(work, struct p9_conn, rq); 585 576 586 577 if (m->err < 0) 587 578 return; 588 579 589 580 rcall = NULL; 590 - dprintk(DEBUG_MUX, "start mux %p pos %d\n", m, m->rpos); 581 + P9_DPRINTK(P9_DEBUG_MUX, "start mux %p pos %d\n", m, m->rpos); 591 582 592 583 if (!m->rcall) { 593 584 m->rcall = 594 - kmalloc(sizeof(struct v9fs_fcall) + m->msize, GFP_KERNEL); 585 + kmalloc(sizeof(struct p9_fcall) + m->msize, GFP_KERNEL); 595 586 if (!m->rcall) { 596 587 err = -ENOMEM; 597 588 goto error; 598 589 } 599 590 600 - m->rbuf = (char *)m->rcall + sizeof(struct v9fs_fcall); 591 + m->rbuf = (char *)m->rcall + sizeof(struct p9_fcall); 601 592 m->rpos = 0; 602 593 } 603 594 604 595 clear_bit(Rpending, &m->wsched); 605 596 err = m->trans->read(m->trans, m->rbuf + m->rpos, m->msize - m->rpos); 606 - dprintk(DEBUG_MUX, "mux %p got %d bytes\n", m, err); 597 + P9_DPRINTK(P9_DEBUG_MUX, "mux %p got %d bytes\n", m, err); 607 598 if (err == -EAGAIN) { 608 599 clear_bit(Rworksched, &m->wsched); 609 600 return; ··· 617 606 while (m->rpos > 4) { 618 607 n = le32_to_cpu(*(__le32 *) m->rbuf); 619 608 if (n >= m->msize) { 620 - dprintk(DEBUG_ERROR, 609 + P9_DPRINTK(P9_DEBUG_ERROR, 621 610 "requested packet size too big: %d\n", n); 622 611 err = -EIO; 623 612 goto error; ··· 626 615 if (m->rpos < n) 627 616 break; 628 617 629 - dump_data(m->rbuf, n); 630 618 err = 631 - v9fs_deserialize_fcall(m->rbuf, n, m->rcall, *m->extended); 619 + p9_deserialize_fcall(m->rbuf, n, m->rcall, *m->extended); 632 620 if (err < 0) { 633 621 goto error; 634 622 } 635 623 636 - if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) { 624 + #ifdef CONFIG_NET_9P_DEBUG 625 + if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) { 637 626 char buf[150]; 638 627 639 - v9fs_printfcall(buf, sizeof(buf), m->rcall, 628 + p9_printfcall(buf, sizeof(buf), m->rcall, 640 629 *m->extended); 641 630 printk(KERN_NOTICE ">>> %p %s\n", m, buf); 642 631 } 632 + #endif 643 633 644 634 rcall = m->rcall; 645 635 rbuf = m->rbuf; 646 636 if (m->rpos > n) { 647 - m->rcall = kmalloc(sizeof(struct v9fs_fcall) + m->msize, 637 + m->rcall = kmalloc(sizeof(struct p9_fcall) + m->msize, 648 638 GFP_KERNEL); 649 639 if (!m->rcall) { 650 640 err = -ENOMEM; 651 641 goto error; 652 642 } 653 643 654 - m->rbuf = (char *)m->rcall + sizeof(struct v9fs_fcall); 644 + m->rbuf = (char *)m->rcall + sizeof(struct p9_fcall); 655 645 memmove(m->rbuf, rbuf + n, m->rpos - n); 656 646 m->rpos -= n; 657 647 } else { ··· 661 649 m->rpos = 0; 662 650 } 663 651 664 - dprintk(DEBUG_MUX, "mux %p fcall id %d tag %d\n", m, rcall->id, 665 - rcall->tag); 652 + P9_DPRINTK(P9_DEBUG_MUX, "mux %p fcall id %d tag %d\n", m, 653 + rcall->id, rcall->tag); 666 654 667 655 req = NULL; 668 656 spin_lock(&m->lock); ··· 689 677 wake_up(&m->equeue); 690 678 } 691 679 } else { 692 - if (err >= 0 && rcall->id != RFLUSH) 693 - dprintk(DEBUG_ERROR, 694 - "unexpected response mux %p id %d tag %d\n", 695 - m, rcall->id, rcall->tag); 680 + if (err >= 0 && rcall->id != P9_RFLUSH) 681 + P9_DPRINTK(P9_DEBUG_ERROR, 682 + "unexpected response mux %p id %d tag %d\n", 683 + m, rcall->id, rcall->tag); 696 684 kfree(rcall); 697 685 } 698 686 } ··· 704 692 n = m->trans->poll(m->trans, NULL); 705 693 706 694 if (n & POLLIN) { 707 - dprintk(DEBUG_MUX, "schedule read work mux %p\n", m); 708 - queue_work(v9fs_mux_wq, &m->rq); 695 + P9_DPRINTK(P9_DEBUG_MUX, "schedule read work %p\n", m); 696 + queue_work(p9_mux_wq, &m->rq); 709 697 } else 710 698 clear_bit(Rworksched, &m->wsched); 711 699 } else ··· 713 701 714 702 return; 715 703 716 - error: 717 - v9fs_mux_cancel(m, err); 704 + error: 705 + p9_conn_cancel(m, err); 718 706 clear_bit(Rworksched, &m->wsched); 719 707 } 720 708 721 709 /** 722 - * v9fs_send_request - send 9P request 710 + * p9_send_request - send 9P request 723 711 * The function can sleep until the request is scheduled for sending. 724 712 * The function can be interrupted. Return from the function is not 725 713 * a guarantee that the request is sent successfully. Can return errors ··· 730 718 * @cb: callback function to call when response is received 731 719 * @cba: parameter to pass to the callback function 732 720 */ 733 - static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m, 734 - struct v9fs_fcall *tc, 735 - v9fs_mux_req_callback cb, void *cba) 721 + static struct p9_req *p9_send_request(struct p9_conn *m, 722 + struct p9_fcall *tc, 723 + p9_conn_req_callback cb, void *cba) 736 724 { 737 725 int n; 738 - struct v9fs_req *req; 726 + struct p9_req *req; 739 727 740 - dprintk(DEBUG_MUX, "mux %p task %p tcall %p id %d\n", m, current, 728 + P9_DPRINTK(P9_DEBUG_MUX, "mux %p task %p tcall %p id %d\n", m, current, 741 729 tc, tc->id); 742 730 if (m->err < 0) 743 731 return ERR_PTR(m->err); 744 732 745 - req = kmalloc(sizeof(struct v9fs_req), GFP_KERNEL); 733 + req = kmalloc(sizeof(struct p9_req), GFP_KERNEL); 746 734 if (!req) 747 735 return ERR_PTR(-ENOMEM); 748 736 749 - if (tc->id == TVERSION) 750 - n = V9FS_NOTAG; 737 + if (tc->id == P9_TVERSION) 738 + n = P9_NOTAG; 751 739 else 752 - n = v9fs_mux_get_tag(m); 740 + n = p9_mux_get_tag(m); 753 741 754 742 if (n < 0) 755 743 return ERR_PTR(-ENOMEM); 756 744 757 - v9fs_set_tag(tc, n); 758 - if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) { 745 + p9_set_tag(tc, n); 746 + 747 + #ifdef CONFIG_NET_9P_DEBUG 748 + if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) { 759 749 char buf[150]; 760 750 761 - v9fs_printfcall(buf, sizeof(buf), tc, *m->extended); 751 + p9_printfcall(buf, sizeof(buf), tc, *m->extended); 762 752 printk(KERN_NOTICE "<<< %p %s\n", m, buf); 763 753 } 754 + #endif 764 755 765 756 spin_lock_init(&req->lock); 766 757 req->tag = n; ··· 784 769 n = m->trans->poll(m->trans, NULL); 785 770 786 771 if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched)) 787 - queue_work(v9fs_mux_wq, &m->wq); 772 + queue_work(p9_mux_wq, &m->wq); 788 773 789 774 return req; 790 775 } 791 776 792 - static void v9fs_mux_free_request(struct v9fs_mux_data *m, struct v9fs_req *req) 777 + static void p9_mux_free_request(struct p9_conn *m, struct p9_req *req) 793 778 { 794 - v9fs_mux_put_tag(m, req->tag); 779 + p9_mux_put_tag(m, req->tag); 795 780 kfree(req); 796 781 } 797 782 798 - static void v9fs_mux_flush_cb(struct v9fs_req *freq, void *a) 783 + static void p9_mux_flush_cb(struct p9_req *freq, void *a) 799 784 { 800 - v9fs_mux_req_callback cb; 785 + p9_conn_req_callback cb; 801 786 int tag; 802 - struct v9fs_mux_data *m; 803 - struct v9fs_req *req, *rreq, *rptr; 787 + struct p9_conn *m; 788 + struct p9_req *req, *rreq, *rptr; 804 789 805 790 m = a; 806 - dprintk(DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m, 791 + P9_DPRINTK(P9_DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m, 807 792 freq->tcall, freq->rcall, freq->err, 808 793 freq->tcall->params.tflush.oldtag); 809 794 ··· 835 820 836 821 kfree(freq->tcall); 837 822 kfree(freq->rcall); 838 - v9fs_mux_free_request(m, freq); 823 + p9_mux_free_request(m, freq); 839 824 } 840 825 841 826 static int 842 - v9fs_mux_flush_request(struct v9fs_mux_data *m, struct v9fs_req *req) 827 + p9_mux_flush_request(struct p9_conn *m, struct p9_req *req) 843 828 { 844 - struct v9fs_fcall *fc; 845 - struct v9fs_req *rreq, *rptr; 829 + struct p9_fcall *fc; 830 + struct p9_req *rreq, *rptr; 846 831 847 - dprintk(DEBUG_MUX, "mux %p req %p tag %d\n", m, req, req->tag); 832 + P9_DPRINTK(P9_DEBUG_MUX, "mux %p req %p tag %d\n", m, req, req->tag); 848 833 849 834 /* if a response was received for a request, do nothing */ 850 835 spin_lock(&req->lock); 851 836 if (req->rcall || req->err) { 852 837 spin_unlock(&req->lock); 853 - dprintk(DEBUG_MUX, "mux %p req %p response already received\n", m, req); 838 + P9_DPRINTK(P9_DEBUG_MUX, 839 + "mux %p req %p response already received\n", m, req); 854 840 return 0; 855 841 } 856 842 ··· 862 846 /* if the request is not sent yet, just remove it from the list */ 863 847 list_for_each_entry_safe(rreq, rptr, &m->unsent_req_list, req_list) { 864 848 if (rreq->tag == req->tag) { 865 - dprintk(DEBUG_MUX, "mux %p req %p request is not sent yet\n", m, req); 849 + P9_DPRINTK(P9_DEBUG_MUX, 850 + "mux %p req %p request is not sent yet\n", m, req); 866 851 list_del(&rreq->req_list); 867 852 req->flush = Flushed; 868 853 spin_unlock(&m->lock); ··· 875 858 spin_unlock(&m->lock); 876 859 877 860 clear_thread_flag(TIF_SIGPENDING); 878 - fc = v9fs_create_tflush(req->tag); 879 - v9fs_send_request(m, fc, v9fs_mux_flush_cb, m); 861 + fc = p9_create_tflush(req->tag); 862 + p9_send_request(m, fc, p9_mux_flush_cb, m); 880 863 return 1; 881 864 } 882 865 883 866 static void 884 - v9fs_mux_rpc_cb(struct v9fs_req *req, void *a) 867 + p9_conn_rpc_cb(struct p9_req *req, void *a) 885 868 { 886 - struct v9fs_mux_rpc *r; 869 + struct p9_mux_rpc *r; 887 870 888 - dprintk(DEBUG_MUX, "req %p r %p\n", req, a); 871 + P9_DPRINTK(P9_DEBUG_MUX, "req %p r %p\n", req, a); 889 872 r = a; 890 873 r->rcall = req->rcall; 891 874 r->err = req->err; 892 875 893 - if (req->flush!=None && !req->err) 876 + if (req->flush != None && !req->err) 894 877 r->err = -ERESTARTSYS; 895 878 896 879 wake_up(&r->wqueue); 897 880 } 898 881 899 882 /** 900 - * v9fs_mux_rpc - sends 9P request and waits until a response is available. 883 + * p9_mux_rpc - sends 9P request and waits until a response is available. 901 884 * The function can be interrupted. 902 885 * @m: mux data 903 886 * @tc: request to be sent 904 887 * @rc: pointer where a pointer to the response is stored 905 888 */ 906 889 int 907 - v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, 908 - struct v9fs_fcall **rc) 890 + p9_conn_rpc(struct p9_conn *m, struct p9_fcall *tc, 891 + struct p9_fcall **rc) 909 892 { 910 893 int err, sigpending; 911 894 unsigned long flags; 912 - struct v9fs_req *req; 913 - struct v9fs_mux_rpc r; 895 + struct p9_req *req; 896 + struct p9_mux_rpc r; 914 897 915 898 r.err = 0; 916 899 r.tcall = tc; ··· 927 910 clear_thread_flag(TIF_SIGPENDING); 928 911 } 929 912 930 - req = v9fs_send_request(m, tc, v9fs_mux_rpc_cb, &r); 913 + req = p9_send_request(m, tc, p9_conn_rpc_cb, &r); 931 914 if (IS_ERR(req)) { 932 915 err = PTR_ERR(req); 933 - dprintk(DEBUG_MUX, "error %d\n", err); 916 + P9_DPRINTK(P9_DEBUG_MUX, "error %d\n", err); 934 917 return err; 935 918 } 936 919 ··· 938 921 if (r.err < 0) 939 922 err = r.err; 940 923 941 - if (err == -ERESTARTSYS && m->trans->status == Connected && m->err == 0) { 942 - if (v9fs_mux_flush_request(m, req)) { 924 + if (err == -ERESTARTSYS && m->trans->status == Connected 925 + && m->err == 0) { 926 + if (p9_mux_flush_request(m, req)) { 943 927 /* wait until we get response of the flush message */ 944 928 do { 945 929 clear_thread_flag(TIF_SIGPENDING); 946 930 err = wait_event_interruptible(r.wqueue, 947 931 r.rcall || r.err); 948 - } while (!r.rcall && !r.err && err==-ERESTARTSYS && 949 - m->trans->status==Connected && !m->err); 932 + } while (!r.rcall && !r.err && err == -ERESTARTSYS && 933 + m->trans->status == Connected && !m->err); 950 934 951 935 err = -ERESTARTSYS; 952 936 } ··· 965 947 else 966 948 kfree(r.rcall); 967 949 968 - v9fs_mux_free_request(m, req); 950 + p9_mux_free_request(m, req); 969 951 if (err > 0) 970 952 err = -EIO; 971 953 972 954 return err; 973 955 } 956 + EXPORT_SYMBOL(p9_conn_rpc); 974 957 975 - #if 0 958 + #ifdef P9_NONBLOCK 976 959 /** 977 - * v9fs_mux_rpcnb - sends 9P request without waiting for response. 960 + * p9_conn_rpcnb - sends 9P request without waiting for response. 978 961 * @m: mux data 979 962 * @tc: request to be sent 980 963 * @cb: callback function to be called when response arrives 981 964 * @cba: value to pass to the callback function 982 965 */ 983 - int v9fs_mux_rpcnb(struct v9fs_mux_data *m, struct v9fs_fcall *tc, 984 - v9fs_mux_req_callback cb, void *a) 966 + int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc, 967 + p9_conn_req_callback cb, void *a) 985 968 { 986 969 int err; 987 - struct v9fs_req *req; 970 + struct p9_req *req; 988 971 989 - req = v9fs_send_request(m, tc, cb, a); 972 + req = p9_send_request(m, tc, cb, a); 990 973 if (IS_ERR(req)) { 991 974 err = PTR_ERR(req); 992 - dprintk(DEBUG_MUX, "error %d\n", err); 975 + P9_DPRINTK(P9_DEBUG_MUX, "error %d\n", err); 993 976 return PTR_ERR(req); 994 977 } 995 978 996 - dprintk(DEBUG_MUX, "mux %p tc %p tag %d\n", m, tc, req->tag); 979 + P9_DPRINTK(P9_DEBUG_MUX, "mux %p tc %p tag %d\n", m, tc, req->tag); 997 980 return 0; 998 981 } 999 - #endif /* 0 */ 982 + EXPORT_SYMBOL(p9_conn_rpcnb); 983 + #endif /* P9_NONBLOCK */ 1000 984 1001 985 /** 1002 - * v9fs_mux_cancel - cancel all pending requests with error 986 + * p9_conn_cancel - cancel all pending requests with error 1003 987 * @m: mux data 1004 988 * @err: error code 1005 989 */ 1006 - void v9fs_mux_cancel(struct v9fs_mux_data *m, int err) 990 + void p9_conn_cancel(struct p9_conn *m, int err) 1007 991 { 1008 - struct v9fs_req *req, *rtmp; 992 + struct p9_req *req, *rtmp; 1009 993 LIST_HEAD(cancel_list); 1010 994 1011 - dprintk(DEBUG_ERROR, "mux %p err %d\n", m, err); 995 + P9_DPRINTK(P9_DEBUG_ERROR, "mux %p err %d\n", m, err); 1012 996 m->err = err; 1013 997 spin_lock(&m->lock); 1014 998 list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) { ··· 1034 1014 1035 1015 wake_up(&m->equeue); 1036 1016 } 1017 + EXPORT_SYMBOL(p9_conn_cancel); 1037 1018 1038 - static u16 v9fs_mux_get_tag(struct v9fs_mux_data *m) 1019 + static u16 p9_mux_get_tag(struct p9_conn *m) 1039 1020 { 1040 1021 int tag; 1041 1022 1042 - tag = v9fs_get_idpool(&m->tagpool); 1023 + tag = p9_idpool_get(m->tagpool); 1043 1024 if (tag < 0) 1044 - return V9FS_NOTAG; 1025 + return P9_NOTAG; 1045 1026 else 1046 1027 return (u16) tag; 1047 1028 } 1048 1029 1049 - static void v9fs_mux_put_tag(struct v9fs_mux_data *m, u16 tag) 1030 + static void p9_mux_put_tag(struct p9_conn *m, u16 tag) 1050 1031 { 1051 - if (tag != V9FS_NOTAG && v9fs_check_idpool(tag, &m->tagpool)) 1052 - v9fs_put_idpool(tag, &m->tagpool); 1032 + if (tag != P9_NOTAG && p9_idpool_check(tag, m->tagpool)) 1033 + p9_idpool_put(tag, m->tagpool); 1053 1034 }
+22 -20
fs/9p/mux.h include/net/9p/conn.h
··· 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 6 * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net> 7 7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> ··· 23 23 * 24 24 */ 25 25 26 - struct v9fs_mux_data; 27 - struct v9fs_req; 26 + #ifndef NET_9P_CONN_H 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 36 * response of a request is received. The callback is called from 32 37 * a workqueue and shouldn't block. 33 38 * 39 + * @req - request 34 40 * @a - the pointer that was specified when the request was send to be 35 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); 43 - void v9fs_mux_global_exit(void); 45 + struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize, 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, 46 - unsigned char *extended); 47 - void v9fs_mux_destroy(struct v9fs_mux_data *); 50 + #ifdef P9_NONBLOCK 51 + int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc, 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); 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); 55 + void p9_conn_cancel(struct p9_conn *m, int err); 52 56 53 - void v9fs_mux_flush(struct v9fs_mux_data *m, int sendflush); 54 - void v9fs_mux_cancel(struct v9fs_mux_data *m, int err); 55 - int v9fs_errstr2errno(char *errstr, int len); 57 + #endif /* NET_9P_CONN_H */
-308
fs/9p/trans_fd.c
··· 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 - };
+16 -12
fs/9p/transport.h include/net/9p/transport.h
··· 1 1 /* 2 - * linux/fs/9p/transport.h 2 + * include/net/9p/transport.h 3 3 * 4 4 * Transport Definition 5 5 * ··· 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 30 Connected, 28 31 Disconnected, 29 32 Hung, 30 33 }; 31 34 32 - struct v9fs_transport { 33 - enum v9fs_transport_status status; 35 + struct p9_transport { 36 + enum p9_transport_status status; 34 37 void *priv; 35 38 36 - int (*init) (struct v9fs_session_info *, const char *, char *); 37 - int (*write) (struct v9fs_transport *, void *, int); 38 - int (*read) (struct v9fs_transport *, void *, int); 39 - void (*close) (struct v9fs_transport *); 40 - unsigned int (*poll)(struct v9fs_transport *, struct poll_table_struct *); 39 + int (*write) (struct p9_transport *, void *, int); 40 + int (*read) (struct p9_transport *, void *, int); 41 + void (*close) (struct p9_transport *); 42 + unsigned int (*poll)(struct p9_transport *, struct poll_table_struct *); 41 43 }; 42 44 43 - extern struct v9fs_transport v9fs_trans_tcp; 44 - extern struct v9fs_transport v9fs_trans_unix; 45 - extern struct v9fs_transport v9fs_trans_fd; 45 + struct p9_transport *p9_trans_create_tcp(const char *addr, int port); 46 + struct p9_transport *p9_trans_create_unix(const char *addr); 47 + struct p9_transport *p9_trans_create_fd(int rfd, int wfd); 48 + 49 + #endif /* NET_9P_TRANSPORT_H */
+63 -230
fs/9p/v9fs.c
··· 29 29 #include <linux/sched.h> 30 30 #include <linux/parser.h> 31 31 #include <linux/idr.h> 32 - 33 - #include "debug.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> 34 36 #include "v9fs.h" 35 - #include "9p.h" 36 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 40 * Option Parsing (code inspired by NFS code) ··· 43 47 44 48 enum { 45 49 /* Options that take integer arguments */ 46 - Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, Opt_debug, 50 + Opt_debug, Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, 47 51 Opt_rfdno, Opt_wfdno, 48 52 /* String options */ 49 53 Opt_uname, Opt_remotename, 50 54 /* Options that take no arguments */ 51 - Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd, 55 + Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd, Opt_pci, 52 56 /* Cache options */ 53 57 Opt_cache_loose, 54 58 /* Error token */ ··· 56 60 }; 57 61 58 62 static match_table_t tokens = { 63 + {Opt_debug, "debug=%x"}, 59 64 {Opt_port, "port=%u"}, 60 65 {Opt_msize, "msize=%u"}, 61 66 {Opt_uid, "uid=%u"}, ··· 64 67 {Opt_afid, "afid=%u"}, 65 68 {Opt_rfdno, "rfdno=%u"}, 66 69 {Opt_wfdno, "wfdno=%u"}, 67 - {Opt_debug, "debug=%x"}, 68 70 {Opt_uname, "uname=%s"}, 69 71 {Opt_remotename, "aname=%s"}, 70 72 {Opt_unix, "proto=unix"}, 71 73 {Opt_tcp, "proto=tcp"}, 72 74 {Opt_fd, "proto=fd"}, 75 + #ifdef CONFIG_PCI_9P 76 + {Opt_pci, "proto=pci"}, 77 + #endif 73 78 {Opt_tcp, "tcp"}, 74 79 {Opt_unix, "unix"}, 75 80 {Opt_fd, "fd"}, ··· 81 82 {Opt_cache_loose, "loose"}, 82 83 {Opt_err, NULL} 83 84 }; 85 + 86 + extern struct p9_transport *p9pci_trans_create(void); 84 87 85 88 /* 86 89 * Parse option string. ··· 123 122 token = match_token(p, tokens, args); 124 123 if (token < Opt_uname) { 125 124 if ((ret = match_int(&args[0], &option)) < 0) { 126 - dprintk(DEBUG_ERROR, 125 + P9_DPRINTK(P9_DEBUG_ERROR, 127 126 "integer field, but no integer?\n"); 128 127 continue; 129 128 } 130 129 } 131 130 switch (token) { 131 + case Opt_debug: 132 + v9ses->debug = option; 133 + p9_debug_level = option; 134 + break; 132 135 case Opt_port: 133 136 v9ses->port = option; 134 137 break; ··· 154 149 case Opt_wfdno: 155 150 v9ses->wfdno = option; 156 151 break; 157 - case Opt_debug: 158 - v9ses->debug = option; 159 - break; 160 152 case Opt_tcp: 161 153 v9ses->proto = PROTO_TCP; 162 154 break; 163 155 case Opt_unix: 164 156 v9ses->proto = PROTO_UNIX; 157 + break; 158 + case Opt_pci: 159 + v9ses->proto = PROTO_PCI; 165 160 break; 166 161 case Opt_fd: 167 162 v9ses->proto = PROTO_FD; ··· 188 183 } 189 184 190 185 /** 191 - * v9fs_inode2v9ses - safely extract v9fs session info from super block 192 - * @inode: inode to extract information from 193 - * 194 - * Paranoid function to extract v9ses information from superblock, 195 - * if anything is missing it will report an error. 196 - * 197 - */ 198 - 199 - struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode) 200 - { 201 - return (inode->i_sb->s_fs_info); 202 - } 203 - 204 - /** 205 - * v9fs_get_idpool - allocate numeric id from pool 206 - * @p - pool to allocate from 207 - * 208 - * XXX - This seems to be an awful generic function, should it be in idr.c with 209 - * the lock included in struct idr? 210 - */ 211 - 212 - int v9fs_get_idpool(struct v9fs_idpool *p) 213 - { 214 - int i = 0; 215 - int error; 216 - 217 - retry: 218 - if (idr_pre_get(&p->pool, GFP_KERNEL) == 0) 219 - return 0; 220 - 221 - if (down_interruptible(&p->lock) == -EINTR) { 222 - eprintk(KERN_WARNING, "Interrupted while locking\n"); 223 - return -1; 224 - } 225 - 226 - /* no need to store exactly p, we just need something non-null */ 227 - error = idr_get_new(&p->pool, p, &i); 228 - up(&p->lock); 229 - 230 - if (error == -EAGAIN) 231 - goto retry; 232 - else if (error) 233 - return -1; 234 - 235 - return i; 236 - } 237 - 238 - /** 239 - * v9fs_put_idpool - release numeric id from pool 240 - * @p - pool to allocate from 241 - * 242 - * XXX - This seems to be an awful generic function, should it be in idr.c with 243 - * the lock included in struct idr? 244 - */ 245 - 246 - void v9fs_put_idpool(int id, struct v9fs_idpool *p) 247 - { 248 - if (down_interruptible(&p->lock) == -EINTR) { 249 - eprintk(KERN_WARNING, "Interrupted while locking\n"); 250 - return; 251 - } 252 - idr_remove(&p->pool, id); 253 - up(&p->lock); 254 - } 255 - 256 - /** 257 - * v9fs_check_idpool - check if the specified id is available 258 - * @id - id to check 259 - * @p - pool 260 - */ 261 - int v9fs_check_idpool(int id, struct v9fs_idpool *p) 262 - { 263 - return idr_find(&p->pool, id) != NULL; 264 - } 265 - 266 - /** 267 186 * v9fs_session_init - initialize session 268 187 * @v9ses: session information structure 269 188 * @dev_name: device being mounted ··· 195 266 * 196 267 */ 197 268 198 - int 199 - v9fs_session_init(struct v9fs_session_info *v9ses, 269 + struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, 200 270 const char *dev_name, char *data) 201 271 { 202 - struct v9fs_fcall *fcall = NULL; 203 - struct v9fs_transport *trans_proto; 204 - int n = 0; 205 - int newfid = -1; 206 272 int retval = -EINVAL; 207 - struct v9fs_str *version; 273 + struct p9_transport *trans; 274 + struct p9_fid *fid; 208 275 209 276 v9ses->name = __getname(); 210 277 if (!v9ses->name) 211 - return -ENOMEM; 278 + return ERR_PTR(-ENOMEM); 212 279 213 280 v9ses->remotename = __getname(); 214 281 if (!v9ses->remotename) { 215 282 __putname(v9ses->name); 216 - return -ENOMEM; 283 + return ERR_PTR(-ENOMEM); 217 284 } 218 285 219 286 strcpy(v9ses->name, V9FS_DEFUSER); ··· 217 292 218 293 v9fs_parse_options(data, v9ses); 219 294 220 - /* set global debug level */ 221 - v9fs_debug_level = v9ses->debug; 222 - 223 - /* id pools that are session-dependent: fids and tags */ 224 - idr_init(&v9ses->fidpool.pool); 225 - init_MUTEX(&v9ses->fidpool.lock); 226 - 227 295 switch (v9ses->proto) { 228 296 case PROTO_TCP: 229 - trans_proto = &v9fs_trans_tcp; 297 + trans = p9_trans_create_tcp(dev_name, v9ses->port); 230 298 break; 231 299 case PROTO_UNIX: 232 - trans_proto = &v9fs_trans_unix; 300 + trans = p9_trans_create_unix(dev_name); 233 301 *v9ses->remotename = 0; 234 302 break; 235 303 case PROTO_FD: 236 - trans_proto = &v9fs_trans_fd; 304 + trans = p9_trans_create_fd(v9ses->rfdno, v9ses->wfdno); 237 305 *v9ses->remotename = 0; 238 306 break; 307 + #ifdef CONFIG_PCI_9P 308 + case PROTO_PCI: 309 + trans = p9pci_trans_create(); 310 + *v9ses->remotename = 0; 311 + break; 312 + #endif 239 313 default: 240 314 printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto); 241 315 retval = -ENOPROTOOPT; 242 - goto SessCleanUp; 316 + goto error; 243 317 }; 244 318 245 - v9ses->transport = kmalloc(sizeof(*v9ses->transport), GFP_KERNEL); 246 - if (!v9ses->transport) { 247 - retval = -ENOMEM; 248 - goto SessCleanUp; 319 + if (IS_ERR(trans)) { 320 + retval = PTR_ERR(trans); 321 + trans = NULL; 322 + goto error; 249 323 } 250 324 251 - memmove(v9ses->transport, trans_proto, sizeof(*v9ses->transport)); 325 + v9ses->clnt = p9_client_create(trans, v9ses->maxdata + P9_IOHDRSZ, 326 + v9ses->extended); 252 327 253 - if ((retval = v9ses->transport->init(v9ses, dev_name, data)) < 0) { 254 - eprintk(KERN_ERR, "problem initializing transport\n"); 255 - goto SessCleanUp; 328 + if (IS_ERR(v9ses->clnt)) { 329 + retval = PTR_ERR(v9ses->clnt); 330 + v9ses->clnt = NULL; 331 + P9_DPRINTK(P9_DEBUG_ERROR, "problem initializing 9p client\n"); 332 + goto error; 256 333 } 257 334 258 - v9ses->inprogress = 0; 259 - v9ses->shutdown = 0; 260 - v9ses->session_hung = 0; 261 - 262 - v9ses->mux = v9fs_mux_init(v9ses->transport, v9ses->maxdata + V9FS_IOHDRSZ, 263 - &v9ses->extended); 264 - 265 - if (IS_ERR(v9ses->mux)) { 266 - retval = PTR_ERR(v9ses->mux); 267 - v9ses->mux = NULL; 268 - dprintk(DEBUG_ERROR, "problem initializing mux\n"); 269 - goto SessCleanUp; 335 + fid = p9_client_attach(v9ses->clnt, NULL, v9ses->name, 336 + v9ses->remotename); 337 + if (IS_ERR(fid)) { 338 + retval = PTR_ERR(fid); 339 + fid = NULL; 340 + P9_DPRINTK(P9_DEBUG_ERROR, "cannot attach\n"); 341 + goto error; 270 342 } 271 343 272 - if (v9ses->afid == ~0) { 273 - if (v9ses->extended) 274 - retval = 275 - v9fs_t_version(v9ses, v9ses->maxdata, "9P2000.u", 276 - &fcall); 277 - else 278 - retval = v9fs_t_version(v9ses, v9ses->maxdata, "9P2000", 279 - &fcall); 344 + return fid; 280 345 281 - if (retval < 0) { 282 - dprintk(DEBUG_ERROR, "v9fs_t_version failed\n"); 283 - goto FreeFcall; 284 - } 285 - 286 - version = &fcall->params.rversion.version; 287 - if (version->len==8 && !memcmp(version->str, "9P2000.u", 8)) { 288 - dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n"); 289 - v9ses->extended = 1; 290 - } else if (version->len==6 && !memcmp(version->str, "9P2000", 6)) { 291 - dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n"); 292 - v9ses->extended = 0; 293 - } else { 294 - retval = -EREMOTEIO; 295 - goto FreeFcall; 296 - } 297 - 298 - n = fcall->params.rversion.msize; 299 - kfree(fcall); 300 - 301 - if (n < v9ses->maxdata) 302 - v9ses->maxdata = n; 303 - } 304 - 305 - newfid = v9fs_get_idpool(&v9ses->fidpool); 306 - if (newfid < 0) { 307 - eprintk(KERN_WARNING, "couldn't allocate FID\n"); 308 - retval = -ENOMEM; 309 - goto SessCleanUp; 310 - } 311 - /* it is a little bit ugly, but we have to prevent newfid */ 312 - /* being the same as afid, so if it is, get a new fid */ 313 - if (v9ses->afid != ~0 && newfid == v9ses->afid) { 314 - newfid = v9fs_get_idpool(&v9ses->fidpool); 315 - if (newfid < 0) { 316 - eprintk(KERN_WARNING, "couldn't allocate FID\n"); 317 - retval = -ENOMEM; 318 - goto SessCleanUp; 319 - } 320 - } 321 - 322 - if ((retval = 323 - v9fs_t_attach(v9ses, v9ses->name, v9ses->remotename, newfid, 324 - v9ses->afid, NULL)) 325 - < 0) { 326 - dprintk(DEBUG_ERROR, "cannot attach\n"); 327 - goto SessCleanUp; 328 - } 329 - 330 - if (v9ses->afid != ~0) { 331 - dprintk(DEBUG_ERROR, "afid not equal to ~0\n"); 332 - if (v9fs_t_clunk(v9ses, v9ses->afid)) 333 - dprintk(DEBUG_ERROR, "clunk failed\n"); 334 - } 335 - 336 - return newfid; 337 - 338 - FreeFcall: 339 - kfree(fcall); 340 - 341 - SessCleanUp: 346 + error: 342 347 v9fs_session_close(v9ses); 343 - return retval; 348 + return ERR_PTR(retval); 344 349 } 345 350 346 351 /** ··· 281 426 282 427 void v9fs_session_close(struct v9fs_session_info *v9ses) 283 428 { 284 - if (v9ses->mux) { 285 - v9fs_mux_destroy(v9ses->mux); 286 - v9ses->mux = NULL; 287 - } 288 - 289 - if (v9ses->transport) { 290 - v9ses->transport->close(v9ses->transport); 291 - kfree(v9ses->transport); 292 - v9ses->transport = NULL; 429 + if (v9ses->clnt) { 430 + p9_client_destroy(v9ses->clnt); 431 + v9ses->clnt = NULL; 293 432 } 294 433 295 434 __putname(v9ses->name); ··· 295 446 * and cancel all pending requests. 296 447 */ 297 448 void v9fs_session_cancel(struct v9fs_session_info *v9ses) { 298 - dprintk(DEBUG_ERROR, "cancel session %p\n", v9ses); 299 - v9ses->transport->status = Disconnected; 300 - v9fs_mux_cancel(v9ses->mux, -EIO); 449 + P9_DPRINTK(P9_DEBUG_ERROR, "cancel session %p\n", v9ses); 450 + p9_client_disconnect(v9ses->clnt); 301 451 } 302 452 303 453 extern int v9fs_error_init(void); ··· 308 460 309 461 static int __init init_v9fs(void) 310 462 { 311 - int ret; 312 - 313 - v9fs_error_init(); 314 - 315 463 printk(KERN_INFO "Installing v9fs 9p2000 file system support\n"); 316 464 317 - ret = v9fs_mux_global_init(); 318 - if (ret) { 319 - printk(KERN_WARNING "v9fs: starting mux failed\n"); 320 - return ret; 321 - } 322 - ret = register_filesystem(&v9fs_fs_type); 323 - if (ret) { 324 - printk(KERN_WARNING "v9fs: registering file system failed\n"); 325 - v9fs_mux_global_exit(); 326 - } 327 - 328 - return ret; 465 + return register_filesystem(&v9fs_fs_type); 329 466 } 330 467 331 468 /** ··· 320 487 321 488 static void __exit exit_v9fs(void) 322 489 { 323 - v9fs_mux_global_exit(); 324 490 unregister_filesystem(&v9fs_fs_type); 325 491 } 326 492 327 493 module_init(init_v9fs) 328 494 module_exit(exit_v9fs) 329 495 496 + MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>"); 330 497 MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>"); 331 498 MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>"); 332 499 MODULE_LICENSE("GPL");
+8 -24
fs/9p/v9fs.h
··· 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 25 * Session structure provides information for an opened session 36 26 * 37 27 */ ··· 44 54 unsigned int uid; /* default uid/muid for legacy support */ 45 55 unsigned int gid; /* default gid for legacy support */ 46 56 47 - /* book keeping */ 48 - struct v9fs_idpool fidpool; /* The FID pool for file descriptors */ 49 - 50 - struct v9fs_transport *transport; 51 - struct v9fs_mux_data *mux; 52 - 53 - int inprogress; /* session in progress => true */ 54 - int shutdown; /* session shutting down. no more attaches. */ 55 - unsigned char session_hung; 57 + struct p9_client *clnt; /* 9p client */ 56 58 struct dentry *debugfs_dir; 57 59 }; 58 60 ··· 53 71 PROTO_TCP, 54 72 PROTO_UNIX, 55 73 PROTO_FD, 74 + PROTO_PCI, 56 75 }; 57 76 58 77 /* possible values of ->cache */ ··· 65 82 66 83 extern struct dentry *v9fs_debugfs_root; 67 84 68 - int v9fs_session_init(struct v9fs_session_info *, const char *, char *); 69 - struct v9fs_session_info *v9fs_inode2v9ses(struct inode *); 85 + struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, 86 + char *); 70 87 void v9fs_session_close(struct v9fs_session_info *v9ses); 71 - int v9fs_get_idpool(struct v9fs_idpool *p); 72 - void v9fs_put_idpool(int id, struct v9fs_idpool *p); 73 - int v9fs_check_idpool(int id, struct v9fs_idpool *p); 74 88 void v9fs_session_cancel(struct v9fs_session_info *v9ses); 75 89 76 90 #define V9FS_MAGIC 0x01021997 ··· 77 97 #define V9FS_DEFUSER "nobody" 78 98 #define V9FS_DEFANAME "" 79 99 100 + static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode) 101 + { 102 + return (inode->i_sb->s_fs_info); 103 + }
+3 -3
fs/9p/v9fs_vfs.h
··· 45 45 extern struct dentry_operations v9fs_cached_dentry_operations; 46 46 47 47 struct inode *v9fs_get_inode(struct super_block *sb, int mode); 48 - ino_t v9fs_qid2ino(struct v9fs_qid *qid); 49 - void v9fs_stat2inode(struct v9fs_stat *, struct inode *, struct super_block *); 48 + ino_t v9fs_qid2ino(struct p9_qid *qid); 49 + void v9fs_stat2inode(struct p9_stat *, struct inode *, struct super_block *); 50 50 int v9fs_dir_release(struct inode *inode, struct file *filp); 51 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 53 void v9fs_dentry_release(struct dentry *); 54 54 int v9fs_uflags2omode(int uflags);
+14 -43
fs/9p/vfs_addr.c
··· 33 33 #include <linux/pagemap.h> 34 34 #include <linux/idr.h> 35 35 #include <linux/sched.h> 36 + #include <net/9p/9p.h> 37 + #include <net/9p/client.h> 36 38 37 - #include "debug.h" 38 39 #include "v9fs.h" 39 - #include "9p.h" 40 40 #include "v9fs_vfs.h" 41 41 #include "fid.h" 42 42 ··· 50 50 51 51 static int v9fs_vfs_readpage(struct file *filp, struct page *page) 52 52 { 53 - char *buffer = NULL; 54 - int retval = -EIO; 55 - loff_t offset = page_offset(page); 56 - int count = PAGE_CACHE_SIZE; 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; 53 + int retval; 54 + loff_t offset; 55 + char *buffer; 56 + struct p9_fid *fid; 65 57 66 - dprintk(DEBUG_VFS, "\n"); 67 - 58 + P9_DPRINTK(P9_DEBUG_VFS, "\n"); 59 + fid = filp->private_data; 68 60 buffer = kmap(page); 69 - do { 70 - if (count < rsize) 71 - rsize = count; 61 + offset = page_offset(page); 72 62 73 - result = v9fs_t_read(v9ses, fid, offset, rsize, &fcall); 63 + retval = p9_client_readn(fid, buffer, offset, PAGE_CACHE_SIZE); 64 + if (retval < 0) 65 + goto done; 74 66 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 - 92 - if (result < rsize) 93 - break; 94 - } while (count); 95 - 96 - memset(buffer, 0, count); 67 + memset(buffer + retval, 0, PAGE_CACHE_SIZE - retval); 97 68 flush_dcache_page(page); 98 69 SetPageUptodate(page); 99 70 retval = 0; 100 71 101 - UnmapAndUnlock: 72 + done: 102 73 kunmap(page); 103 74 unlock_page(page); 104 75 return retval;
+14 -21
fs/9p/vfs_dentry.c
··· 34 34 #include <linux/namei.h> 35 35 #include <linux/idr.h> 36 36 #include <linux/sched.h> 37 + #include <net/9p/9p.h> 38 + #include <net/9p/client.h> 37 39 38 - #include "debug.h" 39 40 #include "v9fs.h" 40 - #include "9p.h" 41 41 #include "v9fs_vfs.h" 42 42 #include "fid.h" 43 43 ··· 52 52 53 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 57 return 1; 58 58 } ··· 69 69 static int v9fs_cached_dentry_delete(struct dentry *dentry) 70 70 { 71 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 74 if(!inode) 75 75 return 1; ··· 85 85 86 86 void v9fs_dentry_release(struct dentry *dentry) 87 87 { 88 - int err; 88 + struct v9fs_dentry *dent; 89 + struct p9_fid *temp, *current_fid; 89 90 90 - dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); 91 - 92 - if (dentry->d_fsdata != NULL) { 93 - struct list_head *fid_list = dentry->d_fsdata; 94 - struct v9fs_fid *temp = NULL; 95 - struct v9fs_fid *current_fid = NULL; 96 - 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); 91 + P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); 92 + dent = dentry->d_fsdata; 93 + if (dent) { 94 + list_for_each_entry_safe(current_fid, temp, &dent->fidlist, 95 + dlist) { 96 + p9_client_clunk(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
+31 -118
fs/9p/vfs_dir.c
··· 32 32 #include <linux/sched.h> 33 33 #include <linux/inet.h> 34 34 #include <linux/idr.h> 35 + #include <net/9p/9p.h> 36 + #include <net/9p/client.h> 35 37 36 - #include "debug.h" 37 38 #include "v9fs.h" 38 - #include "9p.h" 39 - #include "conv.h" 40 39 #include "v9fs_vfs.h" 41 40 #include "fid.h" 42 41 ··· 45 46 * 46 47 */ 47 48 48 - static inline int dt_type(struct v9fs_stat *mistat) 49 + static inline int dt_type(struct p9_stat *mistat) 49 50 { 50 51 unsigned long perm = mistat->mode; 51 52 int rettype = DT_REG; 52 53 53 - if (perm & V9FS_DMDIR) 54 + if (perm & P9_DMDIR) 54 55 rettype = DT_DIR; 55 - if (perm & V9FS_DMSYMLINK) 56 + if (perm & P9_DMSYMLINK) 56 57 rettype = DT_LNK; 57 58 58 59 return rettype; ··· 68 69 69 70 static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) 70 71 { 71 - struct v9fs_fcall *fcall = NULL; 72 - struct inode *inode = filp->f_path.dentry->d_inode; 73 - struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); 74 - struct v9fs_fid *file = filp->private_data; 75 - unsigned int i, n, s; 76 - int fid = -1; 77 - int ret = 0; 78 - struct v9fs_stat stat; 79 - int over = 0; 72 + int over; 73 + struct p9_fid *fid; 74 + struct v9fs_session_info *v9ses; 75 + struct inode *inode; 76 + struct p9_stat *st; 80 77 81 - dprintk(DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name); 78 + P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name); 79 + inode = filp->f_path.dentry->d_inode; 80 + v9ses = v9fs_inode2v9ses(inode); 81 + fid = filp->private_data; 82 + while ((st = p9_client_dirread(fid, filp->f_pos)) != NULL) { 83 + if (IS_ERR(st)) 84 + return PTR_ERR(st); 82 85 83 - fid = file->fid; 86 + over = filldir(dirent, st->name.str, st->name.len, filp->f_pos, 87 + v9fs_qid2ino(&st->qid), dt_type(st)); 84 88 85 - if (file->rdir_fcall && (filp->f_pos != file->rdir_pos)) { 86 - kfree(file->rdir_fcall); 87 - file->rdir_fcall = NULL; 88 - } 89 - 90 - if (file->rdir_fcall) { 91 - n = file->rdir_fcall->params.rread.count; 92 - i = file->rdir_fpos; 93 - while (i < n) { 94 - s = v9fs_deserialize_stat( 95 - file->rdir_fcall->params.rread.data + i, 96 - n - i, &stat, v9ses->extended); 97 - 98 - if (s == 0) { 99 - dprintk(DEBUG_ERROR, 100 - "error while deserializing stat\n"); 101 - ret = -EIO; 102 - goto FreeStructs; 103 - } 104 - 105 - over = filldir(dirent, stat.name.str, stat.name.len, 106 - filp->f_pos, v9fs_qid2ino(&stat.qid), 107 - dt_type(&stat)); 108 - 109 - if (over) { 110 - file->rdir_fpos = i; 111 - file->rdir_pos = filp->f_pos; 112 - break; 113 - } 114 - 115 - i += s; 116 - filp->f_pos += s; 117 - } 118 - 119 - if (!over) { 120 - kfree(file->rdir_fcall); 121 - file->rdir_fcall = NULL; 122 - } 123 - } 124 - 125 - while (!over) { 126 - ret = v9fs_t_read(v9ses, fid, filp->f_pos, 127 - v9ses->maxdata-V9FS_IOHDRSZ, &fcall); 128 - if (ret < 0) { 129 - dprintk(DEBUG_ERROR, "error while reading: %d: %p\n", 130 - ret, fcall); 131 - goto FreeStructs; 132 - } else if (ret == 0) 89 + if (over) 133 90 break; 134 91 135 - n = ret; 136 - i = 0; 137 - while (i < n) { 138 - s = v9fs_deserialize_stat(fcall->params.rread.data + i, 139 - n - i, &stat, v9ses->extended); 140 - 141 - if (s == 0) { 142 - dprintk(DEBUG_ERROR, 143 - "error while deserializing stat\n"); 144 - return -EIO; 145 - } 146 - 147 - over = filldir(dirent, stat.name.str, stat.name.len, 148 - filp->f_pos, v9fs_qid2ino(&stat.qid), 149 - dt_type(&stat)); 150 - 151 - if (over) { 152 - file->rdir_fcall = fcall; 153 - file->rdir_fpos = i; 154 - file->rdir_pos = filp->f_pos; 155 - fcall = NULL; 156 - break; 157 - } 158 - 159 - i += s; 160 - filp->f_pos += s; 161 - } 162 - 163 - kfree(fcall); 92 + filp->f_pos += st->size; 93 + kfree(st); 94 + st = NULL; 164 95 } 165 96 166 - FreeStructs: 167 - kfree(fcall); 168 - return ret; 97 + kfree(st); 98 + return 0; 169 99 } 100 + 170 101 171 102 /** 172 103 * v9fs_dir_release - close a directory ··· 107 178 108 179 int v9fs_dir_release(struct inode *inode, struct file *filp) 109 180 { 110 - struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); 111 - struct v9fs_fid *fid = filp->private_data; 112 - int fidnum = -1; 181 + struct p9_fid *fid; 113 182 114 - dprintk(DEBUG_VFS, "inode: %p filp: %p fid: %d\n", inode, filp, 115 - fid->fid); 116 - fidnum = fid->fid; 117 - 183 + fid = filp->private_data; 184 + P9_DPRINTK(P9_DEBUG_VFS, 185 + "inode: %p filp: %p fid: %d\n", inode, filp, fid->fid); 118 186 filemap_write_and_wait(inode->i_mapping); 119 - 120 - if (fidnum >= 0) { 121 - dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen, 122 - fid->fid); 123 - 124 - if (v9fs_t_clunk(v9ses, fidnum)) 125 - dprintk(DEBUG_ERROR, "clunk failed\n"); 126 - 127 - kfree(fid->rdir_fcall); 128 - kfree(fid); 129 - 130 - filp->private_data = NULL; 131 - } 132 - 187 + p9_client_clunk(fid); 133 188 return 0; 134 189 } 135 190
+47 -119
fs/9p/vfs_file.c
··· 34 34 #include <linux/list.h> 35 35 #include <asm/uaccess.h> 36 36 #include <linux/idr.h> 37 + #include <net/9p/9p.h> 38 + #include <net/9p/client.h> 37 39 38 - #include "debug.h" 39 40 #include "v9fs.h" 40 - #include "9p.h" 41 41 #include "v9fs_vfs.h" 42 42 #include "fid.h" 43 43 ··· 52 52 53 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 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); 62 - 63 - vfid = v9fs_fid_clone(file->f_path.dentry); 64 - if (IS_ERR(vfid)) 65 - return PTR_ERR(vfid); 66 - 60 + P9_DPRINTK(P9_DEBUG_VFS, "inode: %p file: %p \n", inode, file); 61 + v9ses = v9fs_inode2v9ses(inode); 67 62 omode = v9fs_uflags2omode(file->f_flags); 68 - err = v9fs_t_open(v9ses, vfid->fid, omode, &fcall); 69 - if (err < 0) { 70 - PRINT_FCALL_ERROR("open failed", fcall); 71 - goto Clunk_Fid; 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); 70 + if (err < 0) { 71 + p9_client_clunk(fid); 72 + return err; 73 + } 74 + if (omode & P9_OTRUNC) { 75 + inode->i_size = 0; 76 + inode->i_blocks = 0; 77 + } 72 78 } 73 79 74 - file->private_data = vfid; 75 - vfid->fidopen = 1; 76 - vfid->fidclunked = 0; 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"); 80 + file->private_data = fid; 81 + if ((fid->qid.version) && (v9ses->cache)) { 82 + P9_DPRINTK(P9_DEBUG_VFS, "cached"); 85 83 /* enable cached file options */ 86 84 if(file->f_op == &v9fs_file_operations) 87 85 file->f_op = &v9fs_cached_file_operations; 88 86 } 89 87 90 88 return 0; 91 - 92 - Clunk_Fid: 93 - v9fs_fid_clunk(v9ses, vfid); 94 - kfree(fcall); 95 - 96 - return err; 97 89 } 98 90 99 91 /** ··· 102 110 int res = 0; 103 111 struct inode *inode = filp->f_path.dentry->d_inode; 104 112 105 - dprintk(DEBUG_VFS, "filp: %p lock: %p\n", filp, fl); 113 + P9_DPRINTK(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl); 106 114 107 115 /* No mandatory locks */ 108 116 if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) ··· 128 136 v9fs_file_read(struct file *filp, char __user * data, size_t count, 129 137 loff_t * offset) 130 138 { 131 - struct inode *inode = filp->f_path.dentry->d_inode; 132 - struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); 133 - struct v9fs_fid *v9f = filp->private_data; 134 - struct v9fs_fcall *fcall = NULL; 135 - int fid = v9f->fid; 136 - int rsize = 0; 137 - int result = 0; 138 - int total = 0; 139 - int n; 139 + int ret; 140 + struct p9_fid *fid; 140 141 141 - dprintk(DEBUG_VFS, "\n"); 142 + P9_DPRINTK(P9_DEBUG_VFS, "\n"); 143 + fid = filp->private_data; 144 + ret = p9_client_uread(fid, data, *offset, count); 145 + if (ret > 0) 146 + *offset += ret; 142 147 143 - rsize = v9ses->maxdata - V9FS_IOHDRSZ; 144 - if (v9f->iounit != 0 && rsize > v9f->iounit) 145 - rsize = v9f->iounit; 146 - 147 - do { 148 - if (count < rsize) 149 - rsize = count; 150 - 151 - result = v9fs_t_read(v9ses, fid, *offset, rsize, &fcall); 152 - 153 - if (result < 0) { 154 - printk(KERN_ERR "9P2000: v9fs_t_read returned %d\n", 155 - result); 156 - 157 - kfree(fcall); 158 - return total; 159 - } else 160 - *offset += result; 161 - 162 - n = copy_to_user(data, fcall->params.rread.data, result); 163 - if (n) { 164 - dprintk(DEBUG_ERROR, "Problem copying to user %d\n", n); 165 - kfree(fcall); 166 - return -EFAULT; 167 - } 168 - 169 - count -= result; 170 - data += result; 171 - total += result; 172 - 173 - kfree(fcall); 174 - 175 - if (result < rsize) 176 - break; 177 - } while (count); 178 - 179 - return total; 148 + return ret; 180 149 } 181 150 182 151 /** ··· 153 200 v9fs_file_write(struct file *filp, const char __user * data, 154 201 size_t count, loff_t * offset) 155 202 { 203 + int ret; 204 + struct p9_fid *fid; 156 205 struct inode *inode = filp->f_path.dentry->d_inode; 157 - struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); 158 - struct v9fs_fid *v9fid = filp->private_data; 159 - struct v9fs_fcall *fcall; 160 - int fid = v9fid->fid; 161 - int result = -EIO; 162 - int rsize = 0; 163 - int total = 0; 164 206 165 - dprintk(DEBUG_VFS, "data %p count %d offset %x\n", data, (int)count, 166 - (int)*offset); 167 - rsize = v9ses->maxdata - V9FS_IOHDRSZ; 168 - if (v9fid->iounit != 0 && rsize > v9fid->iounit) 169 - rsize = v9fid->iounit; 207 + P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data, 208 + (int)count, (int)*offset); 170 209 171 - do { 172 - if (count < rsize) 173 - rsize = count; 210 + fid = filp->private_data; 211 + ret = p9_client_uwrite(fid, data, *offset, count); 212 + if (ret > 0) 213 + *offset += ret; 174 214 175 - result = v9fs_t_write(v9ses, fid, *offset, rsize, data, &fcall); 176 - if (result < 0) { 177 - PRINT_FCALL_ERROR("error while writing", fcall); 178 - kfree(fcall); 179 - return result; 180 - } else 181 - *offset += result; 182 - 183 - kfree(fcall); 184 - fcall = NULL; 185 - 186 - if (result != rsize) { 187 - eprintk(KERN_ERR, 188 - "short write: v9fs_t_write returned %d\n", 189 - result); 190 - break; 191 - } 192 - 193 - count -= result; 194 - data += result; 195 - total += result; 196 - } while (count); 215 + if (*offset > inode->i_size) { 216 + inode->i_size = *offset; 217 + inode->i_blocks = (inode->i_size + 512 - 1) >> 9; 218 + } 197 219 198 220 invalidate_inode_pages2(inode->i_mapping); 199 - return total; 221 + return ret; 200 222 } 201 223 202 224 static const struct file_operations v9fs_cached_file_operations = {
+285 -469
fs/9p/vfs_inode.c
··· 34 34 #include <linux/namei.h> 35 35 #include <linux/idr.h> 36 36 #include <linux/sched.h> 37 + #include <net/9p/9p.h> 38 + #include <net/9p/client.h> 37 39 38 - #include "debug.h" 39 40 #include "v9fs.h" 40 - #include "9p.h" 41 41 #include "v9fs_vfs.h" 42 42 #include "fid.h" 43 43 ··· 58 58 int res; 59 59 res = mode & 0777; 60 60 if (S_ISDIR(mode)) 61 - res |= V9FS_DMDIR; 61 + res |= P9_DMDIR; 62 62 if (v9ses->extended) { 63 63 if (S_ISLNK(mode)) 64 - res |= V9FS_DMSYMLINK; 64 + res |= P9_DMSYMLINK; 65 65 if (v9ses->nodev == 0) { 66 66 if (S_ISSOCK(mode)) 67 - res |= V9FS_DMSOCKET; 67 + res |= P9_DMSOCKET; 68 68 if (S_ISFIFO(mode)) 69 - res |= V9FS_DMNAMEDPIPE; 69 + res |= P9_DMNAMEDPIPE; 70 70 if (S_ISBLK(mode)) 71 - res |= V9FS_DMDEVICE; 71 + res |= P9_DMDEVICE; 72 72 if (S_ISCHR(mode)) 73 - res |= V9FS_DMDEVICE; 73 + res |= P9_DMDEVICE; 74 74 } 75 75 76 76 if ((mode & S_ISUID) == S_ISUID) 77 - res |= V9FS_DMSETUID; 77 + res |= P9_DMSETUID; 78 78 if ((mode & S_ISGID) == S_ISGID) 79 - res |= V9FS_DMSETGID; 80 - if ((mode & V9FS_DMLINK)) 81 - res |= V9FS_DMLINK; 79 + res |= P9_DMSETGID; 80 + if ((mode & P9_DMLINK)) 81 + res |= P9_DMLINK; 82 82 } 83 83 84 84 return res; ··· 97 97 98 98 res = mode & 0777; 99 99 100 - if ((mode & V9FS_DMDIR) == V9FS_DMDIR) 100 + if ((mode & P9_DMDIR) == P9_DMDIR) 101 101 res |= S_IFDIR; 102 - else if ((mode & V9FS_DMSYMLINK) && (v9ses->extended)) 102 + else if ((mode & P9_DMSYMLINK) && (v9ses->extended)) 103 103 res |= S_IFLNK; 104 - else if ((mode & V9FS_DMSOCKET) && (v9ses->extended) 104 + else if ((mode & P9_DMSOCKET) && (v9ses->extended) 105 105 && (v9ses->nodev == 0)) 106 106 res |= S_IFSOCK; 107 - else if ((mode & V9FS_DMNAMEDPIPE) && (v9ses->extended) 107 + else if ((mode & P9_DMNAMEDPIPE) && (v9ses->extended) 108 108 && (v9ses->nodev == 0)) 109 109 res |= S_IFIFO; 110 - else if ((mode & V9FS_DMDEVICE) && (v9ses->extended) 110 + else if ((mode & P9_DMDEVICE) && (v9ses->extended) 111 111 && (v9ses->nodev == 0)) 112 112 res |= S_IFBLK; 113 113 else 114 114 res |= S_IFREG; 115 115 116 116 if (v9ses->extended) { 117 - if ((mode & V9FS_DMSETUID) == V9FS_DMSETUID) 117 + if ((mode & P9_DMSETUID) == P9_DMSETUID) 118 118 res |= S_ISUID; 119 119 120 - if ((mode & V9FS_DMSETGID) == V9FS_DMSETGID) 120 + if ((mode & P9_DMSETGID) == P9_DMSETGID) 121 121 res |= S_ISGID; 122 122 } 123 123 ··· 132 132 switch (uflags&3) { 133 133 default: 134 134 case O_RDONLY: 135 - ret = V9FS_OREAD; 135 + ret = P9_OREAD; 136 136 break; 137 137 138 138 case O_WRONLY: 139 - ret = V9FS_OWRITE; 139 + ret = P9_OWRITE; 140 140 break; 141 141 142 142 case O_RDWR: 143 - ret = V9FS_ORDWR; 143 + ret = P9_ORDWR; 144 144 break; 145 145 } 146 146 147 147 if (uflags & O_EXCL) 148 - ret |= V9FS_OEXCL; 148 + ret |= P9_OEXCL; 149 149 150 150 if (uflags & O_TRUNC) 151 - ret |= V9FS_OTRUNC; 151 + ret |= P9_OTRUNC; 152 152 153 153 if (uflags & O_APPEND) 154 - ret |= V9FS_OAPPEND; 154 + ret |= P9_OAPPEND; 155 155 156 156 return ret; 157 157 } ··· 164 164 */ 165 165 166 166 static void 167 - v9fs_blank_wstat(struct v9fs_wstat *wstat) 167 + v9fs_blank_wstat(struct p9_wstat *wstat) 168 168 { 169 169 wstat->type = ~0; 170 170 wstat->dev = ~0; ··· 197 197 struct inode *inode; 198 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 202 inode = new_inode(sb); 203 203 if (inode) { ··· 215 215 case S_IFCHR: 216 216 case S_IFSOCK: 217 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 220 return ERR_PTR(-EINVAL); 220 221 } 221 222 init_special_inode(inode, inode->i_mode, ··· 228 227 break; 229 228 case S_IFLNK: 230 229 if(!v9ses->extended) { 231 - dprintk(DEBUG_ERROR, "extended modes used w/o 9P2000.u\n"); 230 + P9_DPRINTK(P9_DEBUG_ERROR, 231 + "extended modes used w/o 9P2000.u\n"); 232 232 return ERR_PTR(-EINVAL); 233 233 } 234 234 inode->i_op = &v9fs_symlink_inode_operations; ··· 243 241 inode->i_fop = &v9fs_dir_operations; 244 242 break; 245 243 default: 246 - dprintk(DEBUG_ERROR, "BAD mode 0x%x S_IFMT 0x%x\n", 244 + P9_DPRINTK(P9_DEBUG_ERROR, 245 + "BAD mode 0x%x S_IFMT 0x%x\n", 247 246 mode, mode & S_IFMT); 248 247 return ERR_PTR(-EINVAL); 249 248 } 250 249 } else { 251 - eprintk(KERN_WARNING, "Problem allocating inode\n"); 250 + P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n"); 252 251 return ERR_PTR(-ENOMEM); 253 252 } 254 253 return inode; 255 254 } 256 255 257 - static int 258 - v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm, 259 - u8 mode, char *extension, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) 260 - { 261 - int fid; 262 - int err; 263 - struct v9fs_fcall *fcall; 264 - 265 - fid = v9fs_get_idpool(&v9ses->fidpool); 266 - if (fid < 0) { 267 - eprintk(KERN_WARNING, "no free fids available\n"); 268 - return -ENOSPC; 269 - } 270 - 271 - err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); 272 - if (err < 0) { 273 - PRINT_FCALL_ERROR("clone error", fcall); 274 - if (fcall && fcall->id == RWALK) 275 - goto clunk_fid; 276 - else 277 - goto put_fid; 278 - } 279 - kfree(fcall); 280 - 281 - err = v9fs_t_create(v9ses, fid, name, perm, mode, extension, &fcall); 282 - if (err < 0) { 283 - PRINT_FCALL_ERROR("create fails", fcall); 284 - goto clunk_fid; 285 - } 286 - 287 - if (iounit) 288 - *iounit = fcall->params.rcreate.iounit; 289 - 290 - if (qid) 291 - *qid = fcall->params.rcreate.qid; 292 - 293 - if (fidp) 294 - *fidp = fid; 295 - 296 - kfree(fcall); 297 - return 0; 298 - 299 - clunk_fid: 300 - v9fs_t_clunk(v9ses, fid); 301 - fid = V9FS_NOFID; 302 - 303 - put_fid: 304 - if (fid != V9FS_NOFID) 305 - v9fs_put_idpool(fid, &v9ses->fidpool); 306 - 307 - kfree(fcall); 308 - return err; 309 - } 310 - 256 + /* 311 257 static struct v9fs_fid* 312 258 v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) 313 259 { ··· 305 355 kfree(fcall); 306 356 return ERR_PTR(err); 307 357 } 358 + */ 308 359 309 360 static struct inode * 310 - v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid, 361 + v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, 311 362 struct super_block *sb) 312 363 { 313 364 int err, umode; 314 365 struct inode *ret; 315 - struct v9fs_fcall *fcall; 366 + struct p9_stat *st; 316 367 317 368 ret = NULL; 318 - err = v9fs_t_stat(v9ses, fid, &fcall); 319 - if (err) { 320 - PRINT_FCALL_ERROR("stat error", fcall); 369 + st = p9_client_stat(fid); 370 + if (IS_ERR(st)) { 371 + err = PTR_ERR(st); 372 + st = NULL; 321 373 goto error; 322 374 } 323 375 324 - umode = p9mode2unixmode(v9ses, fcall->params.rstat.stat.mode); 376 + umode = p9mode2unixmode(v9ses, st->mode); 325 377 ret = v9fs_get_inode(sb, umode); 326 378 if (IS_ERR(ret)) { 327 379 err = PTR_ERR(ret); ··· 331 379 goto error; 332 380 } 333 381 334 - v9fs_stat2inode(&fcall->params.rstat.stat, ret, sb); 335 - kfree(fcall); 382 + v9fs_stat2inode(st, ret, sb); 383 + ret->i_ino = v9fs_qid2ino(&st->qid); 384 + kfree(st); 336 385 return ret; 337 386 338 387 error: 339 - kfree(fcall); 388 + kfree(st); 340 389 if (ret) 341 390 iput(ret); 342 391 ··· 354 401 355 402 static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) 356 403 { 357 - struct v9fs_fcall *fcall = NULL; 358 - struct super_block *sb = NULL; 359 - struct v9fs_session_info *v9ses = NULL; 360 - struct v9fs_fid *v9fid = NULL; 361 - struct inode *file_inode = NULL; 362 - int fid = -1; 363 - int result = 0; 404 + struct inode *file_inode; 405 + struct v9fs_session_info *v9ses; 406 + struct p9_fid *v9fid; 364 407 365 - dprintk(DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file, 408 + P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file, 366 409 rmdir); 367 410 368 411 file_inode = file->d_inode; 369 - sb = file_inode->i_sb; 370 412 v9ses = v9fs_inode2v9ses(file_inode); 371 413 v9fid = v9fs_fid_clone(file); 372 414 if(IS_ERR(v9fid)) 373 415 return PTR_ERR(v9fid); 374 416 375 - fid = v9fid->fid; 376 - if (fid < 0) { 377 - dprintk(DEBUG_ERROR, "inode #%lu, no fid!\n", 378 - file_inode->i_ino); 379 - return -EBADF; 380 - } 381 - 382 - result = v9fs_t_remove(v9ses, fid, &fcall); 383 - if (result < 0) { 384 - PRINT_FCALL_ERROR("remove fails", fcall); 385 - goto Error; 386 - } 387 - 388 - v9fs_put_idpool(fid, &v9ses->fidpool); 389 - v9fs_fid_destroy(v9fid); 390 - 391 - Error: 392 - kfree(fcall); 393 - return result; 417 + return p9_client_remove(v9fid); 394 418 } 395 419 396 420 static int ··· 376 446 return 0; 377 447 } 378 448 449 + 450 + /** 451 + * v9fs_create - Create a file 452 + * @dentry: dentry that is being created 453 + * @perm: create permissions 454 + * @mode: open mode 455 + * 456 + */ 457 + static struct p9_fid * 458 + v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, 459 + struct dentry *dentry, char *extension, u32 perm, u8 mode) 460 + { 461 + int err; 462 + char *name; 463 + struct p9_fid *dfid, *ofid, *fid; 464 + struct inode *inode; 465 + 466 + err = 0; 467 + ofid = NULL; 468 + fid = NULL; 469 + name = (char *) dentry->d_name.name; 470 + dfid = v9fs_fid_clone(dentry->d_parent); 471 + if(IS_ERR(dfid)) { 472 + err = PTR_ERR(dfid); 473 + dfid = NULL; 474 + goto error; 475 + } 476 + 477 + /* clone a fid to use for creation */ 478 + ofid = p9_client_walk(dfid, 0, NULL, 1); 479 + if (IS_ERR(ofid)) { 480 + err = PTR_ERR(ofid); 481 + ofid = NULL; 482 + goto error; 483 + } 484 + 485 + err = p9_client_fcreate(ofid, name, perm, mode, extension); 486 + if (err < 0) 487 + goto error; 488 + 489 + /* now walk from the parent so we can get unopened fid */ 490 + fid = p9_client_walk(dfid, 1, &name, 0); 491 + if (IS_ERR(fid)) { 492 + err = PTR_ERR(fid); 493 + fid = NULL; 494 + goto error; 495 + } else 496 + dfid = NULL; 497 + 498 + /* instantiate inode and assign the unopened fid to the dentry */ 499 + inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 500 + if (IS_ERR(inode)) { 501 + err = PTR_ERR(inode); 502 + goto error; 503 + } 504 + 505 + if(v9ses->cache) 506 + dentry->d_op = &v9fs_cached_dentry_operations; 507 + else 508 + dentry->d_op = &v9fs_dentry_operations; 509 + 510 + d_instantiate(dentry, inode); 511 + v9fs_fid_add(dentry, fid); 512 + return ofid; 513 + 514 + error: 515 + if (dfid) 516 + p9_client_clunk(dfid); 517 + 518 + if (ofid) 519 + p9_client_clunk(ofid); 520 + 521 + if (fid) 522 + p9_client_clunk(fid); 523 + 524 + return ERR_PTR(err); 525 + } 526 + 379 527 /** 380 528 * v9fs_vfs_create - VFS hook to create files 381 - * @inode: directory inode that is being deleted 529 + * @inode: directory inode that is being created 382 530 * @dentry: dentry that is being deleted 383 531 * @mode: create permissions 384 532 * @nd: path information ··· 468 460 struct nameidata *nd) 469 461 { 470 462 int err; 471 - u32 fid, perm, iounit; 463 + u32 perm; 472 464 int flags; 473 465 struct v9fs_session_info *v9ses; 474 - struct v9fs_fid *dfid, *vfid, *ffid; 475 - struct inode *inode; 476 - struct v9fs_qid qid; 466 + struct p9_fid *fid; 477 467 struct file *filp; 478 468 479 - inode = NULL; 480 - vfid = NULL; 469 + err = 0; 470 + fid = NULL; 481 471 v9ses = v9fs_inode2v9ses(dir); 482 - dfid = v9fs_fid_clone(dentry->d_parent); 483 - if(IS_ERR(dfid)) { 484 - err = PTR_ERR(dfid); 485 - goto error; 486 - } 487 - 488 472 perm = unixmode2p9mode(v9ses, mode); 489 473 if (nd && nd->flags & LOOKUP_OPEN) 490 474 flags = nd->intent.open.flags - 1; 491 475 else 492 476 flags = O_RDWR; 493 477 494 - err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, 495 - perm, v9fs_uflags2omode(flags), NULL, &fid, &qid, &iounit); 496 - 497 - if (err) 498 - goto clunk_dfid; 499 - 500 - vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); 501 - v9fs_fid_clunk(v9ses, dfid); 502 - if (IS_ERR(vfid)) { 503 - err = PTR_ERR(vfid); 504 - vfid = NULL; 478 + fid = v9fs_create(v9ses, dir, dentry, NULL, perm, 479 + v9fs_uflags2omode(flags)); 480 + if (IS_ERR(fid)) { 481 + err = PTR_ERR(fid); 482 + fid = NULL; 505 483 goto error; 506 484 } 507 485 508 - inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); 509 - if (IS_ERR(inode)) { 510 - err = PTR_ERR(inode); 511 - inode = NULL; 512 - goto error; 513 - } 514 - 515 - if(v9ses->cache) 516 - dentry->d_op = &v9fs_cached_dentry_operations; 517 - else 518 - dentry->d_op = &v9fs_dentry_operations; 519 - d_instantiate(dentry, inode); 520 - 486 + /* if we are opening a file, assign the open fid to the file */ 521 487 if (nd && nd->flags & LOOKUP_OPEN) { 522 - ffid = v9fs_fid_create(v9ses, fid); 523 - if (!ffid) 524 - return -ENOMEM; 525 - 526 488 filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created); 527 489 if (IS_ERR(filp)) { 528 - v9fs_fid_destroy(ffid); 529 - return PTR_ERR(filp); 490 + err = PTR_ERR(filp); 491 + goto error; 530 492 } 531 493 532 - ffid->rdir_pos = 0; 533 - ffid->rdir_fcall = NULL; 534 - ffid->fidopen = 1; 535 - ffid->iounit = iounit; 536 - ffid->filp = filp; 537 - filp->private_data = ffid; 538 - } 494 + filp->private_data = fid; 495 + } else 496 + p9_client_clunk(fid); 539 497 540 498 return 0; 541 499 542 - clunk_dfid: 543 - v9fs_fid_clunk(v9ses, dfid); 544 - 545 500 error: 546 - if (vfid) 547 - v9fs_fid_destroy(vfid); 501 + if (fid) 502 + p9_client_clunk(fid); 548 503 549 504 return err; 550 505 } ··· 523 552 static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) 524 553 { 525 554 int err; 526 - u32 fid, perm; 555 + u32 perm; 527 556 struct v9fs_session_info *v9ses; 528 - struct v9fs_fid *dfid, *vfid; 529 - struct inode *inode; 557 + struct p9_fid *fid; 530 558 531 - inode = NULL; 532 - vfid = NULL; 559 + P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); 560 + err = 0; 533 561 v9ses = v9fs_inode2v9ses(dir); 534 - dfid = v9fs_fid_clone(dentry->d_parent); 535 - if(IS_ERR(dfid)) { 536 - err = PTR_ERR(dfid); 537 - goto error; 538 - } 539 - 540 562 perm = unixmode2p9mode(v9ses, mode | S_IFDIR); 541 - 542 - err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, 543 - perm, V9FS_OREAD, NULL, &fid, NULL, NULL); 544 - 545 - if (err) { 546 - dprintk(DEBUG_ERROR, "create error %d\n", err); 547 - goto clean_up_dfid; 563 + fid = v9fs_create(v9ses, dir, dentry, NULL, perm, P9_OREAD); 564 + if (IS_ERR(fid)) { 565 + err = PTR_ERR(fid); 566 + fid = NULL; 548 567 } 549 568 550 - vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); 551 - if (IS_ERR(vfid)) { 552 - err = PTR_ERR(vfid); 553 - vfid = NULL; 554 - goto clean_up_dfid; 555 - } 569 + if (fid) 570 + p9_client_clunk(fid); 556 571 557 - v9fs_fid_clunk(v9ses, dfid); 558 - inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); 559 - if (IS_ERR(inode)) { 560 - err = PTR_ERR(inode); 561 - inode = NULL; 562 - v9fs_fid_destroy(vfid); 563 - goto error; 564 - } 565 - 566 - if(v9ses->cache) 567 - dentry->d_op = &v9fs_cached_dentry_operations; 568 - else 569 - dentry->d_op = &v9fs_dentry_operations; 570 - d_instantiate(dentry, inode); 571 - return 0; 572 - 573 - clean_up_dfid: 574 - v9fs_fid_clunk(v9ses, dfid); 575 - 576 - error: 577 572 return err; 578 573 } 579 574 ··· 556 619 { 557 620 struct super_block *sb; 558 621 struct v9fs_session_info *v9ses; 559 - struct v9fs_fid *dirfid; 560 - struct v9fs_fid *fid; 622 + struct p9_fid *dfid, *fid; 561 623 struct inode *inode; 562 - struct v9fs_fcall *fcall = NULL; 563 - int dirfidnum = -1; 564 - int newfid = -1; 624 + char *name; 565 625 int result = 0; 566 626 567 - dprintk(DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", 627 + P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", 568 628 dir, dentry->d_name.name, dentry, nameidata); 569 629 570 630 sb = dir->i_sb; 571 631 v9ses = v9fs_inode2v9ses(dir); 572 - dirfid = v9fs_fid_lookup(dentry->d_parent); 632 + dfid = v9fs_fid_lookup(dentry->d_parent); 633 + if (IS_ERR(dfid)) 634 + return ERR_PTR(PTR_ERR(dfid)); 573 635 574 - if(IS_ERR(dirfid)) 575 - return ERR_PTR(PTR_ERR(dirfid)); 576 - 577 - dirfidnum = dirfid->fid; 578 - 579 - newfid = v9fs_get_idpool(&v9ses->fidpool); 580 - if (newfid < 0) { 581 - eprintk(KERN_WARNING, "newfid fails!\n"); 582 - result = -ENOSPC; 583 - goto Release_Dirfid; 584 - } 585 - 586 - result = v9fs_t_walk(v9ses, dirfidnum, newfid, 587 - (char *)dentry->d_name.name, &fcall); 588 - 589 - up(&dirfid->lock); 590 - 591 - if (result < 0) { 592 - if (fcall && fcall->id == RWALK) 593 - v9fs_t_clunk(v9ses, newfid); 594 - else 595 - v9fs_put_idpool(newfid, &v9ses->fidpool); 596 - 636 + name = (char *) dentry->d_name.name; 637 + fid = p9_client_walk(dfid, 1, &name, 1); 638 + if (IS_ERR(fid)) { 639 + result = PTR_ERR(fid); 597 640 if (result == -ENOENT) { 598 641 d_add(dentry, NULL); 599 - dprintk(DEBUG_VFS, 600 - "Return negative dentry %p count %d\n", 601 - dentry, atomic_read(&dentry->d_count)); 602 - kfree(fcall); 603 642 return NULL; 604 643 } 605 - dprintk(DEBUG_ERROR, "walk error:%d\n", result); 606 - goto FreeFcall; 607 - } 608 - kfree(fcall); 609 644 610 - result = v9fs_t_stat(v9ses, newfid, &fcall); 611 - if (result < 0) { 612 - dprintk(DEBUG_ERROR, "stat error\n"); 613 - goto FreeFcall; 645 + return ERR_PTR(result); 614 646 } 615 647 616 - inode = v9fs_get_inode(sb, p9mode2unixmode(v9ses, 617 - fcall->params.rstat.stat.mode)); 618 - 619 - if (IS_ERR(inode) && (PTR_ERR(inode) == -ENOSPC)) { 620 - eprintk(KERN_WARNING, "inode alloc failes, returns %ld\n", 621 - PTR_ERR(inode)); 622 - 623 - result = -ENOSPC; 624 - goto FreeFcall; 648 + inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 649 + if (IS_ERR(inode)) { 650 + result = PTR_ERR(inode); 651 + inode = NULL; 652 + goto error; 625 653 } 626 654 627 - inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat.qid); 628 - 629 - fid = v9fs_fid_create(v9ses, newfid); 630 - if (fid == NULL) { 631 - dprintk(DEBUG_ERROR, "couldn't insert\n"); 632 - result = -ENOMEM; 633 - goto FreeFcall; 634 - } 635 - 636 - result = v9fs_fid_insert(fid, dentry); 655 + result = v9fs_fid_add(dentry, fid); 637 656 if (result < 0) 638 - goto FreeFcall; 657 + goto error; 639 658 640 - fid->qid = fcall->params.rstat.stat.qid; 641 - v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb); 642 659 if((fid->qid.version)&&(v9ses->cache)) 643 660 dentry->d_op = &v9fs_cached_dentry_operations; 644 661 else 645 662 dentry->d_op = &v9fs_dentry_operations; 646 663 647 664 d_add(dentry, inode); 648 - kfree(fcall); 649 - 650 665 return NULL; 651 666 652 - Release_Dirfid: 653 - up(&dirfid->lock); 654 - 655 - FreeFcall: 656 - kfree(fcall); 667 + error: 668 + if (fid) 669 + p9_client_clunk(fid); 657 670 658 671 return ERR_PTR(result); 659 672 } ··· 645 758 v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, 646 759 struct inode *new_dir, struct dentry *new_dentry) 647 760 { 648 - struct inode *old_inode = old_dentry->d_inode; 649 - struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode); 650 - struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry); 651 - struct v9fs_fid *olddirfid; 652 - struct v9fs_fid *newdirfid; 653 - struct v9fs_wstat wstat; 654 - struct v9fs_fcall *fcall = NULL; 655 - int fid = -1; 656 - int olddirfidnum = -1; 657 - int newdirfidnum = -1; 658 - int retval = 0; 761 + struct inode *old_inode; 762 + struct v9fs_session_info *v9ses; 763 + struct p9_fid *oldfid; 764 + struct p9_fid *olddirfid; 765 + struct p9_fid *newdirfid; 766 + struct p9_wstat wstat; 767 + int retval; 659 768 660 - dprintk(DEBUG_VFS, "\n"); 661 - 769 + P9_DPRINTK(P9_DEBUG_VFS, "\n"); 770 + retval = 0; 771 + old_inode = old_dentry->d_inode; 772 + v9ses = v9fs_inode2v9ses(old_inode); 773 + oldfid = v9fs_fid_lookup(old_dentry); 662 774 if(IS_ERR(oldfid)) 663 775 return PTR_ERR(oldfid); 664 776 665 777 olddirfid = v9fs_fid_clone(old_dentry->d_parent); 666 778 if(IS_ERR(olddirfid)) { 667 779 retval = PTR_ERR(olddirfid); 668 - goto Release_lock; 780 + goto done; 669 781 } 670 782 671 783 newdirfid = v9fs_fid_clone(new_dentry->d_parent); 672 784 if(IS_ERR(newdirfid)) { 673 785 retval = PTR_ERR(newdirfid); 674 - goto Clunk_olddir; 786 + goto clunk_olddir; 675 787 } 676 788 677 789 /* 9P can only handle file rename in the same directory */ 678 790 if (memcmp(&olddirfid->qid, &newdirfid->qid, sizeof(newdirfid->qid))) { 679 - dprintk(DEBUG_ERROR, "old dir and new dir are different\n"); 791 + P9_DPRINTK(P9_DEBUG_ERROR, 792 + "old dir and new dir are different\n"); 680 793 retval = -EXDEV; 681 - goto Clunk_newdir; 682 - } 683 - 684 - fid = oldfid->fid; 685 - olddirfidnum = olddirfid->fid; 686 - newdirfidnum = newdirfid->fid; 687 - 688 - if (fid < 0) { 689 - dprintk(DEBUG_ERROR, "no fid for old file #%lu\n", 690 - old_inode->i_ino); 691 - retval = -EBADF; 692 - goto Clunk_newdir; 794 + goto clunk_newdir; 693 795 } 694 796 695 797 v9fs_blank_wstat(&wstat); 696 798 wstat.muid = v9ses->name; 697 799 wstat.name = (char *) new_dentry->d_name.name; 800 + retval = p9_client_wstat(oldfid, &wstat); 698 801 699 - retval = v9fs_t_wstat(v9ses, fid, &wstat, &fcall); 802 + clunk_newdir: 803 + p9_client_clunk(olddirfid); 700 804 701 - if (retval < 0) 702 - PRINT_FCALL_ERROR("wstat error", fcall); 805 + clunk_olddir: 806 + p9_client_clunk(newdirfid); 703 807 704 - kfree(fcall); 705 - 706 - Clunk_newdir: 707 - v9fs_fid_clunk(v9ses, newdirfid); 708 - 709 - Clunk_olddir: 710 - v9fs_fid_clunk(v9ses, olddirfid); 711 - 712 - Release_lock: 713 - up(&oldfid->lock); 714 - 808 + done: 715 809 return retval; 716 810 } 717 811 ··· 708 840 v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, 709 841 struct kstat *stat) 710 842 { 711 - struct v9fs_fcall *fcall = NULL; 712 - struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); 713 - struct v9fs_fid *fid = v9fs_fid_clone(dentry); 714 - int err = -EPERM; 843 + int err; 844 + struct v9fs_session_info *v9ses; 845 + struct p9_fid *fid; 846 + struct p9_stat *st; 715 847 716 - dprintk(DEBUG_VFS, "dentry: %p\n", dentry); 717 - if(IS_ERR(fid)) 848 + P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); 849 + err = -EPERM; 850 + v9ses = v9fs_inode2v9ses(dentry->d_inode); 851 + if (v9ses->cache == CACHE_LOOSE) 852 + return simple_getattr(mnt, dentry, stat); 853 + 854 + fid = v9fs_fid_lookup(dentry); 855 + if (IS_ERR(fid)) 718 856 return PTR_ERR(fid); 719 857 720 - err = v9fs_t_stat(v9ses, fid->fid, &fcall); 858 + st = p9_client_stat(fid); 859 + if (IS_ERR(st)) 860 + return PTR_ERR(st); 721 861 722 - if (err < 0) 723 - dprintk(DEBUG_ERROR, "stat error\n"); 724 - else { 725 - v9fs_stat2inode(&fcall->params.rstat.stat, dentry->d_inode, 726 - dentry->d_inode->i_sb); 862 + v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb); 727 863 generic_fillattr(dentry->d_inode, stat); 728 - } 729 864 730 - kfree(fcall); 731 - v9fs_fid_clunk(v9ses, fid); 732 - return err; 865 + kfree(st); 866 + return 0; 733 867 } 734 868 735 869 /** ··· 743 873 744 874 static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) 745 875 { 746 - struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); 747 - struct v9fs_fid *fid = v9fs_fid_clone(dentry); 748 - struct v9fs_fcall *fcall = NULL; 749 - struct v9fs_wstat wstat; 750 - int res = -EPERM; 876 + int retval; 877 + struct v9fs_session_info *v9ses; 878 + struct p9_fid *fid; 879 + struct p9_wstat wstat; 751 880 752 - dprintk(DEBUG_VFS, "\n"); 881 + P9_DPRINTK(P9_DEBUG_VFS, "\n"); 882 + retval = -EPERM; 883 + v9ses = v9fs_inode2v9ses(dentry->d_inode); 884 + fid = v9fs_fid_lookup(dentry); 753 885 if(IS_ERR(fid)) 754 886 return PTR_ERR(fid); 755 887 ··· 776 904 wstat.n_gid = iattr->ia_gid; 777 905 } 778 906 779 - res = v9fs_t_wstat(v9ses, fid->fid, &wstat, &fcall); 907 + retval = p9_client_wstat(fid, &wstat); 908 + if (retval >= 0) 909 + retval = inode_setattr(dentry->d_inode, iattr); 780 910 781 - if (res < 0) 782 - PRINT_FCALL_ERROR("wstat error", fcall); 783 - 784 - kfree(fcall); 785 - if (res >= 0) 786 - res = inode_setattr(dentry->d_inode, iattr); 787 - 788 - v9fs_fid_clunk(v9ses, fid); 789 - return res; 911 + return retval; 790 912 } 791 913 792 914 /** ··· 792 926 */ 793 927 794 928 void 795 - v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode, 929 + v9fs_stat2inode(struct p9_stat *stat, struct inode *inode, 796 930 struct super_block *sb) 797 931 { 798 932 int n; ··· 833 967 case 'b': 834 968 break; 835 969 default: 836 - dprintk(DEBUG_ERROR, "Unknown special type %c (%.*s)\n", 837 - type, stat->extension.len, stat->extension.str); 970 + P9_DPRINTK(P9_DEBUG_ERROR, 971 + "Unknown special type %c (%.*s)\n", type, 972 + stat->extension.len, stat->extension.str); 838 973 }; 839 974 inode->i_rdev = MKDEV(major, minor); 840 975 } else ··· 843 976 844 977 inode->i_size = stat->length; 845 978 846 - inode->i_blocks = 847 - (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; 979 + /* not real number of blocks, but 512 byte ones ... */ 980 + inode->i_blocks = (inode->i_size + 512 - 1) >> 9; 848 981 } 849 982 850 983 /** ··· 854 987 * BUG: potential for inode number collisions? 855 988 */ 856 989 857 - ino_t v9fs_qid2ino(struct v9fs_qid *qid) 990 + ino_t v9fs_qid2ino(struct p9_qid *qid) 858 991 { 859 992 u64 path = qid->path + 2; 860 993 ino_t i = 0; ··· 877 1010 878 1011 static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) 879 1012 { 880 - int retval = -EPERM; 1013 + int retval; 881 1014 882 - struct v9fs_fcall *fcall = NULL; 883 - struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); 884 - struct v9fs_fid *fid = v9fs_fid_clone(dentry); 1015 + struct v9fs_session_info *v9ses; 1016 + struct p9_fid *fid; 1017 + struct p9_stat *st; 885 1018 1019 + P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name); 1020 + retval = -EPERM; 1021 + v9ses = v9fs_inode2v9ses(dentry->d_inode); 1022 + fid = v9fs_fid_lookup(dentry); 886 1023 if(IS_ERR(fid)) 887 1024 return PTR_ERR(fid); 888 1025 889 - if (!v9ses->extended) { 890 - retval = -EBADF; 891 - dprintk(DEBUG_ERROR, "not extended\n"); 892 - goto ClunkFid; 893 - } 1026 + if (!v9ses->extended) 1027 + return -EBADF; 894 1028 895 - dprintk(DEBUG_VFS, " %s\n", dentry->d_name.name); 896 - retval = v9fs_t_stat(v9ses, fid->fid, &fcall); 1029 + st = p9_client_stat(fid); 1030 + if (IS_ERR(st)) 1031 + return PTR_ERR(st); 897 1032 898 - if (retval < 0) { 899 - dprintk(DEBUG_ERROR, "stat error\n"); 900 - goto FreeFcall; 901 - } 902 - 903 - if (!fcall) { 904 - retval = -EIO; 905 - goto ClunkFid; 906 - } 907 - 908 - if (!(fcall->params.rstat.stat.mode & V9FS_DMSYMLINK)) { 1033 + if (!(st->mode & P9_DMSYMLINK)) { 909 1034 retval = -EINVAL; 910 - goto FreeFcall; 1035 + goto done; 911 1036 } 912 1037 913 1038 /* copy extension buffer into buffer */ 914 - if (fcall->params.rstat.stat.extension.len < buflen) 915 - buflen = fcall->params.rstat.stat.extension.len + 1; 1039 + if (st->extension.len < buflen) 1040 + buflen = st->extension.len + 1; 916 1041 917 - memmove(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); 1042 + memmove(buffer, st->extension.str, buflen - 1); 918 1043 buffer[buflen-1] = 0; 919 1044 920 - dprintk(DEBUG_ERROR, "%s -> %.*s (%s)\n", dentry->d_name.name, fcall->params.rstat.stat.extension.len, 921 - fcall->params.rstat.stat.extension.str, buffer); 1045 + P9_DPRINTK(P9_DEBUG_VFS, 1046 + "%s -> %.*s (%s)\n", dentry->d_name.name, st->extension.len, 1047 + st->extension.str, buffer); 1048 + 922 1049 retval = buflen; 923 1050 924 - FreeFcall: 925 - kfree(fcall); 926 - 927 - ClunkFid: 928 - v9fs_fid_clunk(v9ses, fid); 929 - 1051 + done: 1052 + kfree(st); 930 1053 return retval; 931 1054 } 932 1055 ··· 941 1084 if (buflen > PATH_MAX) 942 1085 buflen = PATH_MAX; 943 1086 944 - dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); 1087 + P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); 945 1088 946 1089 retval = v9fs_readlink(dentry, link, buflen); 947 1090 948 1091 if (retval > 0) { 949 1092 if ((ret = copy_to_user(buffer, link, retval)) != 0) { 950 - dprintk(DEBUG_ERROR, "problem copying to user: %d\n", 951 - ret); 1093 + P9_DPRINTK(P9_DEBUG_ERROR, 1094 + "problem copying to user: %d\n", ret); 952 1095 retval = ret; 953 1096 } 954 1097 } ··· 969 1112 int len = 0; 970 1113 char *link = __getname(); 971 1114 972 - dprintk(DEBUG_VFS, "%s n", dentry->d_name.name); 1115 + P9_DPRINTK(P9_DEBUG_VFS, "%s n", dentry->d_name.name); 973 1116 974 1117 if (!link) 975 1118 link = ERR_PTR(-ENOMEM); ··· 998 1141 { 999 1142 char *s = nd_get_link(nd); 1000 1143 1001 - dprintk(DEBUG_VFS, " %s %s\n", dentry->d_name.name, s); 1144 + P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s); 1002 1145 if (!IS_ERR(s)) 1003 1146 __putname(s); 1004 1147 } ··· 1006 1149 static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, 1007 1150 int mode, const char *extension) 1008 1151 { 1009 - int err; 1010 - u32 fid, perm; 1152 + u32 perm; 1011 1153 struct v9fs_session_info *v9ses; 1012 - struct v9fs_fid *dfid, *vfid = NULL; 1013 - struct inode *inode = NULL; 1154 + struct p9_fid *fid; 1014 1155 1015 1156 v9ses = v9fs_inode2v9ses(dir); 1016 1157 if (!v9ses->extended) { 1017 - dprintk(DEBUG_ERROR, "not extended\n"); 1158 + P9_DPRINTK(P9_DEBUG_ERROR, "not extended\n"); 1018 1159 return -EPERM; 1019 1160 } 1020 1161 1021 - dfid = v9fs_fid_clone(dentry->d_parent); 1022 - if(IS_ERR(dfid)) { 1023 - err = PTR_ERR(dfid); 1024 - goto error; 1025 - } 1026 - 1027 1162 perm = unixmode2p9mode(v9ses, mode); 1163 + fid = v9fs_create(v9ses, dir, dentry, (char *) extension, perm, 1164 + P9_OREAD); 1165 + if (IS_ERR(fid)) 1166 + return PTR_ERR(fid); 1028 1167 1029 - err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, 1030 - perm, V9FS_OREAD, (char *) extension, &fid, NULL, NULL); 1031 - 1032 - if (err) 1033 - goto clunk_dfid; 1034 - 1035 - err = v9fs_t_clunk(v9ses, fid); 1036 - if (err) 1037 - goto clunk_dfid; 1038 - 1039 - vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); 1040 - if (IS_ERR(vfid)) { 1041 - err = PTR_ERR(vfid); 1042 - vfid = NULL; 1043 - goto clunk_dfid; 1044 - } 1045 - 1046 - inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); 1047 - if (IS_ERR(inode)) { 1048 - err = PTR_ERR(inode); 1049 - inode = NULL; 1050 - goto free_vfid; 1051 - } 1052 - 1053 - if(v9ses->cache) 1054 - dentry->d_op = &v9fs_cached_dentry_operations; 1055 - else 1056 - dentry->d_op = &v9fs_dentry_operations; 1057 - d_instantiate(dentry, inode); 1168 + p9_client_clunk(fid); 1058 1169 return 0; 1059 - 1060 - free_vfid: 1061 - v9fs_fid_destroy(vfid); 1062 - 1063 - clunk_dfid: 1064 - v9fs_fid_clunk(v9ses, dfid); 1065 - 1066 - error: 1067 - return err; 1068 - 1069 1170 } 1070 1171 1071 1172 /** ··· 1039 1224 static int 1040 1225 v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) 1041 1226 { 1042 - dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, 1043 - symname); 1227 + P9_DPRINTK(P9_DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, 1228 + dentry->d_name.name, symname); 1044 1229 1045 1230 return v9fs_vfs_mkspecial(dir, dentry, S_IFLNK, symname); 1046 1231 } ··· 1062 1247 struct dentry *dentry) 1063 1248 { 1064 1249 int retval; 1065 - struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); 1066 - struct v9fs_fid *oldfid; 1250 + struct p9_fid *oldfid; 1067 1251 char *name; 1068 1252 1069 - dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, 1253 + P9_DPRINTK(P9_DEBUG_VFS, 1254 + " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, 1070 1255 old_dentry->d_name.name); 1071 1256 1072 1257 oldfid = v9fs_fid_clone(old_dentry); ··· 1080 1265 } 1081 1266 1082 1267 sprintf(name, "%d\n", oldfid->fid); 1083 - retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name); 1268 + retval = v9fs_vfs_mkspecial(dir, dentry, P9_DMLINK, name); 1084 1269 __putname(name); 1085 1270 1086 1271 clunk_fid: 1087 - v9fs_fid_clunk(v9ses, oldfid); 1272 + p9_client_clunk(oldfid); 1088 1273 return retval; 1089 1274 } 1090 1275 ··· 1103 1288 int retval; 1104 1289 char *name; 1105 1290 1106 - dprintk(DEBUG_VFS, " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, 1291 + P9_DPRINTK(P9_DEBUG_VFS, 1292 + " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, 1107 1293 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); 1108 1294 1109 1295 if (!new_valid_dev(rdev))
+40 -57
fs/9p/vfs_super.c
··· 37 37 #include <linux/mount.h> 38 38 #include <linux/idr.h> 39 39 #include <linux/sched.h> 40 + #include <net/9p/9p.h> 41 + #include <net/9p/client.h> 40 42 41 - #include "debug.h" 42 43 #include "v9fs.h" 43 - #include "9p.h" 44 44 #include "v9fs_vfs.h" 45 45 #include "fid.h" 46 46 ··· 107 107 struct vfsmount *mnt) 108 108 { 109 109 struct super_block *sb = NULL; 110 - struct v9fs_fcall *fcall = NULL; 111 110 struct inode *inode = NULL; 112 111 struct dentry *root = NULL; 113 112 struct v9fs_session_info *v9ses = NULL; 114 - struct v9fs_fid *root_fid = NULL; 113 + struct p9_stat *st = NULL; 115 114 int mode = S_IRWXUGO | S_ISVTX; 116 115 uid_t uid = current->fsuid; 117 116 gid_t gid = current->fsgid; 118 - int stat_result = 0; 119 - int newfid = 0; 117 + struct p9_fid *fid; 120 118 int retval = 0; 121 119 122 - dprintk(DEBUG_VFS, " \n"); 120 + P9_DPRINTK(P9_DEBUG_VFS, " \n"); 123 121 124 122 v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL); 125 123 if (!v9ses) 126 124 return -ENOMEM; 127 125 128 - if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { 129 - dprintk(DEBUG_ERROR, "problem initiating session\n"); 130 - retval = newfid; 131 - goto out_free_session; 126 + fid = v9fs_session_init(v9ses, dev_name, data); 127 + if (IS_ERR(fid)) { 128 + retval = PTR_ERR(fid); 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 141 sb = sget(fs_type, NULL, v9fs_set_super, v9ses); 135 142 if (IS_ERR(sb)) { 136 143 retval = PTR_ERR(sb); 137 - goto out_close_session; 144 + goto error; 138 145 } 139 146 v9fs_fill_super(sb, v9ses, flags); 140 147 141 148 inode = v9fs_get_inode(sb, S_IFDIR | mode); 142 149 if (IS_ERR(inode)) { 143 150 retval = PTR_ERR(inode); 144 - goto put_back_sb; 151 + goto error; 145 152 } 146 153 147 154 inode->i_uid = uid; ··· 157 150 root = d_alloc_root(inode); 158 151 if (!root) { 159 152 retval = -ENOMEM; 160 - goto put_back_sb; 153 + goto error; 161 154 } 162 155 163 156 sb->s_root = root; 164 - 165 - stat_result = v9fs_t_stat(v9ses, newfid, &fcall); 166 - if (stat_result < 0) { 167 - dprintk(DEBUG_ERROR, "stat error\n"); 168 - v9fs_t_clunk(v9ses, newfid); 169 - } else { 170 - /* Setup the Root Inode */ 171 - root_fid = v9fs_fid_create(v9ses, newfid); 172 - if (root_fid == NULL) { 173 - retval = -ENOMEM; 174 - goto put_back_sb; 175 - } 176 - 177 - retval = v9fs_fid_insert(root_fid, root); 178 - if (retval < 0) { 179 - kfree(fcall); 180 - goto put_back_sb; 181 - } 182 - 183 - root_fid->qid = fcall->params.rstat.stat.qid; 184 - root->d_inode->i_ino = 185 - v9fs_qid2ino(&fcall->params.rstat.stat.qid); 186 - v9fs_stat2inode(&fcall->params.rstat.stat, root->d_inode, sb); 187 - } 188 - 189 - kfree(fcall); 190 - 191 - if (stat_result < 0) { 192 - retval = stat_result; 193 - goto put_back_sb; 194 - } 157 + root->d_inode->i_ino = v9fs_qid2ino(&st->qid); 158 + v9fs_stat2inode(st, root->d_inode, sb); 159 + v9fs_fid_add(root, fid); 195 160 196 161 return simple_set_mnt(mnt, sb); 197 162 198 - out_close_session: 199 - v9fs_session_close(v9ses); 200 - out_free_session: 201 - kfree(v9ses); 202 - return retval; 163 + error: 164 + if (fid) 165 + p9_client_clunk(fid); 203 166 204 - put_back_sb: 205 - /* deactivate_super calls v9fs_kill_super which will frees the rest */ 206 - up_write(&sb->s_umount); 207 - deactivate_super(sb); 167 + if (v9ses) { 168 + v9fs_session_close(v9ses); 169 + kfree(v9ses); 170 + } 171 + 172 + if (sb) { 173 + up_write(&sb->s_umount); 174 + deactivate_super(sb); 175 + } 176 + 208 177 return retval; 209 178 } 210 179 ··· 194 211 { 195 212 struct v9fs_session_info *v9ses = s->s_fs_info; 196 213 197 - dprintk(DEBUG_VFS, " %p\n", s); 214 + P9_DPRINTK(P9_DEBUG_VFS, " %p\n", s); 198 215 199 216 v9fs_dentry_release(s->s_root); /* clunk root */ 200 217 ··· 202 219 203 220 v9fs_session_close(v9ses); 204 221 kfree(v9ses); 205 - dprintk(DEBUG_VFS, "exiting kill_super\n"); 222 + P9_DPRINTK(P9_DEBUG_VFS, "exiting kill_super\n"); 206 223 } 207 224 208 225 /** ··· 217 234 struct v9fs_session_info *v9ses = mnt->mnt_sb->s_fs_info; 218 235 219 236 if (v9ses->debug != 0) 220 - seq_printf(m, ",debug=%u", v9ses->debug); 237 + seq_printf(m, ",debug=%x", v9ses->debug); 221 238 if (v9ses->port != V9FS_PORT) 222 239 seq_printf(m, ",port=%u", v9ses->port); 223 240 if (v9ses->maxdata != 9000)
+1 -1
fs/Kconfig
··· 2048 2048 2049 2049 config 9P_FS 2050 2050 tristate "Plan 9 Resource Sharing Support (9P2000) (Experimental)" 2051 - depends on INET && EXPERIMENTAL 2051 + depends on INET && NET_9P && EXPERIMENTAL 2052 2052 help 2053 2053 If you say Y here, you will get experimental support for 2054 2054 Plan 9 resource sharing via the 9P2000 protocol.
+417
include/net/9p/9p.h
··· 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 */
+80
include/net/9p/client.h
··· 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 */
+21
net/9p/Kconfig
··· 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 +
+13
net/9p/Makefile
··· 1 + obj-$(CONFIG_NET_9P) := 9pnet.o 2 + 3 + 9pnet-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 + 9pnet-$(CONFIG_SYSCTL) += sysctl.o
+965
net/9p/client.c
··· 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 + list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) 131 + p9_fid_destroy(fid); 132 + 133 + if (clnt->fidpool) 134 + p9_idpool_destroy(clnt->fidpool); 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 + }
+85
net/9p/mod.c
··· 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");
+86
net/9p/sysctl.c
··· 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 + }
+363
net/9p/trans_fd.c
··· 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 +
+125
net/9p/util.c
··· 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);
+1
net/Kconfig
··· 227 227 endmenu 228 228 229 229 source "net/rfkill/Kconfig" 230 + source "net/9p/Kconfig" 230 231 231 232 endif # if NET 232 233 endmenu # Networking
+1
net/Makefile
··· 51 51 obj-$(CONFIG_NETLABEL) += netlabel/ 52 52 obj-$(CONFIG_IUCV) += iucv/ 53 53 obj-$(CONFIG_RFKILL) += rfkill/ 54 + obj-$(CONFIG_NET_9P) += 9p/ 54 55 55 56 ifeq ($(CONFIG_NET),y) 56 57 obj-$(CONFIG_SYSCTL) += sysctl_net.o