4 * Written 1992,1993 by Werner Almesberger
6 * regular file handling primitives for fat-based filesystems
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
,
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
,
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
;
38 err
= fat_bmap(inode
, iblock
, &phys
);
42 map_bh(bh_result
, sb
, phys
);
47 if (iblock
!= MSDOS_I(inode
)->mmu_private
>> sb
->s_blocksize_bits
) {
51 if (!((unsigned long)iblock
% MSDOS_SB(sb
)->sec_per_clus
)) {
54 error
= fat_add_cluster(inode
);
58 MSDOS_I(inode
)->mmu_private
+= sb
->s_blocksize
;
59 err
= fat_bmap(inode
, iblock
, &phys
);
64 set_buffer_new(bh_result
);
65 map_bh(bh_result
, sb
, phys
);
69 static ssize_t
fat_file_write(struct file
*filp
, const char *buf
, size_t count
,
72 struct inode
*inode
= filp
->f_dentry
->d_inode
;
75 retval
= generic_file_write(filp
, buf
, count
, ppos
);
77 inode
->i_mtime
= inode
->i_ctime
= CURRENT_TIME
;
78 MSDOS_I(inode
)->i_attrs
|= ATTR_ARCH
;
79 mark_inode_dirty(inode
);
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
;
90 /* Why no return value? Surely the disk could fail... */
91 if (IS_RDONLY (inode
))
93 if (IS_IMMUTABLE(inode
))
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
;
106 fat_free(inode
, nr_clusters
);
107 MSDOS_I(inode
)->i_attrs
|= ATTR_ARCH
;
109 inode
->i_ctime
= inode
->i_mtime
= CURRENT_TIME
;
110 mark_inode_dirty(inode
);