Whamcloud - gitweb
- better to make vfs_create() to set correct uid and gid for new inode, as dirtying...
[fs/lustre-release.git] / lustre / smfs / dir.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (C) 2004 Cluster File Systems, Inc.
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
8  *   Lustre is free software; you can redistribute it and/or
9  *   modify it under the terms of version 2 of the GNU General Public
10  *   License as published by the Free Software Foundation.
11  *
12  *   Lustre is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with Lustre; if not, write to the Free Software
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  */
22
23 #define DEBUG_SUBSYSTEM S_SM
24
25 #include <linux/module.h>
26 #include <linux/kernel.h>
27 #include <linux/string.h>
28 #include <linux/slab.h>
29 #include <linux/stat.h>
30 #include <linux/unistd.h>
31 #include <linux/smp_lock.h>
32 #include <linux/obd_class.h>
33 #include <linux/obd_support.h>
34 #include <linux/lustre_lib.h>
35 #include <linux/lustre_idl.h>
36 #include <linux/lustre_fsfilt.h>
37 #include <linux/lustre_smfs.h>
38 #include <linux/lustre_snap.h>
39 #include <linux/security.h>
40 #include "smfs_internal.h"
41
42 //#define NAME_ALLOC_LEN(len)     ((len+16) & ~15)
43
44 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
45 static int smfs_create(struct inode *dir, struct dentry *dentry,
46                        int mode)
47 #else
48 static int smfs_create(struct inode *dir, struct dentry *dentry,
49                        int mode, struct nameidata *nd)
50 #endif
51 {
52         struct inode *inode = NULL;
53         struct inode *parent = I2CI(dentry->d_parent->d_inode);
54         struct inode *cache_dir = I2CI(dir);
55         struct dentry *cache_dentry = NULL;
56         struct dentry *cache_parent = NULL;
57         void *handle = NULL;
58         struct hook_msg msg = {
59                 .dentry = dentry,
60         };
61         int rc = 0;
62         
63         ENTRY;
64
65         LASSERT(cache_dir);
66         LASSERT(cache_dir->i_op->create);
67         
68         cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
69         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
70         if (!cache_dentry || !cache_parent) {
71                 rc = -ENOMEM;
72                 goto exit;
73         }
74        
75         handle = smfs_trans_start(dir, FSFILT_OP_CREATE, NULL);
76         if (IS_ERR(handle)) {
77                 rc = -ENOSPC;
78                 goto exit;
79         }
80         
81         SMFS_PRE_HOOK(dir, HOOK_CREATE, &msg);
82
83         pre_smfs_inode(dir, cache_dir);
84
85 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
86         rc = cache_dir->i_op->create(cache_dir, cache_dentry, mode);
87 #else
88         rc = cache_dir->i_op->create(cache_dir, cache_dentry, mode, nd);
89 #endif
90         if (!rc) {
91                 inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode,
92                                        I2SMI(dir), 0);
93                 if (inode) {
94                         d_instantiate(dentry, inode);
95                 }
96                 else
97                         rc = -ENOENT;
98         }
99         
100         SMFS_POST_HOOK(dir, HOOK_CREATE, &msg, rc); 
101
102         post_smfs_inode(dir, cache_dir);
103         smfs_trans_commit(dir, handle, 0);
104         
105 exit:
106         post_smfs_dentry(cache_dentry);
107         post_smfs_dentry(cache_parent);
108         RETURN(rc);
109 }
110
111 static struct dentry * iopen_connect_dentry(struct dentry * dentry,
112                                      struct inode *inode, int rehash)
113 {
114         struct dentry *tmp, *goal = NULL;
115         struct list_head *lp;
116
117         /* verify this dentry is really new */
118         LASSERT(dentry->d_inode == NULL);
119         LASSERT(list_empty(&dentry->d_alias));          /* d_instantiate */
120         if (rehash)
121                 LASSERT(d_unhashed(dentry));    /* d_rehash */
122         LASSERT(list_empty(&dentry->d_subdirs));
123
124         spin_lock(&dcache_lock);
125         if (!inode)
126                 goto do_rehash;
127
128         /* preferrably return a connected dentry */
129         list_for_each(lp, &inode->i_dentry) {
130                 tmp = list_entry(lp, struct dentry, d_alias);
131                 if (tmp->d_flags & DCACHE_DISCONNECTED) {
132                         LASSERT(tmp->d_alias.next == &inode->i_dentry);
133                         LASSERT(tmp->d_alias.prev == &inode->i_dentry);
134                         goal = tmp;
135                         dget_locked(goal);
136                         break;
137                 }
138         }
139
140         if (!goal)
141                 goto do_instantiate;
142
143         /* Move the goal to the de hash queue */
144         goal->d_flags &= ~ DCACHE_DISCONNECTED;
145         security_d_instantiate(goal, inode);
146         __d_rehash(dentry);
147         __d_move(goal, dentry);
148         spin_unlock(&dcache_lock);
149         iput(inode);
150
151         RETURN(goal);
152
153         /* d_add(), but don't drop dcache_lock before adding dentry to inode */
154 do_instantiate:
155         list_add(&dentry->d_alias, &inode->i_dentry);   /* d_instantiate */
156         dentry->d_inode = inode;
157 do_rehash:
158         if (rehash)
159                 __d_rehash(dentry);
160         spin_unlock(&dcache_lock);
161
162         RETURN(NULL);
163
164 }
165
166 static int smfs_do_lookup (struct inode * dir, 
167                            struct dentry * dentry,
168                            struct nameidata *nd,
169                            struct inode **inode)
170 {
171         struct inode *cache_dir = I2CI(dir);
172         struct inode *parent = I2CI(dentry->d_parent->d_inode);
173         struct dentry *cache_dentry = NULL;
174         struct dentry *cache_parent = NULL;
175         struct dentry *rdentry = NULL, *tmp = NULL;
176         int rc = 0;
177         struct hook_msg msg = {
178                 .dentry = dentry,
179         };
180
181         ENTRY;
182         
183         if (!cache_dir)
184                 RETURN(-ENOENT);
185
186         LASSERT(cache_dir->i_op->lookup);
187
188         /* preparing artificial backing fs dentries. */
189         cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
190         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
191         if (!cache_dentry || !cache_parent) {
192                 rc = -ENOMEM;
193                 goto exit;
194         }
195         
196         SMFS_PRE_HOOK(dir, HOOK_LOOKUP, &msg);
197         
198         /* perform lookup in backing fs. */
199         rdentry = cache_dir->i_op->lookup(cache_dir, cache_dentry, nd);
200         if (rdentry) {
201                 if (IS_ERR(rdentry)) {
202                         rc = PTR_ERR(rdentry);
203                         rdentry = NULL;
204                 } else {
205                         tmp = rdentry;
206                 }
207         } else {
208                 tmp = cache_dentry;
209         }
210
211         SMFS_POST_HOOK(dir, HOOK_LOOKUP, &msg, rc);
212      
213         if (tmp) {
214                 //copy fields if DCACHE_CROSS_REF
215                 smfs_update_dentry(dentry, tmp);         
216                 
217                 if (tmp->d_inode) {
218                         *inode = smfs_get_inode(dir->i_sb, tmp->d_inode, 
219                                                 I2SMI(dir), 0); 
220                         if (!(*inode))
221                                 rc = -ENOENT;
222                         else {
223                                 if (!tmp->d_inode->i_nlink) {
224                                         struct inode * ind = tmp->d_inode;
225                                 
226                                         CWARN("inode #%lu (%s) nlink is %i/%i\n",
227                                               ind->i_ino, tmp->d_name.name, ind->i_nlink, (*inode)->i_nlink);
228                                         CWARN("parent #%lu (%s) nlink is %i\n",
229                                               dir->i_ino, tmp->d_parent->d_name.name, cache_dir->i_nlink);
230                                 }
231                         }
232                 }
233         }
234         
235         if (rdentry) {
236                 dput(rdentry);
237         }
238         
239 exit:
240         post_smfs_dentry(cache_dentry);
241         post_smfs_dentry(cache_parent);
242         
243         RETURN(rc);
244 }
245
246 static struct dentry * smfs_iopen_lookup(struct inode * dir, 
247                                          struct dentry *dentry,
248                                          struct nameidata *nd)
249 {
250         struct dentry * alternate = NULL;
251         struct inode *inode = NULL;
252         int rc = 0;
253         ENTRY;
254         
255         rc = smfs_do_lookup(dir, dentry, nd, &inode);
256         if (rc)
257                 RETURN(ERR_PTR(rc));
258         
259         LASSERT(inode);
260         /* preferrably return a connected dentry */
261         spin_lock(&dcache_lock);
262         list_for_each_entry(alternate, &inode->i_dentry, d_alias) {
263                 LASSERT(!(alternate->d_flags & DCACHE_DISCONNECTED));
264         }
265
266         list_for_each_entry(alternate, &inode->i_dentry, d_alias) {
267                 dget_locked(alternate);
268                 spin_lock(&alternate->d_lock);
269                 alternate->d_flags |= DCACHE_REFERENCED;
270                 spin_unlock(&alternate->d_lock);
271                 iput(inode);
272                 spin_unlock(&dcache_lock);
273                 RETURN(alternate);
274         }
275         
276         dentry->d_flags |= DCACHE_DISCONNECTED;
277
278         /* d_add(), but don't drop dcache_lock before adding dentry to inode */
279         list_add(&dentry->d_alias, &inode->i_dentry);   /* d_instantiate */
280         dentry->d_inode = inode;
281
282         __d_rehash(dentry);                             /* d_rehash */
283         spin_unlock(&dcache_lock);
284
285         return NULL;
286 }
287
288 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
289 static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry)
290 #else
291 static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry,
292                                   struct nameidata *nd)
293 #endif
294 {
295         struct dentry * rdentry = NULL;
296         struct inode * inode = NULL;
297         int rc;
298
299         ENTRY;
300         
301         rc = smfs_do_lookup(dir, dentry, nd, &inode);
302         if (rc)
303                 RETURN(ERR_PTR(rc));
304         
305         //lmv stuff. Special dentry that has no inode.
306         if (dentry->d_flags & DCACHE_CROSS_REF) {
307                 d_add(dentry, NULL);
308                 RETURN(NULL);
309         }
310         //TODO: should flags be checked and copied before?        
311         rdentry = iopen_connect_dentry(dentry, inode, 1);
312         
313         RETURN(rdentry);
314 }
315
316 #if HAVE_LOOKUP_RAW
317 static int smfs_lookup_raw(struct inode *dir, const char *name,
318                            int len, ino_t *data)
319 {
320         struct inode *cache_dir = I2CI(dir);
321         int rc = 0;
322
323         if (!cache_dir)
324                 RETURN(-ENOENT);
325         
326         if (cache_dir->i_op->lookup_raw) {
327                 rc = cache_dir->i_op->lookup_raw(cache_dir, name, len, data);
328         } else {
329                 CWARN("do not have raw lookup ops in bottom fs\n");
330         }
331
332         RETURN(rc);
333 }
334 #endif
335
336 static int smfs_link(struct dentry *old_dentry,
337                      struct inode *dir, struct dentry *dentry)
338 {
339         struct inode *parent = I2CI(dentry->d_parent->d_inode);
340         struct inode *cache_dir = I2CI(dir);
341         struct inode *old_inode = old_dentry->d_inode;
342         struct inode *cache_old_inode = I2CI(old_inode);
343         struct dentry *cache_old_dentry = NULL;
344         struct dentry *cache_dentry = NULL;
345         struct dentry *cache_parent = NULL;
346         void *handle = NULL;
347         int rc = 0;
348         struct hook_link_msg msg = {
349                 .dentry = old_dentry,
350                 .new_dentry = dentry
351         };
352
353         ENTRY;
354
355         if (!cache_dir)
356                 RETURN(-ENOENT);
357         
358         if (!cache_old_inode)
359                 RETURN(-ENOENT);
360         
361         cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
362         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
363         cache_old_dentry = pre_smfs_dentry(NULL, cache_old_inode, old_dentry);
364         if (!cache_old_dentry || !cache_dentry || !cache_parent) {
365                 rc = -ENOMEM;
366                 goto exit;
367         }        
368         
369         handle = smfs_trans_start(dir, FSFILT_OP_LINK, NULL);
370         if (IS_ERR(handle)) {
371                  rc = -ENOSPC;
372                  goto exit;
373         }
374
375         pre_smfs_inode(dir, cache_dir);
376         pre_smfs_inode(old_inode, cache_old_inode);
377
378         //lock_kernel();
379         SMFS_PRE_HOOK(dir, HOOK_LINK, &msg); 
380
381         rc = cache_dir->i_op->link(cache_old_dentry, cache_dir, cache_dentry);
382         if (!rc) {
383                 atomic_inc(&old_inode->i_count);
384                 old_inode->i_nlink++;
385                 dput(iopen_connect_dentry(dentry, old_inode, 0));
386         }
387
388         SMFS_POST_HOOK(dir, HOOK_LINK, &msg, rc); 
389         
390         post_smfs_inode(old_inode, cache_old_inode);
391         post_smfs_inode(dir, cache_dir);
392
393         smfs_trans_commit(dir, handle, 0);
394         
395 exit:
396         //unlock_kernel();
397         post_smfs_dentry(cache_dentry);
398         post_smfs_dentry(cache_parent);
399         post_smfs_dentry(cache_old_dentry);
400         
401         RETURN(rc);
402 }
403
404 static int smfs_unlink(struct inode * dir, struct dentry *dentry)
405 {
406         struct inode *cache_dir = I2CI(dir);
407         struct inode *cache_inode = I2CI(dentry->d_inode);
408         struct inode *parent = I2CI(dentry->d_parent->d_inode);
409         struct dentry *cache_dentry = NULL;
410         struct dentry *cache_parent = NULL;
411         void   *handle = NULL;
412         int    rc = 0;
413         //int    mode = 0;
414         struct hook_unlink_msg msg = {
415                 .dentry = dentry,
416                 .mode = dentry->d_inode->i_mode
417         };
418
419         ENTRY;
420         
421         LASSERT(cache_dir);
422         LASSERT(cache_inode);
423         LASSERT(cache_dir->i_op->unlink);
424         LASSERT(parent);
425         
426         cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
427         cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
428         if (!cache_dentry || !cache_parent) {
429                 rc = -ENOMEM;
430                 goto exit;
431         }
432                 
433         handle = smfs_trans_start(dir, FSFILT_OP_UNLINK, NULL);
434         if (IS_ERR(handle)) {
435                 rc = -ENOSPC;
436                 goto exit;
437         }
438         
439         pre_smfs_inode(dir, cache_dir);
440         pre_smfs_inode(dentry->d_inode, cache_inode);
441
442         SMFS_PRE_HOOK(dir, HOOK_UNLINK, &msg); 
443         
444         rc = cache_dir->i_op->unlink(cache_dir, cache_dentry);
445                 
446         SMFS_POST_HOOK(dir, HOOK_UNLINK, &msg, rc); 
447         if (!rc) {
448                 post_smfs_inode(dentry->d_inode, cache_inode);
449                 dentry->d_inode->i_nlink--;
450                 post_smfs_inode(dir, cache_dir);
451         }
452         
453         smfs_trans_commit(dir, handle, 0);
454 exit:
455         post_smfs_dentry(cache_dentry);
456         post_smfs_dentry(cache_parent);
457         RETURN(rc);
458 }
459
460 static int smfs_symlink(struct inode *dir, struct dentry *dentry,
461                         const char *symname)
462 {
463         struct inode *cache_dir = I2CI(dir);
464         struct inode *inode = NULL;
465         struct inode *parent = I2CI(dentry->d_parent->d_inode);
466         struct dentry *cache_dentry = NULL;
467         struct dentry *cache_parent = NULL;
468         void   *handle = NULL;
469         int    rc = 0;
470         struct hook_symlink_msg msg = {
471                 .dentry = dentry,
472                 .tgt_len = strlen(symname) + 1,
473                 .symname = (char*)symname
474         };
475
476         ENTRY;
477         
478         LASSERT(cache_dir);
479         LASSERT(cache_dir->i_op->symlink);
480         LASSERT(parent);
481
482         cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
483         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
484         if (!cache_parent || !cache_dentry) {
485                 rc = -ENOMEM;
486                 goto exit;
487         }
488        
489         handle = smfs_trans_start(dir, FSFILT_OP_SYMLINK, NULL);
490         if (IS_ERR(handle)) {
491                 rc = -ENOSPC;
492                 goto exit;
493         }
494         
495         pre_smfs_inode(dir, cache_dir);
496
497         SMFS_PRE_HOOK(dir, HOOK_SYMLINK, &msg); 
498         
499         rc = cache_dir->i_op->symlink(cache_dir, cache_dentry, symname);
500         if (!rc) {        
501                 inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode,
502                                        I2SMI(dir), 0);
503                 if (inode) {
504                         d_instantiate(dentry, inode);
505                 }
506                 else
507                         rc = -ENOENT;
508         }
509         
510         SMFS_POST_HOOK(dir, HOOK_SYMLINK, &msg, rc);
511         
512         post_smfs_inode(dir, cache_dir);
513         smfs_trans_commit(dir, handle, 0);
514
515 exit:
516         post_smfs_dentry(cache_dentry);
517         post_smfs_dentry(cache_parent);
518         RETURN(rc);
519 }
520
521 static int smfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
522 {
523         struct inode *cache_dir = I2CI(dir);
524         struct inode *parent = I2CI(dentry->d_parent->d_inode);
525         struct inode *inode = NULL;
526         struct dentry *cache_dentry = NULL;
527         struct dentry *cache_parent = NULL;
528         void   *handle = NULL;
529         int    rc = 0;
530         struct hook_msg msg = {
531                 .dentry = dentry,
532         };
533
534         ENTRY;
535         
536         LASSERT(cache_dir);
537         LASSERT(parent);
538         
539         cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
540         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
541         if (!cache_parent || !cache_dentry) {
542                 rc = -ENOMEM;
543                 goto exit;
544         }
545
546         handle = smfs_trans_start(dir, FSFILT_OP_MKDIR, NULL);
547         if (IS_ERR(handle)) {
548                 rc = -ENOSPC;
549                 goto exit;
550         }
551         
552         pre_smfs_inode(dir, cache_dir);
553         SMFS_PRE_HOOK(dir, HOOK_MKDIR, &msg); 
554         
555         rc = cache_dir->i_op->mkdir(cache_dir, cache_dentry, mode);
556         if (!rc) {
557                 inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode,
558                                        I2SMI(dir), 0);
559                 if (inode) {
560                         dir->i_nlink++;
561                         d_instantiate(dentry, inode);
562                 }
563                 else
564                         rc = -ENOENT;
565         }
566
567         SMFS_POST_HOOK(dir, HOOK_MKDIR, &msg, rc); 
568         post_smfs_inode(dir, cache_dir);
569         smfs_trans_commit(dir, handle, 0);
570
571 exit:
572         post_smfs_dentry(cache_dentry);
573         post_smfs_dentry(cache_parent);
574         RETURN(rc);
575 }
576
577 static int smfs_rmdir(struct inode *dir, struct dentry *dentry)
578 {
579         struct inode *cache_dir = I2CI(dir);
580         struct inode *cache_inode = I2CI(dentry->d_inode);
581         struct inode *parent = I2CI(dentry->d_parent->d_inode);
582         struct dentry *cache_dentry = NULL;
583         struct dentry *cache_parent = NULL;
584         struct inode * inode = dentry->d_inode;
585         void *handle = NULL;
586         int    rc = 0;
587         struct hook_unlink_msg msg = {
588                 .dentry = dentry,
589                 .mode = S_IFDIR
590         };
591
592         ENTRY;
593         
594         LASSERT(cache_dir);
595         LASSERT(cache_dir->i_op->rmdir);
596         LASSERT(parent);
597
598         cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
599         cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
600         if (!cache_parent || !cache_dentry) {
601                 rc = -ENOMEM;
602                 goto exit;
603         }
604         
605         handle = smfs_trans_start(dir, FSFILT_OP_RMDIR, NULL);
606         if (IS_ERR(handle) ) {
607                 rc = -ENOSPC;
608                 goto exit;
609         }
610
611         dentry_unhash(cache_dentry);
612
613         pre_smfs_inode(dir, cache_dir);
614         pre_smfs_inode(inode, cache_inode);
615         
616         SMFS_PRE_HOOK(dir, HOOK_RMDIR, &msg); 
617         
618         rc = cache_dir->i_op->rmdir(cache_dir, cache_dentry);
619               
620         SMFS_POST_HOOK(dir, HOOK_RMDIR, &msg, rc); 
621         if (!rc) {
622                 if (inode->i_nlink != 2)
623                         CWARN("Directory #%lu under rmdir has %i nlinks\n",
624                                 inode->i_ino, inode->i_nlink);
625                 inode->i_nlink = 0;
626                 dir->i_nlink--;
627                 post_smfs_inode(dir, cache_dir);
628                 post_smfs_inode(inode, cache_inode);
629                 //like vfs_rmdir is doing with inode
630                 cache_inode->i_flags |= S_DEAD;
631         }
632         smfs_trans_commit(dir, handle, 0);
633         dput(cache_dentry);
634 exit:
635         post_smfs_dentry(cache_dentry);
636         post_smfs_dentry(cache_parent);
637         RETURN(rc);
638 }
639
640 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
641 static int smfs_mknod(struct inode *dir, struct dentry *dentry,
642                       int mode, int rdev)
643 #else
644 static int smfs_mknod(struct inode *dir, struct dentry *dentry,
645                       int mode, dev_t rdev)
646 #endif
647 {
648         struct inode *cache_dir = I2CI(dir);
649         struct inode *inode = NULL;
650         struct inode *parent = I2CI(dentry->d_parent->d_inode);
651         struct dentry *cache_dentry = NULL;
652         struct dentry *cache_parent = NULL;
653         void *handle = NULL;
654         int rc = 0;
655         struct hook_msg msg = {
656                 .dentry = dentry,
657         };
658  
659         ENTRY;
660         
661         LASSERT(parent);
662         LASSERT(cache_dir);
663         LASSERT(cache_dir->i_op->mknod);
664
665         cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
666         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
667         if (!cache_parent || !cache_dentry) {
668                 rc = -ENOMEM;
669                 goto exit;
670         }
671
672         handle = smfs_trans_start(dir, FSFILT_OP_MKNOD, NULL);
673         if (IS_ERR(handle)) {
674                 rc = -ENOSPC;
675                 goto exit;
676         }
677         
678         pre_smfs_inode(dir, cache_dir);
679         
680         SMFS_PRE_HOOK(dir, HOOK_MKNOD, &msg); 
681         
682         rc = cache_dir->i_op->mknod(cache_dir, cache_dentry, mode, rdev);
683         if (!rc) {
684                 inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode,
685                                        I2SMI(dir), 0);
686                 if (inode) {
687                         //smsf_update_dentry(dentry, cache_dentry);
688                         d_instantiate(dentry, inode);
689                 }
690                 else
691                         rc = -ENOENT;
692         }
693
694         SMFS_POST_HOOK(dir, HOOK_MKNOD, &msg, rc); 
695         
696         post_smfs_inode(dir, cache_dir);
697         
698         smfs_trans_commit(dir, handle, 0);
699
700 exit:
701         post_smfs_dentry(cache_dentry);
702         post_smfs_dentry(cache_parent);
703         RETURN(rc);
704 }
705
706 static int smfs_rename(struct inode *old_dir, struct dentry *old_dentry,
707                        struct inode *new_dir,struct dentry *new_dentry)
708 {
709         struct inode *cache_old_dir = I2CI(old_dir);
710         struct inode *cache_new_dir = I2CI(new_dir);
711         struct inode *new_inode = new_dentry->d_inode;
712         struct inode *cache_old_inode = I2CI(old_dentry->d_inode);
713         struct inode *old_parent = I2CI(old_dentry->d_parent->d_inode);
714         struct inode *new_parent = I2CI(new_dentry->d_parent->d_inode);
715         struct inode *cache_new_inode = NULL;
716         struct dentry *cache_old_dentry = NULL;
717         struct dentry *cache_new_dentry = NULL;
718         struct dentry *cache_new_parent = NULL;
719         struct dentry *cache_old_parent = NULL;
720         void *handle = NULL;
721         int    rc = 0;
722         struct hook_rename_msg msg = {
723                 .dentry = old_dentry,
724                 .new_dir = new_dir,
725                 .new_dentry = new_dentry
726         };
727
728         ENTRY;
729                 
730         if (!cache_old_dir || !cache_new_dir || !cache_old_inode)
731                 RETURN(-ENOENT);
732
733         if (new_inode) {
734                 cache_new_inode = I2CI(new_inode);
735                 if (!cache_new_inode)
736                         RETURN(-ENOENT);
737         }
738         
739         cache_old_parent = pre_smfs_dentry(NULL, old_parent, old_dentry->d_parent);
740         cache_old_dentry = pre_smfs_dentry(cache_old_parent, cache_old_inode,
741                                            old_dentry);
742         if (!cache_old_parent || !cache_old_dentry) {
743                 rc = -ENOMEM;
744                 goto exit;
745         }
746         
747         cache_new_parent = pre_smfs_dentry(NULL, new_parent, new_dentry->d_parent);
748         cache_new_dentry = pre_smfs_dentry(cache_new_parent, cache_new_inode,
749                                            new_dentry);
750         if (!cache_new_parent || !cache_new_dentry) {
751                 rc = -ENOMEM;
752                 goto exit;
753         }
754
755         handle = smfs_trans_start(old_dir, FSFILT_OP_RENAME, NULL);
756         if (IS_ERR(handle)) {
757                 rc = -ENOSPC;
758                 goto exit;
759         }
760         
761         pre_smfs_inode(old_dir, cache_old_dir);
762         pre_smfs_inode(new_dir, cache_new_dir);
763         pre_smfs_inode(old_dentry->d_inode, cache_old_inode);
764         if (new_inode)
765                 pre_smfs_inode(new_inode, cache_new_inode);
766
767         SMFS_PRE_HOOK(old_dir, HOOK_RENAME, &msg); 
768         
769         rc = cache_old_dir->i_op->rename(cache_old_dir, cache_old_dentry,
770                                          cache_new_dir, cache_new_dentry);
771         
772         SMFS_POST_HOOK(old_dir, HOOK_RENAME, &msg, rc); 
773         if (!rc) {
774                 post_smfs_inode(old_dir, cache_old_dir);
775                 post_smfs_inode(new_dir, cache_new_dir);
776                 post_smfs_inode(old_dentry->d_inode, cache_old_inode);
777                 if (new_inode) {
778                         post_smfs_inode(new_inode, cache_new_inode);
779                         new_inode->i_nlink--;
780                 }
781                 //directory is renamed
782                 if (S_ISDIR(old_dentry->d_inode->i_mode)) {
783                         old_dir->i_nlink--;
784                         if (new_inode) {
785                                 new_inode->i_nlink--;
786                         } else {
787                                 new_dir->i_nlink++;
788                         }
789                 }
790         }
791         smfs_trans_commit(old_dir, handle, 0);
792         
793 exit:
794         post_smfs_dentry(cache_old_dentry);
795         post_smfs_dentry(cache_old_parent);
796         post_smfs_dentry(cache_new_dentry);
797         post_smfs_dentry(cache_new_parent);
798         RETURN(rc);
799 }
800
801 struct inode_operations smfs_dir_iops = {
802         .create         = smfs_create,
803         .lookup         = smfs_lookup,
804 #if HAVE_LOOKUP_RAW
805         .lookup_raw     = smfs_lookup_raw,
806 #endif
807         .link           = smfs_link,              
808         .unlink         = smfs_unlink,            
809         .symlink        = smfs_symlink,           
810         .mkdir          = smfs_mkdir,             
811         .rmdir          = smfs_rmdir,             
812         .mknod          = smfs_mknod,             
813         .rename         = smfs_rename,            
814         .setxattr       = smfs_setxattr,
815         .getxattr       = smfs_getxattr,
816         .listxattr      = smfs_listxattr,
817         .removexattr    = smfs_removexattr,
818         .permission     = smfs_permission,
819 };
820
821 struct inode_operations smfs_iopen_iops = {
822         .lookup         = smfs_iopen_lookup,
823 };
824
825 static ssize_t smfs_read_dir(struct file *filp, char *buf,
826                              size_t size, loff_t *ppos)
827 {
828         struct dentry *dentry = filp->f_dentry;
829         struct inode *cache_inode = NULL;
830         struct smfs_file_info *sfi = NULL;
831         loff_t tmp_ppos;
832         loff_t *cache_ppos = NULL;
833         int    rc = 0;
834
835         ENTRY;
836         
837         cache_inode = I2CI(dentry->d_inode);
838
839         if (!cache_inode || !cache_inode->i_fop->read)
840                 RETURN(-EINVAL);
841
842         sfi = F2SMFI(filp);
843         if (sfi->magic != SMFS_FILE_MAGIC)
844                 BUG();
845
846         if (ppos != &(filp->f_pos))
847                 cache_ppos = &tmp_ppos;
848         else
849                 cache_ppos = &sfi->c_file->f_pos;
850         
851         *cache_ppos = *ppos;
852
853         rc = cache_inode->i_fop->read(sfi->c_file, buf, size, cache_ppos);
854         if (rc)
855                 RETURN(rc);
856
857         *ppos = *cache_ppos;
858         
859         duplicate_file(filp, sfi->c_file);
860         
861         RETURN(rc);
862 }
863
864 static int smfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
865 {
866         struct dentry *dentry = filp->f_dentry;
867         struct inode *cache_inode = NULL;
868         struct smfs_file_info *sfi = NULL;
869         int    rc = 0;
870         struct hook_readdir_msg msg = {
871                 .dentry = dentry,
872                 .filp = filp,
873                 .dirent = dirent,
874                 .filldir = filldir
875         };
876
877         ENTRY;
878         
879         cache_inode = I2CI(dentry->d_inode);
880         if (!cache_inode || !cache_inode->i_fop->readdir)
881                 RETURN(-EINVAL);
882
883         sfi = F2SMFI(filp);
884         if (sfi->magic != SMFS_FILE_MAGIC) BUG();
885
886         SMFS_PRE_HOOK(dentry->d_inode, HOOK_READDIR, &msg); 
887         
888         rc = cache_inode->i_fop->readdir(sfi->c_file, dirent, filldir);
889         
890         SMFS_POST_HOOK(dentry->d_inode, HOOK_READDIR, &msg, rc);
891         duplicate_file(filp, sfi->c_file);
892
893         RETURN(rc);
894 }
895
896 struct file_operations smfs_dir_fops = {
897         .read           = smfs_read_dir,
898         .readdir        = smfs_readdir,       /* BKL held */
899         .ioctl          = smfs_ioctl,         /* BKL held */
900         .fsync          = smfs_fsync,         /* BKL held */
901         .open           = smfs_open,
902         .release        = smfs_release,
903 };
904
905 struct file_operations smfs_iopen_fops = {
906         .read           = smfs_read_dir,
907 };
908