root/fs/nfs/file.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. revalidate_inode
  2. nfs_file_read
  3. nfs_file_mmap
  4. nfs_fsync
  5. do_read_nfs
  6. nfs_readpage
  7. nfs_file_write

   1 /*
   2  *  linux/fs/nfs/file.c
   3  *
   4  *  Copyright (C) 1992  Rick Sladkey
   5  *
   6  *  Changes Copyright (C) 1994 by Florian La Roche
   7  *   - Do not copy data too often around in the kernel.
   8  *   - In nfs_file_read the return value of kmalloc wasn't checked.
   9  *   - Put in a better version of read look-ahead buffering. Original idea
  10  *     and implementation by Wai S Kok elekokws@ee.nus.sg.
  11  *
  12  *  Expire cache on write to a file by Wai S Kok (Oct 1994).
  13  *
  14  *  Total rewrite of read side for new NFS buffer cache.. Linus.
  15  *
  16  *  nfs regular file handling functions
  17  */
  18 
  19 #include <linux/sched.h>
  20 #include <linux/kernel.h>
  21 #include <linux/errno.h>
  22 #include <linux/fcntl.h>
  23 #include <linux/stat.h>
  24 #include <linux/mm.h>
  25 #include <linux/nfs_fs.h>
  26 #include <linux/malloc.h>
  27 #include <linux/pagemap.h>
  28 
  29 #include <asm/segment.h>
  30 #include <asm/system.h>
  31 
  32 static int nfs_file_mmap(struct inode *, struct file *, struct vm_area_struct *);
  33 static int nfs_file_read(struct inode *, struct file *, char *, int);
  34 static int nfs_file_write(struct inode *, struct file *, const char *, int);
  35 static int nfs_fsync(struct inode *, struct file *);
  36 static int nfs_readpage(struct inode * inode, struct page * page);
  37 
  38 static struct file_operations nfs_file_operations = {
  39         NULL,                   /* lseek - default */
  40         nfs_file_read,          /* read */
  41         nfs_file_write,         /* write */
  42         NULL,                   /* readdir - bad */
  43         NULL,                   /* select - default */
  44         NULL,                   /* ioctl - default */
  45         nfs_file_mmap,          /* mmap */
  46         NULL,                   /* no special open is needed */
  47         NULL,                   /* release */
  48         nfs_fsync,              /* fsync */
  49 };
  50 
  51 struct inode_operations nfs_file_inode_operations = {
  52         &nfs_file_operations,   /* default file operations */
  53         NULL,                   /* create */
  54         NULL,                   /* lookup */
  55         NULL,                   /* link */
  56         NULL,                   /* unlink */
  57         NULL,                   /* symlink */
  58         NULL,                   /* mkdir */
  59         NULL,                   /* rmdir */
  60         NULL,                   /* mknod */
  61         NULL,                   /* rename */
  62         NULL,                   /* readlink */
  63         NULL,                   /* follow_link */
  64         nfs_readpage,           /* readpage */
  65         NULL,                   /* writepage */
  66         NULL,                   /* bmap */
  67         NULL                    /* truncate */
  68 };
  69 
  70 static inline void revalidate_inode(struct nfs_server * server, struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  71 {
  72         struct nfs_fattr fattr;
  73 
  74         if (jiffies - NFS_READTIME(inode) < server->acregmax)
  75                 return;
  76 
  77         NFS_READTIME(inode) = jiffies;
  78         if (nfs_proc_getattr(server, NFS_FH(inode), &fattr) == 0) {
  79                 nfs_refresh_inode(inode, &fattr);
  80                 if (fattr.mtime.seconds == NFS_OLDMTIME(inode))
  81                         return;
  82                 NFS_OLDMTIME(inode) = fattr.mtime.seconds;
  83         }
  84         invalidate_inode_pages(inode, 0);
  85 }
  86 
  87 
  88 static int nfs_file_read(struct inode * inode, struct file * file,
     /* [previous][next][first][last][top][bottom][index][help] */
  89         char * buf, int count)
  90 {
  91         revalidate_inode(NFS_SERVER(inode), inode);
  92         return generic_file_read(inode, file, buf, count);
  93 }
  94 
  95 static int nfs_file_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
     /* [previous][next][first][last][top][bottom][index][help] */
  96 {
  97         revalidate_inode(NFS_SERVER(inode), inode);
  98         return generic_file_mmap(inode, file, vma);
  99 }
 100 
 101 static int nfs_fsync(struct inode *inode, struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 102 {
 103         return 0;
 104 }
 105 
 106 static inline void do_read_nfs(struct inode * inode, char * buf, unsigned long pos)
     /* [previous][next][first][last][top][bottom][index][help] */
 107 {
 108         int refresh = 0;
 109         int count = PAGE_SIZE;
 110         int rsize = NFS_SERVER(inode)->rsize;
 111         struct nfs_fattr fattr;
 112 
 113         do {
 114                 int result;
 115 
 116                 if (count < rsize)
 117                         rsize = count;
 118                 result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode), 
 119                         pos, rsize, buf, &fattr);
 120                 if (result < 0)
 121                         goto partial;
 122                 refresh = 1;
 123                 count -= rsize;
 124                 pos += rsize;
 125                 buf += rsize;
 126                 if (result < rsize)
 127                         goto partial;
 128         } while (count);
 129         nfs_refresh_inode(inode, &fattr);
 130         return;
 131 
 132 partial:
 133         memset(buf, 0, count);
 134         if (refresh)
 135                 nfs_refresh_inode(inode, &fattr);
 136 }
 137 
 138 static int nfs_readpage(struct inode * inode, struct page * page)
     /* [previous][next][first][last][top][bottom][index][help] */
 139 {
 140         unsigned long address;
 141 
 142         address = page_address(page);
 143         page->count++;
 144         wait_on_page(page);
 145         if (page->uptodate) {
 146                 free_page(address);
 147                 return 0;
 148         }
 149         page->locked = 1;
 150         do_read_nfs(inode, (char *) address, page->offset);
 151         page->locked = 0;
 152         page->uptodate = 1;
 153         wake_up(&page->wait);
 154         free_page(address);
 155         return 0;
 156 }
 157 
 158 static int nfs_file_write(struct inode *inode, struct file *file, const char *buf,
     /* [previous][next][first][last][top][bottom][index][help] */
 159                           int count)
 160 {
 161         int result, hunk, i, n, pos;
 162         struct nfs_fattr fattr;
 163 
 164         if (!inode) {
 165                 printk("nfs_file_write: inode = NULL\n");
 166                 return -EINVAL;
 167         }
 168         if (!S_ISREG(inode->i_mode)) {
 169                 printk("nfs_file_write: write to non-file, mode %07o\n",
 170                         inode->i_mode);
 171                 return -EINVAL;
 172         }
 173         if (count <= 0)
 174                 return 0;
 175 
 176         pos = file->f_pos;
 177         if (file->f_flags & O_APPEND)
 178                 pos = inode->i_size;
 179         n = NFS_SERVER(inode)->wsize;
 180         for (i = 0; i < count; i += n) {
 181                 hunk = count - i;
 182                 if (hunk >= n)
 183                         hunk = n;
 184                 result = nfs_proc_write(inode,
 185                         pos, hunk, buf, &fattr);
 186                 if (result < 0)
 187                         return result;
 188                 pos += hunk;
 189                 buf += hunk;
 190                 if (hunk < n) {
 191                         i += hunk;
 192                         break;
 193                 }
 194         }
 195         file->f_pos = pos;
 196         nfs_refresh_inode(inode, &fattr);
 197         return i;
 198 }
 199 

/* [previous][next][first][last][top][bottom][index][help] */