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