aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/fid.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/9p/fid.c')
-rw-r--r--fs/9p/fid.c168
1 files changed, 54 insertions, 114 deletions
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index 90419715c7e9..08fa320b7e6d 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -26,10 +26,10 @@
26#include <linux/sched.h> 26#include <linux/sched.h>
27#include <linux/idr.h> 27#include <linux/idr.h>
28#include <asm/semaphore.h> 28#include <asm/semaphore.h>
29#include <net/9p/9p.h>
30#include <net/9p/client.h>
29 31
30#include "debug.h"
31#include "v9fs.h" 32#include "v9fs.h"
32#include "9p.h"
33#include "v9fs_vfs.h" 33#include "v9fs_vfs.h"
34#include "fid.h" 34#include "fid.h"
35 35
@@ -40,67 +40,29 @@
40 * 40 *
41 */ 41 */
42 42
43int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry) 43int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
44{ 44{
45 struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; 45 struct v9fs_dentry *dent;
46 dprintk(DEBUG_9P, "fid %d (%p) dentry %s (%p)\n", fid->fid, fid,
47 dentry->d_iname, dentry);
48 if (dentry->d_fsdata == NULL) {
49 dentry->d_fsdata =
50 kmalloc(sizeof(struct list_head), GFP_KERNEL);
51 if (dentry->d_fsdata == NULL) {
52 dprintk(DEBUG_ERROR, "Out of memory\n");
53 return -ENOMEM;
54 }
55 fid_list = (struct list_head *)dentry->d_fsdata;
56 INIT_LIST_HEAD(fid_list); /* Initialize list head */
57 }
58 46
59 fid->uid = current->uid; 47 P9_DPRINTK(P9_DEBUG_VFS, "fid %d dentry %s\n",
60 list_add(&fid->list, fid_list); 48 fid->fid, dentry->d_iname);
61 return 0;
62}
63 49
64/** 50 dent = dentry->d_fsdata;
65 * v9fs_fid_create - allocate a FID structure 51 if (!dent) {
66 * @dentry - dentry to link newly created fid to 52 dent = kmalloc(sizeof(struct v9fs_dentry), GFP_KERNEL);
67 * 53 if (!dent)
68 */ 54 return -ENOMEM;
69
70struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *v9ses, int fid)
71{
72 struct v9fs_fid *new;
73 55
74 dprintk(DEBUG_9P, "fid create fid %d\n", fid); 56 spin_lock_init(&dent->lock);
75 new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); 57 INIT_LIST_HEAD(&dent->fidlist);
76 if (new == NULL) { 58 dentry->d_fsdata = dent;
77 dprintk(DEBUG_ERROR, "Out of Memory\n");
78 return ERR_PTR(-ENOMEM);
79 } 59 }
80 60
81 new->fid = fid; 61 spin_lock(&dent->lock);
82 new->v9ses = v9ses; 62 list_add(&fid->dlist, &dent->fidlist);
83 new->fidopen = 0; 63 spin_unlock(&dent->lock);
84 new->fidclunked = 0;
85 new->iounit = 0;
86 new->rdir_pos = 0;
87 new->rdir_fcall = NULL;
88 init_MUTEX(&new->lock);
89 INIT_LIST_HEAD(&new->list);
90
91 return new;
92}
93
94/**
95 * v9fs_fid_destroy - deallocate a FID structure
96 * @fid: fid to destroy
97 *
98 */
99 64
100void v9fs_fid_destroy(struct v9fs_fid *fid) 65 return 0;
101{
102 list_del(&fid->list);
103 kfree(fid);
104} 66}
105 67
106/** 68/**
@@ -114,30 +76,42 @@ void v9fs_fid_destroy(struct v9fs_fid *fid)
114 * 76 *
115 */ 77 */
116 78
117struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry) 79struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
118{ 80{
119 struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; 81 struct v9fs_dentry *dent;
120 struct v9fs_fid *return_fid = NULL; 82 struct p9_fid *fid;
121 83
122 dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry); 84 P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
123 85 dent = dentry->d_fsdata;
124 if (fid_list) 86 if (dent)
125 return_fid = list_entry(fid_list->next, struct v9fs_fid, list); 87 fid = list_entry(dent->fidlist.next, struct p9_fid, dlist);
88 else
89 fid = ERR_PTR(-EBADF);
90
91 P9_DPRINTK(P9_DEBUG_VFS, " fid: %p\n", fid);
92 return fid;
93}
126 94
127 if (!return_fid) { 95struct p9_fid *v9fs_fid_lookup_remove(struct dentry *dentry)
128 dprintk(DEBUG_ERROR, "Couldn't find a fid in dentry\n"); 96{
129 return_fid = ERR_PTR(-EBADF); 97 struct p9_fid *fid;
98 struct v9fs_dentry *dent;
99
100 dent = dentry->d_fsdata;
101 fid = v9fs_fid_lookup(dentry);
102 if (!IS_ERR(fid)) {
103 spin_lock(&dent->lock);
104 list_del(&fid->dlist);
105 spin_unlock(&dent->lock);
130 } 106 }
131 107
132 if(down_interruptible(&return_fid->lock)) 108 return fid;
133 return ERR_PTR(-EINTR);
134
135 return return_fid;
136} 109}
137 110
111
138/** 112/**
139 * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and 113 * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and
140 * release it 114 * release it
141 * @dentry: dentry to look for fid in 115 * @dentry: dentry to look for fid in
142 * 116 *
143 * find a fid in the dentry and then clone to a new private fid 117 * find a fid in the dentry and then clone to a new private fid
@@ -146,49 +120,15 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry)
146 * 120 *
147 */ 121 */
148 122
149struct v9fs_fid *v9fs_fid_clone(struct dentry *dentry) 123struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
150{ 124{
151 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); 125 struct p9_fid *ofid, *fid;
152 struct v9fs_fid *base_fid, *new_fid = ERR_PTR(-EBADF);
153 struct v9fs_fcall *fcall = NULL;
154 int fid, err;
155
156 base_fid = v9fs_fid_lookup(dentry);
157
158 if(IS_ERR(base_fid))
159 return base_fid;
160
161 if(base_fid) { /* clone fid */
162 fid = v9fs_get_idpool(&v9ses->fidpool);
163 if (fid < 0) {
164 eprintk(KERN_WARNING, "newfid fails!\n");
165 new_fid = ERR_PTR(-ENOSPC);
166 goto Release_Fid;
167 }
168
169 err = v9fs_t_walk(v9ses, base_fid->fid, fid, NULL, &fcall);
170 if (err < 0) {
171 dprintk(DEBUG_ERROR, "clone walk didn't work\n");
172 v9fs_put_idpool(fid, &v9ses->fidpool);
173 new_fid = ERR_PTR(err);
174 goto Free_Fcall;
175 }
176 new_fid = v9fs_fid_create(v9ses, fid);
177 if (new_fid == NULL) {
178 dprintk(DEBUG_ERROR, "out of memory\n");
179 new_fid = ERR_PTR(-ENOMEM);
180 }
181Free_Fcall:
182 kfree(fcall);
183 }
184 126
185Release_Fid: 127 P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
186 up(&base_fid->lock); 128 ofid = v9fs_fid_lookup(dentry);
187 return new_fid; 129 if (IS_ERR(ofid))
188} 130 return ofid;
189 131
190void v9fs_fid_clunk(struct v9fs_session_info *v9ses, struct v9fs_fid *fid) 132 fid = p9_client_walk(ofid, 0, NULL, 1);
191{ 133 return fid;
192 v9fs_t_clunk(v9ses, fid->fid);
193 v9fs_fid_destroy(fid);
194} 134}