1 /*
2 * linux/fs/fat/file.c
3 *
4 * Written 1992,1993 by Werner Almesberger
5 *
6 * regular file handling primitives for fat-based filesystems
7 */
8
9 #define ASC_LINUX_VERSION(V, P, S) (((V) * 65536) + ((P) * 256) + (S))
10 #include <linux/version.h>
11 #include <linux/sched.h>
12 #include <linux/locks.h>
13 #include <linux/fs.h>
14 #include <linux/msdos_fs.h>
15 #include <linux/errno.h>
16 #include <linux/fcntl.h>
17 #include <linux/stat.h>
18 #include <linux/string.h>
19 #include <linux/pagemap.h>
20 #include <linux/fat_cvf.h>
21
22 #include <asm/uaccess.h>
23 #include <asm/system.h>
24
25 #include "msbuffer.h"
26
27 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
28 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
29
30 #define PRINTK(x)
31 #define Printk(x) printk x
32
33 struct file_operations fat_file_operations = {
34 read: fat_file_read,
35 write: fat_file_write,
36 mmap: generic_file_mmap,
37 fsync: file_fsync,
38 };
39
40 struct inode_operations fat_file_inode_operations = {
41 truncate: fat_truncate,
42 setattr: fat_notify_change,
43 };
44
45 ssize_t fat_file_read(
46 struct file *filp,
47 char *buf,
48 size_t count,
49 loff_t *ppos)
50 {
51 struct inode *inode = filp->f_dentry->d_inode;
52 return MSDOS_SB(inode->i_sb)->cvf_format
53 ->cvf_file_read(filp,buf,count,ppos);
54 }
55
56
57 int fat_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create) {
58 unsigned long phys;
59 phys = fat_bmap(inode, iblock);
60 if (phys) {
61 bh_result->b_dev = inode->i_dev;
62 bh_result->b_blocknr = phys;
63 bh_result->b_state |= (1UL << BH_Mapped);
64 return 0;
65 }
66 if (!create)
67 return 0;
68 if (iblock<<9 != MSDOS_I(inode)->mmu_private) {
69 BUG();
70 return -EIO;
71 }
72 if (!(iblock % MSDOS_SB(inode->i_sb)->cluster_size)) {
73 if (fat_add_cluster(inode))
74 return -ENOSPC;
75 }
76 MSDOS_I(inode)->mmu_private += 512;
77 phys=fat_bmap(inode, iblock);
78 if (!phys)
79 BUG();
80 bh_result->b_dev = inode->i_dev;
81 bh_result->b_blocknr = phys;
82 bh_result->b_state |= (1UL << BH_Mapped);
83 bh_result->b_state |= (1UL << BH_New);
84 return 0;
85 }
86
87 ssize_t fat_file_write(
88 struct file *filp,
89 const char *buf,
90 size_t count,
91 loff_t *ppos)
92 {
93 struct inode *inode = filp->f_dentry->d_inode;
94 struct super_block *sb = inode->i_sb;
95 return MSDOS_SB(sb)->cvf_format
96 ->cvf_file_write(filp,buf,count,ppos);
97 }
98
99 ssize_t default_fat_file_write(
100 struct file *filp,
101 const char *buf,
102 size_t count,
103 loff_t *ppos)
104 {
105 struct inode *inode = filp->f_dentry->d_inode;
106 int retval;
107
108 retval = generic_file_write(filp, buf, count, ppos);
109 if (retval > 0) {
110 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
111 MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
112 mark_inode_dirty(inode);
113 }
114 return retval;
115 }
116
117 void fat_truncate(struct inode *inode)
118 {
119 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
120 int cluster;
121
122 /* Why no return value? Surely the disk could fail... */
123 if (IS_RDONLY (inode))
124 return /* -EPERM */;
125 if (IS_IMMUTABLE(inode))
126 return /* -EPERM */;
127 cluster = SECTOR_SIZE*sbi->cluster_size;
128 /*
129 * This protects against truncating a file bigger than it was then
130 * trying to write into the hole.
131 */
132 if (MSDOS_I(inode)->mmu_private > inode->i_size)
133 MSDOS_I(inode)->mmu_private = inode->i_size;
134
135 fat_free(inode,(inode->i_size+(cluster-1))>>sbi->cluster_bits);
136 MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
137 inode->i_ctime = inode->i_mtime = CURRENT_TIME;
138 mark_inode_dirty(inode);
139 }
140
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.