URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [nfs/] [file.c] - Rev 1765
Compare with Previous | Blame | View Log
/* * linux/fs/nfs/file.c * * Copyright (C) 1992 Rick Sladkey * * Changes Copyright (C) 1994 by Florian La Roche * - Do not copy data too often around in the kernel. * - In nfs_file_read the return value of kmalloc wasn't checked. * - Put in a better version of read look-ahead buffering. Original idea * and implementation by Wai S Kok elekokws@ee.nus.sg. * * Expire cache on write to a file by Wai S Kok (Oct 1994). * * Total rewrite of read side for new NFS buffer cache.. Linus. * * nfs regular file handling functions */ #include <linux/sched.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/fcntl.h> #include <linux/stat.h> #include <linux/mm.h> #include <linux/nfs_fs.h> #include <linux/malloc.h> #include <linux/pagemap.h> #include <asm/segment.h> #include <asm/system.h> static int nfs_file_mmap(struct inode *, struct file *, struct vm_area_struct *); static int nfs_file_read(struct inode *, struct file *, char *, int); static int nfs_file_write(struct inode *, struct file *, const char *, int); static int nfs_fsync(struct inode *, struct file *); static struct file_operations nfs_file_operations = { NULL, /* lseek - default */ nfs_file_read, /* read */ nfs_file_write, /* write */ NULL, /* readdir - bad */ NULL, /* select - default */ NULL, /* ioctl - default */ nfs_file_mmap, /* mmap */ NULL, /* no special open is needed */ NULL, /* release */ nfs_fsync, /* fsync */ }; struct inode_operations nfs_file_inode_operations = { &nfs_file_operations, /* default file operations */ NULL, /* create */ NULL, /* lookup */ NULL, /* link */ NULL, /* unlink */ NULL, /* symlink */ NULL, /* mkdir */ NULL, /* rmdir */ NULL, /* mknod */ NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ nfs_readpage, /* readpage */ NULL, /* writepage */ NULL, /* bmap */ NULL /* truncate */ }; static inline void revalidate_inode(struct nfs_server * server, struct inode * inode) { struct nfs_fattr fattr; if (jiffies - NFS_READTIME(inode) < NFS_ATTRTIMEO(inode)) return; NFS_READTIME(inode) = jiffies; if (nfs_proc_getattr(server, NFS_FH(inode), &fattr) == 0) { nfs_refresh_inode(inode, &fattr); if (fattr.mtime.seconds == NFS_OLDMTIME(inode)) { if ((NFS_ATTRTIMEO(inode) <<= 1) > server->acregmax) NFS_ATTRTIMEO(inode) = server->acregmax; return; } NFS_OLDMTIME(inode) = fattr.mtime.seconds; } invalidate_inode_pages(inode); } static int nfs_file_read(struct inode * inode, struct file * file, char * buf, int count) { revalidate_inode(NFS_SERVER(inode), inode); return generic_file_read(inode, file, buf, count); } static int nfs_file_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma) { revalidate_inode(NFS_SERVER(inode), inode); return generic_file_mmap(inode, file, vma); } static int nfs_fsync(struct inode *inode, struct file *file) { return 0; } static int nfs_file_write(struct inode *inode, struct file *file, const char *buf, int count) { int result, written, wsize; struct nfs_fattr fattr; unsigned long pos; if (!inode) { printk("nfs_file_write: inode = NULL\n"); return -EINVAL; } if (!S_ISREG(inode->i_mode)) { printk("nfs_file_write: write to non-file, mode %07o\n", inode->i_mode); return -EINVAL; } if (count <= 0) return 0; pos = file->f_pos; if (file->f_flags & O_APPEND) pos = inode->i_size; wsize = NFS_SERVER(inode)->wsize; result = 0; written = 0; while (written < count) { int hunk = count - written; if (hunk >= wsize) hunk = wsize; result = nfs_proc_write(inode, pos, hunk, buf, &fattr); if (result < 0) break; pos += hunk; buf += hunk; written += hunk; if (hunk < wsize) break; } if (!written) return result; file->f_pos = pos; if (pos > inode->i_size) inode->i_size = pos; /* Avoid possible Solaris 2.5 nfsd bug */ if (inode->i_ino == fattr.fileid) nfs_refresh_inode(inode, &fattr); return written; }