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/kmod.h>
26 #include <linux/init.h>
28 #include <linux/slab.h>
29 #include <linux/string.h>
30 #include <linux/lustre_idl.h>
31 #include <portals/list.h>
32 #include <linux/obd_class.h>
33 #include <linux/obd_support.h>
34 #include <linux/lustre_lib.h>
35 #include <linux/lustre_smfs.h>
37 #include "smfs_internal.h"
38 int smfs_init_sm_ops(struct smfs_super_info *smb)
40 struct sm_operations *sm_ops; /*cache ops for set cache inode ops*/
42 OBD_ALLOC(sm_ops, sizeof(struct sm_operations));
50 void smfs_cleanup_sm_ops(struct smfs_super_info *smb)
53 OBD_FREE(smb->sm_ops, sizeof(struct sm_operations));
56 static void setup_iops(struct inode *cache_inode,
57 struct inode_operations *iops,
58 struct inode_operations *cache_iops)
61 if (cache_inode->i_op && cache_iops && iops) {
62 if (cache_inode->i_op->create)
63 iops->create = cache_iops->create;
64 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
65 if (cache_inode->i_op->create_it)
66 iops->create_it = cache_iops->create_it;
68 if (cache_inode->i_op->lookup)
69 iops->lookup = cache_iops->lookup;
70 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
71 if (cache_inode->i_op->lookup_raw)
72 iops->lookup_raw = cache_iops->lookup_raw;
73 if (cache_inode->i_op->lookup_it)
74 iops->lookup_it = cache_iops->lookup_it;
76 if (cache_inode->i_op->link)
77 iops->link = cache_iops->link;
78 if (cache_inode->i_op->link_raw)
79 iops->link_raw = cache_iops->link_raw;
80 if (cache_inode->i_op->unlink)
81 iops->unlink = cache_iops->unlink;
82 if (cache_inode->i_op->unlink_raw)
83 iops->unlink_raw = cache_iops->unlink_raw;
84 if (cache_inode->i_op->symlink)
85 iops->symlink = cache_iops->symlink;
86 if (cache_inode->i_op->symlink_raw)
87 iops->symlink_raw = cache_iops->symlink_raw;
88 if (cache_inode->i_op->mkdir)
89 iops->mkdir = cache_iops->mkdir;
90 if (cache_inode->i_op->mkdir_raw)
91 iops->mkdir_raw = cache_iops->mkdir_raw;
92 if (cache_inode->i_op->rmdir)
93 iops->rmdir = cache_iops->rmdir;
94 if (cache_inode->i_op->rmdir_raw)
95 iops->rmdir_raw = cache_iops->rmdir_raw;
96 if (cache_inode->i_op->mknod)
97 iops->mknod = cache_iops->mknod;
98 if (cache_inode->i_op->mknod_raw)
99 iops->mknod_raw = cache_iops->mknod_raw;
100 if (cache_inode->i_op->rename)
101 iops->rename = cache_iops->rename;
102 if (cache_inode->i_op->rename_raw)
103 iops->rename_raw = cache_iops->rename_raw;
104 if (cache_inode->i_op->readlink)
105 iops->readlink = cache_iops->readlink;
106 if (cache_inode->i_op->follow_link)
107 iops->follow_link = cache_iops->follow_link;
108 if (cache_inode->i_op->truncate)
109 iops->truncate = cache_iops->truncate;
110 if (cache_inode->i_op->permission)
111 iops->permission = cache_iops->permission;
112 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
113 if (cache_inode->i_op->revalidate)
114 iops->revalidate = cache_iops->revalidate;
115 if (cache_inode->i_op->revalidate_it)
116 iops->revalidate_it = cache_iops->revalidate_it;
118 if (cache_inode->i_op->setattr)
119 iops->setattr = cache_iops->setattr;
120 if (cache_inode->i_op->setattr_raw)
121 iops->setattr_raw = cache_iops->setattr_raw;
122 if (cache_inode->i_op->getattr)
123 iops->getattr = cache_iops->getattr;
124 if (cache_inode->i_op->setxattr)
125 iops->setxattr = cache_iops->setxattr;
126 if (cache_inode->i_op->getxattr)
127 iops->getxattr = cache_iops->getxattr;
128 if (cache_inode->i_op->listxattr)
129 iops->listxattr = cache_iops->listxattr;
130 if (cache_inode->i_op->removexattr)
131 iops->removexattr = cache_iops->removexattr;
135 static void setup_fops(struct inode *cache_inode,
136 struct file_operations *fops,
137 struct file_operations *cache_fops)
139 if (cache_inode->i_fop && cache_fops && fops) {
140 if (cache_inode->i_fop->llseek)
141 fops->llseek = cache_fops->llseek;
142 if (cache_inode->i_fop->read)
143 fops->read = cache_fops->read;
144 if (cache_inode->i_fop->write)
145 fops->write = cache_fops->write;
146 if (cache_inode->i_fop->readdir)
147 fops->readdir = cache_fops->readdir;
148 if (cache_inode->i_fop->poll)
149 fops->poll = cache_fops->poll;
150 if (cache_inode->i_fop->ioctl)
151 fops->ioctl = cache_fops->ioctl;
152 if (cache_inode->i_fop->mmap)
153 fops->mmap = cache_fops->mmap;
154 // if (cache_inode->i_fop->open)
155 fops->open = cache_fops->open;
156 if (cache_inode->i_fop->flush)
157 fops->flush = cache_fops->flush;
158 // if (cache_inode->i_fop->release)
159 fops->release = cache_fops->release;
160 if (cache_inode->i_fop->fsync)
161 fops->fsync = cache_fops->fsync;
162 if (cache_inode->i_fop->fasync)
163 fops->fasync = cache_fops->fasync;
164 if (cache_inode->i_fop->lock)
165 fops->lock = cache_fops->lock;
166 if (cache_inode->i_fop->readv)
167 fops->readv = cache_fops->readv;
168 if (cache_inode->i_fop->writev)
169 fops->writev = cache_fops->writev;
170 if (cache_inode->i_fop->sendpage)
171 fops->sendpage = cache_fops->sendpage;
172 if (cache_inode->i_fop->get_unmapped_area)
173 fops->get_unmapped_area = cache_fops->get_unmapped_area;
177 static void setup_sm_file_ops(struct inode *cache_inode,
179 struct inode_operations *cache_iops,
180 struct file_operations *cache_fops)
182 struct smfs_super_info *smb;
183 struct inode_operations *iops;
184 struct file_operations *fops;
186 smb = S2SMI(inode->i_sb);
188 if (smb->ops_check & FILE_OPS_CHECK)
190 smb->ops_check |= FILE_OPS_CHECK;
192 iops = cache_fiops(smb);
193 fops = cache_ffops(smb);
195 memset(iops , 0 , sizeof (struct inode_operations));
196 memset(fops , 0 , sizeof (struct file_operations));
198 setup_iops(cache_inode, iops, cache_iops);
199 setup_fops(cache_inode, fops, cache_fops);
204 static void setup_sm_dir_ops(struct inode *cache_inode,
206 struct inode_operations *cache_dir_iops,
207 struct file_operations *cache_dir_fops)
209 struct smfs_super_info *smb;
210 struct inode_operations *iops;
211 struct file_operations *fops;
213 smb = S2SMI(inode->i_sb);
215 if (smb->ops_check & DIR_OPS_CHECK)
217 smb->ops_check |= DIR_OPS_CHECK;
219 iops = cache_diops(smb);
220 fops = cache_dfops(smb);
222 memset(iops, 0, sizeof (struct inode_operations));
223 memset(fops, 0, sizeof (struct file_operations));
225 setup_iops(cache_inode, iops, cache_dir_iops);
226 setup_fops(cache_inode, fops, cache_dir_fops);
231 static void setup_sm_symlink_ops(struct inode *cache_inode,
233 struct inode_operations *cache_sym_iops,
234 struct file_operations *cache_sym_fops)
236 struct smfs_super_info *smb;
237 struct inode_operations *iops;
238 struct file_operations *fops;
240 smb = S2SMI(inode->i_sb);
242 if (smb->ops_check & SYMLINK_OPS_CHECK)
244 smb->ops_check |= SYMLINK_OPS_CHECK;
246 iops = cache_siops(smb);
247 fops = cache_sfops(smb);
249 memset(iops , 0 , sizeof (struct inode_operations));
250 memset(fops , 0 , sizeof (struct file_operations));
252 setup_iops(cache_inode, iops, cache_sym_iops);
253 setup_fops(cache_inode, fops, cache_sym_fops);
258 static void setup_sm_sb_ops(struct super_block *cache_sb,
259 struct super_block *sb,
260 struct super_operations *smfs_sops)
262 struct smfs_super_info *smb;
263 struct super_operations *sops;
269 if (smb->ops_check & SB_OPS_CHECK)
271 smb->ops_check |= SB_OPS_CHECK;
272 sops = cache_sops(smb);
273 memset(sops, 0, sizeof (struct super_operations));
275 if (cache_sb->s_op) {
276 if (cache_sb->s_op->read_inode)
277 sops->read_inode = smfs_sops->read_inode;
278 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
279 if (cache_sb->s_op->read_inode2)
280 sops->read_inode2 = smfs_sops->read_inode2;
282 if (cache_sb->s_op->dirty_inode)
283 sops->dirty_inode = smfs_sops->dirty_inode;
284 if (cache_sb->s_op->write_inode)
285 sops->write_inode = smfs_sops->write_inode;
286 if (cache_sb->s_op->put_inode)
287 sops->put_inode = smfs_sops->put_inode;
288 if (cache_sb->s_op->delete_inode)
289 sops->delete_inode = smfs_sops->delete_inode;
290 if (cache_sb->s_op->put_super)
291 sops->put_super = smfs_sops->put_super;
292 if (cache_sb->s_op->write_super)
293 sops->write_super = smfs_sops->write_super;
294 if (cache_sb->s_op->write_super_lockfs)
295 sops->write_super_lockfs =smfs_sops->write_super_lockfs;
296 if (cache_sb->s_op->unlockfs)
297 sops->unlockfs = smfs_sops->unlockfs;
298 if (cache_sb->s_op->statfs)
299 sops->statfs = smfs_sops->statfs;
300 if (cache_sb->s_op->remount_fs)
301 sops->remount_fs = smfs_sops->remount_fs;
302 if (cache_sb->s_op->umount_begin)
303 sops->umount_begin = smfs_sops->umount_begin;
304 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
305 if (cache_sb->s_op->fh_to_dentry)
306 sops->fh_to_dentry = smfs_sops->fh_to_dentry;
307 if (cache_sb->s_op->dentry_to_fh)
308 sops->dentry_to_fh = smfs_sops->dentry_to_fh;
310 if (cache_sb->s_op->show_options)
311 sops->show_options = smfs_sops->show_options;
313 /* FIXME-WANGDI: we need this method to clear the cache
315 sops->clear_inode = smfs_sops->clear_inode;
321 void sm_set_inode_ops(struct inode *cache_inode, struct inode *inode)
323 struct smfs_super_info *smb = S2SMI(inode->i_sb);
324 /* XXX now set the correct sm_{file,dir,sym}_iops */
325 if (S_ISDIR(inode->i_mode)) {
326 setup_sm_dir_ops(cache_inode, inode,
329 inode->i_op = cache_diops(smb);
330 inode->i_fop = cache_dfops(smb);
331 } else if (S_ISREG(inode->i_mode)) {
332 setup_sm_file_ops(cache_inode, inode,
335 CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
336 inode->i_ino, inode->i_op);
337 inode->i_fop = cache_ffops(smb);
338 inode->i_op = cache_fiops(smb);
340 } else if (S_ISLNK(inode->i_mode)) {
341 setup_sm_symlink_ops(cache_inode, inode,
344 inode->i_op = cache_siops(smb);
345 inode->i_fop = cache_sfops(smb);
346 CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
347 inode->i_ino, inode->i_op);
351 void sm_set_sb_ops(struct super_block *cache_sb, struct super_block *sb)
353 struct smfs_super_info *smb;
357 setup_sm_sb_ops(cache_sb, sb, &smfs_super_ops);
359 sb->s_op = cache_sops(smb);