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

1.1       root        1: /*
                      2:  *  linux/fs/truncate.c
                      3:  *
                      4:  *  (C) 1991  Linus Torvalds
                      5:  */
                      6: 
                      7: #include <linux/sched.h>
                      8: #include <linux/minix_fs.h>
                      9: #include <linux/tty.h>
                     10: 
                     11: #include <errno.h>
                     12: #include <fcntl.h>
                     13: #include <sys/stat.h>
                     14: 
1.1.1.3 ! root       15: /*
        !            16:  * Truncate has the most races in the whole filesystem: coding it is
        !            17:  * a pain in the a**. Especially as I don't do any locking...
        !            18:  *
        !            19:  * The code may look a bit weird, but that's just because I've tried to
        !            20:  * handle things like file-size changes in a somewhat graceful manner.
        !            21:  * Anyway, truncating a file at the same time somebody else writes to it
        !            22:  * is likely to result in pretty weird behaviour...
        !            23:  *
        !            24:  * The new code handles normal truncates (size = 0) as well as the more
        !            25:  * general case (size = XXX). I hope.
        !            26:  */
        !            27: 
        !            28: static int trunc_direct(struct inode * inode)
1.1       root       29: {
                     30:        int i;
1.1.1.3 ! root       31:        int result = 0;
        !            32: #define DIRECT_BLOCK ((inode->i_size + 1023) >> 10)
1.1       root       33: 
1.1.1.3 ! root       34: repeat:
        !            35:        for (i = DIRECT_BLOCK ; i < 7 ; i++) {
        !            36:                if (i < DIRECT_BLOCK)
        !            37:                        goto repeat;
        !            38:                if (!inode->i_data[i])
        !            39:                        continue;
        !            40:                result = 1;
        !            41:                if (minix_free_block(inode->i_dev,inode->i_data[i]))
        !            42:                        inode->i_data[i] = 0;
1.1       root       43:        }
1.1.1.3 ! root       44:        return result;
1.1       root       45: }
                     46: 
1.1.1.3 ! root       47: static int trunc_indirect(struct inode * inode, int offset, unsigned short * p)
1.1       root       48: {
                     49:        int i;
1.1.1.3 ! root       50:        struct buffer_head * bh = NULL;
        !            51:        unsigned short * ind;
        !            52:        int result = 0;
        !            53: #define INDIRECT_BLOCK (DIRECT_BLOCK-offset)
        !            54: 
        !            55:        if (*p)
        !            56:                bh = bread(inode->i_dev,*p);
        !            57:        if (!bh)
        !            58:                return 0;
        !            59: repeat:
        !            60:        for (i = INDIRECT_BLOCK ; i < 512 ; i++) {
        !            61:                if (i < 0)
        !            62:                        i = 0;
        !            63:                if (i < INDIRECT_BLOCK)
        !            64:                        goto repeat;
        !            65:                ind = i+(unsigned short *) bh->b_data;
        !            66:                if (!*ind)
        !            67:                        continue;
        !            68:                result = 1;
        !            69:                if (minix_free_block(inode->i_dev,*ind))
        !            70:                        *ind = 0;
1.1       root       71:        }
1.1.1.3 ! root       72:        ind = (unsigned short *) bh->b_data;
        !            73:        for (i = 0; i < 512; i++)
        !            74:                if (*(ind++))
        !            75:                        break;
        !            76:        brelse(bh);
        !            77:        if (i >= 512) {
        !            78:                result = 1;
        !            79:                if (minix_free_block(inode->i_dev,*p))
        !            80:                        *p = 0;
        !            81:        }
        !            82:        return result;
        !            83: }
        !            84:                
        !            85: static int trunc_dindirect(struct inode * inode)
        !            86: {
        !            87:        int i;
        !            88:        struct buffer_head * bh = NULL;
        !            89:        unsigned short * dind;
        !            90:        int result = 0;
        !            91: #define DINDIRECT_BLOCK ((DIRECT_BLOCK-(512+7))>>9)
        !            92: 
        !            93:        if (inode->i_data[8])
        !            94:                bh = bread(inode->i_dev,inode->i_data[8]);
        !            95:        if (!bh)
1.1       root       96:                return 0;
1.1.1.3 ! root       97: repeat:
        !            98:        for (i = DINDIRECT_BLOCK ; i < 512 ; i ++) {
        !            99:                if (i < 0)
        !           100:                        i = 0;
        !           101:                if (i < DINDIRECT_BLOCK)
        !           102:                        goto repeat;
        !           103:                dind = i+(unsigned short *) bh->b_data;
        !           104:                if (!*dind)
        !           105:                        continue;
        !           106:                result |= trunc_indirect(inode,7+512+(i<<9),dind);
        !           107:        }
        !           108:        dind = (unsigned short *) bh->b_data;
        !           109:        for (i = 0; i < 512; i++)
        !           110:                if (*(dind++))
        !           111:                        break;
        !           112:        brelse(bh);
        !           113:        if (i >= 512) {
        !           114:                result = 1;
        !           115:                if (minix_free_block(inode->i_dev,inode->i_data[8]))
        !           116:                        inode->i_data[8] = 0;
        !           117:        }
        !           118:        return result;
1.1       root      119: }
1.1.1.3 ! root      120:                
1.1       root      121: void minix_truncate(struct inode * inode)
                    122: {
1.1.1.3 ! root      123:        int flag;
1.1       root      124: 
                    125:        if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
                    126:             S_ISLNK(inode->i_mode)))
                    127:                return;
1.1.1.3 ! root      128:        if (inode->i_data[7] & 0xffff0000)
        !           129:                printk("BAD! minix inode has 16 high bits set\n");
        !           130:        while (1) {
        !           131:                flag = trunc_direct(inode);
        !           132:                flag |= trunc_indirect(inode,7,(unsigned short *)&inode->i_data[7]);
        !           133:                flag |= trunc_dindirect(inode);
        !           134:                if (!flag)
        !           135:                        break;
1.1       root      136:                current->counter = 0;
                    137:                schedule();
                    138:        }
                    139:        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
1.1.1.3 ! root      140:        inode->i_dirt = 1;
1.1       root      141: }
                    142: 
                    143: /*
                    144:  * Called when a inode is released. Note that this is different
                    145:  * from minix_open: open gets called at every open, but release
                    146:  * gets called only when /all/ the files are closed.
                    147:  */
                    148: void minix_release(struct inode * inode, struct file * filp)
                    149: {
                    150:        printk("minix_release not implemented\n");
                    151: }

unix.superglobalmegacorp.com

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