pre-2.3.4..
[davej-history.git] / fs / minix / file.c
blobf6ddda02140c22fc74ae7e6622d78c4699895bf7
1 /*
2 * linux/fs/minix/file.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
6 * minix regular file handling primitives
7 */
9 #include <linux/sched.h>
10 #include <linux/minix_fs.h>
11 #include <linux/kernel.h>
12 #include <linux/errno.h>
13 #include <linux/fcntl.h>
14 #include <linux/stat.h>
15 #include <linux/locks.h>
16 #include <linux/mm.h>
17 #include <linux/pagemap.h>
19 #include <asm/uaccess.h>
20 #include <asm/system.h>
22 #define NBUF 32
24 #define MIN(a,b) (((a)<(b))?(a):(b))
25 #define MAX(a,b) (((a)>(b))?(a):(b))
27 #include <linux/fs.h>
28 #include <linux/minix_fs.h>
30 static ssize_t minix_file_write(struct file *, const char *, size_t, loff_t *);
33 * We have mostly NULLs here: the current defaults are OK for
34 * the minix filesystem.
36 static struct file_operations minix_file_operations = {
37 NULL, /* lseek - default */
38 generic_file_read, /* read */
39 minix_file_write, /* write */
40 NULL, /* readdir - bad */
41 NULL, /* poll - default */
42 NULL, /* ioctl - default */
43 generic_file_mmap, /* mmap */
44 NULL, /* no special open is needed */
45 NULL, /* flush */
46 NULL, /* release */
47 minix_sync_file /* fsync */
50 struct inode_operations minix_file_inode_operations = {
51 &minix_file_operations, /* default file operations */
52 NULL, /* create */
53 NULL, /* lookup */
54 NULL, /* link */
55 NULL, /* unlink */
56 NULL, /* symlink */
57 NULL, /* mkdir */
58 NULL, /* rmdir */
59 NULL, /* mknod */
60 NULL, /* rename */
61 NULL, /* readlink */
62 NULL, /* follow_link */
63 generic_readpage, /* readpage */
64 NULL, /* writepage */
65 minix_bmap, /* bmap */
66 minix_truncate, /* truncate */
67 NULL /* permission */
70 static ssize_t minix_file_write(struct file * filp, const char * buf,
71 size_t count, loff_t *ppos)
73 struct inode * inode = filp->f_dentry->d_inode;
74 off_t pos;
75 ssize_t written, c;
76 struct buffer_head * bh;
77 char * p;
79 if (!inode) {
80 printk("minix_file_write: inode = NULL\n");
81 return -EINVAL;
83 if (!S_ISREG(inode->i_mode)) {
84 printk("minix_file_write: mode = %07o\n",inode->i_mode);
85 return -EINVAL;
87 if (filp->f_flags & O_APPEND)
88 pos = inode->i_size;
89 else
90 pos = *ppos;
91 written = 0;
92 while (written < count) {
93 bh = minix_getblk(inode,pos/BLOCK_SIZE,1);
94 if (!bh) {
95 if (!written)
96 written = -ENOSPC;
97 break;
99 c = BLOCK_SIZE - (pos % BLOCK_SIZE);
100 if (c > count-written)
101 c = count-written;
102 if (c != BLOCK_SIZE && !buffer_uptodate(bh)) {
103 ll_rw_block(READ, 1, &bh);
104 wait_on_buffer(bh);
105 if (!buffer_uptodate(bh)) {
106 brelse(bh);
107 if (!written)
108 written = -EIO;
109 break;
112 p = (pos % BLOCK_SIZE) + bh->b_data;
113 c -= copy_from_user(p,buf,c);
114 if (!c) {
115 brelse(bh);
116 if (!written)
117 written = -EFAULT;
118 break;
120 update_vm_cache(inode, pos, p, c);
121 mark_buffer_uptodate(bh, 1);
122 mark_buffer_dirty(bh, 0);
123 brelse(bh);
124 pos += c;
125 written += c;
126 buf += c;
128 if (pos > inode->i_size)
129 inode->i_size = pos;
130 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
131 *ppos = pos;
132 mark_inode_dirty(inode);
133 return written;