Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: saving negative to unsigned char
9p: return on mutex_lock_interruptible()
9p: Creating files with names too long should fail with ENAMETOOLONG.
9p: Make sure we are able to clunk the cached fid on umount
9p: drop nlink remove
fs/9p: Clunk the fid resulting from partial walk of the name
9p: documentation update
9p: Fix setting of protocol flags in v9fs_session_info structure.

+78 -13
+16 -2
Documentation/filesystems/9p.txt
··· 37 37 38 38 mount -t 9p `namespace`/acme /mnt/9 -o trans=unix,uname=$USER 39 39 40 + For server running on QEMU host with virtio transport: 41 + 42 + mount -t 9p -o trans=virtio <mount_tag> /mnt/9 43 + 44 + where mount_tag is the tag associated by the server to each of the exported 45 + mount points. Each 9P export is seen by the client as a virtio device with an 46 + associated "mount_tag" property. Available mount tags can be 47 + seen by reading /sys/bus/virtio/drivers/9pnet_virtio/virtio<n>/mount_tag files. 48 + 40 49 OPTIONS 41 50 ======= 42 51 ··· 56 47 fd - used passed file descriptors for connection 57 48 (see rfdno and wfdno) 58 49 virtio - connect to the next virtio channel available 59 - (from lguest or KVM with trans_virtio module) 50 + (from QEMU with trans_virtio module) 60 51 rdma - connect to a specified RDMA channel 61 52 62 53 uname=name user name to attempt mount as on the remote server. The ··· 94 85 95 86 port=n port to connect to on the remote server 96 87 97 - noextend force legacy mode (no 9p2000.u semantics) 88 + noextend force legacy mode (no 9p2000.u or 9p2000.L semantics) 89 + 90 + version=name Select 9P protocol version. Valid options are: 91 + 9p2000 - Legacy mode (same as noextend) 92 + 9p2000.u - Use 9P2000.u protocol 93 + 9p2000.L - Use 9P2000.L protocol 98 94 99 95 dfltuid attempt to mount as a particular uid 100 96
+10 -2
fs/9p/fid.c
··· 111 111 { 112 112 int i, n, l, clone, any, access; 113 113 u32 uid; 114 - struct p9_fid *fid; 114 + struct p9_fid *fid, *old_fid = NULL; 115 115 struct dentry *d, *ds; 116 116 struct v9fs_session_info *v9ses; 117 117 char **wnames, *uname; ··· 184 184 l = min(n - i, P9_MAXWELEM); 185 185 fid = p9_client_walk(fid, l, &wnames[i], clone); 186 186 if (IS_ERR(fid)) { 187 + if (old_fid) { 188 + /* 189 + * If we fail, clunk fid which are mapping 190 + * to path component and not the last component 191 + * of the path. 192 + */ 193 + p9_client_clunk(old_fid); 194 + } 187 195 kfree(wnames); 188 196 return fid; 189 197 } 190 - 198 + old_fid = fid; 191 199 i += l; 192 200 clone = 0; 193 201 }
+18 -3
fs/9p/v9fs.c
··· 242 242 list_add(&v9ses->slist, &v9fs_sessionlist); 243 243 spin_unlock(&v9fs_sessionlist_lock); 244 244 245 - v9ses->flags = V9FS_PROTO_2000U | V9FS_ACCESS_USER; 245 + v9ses->flags = V9FS_ACCESS_USER; 246 246 strcpy(v9ses->uname, V9FS_DEFUSER); 247 247 strcpy(v9ses->aname, V9FS_DEFANAME); 248 248 v9ses->uid = ~0; ··· 263 263 goto error; 264 264 } 265 265 266 - if (!p9_is_proto_dotu(v9ses->clnt)) 267 - v9ses->flags &= ~V9FS_PROTO_2000U; 266 + if (p9_is_proto_dotl(v9ses->clnt)) 267 + v9ses->flags |= V9FS_PROTO_2000L; 268 + else if (p9_is_proto_dotu(v9ses->clnt)) 269 + v9ses->flags |= V9FS_PROTO_2000U; 268 270 269 271 v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ; 270 272 ··· 341 339 void v9fs_session_cancel(struct v9fs_session_info *v9ses) { 342 340 P9_DPRINTK(P9_DEBUG_ERROR, "cancel session %p\n", v9ses); 343 341 p9_client_disconnect(v9ses->clnt); 342 + } 343 + 344 + /** 345 + * v9fs_session_begin_cancel - Begin terminate of a session 346 + * @v9ses: session to terminate 347 + * 348 + * After this call we don't allow any request other than clunk. 349 + */ 350 + 351 + void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses) 352 + { 353 + P9_DPRINTK(P9_DEBUG_ERROR, "begin cancel session %p\n", v9ses); 354 + p9_client_begin_disconnect(v9ses->clnt); 344 355 } 345 356 346 357 extern int v9fs_error_init(void);
+1
fs/9p/v9fs.h
··· 108 108 char *); 109 109 void v9fs_session_close(struct v9fs_session_info *v9ses); 110 110 void v9fs_session_cancel(struct v9fs_session_info *v9ses); 111 + void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses); 111 112 112 113 #define V9FS_MAGIC 0x01021997 113 114
+2
fs/9p/vfs_dir.c
··· 131 131 rdir = (struct p9_rdir *) fid->rdir; 132 132 133 133 err = mutex_lock_interruptible(&rdir->mutex); 134 + if (err) 135 + return err; 134 136 while (err == 0) { 135 137 if (rdir->tail == rdir->head) { 136 138 err = v9fs_file_readn(filp, rdir->buf, NULL,
+8 -1
fs/9p/vfs_inode.c
··· 432 432 433 433 static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) 434 434 { 435 + int retval; 435 436 struct inode *file_inode; 436 437 struct v9fs_session_info *v9ses; 437 438 struct p9_fid *v9fid; ··· 446 445 if (IS_ERR(v9fid)) 447 446 return PTR_ERR(v9fid); 448 447 449 - return p9_client_remove(v9fid); 448 + retval = p9_client_remove(v9fid); 449 + if (!retval) 450 + drop_nlink(file_inode); 451 + return retval; 450 452 } 451 453 452 454 static int ··· 660 656 661 657 P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", 662 658 dir, dentry->d_name.name, dentry, nameidata); 659 + 660 + if (dentry->d_name.len > NAME_MAX) 661 + return ERR_PTR(-ENAMETOOLONG); 663 662 664 663 sb = dir->i_sb; 665 664 v9ses = v9fs_inode2v9ses(dir);
+2 -1
fs/9p/vfs_super.c
··· 194 194 195 195 kill_anon_super(s); 196 196 197 + v9fs_session_cancel(v9ses); 197 198 v9fs_session_close(v9ses); 198 199 kfree(v9ses); 199 200 s->s_fs_info = NULL; ··· 207 206 struct v9fs_session_info *v9ses; 208 207 209 208 v9ses = sb->s_fs_info; 210 - v9fs_session_cancel(v9ses); 209 + v9fs_session_begin_cancel(v9ses); 211 210 } 212 211 213 212 static const struct super_operations v9fs_super_ops = {
+2
include/net/9p/client.h
··· 54 54 55 55 enum p9_trans_status { 56 56 Connected, 57 + BeginDisconnect, 57 58 Disconnected, 58 59 Hung, 59 60 }; ··· 199 198 struct p9_client *p9_client_create(const char *dev_name, char *options); 200 199 void p9_client_destroy(struct p9_client *clnt); 201 200 void p9_client_disconnect(struct p9_client *clnt); 201 + void p9_client_begin_disconnect(struct p9_client *clnt); 202 202 struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, 203 203 char *uname, u32 n_uname, char *aname); 204 204 struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname,
+19 -4
net/9p/client.c
··· 72 72 EXPORT_SYMBOL(p9_is_proto_dotu); 73 73 74 74 /* Interpret mount option for protocol version */ 75 - static unsigned char get_protocol_version(const substring_t *name) 75 + static int get_protocol_version(const substring_t *name) 76 76 { 77 - unsigned char version = -EINVAL; 77 + int version = -EINVAL; 78 + 78 79 if (!strncmp("9p2000", name->from, name->to-name->from)) { 79 80 version = p9_proto_legacy; 80 81 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: Legacy\n"); ··· 535 534 536 535 P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type); 537 536 538 - if (c->status != Connected) 537 + /* we allow for any status other than disconnected */ 538 + if (c->status == Disconnected) 539 + return ERR_PTR(-EIO); 540 + 541 + /* if status is begin_disconnected we allow only clunk request */ 542 + if ((c->status == BeginDisconnect) && (type != P9_TCLUNK)) 539 543 return ERR_PTR(-EIO); 540 544 541 545 if (signal_pending(current)) { ··· 806 800 807 801 v9fs_put_trans(clnt->trans_mod); 808 802 809 - list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) 803 + list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) { 804 + printk(KERN_INFO "Found fid %d not clunked\n", fid->fid); 810 805 p9_fid_destroy(fid); 806 + } 811 807 812 808 if (clnt->fidpool) 813 809 p9_idpool_destroy(clnt->fidpool); ··· 826 818 clnt->status = Disconnected; 827 819 } 828 820 EXPORT_SYMBOL(p9_client_disconnect); 821 + 822 + void p9_client_begin_disconnect(struct p9_client *clnt) 823 + { 824 + P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); 825 + clnt->status = BeginDisconnect; 826 + } 827 + EXPORT_SYMBOL(p9_client_begin_disconnect); 829 828 830 829 struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, 831 830 char *uname, u32 n_uname, char *aname)