1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
5 * Lustre filesystem abstraction routines
7 * Copyright (C) 2004 Cluster File Systems, Inc.
9 * This file is part of Lustre, http://www.lustre.org.
11 * Lustre is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * Lustre is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with Lustre; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #define DEBUG_SUBSYSTEM S_SM
26 #include <linux/kmod.h>
27 #include <linux/init.h>
29 #include <linux/slab.h>
30 #include <linux/string.h>
31 #include <linux/lustre_idl.h>
32 #include <libcfs/list.h>
33 #include <linux/obd_class.h>
34 #include <linux/obd_support.h>
35 #include <linux/lustre_lib.h>
36 #include <linux/lustre_fsfilt.h>
37 #include <linux/lustre_smfs.h>
39 #include "smfs_internal.h"
40 int smfs_init_sm_ops(struct smfs_super_info *smb)
42 struct sm_operations *sm_ops; /*cache ops for set cache inode ops*/
44 OBD_ALLOC(sm_ops, sizeof(struct sm_operations));
52 void smfs_cleanup_sm_ops(struct smfs_super_info *smb)
55 OBD_FREE(smb->sm_ops, sizeof(struct sm_operations));
58 static void setup_iops(struct inode *cache_inode,
59 struct inode_operations *smfs_iops,
60 struct inode_operations *iops)
63 LASSERT(cache_inode->i_op && smfs_iops && iops);
65 if (cache_inode->i_op->create)
66 iops->create = smfs_iops->create;
67 if (cache_inode->i_op->lookup)
68 iops->lookup = smfs_iops->lookup;
69 if (cache_inode->i_op->link)
70 iops->link = smfs_iops->link;
71 if (cache_inode->i_op->unlink)
72 iops->unlink = smfs_iops->unlink;
73 if (cache_inode->i_op->symlink)
74 iops->symlink = smfs_iops->symlink;
75 if (cache_inode->i_op->mkdir)
76 iops->mkdir = smfs_iops->mkdir;
77 if (cache_inode->i_op->rmdir)
78 iops->rmdir = smfs_iops->rmdir;
79 if (cache_inode->i_op->mknod)
80 iops->mknod = smfs_iops->mknod;
81 if (cache_inode->i_op->rename)
82 iops->rename = smfs_iops->rename;
83 if (cache_inode->i_op->readlink)
84 iops->readlink = smfs_iops->readlink;
85 if (cache_inode->i_op->follow_link)
86 iops->follow_link = smfs_iops->follow_link;
87 if (cache_inode->i_op->truncate)
88 iops->truncate = smfs_iops->truncate;
89 if (cache_inode->i_op->permission)
90 iops->permission = smfs_iops->permission;
91 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
92 if (cache_inode->i_op->revalidate)
93 iops->revalidate = smfs_iops->revalidate;
95 if (cache_inode->i_op->setattr)
96 iops->setattr = smfs_iops->setattr;
97 if (cache_inode->i_op->getattr)
98 iops->getattr = smfs_iops->getattr;
99 if (cache_inode->i_op->setxattr)
100 iops->setxattr = smfs_iops->setxattr;
101 if (cache_inode->i_op->getxattr)
102 iops->getxattr = smfs_iops->getxattr;
103 if (cache_inode->i_op->listxattr)
104 iops->listxattr = smfs_iops->listxattr;
105 if (cache_inode->i_op->removexattr)
106 iops->removexattr = smfs_iops->removexattr;
108 if (cache_inode->i_op->lookup_raw)
109 iops->lookup_raw = smfs_iops->lookup_raw;
114 static void setup_fops(struct inode *cache_inode,
115 struct file_operations *smfs_fops,
116 struct file_operations *fops)
118 LASSERT(cache_inode->i_fop && smfs_fops && fops);
120 if (cache_inode->i_fop->llseek)
121 fops->llseek = smfs_fops->llseek;
122 if (cache_inode->i_fop->read)
123 fops->read = smfs_fops->read;
124 if (cache_inode->i_fop->write)
125 fops->write = smfs_fops->write;
126 if (cache_inode->i_fop->readdir)
127 fops->readdir = smfs_fops->readdir;
128 if (cache_inode->i_fop->poll)
129 fops->poll = smfs_fops->poll;
130 if (cache_inode->i_fop->ioctl)
131 fops->ioctl = smfs_fops->ioctl;
132 if (cache_inode->i_fop->mmap)
133 fops->mmap = smfs_fops->mmap;
134 if (cache_inode->i_fop->flush)
135 fops->flush = smfs_fops->flush;
136 if (cache_inode->i_fop->fsync)
137 fops->fsync = smfs_fops->fsync;
138 if (cache_inode->i_fop->fasync)
139 fops->fasync = smfs_fops->fasync;
140 if (cache_inode->i_fop->lock)
141 fops->lock = smfs_fops->lock;
142 if (cache_inode->i_fop->readv)
143 fops->readv = smfs_fops->readv;
144 if (cache_inode->i_fop->writev)
145 fops->writev = smfs_fops->writev;
146 if (cache_inode->i_fop->sendpage)
147 fops->sendpage = smfs_fops->sendpage;
148 if (cache_inode->i_fop->get_unmapped_area)
149 fops->get_unmapped_area = smfs_fops->get_unmapped_area;
151 /* for dir file we also need replace the open and release method,
152 * because we need initialize the cache file structs. */
153 fops->open = smfs_fops->open;
154 fops->release = smfs_fops->release;
157 static void setup_sm_file_ops(struct inode *inode)
159 struct smfs_super_info *smb = S2SMI(inode->i_sb);
160 struct inode *cache_inode = I2CI(inode);
162 setup_iops(cache_inode, &smfs_file_iops, &smb->sm_ops->sm_file_iops);
163 setup_fops(cache_inode, &smfs_file_fops, &smb->sm_ops->sm_file_fops);
166 smb->smsi_ops_check |= FILE_OPS_CHECK;
170 static void setup_sm_dir_ops(struct inode *inode)
172 struct smfs_super_info *smb = S2SMI(inode->i_sb);
173 struct inode *cache_inode = I2CI(inode);
175 setup_iops(cache_inode, &smfs_dir_iops, &smb->sm_ops->sm_dir_iops);
176 setup_fops(cache_inode, &smfs_dir_fops, &smb->sm_ops->sm_dir_fops);
179 smb->smsi_ops_check |= DIR_OPS_CHECK;
183 static void setup_sm_symlink_ops(struct inode *inode)
185 struct smfs_super_info *smb = S2SMI(inode->i_sb);
186 struct inode *cache_inode = I2CI(inode);
188 setup_iops(cache_inode, &smfs_sym_iops, &smb->sm_ops->sm_sym_iops);
189 setup_fops(cache_inode, &smfs_sym_fops, &smb->sm_ops->sm_sym_fops);
192 smb->smsi_ops_check |= SYMLINK_OPS_CHECK;
196 static void setup_sm_special_ops(struct inode *inode)
198 struct smfs_super_info *smb = S2SMI(inode->i_sb);
199 struct inode *cache_inode = I2CI(inode);
201 setup_iops(cache_inode, &smfs_special_iops, &smb->sm_ops->sm_special_iops);
204 smb->smsi_ops_check |= SPECIAL_OPS_CHECK;
208 void sm_set_inode_ops(struct inode *inode)
210 struct smfs_super_info *smb = S2SMI(inode->i_sb);
213 if (inode->i_ino == SMFS_IOPEN_INO) {
214 inode->i_op = &smfs_iopen_iops;
215 inode->i_fop = &smfs_iopen_fops;
219 /* set the correct sm_{file,dir,sym}_iops */
220 if (S_ISDIR(inode->i_mode)) {
221 if (!(smb->smsi_ops_check & DIR_OPS_CHECK))
222 setup_sm_dir_ops(inode);
223 inode->i_op = &smb->sm_ops->sm_dir_iops;
224 inode->i_fop = &smb->sm_ops->sm_dir_fops;
225 } else if (S_ISREG(inode->i_mode)) {
226 if (!(smb->smsi_ops_check & FILE_OPS_CHECK))
227 setup_sm_file_ops(inode);
228 inode->i_fop = &smb->sm_ops->sm_file_fops;
229 inode->i_op = &smb->sm_ops->sm_file_iops;
231 } else if (S_ISLNK(inode->i_mode)) {
232 if (!(smb->smsi_ops_check & SYMLINK_OPS_CHECK))
233 setup_sm_symlink_ops(inode);
234 inode->i_op = &smb->sm_ops->sm_sym_iops;
235 inode->i_fop = &smb->sm_ops->sm_sym_fops;
237 if (!(smb->smsi_ops_check & SPECIAL_OPS_CHECK))
238 setup_sm_special_ops(inode);
239 inode->i_op = &smb->sm_ops->sm_special_iops;
244 void sm_set_sb_ops(struct super_block *cache_sb, struct super_block *sb)
246 struct smfs_super_info *smb = S2SMI(sb);
247 struct super_operations *sops = &smb->sm_ops->sm_sb_ops;
248 struct super_operations *smfs_sops = &smfs_super_ops;
251 if (smb->smsi_ops_check & SB_OPS_CHECK)
254 //set up only operations exist in backfs
255 memset(sops, 0, sizeof (struct super_operations));
256 if (cache_sb->s_op) {
257 if (cache_sb->s_op->dirty_inode)
258 sops->dirty_inode = smfs_sops->dirty_inode;
259 if (cache_sb->s_op->write_inode)
260 sops->write_inode = smfs_sops->write_inode;
261 if (cache_sb->s_op->put_super)
262 sops->put_super = smfs_sops->put_super;
263 if (cache_sb->s_op->write_super)
264 sops->write_super = smfs_sops->write_super;
265 if (cache_sb->s_op->write_super_lockfs)
266 sops->write_super_lockfs = smfs_sops->write_super_lockfs;
267 if (cache_sb->s_op->unlockfs)
268 sops->unlockfs = smfs_sops->unlockfs;
269 if (cache_sb->s_op->statfs)
270 sops->statfs = smfs_sops->statfs;
271 if (cache_sb->s_op->remount_fs)
272 sops->remount_fs = smfs_sops->remount_fs;
273 //if (cache_sb->s_op->umount_begin)
274 // sops->umount_begin = smfs_sops->umount_begin;
276 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
277 if (cache_sb->s_op->fh_to_dentry)
278 sops->fh_to_dentry = smfs_sops->fh_to_dentry;
279 if (cache_sb->s_op->dentry_to_fh)
280 sops->dentry_to_fh = smfs_sops->dentry_to_fh;
281 if (cache_sb->s_op->show_options)
282 sops->show_options = smfs_sops->show_options;
284 sops->read_inode2 = smfs_sops->read_inode2;
286 /* these ops are needed always */
287 sops->clear_inode = smfs_sops->clear_inode;
288 sops->delete_inode = smfs_sops->delete_inode;
293 smb->smsi_ops_check |= SB_OPS_CHECK;