Annotation of linux/fs/ext/file.c, revision 1.1.1.3

1.1       root        1: /*
                      2:  *  linux/fs/ext/file.c
                      3:  *
1.1.1.2   root        4:  *  Copyright (C) 1992 Remy Card ([email protected])
1.1       root        5:  *
                      6:  *  from
                      7:  *
                      8:  *  linux/fs/minix/file.c
                      9:  *
1.1.1.2   root       10:  *  Copyright (C) 1991, 1992 Linus Torvalds
1.1       root       11:  *
                     12:  *  ext regular file handling primitives
                     13:  */
                     14: 
                     15: #include <asm/segment.h>
                     16: #include <asm/system.h>
                     17: 
                     18: #include <linux/sched.h>
                     19: #include <linux/ext_fs.h>
                     20: #include <linux/kernel.h>
1.1.1.2   root       21: #include <linux/errno.h>
                     22: #include <linux/fcntl.h>
1.1       root       23: #include <linux/stat.h>
                     24: 
                     25: #define        NBUF    16
                     26: 
                     27: #define MIN(a,b) (((a)<(b))?(a):(b))
                     28: #define MAX(a,b) (((a)>(b))?(a):(b))
                     29: 
                     30: #include <linux/fs.h>
                     31: #include <linux/ext_fs.h>
                     32: 
1.1.1.3 ! root       33: static inline void wait_on_buffer(struct buffer_head * bh)
        !            34: {
        !            35:        cli();
        !            36:        while (bh->b_lock)
        !            37:                sleep_on(&bh->b_wait);
        !            38:        sti();
        !            39: }
        !            40: 
1.1       root       41: static int ext_file_read(struct inode *, struct file *, char *, int);
                     42: static int ext_file_write(struct inode *, struct file *, char *, int);
                     43: 
                     44: /*
                     45:  * We have mostly NULL's here: the current defaults are ok for
                     46:  * the ext filesystem.
                     47:  */
                     48: static struct file_operations ext_file_operations = {
                     49:        NULL,                   /* lseek - default */
                     50:        ext_file_read,  /* read */
                     51:        ext_file_write, /* write */
                     52:        NULL,                   /* readdir - bad */
                     53:        NULL,                   /* select - default */
                     54:        NULL,                   /* ioctl - default */
                     55:        NULL,                   /* no special open is needed */
                     56:        NULL                    /* release */
                     57: };
                     58: 
                     59: struct inode_operations ext_file_inode_operations = {
                     60:        &ext_file_operations,   /* default file operations */
                     61:        NULL,                   /* create */
                     62:        NULL,                   /* lookup */
                     63:        NULL,                   /* link */
                     64:        NULL,                   /* unlink */
                     65:        NULL,                   /* symlink */
                     66:        NULL,                   /* mkdir */
                     67:        NULL,                   /* rmdir */
                     68:        NULL,                   /* mknod */
                     69:        NULL,                   /* rename */
                     70:        NULL,                   /* readlink */
                     71:        NULL,                   /* follow_link */
                     72:        ext_bmap,               /* bmap */
                     73:        ext_truncate            /* truncate */
                     74: };
                     75: 
                     76: static int ext_file_read(struct inode * inode, struct file * filp, char * buf, int count)
                     77: {
1.1.1.3 ! root       78:        int read,left,chars;
1.1       root       79:        int block, blocks, offset;
                     80:        struct buffer_head ** bhb, ** bhe;
                     81:        struct buffer_head * buflist[NBUF];
                     82: 
                     83:        if (!inode) {
                     84:                printk("ext_file_read: inode = NULL\n");
                     85:                return -EINVAL;
                     86:        }
                     87:        if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
                     88:                printk("ext_file_read: mode = %07o\n",inode->i_mode);
                     89:                return -EINVAL;
                     90:        }
                     91:        if (filp->f_pos > inode->i_size)
                     92:                left = 0;
                     93:        else
                     94:                left = inode->i_size - filp->f_pos;
                     95:        if (left > count)
                     96:                left = count;
                     97:        if (left <= 0)
                     98:                return 0;
                     99:        read = 0;
                    100:        block = filp->f_pos >> BLOCK_SIZE_BITS;
                    101:        offset = filp->f_pos & (BLOCK_SIZE-1);
                    102:        blocks = (left + offset + BLOCK_SIZE - 1) / BLOCK_SIZE;
                    103:        bhb = bhe = buflist;
                    104:        do {
                    105:                if (blocks) {
                    106:                        --blocks;
1.1.1.3 ! root      107:                        *bhb = ext_getblk(inode,block++,0);
        !           108:                        if (*bhb && !(*bhb)->b_uptodate)
        !           109:                                ll_rw_block(READ,*bhb);
1.1       root      110: 
                    111:                        if (++bhb == &buflist[NBUF])
                    112:                                bhb = buflist;
                    113: 
                    114:                        if (bhb != bhe)
                    115:                                continue;
                    116:                }
                    117:                if (*bhe) {
                    118:                        wait_on_buffer(*bhe);
                    119:                        if (!(*bhe)->b_uptodate) {
                    120:                                do {
                    121:                                        brelse(*bhe);
                    122:                                        if (++bhe == &buflist[NBUF])
                    123:                                                bhe = buflist;
                    124:                                } while (bhe != bhb);
                    125:                                break;
                    126:                        }
                    127:                }
                    128: 
                    129:                if (left < BLOCK_SIZE - offset)
                    130:                        chars = left;
                    131:                else
                    132:                        chars = BLOCK_SIZE - offset;
                    133:                filp->f_pos += chars;
                    134:                left -= chars;
                    135:                read += chars;
                    136:                if (*bhe) {
                    137:                        memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
                    138:                        brelse(*bhe);
                    139:                        buf += chars;
                    140:                } else {
                    141:                        while (chars-->0)
                    142:                                put_fs_byte(0,buf++);
                    143:                }
                    144:                offset = 0;
                    145:                if (++bhe == &buflist[NBUF])
                    146:                        bhe = buflist;
                    147:        } while (left > 0);
                    148:        if (!read)
                    149:                return -EIO;
