4 #define DEBUG_SUBSYSTEM S_SNAP
6 #include <linux/module.h>
7 #include <linux/kernel.h>
8 #include <linux/string.h>
9 #include <linux/slab.h>
10 #include <linux/stat.h>
11 #include <linux/unistd.h>
13 #include "smfs_internal.h"
15 static void d_unalloc(struct dentry *dentry)
18 list_del(&dentry->d_hash);
19 INIT_LIST_HEAD(&dentry->d_hash);
23 static struct inode *sm_create_inode(struct super_block *sb,
24 struct inode *cache_inode)
28 inode = new_inode(sb);
30 /*FIXME there are still some
31 * other attributes need to
33 inode->i_ino = cache_inode->i_ino;
34 inode->i_mode = cache_inode->i_mode;
36 I2CI(inode) = cache_inode;
40 static void prepare_parent_dentry(struct dentry *dentry, struct inode *inode)
42 atomic_set(&dentry->d_count, 1);
43 dentry->d_vfs_flags = 0;
45 dentry->d_inode = inode;
47 dentry->d_fsdata = NULL;
48 dentry->d_mounted = 0;
49 INIT_LIST_HEAD(&dentry->d_hash);
50 INIT_LIST_HEAD(&dentry->d_lru);
51 INIT_LIST_HEAD(&dentry->d_subdirs);
52 INIT_LIST_HEAD(&dentry->d_alias);
55 static int smfs_create(struct inode *dir,
56 struct dentry *dentry,
59 struct inode *cache_dir;
60 struct inode *cache_inode, *inode;
62 struct dentry *cache_dentry;
67 cache_dir = I2CI(dir);
71 prepare_parent_dentry(&tmp, cache_dir);
72 cache_dentry = d_alloc(&tmp, &dentry->d_name);
77 if(cache_dir && cache_dir->i_op->create)
78 rc = cache_dir->i_op->create(cache_dir, cache_dentry, mode);
82 cache_inode = cache_dentry->d_inode;
84 // inode = sm_create_inode(dir->i_sb, cache_inode);
85 inode = iget(dir->i_sb, cache_inode->i_ino);
88 GOTO(exit, rc = -ENOMEM);
90 d_instantiate(dentry, inode);
92 sm_set_inode_ops(cache_inode, inode);
94 d_unalloc(cache_dentry);
98 static struct dentry *smfs_lookup(struct inode *dir,
99 struct dentry *dentry)
101 struct inode *cache_dir;
102 struct inode *cache_inode, *inode;
104 struct dentry *cache_dentry;
105 struct dentry *rc = NULL;
109 cache_dir = I2CI(dir);
111 RETURN(ERR_PTR(-ENOENT));
112 prepare_parent_dentry(&tmp, cache_dir);
113 cache_dentry = d_alloc(&tmp, &dentry->d_name);
116 RETURN(ERR_PTR(-ENOENT));
118 if(cache_dir && cache_dir->i_op->lookup)
119 rc = cache_dir->i_op->lookup(cache_dir, cache_dentry);
121 if (rc || !cache_dentry->d_inode ||
122 is_bad_inode(cache_dentry->d_inode) ||
123 IS_ERR(cache_dentry->d_inode)) {
127 cache_inode = cache_dentry->d_inode;
129 inode = iget(dir->i_sb, cache_inode->i_ino);
131 d_add(dentry, inode);
133 d_unalloc(cache_dentry);
137 static int smfs_lookup_raw(struct inode *dir, const char *name,
138 int len, ino_t *data)
140 struct inode *cache_dir;
143 cache_dir = I2CI(dir);
148 if (cache_dir->i_op->lookup_raw)
149 rc = cache_dir->i_op->lookup_raw(cache_dir, name, len, data);
154 static int smfs_link(struct dentry * old_dentry,
155 struct inode * dir, struct dentry *dentry)
157 struct inode *cache_old_inode = NULL;
158 struct inode *cache_dir = I2CI(dir);
159 struct inode *inode = NULL;
160 struct dentry *cache_dentry = NULL;
162 struct dentry tmp_old;
165 inode = old_dentry->d_inode;
167 cache_old_inode = I2CI(inode);
169 if (!cache_old_inode || !dir)
172 prepare_parent_dentry(&tmp_old, cache_old_inode);
174 prepare_parent_dentry(&tmp, cache_dir);
175 cache_dentry = d_alloc(&tmp, &dentry->d_name);
177 if (cache_dir->i_op->link)
178 rc = cache_dir->i_op->link(&tmp, cache_dir, cache_dentry);
181 d_instantiate(dentry, inode);
184 d_unalloc(cache_dentry);
188 static int smfs_unlink(struct inode * dir,
189 struct dentry *dentry)
191 struct inode *cache_dir = I2CI(dir);
192 struct inode *cache_inode = I2CI(dentry->d_inode);
193 struct dentry *cache_dentry = NULL;
197 if (!cache_dir || !cache_inode)
200 prepare_parent_dentry(&tmp, cache_dir);
201 cache_dentry = d_alloc(&tmp, &dentry->d_name);
202 d_add(cache_dentry, cache_inode);
204 if (cache_inode->i_op->unlink)
205 rc = cache_dir->i_op->unlink(cache_dir, cache_dentry);
207 duplicate_inode(tmp.d_inode, dentry->d_inode);
209 d_unalloc(cache_dentry);
212 static int smfs_symlink (struct inode * dir,
213 struct dentry *dentry,
214 const char * symname)
216 struct inode *cache_dir = I2CI(dir);
217 struct inode *cache_inode = NULL;
218 struct inode *inode = NULL;
219 struct dentry *cache_dentry = NULL;
226 prepare_parent_dentry(&tmp, NULL);
227 cache_dentry = d_alloc(&tmp, &dentry->d_name);
229 if (cache_inode->i_op->symlink)
230 rc = cache_dir->i_op->symlink(cache_dir, cache_dentry, symname);
232 cache_inode = cache_dentry->d_inode;
234 inode = iget(dir->i_sb, cache_inode->i_ino);
237 d_instantiate(dentry, inode);
241 d_unalloc(cache_dentry);
244 static int smfs_mkdir(struct inode * dir,
245 struct dentry * dentry,
248 struct inode *cache_dir = I2CI(dir);
249 struct inode *cache_inode = NULL;
250 struct inode *inode = NULL;
251 struct dentry *cache_dentry = NULL;
258 prepare_parent_dentry(&tmp, NULL);
259 cache_dentry = d_alloc(&tmp, &dentry->d_name);
261 if (cache_dir->i_op->mkdir)
262 rc = cache_dir->i_op->mkdir(cache_dir, cache_dentry, mode);
264 cache_inode = cache_dentry->d_inode;
266 inode = iget(dir->i_sb, cache_inode->i_ino);
269 GOTO(exit, rc = -ENOENT);
271 d_instantiate(dentry, inode);
272 duplicate_inode(cache_dir, dir);
274 d_unalloc(cache_dentry);
277 static int smfs_rmdir(struct inode * dir,
278 struct dentry *dentry)
280 struct inode *cache_dir = I2CI(dir);
281 struct dentry *cache_dentry = NULL;
288 prepare_parent_dentry(&tmp, NULL);
289 cache_dentry = d_alloc(&tmp, &dentry->d_name);
291 if (cache_dir->i_op->rmdir)
292 rc = cache_dir->i_op->rmdir(cache_dir, cache_dentry);
294 duplicate_inode(cache_dir, dir);
295 duplicate_inode(cache_dentry->d_inode, dentry->d_inode);
297 d_unalloc(cache_dentry);
301 static int smfs_mknod(struct inode * dir, struct dentry *dentry,
304 struct inode *cache_dir = I2CI(dir);
305 struct dentry *cache_dentry = NULL;
312 prepare_parent_dentry(&tmp, NULL);
313 cache_dentry = d_alloc(&tmp, &dentry->d_name);
315 if (cache_dir->i_op->mknod)
316 rc = cache_dir->i_op->mknod(cache_dir, dentry, mode, rdev);
318 duplicate_inode(cache_dir, dir);
319 duplicate_inode(cache_dentry->d_inode, dentry->d_inode);
321 d_unalloc(cache_dentry);
324 static int smfs_rename(struct inode * old_dir, struct dentry *old_dentry,
325 struct inode * new_dir,struct dentry *new_dentry)
327 struct inode *cache_old_dir = I2CI(old_dir);
328 struct inode *cache_new_dir = I2CI(new_dir);
329 struct inode *cache_old_inode = I2CI(old_dentry->d_inode);
330 struct inode *cache_new_inode = NULL;
331 struct inode *new_inode = NULL;
332 struct dentry *cache_old_dentry = NULL;
333 struct dentry *cache_new_dentry = NULL;
334 struct dentry tmp_new;
335 struct dentry tmp_old;
338 if (!cache_old_dir || !cache_new_dir || !cache_old_inode)
341 prepare_parent_dentry(&tmp_old, old_dir);
342 cache_old_dentry = d_alloc(&tmp_old, &old_dentry->d_name);
343 d_add(cache_old_dentry, cache_old_inode);
345 prepare_parent_dentry(&tmp_new, NULL);
346 cache_new_dentry = d_alloc(&tmp_new, &new_dentry->d_name);
348 if (cache_old_dir->i_op->rename)
349 rc = cache_old_dir->i_op->rename(cache_old_dir, cache_old_dentry,
350 cache_new_dir, cache_new_dentry);
352 cache_new_inode = cache_new_dentry->d_inode;
353 new_inode = iget(new_dir->i_sb, cache_new_inode->i_ino);
355 d_instantiate(new_dentry, new_inode);
357 duplicate_inode(cache_old_dir, old_dir);
358 duplicate_inode(cache_new_dir, new_dir);
360 d_unalloc(cache_old_dentry);
361 d_unalloc(cache_new_dentry);
366 struct inode_operations smfs_dir_iops = {
369 lookup_raw: smfs_lookup_raw, /* BKL held */
370 link: smfs_link, /* BKL held */
371 unlink: smfs_unlink, /* BKL held */
372 symlink: smfs_symlink, /* BKL held */
373 mkdir: smfs_mkdir, /* BKL held */
374 rmdir: smfs_rmdir, /* BKL held */
375 mknod: smfs_mknod, /* BKL held */
376 rename: smfs_rename, /* BKL held */
377 setxattr: smfs_setxattr, /* BKL held */
378 getxattr: smfs_getxattr, /* BKL held */
379 listxattr: smfs_listxattr, /* BKL held */
380 removexattr: smfs_removexattr, /* BKL held */
383 static ssize_t smfs_read_dir(struct file *filp, char *buf,
384 size_t size, loff_t *ppos)
386 struct dentry *dentry = filp->f_dentry;
387 struct inode *cache_inode = NULL;
388 struct file open_file;
389 struct dentry open_dentry;
392 cache_inode = I2CI(dentry->d_inode);
397 smfs_prepare_cachefile(dentry->d_inode, filp, cache_inode,
398 &open_file, &open_dentry);
400 if (cache_inode->i_fop->read)
401 rc = cache_inode->i_fop->read(&open_file, buf, size, ppos);
403 smfs_update_file(filp, &open_file);
407 static int smfs_readdir(struct file * filp,
411 struct dentry *dentry = filp->f_dentry;
412 struct inode *cache_inode = NULL;
413 struct file open_file;
414 struct dentry open_dentry;
417 cache_inode = I2CI(dentry->d_inode);
422 smfs_prepare_cachefile(dentry->d_inode, filp, cache_inode,
423 &open_file, &open_dentry);
425 if (cache_inode->i_fop->readdir)
426 rc = cache_inode->i_fop->readdir(&open_file, dirent, filldir);
428 smfs_update_file(filp, &open_file);
432 struct file_operations smfs_dir_fops = {
434 readdir: smfs_readdir, /* BKL held */
435 ioctl: smfs_ioctl, /* BKL held */
436 fsync: smfs_fsync, /* BKL held */