Whamcloud - gitweb
1. Replace i_mapping with the bottom inode imapping in mmap method according to peter...
[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 <portals/list.h>
13 #include "smfs_internal.h" 
14 struct sm_ops smfs_operations;
15  
16 extern struct inode_operations smfs_file_iops;
17 extern struct file_operations  smfs_file_fops;
18 extern struct inode_operations smfs_sym_iops; 
19 extern struct file_operations smfs_sym_fops;
20 extern struct super_operations smfs_super_ops;
21
22 inline struct super_operations *cache_sops(struct sm_ops *smfs_ops)
23 {
24         return &smfs_ops->sm_sb_ops;
25 }
26
27 inline struct inode_operations *cache_diops(struct sm_ops *smfs_ops)
28 {
29         return &smfs_ops->sm_dir_iops;
30 }
31
32 inline struct inode_operations *cache_fiops(struct sm_ops *smfs_ops)
33 {
34         return &smfs_ops->sm_file_iops;
35 }
36
37 inline struct inode_operations *cache_siops(struct sm_ops *smfs_ops)
38 {
39         return &smfs_ops->sm_sym_iops;
40 }
41
42 inline struct file_operations *cache_dfops(struct sm_ops *smfs_ops) 
43 {
44         return &smfs_ops->sm_dir_fops;
45 }
46
47 inline struct file_operations *cache_ffops(struct sm_ops *smfs_ops)
48 {
49         return &smfs_ops->sm_file_fops;
50 }
51
52 inline struct file_operations *cache_sfops(struct sm_ops *smfs_ops)
53 {
54         return &smfs_ops->sm_sym_fops;
55 }
56
57 inline struct dentry_operations *cache_dops(struct sm_ops *smfs_ops)
58 {
59         return &smfs_ops->sm_dentry_ops;
60 }
61
62 void init_smfs_cache()
63 {
64         memset(&smfs_operations, 0, sizeof(struct sm_ops)); 
65 }
66 void cleanup_smfs_cache()
67 {
68         return;
69 }
70
71 static void setup_iops(struct inode *cache_inode, 
72                        struct inode_operations *iops,
73                        struct inode_operations *cache_iops)
74 {
75
76         if (cache_inode->i_op && cache_iops && iops) {
77                 if (cache_inode->i_op->create) 
78                         iops->create = cache_iops->create;
79                 if (cache_inode->i_op->create_it) 
80                         iops->create_it = cache_iops->create_it;
81                 if (cache_inode->i_op->lookup)
82                         iops->lookup = cache_iops->lookup;
83                 if (cache_inode->i_op->lookup_raw)
84                         iops->lookup_raw = cache_iops->lookup_raw;
85                 if (cache_inode->i_op->lookup_it)
86                         iops->lookup_it = cache_iops->lookup_it;
87                 if (cache_inode->i_op->link)
88                         iops->link = cache_iops->link;
89                 if (cache_inode->i_op->link_raw)
90                         iops->link_raw = cache_iops->link_raw;
91                 if (cache_inode->i_op->unlink)
92                         iops->unlink = cache_iops->unlink;
93                 if (cache_inode->i_op->unlink_raw)
94                         iops->unlink_raw = cache_iops->unlink_raw;
95                 if (cache_inode->i_op->symlink)
96                         iops->symlink = cache_iops->symlink;
97                 if (cache_inode->i_op->symlink_raw)
98                         iops->symlink_raw = cache_iops->symlink_raw;
99                 if (cache_inode->i_op->mkdir)
100                         iops->mkdir = cache_iops->mkdir;
101                 if (cache_inode->i_op->mkdir_raw)
102                         iops->mkdir_raw = cache_iops->mkdir_raw;
103                 if (cache_inode->i_op->rmdir)
104                         iops->rmdir = cache_iops->rmdir;
105                 if (cache_inode->i_op->rmdir_raw)
106                         iops->rmdir_raw = cache_iops->rmdir_raw;
107                 if (cache_inode->i_op->mknod)
108                         iops->mknod = cache_iops->mknod;
109                 if (cache_inode->i_op->mknod_raw)
110                         iops->mknod_raw = cache_iops->mknod_raw;
111                 if (cache_inode->i_op->rename)
112                         iops->rename = cache_iops->rename;
113                 if (cache_inode->i_op->rename_raw)
114                         iops->rename_raw = cache_iops->rename_raw;
115                 if (cache_inode->i_op->readlink)
116                         iops->readlink = cache_iops->readlink;
117                 if (cache_inode->i_op->follow_link)
118                         iops->follow_link = cache_iops->follow_link;
119                 if (cache_inode->i_op->truncate)
120                         iops->truncate = cache_iops->truncate;
121                 if (cache_inode->i_op->permission)
122                         iops->permission = cache_iops->permission;
123                 if (cache_inode->i_op->revalidate)
124                         iops->revalidate = cache_iops->revalidate;
125                 if (cache_inode->i_op->revalidate_it)
126                         iops->revalidate_it = cache_iops->revalidate_it;
127                 if (cache_inode->i_op->setattr)
128                         iops->setattr = cache_iops->setattr;
129                 if (cache_inode->i_op->setattr_raw)
130                         iops->setattr_raw = cache_iops->setattr_raw;
131                 if (cache_inode->i_op->getattr)
132                         iops->getattr = cache_iops->getattr;
133                 if (cache_inode->i_op->setxattr)
134                         iops->setxattr = cache_iops->setxattr;
135                 if (cache_inode->i_op->getxattr)
136                         iops->getxattr = cache_iops->getxattr;
137                 if (cache_inode->i_op->listxattr)
138                         iops->listxattr = cache_iops->listxattr;
139                 if (cache_inode->i_op->removexattr)
140                         iops->removexattr = cache_iops->removexattr;
141         }
142 }
143 static void setup_fops(struct inode *cache_inode,
144                        struct file_operations *fops,
145                        struct file_operations *cache_fops)
146 {
147         if (cache_inode->i_fop && cache_fops && fops) {
148                 if (cache_inode->i_fop->llseek)
149                         fops->llseek = cache_fops->llseek;
150                 if (cache_inode->i_fop->read)
151                         fops->read = cache_fops->read;
152                 if (cache_inode->i_fop->write)
153                         fops->write = cache_fops->write;
154                 if (cache_inode->i_fop->readdir)
155                         fops->readdir = cache_fops->readdir;
156                 if (cache_inode->i_fop->poll)
157                         fops->poll = cache_fops->poll;
158                 if (cache_inode->i_fop->ioctl)
159                         fops->ioctl = cache_fops->ioctl;
160                 if (cache_inode->i_fop->mmap)
161                         fops->mmap = cache_fops->mmap;
162                 if (cache_inode->i_fop->open)
163                         fops->open = cache_fops->open;
164                 if (cache_inode->i_fop->flush)
165                         fops->flush = cache_fops->flush;
166                 if (cache_inode->i_fop->release)
167                         fops->release = cache_fops->release;
168                 if (cache_inode->i_fop->fsync)
169                         fops->fsync = cache_fops->fsync;
170                 if (cache_inode->i_fop->fasync)
171                         fops->fasync = cache_fops->fasync;
172                 if (cache_inode->i_fop->lock)
173                         fops->lock = cache_fops->lock;
174                 if (cache_inode->i_fop->readv)
175                         fops->readv = cache_fops->readv;
176                 if (cache_inode->i_fop->writev)
177                         fops->writev = cache_fops->writev;
178                 if (cache_inode->i_fop->sendpage)
179                         fops->sendpage = cache_fops->sendpage;
180                 if (cache_inode->i_fop->get_unmapped_area)
181                         fops->get_unmapped_area = cache_fops->get_unmapped_area;                                                                                        
182         }
183 }
184 static void setup_sm_file_ops(struct inode *cache_inode, 
185                               struct inode *inode,
186                               struct inode_operations *cache_iops,
187                               struct file_operations *cache_fops)
188 {
189         struct smfs_super_info *smb;
190         struct inode_operations *iops;
191         struct file_operations *fops;
192
193         smb = S2SMI(inode->i_sb); 
194         
195         if (smb->ops_check & FILE_OPS_CHECK) 
196                 return; 
197         smb->ops_check |= FILE_OPS_CHECK;
198
199         iops = cache_fiops(&smfs_operations);
200         fops = cache_ffops(&smfs_operations);
201
202         memset(iops , 0 , sizeof (struct inode_operations));    
203         memset(fops , 0 , sizeof (struct file_operations));     
204
205         setup_iops(cache_inode, iops, cache_iops);      
206         setup_fops(cache_inode, fops, cache_fops);
207
208         return;
209 }
210
211 static void setup_sm_dir_ops(struct inode *cache_inode, 
212                              struct  inode *inode,
213                              struct inode_operations *cache_dir_iops,
214                              struct file_operations *cache_dir_fops)
215 {
216         struct smfs_super_info *smb;
217         struct inode_operations *iops;
218         struct file_operations *fops;
219
220         smb = S2SMI(inode->i_sb); 
221         
222         if (smb->ops_check & DIR_OPS_CHECK) 
223                 return; 
224         smb->ops_check |= DIR_OPS_CHECK;
225
226         iops = cache_diops(&smfs_operations);
227         fops = cache_dfops(&smfs_operations);
228
229         memset(iops, 0, sizeof (struct inode_operations));      
230         memset(fops, 0, sizeof (struct file_operations));       
231
232         setup_iops(cache_inode, iops, cache_dir_iops);  
233         setup_fops(cache_inode, fops, cache_dir_fops);
234
235         return;
236 }
237
238 static void setup_sm_symlink_ops(struct inode *cache_inode, 
239                                  struct  inode *inode,
240                                  struct inode_operations *cache_sym_iops,
241                                  struct file_operations *cache_sym_fops)
242 {
243         struct smfs_super_info *smb;
244         struct inode_operations *iops;
245         struct file_operations *fops;
246
247         smb = S2SMI(inode->i_sb); 
248         
249         if (smb->ops_check & SYMLINK_OPS_CHECK) 
250                 return; 
251         smb->ops_check |= SYMLINK_OPS_CHECK;
252
253         iops = cache_siops(&smfs_operations);
254         fops = cache_sfops(&smfs_operations);
255
256         memset(iops , 0 , sizeof (struct inode_operations));    
257         memset(fops , 0 , sizeof (struct file_operations));     
258
259         setup_iops(cache_inode, iops, cache_sym_iops);  
260         setup_fops(cache_inode, fops, cache_sym_fops);
261
262         return;
263 }
264
265 static void setup_sm_sb_ops(struct super_block *cache_sb, 
266                             struct super_block *sb, 
267                             struct super_operations *smfs_sops) 
268 {
269         struct smfs_super_info *smb;
270         struct super_operations *sops;
271
272         ENTRY;
273
274         smb = S2SMI(sb); 
275         
276         if (smb->ops_check & SB_OPS_CHECK) 
277                 return; 
278         smb->ops_check |= SB_OPS_CHECK;
279         sops = cache_sops(&smfs_operations);
280         memset(sops, 0, sizeof (struct super_operations));      
281
282         if (cache_sb->s_op) {
283                 if (cache_sb->s_op->read_inode) 
284                         sops->read_inode = smfs_sops->read_inode;
285                 if (cache_sb->s_op->read_inode2)
286                         sops->read_inode2 = smfs_sops->read_inode2;
287                 if (cache_sb->s_op->dirty_inode)
288                         sops->dirty_inode = smfs_sops->dirty_inode;
289                 if (cache_sb->s_op->write_inode)
290                         sops->write_inode = smfs_sops->write_inode;
291                 if (cache_sb->s_op->put_inode)
292                         sops->put_inode = smfs_sops->put_inode;
293                 if (cache_sb->s_op->delete_inode)
294                         sops->delete_inode = smfs_sops->delete_inode;
295                 if (cache_sb->s_op->put_super)
296                         sops->put_super = smfs_sops->put_super;
297                 if (cache_sb->s_op->write_super)
298                         sops->write_super = smfs_sops->write_super;
299                 if (cache_sb->s_op->write_super_lockfs)
300                         sops->write_super_lockfs = smfs_sops->write_super_lockfs;
301                 if (cache_sb->s_op->unlockfs)
302                         sops->unlockfs = smfs_sops->unlockfs;
303                 if (cache_sb->s_op->statfs)
304                         sops->statfs = smfs_sops->statfs;
305                 if (cache_sb->s_op->remount_fs)
306                         sops->remount_fs = smfs_sops->remount_fs;
307                 if (cache_sb->s_op->umount_begin)
308                         sops->umount_begin = smfs_sops->umount_begin;
309                 if (cache_sb->s_op->fh_to_dentry)
310                         sops->fh_to_dentry = smfs_sops->fh_to_dentry;
311                 if (cache_sb->s_op->dentry_to_fh)
312                         sops->dentry_to_fh = smfs_sops->dentry_to_fh;
313                 if (cache_sb->s_op->show_options)
314                         sops->show_options = smfs_sops->show_options;
315                 /*FIXME we need this method to clear the cache inode */
316                 sops->clear_inode = smfs_sops->clear_inode;
317         }
318                                         
319         return;
320 }       
321 void sm_set_inode_ops(struct inode *cache_inode, struct inode *inode)
322 {
323         /* XXX now set the correct snap_{file,dir,sym}_iops */
324         if (S_ISDIR(inode->i_mode)) {
325                 setup_sm_dir_ops(cache_inode, inode,
326                                  &smfs_dir_iops,
327                                  &smfs_dir_fops);
328                 inode->i_op = cache_diops(&smfs_operations);
329                 inode->i_fop = cache_dfops(&smfs_operations);
330         } else if (S_ISREG(inode->i_mode)) {
331                 setup_sm_file_ops(cache_inode, inode,
332                                   &smfs_file_iops,
333                                   &smfs_file_fops);
334                 CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
335                        inode->i_ino, inode->i_op);
336                 inode->i_fop = cache_ffops(&smfs_operations);
337                 inode->i_op = cache_fiops(&smfs_operations);
338         
339         } else if (S_ISLNK(inode->i_mode)) {
340                 setup_sm_symlink_ops(cache_inode, inode,
341                                      &smfs_sym_iops, 
342                                      &smfs_sym_fops);
343                 inode->i_op = cache_siops(&smfs_operations);
344                 inode->i_fop = cache_sfops(&smfs_operations);
345                 CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
346                        inode->i_ino, inode->i_op);
347         }
348 }
349 void sm_set_sb_ops (struct super_block *cache_sb,
350                       struct super_block *sb)
351 {
352         struct smfs_super_info *smb;
353
354         smb = S2SMI(sb); 
355         
356         setup_sm_sb_ops(cache_sb, sb, &smfs_super_ops); 
357         
358         sb->s_op = cache_sops(&smfs_operations);
359         return; 
360 }
361