1.1.1.2   root      150:        if (!IS_RDONLY(inode)) {
                    151:                inode->i_atime = CURRENT_TIME;
                    152:                inode->i_dirt = 1;
                    153:        }
1.1       root      154:        return read;
                    155: }
                    156: 
                    157: static int ext_file_write(struct inode * inode, struct file * filp, char * buf, int count)
                    158: {
                    159:        off_t pos;
1.1.1.3 ! root      160:        int written,c;
1.1       root      161:        struct buffer_head * bh;
                    162:        char * p;
                    163: 
                    164:        if (!inode) {
                    165:                printk("ext_file_write: inode = NULL\n");
                    166:                return -EINVAL;
                    167:        }
                    168:        if (!S_ISREG(inode->i_mode)) {
                    169:                printk("ext_file_write: mode = %07o\n",inode->i_mode);
                    170:                return -EINVAL;
                    171:        }
                    172: /*
                    173:  * ok, append may not work when many processes are writing at the same time
                    174:  * but so what. That way leads to madness anyway.
                    175:  */
                    176:        if (filp->f_flags & O_APPEND)
                    177:                pos = inode->i_size;
                    178:        else
                    179:                pos = filp->f_pos;
                    180:        written = 0;
                    181:        while (written<count) {
1.1.1.3 ! root      182:                bh = ext_getblk(inode,pos/BLOCK_SIZE,1);
        !           183:                if (!bh) {
1.1       root      184:                        if (!written)
                    185:                                written = -ENOSPC;
                    186:                        break;
                    187:                }
                    188:                c = BLOCK_SIZE - (pos % BLOCK_SIZE);
                    189:                if (c > count-written)
                    190:                        c = count-written;
1.1.1.3 ! root      191:                if (c != BLOCK_SIZE && !bh->b_uptodate) {
        !           192:                        ll_rw_block(READ,bh);
        !           193:                        wait_on_buffer(bh);
        !           194:                        if (!bh->b_uptodate) {
        !           195:                                brelse(bh);
        !           196:                                if (!written)
        !           197:                                        written = -EIO;
        !           198:                                break;
        !           199:                        }
1.1       root      200:                }
                    201:                p = (pos % BLOCK_SIZE) + bh->b_data;
                    202:                pos += c;
                    203:                if (pos > inode->i_size) {
                    204:                        inode->i_size = pos;
                    205:                        inode->i_dirt = 1;
                    206:                }
                    207:                written += c;
                    208:                memcpy_fromfs(p,buf,c);
                    209:                buf += c;
                    210:                bh->b_uptodate = 1;
                    211:                bh->b_dirt = 1;
                    212:                brelse(bh);
                    213:        }
                    214:        inode->i_mtime = CURRENT_TIME;
                    215:        inode->i_ctime = CURRENT_TIME;
                    216:        filp->f_pos = pos;
                    217:        inode->i_dirt = 1;
                    218:        return written;
                    219: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.