diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-05 16:42:54 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-05 16:42:54 -0400 |
| commit | 749d229761ff0135cc4e16b8a28b41ae2f6b2c35 (patch) | |
| tree | 25551c8cfb38319211f5ee59e78462a0f6fb85c4 /fs | |
| parent | 795d580baec0d5386b83a8b557df47c20810e86b (diff) | |
| parent | 3dc9fef67f6292692dba181a6d0fd0211bd0a607 (diff) | |
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.
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/9p/fid.c | 12 | ||||
| -rw-r--r-- | fs/9p/v9fs.c | 21 | ||||
| -rw-r--r-- | fs/9p/v9fs.h | 1 | ||||
| -rw-r--r-- | fs/9p/vfs_dir.c | 2 | ||||
| -rw-r--r-- | fs/9p/vfs_inode.c | 9 | ||||
| -rw-r--r-- | fs/9p/vfs_super.c | 3 |
6 files changed, 41 insertions, 7 deletions
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 82ee460e534d..7317b39b2815 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
| @@ -111,7 +111,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) | |||
| 111 | { | 111 | { |
| 112 | int i, n, l, clone, any, access; | 112 | int i, n, l, clone, any, access; |
| 113 | u32 uid; | 113 | u32 uid; |
| 114 | struct p9_fid *fid; | 114 | struct p9_fid *fid, *old_fid = NULL; |
| 115 | struct dentry *d, *ds; | 115 | struct dentry *d, *ds; |
| 116 | struct v9fs_session_info *v9ses; | 116 | struct v9fs_session_info *v9ses; |
| 117 | char **wnames, *uname; | 117 | char **wnames, *uname; |
| @@ -184,10 +184,18 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) | |||
| 184 | l = min(n - i, P9_MAXWELEM); | 184 | l = min(n - i, P9_MAXWELEM); |
| 185 | fid = p9_client_walk(fid, l, &wnames[i], clone); | 185 | fid = p9_client_walk(fid, l, &wnames[i], clone); |
| 186 | if (IS_ERR(fid)) { | 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 | kfree(wnames); | 195 | kfree(wnames); |
| 188 | return fid; | 196 | return fid; |
| 189 | } | 197 | } |
| 190 | 198 | old_fid = fid; | |
| 191 | i += l; | 199 | i += l; |
| 192 | clone = 0; | 200 | clone = 0; |
| 193 | } | 201 | } |
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index cb57d3326182..5c5bc8480070 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
| @@ -242,7 +242,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
| 242 | list_add(&v9ses->slist, &v9fs_sessionlist); | 242 | list_add(&v9ses->slist, &v9fs_sessionlist); |
| 243 | spin_unlock(&v9fs_sessionlist_lock); | 243 | spin_unlock(&v9fs_sessionlist_lock); |
| 244 | 244 | ||
| 245 | v9ses->flags = V9FS_PROTO_2000U | V9FS_ACCESS_USER; | 245 | v9ses->flags = V9FS_ACCESS_USER; |
| 246 | strcpy(v9ses->uname, V9FS_DEFUSER); | 246 | strcpy(v9ses->uname, V9FS_DEFUSER); |
| 247 | strcpy(v9ses->aname, V9FS_DEFANAME); | 247 | strcpy(v9ses->aname, V9FS_DEFANAME); |
| 248 | v9ses->uid = ~0; | 248 | v9ses->uid = ~0; |
| @@ -263,8 +263,10 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
| 263 | goto error; | 263 | goto error; |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | if (!p9_is_proto_dotu(v9ses->clnt)) | 266 | if (p9_is_proto_dotl(v9ses->clnt)) |
| 267 | v9ses->flags &= ~V9FS_PROTO_2000U; | 267 | v9ses->flags |= V9FS_PROTO_2000L; |
| 268 | else if (p9_is_proto_dotu(v9ses->clnt)) | ||
| 269 | v9ses->flags |= V9FS_PROTO_2000U; | ||
| 268 | 270 | ||
| 269 | v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ; | 271 | v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ; |
| 270 | 272 | ||
| @@ -341,6 +343,19 @@ void v9fs_session_cancel(struct v9fs_session_info *v9ses) { | |||
| 341 | p9_client_disconnect(v9ses->clnt); | 343 | p9_client_disconnect(v9ses->clnt); |
| 342 | } | 344 | } |
| 343 | 345 | ||
| 346 | /** | ||
| 347 | * v9fs_session_begin_cancel - Begin terminate of a session | ||
| 348 | * @v9ses: session to terminate | ||
| 349 | * | ||
| 350 | * After this call we don't allow any request other than clunk. | ||
| 351 | */ | ||
| 352 | |||
| 353 | void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses) | ||
| 354 | { | ||
| 355 | P9_DPRINTK(P9_DEBUG_ERROR, "begin cancel session %p\n", v9ses); | ||
| 356 | p9_client_begin_disconnect(v9ses->clnt); | ||
| 357 | } | ||
| 358 | |||
| 344 | extern int v9fs_error_init(void); | 359 | extern int v9fs_error_init(void); |
| 345 | 360 | ||
| 346 | static struct kobject *v9fs_kobj; | 361 | static struct kobject *v9fs_kobj; |
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 6b801d1ddf4b..a0a8d3dd1361 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h | |||
| @@ -108,6 +108,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, | |||
| 108 | char *); | 108 | char *); |
| 109 | void v9fs_session_close(struct v9fs_session_info *v9ses); | 109 | void v9fs_session_close(struct v9fs_session_info *v9ses); |
| 110 | void v9fs_session_cancel(struct v9fs_session_info *v9ses); | 110 | void v9fs_session_cancel(struct v9fs_session_info *v9ses); |
| 111 | void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses); | ||
| 111 | 112 | ||
| 112 | #define V9FS_MAGIC 0x01021997 | 113 | #define V9FS_MAGIC 0x01021997 |
| 113 | 114 | ||
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 909711f57c0d..0adfd64dfcee 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
| @@ -131,6 +131,8 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 131 | rdir = (struct p9_rdir *) fid->rdir; | 131 | rdir = (struct p9_rdir *) fid->rdir; |
| 132 | 132 | ||
| 133 | err = mutex_lock_interruptible(&rdir->mutex); | 133 | err = mutex_lock_interruptible(&rdir->mutex); |
| 134 | if (err) | ||
| 135 | return err; | ||
| 134 | while (err == 0) { | 136 | while (err == 0) { |
| 135 | if (rdir->tail == rdir->head) { | 137 | if (rdir->tail == rdir->head) { |
| 136 | err = v9fs_file_readn(filp, rdir->buf, NULL, | 138 | err = v9fs_file_readn(filp, rdir->buf, NULL, |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 63c2b5af268a..f2434fc9d2c4 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
| @@ -432,6 +432,7 @@ error: | |||
| 432 | 432 | ||
| 433 | static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) | 433 | static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) |
| 434 | { | 434 | { |
| 435 | int retval; | ||
| 435 | struct inode *file_inode; | 436 | struct inode *file_inode; |
| 436 | struct v9fs_session_info *v9ses; | 437 | struct v9fs_session_info *v9ses; |
| 437 | struct p9_fid *v9fid; | 438 | struct p9_fid *v9fid; |
| @@ -445,7 +446,10 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) | |||
| 445 | if (IS_ERR(v9fid)) | 446 | if (IS_ERR(v9fid)) |
| 446 | return PTR_ERR(v9fid); | 447 | return PTR_ERR(v9fid); |
| 447 | 448 | ||
| 448 | return p9_client_remove(v9fid); | 449 | retval = p9_client_remove(v9fid); |
| 450 | if (!retval) | ||
| 451 | drop_nlink(file_inode); | ||
| 452 | return retval; | ||
| 449 | } | 453 | } |
| 450 | 454 | ||
| 451 | static int | 455 | static int |
| @@ -657,6 +661,9 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 657 | P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", | 661 | P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", |
| 658 | dir, dentry->d_name.name, dentry, nameidata); | 662 | dir, dentry->d_name.name, dentry, nameidata); |
| 659 | 663 | ||
| 664 | if (dentry->d_name.len > NAME_MAX) | ||
| 665 | return ERR_PTR(-ENAMETOOLONG); | ||
| 666 | |||
| 660 | sb = dir->i_sb; | 667 | sb = dir->i_sb; |
| 661 | v9ses = v9fs_inode2v9ses(dir); | 668 | v9ses = v9fs_inode2v9ses(dir); |
| 662 | dfid = v9fs_fid_lookup(dentry->d_parent); | 669 | dfid = v9fs_fid_lookup(dentry->d_parent); |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index a271549d9e21..491108bd6e0d 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
| @@ -194,6 +194,7 @@ static void v9fs_kill_super(struct super_block *s) | |||
| 194 | 194 | ||
| 195 | kill_anon_super(s); | 195 | kill_anon_super(s); |
| 196 | 196 | ||
| 197 | v9fs_session_cancel(v9ses); | ||
| 197 | v9fs_session_close(v9ses); | 198 | v9fs_session_close(v9ses); |
| 198 | kfree(v9ses); | 199 | kfree(v9ses); |
| 199 | s->s_fs_info = NULL; | 200 | s->s_fs_info = NULL; |
| @@ -206,7 +207,7 @@ v9fs_umount_begin(struct super_block *sb) | |||
| 206 | struct v9fs_session_info *v9ses; | 207 | struct v9fs_session_info *v9ses; |
| 207 | 208 | ||
| 208 | v9ses = sb->s_fs_info; | 209 | v9ses = sb->s_fs_info; |
| 209 | v9fs_session_cancel(v9ses); | 210 | v9fs_session_begin_cancel(v9ses); |
| 210 | } | 211 | } |
| 211 | 212 | ||
| 212 | static const struct super_operations v9fs_super_ops = { | 213 | static const struct super_operations v9fs_super_ops = { |
