diff options
author | Eric Van Hensbergen <ericvh@gmail.com> | 2006-03-02 05:54:33 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-02 11:33:07 -0500 |
commit | 46f6dac259717551916405ee3388de89fb152bca (patch) | |
tree | 0e6c8b4505339e90c05ec8326220286fd19fe1f4 /fs/9p/fid.c | |
parent | 74b8054c730785cd9db093e48f53337e521b6270 (diff) |
[PATCH] v9fs: simplify fid mapping
v9fs has been plagued by an over-complicated approach trying to map Linux
dentry semantics to Plan 9 fid semantics. Our previous approach called for
aggressive flushing of the dcache resulting in several problems (including
wierd cwd behavior when running /bin/pwd).
This patch dramatically simplifies our handling of this fid management. Fids
will not be clunked as promptly, but the new approach is more functionally
correct. We now clunk un-open fids only when their dentry ref_count reaches 0
(and d_delete is called).
Another simplification is we no longer seek to match fids to the process-id or
uid of the action initiator. The uid-matching will need to be revisited when
we fix the security model.
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/9p/fid.c')
-rw-r--r-- | fs/9p/fid.c | 94 |
1 files changed, 6 insertions, 88 deletions
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index c27f546dd25b..c4d13bf904d2 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * V9FS FID Management | 2 | * V9FS FID Management |
3 | * | 3 | * |
4 | * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com> | 4 | * Copyright (C) 2005, 2006 by Eric Van Hensbergen <ericvh@gmail.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -57,7 +57,6 @@ int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry) | |||
57 | } | 57 | } |
58 | 58 | ||
59 | fid->uid = current->uid; | 59 | fid->uid = current->uid; |
60 | fid->pid = current->pid; | ||
61 | list_add(&fid->list, fid_list); | 60 | list_add(&fid->list, fid_list); |
62 | return 0; | 61 | return 0; |
63 | } | 62 | } |
@@ -88,7 +87,7 @@ struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *v9ses, int fid) | |||
88 | new->rdir_fcall = NULL; | 87 | new->rdir_fcall = NULL; |
89 | INIT_LIST_HEAD(&new->list); | 88 | INIT_LIST_HEAD(&new->list); |
90 | 89 | ||
91 | return new; | 90 | return new; |
92 | } | 91 | } |
93 | 92 | ||
94 | /** | 93 | /** |
@@ -104,75 +103,13 @@ void v9fs_fid_destroy(struct v9fs_fid *fid) | |||
104 | } | 103 | } |
105 | 104 | ||
106 | /** | 105 | /** |
107 | * v9fs_fid_walk_up - walks from the process current directory | ||
108 | * up to the specified dentry. | ||
109 | */ | ||
110 | static struct v9fs_fid *v9fs_fid_walk_up(struct dentry *dentry) | ||
111 | { | ||
112 | int fidnum, cfidnum, err; | ||
113 | struct v9fs_fid *cfid, *fid; | ||
114 | struct dentry *cde; | ||
115 | struct v9fs_session_info *v9ses; | ||
116 | |||
117 | v9ses = v9fs_inode2v9ses(current->fs->pwd->d_inode); | ||
118 | cfid = v9fs_fid_lookup(current->fs->pwd); | ||
119 | if (cfid == NULL) { | ||
120 | dprintk(DEBUG_ERROR, "process cwd doesn't have a fid\n"); | ||
121 | return ERR_PTR(-ENOENT); | ||
122 | } | ||
123 | |||
124 | cfidnum = cfid->fid; | ||
125 | cde = current->fs->pwd; | ||
126 | /* TODO: take advantage of multiwalk */ | ||
127 | |||
128 | fidnum = v9fs_get_idpool(&v9ses->fidpool); | ||
129 | if (fidnum < 0) { | ||
130 | dprintk(DEBUG_ERROR, "could not get a new fid num\n"); | ||
131 | err = -ENOENT; | ||
132 | goto clunk_fid; | ||
133 | } | ||
134 | |||
135 | while (cde != dentry) { | ||
136 | if (cde == cde->d_parent) { | ||
137 | dprintk(DEBUG_ERROR, "can't find dentry\n"); | ||
138 | err = -ENOENT; | ||
139 | goto clunk_fid; | ||
140 | } | ||
141 | |||
142 | err = v9fs_t_walk(v9ses, cfidnum, fidnum, "..", NULL); | ||
143 | if (err < 0) { | ||
144 | dprintk(DEBUG_ERROR, "problem walking to parent\n"); | ||
145 | goto clunk_fid; | ||
146 | } | ||
147 | |||
148 | cfidnum = fidnum; | ||
149 | cde = cde->d_parent; | ||
150 | } | ||
151 | |||
152 | fid = v9fs_fid_create(v9ses, fidnum); | ||
153 | if (fid) { | ||
154 | err = v9fs_fid_insert(fid, dentry); | ||
155 | if (err < 0) { | ||
156 | kfree(fid); | ||
157 | goto clunk_fid; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | return fid; | ||
162 | |||
163 | clunk_fid: | ||
164 | v9fs_t_clunk(v9ses, fidnum); | ||
165 | return ERR_PTR(err); | ||
166 | } | ||
167 | |||
168 | /** | ||
169 | * v9fs_fid_lookup - retrieve the right fid from a particular dentry | 106 | * v9fs_fid_lookup - retrieve the right fid from a particular dentry |
170 | * @dentry: dentry to look for fid in | 107 | * @dentry: dentry to look for fid in |
171 | * @type: intent of lookup (operation or traversal) | 108 | * @type: intent of lookup (operation or traversal) |
172 | * | 109 | * |
173 | * search list of fids associated with a dentry for a fid with a matching | 110 | * find a fid in the dentry |
174 | * thread id or uid. If that fails, look up the dentry's parents to see if you | 111 | * |
175 | * can find a matching fid. | 112 | * TODO: only match fids that have the same uid as current user |
176 | * | 113 | * |
177 | */ | 114 | */ |
178 | 115 | ||
@@ -187,26 +124,7 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry) | |||
187 | return_fid = list_entry(fid_list->next, struct v9fs_fid, list); | 124 | return_fid = list_entry(fid_list->next, struct v9fs_fid, list); |
188 | 125 | ||
189 | if (!return_fid) { | 126 | if (!return_fid) { |
190 | struct dentry *par = current->fs->pwd->d_parent; | 127 | dprintk(DEBUG_ERROR, "Couldn't find a fid in dentry\n"); |
191 | int count = 1; | ||
192 | while (par != NULL) { | ||
193 | if (par == dentry) | ||
194 | break; | ||
195 | count++; | ||
196 | if (par == par->d_parent) { | ||
197 | dprintk(DEBUG_ERROR, | ||
198 | "got to root without finding dentry\n"); | ||
199 | break; | ||
200 | } | ||
201 | par = par->d_parent; | ||
202 | } | ||
203 | |||
204 | /* XXX - there may be some duplication we can get rid of */ | ||
205 | if (par == dentry) { | ||
206 | return_fid = v9fs_fid_walk_up(dentry); | ||
207 | if (IS_ERR(return_fid)) | ||
208 | return_fid = NULL; | ||
209 | } | ||
210 | } | 128 | } |
211 | 129 | ||
212 | return return_fid; | 130 | return return_fid; |