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 #define NAME_ALLOC_LEN(len) ((len+16) & ~15)
17 void smfs_clear_dentry(struct dentry *dentry)
19 struct qstr *name = NULL;
22 if (!atomic_dec_and_lock(&dentry->d_count, &dcache_lock))
24 list_del(&dentry->d_hash);
25 INIT_LIST_HEAD(&dentry->d_hash);
26 list_del(&dentry->d_child);
27 if (dentry->d_inode) {
28 dentry->d_inode = NULL;
29 list_del_init(&dentry->d_alias);
32 name = &(dentry->d_name);
33 if (name->len > DNAME_INLINE_LEN-1) {
34 SM_FREE((char *)name->name, NAME_ALLOC_LEN(name->len));
39 int smfs_prepare_dentry(struct dentry *dentry,
40 struct dentry *parent,
45 if (name->len > DNAME_INLINE_LEN-1) {
46 SM_ALLOC(str, NAME_ALLOC_LEN(name->len));
50 str = dentry->d_iname;
52 memcpy(str, name->name, name->len);
55 atomic_set(&dentry->d_count, 1);
56 dentry->d_vfs_flags = 0;
58 dentry->d_inode = NULL;
59 dentry->d_parent = NULL;
61 dentry->d_name.name = str;
62 dentry->d_name.len = name->len;
63 dentry->d_name.hash = name->hash;
65 dentry->d_fsdata = NULL;
66 dentry->d_mounted = 0;
67 INIT_LIST_HEAD(&dentry->d_hash);
68 INIT_LIST_HEAD(&dentry->d_lru);
69 INIT_LIST_HEAD(&dentry->d_subdirs);
70 INIT_LIST_HEAD(&dentry->d_alias);
73 dentry->d_parent = dget(parent);
74 dentry->d_sb = parent->d_sb;
75 list_add(&dentry->d_child, &parent->d_subdirs);
77 INIT_LIST_HEAD(&dentry->d_child);
81 static void prepare_parent_dentry(struct dentry *dentry, struct inode *inode)
83 atomic_set(&dentry->d_count, 1);
84 dentry->d_vfs_flags = 0;
86 dentry->d_inode = inode;
88 dentry->d_fsdata = NULL;
89 dentry->d_mounted = 0;
90 INIT_LIST_HEAD(&dentry->d_hash);
91 INIT_LIST_HEAD(&dentry->d_lru);
92 INIT_LIST_HEAD(&dentry->d_subdirs);
93 INIT_LIST_HEAD(&dentry->d_alias);
96 static int smfs_create(struct inode *dir,
97 struct dentry *dentry,
100 struct inode *cache_dir;
101 struct inode *cache_inode = NULL, *inode;
102 struct dentry parent;
103 struct dentry cache_dentry;
108 cache_dir = I2CI(dir);
112 prepare_parent_dentry(&parent, cache_dir);
113 smfs_prepare_dentry(&cache_dentry, &parent, &dentry->d_name);
115 if (cache_dir && cache_dir->i_op->create)
116 rc = cache_dir->i_op->create(cache_dir, &cache_dentry, mode);
120 cache_inode = cache_dentry.d_inode;
122 inode = iget(dir->i_sb, cache_inode->i_ino);
125 GOTO(exit, rc = -ENOMEM);
127 d_instantiate(dentry, inode);
129 sm_set_inode_ops(cache_inode, inode);
131 smfs_clear_dentry(&cache_dentry);
135 static struct dentry *smfs_lookup(struct inode *dir,
136 struct dentry *dentry)
138 struct inode *cache_dir;
139 struct inode *cache_inode = NULL, *inode;
141 struct dentry cache_dentry;
142 struct dentry *rc = NULL;
146 cache_dir = I2CI(dir);
148 RETURN(ERR_PTR(-ENOENT));
149 prepare_parent_dentry(&tmp, cache_dir);
150 smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
152 if(cache_dir && cache_dir->i_op->lookup)
153 rc = cache_dir->i_op->lookup(cache_dir, &cache_dentry);
155 if (rc || !cache_dentry.d_inode ||
156 is_bad_inode(cache_dentry.d_inode) ||
157 IS_ERR(cache_dentry.d_inode)) {
161 cache_inode = cache_dentry.d_inode;
163 inode = iget(dir->i_sb, cache_inode->i_ino);
165 d_add(dentry, inode);
167 smfs_clear_dentry(&cache_dentry);
171 static int smfs_lookup_raw(struct inode *dir, const char *name,
172 int len, ino_t *data)
174 struct inode *cache_dir;
177 cache_dir = I2CI(dir);
182 if (cache_dir->i_op->lookup_raw)
183 rc = cache_dir->i_op->lookup_raw(cache_dir, name, len, data);
188 static int smfs_link(struct dentry * old_dentry,
189 struct inode * dir, struct dentry *dentry)
191 struct inode *cache_old_inode = NULL;
192 struct inode *cache_dir = I2CI(dir);
193 struct inode *inode = NULL;
194 struct dentry cache_dentry;
195 struct dentry cache_old_dentry;
197 struct dentry tmp_old;
200 inode = old_dentry->d_inode;
202 cache_old_inode = I2CI(inode);
204 if (!cache_old_inode || !cache_dir)
207 prepare_parent_dentry(&tmp, cache_dir);
208 smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
210 prepare_parent_dentry(&tmp_old, cache_dir);
211 smfs_prepare_dentry(&cache_old_dentry, &tmp_old, &dentry->d_name);
212 d_add(&cache_old_dentry, cache_old_inode);
214 if (cache_dir->i_op->link)
215 rc = cache_dir->i_op->link(&cache_old_dentry, cache_dir, &cache_dentry);
218 d_instantiate(dentry, inode);
221 smfs_clear_dentry(&cache_dentry);
222 smfs_clear_dentry(&cache_old_dentry);
226 static int smfs_unlink(struct inode * dir,
227 struct dentry *dentry)
229 struct inode *cache_dir = I2CI(dir);
230 struct inode *cache_inode = I2CI(dentry->d_inode);
231 struct dentry cache_dentry;
235 if (!cache_dir || !cache_inode)
238 prepare_parent_dentry(&tmp, cache_dir);
239 smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
240 d_add(&cache_dentry, cache_inode);
242 if (cache_dir->i_op->unlink)
243 rc = cache_dir->i_op->unlink(cache_dir, &cache_dentry);
245 duplicate_inode(cache_dentry.d_inode, dentry->d_inode);
246 duplicate_inode(cache_dir, dir);
248 smfs_clear_dentry(&cache_dentry);
252 static int smfs_symlink (struct inode * dir,
253 struct dentry *dentry,
254 const char * symname)
256 struct inode *cache_dir = I2CI(dir);
257 struct inode *cache_inode = NULL;
258 struct inode *inode = NULL;
259 struct dentry cache_dentry;
266 prepare_parent_dentry(&tmp, cache_dir);
267 smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
269 if (cache_dir->i_op->symlink)
270 rc = cache_dir->i_op->symlink(cache_dir, &cache_dentry, symname);
272 cache_inode = cache_dentry.d_inode;
274 inode = iget(dir->i_sb, cache_inode->i_ino);
277 d_instantiate(dentry, inode);
281 smfs_clear_dentry(&cache_dentry);
285 static int smfs_mkdir(struct inode * dir,
286 struct dentry * dentry,
289 struct inode *cache_dir = I2CI(dir);
290 struct inode *cache_inode = NULL;
291 struct inode *inode = NULL;
292 struct dentry cache_dentry;
299 prepare_parent_dentry(&tmp, cache_dir);
300 smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
302 if (cache_dir->i_op->mkdir)
303 rc = cache_dir->i_op->mkdir(cache_dir, &cache_dentry, mode);
305 cache_inode = cache_dentry.d_inode;
307 inode = iget(dir->i_sb, cache_inode->i_ino);
310 GOTO(exit, rc = -ENOENT);
312 d_instantiate(dentry, inode);
313 duplicate_inode(cache_dir, dir);
315 smfs_clear_dentry(&cache_dentry);
319 static int smfs_rmdir(struct inode * dir,
320 struct dentry *dentry)
322 struct inode *cache_dir = I2CI(dir);
323 struct inode *cache_inode = I2CI(dentry->d_inode);
324 struct dentry cache_dentry;
331 prepare_parent_dentry(&tmp, cache_dir);
332 smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
333 d_add(&cache_dentry, cache_inode);
335 if (cache_dir->i_op->rmdir)
336 rc = cache_dir->i_op->rmdir(cache_dir, &cache_dentry);
338 duplicate_inode(cache_dir, dir);
339 duplicate_inode(cache_dentry.d_inode, dentry->d_inode);
341 smfs_clear_dentry(&cache_dentry);
345 static int smfs_mknod(struct inode * dir, struct dentry *dentry,
348 struct inode *cache_dir = I2CI(dir);
349 struct inode *inode = NULL;
350 struct inode *cache_inode = NULL;
351 struct dentry cache_dentry;
358 prepare_parent_dentry(&tmp, cache_dir);
359 smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
361 if (cache_dir->i_op->mknod)
362 rc = cache_dir->i_op->mknod(cache_dir, &cache_dentry, mode, rdev);
365 cache_inode = cache_dentry.d_inode;
366 inode = iget(dir->i_sb, cache_inode->i_ino);
367 d_instantiate(dentry, inode);
368 duplicate_inode(cache_dir, dir);
369 duplicate_inode(cache_dentry.d_inode, dentry->d_inode);
371 smfs_clear_dentry(&cache_dentry);
374 static int smfs_rename(struct inode * old_dir, struct dentry *old_dentry,
375 struct inode * new_dir,struct dentry *new_dentry)
377 struct inode *cache_old_dir = I2CI(old_dir);
378 struct inode *cache_new_dir = I2CI(new_dir);
379 struct inode *cache_old_inode = I2CI(old_dentry->d_inode);
380 struct inode *cache_new_inode = NULL;
381 struct inode *new_inode = NULL;
382 struct dentry cache_old_dentry;
383 struct dentry cache_new_dentry;
384 struct dentry tmp_new;
385 struct dentry tmp_old;
388 if (!cache_old_dir || !cache_new_dir || !cache_old_inode)
391 prepare_parent_dentry(&tmp_old, cache_old_dir);
392 smfs_prepare_dentry(&cache_old_dentry, &tmp_old, &old_dentry->d_name);
393 d_add(&cache_old_dentry, cache_old_inode);
395 prepare_parent_dentry(&tmp_new, cache_new_dir);
396 smfs_prepare_dentry(&cache_new_dentry, &tmp_new, &new_dentry->d_name);
398 if (cache_old_dir->i_op->rename)
399 rc = cache_old_dir->i_op->rename(cache_old_dir, &cache_old_dentry,
400 cache_new_dir, &cache_new_dentry);
402 duplicate_inode(cache_old_dir, old_dir);
403 duplicate_inode(cache_new_dir, new_dir);
404 smfs_clear_dentry(&cache_old_dentry);
405 smfs_clear_dentry(&cache_new_dentry);
410 struct inode_operations smfs_dir_iops = {
413 lookup_raw: smfs_lookup_raw, /* BKL held */
414 link: smfs_link, /* BKL held */
415 unlink: smfs_unlink, /* BKL held */
416 symlink: smfs_symlink, /* BKL held */
417 mkdir: smfs_mkdir, /* BKL held */
418 rmdir: smfs_rmdir, /* BKL held */
419 mknod: smfs_mknod, /* BKL held */
420 rename: smfs_rename, /* BKL held */
421 setxattr: smfs_setxattr, /* BKL held */
422 getxattr: smfs_getxattr, /* BKL held */
423 listxattr: smfs_listxattr, /* BKL held */
424 removexattr: smfs_removexattr, /* BKL held */
427 static ssize_t smfs_read_dir(struct file *filp, char *buf,
428 size_t size, loff_t *ppos)
430 struct dentry *dentry = filp->f_dentry;
431 struct inode *cache_inode = NULL;
432 struct file open_file;
433 struct dentry open_dentry;
436 cache_inode = I2CI(dentry->d_inode);
441 smfs_prepare_cachefile(dentry->d_inode, filp, cache_inode,
442 &open_file, &open_dentry);
444 if (cache_inode->i_fop->read)
445 rc = cache_inode->i_fop->read(&open_file, buf, size, ppos);
447 smfs_update_file(filp, &open_file);
451 static int smfs_readdir(struct file * filp,
455 struct dentry *dentry = filp->f_dentry;
456 struct inode *cache_inode = NULL;
457 struct file open_file;
458 struct dentry open_dentry;
461 cache_inode = I2CI(dentry->d_inode);
466 smfs_prepare_cachefile(dentry->d_inode, filp, cache_inode,
467 &open_file, &open_dentry);
469 if (cache_inode->i_fop->readdir)
470 rc = cache_inode->i_fop->readdir(&open_file, dirent, filldir);
472 smfs_update_file(filp, &open_file);
476 struct file_operations smfs_dir_fops = {
478 readdir: smfs_readdir, /* BKL held */
479 ioctl: smfs_ioctl, /* BKL held */
480 fsync: smfs_fsync, /* BKL held */