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

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

unix.superglobalmegacorp.com

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