aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/fid.c
diff options
context:
space:
mode:
authorLatchesar Ionkov <lucho@ionkov.net>2006-03-02 05:54:30 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-02 11:33:07 -0500
commit6a3124a3946c16159c3faf83e62ffdb5d1134b3a (patch)
tree989f1e89ed0971824db973af5347b879e12c67cd /fs/9p/fid.c
parent77a3313551afd53c90012e5a87f7f2b2195fc67e (diff)
[PATCH] v9fs: fix atomic create open
In order to assure atomic create+open v9fs stores the open fid produced by v9fs_vfs_create in the dentry, from where v9fs_file_open retrieves it and associates it with the open file. This patch modifies v9fs to use nameidata.intent.open values to do the atomic create+open. Signed-off-by: Latchesar Ionkov <lucho@ionkov.net> 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.c73
1 files changed, 17 insertions, 56 deletions
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index eda449778fa5..c27f546dd25b 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -40,7 +40,7 @@
40 * 40 *
41 */ 41 */
42 42
43static int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry) 43int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry)
44{ 44{
45 struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; 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, 46 dprintk(DEBUG_9P, "fid %d (%p) dentry %s (%p)\n", fid->fid, fid,
@@ -68,14 +68,11 @@ static int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry)
68 * 68 *
69 */ 69 */
70 70
71struct v9fs_fid *v9fs_fid_create(struct dentry *dentry, 71struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *v9ses, int fid)
72 struct v9fs_session_info *v9ses, int fid, int create)
73{ 72{
74 struct v9fs_fid *new; 73 struct v9fs_fid *new;
75 74
76 dprintk(DEBUG_9P, "fid create dentry %p, fid %d, create %d\n", 75 dprintk(DEBUG_9P, "fid create fid %d\n", fid);
77 dentry, fid, create);
78
79 new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); 76 new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL);
80 if (new == NULL) { 77 if (new == NULL) {
81 dprintk(DEBUG_ERROR, "Out of Memory\n"); 78 dprintk(DEBUG_ERROR, "Out of Memory\n");
@@ -85,19 +82,13 @@ struct v9fs_fid *v9fs_fid_create(struct dentry *dentry,
85 new->fid = fid; 82 new->fid = fid;
86 new->v9ses = v9ses; 83 new->v9ses = v9ses;
87 new->fidopen = 0; 84 new->fidopen = 0;
88 new->fidcreate = create;
89 new->fidclunked = 0; 85 new->fidclunked = 0;
90 new->iounit = 0; 86 new->iounit = 0;
91 new->rdir_pos = 0; 87 new->rdir_pos = 0;
92 new->rdir_fcall = NULL; 88 new->rdir_fcall = NULL;
89 INIT_LIST_HEAD(&new->list);
93 90
94 if (v9fs_fid_insert(new, dentry) == 0)
95 return new; 91 return new;
96 else {
97 dprintk(DEBUG_ERROR, "Problems inserting to dentry\n");
98 kfree(new);
99 return NULL;
100 }
101} 92}
102 93
103/** 94/**
@@ -119,7 +110,7 @@ void v9fs_fid_destroy(struct v9fs_fid *fid)
119static struct v9fs_fid *v9fs_fid_walk_up(struct dentry *dentry) 110static struct v9fs_fid *v9fs_fid_walk_up(struct dentry *dentry)
120{ 111{
121 int fidnum, cfidnum, err; 112 int fidnum, cfidnum, err;
122 struct v9fs_fid *cfid; 113 struct v9fs_fid *cfid, *fid;
123 struct dentry *cde; 114 struct dentry *cde;
124 struct v9fs_session_info *v9ses; 115 struct v9fs_session_info *v9ses;
125 116
@@ -158,7 +149,16 @@ static struct v9fs_fid *v9fs_fid_walk_up(struct dentry *dentry)
158 cde = cde->d_parent; 149 cde = cde->d_parent;
159 } 150 }
160 151
161 return v9fs_fid_create(dentry, v9ses, fidnum, 0); 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 162
163clunk_fid: 163clunk_fid:
164 v9fs_t_clunk(v9ses, fidnum); 164 v9fs_t_clunk(v9ses, fidnum);
@@ -179,29 +179,12 @@ clunk_fid:
179struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry) 179struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry)
180{ 180{
181 struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; 181 struct list_head *fid_list = (struct list_head *)dentry->d_fsdata;
182 struct v9fs_fid *current_fid = NULL;
183 struct v9fs_fid *temp = NULL;
184 struct v9fs_fid *return_fid = NULL; 182 struct v9fs_fid *return_fid = NULL;
185 183
186 dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry); 184 dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry);
187 185
188 if (fid_list) { 186 if (fid_list)
189 list_for_each_entry_safe(current_fid, temp, fid_list, list) { 187 return_fid = list_entry(fid_list->next, struct v9fs_fid, list);
190 if (!current_fid->fidcreate) {
191 return_fid = current_fid;
192 break;
193 }
194 }
195
196 if (!return_fid)
197 return_fid = current_fid;
198 }
199
200 /* we are at the root but didn't match */
201 if ((!return_fid) && (dentry->d_parent == dentry)) {
202 /* TODO: clone attach with new uid */
203 return_fid = current_fid;
204 }
205 188
206 if (!return_fid) { 189 if (!return_fid) {
207 struct dentry *par = current->fs->pwd->d_parent; 190 struct dentry *par = current->fs->pwd->d_parent;
@@ -228,25 +211,3 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry)
228 211
229 return return_fid; 212 return return_fid;
230} 213}
231
232struct v9fs_fid *v9fs_fid_get_created(struct dentry *dentry)
233{
234 struct list_head *fid_list;
235 struct v9fs_fid *fid, *ftmp, *ret;
236
237 dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry);
238 fid_list = (struct list_head *)dentry->d_fsdata;
239 ret = NULL;
240 if (fid_list) {
241 list_for_each_entry_safe(fid, ftmp, fid_list, list) {
242 if (fid->fidcreate && fid->pid == current->pid) {
243 list_del(&fid->list);
244 ret = fid;
245 break;
246 }
247 }
248 }
249
250 dprintk(DEBUG_9P, "return %p\n", ret);
251 return ret;
252}