Whamcloud - gitweb
smash the HEAD with the contents of b_cmd. HEAD_PRE_CMD_SMASH and
[fs/lustre-release.git] / lustre / smfs / cache.c
1 /*  
2  *  snapfs/cache.c
3  */
4
5 #define DEBUG_SUBSYSTEM S_SM
6
7 #include <linux/kmod.h>
8 #include <linux/init.h>
9 #include <linux/fs.h>
10 #include <linux/slab.h>
11 #include <linux/string.h>
12 #include <linux/lustre_idl.h>
13 #include <portals/list.h>
14
15 #include "smfs_internal.h" 
16 struct sm_ops smfs_operations;
17  
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;
24
25
26 inline struct super_operations *cache_sops(struct sm_ops *smfs_ops)
27 {
28         return &smfs_ops->sm_sb_ops;
29 }
30
31 inline struct inode_operations *cache_diops(struct sm_ops *smfs_ops)
32 {
33         return &smfs_ops->sm_dir_iops;
34 }
35
36 inline struct inode_operations *cache_fiops(struct sm_ops *smfs_ops)
37 {
38         return &smfs_ops->sm_file_iops;
39 }
40
41 inline struct inode_operations *cache_siops(struct sm_ops *smfs_ops)
42 {
43         return &smfs_ops->sm_sym_iops;
44 }
45
46 inline struct file_operations *cache_dfops(struct sm_ops *smfs_ops) 
47 {
48         return &smfs_ops->sm_dir_fops;
49 }
50
51 inline struct file_operations *cache_ffops(struct sm_ops *smfs_ops)
52 {
53         return &smfs_ops->sm_file_fops;
54 }
55
56 inline struct file_operations *cache_sfops(struct sm_ops *smfs_ops)
57 {
58         return &smfs_ops->sm_sym_fops;
59 }
60
61 inline struct dentry_operations *cache_dops(struct sm_ops *smfs_ops)
62 {
63         return &smfs_ops->sm_dentry_ops;
64 }
65
66 inline struct journal_operations *journal_ops(struct sm_ops *smfs_ops)
67 {
68         return &smfs_ops->sm_journal_ops;
69 }
70
71 void init_smfs_cache()
72 {
73         memset(&smfs_operations, 0, sizeof(struct sm_ops)); 
74 }
75 void cleanup_smfs_cache()
76 {
77         return;
78 }
79
80 static void setup_iops(struct inode *cache_inode, 
81                        struct inode_operations *iops,
82                        struct inode_operations *cache_iops)
83 {
84
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;
150         }
151 }
152 static void setup_fops(struct inode *cache_inode,
153                        struct file_operations *fops,
154                        struct file_operations *cache_fops)
155 {
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;                                                                                        
191         }
192 }
193 static void setup_sm_file_ops(struct inode *cache_inode, 
194                               struct inode *inode,
195                               struct inode_operations *cache_iops,
196                               struct file_operations *cache_fops)
197 {
198         struct smfs_super_info *smb;
199         struct inode_operations *iops;
200         struct file_operations *fops;
201
202         smb = S2SMI(inode->i_sb); 
203         
204         if (smb->ops_check & FILE_OPS_CHECK) 
205                 return; 
206         smb->ops_check |= FILE_OPS_CHECK;
207
208         iops = cache_fiops(&smfs_operations);
209         fops = cache_ffops(&smfs_operations);
210
211         memset(iops , 0 , sizeof (struct inode_operations));    
212         memset(fops , 0 , sizeof (struct file_operations));     
213
214         setup_iops(cache_inode, iops, cache_iops);      
215         setup_fops(cache_inode, fops, cache_fops);
216
217         return;
218 }
219
220 static void setup_sm_dir_ops(struct inode *cache_inode, 
221                              struct  inode *inode,
222                              struct inode_operations *cache_dir_iops,
223                              struct file_operations *cache_dir_fops)
224 {
225         struct smfs_super_info *smb;
226         struct inode_operations *iops;
227         struct file_operations *fops;
228
229         smb = S2SMI(inode->i_sb); 
230         
231         if (smb->ops_check & DIR_OPS_CHECK) 
232                 return; 
233         smb->ops_check |= DIR_OPS_CHECK;
234
235         iops = cache_diops(&smfs_operations);
236         fops = cache_dfops(&smfs_operations);
237
238         memset(iops, 0, sizeof (struct inode_operations));      
239         memset(fops, 0, sizeof (struct file_operations));       
240
241         setup_iops(cache_inode, iops, cache_dir_iops);  
242         setup_fops(cache_inode, fops, cache_dir_fops);
243
244         return;
245 }
246
247 static void setup_sm_symlink_ops(struct inode *cache_inode, 
248                                  struct  inode *inode,
249                                  struct inode_operations *cache_sym_iops,
250                                  struct file_operations *cache_sym_fops)
251 {
252         struct smfs_super_info *smb;
253         struct inode_operations *iops;
254         struct file_operations *fops;
255
256         smb = S2SMI(inode->i_sb); 
257         
258         if (smb->ops_check & SYMLINK_OPS_CHECK) 
259                 return; 
260         smb->ops_check |= SYMLINK_OPS_CHECK;
261
262         iops = cache_siops(&smfs_operations);
263         fops = cache_sfops(&smfs_operations);
264
265         memset(iops , 0 , sizeof (struct inode_operations));    
266         memset(fops , 0 , sizeof (struct file_operations));     
267
268         setup_iops(cache_inode, iops, cache_sym_iops);  
269         setup_fops(cache_inode, fops, cache_sym_fops);
270
271         return;
272 }
273
274 static void setup_sm_sb_ops(struct super_block *cache_sb, 
275                             struct super_block *sb, 
276                             struct super_operations *smfs_sops) 
277 {
278         struct smfs_super_info *smb;
279         struct super_operations *sops;
280
281         ENTRY;
282
283         smb = S2SMI(sb); 
284         
285         if (smb->ops_check & SB_OPS_CHECK) 
286                 return; 
287         smb->ops_check |= SB_OPS_CHECK;
288         sops = cache_sops(&smfs_operations);
289         memset(sops, 0, sizeof (struct super_operations));      
290
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;
326         }
327                                         
328         return;
329 }       
330 void sm_set_inode_ops(struct inode *cache_inode, struct inode *inode)
331 {
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,
335                                  &smfs_dir_iops,
336                                  &smfs_dir_fops);
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,
341                                   &smfs_file_iops,
342                                   &smfs_file_fops);
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);
347         
348         } else if (S_ISLNK(inode->i_mode)) {
349                 setup_sm_symlink_ops(cache_inode, inode,
350                                      &smfs_sym_iops, 
351                                      &smfs_sym_fops);
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);
356         }
357 }
358 void sm_set_sb_ops (struct super_block *cache_sb,
359                       struct super_block *sb)
360 {
361         struct smfs_super_info *smb;
362
363         smb = S2SMI(sb); 
364         
365         setup_sm_sb_ops(cache_sb, sb, &smfs_super_ops); 
366         
367         sb->s_op = cache_sops(&smfs_operations);
368         return; 
369 }
370
371 void setup_sm_journal_ops(char *cache_type)
372 {
373         struct journal_operations *jops;
374
375         jops = journal_ops(&smfs_operations); 
376         
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)); 
382 #else
383                 memset(jops, 0, sizeof(journal_operations));
384 #endif
385                 CDEBUG(D_SUPER, "ops at %p\n", jops);
386         }
387 }
388