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 static int smfs_sync_page(struct page *page)
87 struct inode *inode = page->mapping->host;
88 struct inode *cache_inode;
91 cache_inode = I2CI(inode);
96 if (cache_inode->i_mapping->a_ops->sync_page)
97 rc = cache_inode->i_mapping->a_ops->sync_page(page);
102 static int smfs_prepare_write(struct file *file, struct page *page,
103 unsigned from, unsigned to)
105 struct inode *inode = page->mapping->host;
106 struct inode *cache_inode;
109 cache_inode = I2CI(inode);
114 if (cache_inode->i_mapping->a_ops->prepare_write)
115 rc = cache_inode->i_mapping->a_ops->prepare_write(file, page, from, to);
120 static int smfs_commit_write(struct file *file, struct page *page,
121 unsigned from, unsigned to)
123 struct inode *inode = page->mapping->host;
124 struct inode *cache_inode;
127 cache_inode = I2CI(inode);
132 if (cache_inode->i_mapping->a_ops->commit_write)
133 rc = cache_inode->i_mapping->a_ops->commit_write(file, page, from, to);
138 static int smfs_bmap(struct address_space *mapping, long block)
140 struct inode *inode = mapping->host;
141 struct inode *cache_inode;
144 cache_inode = I2CI(inode);
149 if (cache_inode->i_mapping->a_ops->bmap)
150 rc = cache_inode->i_mapping->a_ops->bmap(mapping, block);
155 static int smfs_flushpage(struct page *page, unsigned long offset)
157 struct inode *inode = page->mapping->host;
158 struct inode *cache_inode;
161 cache_inode = I2CI(inode);
166 if (cache_inode->i_mapping->a_ops->flushpage)
167 rc = cache_inode->i_mapping->a_ops->flushpage(page, offset);
172 static int smfs_releasepage(struct page *page, int wait)
174 struct inode *inode = page->mapping->host;
175 struct inode *cache_inode;
178 cache_inode = I2CI(inode);
183 if (cache_inode->i_mapping->a_ops->releasepage)
184 rc = cache_inode->i_mapping->a_ops->releasepage(page, wait);
189 static int smfs_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf,
190 unsigned long blocknr, int blocksize)
192 struct inode *cache_inode;
195 cache_inode = I2CI(inode);
200 if (cache_inode->i_mapping->a_ops->direct_IO)
201 rc = cache_inode->i_mapping->a_ops->direct_IO(rw, cache_inode, iobuf,
206 struct address_space_operations smfs_file_aops = {
207 readpage: smfs_readpage,
208 writepage: smfs_writepage,
209 sync_page: smfs_sync_page,
210 prepare_write: smfs_prepare_write,
211 commit_write: smfs_commit_write,
213 flushpage: smfs_flushpage,
214 releasepage: smfs_releasepage,
215 direct_IO: smfs_direct_IO,
218 /* instantiate a file handle to the cache file */
219 void smfs_prepare_cachefile(struct inode *inode,
221 struct inode *cache_inode,
222 struct file *cache_file,
223 struct dentry *cache_dentry)
226 cache_file->f_pos = file->f_pos;
227 cache_file->f_mode = file->f_mode;
228 cache_file->f_flags = file->f_flags;
229 cache_file->f_count = file->f_count;
230 cache_file->f_owner = file->f_owner;
231 cache_file->f_error = file->f_error;
232 cache_file->f_op = inode->i_fop;
233 cache_file->f_dentry = cache_dentry;
234 cache_file->f_dentry->d_inode = cache_inode;
235 cache_file->f_vfsmnt = file->f_vfsmnt;
236 cache_file->private_data = file->private_data;
237 cache_file->f_it = file->f_it;
238 cache_file->f_reada = file->f_reada;
239 cache_file->f_ramax = file->f_ramax;
240 cache_file->f_raend = file->f_raend;
241 cache_file->f_ralen = file->f_ralen;
242 cache_file->f_rawin = file->f_rawin;
245 /* update file structs*/
246 void smfs_update_file(struct file *file,
247 struct file *cache_file)
250 file->f_pos = cache_file->f_pos;
251 file->f_mode = cache_file->f_mode;
252 file->f_flags = cache_file->f_flags;
253 file->f_count = cache_file->f_count;
254 file->f_owner = cache_file->f_owner;
255 file->f_reada = cache_file->f_reada;
256 file->f_ramax = cache_file->f_ramax;
257 file->f_raend = cache_file->f_raend;
258 file->f_ralen = cache_file->f_ralen;
259 file->f_rawin = cache_file->f_rawin;
263 static ssize_t smfs_write (struct file *filp, const char *buf,
264 size_t count, loff_t *ppos)
266 struct inode *cache_inode;
267 struct dentry *dentry = filp->f_dentry;
268 struct inode *inode = dentry->d_inode;
269 struct file open_file;
270 struct dentry open_dentry;
277 cache_inode = I2CI(inode);
282 if (ppos != &(filp->f_pos)) {
283 cache_ppos = &tmp_ppos;
285 cache_ppos = &open_file.f_pos;
289 smfs_prepare_cachefile(inode, filp, cache_inode,
290 &open_file, &open_dentry);
291 if (cache_inode->i_fop->write)
292 rc = cache_inode->i_fop->write(&open_file, buf, count, cache_ppos);
295 duplicate_inode(cache_inode, inode);
296 smfs_update_file(filp, &open_file);
301 int smfs_ioctl(struct inode * inode, struct file * filp,
302 unsigned int cmd, unsigned long arg)
304 struct inode *cache_inode;
305 struct dentry *dentry = filp->f_dentry;
306 struct file open_file;
307 struct dentry open_dentry;
312 cache_inode = I2CI(dentry->d_inode);
316 smfs_prepare_cachefile(inode, filp, cache_inode,
317 &open_file, &open_dentry);
319 if (cache_inode->i_fop->ioctl)
320 rc = cache_inode->i_fop->ioctl(cache_inode, &open_file, cmd, arg);
322 duplicate_inode(cache_inode, inode);
323 smfs_update_file(filp, &open_file);
327 static ssize_t smfs_read (struct file *filp, char *buf,
328 size_t count, loff_t *ppos)
330 struct inode *cache_inode;
331 struct dentry *dentry = filp->f_dentry;
332 struct inode *inode = dentry->d_inode;
333 struct file open_file;
334 struct dentry open_dentry;
341 cache_inode = I2CI(dentry->d_inode);
345 if (ppos != &(filp->f_pos)) {
346 cache_ppos = &tmp_ppos;
348 cache_ppos = &open_file.f_pos;
353 smfs_prepare_cachefile(inode, filp, cache_inode,
354 &open_file, &open_dentry);
357 if (cache_inode->i_fop->read)
358 rc = cache_inode->i_fop->read(&open_file, buf, count, cache_ppos);
361 duplicate_inode(cache_inode, inode);
362 smfs_update_file(filp, &open_file);
366 static loff_t smfs_llseek(struct file *file,
370 struct inode *cache_inode;
371 struct dentry *dentry = file->f_dentry;
372 struct file open_file;
373 struct dentry open_dentry;
378 cache_inode = I2CI(dentry->d_inode);
382 smfs_prepare_cachefile(dentry->d_inode, file, cache_inode,
383 &open_file, &open_dentry);
385 if (cache_inode->i_fop->llseek)
386 rc = cache_inode->i_fop->llseek(&open_file, offset, origin);
388 duplicate_inode(cache_inode, dentry->d_inode);
389 smfs_update_file(file, &open_file);
394 static int smfs_mmap(struct file * file, struct vm_area_struct * vma)
396 struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
397 struct inode *inode = mapping->host;
398 struct inode *cache_inode = NULL;
399 struct file open_file;
400 struct dentry open_dentry;
403 cache_inode = I2CI(inode);
407 smfs_prepare_cachefile(inode, file, cache_inode,
408 &open_file, &open_dentry);
410 if (cache_inode->i_fop->mmap)
411 rc = cache_inode->i_fop->mmap(&open_file, vma);
413 duplicate_inode(cache_inode, inode);
414 smfs_update_file(file, &open_file);
419 static int smfs_open(struct inode * inode, struct file * filp)
421 struct inode *cache_inode = NULL;
422 struct file open_file;
423 struct dentry open_dentry;
426 cache_inode = I2CI(inode);
430 smfs_prepare_cachefile(inode, filp, cache_inode,
431 &open_file, &open_dentry);
433 if (cache_inode->i_fop->open)
434 rc = cache_inode->i_fop->open(cache_inode, &open_file);
436 duplicate_inode(cache_inode, inode);
437 smfs_update_file(filp, &open_file);
442 static int smfs_release(struct inode * inode, struct file * filp)
444 struct inode *cache_inode = NULL;
445 struct file open_file;
446 struct dentry open_dentry;
449 cache_inode = I2CI(inode);
453 smfs_prepare_cachefile(inode, filp, cache_inode,
454 &open_file, &open_dentry);
456 if (cache_inode->i_fop->release)
457 rc = cache_inode->i_fop->release(cache_inode, &open_file);
459 duplicate_inode(cache_inode, inode);
460 smfs_update_file(filp, &open_file);
464 int smfs_fsync(struct file * file,
465 struct dentry *dentry,
468 struct inode *inode = dentry->d_inode;
469 struct inode *cache_inode;
470 struct file open_file;
471 struct dentry open_dentry;
474 cache_inode = I2CI(inode);
478 smfs_prepare_cachefile(inode, file, cache_inode,
479 &open_file, &open_dentry);
481 if (cache_inode->i_fop->fsync)
482 rc = cache_inode->i_fop->fsync(&open_file, &open_dentry, datasync);
484 duplicate_inode(cache_inode, inode);
485 smfs_update_file(file, &open_file);
490 struct file_operations smfs_file_fops = {
497 release: smfs_release,
501 static void smfs_prepare_cache_dentry(struct dentry *dentry, struct inode *inode)
503 atomic_set(&dentry->d_count, 1);
504 dentry->d_vfs_flags = 0;
506 dentry->d_inode = inode;
508 dentry->d_fsdata = NULL;
509 dentry->d_mounted = 0;
510 INIT_LIST_HEAD(&dentry->d_hash);
511 INIT_LIST_HEAD(&dentry->d_lru);
512 INIT_LIST_HEAD(&dentry->d_subdirs);
513 INIT_LIST_HEAD(&dentry->d_alias);
516 static void smfs_truncate(struct inode * inode)
518 struct inode *cache_inode;
520 cache_inode = I2CI(inode);
525 if (cache_inode->i_op->truncate)
526 cache_inode->i_op->truncate(cache_inode);
528 duplicate_inode(inode, cache_inode);
533 int smfs_setattr(struct dentry *dentry, struct iattr *attr)
535 struct inode *cache_inode;
536 struct dentry open_dentry;
540 cache_inode = I2CI(dentry->d_inode);
544 smfs_prepare_cache_dentry(&open_dentry, cache_inode);
546 if (cache_inode->i_op->setattr)
547 rc = cache_inode->i_op->setattr(&open_dentry, attr);
549 duplicate_inode(cache_inode, dentry->d_inode);
554 int smfs_setxattr(struct dentry *dentry, const char *name,
555 const void *value, size_t size, int flags)
557 struct inode *cache_inode;
558 struct dentry open_dentry;
561 cache_inode = I2CI(dentry->d_inode);
566 smfs_prepare_cache_dentry(&open_dentry, cache_inode);
568 if (cache_inode->i_op->setattr)
569 rc = cache_inode->i_op->setxattr(&open_dentry, name, value, size, flags);
571 duplicate_inode(cache_inode, dentry->d_inode);
575 int smfs_getxattr(struct dentry *dentry, const char *name,
576 void *buffer, size_t size)
578 struct inode *cache_inode;
579 struct dentry open_dentry;
582 cache_inode = I2CI(dentry->d_inode);
587 smfs_prepare_cache_dentry(&open_dentry, cache_inode);
589 if (cache_inode->i_op->setattr)
590 rc = cache_inode->i_op->getxattr(&open_dentry, name, buffer, size);
592 duplicate_inode(cache_inode, dentry->d_inode);
596 ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
598 struct inode *cache_inode;
599 struct dentry open_dentry;
602 cache_inode = I2CI(dentry->d_inode);
607 smfs_prepare_cache_dentry(&open_dentry, cache_inode);
609 if (cache_inode->i_op->listxattr)
610 rc = cache_inode->i_op->listxattr(&open_dentry, buffer, size);
612 duplicate_inode(cache_inode, dentry->d_inode);
616 int smfs_removexattr(struct dentry *dentry, const char *name)
618 struct inode *cache_inode;
619 struct dentry open_dentry;
622 cache_inode = I2CI(dentry->d_inode);
627 smfs_prepare_cache_dentry(&open_dentry, cache_inode);
629 if (cache_inode->i_op->removexattr)
630 rc = cache_inode->i_op->removexattr(&open_dentry, name);
632 duplicate_inode(cache_inode, dentry->d_inode);
636 struct inode_operations smfs_file_iops = {
637 truncate: smfs_truncate, /* BKL held */
638 setattr: smfs_setattr, /* BKL held */
639 setxattr: smfs_setxattr, /* BKL held */
640 getxattr: smfs_getxattr, /* BKL held */
641 listxattr: smfs_listxattr, /* BKL held */
642 removexattr: smfs_removexattr, /* BKL held */