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 *iops,
60 struct inode_operations *cache_iops)
63 if (cache_inode->i_op && cache_iops && iops) {
64 if (cache_inode->i_op->create)
65 iops->create = cache_iops->create;
66 if (cache_inode->i_op->lookup)
67 iops->lookup = cache_iops->lookup;
68 if (cache_inode->i_op->link)
69 iops->link = cache_iops->link;
70 if (cache_inode->i_op->unlink)
71 iops->unlink = cache_iops->unlink;
72 if (cache_inode->i_op->symlink)
73 iops->symlink = cache_iops->symlink;
74 if (cache_inode->i_op->mkdir)
75 iops->mkdir = cache_iops->mkdir;
76 if (cache_inode->i_op->rmdir)
77 iops->rmdir = cache_iops->rmdir;
78 if (cache_inode->i_op->mknod)
79 iops->mknod = cache_iops->mknod;
80 if (cache_inode->i_op->rename)
81 iops->rename = cache_iops->rename;
82 if (cache_inode->i_op->readlink)
83 iops->readlink = cache_iops->readlink;
84 if (cache_inode->i_op->follow_link)
85 iops->follow_link = cache_iops->follow_link;
86 if (cache_inode->i_op->truncate)
87 iops->truncate = cache_iops->truncate;
88 if (cache_inode->i_op->permission)
89 iops->permission = cache_iops->permission;
90 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
91 if (cache_inode->i_op->revalidate)
92 iops->revalidate = cache_iops->revalidate;
94 if (cache_inode->i_op->setattr)
95 iops->setattr = cache_iops->setattr;
96 if (cache_inode->i_op->getattr)
97 iops->getattr = cache_iops->getattr;
98 if (cache_inode->i_op->setxattr)
99 iops->setxattr = cache_iops->setxattr;
100 if (cache_inode->i_op->getxattr)
101 iops->getxattr = cache_iops->getxattr;
102 if (cache_inode->i_op->listxattr)
103 iops->listxattr = cache_iops->listxattr;
104 if (cache_inode->i_op->removexattr)
105 iops->removexattr = cache_iops->removexattr;
107 if (cache_inode->i_op->lookup_raw)
108 iops->lookup_raw = cache_iops->lookup_raw;
113 static void setup_fops(struct inode *cache_inode,
114 struct file_operations *fops,
115 struct file_operations *cache_fops)
117 if (cache_inode->i_fop && cache_fops && fops) {
118 if (cache_inode->i_fop->llseek)
119 fops->llseek = cache_fops->llseek;
120 if (cache_inode->i_fop->read)
121 fops->read = cache_fops->read;
122 if (cache_inode->i_fop->write)
123 fops->write = cache_fops->write;
124 if (cache_inode->i_fop->readdir)
125 fops->readdir = cache_fops->readdir;
126 if (cache_inode->i_fop->poll)
127 fops->poll = cache_fops->poll;
128 if (cache_inode->i_fop->ioctl)
129 fops->ioctl = cache_fops->ioctl;
130 if (cache_inode->i_fop->mmap)
131 fops->mmap = cache_fops->mmap;
132 if (cache_inode->i_fop->flush)
133 fops->flush = cache_fops->flush;
134 if (cache_inode->i_fop->fsync)
135 fops->fsync = cache_fops->fsync;
136 if (cache_inode->i_fop->fasync)
137 fops->fasync = cache_fops->fasync;
138 if (cache_inode->i_fop->lock)
139 fops->lock = cache_fops->lock;
140 if (cache_inode->i_fop->readv)
141 fops->readv = cache_fops->readv;
142 if (cache_inode->i_fop->writev)
143 fops->writev = cache_fops->writev;
144 if (cache_inode->i_fop->sendpage)
145 fops->sendpage = cache_fops->sendpage;
146 if (cache_inode->i_fop->get_unmapped_area)
147 fops->get_unmapped_area = cache_fops->get_unmapped_area;
149 /* for dir file we also need replace the open and release method,
150 * because we need initialize the cache file structs. */
151 fops->open = cache_fops->open;
152 fops->release = cache_fops->release;
156 static void setup_sm_file_ops(struct inode *cache_inode, struct inode *inode,
157 struct inode_operations *cache_iops,
158 struct file_operations *cache_fops)
160 struct smfs_super_info *smb;
161 struct inode_operations *iops;
162 struct file_operations *fops;
164 smb = S2SMI(inode->i_sb);
166 if (smb->smsi_ops_check & FILE_OPS_CHECK)
169 iops = cache_fiops(smb);
170 fops = cache_ffops(smb);
172 setup_iops(cache_inode, iops, cache_iops);
173 setup_fops(cache_inode, fops, cache_fops);
176 smb->smsi_ops_check |= FILE_OPS_CHECK;
180 static void setup_sm_dir_ops(struct inode *cache_inode, struct inode *inode,
181 struct inode_operations *cache_dir_iops,
182 struct file_operations *cache_dir_fops)
184 struct smfs_super_info *smb;
185 struct inode_operations *iops;
186 struct file_operations *fops;
188 smb = S2SMI(inode->i_sb);
190 if (smb->smsi_ops_check & DIR_OPS_CHECK)
193 iops = cache_diops(smb);
194 fops = cache_dfops(smb);
196 setup_iops(cache_inode, iops, cache_dir_iops);
197 setup_fops(cache_inode, fops, cache_dir_fops);
200 smb->smsi_ops_check |= DIR_OPS_CHECK;
204 static void setup_sm_symlink_ops(struct inode *cache_inode, struct inode *inode,
205 struct inode_operations *cache_sym_iops,
206 struct file_operations *cache_sym_fops)
208 struct smfs_super_info *smb;
209 struct inode_operations *iops;
210 struct file_operations *fops;
212 smb = S2SMI(inode->i_sb);
214 if (smb->smsi_ops_check & SYMLINK_OPS_CHECK)
217 iops = cache_siops(smb);
218 fops = cache_sfops(smb);
220 setup_iops(cache_inode, iops, cache_sym_iops);
221 setup_fops(cache_inode, fops, cache_sym_fops);
224 smb->smsi_ops_check |= SYMLINK_OPS_CHECK;
229 void sm_set_inode_ops(struct inode *cache_inode, struct inode *inode)
231 struct smfs_super_info *smb = S2SMI(inode->i_sb);
233 /* XXX now set the correct sm_{file,dir,sym}_iops */
234 if (S_ISDIR(inode->i_mode)) {
235 setup_sm_dir_ops(cache_inode, inode,
238 inode->i_op = cache_diops(smb);
239 inode->i_fop = cache_dfops(smb);
240 } else if (S_ISREG(inode->i_mode)) {
241 setup_sm_file_ops(cache_inode, inode,
244 CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
245 inode->i_ino, inode->i_op);
246 inode->i_fop = cache_ffops(smb);
247 inode->i_op = cache_fiops(smb);
249 } else if (S_ISLNK(inode->i_mode)) {
250 setup_sm_symlink_ops(cache_inode, inode,
253 inode->i_op = cache_siops(smb);
254 inode->i_fop = cache_sfops(smb);
255 CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
256 inode->i_ino, inode->i_op);
261 void sm_set_sb_ops(struct super_block *cache_sb, struct super_block *sb)
263 struct smfs_super_info *smb = S2SMI(sb);
264 struct super_operations *sops = &smb->sm_ops->sm_sb_ops;
265 struct super_operations *smfs_sops = &smfs_super_ops;
268 if (smb->smsi_ops_check & SB_OPS_CHECK)
271 //set up only operations exist in backfs
272 memset(sops, 0, sizeof (struct super_operations));
273 if (cache_sb->s_op) {
274 if (cache_sb->s_op->dirty_inode)
275 sops->dirty_inode = smfs_sops->dirty_inode;
276 if (cache_sb->s_op->write_inode)
277 sops->write_inode = smfs_sops->write_inode;
278 if (cache_sb->s_op->put_super)
279 sops->put_super = smfs_sops->put_super;
280 if (cache_sb->s_op->write_super)
281 sops->write_super = smfs_sops->write_super;
282 if (cache_sb->s_op->write_super_lockfs)
283 sops->write_super_lockfs = smfs_sops->write_super_lockfs;
284 if (cache_sb->s_op->unlockfs)
285 sops->unlockfs = smfs_sops->unlockfs;
286 if (cache_sb->s_op->statfs)
287 sops->statfs = smfs_sops->statfs;
288 if (cache_sb->s_op->remount_fs)
289 sops->remount_fs = smfs_sops->remount_fs;
290 //if (cache_sb->s_op->umount_begin)
291 // sops->umount_begin = smfs_sops->umount_begin;
293 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
294 if (cache_sb->s_op->fh_to_dentry)
295 sops->fh_to_dentry = smfs_sops->fh_to_dentry;
296 if (cache_sb->s_op->dentry_to_fh)
297 sops->dentry_to_fh = smfs_sops->dentry_to_fh;
298 if (cache_sb->s_op->show_options)
299 sops->show_options = smfs_sops->show_options;
301 sops->read_inode2 = smfs_sops->read_inode2;
303 /* these ops are needed always */
304 sops->clear_inode = smfs_sops->clear_inode;
305 sops->delete_inode = smfs_sops->delete_inode;
310 smb->smsi_ops_check |= SB_OPS_CHECK;