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;
22 inline struct super_operations *cache_sops(struct sm_ops *smfs_ops)
24 return &smfs_ops->sm_sb_ops;
27 inline struct inode_operations *cache_diops(struct sm_ops *smfs_ops)
29 return &smfs_ops->sm_dir_iops;
32 inline struct inode_operations *cache_fiops(struct sm_ops *smfs_ops)
34 return &smfs_ops->sm_file_iops;
37 inline struct inode_operations *cache_siops(struct sm_ops *smfs_ops)
39 return &smfs_ops->sm_sym_iops;
42 inline struct file_operations *cache_dfops(struct sm_ops *smfs_ops)
44 return &smfs_ops->sm_dir_fops;
47 inline struct file_operations *cache_ffops(struct sm_ops *smfs_ops)
49 return &smfs_ops->sm_file_fops;
52 inline struct address_space_operations *cache_faops(struct sm_ops *smfs_ops)
54 return &smfs_ops->sm_file_aops;
57 inline struct file_operations *cache_sfops(struct sm_ops *smfs_ops)
59 return &smfs_ops->sm_sym_fops;
62 inline struct dentry_operations *cache_dops(struct sm_ops *smfs_ops)
64 return &smfs_ops->sm_dentry_ops;
67 void init_smfs_cache()
69 memset(&smfs_operations, 0, sizeof(struct sm_ops));
71 void cleanup_smfs_cache()
76 static void setup_sm_symlink_ops(struct inode *cache_inode,
78 struct inode_operations *cache_sym_iops,
79 struct file_operations *cache_sym_fops)
84 static void setup_sm_file_ops(struct inode *cache_inode,
86 struct inode_operations *cache_iops,
87 struct file_operations *cache_fops,
88 struct address_space_operations *cache_aops)
91 struct smfs_super_info *smb;
92 struct inode_operations *iops;
93 struct file_operations *fops;
94 struct address_space_operations *aops;
96 smb = S2SMI(inode->i_sb);
98 if (smb->ops_check & FILE_OPS_CHECK)
100 smb->ops_check |= FILE_OPS_CHECK;
102 iops = cache_fiops(&smfs_operations);
103 fops = cache_ffops(&smfs_operations);
104 aops = cache_faops(&smfs_operations);
106 memset(iops , 0 , sizeof (struct inode_operations));
107 memset(fops , 0 , sizeof (struct file_operations));
108 memset(aops , 0 , sizeof (struct address_space_operations));
110 if (cache_inode->i_op) {
111 if (cache_inode->i_op->create)
112 iops->create = cache_iops->create;
113 if (cache_inode->i_op->create_it)
114 iops->create_it = cache_iops->create_it;
115 if (cache_inode->i_op->lookup)
116 iops->lookup = cache_iops->lookup;
117 if (cache_inode->i_op->lookup_raw)
118 iops->lookup_raw = cache_iops->lookup_raw;
119 if (cache_inode->i_op->lookup_it)
120 iops->lookup_it = cache_iops->lookup_it;
121 if (cache_inode->i_op->link)
122 iops->link = cache_iops->link;
123 if (cache_inode->i_op->link_raw)
124 iops->link_raw = cache_iops->link_raw;
125 if (cache_inode->i_op->unlink)
126 iops->unlink = cache_iops->unlink;
127 if (cache_inode->i_op->unlink_raw)
128 iops->unlink_raw = cache_iops->unlink_raw;
129 if (cache_inode->i_op->symlink)
130 iops->symlink = cache_iops->symlink;
131 if (cache_inode->i_op->symlink_raw)
132 iops->symlink_raw = cache_iops->symlink_raw;
133 if (cache_inode->i_op->mkdir)
134 iops->mkdir = cache_iops->mkdir;
135 if (cache_inode->i_op->mkdir_raw)
136 iops->mkdir_raw = cache_iops->mkdir_raw;
137 if (cache_inode->i_op->rmdir)
138 iops->rmdir = cache_iops->rmdir;
139 if (cache_inode->i_op->rmdir_raw)
140 iops->rmdir_raw = cache_iops->rmdir_raw;
141 if (cache_inode->i_op->mknod)
142 iops->mknod = cache_iops->mknod;
143 if (cache_inode->i_op->mknod_raw)
144 iops->mknod_raw = cache_iops->mknod_raw;
145 if (cache_inode->i_op->rename)
146 iops->rename = cache_iops->rename;
147 if (cache_inode->i_op->rename_raw)
148 iops->rename_raw = cache_iops->rename_raw;
149 if (cache_inode->i_op->readlink)
150 iops->readlink = cache_iops->readlink;
151 if (cache_inode->i_op->follow_link)
152 iops->follow_link = cache_iops->follow_link;
153 if (cache_inode->i_op->truncate)
154 iops->truncate = cache_iops->truncate;
155 if (cache_inode->i_op->permission)
156 iops->permission = cache_iops->permission;
157 if (cache_inode->i_op->revalidate)
158 iops->revalidate = cache_iops->revalidate;
159 if (cache_inode->i_op->revalidate_it)
160 iops->revalidate_it = cache_iops->revalidate_it;
161 if (cache_inode->i_op->setattr)
162 iops->setattr = cache_iops->setattr;
163 if (cache_inode->i_op->setattr_raw)
164 iops->setattr_raw = cache_iops->setattr_raw;
165 if (cache_inode->i_op->getattr)
166 iops->getattr = cache_iops->getattr;
167 if (cache_inode->i_op->setxattr)
168 iops->setxattr = cache_iops->setxattr;
169 if (cache_inode->i_op->getxattr)
170 iops->getxattr = cache_iops->getxattr;
171 if (cache_inode->i_op->listxattr)
172 iops->setxattr = cache_iops->setxattr;
173 if (cache_inode->i_op->removexattr)
174 iops->removexattr = cache_iops->removexattr;
176 if (cache_inode->i_fop) {
179 if (cache_inode->i_mapping && cache_inode->i_mapping->a_ops) {
184 void sm_setup_inode_ops(struct inode *cache_inode, struct inode *inode)
186 /* XXX now set the correct snap_{file,dir,sym}_iops */
187 if (S_ISDIR(inode->i_mode)) {
188 inode->i_op = cache_diops(&smfs_operations);
189 inode->i_fop = cache_dfops(&smfs_operations);
190 } else if (S_ISREG(inode->i_mode)) {
191 if (!cache_fiops(&smfs_operations) ) {
192 setup_sm_file_ops(cache_inode, inode,
197 CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
198 inode->i_ino, inode->i_op);
199 inode->i_fop = cache_ffops(&smfs_operations);
200 inode->i_op = cache_fiops(&smfs_operations);
201 if (inode->i_mapping)
202 inode->i_mapping->a_ops = cache_faops(&smfs_operations);
205 else if (S_ISLNK(inode->i_mode)) {
206 if (!cache_siops(&smfs_operations)) {
207 setup_sm_symlink_ops(cache_inode, inode,
208 &smfs_sym_iops, &smfs_sym_fops);
210 inode->i_op = cache_siops(&smfs_operations);
211 inode->i_fop = cache_sfops(&smfs_operations);
212 CDEBUG(D_INODE, "inode %lu, i_op at %p\n",
213 inode->i_ino, inode->i_op);