5 #define DEBUG_SUBSYSTEM S_SM
7 #include <linux/module.h>
8 #include <linux/kernel.h>
9 #include <linux/string.h>
10 #include <linux/slab.h>
11 #include <linux/stat.h>
12 #include <linux/unistd.h>
13 #include <linux/pagemap.h>
14 #include "smfs_internal.h"
17 static int smfs_readpage(struct file *file,
20 struct inode *inode = page->mapping->host;
21 struct inode *cache_inode;
26 cache_inode = I2CI(inode);
31 if (cache_inode->i_mapping->a_ops->readpage)
32 rc = cache_inode->i_mapping->a_ops->readpage(file, page);
37 static int smfs_writepage(struct page *page)
40 struct inode *inode = page->mapping->host;
41 struct inode *cache_inode;
46 cache_inode = I2CI(inode);
51 if (cache_inode->i_mapping->a_ops->writepage)
52 rc = cache_inode->i_mapping->a_ops->writepage(page);
57 struct address_space_operations smfs_file_aops = {
58 readpage: smfs_readpage,
59 writepage: smfs_writepage,
62 /* instantiate a file handle to the cache file */
63 void smfs_prepare_cachefile(struct inode *inode,
65 struct inode *cache_inode,
66 struct file *cache_file,
67 struct dentry *cache_dentry)
70 cache_file->f_pos = file->f_pos;
71 cache_file->f_mode = file->f_mode;
72 cache_file->f_flags = file->f_flags;
73 cache_file->f_count = file->f_count;
74 cache_file->f_owner = file->f_owner;
75 cache_file->f_op = inode->i_fop;
76 cache_file->f_dentry = cache_dentry;
77 cache_file->f_dentry->d_inode = cache_inode;
80 /* update file structs*/
81 void smfs_update_file(struct file *file,
82 struct file *cache_file)
85 file->f_pos = cache_file->f_pos;
86 file->f_mode = cache_file->f_mode;
87 file->f_flags = cache_file->f_flags;
88 file->f_count = cache_file->f_count;
89 file->f_owner = cache_file->f_owner;
93 static ssize_t smfs_write (struct file *filp, const char *buf,
94 size_t count, loff_t *ppos)
96 struct inode *cache_inode;
97 struct dentry *dentry = filp->f_dentry;
98 struct inode *inode = dentry->d_inode;
99 struct file open_file;
100 struct dentry open_dentry;
105 cache_inode = I2CI(inode);
110 smfs_prepare_cachefile(inode, filp, cache_inode,
111 &open_file, &open_dentry);
113 if (cache_inode->i_fop->write)
114 cache_inode->i_fop->write(&open_file, buf, count, ppos);
116 smfs_update_file(filp, &open_file);
119 int smfs_ioctl(struct inode * inode, struct file * filp,
120 unsigned int cmd, unsigned long arg)
122 struct inode *cache_inode;
123 struct dentry *dentry = filp->f_dentry;
124 struct file open_file;
125 struct dentry open_dentry;
130 cache_inode = I2CI(dentry->d_inode);
134 smfs_prepare_cachefile(inode, filp, cache_inode,
135 &open_file, &open_dentry);
137 if (cache_inode->i_fop->ioctl)
138 rc = cache_inode->i_fop->ioctl(cache_inode, &open_file, cmd, arg);
140 smfs_update_file(filp, &open_file);
143 static ssize_t smfs_read (struct file *filp, char *buf,
144 size_t count, loff_t *ppos)
146 struct inode *cache_inode;
147 struct dentry *dentry = filp->f_dentry;
148 struct file open_file;
149 struct dentry open_dentry;
154 cache_inode = I2CI(dentry->d_inode);
158 smfs_prepare_cachefile(dentry->d_inode, filp, cache_inode,
159 &open_file, &open_dentry);
161 if (cache_inode->i_fop->read)
162 rc = cache_inode->i_fop->read(&open_file, buf, count, ppos);
164 smfs_update_file(filp, &open_file);
167 static loff_t smfs_llseek(struct file *file,
171 struct inode *cache_inode;
172 struct dentry *dentry = file->f_dentry;
173 struct file open_file;
174 struct dentry open_dentry;
179 cache_inode = I2CI(dentry->d_inode);
183 smfs_prepare_cachefile(dentry->d_inode, file, cache_inode,
184 &open_file, &open_dentry);
186 if (cache_inode->i_fop->llseek)
187 rc = cache_inode->i_fop->llseek(&open_file, offset, origin);
189 smfs_update_file(file, &open_file);
194 static int smfs_mmap(struct file * file, struct vm_area_struct * vma)
196 struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
197 struct inode *inode = mapping->host;
198 struct inode *cache_inode = NULL;
199 struct file open_file;
200 struct dentry open_dentry;
203 cache_inode = I2CI(inode);
207 smfs_prepare_cachefile(inode, file, cache_inode,
208 &open_file, &open_dentry);
210 if (cache_inode->i_fop->mmap)
211 rc = cache_inode->i_fop->mmap(&open_file, vma);
213 smfs_update_file(file, &open_file);
218 static int smfs_open(struct inode * inode, struct file * filp)
220 struct inode *cache_inode = NULL;
221 struct file open_file;
222 struct dentry open_dentry;
225 cache_inode = I2CI(inode);
229 smfs_prepare_cachefile(inode, filp, cache_inode,
230 &open_file, &open_dentry);
232 if (cache_inode->i_fop->open)
233 rc = cache_inode->i_fop->open(cache_inode, &open_file);
235 smfs_update_file(filp, &open_file);
240 static int smfs_release(struct inode * inode, struct file * filp)
242 struct inode *cache_inode = NULL;
243 struct file open_file;
244 struct dentry open_dentry;
247 cache_inode = I2CI(inode);
251 smfs_prepare_cachefile(inode, filp, cache_inode,
252 &open_file, &open_dentry);
254 if (cache_inode->i_fop->release)
255 rc = cache_inode->i_fop->release(cache_inode, &open_file);
257 smfs_update_file(filp, &open_file);
261 int smfs_fsync(struct file * file,
262 struct dentry *dentry,
265 struct inode *inode = dentry->d_inode;
266 struct inode *cache_inode;
267 struct file open_file;
268 struct dentry open_dentry;
271 cache_inode = I2CI(inode);
275 smfs_prepare_cachefile(inode, file, cache_inode,
276 &open_file, &open_dentry);
278 if (cache_inode->i_fop->fsync)
279 rc = cache_inode->i_fop->fsync(&open_file, &open_dentry, datasync);
281 smfs_update_file(file, &open_file);
286 struct file_operations smfs_file_fops = {
293 release: smfs_release,
297 static void smfs_prepare_cache_dentry(struct dentry *dentry, struct inode *inode)
299 atomic_set(&dentry->d_count, 1);
300 dentry->d_vfs_flags = 0;
302 dentry->d_inode = inode;
304 dentry->d_fsdata = NULL;
305 dentry->d_mounted = 0;
306 INIT_LIST_HEAD(&dentry->d_hash);
307 INIT_LIST_HEAD(&dentry->d_lru);
308 INIT_LIST_HEAD(&dentry->d_subdirs);
309 INIT_LIST_HEAD(&dentry->d_alias);
312 static void smfs_truncate(struct inode * inode)
314 struct inode *cache_inode;
316 cache_inode = I2CI(inode);
321 if (cache_inode->i_op->truncate)
322 cache_inode->i_op->truncate(cache_inode);
324 duplicate_inode(inode, cache_inode);
329 int smfs_setattr(struct dentry *dentry, struct iattr *attr)
331 struct inode *cache_inode;
332 struct dentry open_dentry;
336 cache_inode = I2CI(dentry->d_inode);
340 smfs_prepare_cache_dentry(&open_dentry, cache_inode);
342 if (cache_inode->i_op->setattr)
343 rc = cache_inode->i_op->setattr(&open_dentry, attr);
348 int smfs_setxattr(struct dentry *dentry, const char *name,
349 const void *value, size_t size, int flags)
351 struct inode *cache_inode;
352 struct dentry open_dentry;
355 cache_inode = I2CI(dentry->d_inode);
360 smfs_prepare_cache_dentry(&open_dentry, cache_inode);
362 if (cache_inode->i_op->setattr)
363 rc = cache_inode->i_op->setxattr(&open_dentry, name, value, size, flags);
368 int smfs_getxattr(struct dentry *dentry, const char *name,
369 void *buffer, size_t size)
371 struct inode *cache_inode;
372 struct dentry open_dentry;
375 cache_inode = I2CI(dentry->d_inode);
380 smfs_prepare_cache_dentry(&open_dentry, cache_inode);
382 if (cache_inode->i_op->setattr)
383 rc = cache_inode->i_op->getxattr(&open_dentry, name, buffer, size);
388 ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
390 struct inode *cache_inode;
391 struct dentry open_dentry;
394 cache_inode = I2CI(dentry->d_inode);
399 smfs_prepare_cache_dentry(&open_dentry, cache_inode);
401 if (cache_inode->i_op->listxattr)
402 rc = cache_inode->i_op->listxattr(&open_dentry, buffer, size);
407 int smfs_removexattr(struct dentry *dentry, const char *name)
409 struct inode *cache_inode;
410 struct dentry open_dentry;
413 cache_inode = I2CI(dentry->d_inode);
418 smfs_prepare_cache_dentry(&open_dentry, cache_inode);
420 if (cache_inode->i_op->removexattr)
421 rc = cache_inode->i_op->removexattr(&open_dentry, name);
426 struct inode_operations smfs_file_iops = {
427 truncate: smfs_truncate, /* BKL held */
428 setattr: smfs_setattr, /* BKL held */
429 setxattr: smfs_setxattr, /* BKL held */
430 getxattr: smfs_getxattr, /* BKL held */
431 listxattr: smfs_listxattr, /* BKL held */
432 removexattr: smfs_removexattr, /* BKL held */