diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-14 22:30:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-14 22:30:51 -0400 |
commit | 8f40f672e6bb071812f61bfbd30efc3fc1263ad1 (patch) | |
tree | 8dcdbbb7adc68647267794c4e3a4686afd94ad65 /fs | |
parent | 8978a318837d7acefca82645017c0534aeba5a36 (diff) | |
parent | 887b3ece65be7b643dfdae0d433c91a26a3f437d (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs
* 'for-linus' of ssh://master.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs:
9p: fix error path during early mount
9p: make cryptic unknown error from server less scary
9p: fix flags length in net
9p: Correct fidpool creation failure in p9_client_create
9p: use struct mutex instead of struct semaphore
9p: propagate parse_option changes to client and transports
fs/9p/v9fs.c (v9fs_parse_options): Handle kstrdup and match_strdup failure.
9p: Documentation updates
add match_strlcpy() us it to make v9fs make uname and remotename parsing more robust
Diffstat (limited to 'fs')
-rw-r--r-- | fs/9p/fid.h | 15 | ||||
-rw-r--r-- | fs/9p/v9fs.c | 57 | ||||
-rw-r--r-- | fs/9p/v9fs.h | 85 | ||||
-rw-r--r-- | fs/9p/vfs_addr.c | 2 | ||||
-rw-r--r-- | fs/9p/vfs_dir.c | 2 | ||||
-rw-r--r-- | fs/9p/vfs_file.c | 11 | ||||
-rw-r--r-- | fs/9p/vfs_inode.c | 50 | ||||
-rw-r--r-- | fs/9p/vfs_super.c | 35 |
8 files changed, 181 insertions, 76 deletions
diff --git a/fs/9p/fid.h b/fs/9p/fid.h index 26e07df783b9..c3bbd6af996d 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h | |||
@@ -22,6 +22,21 @@ | |||
22 | 22 | ||
23 | #include <linux/list.h> | 23 | #include <linux/list.h> |
24 | 24 | ||
25 | /** | ||
26 | * struct v9fs_dentry - 9p private data stored in dentry d_fsdata | ||
27 | * @lock: protects the fidlist | ||
28 | * @fidlist: list of FIDs currently associated with this dentry | ||
29 | * | ||
30 | * This structure defines the 9p private data associated with | ||
31 | * a particular dentry. In particular, this private data is used | ||
32 | * to lookup which 9P FID handle should be used for a particular VFS | ||
33 | * operation. FID handles are associated with dentries instead of | ||
34 | * inodes in order to more closely map functionality to the Plan 9 | ||
35 | * expected behavior for FID reclaimation and tracking. | ||
36 | * | ||
37 | * See Also: Mapping FIDs to Linux VFS model in | ||
38 | * Design and Implementation of the Linux 9P File System documentation | ||
39 | */ | ||
25 | struct v9fs_dentry { | 40 | struct v9fs_dentry { |
26 | spinlock_t lock; /* protect fidlist */ | 41 | spinlock_t lock; /* protect fidlist */ |
27 | struct list_head fidlist; | 42 | struct list_head fidlist; |
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 9b0f0222e8bb..047c791427aa 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -71,19 +71,19 @@ static match_table_t tokens = { | |||
71 | 71 | ||
72 | /** | 72 | /** |
73 | * v9fs_parse_options - parse mount options into session structure | 73 | * v9fs_parse_options - parse mount options into session structure |
74 | * @options: options string passed from mount | ||
75 | * @v9ses: existing v9fs session information | 74 | * @v9ses: existing v9fs session information |
76 | * | 75 | * |
76 | * Return 0 upon success, -ERRNO upon failure. | ||
77 | */ | 77 | */ |
78 | 78 | ||
79 | static void v9fs_parse_options(struct v9fs_session_info *v9ses) | 79 | static int v9fs_parse_options(struct v9fs_session_info *v9ses) |
80 | { | 80 | { |
81 | char *options; | 81 | char *options; |
82 | substring_t args[MAX_OPT_ARGS]; | 82 | substring_t args[MAX_OPT_ARGS]; |
83 | char *p; | 83 | char *p; |
84 | int option = 0; | 84 | int option = 0; |
85 | char *s, *e; | 85 | char *s, *e; |
86 | int ret; | 86 | int ret = 0; |
87 | 87 | ||
88 | /* setup defaults */ | 88 | /* setup defaults */ |
89 | v9ses->afid = ~0; | 89 | v9ses->afid = ~0; |
@@ -91,19 +91,26 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) | |||
91 | v9ses->cache = 0; | 91 | v9ses->cache = 0; |
92 | 92 | ||
93 | if (!v9ses->options) | 93 | if (!v9ses->options) |
94 | return; | 94 | return 0; |
95 | 95 | ||
96 | options = kstrdup(v9ses->options, GFP_KERNEL); | 96 | options = kstrdup(v9ses->options, GFP_KERNEL); |
97 | if (!options) { | ||
98 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
99 | "failed to allocate copy of option string\n"); | ||
100 | return -ENOMEM; | ||
101 | } | ||
102 | |||
97 | while ((p = strsep(&options, ",")) != NULL) { | 103 | while ((p = strsep(&options, ",")) != NULL) { |
98 | int token; | 104 | int token; |
99 | if (!*p) | 105 | if (!*p) |
100 | continue; | 106 | continue; |
101 | token = match_token(p, tokens, args); | 107 | token = match_token(p, tokens, args); |
102 | if (token < Opt_uname) { | 108 | if (token < Opt_uname) { |
103 | ret = match_int(&args[0], &option); | 109 | int r = match_int(&args[0], &option); |
104 | if (ret < 0) { | 110 | if (r < 0) { |
105 | P9_DPRINTK(P9_DEBUG_ERROR, | 111 | P9_DPRINTK(P9_DEBUG_ERROR, |
106 | "integer field, but no integer?\n"); | 112 | "integer field, but no integer?\n"); |
113 | ret = r; | ||
107 | continue; | 114 | continue; |
108 | } | 115 | } |
109 | } | 116 | } |
@@ -125,10 +132,10 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) | |||
125 | v9ses->afid = option; | 132 | v9ses->afid = option; |
126 | break; | 133 | break; |
127 | case Opt_uname: | 134 | case Opt_uname: |
128 | match_strcpy(v9ses->uname, &args[0]); | 135 | match_strlcpy(v9ses->uname, &args[0], PATH_MAX); |
129 | break; | 136 | break; |
130 | case Opt_remotename: | 137 | case Opt_remotename: |
131 | match_strcpy(v9ses->aname, &args[0]); | 138 | match_strlcpy(v9ses->aname, &args[0], PATH_MAX); |
132 | break; | 139 | break; |
133 | case Opt_nodevmap: | 140 | case Opt_nodevmap: |
134 | v9ses->nodev = 1; | 141 | v9ses->nodev = 1; |
@@ -139,6 +146,13 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) | |||
139 | 146 | ||
140 | case Opt_access: | 147 | case Opt_access: |
141 | s = match_strdup(&args[0]); | 148 | s = match_strdup(&args[0]); |
149 | if (!s) { | ||
150 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
151 | "failed to allocate copy" | ||
152 | " of option argument\n"); | ||
153 | ret = -ENOMEM; | ||
154 | break; | ||
155 | } | ||
142 | v9ses->flags &= ~V9FS_ACCESS_MASK; | 156 | v9ses->flags &= ~V9FS_ACCESS_MASK; |
143 | if (strcmp(s, "user") == 0) | 157 | if (strcmp(s, "user") == 0) |
144 | v9ses->flags |= V9FS_ACCESS_USER; | 158 | v9ses->flags |= V9FS_ACCESS_USER; |
@@ -158,6 +172,7 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) | |||
158 | } | 172 | } |
159 | } | 173 | } |
160 | kfree(options); | 174 | kfree(options); |
175 | return ret; | ||
161 | } | 176 | } |
162 | 177 | ||
163 | /** | 178 | /** |
@@ -173,6 +188,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
173 | { | 188 | { |
174 | int retval = -EINVAL; | 189 | int retval = -EINVAL; |
175 | struct p9_fid *fid; | 190 | struct p9_fid *fid; |
191 | int rc; | ||
176 | 192 | ||
177 | v9ses->uname = __getname(); | 193 | v9ses->uname = __getname(); |
178 | if (!v9ses->uname) | 194 | if (!v9ses->uname) |
@@ -190,8 +206,21 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
190 | v9ses->uid = ~0; | 206 | v9ses->uid = ~0; |
191 | v9ses->dfltuid = V9FS_DEFUID; | 207 | v9ses->dfltuid = V9FS_DEFUID; |
192 | v9ses->dfltgid = V9FS_DEFGID; | 208 | v9ses->dfltgid = V9FS_DEFGID; |
193 | v9ses->options = kstrdup(data, GFP_KERNEL); | 209 | if (data) { |
194 | v9fs_parse_options(v9ses); | 210 | v9ses->options = kstrdup(data, GFP_KERNEL); |
211 | if (!v9ses->options) { | ||
212 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
213 | "failed to allocate copy of option string\n"); | ||
214 | retval = -ENOMEM; | ||
215 | goto error; | ||
216 | } | ||
217 | } | ||
218 | |||
219 | rc = v9fs_parse_options(v9ses); | ||
220 | if (rc < 0) { | ||
221 | retval = rc; | ||
222 | goto error; | ||
223 | } | ||
195 | 224 | ||
196 | v9ses->clnt = p9_client_create(dev_name, v9ses->options); | 225 | v9ses->clnt = p9_client_create(dev_name, v9ses->options); |
197 | 226 | ||
@@ -233,7 +262,6 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
233 | return fid; | 262 | return fid; |
234 | 263 | ||
235 | error: | 264 | error: |
236 | v9fs_session_close(v9ses); | ||
237 | return ERR_PTR(retval); | 265 | return ERR_PTR(retval); |
238 | } | 266 | } |
239 | 267 | ||
@@ -256,9 +284,12 @@ void v9fs_session_close(struct v9fs_session_info *v9ses) | |||
256 | } | 284 | } |
257 | 285 | ||
258 | /** | 286 | /** |
259 | * v9fs_session_cancel - mark transport as disconnected | 287 | * v9fs_session_cancel - terminate a session |
260 | * and cancel all pending requests. | 288 | * @v9ses: session to terminate |
289 | * | ||
290 | * mark transport as disconnected and cancel all pending requests. | ||
261 | */ | 291 | */ |
292 | |||
262 | void v9fs_session_cancel(struct v9fs_session_info *v9ses) { | 293 | void v9fs_session_cancel(struct v9fs_session_info *v9ses) { |
263 | P9_DPRINTK(P9_DEBUG_ERROR, "cancel session %p\n", v9ses); | 294 | P9_DPRINTK(P9_DEBUG_ERROR, "cancel session %p\n", v9ses); |
264 | p9_client_disconnect(v9ses->clnt); | 295 | p9_client_disconnect(v9ses->clnt); |
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 7d3a1018db52..a7d567192998 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h | |||
@@ -21,18 +21,69 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* | 24 | /** |
25 | * Session structure provides information for an opened session | 25 | * enum p9_session_flags - option flags for each 9P session |
26 | * | 26 | * @V9FS_EXTENDED: whether or not to use 9P2000.u extensions |
27 | */ | 27 | * @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy |
28 | * @V9FS_ACCESS_USER: a new attach will be issued for every user (default) | ||
29 | * @V9FS_ACCESS_ANY: use a single attach for all users | ||
30 | * @V9FS_ACCESS_MASK: bit mask of different ACCESS options | ||
31 | * | ||
32 | * Session flags reflect options selected by users at mount time | ||
33 | */ | ||
34 | enum p9_session_flags { | ||
35 | V9FS_EXTENDED = 0x01, | ||
36 | V9FS_ACCESS_SINGLE = 0x02, | ||
37 | V9FS_ACCESS_USER = 0x04, | ||
38 | V9FS_ACCESS_ANY = 0x06, | ||
39 | V9FS_ACCESS_MASK = 0x06, | ||
40 | }; | ||
41 | |||
42 | /* possible values of ->cache */ | ||
43 | /** | ||
44 | * enum p9_cache_modes - user specified cache preferences | ||
45 | * @CACHE_NONE: do not cache data, dentries, or directory contents (default) | ||
46 | * @CACHE_LOOSE: cache data, dentries, and directory contents w/no consistency | ||
47 | * | ||
48 | * eventually support loose, tight, time, session, default always none | ||
49 | */ | ||
50 | |||
51 | enum p9_cache_modes { | ||
52 | CACHE_NONE, | ||
53 | CACHE_LOOSE, | ||
54 | }; | ||
55 | |||
56 | /** | ||
57 | * struct v9fs_session_info - per-instance session information | ||
58 | * @flags: session options of type &p9_session_flags | ||
59 | * @nodev: set to 1 to disable device mapping | ||
60 | * @debug: debug level | ||
61 | * @afid: authentication handle | ||
62 | * @cache: cache mode of type &p9_cache_modes | ||
63 | * @options: copy of options string given by user | ||
64 | * @uname: string user name to mount hierarchy as | ||
65 | * @aname: mount specifier for remote hierarchy | ||
66 | * @maxdata: maximum data to be sent/recvd per protocol message | ||
67 | * @dfltuid: default numeric userid to mount hierarchy as | ||
68 | * @dfltgid: default numeric groupid to mount hierarchy as | ||
69 | * @uid: if %V9FS_ACCESS_SINGLE, the numeric uid which mounted the hierarchy | ||
70 | * @clnt: reference to 9P network client instantiated for this session | ||
71 | * @debugfs_dir: reference to debugfs_dir which can be used for add'l debug | ||
72 | * | ||
73 | * This structure holds state for each session instance established during | ||
74 | * a sys_mount() . | ||
75 | * | ||
76 | * Bugs: there seems to be a lot of state which could be condensed and/or | ||
77 | * removed. | ||
78 | */ | ||
28 | 79 | ||
29 | struct v9fs_session_info { | 80 | struct v9fs_session_info { |
30 | /* options */ | 81 | /* options */ |
31 | unsigned char flags; /* session flags */ | 82 | unsigned char flags; |
32 | unsigned char nodev; /* set to 1 if no disable device mapping */ | 83 | unsigned char nodev; |
33 | unsigned short debug; /* debug level */ | 84 | unsigned short debug; |
34 | unsigned int afid; /* authentication fid */ | 85 | unsigned int afid; |
35 | unsigned int cache; /* cache mode */ | 86 | unsigned int cache; |
36 | 87 | ||
37 | char *options; /* copy of mount options */ | 88 | char *options; /* copy of mount options */ |
38 | char *uname; /* user name to mount as */ | 89 | char *uname; /* user name to mount as */ |
@@ -45,22 +96,6 @@ struct v9fs_session_info { | |||
45 | struct dentry *debugfs_dir; | 96 | struct dentry *debugfs_dir; |
46 | }; | 97 | }; |
47 | 98 | ||
48 | /* session flags */ | ||
49 | enum { | ||
50 | V9FS_EXTENDED = 0x01, /* 9P2000.u */ | ||
51 | V9FS_ACCESS_MASK = 0x06, /* access mask */ | ||
52 | V9FS_ACCESS_SINGLE = 0x02, /* only one user can access the files */ | ||
53 | V9FS_ACCESS_USER = 0x04, /* attache per user */ | ||
54 | V9FS_ACCESS_ANY = 0x06, /* use the same attach for all users */ | ||
55 | }; | ||
56 | |||
57 | /* possible values of ->cache */ | ||
58 | /* eventually support loose, tight, time, session, default always none */ | ||
59 | enum { | ||
60 | CACHE_NONE, /* default */ | ||
61 | CACHE_LOOSE, /* no consistency */ | ||
62 | }; | ||
63 | |||
64 | extern struct dentry *v9fs_debugfs_root; | 99 | extern struct dentry *v9fs_debugfs_root; |
65 | 100 | ||
66 | struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, | 101 | struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, |
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 6248f0e727a3..97d3aed57983 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c | |||
@@ -43,7 +43,7 @@ | |||
43 | /** | 43 | /** |
44 | * v9fs_vfs_readpage - read an entire page in from 9P | 44 | * v9fs_vfs_readpage - read an entire page in from 9P |
45 | * | 45 | * |
46 | * @file: file being read | 46 | * @filp: file being read |
47 | * @page: structure to page | 47 | * @page: structure to page |
48 | * | 48 | * |
49 | */ | 49 | */ |
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 0924d4477da3..88e3787c6ea9 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
@@ -60,7 +60,7 @@ static inline int dt_type(struct p9_stat *mistat) | |||
60 | 60 | ||
61 | /** | 61 | /** |
62 | * v9fs_dir_readdir - read a directory | 62 | * v9fs_dir_readdir - read a directory |
63 | * @filep: opened file structure | 63 | * @filp: opened file structure |
64 | * @dirent: directory structure ??? | 64 | * @dirent: directory structure ??? |
65 | * @filldir: function to populate directory structure ??? | 65 | * @filldir: function to populate directory structure ??? |
66 | * | 66 | * |
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index a616fff8906d..0d55affe37d4 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -90,10 +90,11 @@ int v9fs_file_open(struct inode *inode, struct file *file) | |||
90 | 90 | ||
91 | /** | 91 | /** |
92 | * v9fs_file_lock - lock a file (or directory) | 92 | * v9fs_file_lock - lock a file (or directory) |
93 | * @inode: inode to be opened | 93 | * @filp: file to be locked |
94 | * @file: file being opened | 94 | * @cmd: lock command |
95 | * @fl: file lock structure | ||
95 | * | 96 | * |
96 | * XXX - this looks like a local only lock, we should extend into 9P | 97 | * Bugs: this looks like a local only lock, we should extend into 9P |
97 | * by using open exclusive | 98 | * by using open exclusive |
98 | */ | 99 | */ |
99 | 100 | ||
@@ -118,7 +119,7 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) | |||
118 | 119 | ||
119 | /** | 120 | /** |
120 | * v9fs_file_read - read from a file | 121 | * v9fs_file_read - read from a file |
121 | * @filep: file pointer to read | 122 | * @filp: file pointer to read |
122 | * @data: data buffer to read data into | 123 | * @data: data buffer to read data into |
123 | * @count: size of buffer | 124 | * @count: size of buffer |
124 | * @offset: offset at which to read data | 125 | * @offset: offset at which to read data |
@@ -142,7 +143,7 @@ v9fs_file_read(struct file *filp, char __user * data, size_t count, | |||
142 | 143 | ||
143 | /** | 144 | /** |
144 | * v9fs_file_write - write to a file | 145 | * v9fs_file_write - write to a file |
145 | * @filep: file pointer to write | 146 | * @filp: file pointer to write |
146 | * @data: data buffer to write data from | 147 | * @data: data buffer to write data from |
147 | * @count: size of buffer | 148 | * @count: size of buffer |
148 | * @offset: offset at which to write data | 149 | * @offset: offset at which to write data |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 6a28842052ea..40fa807bd929 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -129,6 +129,12 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode) | |||
129 | return res; | 129 | return res; |
130 | } | 130 | } |
131 | 131 | ||
132 | /** | ||
133 | * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits | ||
134 | * @uflags: flags to convert | ||
135 | * | ||
136 | */ | ||
137 | |||
132 | int v9fs_uflags2omode(int uflags) | 138 | int v9fs_uflags2omode(int uflags) |
133 | { | 139 | { |
134 | int ret; | 140 | int ret; |
@@ -312,6 +318,14 @@ error: | |||
312 | } | 318 | } |
313 | */ | 319 | */ |
314 | 320 | ||
321 | /** | ||
322 | * v9fs_inode_from_fid - populate an inode by issuing a attribute request | ||
323 | * @v9ses: session information | ||
324 | * @fid: fid to issue attribute request for | ||
325 | * @sb: superblock on which to create inode | ||
326 | * | ||
327 | */ | ||
328 | |||
315 | static struct inode * | 329 | static struct inode * |
316 | v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, | 330 | v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, |
317 | struct super_block *sb) | 331 | struct super_block *sb) |
@@ -384,9 +398,12 @@ v9fs_open_created(struct inode *inode, struct file *file) | |||
384 | 398 | ||
385 | /** | 399 | /** |
386 | * v9fs_create - Create a file | 400 | * v9fs_create - Create a file |
401 | * @v9ses: session information | ||
402 | * @dir: directory that dentry is being created in | ||
387 | * @dentry: dentry that is being created | 403 | * @dentry: dentry that is being created |
388 | * @perm: create permissions | 404 | * @perm: create permissions |
389 | * @mode: open mode | 405 | * @mode: open mode |
406 | * @extension: 9p2000.u extension string to support devices, etc. | ||
390 | * | 407 | * |
391 | */ | 408 | */ |
392 | static struct p9_fid * | 409 | static struct p9_fid * |
@@ -461,7 +478,7 @@ error: | |||
461 | 478 | ||
462 | /** | 479 | /** |
463 | * v9fs_vfs_create - VFS hook to create files | 480 | * v9fs_vfs_create - VFS hook to create files |
464 | * @inode: directory inode that is being created | 481 | * @dir: directory inode that is being created |
465 | * @dentry: dentry that is being deleted | 482 | * @dentry: dentry that is being deleted |
466 | * @mode: create permissions | 483 | * @mode: create permissions |
467 | * @nd: path information | 484 | * @nd: path information |
@@ -519,7 +536,7 @@ error: | |||
519 | 536 | ||
520 | /** | 537 | /** |
521 | * v9fs_vfs_mkdir - VFS mkdir hook to create a directory | 538 | * v9fs_vfs_mkdir - VFS mkdir hook to create a directory |
522 | * @inode: inode that is being unlinked | 539 | * @dir: inode that is being unlinked |
523 | * @dentry: dentry that is being unlinked | 540 | * @dentry: dentry that is being unlinked |
524 | * @mode: mode for new directory | 541 | * @mode: mode for new directory |
525 | * | 542 | * |
@@ -703,9 +720,9 @@ done: | |||
703 | 720 | ||
704 | /** | 721 | /** |
705 | * v9fs_vfs_getattr - retrieve file metadata | 722 | * v9fs_vfs_getattr - retrieve file metadata |
706 | * @mnt - mount information | 723 | * @mnt: mount information |
707 | * @dentry - file to get attributes on | 724 | * @dentry: file to get attributes on |
708 | * @stat - metadata structure to populate | 725 | * @stat: metadata structure to populate |
709 | * | 726 | * |
710 | */ | 727 | */ |
711 | 728 | ||
@@ -928,7 +945,7 @@ done: | |||
928 | /** | 945 | /** |
929 | * v9fs_vfs_readlink - read a symlink's location | 946 | * v9fs_vfs_readlink - read a symlink's location |
930 | * @dentry: dentry for symlink | 947 | * @dentry: dentry for symlink |
931 | * @buf: buffer to load symlink location into | 948 | * @buffer: buffer to load symlink location into |
932 | * @buflen: length of buffer | 949 | * @buflen: length of buffer |
933 | * | 950 | * |
934 | */ | 951 | */ |
@@ -996,10 +1013,12 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
996 | * v9fs_vfs_put_link - release a symlink path | 1013 | * v9fs_vfs_put_link - release a symlink path |
997 | * @dentry: dentry for symlink | 1014 | * @dentry: dentry for symlink |
998 | * @nd: nameidata | 1015 | * @nd: nameidata |
1016 | * @p: unused | ||
999 | * | 1017 | * |
1000 | */ | 1018 | */ |
1001 | 1019 | ||
1002 | static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) | 1020 | static void |
1021 | v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) | ||
1003 | { | 1022 | { |
1004 | char *s = nd_get_link(nd); | 1023 | char *s = nd_get_link(nd); |
1005 | 1024 | ||
@@ -1008,6 +1027,15 @@ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void | |||
1008 | __putname(s); | 1027 | __putname(s); |
1009 | } | 1028 | } |
1010 | 1029 | ||
1030 | /** | ||
1031 | * v9fs_vfs_mkspecial - create a special file | ||
1032 | * @dir: inode to create special file in | ||
1033 | * @dentry: dentry to create | ||
1034 | * @mode: mode to create special file | ||
1035 | * @extension: 9p2000.u format extension string representing special file | ||
1036 | * | ||
1037 | */ | ||
1038 | |||
1011 | static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, | 1039 | static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, |
1012 | int mode, const char *extension) | 1040 | int mode, const char *extension) |
1013 | { | 1041 | { |
@@ -1037,7 +1065,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, | |||
1037 | * @dentry: dentry for symlink | 1065 | * @dentry: dentry for symlink |
1038 | * @symname: symlink data | 1066 | * @symname: symlink data |
1039 | * | 1067 | * |
1040 | * See 9P2000.u RFC for more information | 1068 | * See Also: 9P2000.u RFC for more information |
1041 | * | 1069 | * |
1042 | */ | 1070 | */ |
1043 | 1071 | ||
@@ -1058,10 +1086,6 @@ v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) | |||
1058 | * | 1086 | * |
1059 | */ | 1087 | */ |
1060 | 1088 | ||
1061 | /* XXX - lots of code dup'd from symlink and creates, | ||
1062 | * figure out a better reuse strategy | ||
1063 | */ | ||
1064 | |||
1065 | static int | 1089 | static int |
1066 | v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, | 1090 | v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, |
1067 | struct dentry *dentry) | 1091 | struct dentry *dentry) |
@@ -1098,7 +1122,7 @@ clunk_fid: | |||
1098 | * @dir: inode destination for new link | 1122 | * @dir: inode destination for new link |
1099 | * @dentry: dentry for file | 1123 | * @dentry: dentry for file |
1100 | * @mode: mode for creation | 1124 | * @mode: mode for creation |
1101 | * @dev_t: device associated with special file | 1125 | * @rdev: device associated with special file |
1102 | * | 1126 | * |
1103 | */ | 1127 | */ |
1104 | 1128 | ||
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index a452ac67fc94..bf59c3960494 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -75,6 +75,7 @@ static int v9fs_set_super(struct super_block *s, void *data) | |||
75 | * v9fs_fill_super - populate superblock with info | 75 | * v9fs_fill_super - populate superblock with info |
76 | * @sb: superblock | 76 | * @sb: superblock |
77 | * @v9ses: session information | 77 | * @v9ses: session information |
78 | * @flags: flags propagated from v9fs_get_sb() | ||
78 | * | 79 | * |
79 | */ | 80 | */ |
80 | 81 | ||
@@ -127,29 +128,26 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, | |||
127 | fid = v9fs_session_init(v9ses, dev_name, data); | 128 | fid = v9fs_session_init(v9ses, dev_name, data); |
128 | if (IS_ERR(fid)) { | 129 | if (IS_ERR(fid)) { |
129 | retval = PTR_ERR(fid); | 130 | retval = PTR_ERR(fid); |
130 | fid = NULL; | 131 | goto close_session; |
131 | kfree(v9ses); | ||
132 | v9ses = NULL; | ||
133 | goto error; | ||
134 | } | 132 | } |
135 | 133 | ||
136 | st = p9_client_stat(fid); | 134 | st = p9_client_stat(fid); |
137 | if (IS_ERR(st)) { | 135 | if (IS_ERR(st)) { |
138 | retval = PTR_ERR(st); | 136 | retval = PTR_ERR(st); |
139 | goto error; | 137 | goto clunk_fid; |
140 | } | 138 | } |
141 | 139 | ||
142 | sb = sget(fs_type, NULL, v9fs_set_super, v9ses); | 140 | sb = sget(fs_type, NULL, v9fs_set_super, v9ses); |
143 | if (IS_ERR(sb)) { | 141 | if (IS_ERR(sb)) { |
144 | retval = PTR_ERR(sb); | 142 | retval = PTR_ERR(sb); |
145 | goto error; | 143 | goto free_stat; |
146 | } | 144 | } |
147 | v9fs_fill_super(sb, v9ses, flags); | 145 | v9fs_fill_super(sb, v9ses, flags); |
148 | 146 | ||
149 | inode = v9fs_get_inode(sb, S_IFDIR | mode); | 147 | inode = v9fs_get_inode(sb, S_IFDIR | mode); |
150 | if (IS_ERR(inode)) { | 148 | if (IS_ERR(inode)) { |
151 | retval = PTR_ERR(inode); | 149 | retval = PTR_ERR(inode); |
152 | goto error; | 150 | goto release_sb; |
153 | } | 151 | } |
154 | 152 | ||
155 | inode->i_uid = uid; | 153 | inode->i_uid = uid; |
@@ -158,7 +156,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, | |||
158 | root = d_alloc_root(inode); | 156 | root = d_alloc_root(inode); |
159 | if (!root) { | 157 | if (!root) { |
160 | retval = -ENOMEM; | 158 | retval = -ENOMEM; |
161 | goto error; | 159 | goto release_sb; |
162 | } | 160 | } |
163 | 161 | ||
164 | sb->s_root = root; | 162 | sb->s_root = root; |
@@ -169,21 +167,22 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, | |||
169 | 167 | ||
170 | return simple_set_mnt(mnt, sb); | 168 | return simple_set_mnt(mnt, sb); |
171 | 169 | ||
172 | error: | 170 | release_sb: |
173 | kfree(st); | ||
174 | if (fid) | ||
175 | p9_client_clunk(fid); | ||
176 | |||
177 | if (v9ses) { | ||
178 | v9fs_session_close(v9ses); | ||
179 | kfree(v9ses); | ||
180 | } | ||
181 | |||
182 | if (sb) { | 171 | if (sb) { |
183 | up_write(&sb->s_umount); | 172 | up_write(&sb->s_umount); |
184 | deactivate_super(sb); | 173 | deactivate_super(sb); |
185 | } | 174 | } |
186 | 175 | ||
176 | free_stat: | ||
177 | kfree(st); | ||
178 | |||
179 | clunk_fid: | ||
180 | p9_client_clunk(fid); | ||
181 | |||
182 | close_session: | ||
183 | v9fs_session_close(v9ses); | ||
184 | kfree(v9ses); | ||
185 | |||
187 | return retval; | 186 | return retval; |
188 | } | 187 | } |
189 | 188 | ||