1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2004 Cluster File Systems, Inc.
6 * This file is part of Lustre, http://www.lustre.org.
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.
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.
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.
23 #define DEBUG_SUBSYSTEM S_SM
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"
42 //#define NAME_ALLOC_LEN(len) ((len+16) & ~15)
44 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
45 static int smfs_create(struct inode *dir, struct dentry *dentry,
48 static int smfs_create(struct inode *dir, struct dentry *dentry,
49 int mode, struct nameidata *nd)
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;
58 struct hook_msg msg = {
65 CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s (%p),dir=%lu/%u\n",
66 dentry->d_name.len, dentry->d_name.name, dentry,
67 dir->i_ino, dir->i_generation);
70 LASSERT(cache_dir->i_op->create);
72 cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
73 cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
74 if (!cache_dentry || !cache_parent) {
79 handle = smfs_trans_start(dir, FSFILT_OP_CREATE, NULL);
85 SMFS_PRE_HOOK(dir, HOOK_CREATE, &msg);
87 pre_smfs_inode(dir, cache_dir);
89 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
90 rc = cache_dir->i_op->create(cache_dir, cache_dentry, mode);
92 rc = cache_dir->i_op->create(cache_dir, cache_dentry, mode, nd);
95 inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode,
98 d_instantiate(dentry, inode);
104 SMFS_POST_HOOK(dir, HOOK_CREATE, &msg, rc);
106 post_smfs_inode(dir, cache_dir);
107 smfs_trans_commit(dir, handle, 0);
110 post_smfs_dentry(cache_dentry);
111 post_smfs_dentry(cache_parent);
115 static struct dentry * iopen_connect_dentry(struct dentry * dentry,
116 struct inode *inode, int rehash)
118 struct dentry *tmp, *goal = NULL;
119 struct list_head *lp;
121 /* verify this dentry is really new */
122 LASSERT(dentry->d_inode == NULL);
123 LASSERT(list_empty(&dentry->d_alias)); /* d_instantiate */
125 LASSERT(d_unhashed(dentry)); /* d_rehash */
126 LASSERT(list_empty(&dentry->d_subdirs));
128 spin_lock(&dcache_lock);
132 /* preferrably return a connected dentry */
133 list_for_each(lp, &inode->i_dentry) {
134 tmp = list_entry(lp, struct dentry, d_alias);
135 if (tmp->d_flags & DCACHE_DISCONNECTED) {
136 LASSERT(tmp->d_alias.next == &inode->i_dentry);
137 LASSERT(tmp->d_alias.prev == &inode->i_dentry);
147 /* Move the goal to the de hash queue */
148 goal->d_flags &= ~ DCACHE_DISCONNECTED;
149 security_d_instantiate(goal, inode);
151 __d_move(goal, dentry);
152 spin_unlock(&dcache_lock);
157 /* d_add(), but don't drop dcache_lock before adding dentry to inode */
159 list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */
160 dentry->d_inode = inode;
164 spin_unlock(&dcache_lock);
170 static int smfs_do_lookup (struct inode * dir,
171 struct dentry * dentry,
172 struct nameidata *nd,
173 struct inode **inode)
175 struct inode *cache_dir = I2CI(dir);
176 struct inode *parent = I2CI(dentry->d_parent->d_inode);
177 struct dentry *cache_dentry = NULL;
178 struct dentry *cache_parent = NULL;
179 struct dentry *rdentry = NULL, *tmp = NULL;
181 struct hook_msg msg = {
187 CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s (%p),dir=%lu/%u\n",
188 dentry->d_name.len, dentry->d_name.name, dentry,
189 dir->i_ino, dir->i_generation);
194 LASSERT(cache_dir->i_op->lookup);
196 /* preparing artificial backing fs dentries. */
197 cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
198 cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
199 if (!cache_dentry || !cache_parent) {
204 SMFS_PRE_HOOK(dir, HOOK_LOOKUP, &msg);
206 /* perform lookup in backing fs. */
207 rdentry = cache_dir->i_op->lookup(cache_dir, cache_dentry, nd);
209 if (IS_ERR(rdentry)) {
210 rc = PTR_ERR(rdentry);
219 SMFS_POST_HOOK(dir, HOOK_LOOKUP, &msg, rc);
222 //copy fields if DCACHE_CROSS_REF
223 smfs_update_dentry(dentry, tmp);
226 *inode = smfs_get_inode(dir->i_sb, tmp->d_inode,
231 if (!tmp->d_inode->i_nlink) {
232 struct inode * ind = tmp->d_inode;
234 CWARN("inode #%lu (%*s) nlink is %i/%i\n",
235 ind->i_ino, tmp->d_name.len,
236 tmp->d_name.name, ind->i_nlink,
238 CWARN("parent #%lu (%*s) nlink is %i\n",
239 dir->i_ino, tmp->d_parent->d_name.len,
240 tmp->d_parent->d_name.name,
252 post_smfs_dentry(cache_dentry);
253 post_smfs_dentry(cache_parent);
258 static struct dentry * smfs_iopen_lookup(struct inode * dir,
259 struct dentry *dentry,
260 struct nameidata *nd)
262 struct dentry * alternate = NULL;
263 struct inode *inode = NULL;
267 rc = smfs_do_lookup(dir, dentry, nd, &inode);
272 /* preferrably return a connected dentry */
273 spin_lock(&dcache_lock);
274 list_for_each_entry(alternate, &inode->i_dentry, d_alias) {
275 LASSERT(!(alternate->d_flags & DCACHE_DISCONNECTED));
278 list_for_each_entry(alternate, &inode->i_dentry, d_alias) {
279 dget_locked(alternate);
280 spin_lock(&alternate->d_lock);
281 alternate->d_flags |= DCACHE_REFERENCED;
282 spin_unlock(&alternate->d_lock);
284 spin_unlock(&dcache_lock);
288 dentry->d_flags |= DCACHE_DISCONNECTED;
290 /* d_add(), but don't drop dcache_lock before adding dentry to inode */
291 list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */
292 dentry->d_inode = inode;
294 __d_rehash(dentry); /* d_rehash */
295 spin_unlock(&dcache_lock);
300 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
301 static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry)
303 static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry,
304 struct nameidata *nd)
307 struct dentry * rdentry = NULL;
308 struct inode * inode = NULL;
313 rc = smfs_do_lookup(dir, dentry, nd, &inode);
317 //lmv stuff. Special dentry that has no inode.
318 if (dentry->d_flags & DCACHE_CROSS_REF) {
322 //TODO: should flags be checked and copied before?
323 rdentry = iopen_connect_dentry(dentry, inode, 1);
329 static int smfs_lookup_raw(struct inode *dir, const char *name,
330 int len, ino_t *data)
332 struct inode *cache_dir = I2CI(dir);
338 if (cache_dir->i_op->lookup_raw) {
339 rc = cache_dir->i_op->lookup_raw(cache_dir, name, len, data);
341 CWARN("do not have raw lookup ops in bottom fs\n");
348 static int smfs_link(struct dentry *old_dentry,
349 struct inode *dir, struct dentry *dentry)
351 struct inode *parent = I2CI(dentry->d_parent->d_inode);
352 struct inode *cache_dir = I2CI(dir);
353 struct inode *old_inode = old_dentry->d_inode;
354 struct inode *cache_old_inode = I2CI(old_inode);
355 struct dentry *cache_old_dentry = NULL;
356 struct dentry *cache_dentry = NULL;
357 struct dentry *cache_parent = NULL;
360 struct hook_link_msg msg = {
361 .dentry = old_dentry,
370 if (!cache_old_inode)
373 cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
374 cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
375 cache_old_dentry = pre_smfs_dentry(NULL, cache_old_inode, old_dentry);
376 if (!cache_old_dentry || !cache_dentry || !cache_parent) {
381 handle = smfs_trans_start(dir, FSFILT_OP_LINK, NULL);
382 if (IS_ERR(handle)) {
387 pre_smfs_inode(dir, cache_dir);
388 pre_smfs_inode(old_inode, cache_old_inode);
391 SMFS_PRE_HOOK(dir, HOOK_LINK, &msg);
393 rc = cache_dir->i_op->link(cache_old_dentry, cache_dir, cache_dentry);
395 atomic_inc(&old_inode->i_count);
396 old_inode->i_nlink++;
397 dput(iopen_connect_dentry(dentry, old_inode, 0));
400 SMFS_POST_HOOK(dir, HOOK_LINK, &msg, rc);
402 post_smfs_inode(old_inode, cache_old_inode);
403 post_smfs_inode(dir, cache_dir);
405 smfs_trans_commit(dir, handle, 0);
409 post_smfs_dentry(cache_dentry);
410 post_smfs_dentry(cache_parent);
411 post_smfs_dentry(cache_old_dentry);
416 static int smfs_unlink(struct inode * dir, struct dentry *dentry)
418 struct inode *cache_dir = I2CI(dir);
419 struct inode *cache_inode = I2CI(dentry->d_inode);
420 struct inode *parent = I2CI(dentry->d_parent->d_inode);
421 struct dentry *cache_dentry = NULL;
422 struct dentry *cache_parent = NULL;
426 struct hook_unlink_msg msg = {
428 .mode = dentry->d_inode->i_mode
434 LASSERT(cache_inode);
435 LASSERT(cache_dir->i_op->unlink);
438 CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s (%p),dir=%lu/%u\n",
439 dentry->d_name.len, dentry->d_name.name, dentry,
440 dir->i_ino, dir->i_generation);
442 cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
443 cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
444 if (!cache_dentry || !cache_parent) {
449 handle = smfs_trans_start(dir, FSFILT_OP_UNLINK, NULL);
450 if (IS_ERR(handle)) {
455 pre_smfs_inode(dir, cache_dir);
456 pre_smfs_inode(dentry->d_inode, cache_inode);
458 SMFS_PRE_HOOK(dir, HOOK_UNLINK, &msg);
460 rc = cache_dir->i_op->unlink(cache_dir, cache_dentry);
462 SMFS_POST_HOOK(dir, HOOK_UNLINK, &msg, rc);
464 post_smfs_inode(dentry->d_inode, cache_inode);
465 dentry->d_inode->i_nlink--;
466 post_smfs_inode(dir, cache_dir);
469 smfs_trans_commit(dir, handle, 0);
471 post_smfs_dentry(cache_dentry);
472 post_smfs_dentry(cache_parent);
476 static int smfs_symlink(struct inode *dir, struct dentry *dentry,
479 struct inode *cache_dir = I2CI(dir);
480 struct inode *inode = NULL;
481 struct inode *parent = I2CI(dentry->d_parent->d_inode);
482 struct dentry *cache_dentry = NULL;
483 struct dentry *cache_parent = NULL;
486 struct hook_symlink_msg msg = {
488 .tgt_len = strlen(symname) + 1,
489 .symname = (char*)symname
495 LASSERT(cache_dir->i_op->symlink);
498 cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
499 cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
500 if (!cache_parent || !cache_dentry) {
505 handle = smfs_trans_start(dir, FSFILT_OP_SYMLINK, NULL);
506 if (IS_ERR(handle)) {
511 pre_smfs_inode(dir, cache_dir);
513 SMFS_PRE_HOOK(dir, HOOK_SYMLINK, &msg);
515 rc = cache_dir->i_op->symlink(cache_dir, cache_dentry, symname);
517 inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode,
520 d_instantiate(dentry, inode);
526 SMFS_POST_HOOK(dir, HOOK_SYMLINK, &msg, rc);
528 post_smfs_inode(dir, cache_dir);
529 smfs_trans_commit(dir, handle, 0);
532 post_smfs_dentry(cache_dentry);
533 post_smfs_dentry(cache_parent);
537 static int smfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
539 struct inode *cache_dir = I2CI(dir);
540 struct inode *parent = I2CI(dentry->d_parent->d_inode);
541 struct inode *inode = NULL;
542 struct dentry *cache_dentry = NULL;
543 struct dentry *cache_parent = NULL;
546 struct hook_msg msg = {
555 CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s (%p),dir=%lu/%u\n",
556 dentry->d_name.len, dentry->d_name.name, dentry,
557 dir->i_ino, dir->i_generation);
560 cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
561 cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
562 if (!cache_parent || !cache_dentry) {
567 handle = smfs_trans_start(dir, FSFILT_OP_MKDIR, NULL);
568 if (IS_ERR(handle)) {
573 pre_smfs_inode(dir, cache_dir);
574 SMFS_PRE_HOOK(dir, HOOK_MKDIR, &msg);
576 rc = cache_dir->i_op->mkdir(cache_dir, cache_dentry, mode);
578 inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode,
582 d_instantiate(dentry, inode);
588 SMFS_POST_HOOK(dir, HOOK_MKDIR, &msg, rc);
589 post_smfs_inode(dir, cache_dir);
590 smfs_trans_commit(dir, handle, 0);
593 post_smfs_dentry(cache_dentry);
594 post_smfs_dentry(cache_parent);
598 static int smfs_rmdir(struct inode *dir, struct dentry *dentry)
600 struct inode *cache_dir = I2CI(dir);
601 struct inode *cache_inode = I2CI(dentry->d_inode);
602 struct inode *parent = I2CI(dentry->d_parent->d_inode);
603 struct dentry *cache_dentry = NULL;
604 struct dentry *cache_parent = NULL;
605 struct inode * inode = dentry->d_inode;
608 struct hook_unlink_msg msg = {
615 CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s (%p),dir=%lu/%u\n",
616 dentry->d_name.len, dentry->d_name.name, dentry,
617 dir->i_ino, dir->i_generation);
620 LASSERT(cache_dir->i_op->rmdir);
623 cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
624 cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
625 if (!cache_parent || !cache_dentry) {
630 handle = smfs_trans_start(dir, FSFILT_OP_RMDIR, NULL);
631 if (IS_ERR(handle) ) {
636 dentry_unhash(cache_dentry);
638 pre_smfs_inode(dir, cache_dir);
639 pre_smfs_inode(inode, cache_inode);
641 SMFS_PRE_HOOK(dir, HOOK_RMDIR, &msg);
643 rc = cache_dir->i_op->rmdir(cache_dir, cache_dentry);
645 SMFS_POST_HOOK(dir, HOOK_RMDIR, &msg, rc);
647 if (inode->i_nlink != 2)
648 CWARN("Directory #%lu under rmdir has %i nlinks\n",
649 inode->i_ino, inode->i_nlink);
652 post_smfs_inode(dir, cache_dir);
653 post_smfs_inode(inode, cache_inode);
654 //like vfs_rmdir is doing with inode
655 cache_inode->i_flags |= S_DEAD;
657 smfs_trans_commit(dir, handle, 0);
660 post_smfs_dentry(cache_dentry);
661 post_smfs_dentry(cache_parent);
665 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
666 static int smfs_mknod(struct inode *dir, struct dentry *dentry,
669 static int smfs_mknod(struct inode *dir, struct dentry *dentry,
670 int mode, dev_t rdev)
673 struct inode *cache_dir = I2CI(dir);
674 struct inode *inode = NULL;
675 struct inode *parent = I2CI(dentry->d_parent->d_inode);
676 struct dentry *cache_dentry = NULL;
677 struct dentry *cache_parent = NULL;
680 struct hook_msg msg = {
688 LASSERT(cache_dir->i_op->mknod);
690 cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
691 cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
692 if (!cache_parent || !cache_dentry) {
697 handle = smfs_trans_start(dir, FSFILT_OP_MKNOD, NULL);
698 if (IS_ERR(handle)) {
703 pre_smfs_inode(dir, cache_dir);
705 SMFS_PRE_HOOK(dir, HOOK_MKNOD, &msg);
707 rc = cache_dir->i_op->mknod(cache_dir, cache_dentry, mode, rdev);
709 inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode,
712 //smsf_update_dentry(dentry, cache_dentry);
713 d_instantiate(dentry, inode);
719 SMFS_POST_HOOK(dir, HOOK_MKNOD, &msg, rc);
721 post_smfs_inode(dir, cache_dir);
723 smfs_trans_commit(dir, handle, 0);
726 post_smfs_dentry(cache_dentry);
727 post_smfs_dentry(cache_parent);
731 static int smfs_rename(struct inode *old_dir, struct dentry *old_dentry,
732 struct inode *new_dir,struct dentry *new_dentry)
734 struct inode *cache_old_dir = I2CI(old_dir);
735 struct inode *cache_new_dir = I2CI(new_dir);
736 struct inode *new_inode = new_dentry->d_inode;
737 struct inode *cache_old_inode = I2CI(old_dentry->d_inode);
738 struct inode *old_parent = I2CI(old_dentry->d_parent->d_inode);
739 struct inode *new_parent = I2CI(new_dentry->d_parent->d_inode);
740 struct inode *cache_new_inode = NULL;
741 struct dentry *cache_old_dentry = NULL;
742 struct dentry *cache_new_dentry = NULL;
743 struct dentry *cache_new_parent = NULL;
744 struct dentry *cache_old_parent = NULL;
747 struct hook_rename_msg msg = {
748 .dentry = old_dentry,
750 .new_dentry = new_dentry
755 if (!cache_old_dir || !cache_new_dir || !cache_old_inode)
759 cache_new_inode = I2CI(new_inode);
760 if (!cache_new_inode)
764 cache_old_parent = pre_smfs_dentry(NULL, old_parent, old_dentry->d_parent);
765 cache_old_dentry = pre_smfs_dentry(cache_old_parent, cache_old_inode,
767 if (!cache_old_parent || !cache_old_dentry) {
772 cache_new_parent = pre_smfs_dentry(NULL, new_parent, new_dentry->d_parent);
773 cache_new_dentry = pre_smfs_dentry(cache_new_parent, cache_new_inode,
775 if (!cache_new_parent || !cache_new_dentry) {
780 handle = smfs_trans_start(old_dir, FSFILT_OP_RENAME, NULL);
781 if (IS_ERR(handle)) {
786 pre_smfs_inode(old_dir, cache_old_dir);
787 pre_smfs_inode(new_dir, cache_new_dir);
788 pre_smfs_inode(old_dentry->d_inode, cache_old_inode);
790 pre_smfs_inode(new_inode, cache_new_inode);
792 SMFS_PRE_HOOK(old_dir, HOOK_RENAME, &msg);
794 rc = cache_old_dir->i_op->rename(cache_old_dir, cache_old_dentry,
795 cache_new_dir, cache_new_dentry);
797 SMFS_POST_HOOK(old_dir, HOOK_RENAME, &msg, rc);
799 post_smfs_inode(old_dir, cache_old_dir);
800 post_smfs_inode(new_dir, cache_new_dir);
801 post_smfs_inode(old_dentry->d_inode, cache_old_inode);
803 post_smfs_inode(new_inode, cache_new_inode);
804 new_inode->i_nlink--;
806 //directory is renamed
807 if (S_ISDIR(old_dentry->d_inode->i_mode)) {
810 new_inode->i_nlink--;
816 smfs_trans_commit(old_dir, handle, 0);
819 post_smfs_dentry(cache_old_dentry);
820 post_smfs_dentry(cache_old_parent);
821 post_smfs_dentry(cache_new_dentry);
822 post_smfs_dentry(cache_new_parent);
826 struct inode_operations smfs_dir_iops = {
827 .create = smfs_create,
828 .lookup = smfs_lookup,
830 .lookup_raw = smfs_lookup_raw,
833 .unlink = smfs_unlink,
834 .symlink = smfs_symlink,
838 .rename = smfs_rename,
839 .setxattr = smfs_setxattr,
840 .getxattr = smfs_getxattr,
841 .listxattr = smfs_listxattr,
842 .removexattr = smfs_removexattr,
843 .permission = smfs_permission,
846 struct inode_operations smfs_iopen_iops = {
847 .lookup = smfs_iopen_lookup,
850 static ssize_t smfs_read_dir(struct file *filp, char *buf,
851 size_t size, loff_t *ppos)
853 struct dentry *dentry = filp->f_dentry;
854 struct inode *cache_inode = NULL;
855 struct smfs_file_info *sfi = NULL;
857 loff_t *cache_ppos = NULL;
862 cache_inode = I2CI(dentry->d_inode);
864 if (!cache_inode || !cache_inode->i_fop->read)
868 if (sfi->magic != SMFS_FILE_MAGIC)
871 if (ppos != &(filp->f_pos))
872 cache_ppos = &tmp_ppos;
874 cache_ppos = &sfi->c_file->f_pos;
878 rc = cache_inode->i_fop->read(sfi->c_file, buf, size, cache_ppos);
884 duplicate_file(filp, sfi->c_file);
889 static int smfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
891 struct dentry *dentry = filp->f_dentry;
892 struct inode *cache_inode = NULL;
893 struct smfs_file_info *sfi = NULL;
895 struct hook_readdir_msg msg = {
904 cache_inode = I2CI(dentry->d_inode);
905 if (!cache_inode || !cache_inode->i_fop->readdir)
909 if (sfi->magic != SMFS_FILE_MAGIC) BUG();
911 SMFS_PRE_HOOK(dentry->d_inode, HOOK_READDIR, &msg);
913 rc = cache_inode->i_fop->readdir(sfi->c_file, dirent, filldir);
915 SMFS_POST_HOOK(dentry->d_inode, HOOK_READDIR, &msg, rc);
916 duplicate_file(filp, sfi->c_file);
921 struct file_operations smfs_dir_fops = {
922 .read = smfs_read_dir,
923 .readdir = smfs_readdir, /* BKL held */
924 .ioctl = smfs_ioctl, /* BKL held */
925 .fsync = smfs_fsync, /* BKL held */
927 .release = smfs_release,
930 struct file_operations smfs_iopen_fops = {
931 .read = smfs_read_dir,