MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / fs / fat / prince-fat / fat-cache-atomic / file.c
blobcb0b6a9856d3faba5dff4fd38143f7669d6972e5
1 /*
2 * linux/fs/fat/file.c
4 * Written 1992,1993 by Werner Almesberger
6 * regular file handling primitives for fat-based filesystems
7 */
9 #include <linux/time.h>
10 #include <linux/msdos_fs.h>
11 #include <linux/smp_lock.h>
12 #include <linux/buffer_head.h>
14 static ssize_t fat_file_write(struct file *filp, const char __user *buf,
15 size_t count, loff_t *ppos);
17 struct file_operations fat_file_operations = {
18 .llseek = generic_file_llseek,
19 .read = generic_file_read,
20 .write = fat_file_write,
21 .mmap = generic_file_mmap,
22 .fsync = file_fsync,
23 .readv = generic_file_readv,
24 .writev = generic_file_writev,
25 .sendfile = generic_file_sendfile,
28 struct inode_operations fat_file_inode_operations = {
29 .truncate = fat_truncate,
30 .setattr = fat_notify_change,
33 int fat_get_block(struct inode *inode, sector_t iblock,
34 struct buffer_head *bh_result, int create)
36 struct super_block *sb = inode->i_sb;
37 sector_t phys;
38 int err;
41 err = fat_bmap(inode, iblock, &phys);
42 if (err)
43 return err;
44 if (phys) {
45 map_bh(bh_result, sb, phys);
46 return 0;
48 if (!create)
49 return 0;
50 if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
51 fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)",
52 MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private);
53 return -EIO;
55 if (!((unsigned long)iblock & (MSDOS_SB(sb)->sec_per_clus - 1))) {
56 int error;
58 error = fat_add_cluster(inode);
59 if (error < 0)
60 return error;
62 MSDOS_I(inode)->mmu_private += sb->s_blocksize;
63 err = fat_bmap(inode, iblock, &phys);
64 if (err)
65 return err;
66 if (!phys)
67 BUG();
68 set_buffer_new(bh_result);
69 map_bh(bh_result, sb, phys);
70 return 0;
73 static ssize_t fat_file_write(struct file *filp, const char __user *buf,
74 size_t count, loff_t *ppos)
76 struct inode *inode = filp->f_dentry->d_inode;
77 int retval;
79 retval = generic_file_write(filp, buf, count, ppos);
80 if (retval > 0) {
81 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
82 MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
83 mark_inode_dirty(inode);
85 return retval;
88 void fat_truncate(struct inode *inode)
90 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
91 const unsigned int cluster_size = sbi->cluster_size;
92 int nr_clusters;
94 /*
95 * This protects against truncating a file bigger than it was then
96 * trying to write into the hole.
98 if (MSDOS_I(inode)->mmu_private > inode->i_size)
99 MSDOS_I(inode)->mmu_private = inode->i_size;
101 nr_clusters = (inode->i_size + (cluster_size - 1)) >> sbi->cluster_bits;
103 lock_kernel();
104 fat_free(inode, nr_clusters);
105 MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
106 unlock_kernel();
107 inode->i_ctime = inode->i_mtime = CURRENT_TIME;
108 mark_inode_dirty(inode);