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);
24 static void prepare_parent_dentry(struct dentry *dentry, struct inode *inode)
26 atomic_set(&dentry->d_count, 1);
27 dentry->d_vfs_flags = 0;
29 dentry->d_inode = inode;
31 dentry->d_fsdata = NULL;
32 dentry->d_mounted = 0;
33 INIT_LIST_HEAD(&dentry->d_hash);
34 INIT_LIST_HEAD(&dentry->d_lru);
35 INIT_LIST_HEAD(&dentry->d_subdirs);
36 INIT_LIST_HEAD(&dentry->d_alias);
39 static int smfs_create(struct inode *dir,
40 struct dentry *dentry,
43 struct inode *cache_dir;
44 struct inode *cache_inode, *inode;
46 struct dentry *cache_dentry;
51 cache_dir = I2CI(dir);
55 prepare_parent_dentry(&tmp, cache_dir);
56 cache_dentry = d_alloc(&tmp, &dentry->d_name);
61 if(cache_dir && cache_dir->i_op->create)
62 rc = cache_dir->i_op->create(cache_dir, cache_dentry, mode);
66 cache_inode = cache_dentry->d_inode;
68 inode = iget(dir->i_sb, cache_inode->i_ino);
71 GOTO(exit, rc = -ENOMEM);
73 d_instantiate(dentry, inode);
75 sm_set_inode_ops(cache_inode, inode);
77 d_unalloc(cache_dentry);
81 static struct dentry *smfs_lookup(struct inode *dir,
82 struct dentry *dentry)
84 struct inode *cache_dir;
85 struct inode *cache_inode, *inode;
87 struct dentry *cache_dentry;
88 struct dentry *rc = NULL;
92 cache_dir = I2CI(dir);
94 RETURN(ERR_PTR(-ENOENT));
95 prepare_parent_dentry(&tmp, cache_dir);
96 cache_dentry = d_alloc(&tmp, &dentry->d_name);
99 RETURN(ERR_PTR(-ENOENT));
101 if(cache_dir && cache_dir->i_op->lookup)
102 rc = cache_dir->i_op->lookup(cache_dir, cache_dentry);
104 if (rc || !cache_dentry->d_inode ||
105 is_bad_inode(cache_dentry->d_inode) ||
106 IS_ERR(cache_dentry->d_inode)) {
110 cache_inode = cache_dentry->d_inode;
112 inode = iget(dir->i_sb, cache_inode->i_ino);
114 d_add(dentry, inode);
116 d_unalloc(cache_dentry);
120 static int smfs_lookup_raw(struct inode *dir, const char *name,
121 int len, ino_t *data)
123 struct inode *cache_dir;
126 cache_dir = I2CI(dir);
131 if (cache_dir->i_op->lookup_raw)
132 rc = cache_dir->i_op->lookup_raw(cache_dir, name, len, data);
137 static int smfs_link(struct dentry * old_dentry,
138 struct inode * dir, struct dentry *dentry)
140 struct inode *cache_old_inode = NULL;
141 struct inode *cache_dir = I2CI(dir);
142 struct inode *inode = NULL;
143 struct dentry *cache_dentry = NULL;
145 struct dentry tmp_old;
148 inode = old_dentry->d_inode;
150 cache_old_inode = I2CI(inode);
152 if (!cache_old_inode || !dir)
155 prepare_parent_dentry(&tmp_old, cache_old_inode);
157 prepare_parent_dentry(&tmp, cache_dir);
158 cache_dentry = d_alloc(&tmp, &dentry->d_name);
160 if (cache_dir->i_op->link)
161 rc = cache_dir->i_op->link(&tmp, cache_dir, cache_dentry);
164 d_instantiate(dentry, inode);
167 d_unalloc(cache_dentry);
171 static int smfs_unlink(struct inode * dir,
172 struct dentry *dentry)
174 struct inode *cache_dir = I2CI(dir);
175 struct inode *cache_inode = I2CI(dentry->d_inode);
176 struct dentry *cache_dentry = NULL;
180 if (!cache_dir || !cache_inode)
183 prepare_parent_dentry(&tmp, cache_dir);
184 cache_dentry = d_alloc(&tmp, &dentry->d_name);
185 d_add(cache_dentry, cache_inode);
188 if (cache_dir->i_op->unlink)
189 rc = cache_dir->i_op->unlink(cache_dir, cache_dentry);
192 duplicate_inode(cache_dentry->d_inode, dentry->d_inode);
193 duplicate_inode(cache_dir, dir);
195 d_unalloc(cache_dentry);
198 static int smfs_symlink (struct inode * dir,
199 struct dentry *dentry,
200 const char * symname)
202 struct inode *cache_dir = I2CI(dir);
203 struct inode *cache_inode = NULL;
204 struct inode *inode = NULL;
205 struct dentry *cache_dentry = NULL;
212 prepare_parent_dentry(&tmp, NULL);
213 cache_dentry = d_alloc(&tmp, &dentry->d_name);
215 if (cache_inode->i_op->symlink)
216 rc = cache_dir->i_op->symlink(cache_dir, cache_dentry, symname);
218 cache_inode = cache_dentry->d_inode;
220 inode = iget(dir->i_sb, cache_inode->i_ino);
223 d_instantiate(dentry, inode);
227 d_unalloc(cache_dentry);
230 static int smfs_mkdir(struct inode * dir,
231 struct dentry * dentry,
234 struct inode *cache_dir = I2CI(dir);
235 struct inode *cache_inode = NULL;
236 struct inode *inode = NULL;
237 struct dentry *cache_dentry = NULL;
244 prepare_parent_dentry(&tmp, NULL);
245 cache_dentry = d_alloc(&tmp, &dentry->d_name);
247 if (cache_dir->i_op->mkdir)
248 rc = cache_dir->i_op->mkdir(cache_dir, cache_dentry, mode);
250 cache_inode = cache_dentry->d_inode;
252 inode = iget(dir->i_sb, cache_inode->i_ino);
255 GOTO(exit, rc = -ENOENT);
257 d_instantiate(dentry, inode);
258 duplicate_inode(cache_dir, dir);
260 d_unalloc(cache_dentry);
263 static int smfs_rmdir(struct inode * dir,
264 struct dentry *dentry)
266 struct inode *cache_dir = I2CI(dir);
267 struct dentry *cache_dentry = NULL;
274 prepare_parent_dentry(&tmp, NULL);
275 cache_dentry = d_alloc(&tmp, &dentry->d_name);
277 if (cache_dir->i_op->rmdir)
278 rc = cache_dir->i_op->rmdir(cache_dir, cache_dentry);
280 duplicate_inode(cache_dir, dir);
281 duplicate_inode(cache_dentry->d_inode, dentry->d_inode);
283 d_unalloc(cache_dentry);
287 static int smfs_mknod(struct inode * dir, struct dentry *dentry,
290 struct inode *cache_dir = I2CI(dir);
291 struct dentry *cache_dentry = NULL;
298 prepare_parent_dentry(&tmp, NULL);
299 cache_dentry = d_alloc(&tmp, &dentry->d_name);
301 if (cache_dir->i_op->mknod)
302 rc = cache_dir->i_op->mknod(cache_dir, dentry, mode, rdev);
304 duplicate_inode(cache_dir, dir);
305 duplicate_inode(cache_dentry->d_inode, dentry->d_inode);
307 d_unalloc(cache_dentry);
310 static int smfs_rename(struct inode * old_dir, struct dentry *old_dentry,
311 struct inode * new_dir,struct dentry *new_dentry)
313 struct inode *cache_old_dir = I2CI(old_dir);
314 struct inode *cache_new_dir = I2CI(new_dir);
315 struct inode *cache_old_inode = I2CI(old_dentry->d_inode);
316 struct inode *cache_new_inode = NULL;
317 struct inode *new_inode = NULL;
318 struct dentry *cache_old_dentry = NULL;
319 struct dentry *cache_new_dentry = NULL;
320 struct dentry tmp_new;
321 struct dentry tmp_old;
324 if (!cache_old_dir || !cache_new_dir || !cache_old_inode)
327 prepare_parent_dentry(&tmp_old, old_dir);
328 cache_old_dentry = d_alloc(&tmp_old, &old_dentry->d_name);
329 d_add(cache_old_dentry, cache_old_inode);
331 prepare_parent_dentry(&tmp_new, NULL);
332 cache_new_dentry = d_alloc(&tmp_new, &new_dentry->d_name);
334 if (cache_old_dir->i_op->rename)
335 rc = cache_old_dir->i_op->rename(cache_old_dir, cache_old_dentry,
336 cache_new_dir, cache_new_dentry);
338 cache_new_inode = cache_new_dentry->d_inode;
339 new_inode = iget(new_dir->i_sb, cache_new_inode->i_ino);
341 d_instantiate(new_dentry, new_inode);
343 duplicate_inode(cache_old_dir, old_dir);
344 duplicate_inode(cache_new_dir, new_dir);
346 d_unalloc(cache_old_dentry);
347 d_unalloc(cache_new_dentry);
352 struct inode_operations smfs_dir_iops = {
355 lookup_raw: smfs_lookup_raw, /* BKL held */
356 link: smfs_link, /* BKL held */
357 unlink: smfs_unlink, /* BKL held */
358 symlink: smfs_symlink, /* BKL held */
359 mkdir: smfs_mkdir, /* BKL held */
360 rmdir: smfs_rmdir, /* BKL held */
361 mknod: smfs_mknod, /* BKL held */
362 rename: smfs_rename, /* BKL held */
363 setxattr: smfs_setxattr, /* BKL held */
364 getxattr: smfs_getxattr, /* BKL held */
365 listxattr: smfs_listxattr, /* BKL held */
366 removexattr: smfs_removexattr, /* BKL held */
369 static ssize_t smfs_read_dir(struct file *filp, char *buf,
370 size_t size, loff_t *ppos)
372 struct dentry *dentry = filp->f_dentry;
373 struct inode *cache_inode = NULL;
374 struct file open_file;
375 struct dentry open_dentry;
378 cache_inode = I2CI(dentry->d_inode);
383 smfs_prepare_cachefile(dentry->d_inode, filp, cache_inode,
384 &open_file, &open_dentry);
386 if (cache_inode->i_fop->read)
387 rc = cache_inode->i_fop->read(&open_file, buf, size, ppos);
389 smfs_update_file(filp, &open_file);
393 static int smfs_readdir(struct file * filp,
397 struct dentry *dentry = filp->f_dentry;
398 struct inode *cache_inode = NULL;
399 struct file open_file;
400 struct dentry open_dentry;
403 cache_inode = I2CI(dentry->d_inode);
408 smfs_prepare_cachefile(dentry->d_inode, filp, cache_inode,
409 &open_file, &open_dentry);
411 if (cache_inode->i_fop->readdir)
412 rc = cache_inode->i_fop->readdir(&open_file, dirent, filldir);
414 smfs_update_file(filp, &open_file);
418 struct file_operations smfs_dir_fops = {
420 readdir: smfs_readdir, /* BKL held */
421 ioctl: smfs_ioctl, /* BKL held */
422 fsync: smfs_fsync, /* BKL held */