[PATCH] ->cluster_size cleanup (11/11)
[linux-2.6/history.git] / fs / fat / file.c
blob029190ca34e3e5fbb3dcf3d2a8a46a1952308894
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 *buf, size_t count,
15 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 .sendfile = generic_file_sendfile,
26 struct inode_operations fat_file_inode_operations = {
27 .truncate = fat_truncate,
28 .setattr = fat_notify_change,
31 int fat_get_block(struct inode *inode, sector_t iblock,
32 struct buffer_head *bh_result, int create)
34 struct super_block *sb = inode->i_sb;
35 sector_t phys;
36 int err;
38 err = fat_bmap(inode, iblock, &phys);
39 if (err)
40 return err;
41 if (phys) {
42 map_bh(bh_result, sb, phys);
43 return 0;
45 if (!create)
46 return 0;
47 if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
48 BUG();
49 return -EIO;
51 if (!((unsigned long)iblock % MSDOS_SB(sb)->sec_per_clus)) {
52 int error;
54 error = fat_add_cluster(inode);
55 if (error < 0)
56 return error;
58 MSDOS_I(inode)->mmu_private += sb->s_blocksize;
59 err = fat_bmap(inode, iblock, &phys);
60 if (err)
61 return err;
62 if (!phys)
63 BUG();
64 set_buffer_new(bh_result);
65 map_bh(bh_result, sb, phys);
66 return 0;
69 static ssize_t fat_file_write(struct file *filp, const char *buf, size_t count,
70 loff_t *ppos)
72 struct inode *inode = filp->f_dentry->d_inode;
73 int retval;
75 retval = generic_file_write(filp, buf, count, ppos);
76 if (retval > 0) {
77 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
78 MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
79 mark_inode_dirty(inode);
81 return retval;
84 void fat_truncate(struct inode *inode)
86 struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
87 const unsigned int cluster_size = sbi->cluster_size;
88 int nr_clusters;
90 /* Why no return value? Surely the disk could fail... */
91 if (IS_RDONLY (inode))
92 return /* -EPERM */;
93 if (IS_IMMUTABLE(inode))
94 return /* -EPERM */;
96 /*
97 * This protects against truncating a file bigger than it was then
98 * trying to write into the hole.
100 if (MSDOS_I(inode)->mmu_private > inode->i_size)
101 MSDOS_I(inode)->mmu_private = inode->i_size;
103 nr_clusters = (inode->i_size + (cluster_size - 1)) >> sbi->cluster_bits;
105 lock_kernel();
106 fat_free(inode, nr_clusters);
107 MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
108 unlock_kernel();
109 inode->i_ctime = inode->i_mtime = CURRENT_TIME;
110 mark_inode_dirty(inode);