2 * File operations for Coda.
3 * Original version: (C) 1996 Peter Braam
4 * Rewritten for Linux 2.1: (C) 1997 Carnegie Mellon University
6 * Carnegie Mellon encourages users of this code to contribute improvements
7 * to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>.
10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/sched.h>
14 #include <linux/stat.h>
15 #include <linux/errno.h>
16 #include <linux/locks.h>
17 #include <asm/segment.h>
18 #include <linux/string.h>
19 #include <asm/uaccess.h>
21 #include <linux/coda.h>
22 #include <linux/coda_linux.h>
23 #include <linux/coda_fs_i.h>
24 #include <linux/coda_psdev.h>
25 #include <linux/coda_cache.h>
26 #include <linux/coda_proc.h>
29 static int coda_readpage(struct file
*file
, struct page
* page
);
30 static ssize_t
coda_file_read(struct file
*f
, char *buf
, size_t count
, loff_t
*off
);
31 static ssize_t
coda_file_write(struct file
*f
, const char *buf
, size_t count
, loff_t
*off
);
32 static int coda_file_mmap(struct file
* file
, struct vm_area_struct
* vma
);
34 /* also exported from this file (used for dirs) */
35 int coda_fsync(struct file
*, struct dentry
*dentry
);
37 struct inode_operations coda_file_inode_operations
= {
38 &coda_file_operations
, /* default file operations */
49 NULL
, /* follow_link */
51 coda_readpage
, /* readpage */
55 coda_permission
, /* permission */
57 coda_revalidate_inode
/* revalidate */
60 struct file_operations coda_file_operations
= {
61 NULL
, /* lseek - default should work for coda */
62 coda_file_read
, /* read */
63 coda_file_write
, /* write */
65 NULL
, /* select - default */
67 coda_file_mmap
, /* mmap */
70 coda_release
, /* release */
71 coda_fsync
, /* fsync */
73 NULL
, /* check_media_change */
74 NULL
, /* revalidate */
78 /* File file operations */
79 static int coda_readpage(struct file
* coda_file
, struct page
* page
)
81 struct dentry
*de
= coda_file
->f_dentry
;
82 struct inode
*coda_inode
= de
->d_inode
;
83 struct dentry cont_dentry
;
84 struct file cont_file
;
85 struct coda_inode_info
*cii
;
88 coda_vfs_stat
.readpage
++;
90 cii
= ITOC(coda_inode
);
93 printk("coda_readpage: no open inode for ino %ld, %s\n",
94 coda_inode
->i_ino
, de
->d_name
.name
);
98 coda_prepare_openfile(coda_inode
, coda_file
, cii
->c_ovp
,
99 &cont_file
, &cont_dentry
);
101 CDEBUG(D_INODE
, "coda ino: %ld, cached ino %ld, page offset: %lx\n",
102 coda_inode
->i_ino
, cii
->c_ovp
->i_ino
, page
->offset
);
104 block_read_full_page(&cont_file
, page
);
109 static int coda_file_mmap(struct file
* file
, struct vm_area_struct
* vma
)
111 struct coda_inode_info
*cii
;
114 coda_vfs_stat
.file_mmap
++;
117 cii
= ITOC(file
->f_dentry
->d_inode
);
120 res
=generic_file_mmap(file
, vma
);
125 static ssize_t
coda_file_read(struct file
*coda_file
, char *buff
,
126 size_t count
, loff_t
*ppos
)
128 struct coda_inode_info
*cnp
;
129 struct inode
*coda_inode
= coda_file
->f_dentry
->d_inode
;
130 struct inode
*cont_inode
= NULL
;
131 struct file cont_file
;
132 struct dentry cont_dentry
;
136 coda_vfs_stat
.file_read
++;
138 cnp
= ITOC(coda_inode
);
141 cont_inode
= cnp
->c_ovp
;
142 if ( cont_inode
== NULL
) {
143 printk("coda_file_read: cached inode is 0!\n");
147 coda_prepare_openfile(coda_inode
, coda_file
, cont_inode
,
148 &cont_file
, &cont_dentry
);
150 if (!cont_file
.f_op
|| ! cont_file
.f_op
->read
) {
151 printk( "container file has no read in file operations.\n");
155 result
= cont_file
.f_op
->read(&cont_file
, buff
, count
,
158 CDEBUG(D_FILE
, "ops at %p result %d, count %ld, position: %d\n",
159 cont_file
.f_op
, result
, (long)count
, (int)cont_file
.f_pos
);
161 coda_restore_codafile(coda_inode
, coda_file
, cont_inode
, &cont_file
);
166 static ssize_t
coda_file_write(struct file
*coda_file
, const char *buff
,
167 size_t count
, loff_t
*ppos
)
169 struct coda_inode_info
*cnp
;
170 struct inode
*coda_inode
= coda_file
->f_dentry
->d_inode
;
171 struct inode
*cont_inode
= NULL
;
172 struct file cont_file
;
173 struct dentry cont_dentry
;
177 coda_vfs_stat
.file_write
++;
179 cnp
= ITOC(coda_inode
);
182 cont_inode
= cnp
->c_ovp
;
183 if ( cont_inode
== NULL
) {
184 printk("coda_file_write: cached inode is 0!\n");
188 coda_prepare_openfile(coda_inode
, coda_file
, cont_inode
,
189 &cont_file
, &cont_dentry
);
191 if (!cont_file
.f_op
|| !cont_file
.f_op
->write
) {
192 printk("coda_file_write: container file has no file ops.\n");
196 down(&cont_inode
->i_sem
);
197 result
= cont_file
.f_op
->write(&cont_file
, buff
, count
,
199 up(&cont_inode
->i_sem
);
200 coda_restore_codafile(coda_inode
, coda_file
, cont_inode
, &cont_file
);
203 cnp
->c_flags
|= C_VATTR
;
208 int coda_fsync(struct file
*coda_file
, struct dentry
*coda_dentry
)
210 struct coda_inode_info
*cnp
;
211 struct inode
*coda_inode
= coda_dentry
->d_inode
;
212 struct inode
*cont_inode
= NULL
;
213 struct file cont_file
;
214 struct dentry cont_dentry
;
217 coda_vfs_stat
.fsync
++;
219 if (!(S_ISREG(coda_inode
->i_mode
) || S_ISDIR(coda_inode
->i_mode
) ||
220 S_ISLNK(coda_inode
->i_mode
)))
223 cnp
= ITOC(coda_inode
);
226 cont_inode
= cnp
->c_ovp
;
227 if ( cont_inode
== NULL
) {
228 printk("coda_file_write: cached inode is 0!\n");
232 coda_prepare_openfile(coda_inode
, coda_file
, cont_inode
,
233 &cont_file
, &cont_dentry
);
235 down(&cont_inode
->i_sem
);
237 result
= file_fsync(&cont_file
,&cont_dentry
);
239 result
= venus_fsync(coda_inode
->i_sb
, &(cnp
->c_fid
));
242 up(&cont_inode
->i_sem
);
244 coda_restore_codafile(coda_inode
, coda_file
, cont_inode
, &cont_file
);
251 /* instantiate the container file and dentry object to do io */
252 void coda_prepare_openfile(struct inode
*i
, struct file
*coda_file
,
253 struct inode
*cont_inode
, struct file
*cont_file
,
254 struct dentry
*cont_dentry
)
256 cont_file
->f_pos
= coda_file
->f_pos
;
257 cont_file
->f_mode
= coda_file
->f_mode
;
258 cont_file
->f_flags
= coda_file
->f_flags
;
259 atomic_set(&cont_file
->f_count
, atomic_read(&coda_file
->f_count
));
260 cont_file
->f_owner
= coda_file
->f_owner
;
261 cont_file
->f_op
= cont_inode
->i_op
->default_file_ops
;
262 cont_file
->f_dentry
= cont_dentry
;
263 cont_file
->f_dentry
->d_inode
= cont_inode
;
267 /* update the Coda file & inode after I/O */
268 void coda_restore_codafile(struct inode
*coda_inode
, struct file
*coda_file
,
269 struct inode
*open_inode
, struct file
*open_file
)
271 coda_file
->f_pos
= open_file
->f_pos
;
272 /* XXX what about setting the mtime here too? */
273 /* coda_inode->i_mtime = open_inode->i_mtime; */
274 coda_inode
->i_size
= open_inode
->i_size
;
278 /* grab the ext2 inode of the container file */
279 int coda_inode_grab(dev_t dev
, ino_t ino
, struct inode
**ind
)
281 struct super_block
*sbptr
;
283 sbptr
= get_super(dev
);
286 printk("coda_inode_grab: coda_find_super returns NULL.\n");
291 *ind
= iget(sbptr
, ino
);
293 if ( *ind
== NULL
) {
294 printk("coda_inode_grab: iget(dev: %d, ino: %ld)
295 returns NULL.\n", dev
, (long)ino
);
298 CDEBUG(D_FILE
, "ino: %ld, ops at %p\n", (long)ino
, (*ind
)->i_op
);