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"
16 static int smfs_readpage(struct file *file,
19 struct inode *inode = page->mapping->host;
20 struct inode *cache_inode;
21 struct page *cache_page = NULL;
26 cache_inode = I2CI(inode);
31 cache_page = grab_cache_page(cache_inode->i_mapping, page->index);
34 GOTO(exit_release, rc = -ENOMEM);
36 if ((rc = cache_inode->i_mapping->a_ops->readpage(file, cache_page)))
37 GOTO(exit_release, 0);
39 wait_on_page(cache_page);
41 if (!Page_Uptodate(cache_page))
42 GOTO(exit_release, rc = -EIO);
44 memcpy(kmap(page), kmap(cache_page), PAGE_CACHE_SIZE);
46 flush_dcache_page(page);
49 page_cache_release(cache_page);
53 SetPageUptodate(page);
60 page_cache_release(cache_page);
65 static int smfs_writepage(struct page *page)
68 struct inode *inode = page->mapping->host;
69 struct inode *cache_inode;
74 cache_inode = I2CI(inode);
79 if (cache_inode->i_mapping->a_ops->writepage)
80 rc = cache_inode->i_mapping->a_ops->writepage(page);
85 struct address_space_operations smfs_file_aops = {
86 readpage: smfs_readpage,
87 writepage: smfs_writepage,
90 /* instantiate a file handle to the cache file */
91 void smfs_prepare_cachefile(struct inode *inode,
93 struct inode *cache_inode,
94 struct file *cache_file,
95 struct dentry *cache_dentry)
98 cache_file->f_pos = file->f_pos;
99 cache_file->f_mode = file->f_mode;
100 cache_file->f_flags = file->f_flags;
101 cache_file->f_count = file->f_count;
102 cache_file->f_owner = file->f_owner;
103 cache_file->f_error = file->f_error;
104 cache_file->f_op = inode->i_fop;
105 cache_file->f_dentry = cache_dentry;
106 cache_file->f_dentry->d_inode = cache_inode;
107 cache_file->f_vfsmnt = file->f_vfsmnt;
108 cache_file->private_data = file->private_data;
109 cache_file->f_it = file->f_it;
110 cache_file->f_reada = file->f_reada;
111 cache_file->f_ramax = file->f_ramax;
112 cache_file->f_raend = file->f_raend;
113 cache_file->f_ralen = file->f_ralen;
114 cache_file->f_rawin = file->f_rawin;
117 /* update file structs*/
118 void smfs_update_file(struct file *file,
119 struct file *cache_file)
122 file->f_pos = cache_file->f_pos;
123 file->f_mode = cache_file->f_mode;
124 file->f_flags = cache_file->f_flags;
125 file->f_count = cache_file->f_count;
126 file->f_owner = cache_file->f_owner;
127 file->f_reada = cache_file->f_reada;
128 file->f_ramax = cache_file->f_ramax;
129 file->f_raend = cache_file->f_raend;
130 file->f_ralen = cache_file->f_ralen;
131 file->f_rawin = cache_file->f_rawin;
135 static ssize_t smfs_write (struct file *filp, const char *buf,
136 size_t count, loff_t *ppos)
138 struct inode *cache_inode;
139 struct dentry *dentry = filp->f_dentry;
140 struct inode *inode = dentry->d_inode;
141 struct file open_file;
142 struct dentry open_dentry;
147 cache_inode = I2CI(inode);
152 smfs_prepare_cachefile(inode, filp, cache_inode,
153 &open_file, &open_dentry);
155 if (cache_inode->i_fop->write)
156 rc = cache_inode->i_fop->write(&open_file, buf, count, ppos);
158 duplicate_inode(cache_inode, inode);
159 smfs_update_file(filp, &open_file);
163 int smfs_ioctl(struct inode * inode, struct file * filp,
164 unsigned int cmd, unsigned long arg)
166 struct inode *cache_inode;
167 struct dentry *dentry = filp->f_dentry;
168 struct file open_file;
169 struct dentry open_dentry;
174 cache_inode = I2CI(dentry->d_inode);
178 smfs_prepare_cachefile(inode, filp, cache_inode,
179 &open_file, &open_dentry);
181 if (cache_inode->i_fop->ioctl)
182 rc = cache_inode->i_fop->ioctl(cache_inode, &open_file, cmd, arg);
184 duplicate_inode(cache_inode, inode);
185 smfs_update_file(filp, &open_file);
189 static ssize_t smfs_read (struct file *filp, char *buf,
190 size_t count, loff_t *ppos)
192 struct inode *cache_inode;
193 struct dentry *dentry = filp->f_dentry;
198 cache_inode = I2CI(dentry->d_inode);
202 if (cache_inode->i_fop->read)
203 rc = cache_inode->i_fop->read(filp, buf, count, ppos);
205 duplicate_inode(cache_inode, dentry->d_inode);
209 static loff_t smfs_llseek(struct file *file,
213 struct inode *cache_inode;
214 struct dentry *dentry = file->f_dentry;
215 struct file open_file;
216 struct dentry open_dentry;
221 cache_inode = I2CI(dentry->d_inode);
225 smfs_prepare_cachefile(dentry->d_inode, file, cache_inode,
226 &open_file, &open_dentry);
228 if (cache_inode->i_fop->llseek)
229 rc = cache_inode->i_fop->llseek(&open_file, offset, origin);
231 duplicate_inode(cache_inode, dentry->d_inode);
232 smfs_update_file(file, &open_file);
237 static int smfs_mmap(struct file * file, struct vm_area_struct * vma)
239 struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
240 struct inode *inode = mapping->host;
241 struct inode *cache_inode = NULL;
242 struct file open_file;
243 struct dentry open_dentry;
246 cache_inode = I2CI(inode);
250 smfs_prepare_cachefile(inode, file, cache_inode,
251 &open_file, &open_dentry);
253 if (cache_inode->i_fop->mmap)
254 rc = cache_inode->i_fop->mmap(&open_file, vma);
256 duplicate_inode(cache_inode, inode);
257 smfs_update_file(file, &open_file);
262 static int smfs_open(struct inode * inode, struct file * filp)
264 struct inode *cache_inode = NULL;
265 struct file open_file;
266 struct dentry open_dentry;
269 cache_inode = I2CI(inode);
273 smfs_prepare_cachefile(inode, filp, cache_inode,
274 &open_file, &open_dentry);
276 if (cache_inode->i_fop->open)
277 rc = cache_inode->i_fop->open(cache_inode, &open_file);
279 duplicate_inode(cache_inode, inode);
280 smfs_update_file(filp, &open_file);
285 static int smfs_release(struct inode * inode, struct file * filp)
287 struct inode *cache_inode = NULL;
288 struct file open_file;
289 struct dentry open_dentry;
292 cache_inode = I2CI(inode);
296 smfs_prepare_cachefile(inode, filp, cache_inode,
297 &open_file, &open_dentry);
299 if (cache_inode->i_fop->release)
300 rc = cache_inode->i_fop->release(cache_inode, &open_file);
302 duplicate_inode(cache_inode, inode);
303 smfs_update_file(filp, &open_file);
307 int smfs_fsync(struct file * file,
308 struct dentry *dentry,
311 struct inode *inode = dentry->d_inode;
312 struct inode *cache_inode;
313 struct file open_file;
314 struct dentry open_dentry;
317 cache_inode = I2CI(inode);
321 smfs_prepare_cachefile(inode, file, cache_inode,
322 &open_file, &open_dentry);
324 if (cache_inode->i_fop->fsync)
325 rc = cache_inode->i_fop->fsync(&open_file, &open_dentry, datasync);
327 duplicate_inode(cache_inode, inode);
328 smfs_update_file(file, &open_file);
333 struct file_operations smfs_file_fops = {
340 release: smfs_release,
344 static void smfs_prepare_cache_dentry(struct dentry *dentry, struct inode *inode)
346 atomic_set(&dentry->d_count, 1);
347 dentry->d_vfs_flags = 0;
349 dentry->d_inode = inode;
351 dentry->d_fsdata = NULL;
352 dentry->d_mounted = 0;
353 INIT_LIST_HEAD(&dentry->d_hash);
354 INIT_LIST_HEAD(&dentry->d_lru);
355 INIT_LIST_HEAD(&dentry->d_subdirs);
356 INIT_LIST_HEAD(&dentry->d_alias);
359 static void smfs_truncate(struct inode * inode)
361 struct inode *cache_inode;
363 cache_inode = I2CI(inode);
368 if (cache_inode->i_op->truncate)
369 cache_inode->i_op->truncate(cache_inode);
371 duplicate_inode(inode, cache_inode);
376 int smfs_setattr(struct dentry *dentry, struct iattr *attr)
378 struct inode *cache_inode;
379 struct dentry open_dentry;
383 cache_inode = I2CI(dentry->d_inode);
387 smfs_prepare_cache_dentry(&open_dentry, cache_inode);
389 if (cache_inode->i_op->setattr)
390 rc = cache_inode->i_op->setattr(&open_dentry, attr);
395 int smfs_setxattr(struct dentry *dentry, const char *name,
396 const void *value, size_t size, int flags)
398 struct inode *cache_inode;
399 struct dentry open_dentry;
402 cache_inode = I2CI(dentry->d_inode);
407 smfs_prepare_cache_dentry(&open_dentry, cache_inode);
409 if (cache_inode->i_op->setattr)
410 rc = cache_inode->i_op->setxattr(&open_dentry, name, value, size, flags);
415 int smfs_getxattr(struct dentry *dentry, const char *name,
416 void *buffer, size_t size)
418 struct inode *cache_inode;
419 struct dentry open_dentry;
422 cache_inode = I2CI(dentry->d_inode);
427 smfs_prepare_cache_dentry(&open_dentry, cache_inode);
429 if (cache_inode->i_op->setattr)
430 rc = cache_inode->i_op->getxattr(&open_dentry, name, buffer, size);
435 ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
437 struct inode *cache_inode;
438 struct dentry open_dentry;
441 cache_inode = I2CI(dentry->d_inode);
446 smfs_prepare_cache_dentry(&open_dentry, cache_inode);
448 if (cache_inode->i_op->listxattr)
449 rc = cache_inode->i_op->listxattr(&open_dentry, buffer, size);
454 int smfs_removexattr(struct dentry *dentry, const char *name)
456 struct inode *cache_inode;
457 struct dentry open_dentry;
460 cache_inode = I2CI(dentry->d_inode);
465 smfs_prepare_cache_dentry(&open_dentry, cache_inode);
467 if (cache_inode->i_op->removexattr)
468 rc = cache_inode->i_op->removexattr(&open_dentry, name);
473 struct inode_operations smfs_file_iops = {
474 truncate: smfs_truncate, /* BKL held */
475 setattr: smfs_setattr, /* BKL held */
476 setxattr: smfs_setxattr, /* BKL held */
477 getxattr: smfs_getxattr, /* BKL held */
478 listxattr: smfs_listxattr, /* BKL held */
479 removexattr: smfs_removexattr, /* BKL held */