5 #define DEBUG_SUBSYSTEM S_SM
7 #include <linux/kmod.h>
8 #include <linux/init.h>
10 #include <linux/slab.h>
11 #include <linux/string.h>
12 #include <linux/lustre_idl.h>
13 #include <portals/list.h>
15 #include "smfs_internal.h"
16 struct sm_ops smfs_operations;
18 extern struct inode_operations smfs_file_iops;
19 extern struct file_operations smfs_file_fops;
20 extern struct inode_operations smfs_sym_iops;
21 extern struct file_operations smfs_sym_fops;
22 extern struct super_operations smfs_super_ops;
23 extern struct journal_operations smfs_journal_ops;
26 inline struct super_operations *cache_sops(struct sm_ops *smfs_ops)
28 return &smfs_ops->sm_sb_ops;
31 inline struct inode_operations *cache_diops(struct sm_ops *smfs_ops)
33 return &smfs_ops->sm_dir_iops;
36 inline struct inode_operations *cache_fiops(struct sm_ops *smfs_ops)
38 return &smfs_ops->sm_file_iops;
41 inline struct inode_operations *cache_siops(struct sm_ops *smfs_ops)
43 return &smfs_ops->sm_sym_iops;
46 inline struct file_operations *cache_dfops(struct sm_ops *smfs_ops)
48 return &smfs_ops->sm_dir_fops;
51 inline struct file_operations *cache_ffops(struct sm_ops *smfs_ops)
53 return &smfs_ops->sm_file_fops;
56 inline struct file_operations *cache_sfops(struct sm_ops *smfs_ops)
58 return &smfs_ops->sm_sym_fops;
61 inline struct dentry_operations *cache_dops(struct sm_ops *smfs_ops)
63 return &smfs_ops->sm_dentry_ops;
66 inline struct journal_operations *journal_ops(struct sm_ops *smfs_ops)
68 return &smfs_ops->sm_journal_ops;
71 void init_smfs_cache()
73 memset(&smfs_operations, 0, sizeof(struct sm_ops));
75 void cleanup_smfs_cache()
80 static void setup_iops(struct inode *cache_inode,
81 struct inode_operations *iops,
82 struct inode_operations *cache_iops)
85 if (cache_inode->i_op && cache_iops && iops) {
86 if (cache_inode->i_op->create)
87 iops->create = cache_iops->create;
88 if (cache_inode->i_op->create_it)
89 iops->create_it = cache_iops->create_it;
90 if (cache_inode->i_op->lookup)
91 iops->lookup = cache_iops->lookup;
92 if (cache_inode->i_op->lookup_raw)
93 iops->lookup_raw = cache_iops->lookup_raw;
94 if (cache_inode->i_op->lookup_it)
95 iops->lookup_it = cache_iops->lookup_it;
96 if (cache_inode->i_op->link)
97 iops->link = cache_iops->link;
98 if (cache_inode->i_op->link_raw)
99 iops->link_raw = cache_iops->link_raw;
100 if (cache_inode->i_op->unlink)
101 iops->unlink = cache_iops->unlink;
102 if (cache_inode->i_op->unlink_raw)
103 iops->unlink_raw = cache_iops->unlink_raw;
104 if (cache_inode->i_op->symlink)
105 iops->symlink = cache_iops->symlink;
106 if (cache_inode->i_op->symlink_raw)
107 iops->symlink_raw = cache_iops->symlink_raw;
108 if (cache_inode->i_op->mkdir)
109 iops->mkdir = cache_iops->mkdir;
110 if (cache_inode->i_op->mkdir_raw)
111 iops->mkdir_raw = cache_iops->mkdir_raw;
112 if (cache_inode->i_op->rmdir)
113 iops->rmdir = cache_iops->rmdir;
114 if (cache_inode->i_op->rmdir_raw)
115 iops->rmdir_raw = cache_iops->rmdir_raw;
116 if (cache_inode->i_op->mknod)
117 iops->mknod = cache_iops->mknod;
118 if (cache_inode->i_op->mknod_raw)
119 iops->mknod_raw = cache_iops->mknod_raw;
120 if (cache_inode->i_op->rename)
121 iops->rename = cache_iops->rename;
122 if (cache_inode->i_op->rename_raw)
123 iops->rename_raw = cache_iops->rename_raw;
124 if (cache_inode->i_op->readlink)
125 iops->readlink = cache_iops->readlink;
126 if (cache_inode->i_op->follow_link)
127 iops->follow_link = cache_iops->follow_link;
128 if (cache_inode->i_op->truncate)
129 iops->truncate = cache_iops->truncate;
130 if (cache_inode->i_op->permission)
131 iops->permission = cache_iops->permission;
132 if (cache_inode->i_op->revalidate)
133 iops->revalidate = cache_iops->revalidate;
134 if (cache_inode->i_op->revalidate_it)
135 iops->revalidate_it = cache_iops->revalidate_it;
136 if (cache_inode->i_op->setattr)
137 iops->setattr = cache_iops->setattr;
138 if (cache_inode->i_op->setattr_raw)
139 iops->setattr_raw = cache_iops->setattr_raw;
140 if (cache_inode->i_op->getattr)
141 iops->getattr = cache_iops->getattr;
142 if (cache_inode->i_op->setxattr)
143 iops->setxattr = cache_iops->setxattr;
144 if (cache_inode->i_op->getxattr)
145 iops->getxattr = cache_iops->getxattr;
146 if (cache_inode->i_op->listxattr)
147 iops->listxattr = cache_iops->listxattr;
148 if (cache_inode->i_op->removexattr)
149 iops->removexattr = cache_iops->removexattr;
152 static void setup_fops(struct inode *cache_inode,
153 struct file_operations *fops,
154 struct file_operations *cache_fops)
156 if (cache_inode->i_fop && cache_fops && fops) {
157 if (cache_inode->i_fop->llseek)
158 fops->llseek = cache_fops->llseek;
159 if (cache_inode->i_fop->read)
160 fops->read = cache_fops->read;
161 if (cache_inode->i_fop->write)
162 fops->write = cache_fops->write;
163 if (cache_inode->i_fop->readdir)
164 fops->readdir = cache_fops->readdir;
165 if (cache_inode->i_fop->poll)
166 fops->poll = cache_fops->poll;
167 if (cache_inode->i_fop->ioctl)
168 fops->ioctl = cache_fops->ioctl;
169 if (cache_inode->i_fop->mmap)
170 fops->mmap = cache_fops->mmap;
171 if (cache_inode->i_fop->open)
172 fops->open = cache_fops->open;
173 if (cache_inode->i_fop->flush)
174 fops->flush = cache_fops->flush;
175 if (cache_inode->i_fop->release)
176 fops->release = cache_fops->release;
177 if (cache_inode->i_fop->fsync)
178 fops->fsync = cache_fops->fsync;
179 if (cache_inode->i_fop->fasync)
180 fops->fasync = cache_fops->fasync;
181 if (cache_inode->i_fop->lock)
182 fops->lock = cache_fops->lock;
183 if (cache_inode->i_fop->readv)
184 fops->readv = cache_fops->readv;
185 if (cache_inode->i_fop->writev)
186 fops->writev = cache_fops->writev;
187 if (cache_inode->i_fop->sendpage)
188 fops->sendpage = cache_fops->sendpage;
189 if (cache_inode->i_fop->get_unmapped_area)
190 fops->get_unmapped_area = cache_fops->get_unmapped_area;
193 static void setup_sm_file_ops(struct inode *cache_inode,
195 struct inode_operations *cache_iops,
196 struct file_operations *cache_fops)
198 struct smfs_super_info *smb;
199 struct inode_operations *iops;
200 struct file_operations *fops;
202 smb = S2SMI(inode->i_sb);
204 if (smb->ops_check & FILE_OPS_CHECK)
206 smb->ops_check |= FILE_OPS_CHECK;
208 iops = cache_fiops(&smfs_operations);
209 fops = cache_ffops(&smfs_operations);
211 memset(iops , 0 , sizeof (struct inode_operations));
212 memset(fops , 0 , sizeof (struct file_operations));
214 setup_iops(cache_inode, iops, cache_iops);
215 setup_fops(cache_inode, fops, cache_fops);
220 static void setup_sm_dir_ops(struct inode *cache_inode,
222 struct inode_operations *cache_dir_iops,
223 struct file_operations *cache_dir_fops)
225 struct smfs_super_info *smb;
226 struct inode_operations *iops;
227 struct file_operations *fops;
229 smb = S2SMI(inode->i_sb);
231 if (smb->ops_check & DIR_OPS_CHECK)
233 smb->ops_check |= DIR_OPS_CHECK;
235 iops = cache_diops(&smfs_operations);
236 fops = cache_dfops(&smfs_operations);
238 memset(iops, 0, sizeof (struct inode_operations));
239 memset(fops, 0, sizeof (struct file_operations));
241 setup_iops(cache_inode, iops, cache_dir_iops);
242 setup_fops(cache_inode, fops, cache_dir_fops);
247 static void setup_sm_symlink_ops(struct inode *cache_inode,
249 struct inode_operations *cache_sym_iops,
250 struct file_operations *cache_sym_fops)
252 struct smfs_super_info *smb;
253 struct inode_operations *iops;
254 struct file_operations *fops;
256 smb = S2SMI(inode->i_sb);
258 if (smb->ops_check & SYMLINK_OPS_CHECK)
260 smb->ops_check |= SYMLINK_OPS_CHECK;
262 iops = cache_siops(&smfs_operations);
263 fops = cache_sfops(&smfs_operations);
265 memset(iops , 0 , sizeof (struct inode_operations));
266 memset(fops , 0 , sizeof (struct file_operations));
268 setup_iops(cache_inode, iops, cache_sym_iops);
269 setup_fops(cache_inode, fops, cache_sym_fops);
274 static void setup_sm_sb_ops(struct super_block *cache_sb,
275 struct super_block *sb,
276 struct super_operations *smfs_sops)
278 struct smfs_super_info *smb;
279 struct super_operations *sops;
285 if (smb->ops_check & SB_OPS_CHECK)
287 smb->ops_check |= SB_OPS_CHECK;
288 sops = cache_sops(&smfs_operations);
289 memset(sops, 0, sizeof (struct super_operations));
291 if (cache_sb->s_op) {
292 if (cache_sb->s_op->read_inode)
293 sops->read_inode = smfs_sops->read_inode;
294 if (cache_sb->s_op->read_inode2)
295 sops->read_inode2 = smfs_sops->read_inode2;
296 if (cache_sb->s_op->dirty_inode)
297 sops->dirty_inode = smfs_sops->dirty_inode;
298 if (cache_sb->s_op->write_inode)
299 sops->write_inode = smfs_sops->write_inode;
300 if (cache_sb->s_op->put_inode)
301 sops->put_inode = smfs_sops->put_inode;
302 if (cache_sb->s_op->delete_inode)
303 sops->delete_inode = smfs_sops->delete_inode;
304 if (cache_sb->s_op->put_super)
305 sops->put_super = smfs_sops->put_super;
306 if (cache_sb->s_op->write_super)
307 sops->write_super = smfs_sops->write_super;
308 if (cache_sb->s_op->write_super_lockfs)
309 sops->write_super_lockfs = smfs_sops->write_super_lockfs;
310 if (cache_sb->s_op->unlockfs)
311 sops->unlockfs = smfs_sops->unlockfs;
312 if (cache_sb->s_op->statfs)
313 sops->statfs = smfs_sops->statfs;
314 if (cache_sb->s_op->remount_fs)
315 sops->remount_fs = smfs_sops->remount_fs;
316 if (cache_sb->s_op->umount_begin)
317 sops->umount_begin = smfs_sops->umount_begin;
318 if (cache_sb->s_op->fh_to_dentry)
319 sops->fh_to_dentry = smfs_sops->fh_to_dentry;
320 if (cache_sb->s_op->dentry_to_fh)
321 sops->dentry_to_fh = smfs_sops->dentry_to_fh;
322 if (cache_sb->s_op->show_options)
323 sops->show_options = smfs_sops->show_options;
324 /*FIXME we need this method to clear the cache inode */
325 sops->clear_inode = smfs_sops->clear_inode;
330 void sm_set_inode_ops(struct inode *cache_inode, struct inode *inode)
332 /* XXX now set the correct snap_{file,dir,sym}_iops */
333 if (S_ISDIR(inode->i_mode)) {
334 setup_sm_dir_ops(cache_inode, inode,
337 inode->i_op = cache_diops(&smfs_operations);
338 inode->i_fop = cache_dfops(&smfs_operations);
339 } else if (S_ISREG(inode->i_mode)) {
340 setup_sm_file_ops(cache_inode, inode,
343 CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
344 inode->i_ino, inode->i_op);
345 inode->i_fop = cache_ffops(&smfs_operations);
346 inode->i_op = cache_fiops(&smfs_operations);
348 } else if (S_ISLNK(inode->i_mode)) {
349 setup_sm_symlink_ops(cache_inode, inode,
352 inode->i_op = cache_siops(&smfs_operations);
353 inode->i_fop = cache_sfops(&smfs_operations);
354 CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
355 inode->i_ino, inode->i_op);
358 void sm_set_sb_ops (struct super_block *cache_sb,
359 struct super_block *sb)
361 struct smfs_super_info *smb;
365 setup_sm_sb_ops(cache_sb, sb, &smfs_super_ops);
367 sb->s_op = cache_sops(&smfs_operations);
371 void setup_sm_journal_ops(char *cache_type)
373 struct journal_operations *jops;
375 jops = journal_ops(&smfs_operations);
377 if (strlen(cache_type) == strlen("ext3") &&
378 memcmp(cache_type, "ext3", strlen("ext3")) == 0 ) {
379 #if defined(CONFIG_EXT3_FS) || defined (CONFIG_EXT3_FS_MODULE)
380 memcpy(jops, &smfs_ext3_journal_ops,
381 sizeof(struct journal_operations));
383 memset(jops, 0, sizeof(journal_operations));
385 CDEBUG(D_SUPER, "ops at %p\n", jops);