Blame view
fs/coda/file.c
6.23 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* * File operations for Coda. * Original version: (C) 1996 Peter Braam * Rewritten for Linux 2.1: (C) 1997 Carnegie Mellon University * * Carnegie Mellon encourages users of this code to contribute improvements * to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>. */ #include <linux/types.h> #include <linux/kernel.h> #include <linux/time.h> #include <linux/file.h> #include <linux/fs.h> #include <linux/stat.h> |
7596b27db coda: fix creds r... |
16 |
#include <linux/cred.h> |
1da177e4c Linux-2.6.12-rc2 |
17 |
#include <linux/errno.h> |
b5ce1d83a Coda: add spin lo... |
18 |
#include <linux/spinlock.h> |
1da177e4c Linux-2.6.12-rc2 |
19 |
#include <linux/string.h> |
5a0e3ad6a include cleanup: ... |
20 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
21 22 23 |
#include <asm/uaccess.h> #include <linux/coda.h> |
1da177e4c Linux-2.6.12-rc2 |
24 |
#include <linux/coda_psdev.h> |
1da177e4c Linux-2.6.12-rc2 |
25 |
|
31a203df9 take coda-private... |
26 |
#include "coda_linux.h" |
c98d8cfbc [PATCH] fs/coda/:... |
27 |
#include "coda_int.h" |
1da177e4c Linux-2.6.12-rc2 |
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
static ssize_t coda_file_read(struct file *coda_file, char __user *buf, size_t count, loff_t *ppos) { struct coda_file_info *cfi; struct file *host_file; cfi = CODA_FTOC(coda_file); BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); host_file = cfi->cfi_container; if (!host_file->f_op || !host_file->f_op->read) return -EINVAL; return host_file->f_op->read(host_file, buf, count, ppos); } static ssize_t |
5ffc4ef45 sendfile: remove ... |
45 46 47 |
coda_file_splice_read(struct file *coda_file, loff_t *ppos, struct pipe_inode_info *pipe, size_t count, unsigned int flags) |
1da177e4c Linux-2.6.12-rc2 |
48 |
{ |
6818173bd splice: implement... |
49 50 |
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); |
1da177e4c Linux-2.6.12-rc2 |
51 52 53 54 55 56 |
struct coda_file_info *cfi; struct file *host_file; cfi = CODA_FTOC(coda_file); BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); host_file = cfi->cfi_container; |
6818173bd splice: implement... |
57 58 59 |
splice_read = host_file->f_op->splice_read; if (!splice_read) splice_read = default_file_splice_read; |
1da177e4c Linux-2.6.12-rc2 |
60 |
|
6818173bd splice: implement... |
61 |
return splice_read(host_file, ppos, pipe, count, flags); |
1da177e4c Linux-2.6.12-rc2 |
62 63 64 65 66 |
} static ssize_t coda_file_write(struct file *coda_file, const char __user *buf, size_t count, loff_t *ppos) { |
d4176d326 [PATCH] struct pa... |
67 |
struct inode *host_inode, *coda_inode = coda_file->f_path.dentry->d_inode; |
1da177e4c Linux-2.6.12-rc2 |
68 69 70 71 72 73 74 75 76 77 |
struct coda_file_info *cfi; struct file *host_file; ssize_t ret; cfi = CODA_FTOC(coda_file); BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); host_file = cfi->cfi_container; if (!host_file->f_op || !host_file->f_op->write) return -EINVAL; |
d4176d326 [PATCH] struct pa... |
78 |
host_inode = host_file->f_path.dentry->d_inode; |
1b1dcc1b5 [PATCH] mutex sub... |
79 |
mutex_lock(&coda_inode->i_mutex); |
1da177e4c Linux-2.6.12-rc2 |
80 81 82 83 84 85 |
ret = host_file->f_op->write(host_file, buf, count, ppos); coda_inode->i_size = host_inode->i_size; coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9; coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME_SEC; |
1b1dcc1b5 [PATCH] mutex sub... |
86 |
mutex_unlock(&coda_inode->i_mutex); |
1da177e4c Linux-2.6.12-rc2 |
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
return ret; } static int coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma) { struct coda_file_info *cfi; struct coda_inode_info *cii; struct file *host_file; struct inode *coda_inode, *host_inode; cfi = CODA_FTOC(coda_file); BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); host_file = cfi->cfi_container; if (!host_file->f_op || !host_file->f_op->mmap) return -ENODEV; |
d4176d326 [PATCH] struct pa... |
105 106 |
coda_inode = coda_file->f_path.dentry->d_inode; host_inode = host_file->f_path.dentry->d_inode; |
b5ce1d83a Coda: add spin lo... |
107 108 109 |
cii = ITOC(coda_inode); spin_lock(&cii->c_lock); |
1da177e4c Linux-2.6.12-rc2 |
110 111 112 113 114 115 |
coda_file->f_mapping = host_file->f_mapping; if (coda_inode->i_mapping == &coda_inode->i_data) coda_inode->i_mapping = host_inode->i_mapping; /* only allow additional mmaps as long as userspace isn't changing * the container file on us! */ |
b5ce1d83a Coda: add spin lo... |
116 117 |
else if (coda_inode->i_mapping != host_inode->i_mapping) { spin_unlock(&cii->c_lock); |
1da177e4c Linux-2.6.12-rc2 |
118 |
return -EBUSY; |
b5ce1d83a Coda: add spin lo... |
119 |
} |
1da177e4c Linux-2.6.12-rc2 |
120 121 |
/* keep track of how often the coda_inode/host_file has been mmapped */ |
1da177e4c Linux-2.6.12-rc2 |
122 123 |
cii->c_mapcount++; cfi->cfi_mapcount++; |
b5ce1d83a Coda: add spin lo... |
124 |
spin_unlock(&cii->c_lock); |
1da177e4c Linux-2.6.12-rc2 |
125 126 127 128 129 130 131 132 133 134 135 |
return host_file->f_op->mmap(host_file, vma); } int coda_open(struct inode *coda_inode, struct file *coda_file) { struct file *host_file = NULL; int error; unsigned short flags = coda_file->f_flags & (~O_EXCL); unsigned short coda_flags = coda_flags_to_cflags(flags); struct coda_file_info *cfi; |
1da177e4c Linux-2.6.12-rc2 |
136 |
cfi = kmalloc(sizeof(struct coda_file_info), GFP_KERNEL); |
6ecbc4e1a [PATCH] Remove in... |
137 |
if (!cfi) |
1da177e4c Linux-2.6.12-rc2 |
138 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
139 |
|
1da177e4c Linux-2.6.12-rc2 |
140 |
error = venus_open(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags, |
38c2e4370 coda: do not grab... |
141 142 143 144 145 |
&host_file); if (!host_file) error = -EIO; if (error) { |
1da177e4c Linux-2.6.12-rc2 |
146 |
kfree(cfi); |
1da177e4c Linux-2.6.12-rc2 |
147 148 149 150 151 152 153 154 155 156 157 |
return error; } host_file->f_flags |= coda_file->f_flags & (O_APPEND | O_SYNC); cfi->cfi_magic = CODA_MAGIC; cfi->cfi_mapcount = 0; cfi->cfi_container = host_file; BUG_ON(coda_file->private_data != NULL); coda_file->private_data = cfi; |
1da177e4c Linux-2.6.12-rc2 |
158 159 |
return 0; } |
1da177e4c Linux-2.6.12-rc2 |
160 161 162 163 164 165 166 |
int coda_release(struct inode *coda_inode, struct file *coda_file) { unsigned short flags = (coda_file->f_flags) & (~O_EXCL); unsigned short coda_flags = coda_flags_to_cflags(flags); struct coda_file_info *cfi; struct coda_inode_info *cii; struct inode *host_inode; |
f7cc02b87 Coda: push BKL re... |
167 |
int err; |
3cf01f28c coda: remove stat... |
168 |
|
1da177e4c Linux-2.6.12-rc2 |
169 170 |
cfi = CODA_FTOC(coda_file); BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); |
d3fec424b coda: remove CODA... |
171 |
err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode), |
d76b0d9b2 CRED: Use creds i... |
172 |
coda_flags, coda_file->f_cred->fsuid); |
1da177e4c Linux-2.6.12-rc2 |
173 |
|
d4176d326 [PATCH] struct pa... |
174 |
host_inode = cfi->cfi_container->f_path.dentry->d_inode; |
1da177e4c Linux-2.6.12-rc2 |
175 176 177 |
cii = ITOC(coda_inode); /* did we mmap this file? */ |
b5ce1d83a Coda: add spin lo... |
178 |
spin_lock(&cii->c_lock); |
1da177e4c Linux-2.6.12-rc2 |
179 180 181 182 183 |
if (coda_inode->i_mapping == &host_inode->i_data) { cii->c_mapcount -= cfi->cfi_mapcount; if (!cii->c_mapcount) coda_inode->i_mapping = &coda_inode->i_data; } |
b5ce1d83a Coda: add spin lo... |
184 |
spin_unlock(&cii->c_lock); |
1da177e4c Linux-2.6.12-rc2 |
185 186 187 188 |
fput(cfi->cfi_container); kfree(coda_file->private_data); coda_file->private_data = NULL; |
d3fec424b coda: remove CODA... |
189 190 191 |
/* VFS fput ignores the return value from file_operations->release, so * there is no use returning an error here */ return 0; |
1da177e4c Linux-2.6.12-rc2 |
192 |
} |
02c24a821 fs: push i_mutex ... |
193 |
int coda_fsync(struct file *coda_file, loff_t start, loff_t end, int datasync) |
1da177e4c Linux-2.6.12-rc2 |
194 195 |
{ struct file *host_file; |
7ea808591 drop unused dentr... |
196 |
struct inode *coda_inode = coda_file->f_path.dentry->d_inode; |
1da177e4c Linux-2.6.12-rc2 |
197 |
struct coda_file_info *cfi; |
f7cc02b87 Coda: push BKL re... |
198 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
199 200 201 202 |
if (!(S_ISREG(coda_inode->i_mode) || S_ISDIR(coda_inode->i_mode) || S_ISLNK(coda_inode->i_mode))) return -EINVAL; |
02c24a821 fs: push i_mutex ... |
203 204 205 206 |
err = filemap_write_and_wait_range(coda_inode->i_mapping, start, end); if (err) return err; mutex_lock(&coda_inode->i_mutex); |
1da177e4c Linux-2.6.12-rc2 |
207 208 209 |
cfi = CODA_FTOC(coda_file); BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); host_file = cfi->cfi_container; |
8018ab057 sanitize vfs_fsyn... |
210 |
err = vfs_fsync(host_file, datasync); |
f7cc02b87 Coda: push BKL re... |
211 |
if (!err && !datasync) |
1da177e4c Linux-2.6.12-rc2 |
212 |
err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode)); |
02c24a821 fs: push i_mutex ... |
213 |
mutex_unlock(&coda_inode->i_mutex); |
1da177e4c Linux-2.6.12-rc2 |
214 215 216 |
return err; } |
4b6f5d20b [PATCH] Make most... |
217 |
const struct file_operations coda_file_operations = { |
1da177e4c Linux-2.6.12-rc2 |
218 219 220 221 222 |
.llseek = generic_file_llseek, .read = coda_file_read, .write = coda_file_write, .mmap = coda_file_mmap, .open = coda_open, |
1da177e4c Linux-2.6.12-rc2 |
223 224 |
.release = coda_release, .fsync = coda_fsync, |
5ffc4ef45 sendfile: remove ... |
225 |
.splice_read = coda_file_splice_read, |
1da177e4c Linux-2.6.12-rc2 |
226 |
}; |