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 <portals/list.h>
13 #include "smfs_internal.h"
14 struct sm_ops smfs_operations;
16 extern struct inode_operations smfs_file_iops;
17 extern struct file_operations smfs_file_fops;
18 extern struct address_space_operations smfs_file_aops;
19 extern struct inode_operations smfs_sym_iops;
20 extern struct file_operations smfs_sym_fops;
21 extern struct super_operations smfs_super_ops;
23 inline struct super_operations *cache_sops(struct sm_ops *smfs_ops)
25 return &smfs_ops->sm_sb_ops;
28 inline struct inode_operations *cache_diops(struct sm_ops *smfs_ops)
30 return &smfs_ops->sm_dir_iops;
33 inline struct inode_operations *cache_fiops(struct sm_ops *smfs_ops)
35 return &smfs_ops->sm_file_iops;
38 inline struct inode_operations *cache_siops(struct sm_ops *smfs_ops)
40 return &smfs_ops->sm_sym_iops;
43 inline struct file_operations *cache_dfops(struct sm_ops *smfs_ops)
45 return &smfs_ops->sm_dir_fops;
48 inline struct file_operations *cache_ffops(struct sm_ops *smfs_ops)
50 return &smfs_ops->sm_file_fops;
53 inline struct address_space_operations *cache_faops(struct sm_ops *smfs_ops)
55 return &smfs_ops->sm_file_aops;
58 inline struct file_operations *cache_sfops(struct sm_ops *smfs_ops)
60 return &smfs_ops->sm_sym_fops;
63 inline struct dentry_operations *cache_dops(struct sm_ops *smfs_ops)
65 return &smfs_ops->sm_dentry_ops;
68 void init_smfs_cache()
70 memset(&smfs_operations, 0, sizeof(struct sm_ops));
72 void cleanup_smfs_cache()
77 static void setup_iops(struct inode *cache_inode,
78 struct inode_operations *iops,
79 struct inode_operations *cache_iops)
82 if (cache_inode->i_op && cache_iops && iops) {
83 if (cache_inode->i_op->create)
84 iops->create = cache_iops->create;
85 if (cache_inode->i_op->create_it)
86 iops->create_it = cache_iops->create_it;
87 if (cache_inode->i_op->lookup)
88 iops->lookup = cache_iops->lookup;
89 if (cache_inode->i_op->lookup_raw)
90 iops->lookup_raw = cache_iops->lookup_raw;
91 if (cache_inode->i_op->lookup_it)
92 iops->lookup_it = cache_iops->lookup_it;
93 if (cache_inode->i_op->link)
94 iops->link = cache_iops->link;
95 if (cache_inode->i_op->link_raw)
96 iops->link_raw = cache_iops->link_raw;
97 if (cache_inode->i_op->unlink)
98 iops->unlink = cache_iops->unlink;
99 if (cache_inode->i_op->unlink_raw)
100 iops->unlink_raw = cache_iops->unlink_raw;
101 if (cache_inode->i_op->symlink)
102 iops->symlink = cache_iops->symlink;
103 if (cache_inode->i_op->symlink_raw)
104 iops->symlink_raw = cache_iops->symlink_raw;
105 if (cache_inode->i_op->mkdir)
106 iops->mkdir = cache_iops->mkdir;
107 if (cache_inode->i_op->mkdir_raw)
108 iops->mkdir_raw = cache_iops->mkdir_raw;
109 if (cache_inode->i_op->rmdir)
110 iops->rmdir = cache_iops->rmdir;
111 if (cache_inode->i_op->rmdir_raw)
112 iops->rmdir_raw = cache_iops->rmdir_raw;
113 if (cache_inode->i_op->mknod)
114 iops->mknod = cache_iops->mknod;
115 if (cache_inode->i_op->mknod_raw)
116 iops->mknod_raw = cache_iops->mknod_raw;
117 if (cache_inode->i_op->rename)
118 iops->rename = cache_iops->rename;
119 if (cache_inode->i_op->rename_raw)
120 iops->rename_raw = cache_iops->rename_raw;
121 if (cache_inode->i_op->readlink)
122 iops->readlink = cache_iops->readlink;
123 if (cache_inode->i_op->follow_link)
124 iops->follow_link = cache_iops->follow_link;
125 if (cache_inode->i_op->truncate)
126 iops->truncate = cache_iops->truncate;
127 if (cache_inode->i_op->permission)
128 iops->permission = cache_iops->permission;
129 if (cache_inode->i_op->revalidate)
130 iops->revalidate = cache_iops->revalidate;
131 if (cache_inode->i_op->revalidate_it)
132 iops->revalidate_it = cache_iops->revalidate_it;
133 if (cache_inode->i_op->setattr)
134 iops->setattr = cache_iops->setattr;
135 if (cache_inode->i_op->setattr_raw)
136 iops->setattr_raw = cache_iops->setattr_raw;
137 if (cache_inode->i_op->getattr)
138 iops->getattr = cache_iops->getattr;
139 if (cache_inode->i_op->setxattr)
140 iops->setxattr = cache_iops->setxattr;
141 if (cache_inode->i_op->getxattr)
142 iops->getxattr = cache_iops->getxattr;
143 if (cache_inode->i_op->listxattr)
144 iops->listxattr = cache_iops->listxattr;
145 if (cache_inode->i_op->removexattr)
146 iops->removexattr = cache_iops->removexattr;
149 static void setup_fops(struct inode *cache_inode,
150 struct file_operations *fops,
151 struct file_operations *cache_fops)
153 if (cache_inode->i_fop && cache_fops && fops) {
154 if (cache_inode->i_fop->llseek)
155 fops->llseek = cache_fops->llseek;
156 if (cache_inode->i_fop->read)
157 fops->read = cache_fops->read;
158 if (cache_inode->i_fop->write)
159 fops->write = cache_fops->write;
160 if (cache_inode->i_fop->readdir)
161 fops->readdir = cache_fops->readdir;
162 if (cache_inode->i_fop->poll)
163 fops->poll = cache_fops->poll;
164 if (cache_inode->i_fop->ioctl)
165 fops->ioctl = cache_fops->ioctl;
166 if (cache_inode->i_fop->mmap)
167 fops->mmap = cache_fops->mmap;
168 if (cache_inode->i_fop->open)
169 fops->open = cache_fops->open;
170 if (cache_inode->i_fop->flush)
171 fops->flush = cache_fops->flush;
172 if (cache_inode->i_fop->release)
173 fops->release = cache_fops->release;
174 if (cache_inode->i_fop->fsync)
175 fops->fsync = cache_fops->fsync;
176 if (cache_inode->i_fop->fasync)
177 fops->fasync = cache_fops->fasync;
178 if (cache_inode->i_fop->lock)
179 fops->lock = cache_fops->lock;
180 if (cache_inode->i_fop->readv)
181 fops->readv = cache_fops->readv;
182 if (cache_inode->i_fop->writev)
183 fops->writev = cache_fops->writev;
184 if (cache_inode->i_fop->sendpage)
185 fops->sendpage = cache_fops->sendpage;
186 if (cache_inode->i_fop->get_unmapped_area)
187 fops->get_unmapped_area = cache_fops->get_unmapped_area;
190 static void setup_aops(struct inode *cache_inode,
191 struct address_space_operations *aops,
192 struct address_space_operations *cache_aops)
194 if (cache_inode && cache_inode->i_mapping &&
195 aops && cache_aops) {
196 struct address_space_operations *caops = cache_inode->i_mapping->a_ops;
198 if (caops->writepage)
199 aops->writepage = cache_aops->writepage;
201 aops->readpage = cache_aops->readpage;
202 if (caops->sync_page)
203 aops->sync_page = cache_aops->sync_page;
204 if (caops->prepare_write)
205 aops->prepare_write = cache_aops->prepare_write;
206 if (caops->commit_write)
207 aops->commit_write = cache_aops->commit_write;
209 aops->bmap = cache_aops->bmap;
210 if (caops->flushpage)
211 aops->flushpage = cache_aops->flushpage;
212 if (caops->releasepage)
213 aops->releasepage = cache_aops->releasepage;
214 if (caops->direct_IO)
215 aops->direct_IO = cache_aops->direct_IO;
216 if (caops->removepage)
217 aops->removepage = cache_aops->removepage;
221 static void setup_sm_file_ops(struct inode *cache_inode,
223 struct inode_operations *cache_iops,
224 struct file_operations *cache_fops,
225 struct address_space_operations *cache_aops)
227 struct smfs_super_info *smb;
228 struct inode_operations *iops;
229 struct file_operations *fops;
230 struct address_space_operations *aops;
232 smb = S2SMI(inode->i_sb);
234 if (smb->ops_check & FILE_OPS_CHECK)
236 smb->ops_check |= FILE_OPS_CHECK;
238 iops = cache_fiops(&smfs_operations);
239 fops = cache_ffops(&smfs_operations);
240 aops = cache_faops(&smfs_operations);
242 memset(iops , 0 , sizeof (struct inode_operations));
243 memset(fops , 0 , sizeof (struct file_operations));
244 memset(aops , 0 , sizeof (struct address_space_operations));
246 setup_iops(cache_inode, iops, cache_iops);
247 setup_fops(cache_inode, fops, cache_fops);
248 setup_aops(cache_inode, aops, cache_aops);
253 static void setup_sm_dir_ops(struct inode *cache_inode,
255 struct inode_operations *cache_dir_iops,
256 struct file_operations *cache_dir_fops)
258 struct smfs_super_info *smb;
259 struct inode_operations *iops;
260 struct file_operations *fops;
262 smb = S2SMI(inode->i_sb);
264 if (smb->ops_check & DIR_OPS_CHECK)
266 smb->ops_check |= DIR_OPS_CHECK;
268 iops = cache_diops(&smfs_operations);
269 fops = cache_dfops(&smfs_operations);
271 memset(iops, 0, sizeof (struct inode_operations));
272 memset(fops, 0, sizeof (struct file_operations));
274 setup_iops(cache_inode, iops, cache_dir_iops);
275 setup_fops(cache_inode, fops, cache_dir_fops);
280 static void setup_sm_symlink_ops(struct inode *cache_inode,
282 struct inode_operations *cache_sym_iops,
283 struct file_operations *cache_sym_fops)
285 struct smfs_super_info *smb;
286 struct inode_operations *iops;
287 struct file_operations *fops;
289 smb = S2SMI(inode->i_sb);
291 if (smb->ops_check & SYMLINK_OPS_CHECK)
293 smb->ops_check |= SYMLINK_OPS_CHECK;
295 iops = cache_siops(&smfs_operations);
296 fops = cache_sfops(&smfs_operations);
298 memset(iops , 0 , sizeof (struct inode_operations));
299 memset(fops , 0 , sizeof (struct file_operations));
301 setup_iops(cache_inode, iops, cache_sym_iops);
302 setup_fops(cache_inode, fops, cache_sym_fops);
307 static void setup_sm_sb_ops(struct super_block *cache_sb,
308 struct super_block *sb,
309 struct super_operations *smfs_sops)
311 struct smfs_super_info *smb;
312 struct super_operations *sops;
318 if (smb->ops_check & SB_OPS_CHECK)
320 smb->ops_check |= SB_OPS_CHECK;
321 sops = cache_sops(&smfs_operations);
322 memset(sops, 0, sizeof (struct super_operations));
324 if (cache_sb->s_op) {
325 if (cache_sb->s_op->read_inode)
326 sops->read_inode = smfs_sops->read_inode;
327 if (cache_sb->s_op->read_inode2)
328 sops->read_inode2 = smfs_sops->read_inode2;
329 if (cache_sb->s_op->dirty_inode)
330 sops->dirty_inode = smfs_sops->dirty_inode;
331 if (cache_sb->s_op->write_inode)
332 sops->write_inode = smfs_sops->write_inode;
333 if (cache_sb->s_op->put_inode)
334 sops->put_inode = smfs_sops->put_inode;
335 if (cache_sb->s_op->delete_inode)
336 sops->delete_inode = smfs_sops->delete_inode;
337 if (cache_sb->s_op->put_super)
338 sops->put_super = smfs_sops->put_super;
339 if (cache_sb->s_op->write_super)
340 sops->write_super = smfs_sops->write_super;
341 if (cache_sb->s_op->write_super_lockfs)
342 sops->write_super_lockfs = smfs_sops->write_super_lockfs;
343 if (cache_sb->s_op->unlockfs)
344 sops->unlockfs = smfs_sops->unlockfs;
345 if (cache_sb->s_op->statfs)
346 sops->statfs = smfs_sops->statfs;
347 if (cache_sb->s_op->remount_fs)
348 sops->remount_fs = smfs_sops->remount_fs;
349 if (cache_sb->s_op->umount_begin)
350 sops->umount_begin = smfs_sops->umount_begin;
351 if (cache_sb->s_op->fh_to_dentry)
352 sops->fh_to_dentry = smfs_sops->fh_to_dentry;
353 if (cache_sb->s_op->dentry_to_fh)
354 sops->dentry_to_fh = smfs_sops->dentry_to_fh;
355 if (cache_sb->s_op->show_options)
356 sops->show_options = smfs_sops->show_options;
357 /*FIXME we need this method to clear the cache inode */
358 sops->clear_inode = smfs_sops->clear_inode;
363 void sm_set_inode_ops(struct inode *cache_inode, struct inode *inode)
365 /* XXX now set the correct snap_{file,dir,sym}_iops */
366 if (S_ISDIR(inode->i_mode)) {
367 setup_sm_dir_ops(cache_inode, inode,
370 inode->i_op = cache_diops(&smfs_operations);
371 inode->i_fop = cache_dfops(&smfs_operations);
372 } else if (S_ISREG(inode->i_mode)) {
373 setup_sm_file_ops(cache_inode, inode,
377 CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
378 inode->i_ino, inode->i_op);
379 inode->i_fop = cache_ffops(&smfs_operations);
380 inode->i_op = cache_fiops(&smfs_operations);
381 if (inode->i_mapping)
382 inode->i_mapping->a_ops = cache_faops(&smfs_operations);
384 } else if (S_ISLNK(inode->i_mode)) {
385 setup_sm_symlink_ops(cache_inode, inode,
388 inode->i_op = cache_siops(&smfs_operations);
389 inode->i_fop = cache_sfops(&smfs_operations);
390 CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
391 inode->i_ino, inode->i_op);
394 void sm_set_sb_ops (struct super_block *cache_sb,
395 struct super_block *sb)
397 struct smfs_super_info *smb;
401 setup_sm_sb_ops(cache_sb, sb, &smfs_super_ops);
403 sb->s_op = cache_sops(&smfs_operations);