diff options
Diffstat (limited to 'fs/ext2')
-rw-r--r-- | fs/ext2/CHANGES | 7 | ||||
-rw-r--r-- | fs/ext2/acl.c | 15 | ||||
-rw-r--r-- | fs/ext2/balloc.c | 19 | ||||
-rw-r--r-- | fs/ext2/bitmap.c | 7 | ||||
-rw-r--r-- | fs/ext2/dir.c | 54 | ||||
-rw-r--r-- | fs/ext2/file.c | 35 | ||||
-rw-r--r-- | fs/ext2/fsync.c | 19 | ||||
-rw-r--r-- | fs/ext2/ialloc.c | 19 | ||||
-rw-r--r-- | fs/ext2/inode.c | 32 | ||||
-rw-r--r-- | fs/ext2/ioctl.c | 8 | ||||
-rw-r--r-- | fs/ext2/namei.c | 7 | ||||
-rw-r--r-- | fs/ext2/super.c | 87 | ||||
-rw-r--r-- | fs/ext2/symlink.c | 7 | ||||
-rw-r--r-- | fs/ext2/truncate.c | 55 |
14 files changed, 218 insertions, 153 deletions
diff --git a/fs/ext2/CHANGES b/fs/ext2/CHANGES index b760d18c7..a2495a41e 100644 --- a/fs/ext2/CHANGES +++ b/fs/ext2/CHANGES @@ -1,5 +1,12 @@ Changes from version 0.5 to version 0.5a ======================================== + - Zero the partial block following the end of the file when a file + is truncated. + - Dates updated in the copyright. + - More checks when the filesystem is mounted: the count of blocks, + fragments, and inodes per group is checked against the block size. + - The buffers used by the error routines are now static variables, to + avoid using space on the kernel stack, as requested by Linus. - Some cleanups in the error messages (some versions of syslog contain a bug which truncates an error message if it contains '\n'). - Check that no data can be written to a file past the 2GB limit. diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index 91ef7c8cc..0b2701fe6 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -1,9 +1,10 @@ /* * linux/fs/ext2/acl.c * - * Copyright (C) 1993, 1994 Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) + * Copyright (C) 1993, 1994, 1995 + * Remy Card (card@masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) */ /* @@ -30,12 +31,12 @@ int ext2_permission (struct inode * inode, int mask) * Nobody gets write access to an immutable file */ if ((mask & S_IWOTH) && IS_IMMUTABLE(inode)) - return 0; + return -EACCES; /* * Special case, access is always granted for root */ if (fsuser()) - return 1; + return 0; /* * If no ACL, checks using the file mode */ @@ -44,7 +45,7 @@ int ext2_permission (struct inode * inode, int mask) else if (in_group_p (inode->i_gid)) mode >>= 3; if (((mode & mask & S_IRWXO) == mask)) - return 1; - else return 0; + else + return -EACCES; } diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index bc6faa7ed..c476fa2b2 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c @@ -1,9 +1,10 @@ /* * linux/fs/ext2/balloc.c * - * Copyright (C) 1992, 1993, 1994 Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) + * Copyright (C) 1992, 1993, 1994, 1995 + * Remy Card (card@masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) * * Enhanced block allocation by Stephen Tweedie (sct@dcs.ed.ac.uk), 1993 */ @@ -75,7 +76,7 @@ static void read_block_bitmap (struct super_block * sb, ext2_panic (sb, "read_block_bitmap", "Cannot read block bitmap - " "block_group = %d, block_bitmap = %lu", - block_group, gdp->bg_block_bitmap); + block_group, (unsigned long) gdp->bg_block_bitmap); sb->u.ext2_sb.s_block_bitmap_number[bitmap_nr] = block_group; sb->u.ext2_sb.s_block_bitmap[bitmap_nr] = bh; } @@ -232,7 +233,7 @@ void ext2_free_blocks (struct super_block * sb, unsigned long block, mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1); mark_buffer_dirty(bh, 1); - if (sb->s_flags & MS_SYNC) { + if (sb->s_flags & MS_SYNCHRONOUS) { ll_rw_block (WRITE, 1, &bh); wait_on_buffer (bh); } @@ -249,8 +250,8 @@ void ext2_free_blocks (struct super_block * sb, unsigned long block, * bitmap, and then for any free bit if that fails. */ int ext2_new_block (struct super_block * sb, unsigned long goal, - unsigned long * prealloc_count, - unsigned long * prealloc_block) + u32 * prealloc_count, + u32 * prealloc_block) { struct buffer_head * bh; struct buffer_head * bh2; @@ -441,7 +442,7 @@ got_block: j = tmp; mark_buffer_dirty(bh, 1); - if (sb->s_flags & MS_SYNC) { + if (sb->s_flags & MS_SYNCHRONOUS) { ll_rw_block (WRITE, 1, &bh); wait_on_buffer (bh); } @@ -577,6 +578,6 @@ void ext2_check_blocks_bitmap (struct super_block * sb) ext2_error (sb, "ext2_check_blocks_bitmap", "Wrong free blocks count in super block, " "stored = %lu, counted = %lu", - es->s_free_blocks_count, bitmap_count); + (unsigned long) es->s_free_blocks_count, bitmap_count); unlock_super (sb); } diff --git a/fs/ext2/bitmap.c b/fs/ext2/bitmap.c index 1084da16d..8b9b5d233 100644 --- a/fs/ext2/bitmap.c +++ b/fs/ext2/bitmap.c @@ -1,9 +1,10 @@ /* * linux/fs/ext2/bitmap.c * - * Copyright (C) 1992, 1993, 1994 Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) + * Copyright (C) 1992, 1993, 1994, 1995 + * Remy Card (card@masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) */ #include <linux/fs.h> diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index c98139bc6..5b8bf9cc7 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c @@ -1,9 +1,10 @@ /* * linux/fs/ext2/dir.c * - * Copyright (C) 1992, 1993, 1994 Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) + * Copyright (C) 1992, 1993, 1994, 1995 + * Remy Card (card@masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) * * from * @@ -22,16 +23,13 @@ #include <linux/sched.h> #include <linux/stat.h> -#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de))) -#define ROUND_UP(x) (((x)+3) & ~3) - static int ext2_dir_read (struct inode * inode, struct file * filp, char * buf, int count) { return -EISDIR; } -static int ext2_readdir (struct inode *, struct file *, struct dirent *, int); +static int ext2_readdir (struct inode *, struct file *, void *, filldir_t); static struct file_operations ext2_dir_operations = { NULL, /* lseek - default */ @@ -92,16 +90,17 @@ int ext2_check_dir_entry (char * function, struct inode * dir, if (error_msg != NULL) ext2_error (dir->i_sb, function, "bad directory entry: %s\n" "offset=%lu, inode=%lu, rec_len=%d, name_len=%d", - error_msg, offset, de->inode, de->rec_len, + error_msg, offset, (unsigned long) de->inode, de->rec_len, de->name_len); return error_msg == NULL ? 1 : 0; } static int ext2_readdir (struct inode * inode, struct file * filp, - struct dirent * dirent, int count) + void * dirent, filldir_t filldir) { + int error = 0; unsigned long offset, blk; - int i, num, stored, dlen; + int i, num, stored; struct buffer_head * bh, * tmp, * bha[16]; struct ext2_dir_entry * de; struct super_block * sb; @@ -115,7 +114,7 @@ static int ext2_readdir (struct inode * inode, struct file * filp, bh = NULL; offset = filp->f_pos & (sb->s_blocksize - 1); - while (count > 0 && !stored && filp->f_pos < inode->i_size) { + while (!error && !stored && filp->f_pos < inode->i_size) { blk = (filp->f_pos) >> EXT2_BLOCK_SIZE_BITS(sb); bh = ext2_bread (inode, blk, 0, &err); if (!bh) { @@ -167,7 +166,7 @@ revalidate: filp->f_version = inode->i_version; } - while (count > 0 && filp->f_pos < inode->i_size + while (!error && filp->f_pos < inode->i_size && offset < sb->s_blocksize) { de = (struct ext2_dir_entry *) (bh->b_data + offset); if (!ext2_check_dir_entry ("ext2_readdir", inode, de, @@ -179,18 +178,8 @@ revalidate: brelse (bh); return stored; } + offset += de->rec_len; if (de->inode) { - dlen = ROUND_UP(NAME_OFFSET(dirent) - + de->name_len + 1); - /* Old libc libraries always use a - count of 1. */ - if (count == 1 && !stored) - count = dlen; - if (count < dlen) { - count = 0; - break; - } - /* We might block in the next section * if the data destination is * currently swapped out. So, use a @@ -198,22 +187,13 @@ revalidate: * not the directory has been modified * during the copy operation. */ version = inode->i_version; - i = de->name_len; - memcpy_tofs (dirent->d_name, de->name, i); - put_fs_long (de->inode, &dirent->d_ino); - put_fs_byte (0, dirent->d_name + i); - put_fs_word (i, &dirent->d_reclen); - put_fs_long (dlen, &dirent->d_off); + error = filldir(dirent, de->name, de->name_len, filp->f_pos, de->inode); + if (error) + break; if (version != inode->i_version) goto revalidate; - dcache_add(inode, de->name, de->name_len, - de->inode); - - stored += dlen; - count -= dlen; - ((char *) dirent) += dlen; + stored ++; } - offset += de->rec_len; filp->f_pos += de->rec_len; } offset = 0; @@ -223,5 +203,5 @@ revalidate: inode->i_atime = CURRENT_TIME; inode->i_dirt = 1; } - return stored; + return 0; } diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 20628b349..9491942c5 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -1,9 +1,10 @@ /* * linux/fs/ext2/file.c * - * Copyright (C) 1992, 1993, 1994 Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) + * Copyright (C) 1992, 1993, 1994, 1995 + * Remy Card (card@masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) * * from * @@ -195,9 +196,37 @@ static int ext2_file_read (struct inode * inode, struct file * filp, left -= chars; read += chars; if (*bhe) { +#if 0 +printk("ext2_file_read() #1:\n"); +printk("ext2_file_read() #1.1: ");print_sp(); +#endif memcpy_tofs (buf, offset + (*bhe)->b_data, chars); +#if 0 +printk("ext2_file_read() #2: buf == %08x\n", offset+(*bhe)->b_data); +if(!buf) + { +#if 0 + printk("Flushing caches...\n"); + sys_cacheflush(0, ~0, 3); +#endif + printk("dumping #1 at %08lx...\n", (unsigned long) buf); + dump16(buf); + printk("dumping #2 at %08lx...\n", (unsigned long) (offset+(*bhe)->b_data)); + dump16(offset+(*bhe)->b_data); +#if 0 + printk("Jumping to 0x0\n"); + __asm__ __volatile__ ("jr\t%0;nop"::"r" (0)); + printk("Freezing ...\n"); + while(1); +#endif + } +/*dump_list(0);*/ +#endif brelse (*bhe); +#if 0 +printk("ext2_file_read() #3:\n"); +#endif buf += chars; } else { while (chars-- > 0) diff --git a/fs/ext2/fsync.c b/fs/ext2/fsync.c index 2f79c4749..dd3d992c3 100644 --- a/fs/ext2/fsync.c +++ b/fs/ext2/fsync.c @@ -27,7 +27,7 @@ #define blocksize (EXT2_BLOCK_SIZE(inode->i_sb)) #define addr_per_block (EXT2_ADDR_PER_BLOCK(inode->i_sb)) -static int sync_block (struct inode * inode, unsigned long * block, int wait) +static int sync_block (struct inode * inode, u32 * block, int wait) { struct buffer_head * bh; int tmp; @@ -55,7 +55,7 @@ static int sync_block (struct inode * inode, unsigned long * block, int wait) return 0; } -static int sync_iblock (struct inode * inode, unsigned long * iblock, +static int sync_iblock (struct inode * inode, u32 * iblock, struct buffer_head ** bh, int wait) { int rc, tmp; @@ -94,8 +94,7 @@ static int sync_direct (struct inode * inode, int wait) return err; } -static int sync_indirect (struct inode * inode, unsigned long * iblock, - int wait) +static int sync_indirect (struct inode * inode, u32 * iblock, int wait) { int i; struct buffer_head * ind_bh; @@ -107,7 +106,7 @@ static int sync_indirect (struct inode * inode, unsigned long * iblock, for (i = 0; i < addr_per_block; i++) { rc = sync_block (inode, - ((unsigned long *) ind_bh->b_data) + i, + ((u32 *) ind_bh->b_data) + i, wait); if (rc > 0) break; @@ -118,8 +117,7 @@ static int sync_indirect (struct inode * inode, unsigned long * iblock, return err; } -static int sync_dindirect (struct inode * inode, unsigned long * diblock, - int wait) +static int sync_dindirect (struct inode * inode, u32 * diblock, int wait) { int i; struct buffer_head * dind_bh; @@ -131,7 +129,7 @@ static int sync_dindirect (struct inode * inode, unsigned long * diblock, for (i = 0; i < addr_per_block; i++) { rc = sync_indirect (inode, - ((unsigned long *) dind_bh->b_data) + i, + ((u32 *) dind_bh->b_data) + i, wait); if (rc > 0) break; @@ -142,8 +140,7 @@ static int sync_dindirect (struct inode * inode, unsigned long * diblock, return err; } -static int sync_tindirect (struct inode * inode, unsigned long * tiblock, - int wait) +static int sync_tindirect (struct inode * inode, u32 * tiblock, int wait) { int i; struct buffer_head * tind_bh; @@ -155,7 +152,7 @@ static int sync_tindirect (struct inode * inode, unsigned long * tiblock, for (i = 0; i < addr_per_block; i++) { rc = sync_dindirect (inode, - ((unsigned long *) tind_bh->b_data) + i, + ((u32 *) tind_bh->b_data) + i, wait); if (rc > 0) break; diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 69c9e2224..9102d02b2 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c @@ -1,9 +1,10 @@ /* * linux/fs/ext2/ialloc.c * - * Copyright (C) 1992, 1993, 1994 Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) + * Copyright (C) 1992, 1993, 1994, 1995 + * Remy Card (card@masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) * * BSD ufs-inspired inode and directory allocation by * Stephen Tweedie (sct@dcs.ed.ac.uk), 1993 @@ -74,7 +75,7 @@ static void read_inode_bitmap (struct super_block * sb, ext2_panic (sb, "read_inode_bitmap", "Cannot read inode bitmap - " "block_group = %lu, inode_bitmap = %lu", - block_group, gdp->bg_inode_bitmap); + block_group, (unsigned long) gdp->bg_inode_bitmap); sb->u.ext2_sb.s_inode_bitmap_number[bitmap_nr] = block_group; sb->u.ext2_sb.s_inode_bitmap[bitmap_nr] = bh; } @@ -247,7 +248,7 @@ void ext2_free_inode (struct inode * inode) set_inode_dtime (inode, gdp); } mark_buffer_dirty(bh, 1); - if (sb->s_flags & MS_SYNC) { + if (sb->s_flags & MS_SYNCHRONOUS) { ll_rw_block (WRITE, 1, &bh); wait_on_buffer (bh); } @@ -358,7 +359,7 @@ repeat: else { /* - * Try to place the inode in it's parent directory + * Try to place the inode in its parent directory */ i = dir->u.ext2_i.i_block_group; tmp = get_group_desc (sb, i, &bh2); @@ -414,7 +415,7 @@ repeat: goto repeat; } mark_buffer_dirty(bh, 1); - if (sb->s_flags & MS_SYNC) { + if (sb->s_flags & MS_SYNCHRONOUS) { ll_rw_block (WRITE, 1, &bh); wait_on_buffer (bh); } @@ -476,7 +477,7 @@ repeat: inode->u.ext2_i.i_block_group = i; inode->i_op = NULL; if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL) - inode->i_flags |= MS_SYNC; + inode->i_flags |= MS_SYNCHRONOUS; insert_inode_hash(inode); inc_inode_version (inode, gdp, mode); @@ -549,6 +550,6 @@ void ext2_check_inodes_bitmap (struct super_block * sb) ext2_error (sb, "ext2_check_inodes_bitmap", "Wrong free inodes count in super block, " "stored = %lu, counted = %lu", - es->s_free_inodes_count, bitmap_count); + (unsigned long) es->s_free_inodes_count, bitmap_count); unlock_super (sb); } diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 7a3c37b79..127f4a9cd 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -1,9 +1,10 @@ /* * linux/fs/ext2/inode.c * - * Copyright (C) 1992, 1993, 1994 Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) + * Copyright (C) 1992, 1993, 1994, 1995 + * Remy Card (card@masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) * * from * @@ -24,6 +25,7 @@ #include <linux/stat.h> #include <linux/string.h> #include <linux/locks.h> +#include <linux/mm.h> void ext2_put_inode (struct inode * inode) { @@ -45,7 +47,7 @@ static int block_bmap (struct buffer_head * bh, int nr) if (!bh) return 0; - tmp = ((unsigned long *) bh->b_data)[nr]; + tmp = ((u32 *) bh->b_data)[nr]; brelse (bh); return tmp; } @@ -99,7 +101,7 @@ static int ext2_alloc_block (struct inode * inode, unsigned long goal) "cannot get block %lu", result); return 0; } - memset (bh->b_data, 0, inode->i_sb->s_blocksize); + memset(bh->b_data, 0, inode->i_sb->s_blocksize); bh->b_uptodate = 1; mark_buffer_dirty(bh, 1); brelse (bh); @@ -181,8 +183,8 @@ int ext2_bmap (struct inode * inode, int block) static struct buffer_head * inode_getblk (struct inode * inode, int nr, int create, int new_block, int * err) { + u32 * p; int tmp, goal = 0; - unsigned long * p; struct buffer_head * result; int blocks = inode->i_sb->s_blocksize / 512; @@ -249,7 +251,7 @@ static struct buffer_head * block_getblk (struct inode * inode, int new_block, int * err) { int tmp, goal = 0; - unsigned long * p; + u32 * p; struct buffer_head * result; int blocks = inode->i_sb->s_blocksize / 512; @@ -263,7 +265,7 @@ static struct buffer_head * block_getblk (struct inode * inode, return NULL; } } - p = (unsigned long *) bh->b_data + nr; + p = (u32 *) bh->b_data + nr; repeat: tmp = *p; if (tmp) { @@ -286,8 +288,8 @@ repeat: goal = inode->u.ext2_i.i_next_alloc_goal; if (!goal) { for (tmp = nr - 1; tmp >= 0; tmp--) { - if (((unsigned long *) bh->b_data)[tmp]) { - goal = ((unsigned long *)bh->b_data)[tmp]; + if (((u32 *) bh->b_data)[tmp]) { + goal = ((u32 *)bh->b_data)[tmp]; break; } } @@ -324,7 +326,7 @@ static int block_getcluster (struct inode * inode, struct buffer_head * bh, int nr, int blocksize) { - unsigned long * p; + u32 * p; int firstblock = 0; int result = 0; int i; @@ -337,7 +339,7 @@ static int block_getcluster (struct inode * inode, struct buffer_head * bh, if(nr + 3 > EXT2_ADDR_PER_BLOCK(inode->i_sb)) goto out; for(i=0; i< (PAGE_SIZE / inode->i_sb->s_blocksize); i++) { - p = (unsigned long *) bh->b_data + nr + i; + p = (u32 *) bh->b_data + nr + i; /* All blocks in cluster must already be allocated */ if(*p == 0) goto out; @@ -345,9 +347,9 @@ static int block_getcluster (struct inode * inode, struct buffer_head * bh, /* See if aligned correctly */ if(i==0) firstblock = *p; else if(*p != firstblock + i) goto out; - }; + } - p = (unsigned long *) bh->b_data + nr; + p = (u32 *) bh->b_data + nr; result = generate_cluster(bh->b_dev, (int *) p, blocksize); out: @@ -567,7 +569,7 @@ void ext2_read_inode (struct inode * inode) else if (S_ISFIFO(inode->i_mode)) init_fifo(inode); if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL) - inode->i_flags |= MS_SYNC; + inode->i_flags |= MS_SYNCHRONOUS; if (inode->u.ext2_i.i_flags & EXT2_APPEND_FL) inode->i_flags |= S_APPEND; if (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL) diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index 447968ef0..e0de8de11 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c @@ -1,9 +1,10 @@ /* * linux/fs/ext2/ioctl.c * - * Copyright (C) 1993, 1994 Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) + * Copyright (C) 1993, 1994, 1995 + * Remy Card (card@masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) */ #include <asm/segment.h> @@ -13,6 +14,7 @@ #include <linux/ext2_fs.h> #include <linux/ioctl.h> #include <linux/sched.h> +#include <linux/mm.h> int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, unsigned long arg) diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index f56c5404e..6c0b277e2 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -1,9 +1,10 @@ /* * linux/fs/ext2/namei.c * - * Copyright (C) 1992, 1993, 1994 Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) + * Copyright (C) 1992, 1993, 1994, 1995 + * Remy Card (card@masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) * * from * diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 37fae41ad..5cd418364 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -1,9 +1,10 @@ /* * linux/fs/ext2/super.c * - * Copyright (C) 1992, 1993, 1994 Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) + * Copyright (C) 1992, 1993, 1994, 1995 + * Remy Card (card@masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) * * from * @@ -26,10 +27,11 @@ #include <linux/string.h> #include <linux/locks.h> +static char error_buf[1024]; + void ext2_error (struct super_block * sb, const char * function, const char * fmt, ...) { - char buf[1024]; va_list args; if (!(sb->s_flags & MS_RDONLY)) { @@ -39,15 +41,15 @@ void ext2_error (struct super_block * sb, const char * function, sb->s_dirt = 1; } va_start (args, fmt); - vsprintf (buf, fmt, args); + vsprintf (error_buf, fmt, args); va_end (args); if (test_opt (sb, ERRORS_PANIC) || (sb->u.ext2_sb.s_es->s_errors == EXT2_ERRORS_PANIC && !test_opt (sb, ERRORS_CONT) && !test_opt (sb, ERRORS_RO))) panic ("EXT2-fs panic (device %d/%d): %s: %s\n", - MAJOR(sb->s_dev), MINOR(sb->s_dev), function, buf); + MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf); printk (KERN_CRIT "EXT2-fs error (device %d/%d): %s: %s\n", - MAJOR(sb->s_dev), MINOR(sb->s_dev), function, buf); + MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf); if (test_opt (sb, ERRORS_RO) || (sb->u.ext2_sb.s_es->s_errors == EXT2_ERRORS_RO && !test_opt (sb, ERRORS_CONT) && !test_opt (sb, ERRORS_PANIC))) { @@ -59,7 +61,6 @@ void ext2_error (struct super_block * sb, const char * function, NORET_TYPE void ext2_panic (struct super_block * sb, const char * function, const char * fmt, ...) { - char buf[1024]; va_list args; if (!(sb->s_flags & MS_RDONLY)) { @@ -69,23 +70,22 @@ NORET_TYPE void ext2_panic (struct super_block * sb, const char * function, sb->s_dirt = 1; } va_start (args, fmt); - vsprintf (buf, fmt, args); + vsprintf (error_buf, fmt, args); va_end (args); panic ("EXT2-fs panic (device %d/%d): %s: %s\n", - MAJOR(sb->s_dev), MINOR(sb->s_dev), function, buf); + MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf); } void ext2_warning (struct super_block * sb, const char * function, const char * fmt, ...) { - char buf[1024]; va_list args; va_start (args, fmt); - vsprintf (buf, fmt, args); + vsprintf (error_buf, fmt, args); va_end (args); printk (KERN_WARNING "EXT2-fs warning (device %d/%d): %s: %s\n", - MAJOR(sb->s_dev), MINOR(sb->s_dev), function, buf); + MAJOR(sb->s_dev), MINOR(sb->s_dev), function, error_buf); } void ext2_put_super (struct super_block * sb) @@ -360,7 +360,7 @@ static int ext2_check_descriptors (struct super_block * sb) ext2_error (sb, "ext2_check_descriptors", "Block bitmap for group %d" " not in group (block %lu)!", - i, gdp->bg_block_bitmap); + i, (unsigned long) gdp->bg_block_bitmap); return 0; } if (gdp->bg_inode_bitmap < block || @@ -369,7 +369,7 @@ static int ext2_check_descriptors (struct super_block * sb) ext2_error (sb, "ext2_check_descriptors", "Inode bitmap for group %d" " not in group (block %lu)!", - i, gdp->bg_inode_bitmap); + i, (unsigned long) gdp->bg_inode_bitmap); return 0; } if (gdp->bg_inode_table < block || @@ -379,7 +379,7 @@ static int ext2_check_descriptors (struct super_block * sb) ext2_error (sb, "ext2_check_descriptors", "Inode table for group %d" " not in group (block %lu)!", - i, gdp->bg_inode_table); + i, (unsigned long) gdp->bg_inode_table); return 0; } block += EXT2_BLOCKS_PER_GROUP(sb); @@ -553,6 +553,31 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, return NULL; } + if (sb->u.ext2_sb.s_blocks_per_group > sb->s_blocksize * 8) { + sb->s_dev = 0; + unlock_super (sb); + brelse (bh); + printk ("EXT2-fs: #blocks per group too big: %lu\n", + sb->u.ext2_sb.s_blocks_per_group); + return NULL; + } + if (sb->u.ext2_sb.s_frags_per_group > sb->s_blocksize * 8) { + sb->s_dev = 0; + unlock_super (sb); + brelse (bh); + printk ("EXT2-fs: #fragments per group too big: %lu\n", + sb->u.ext2_sb.s_frags_per_group); + return NULL; + } + if (sb->u.ext2_sb.s_inodes_per_group > sb->s_blocksize * 8) { + sb->s_dev = 0; + unlock_super (sb); + brelse (bh); + printk ("EXT2-fs: #inodes per group too big: %lu\n", + sb->u.ext2_sb.s_inodes_per_group); + return NULL; + } + sb->u.ext2_sb.s_groups_count = (es->s_blocks_count - es->s_first_data_block + EXT2_BLOCKS_PER_GROUP(sb) - 1) / @@ -716,11 +741,11 @@ int ext2_remount (struct super_block * sb, int * flags, char * data) return 0; } -void ext2_statfs (struct super_block * sb, struct statfs * buf) +void ext2_statfs (struct super_block * sb, struct statfs * buf, int bufsiz) { - long tmp; unsigned long overhead; unsigned long overhead_per_group; + struct statfs tmp; if (test_opt (sb, MINIX_DF)) overhead = 0; @@ -737,19 +762,15 @@ void ext2_statfs (struct super_block * sb, struct statfs * buf) sb->u.ext2_sb.s_groups_count * overhead_per_group; } - put_fs_long (EXT2_SUPER_MAGIC, &buf->f_type); - put_fs_long (sb->s_blocksize, &buf->f_bsize); - put_fs_long (sb->u.ext2_sb.s_es->s_blocks_count - overhead, - &buf->f_blocks); - tmp = ext2_count_free_blocks (sb); - put_fs_long (tmp, &buf->f_bfree); - if (tmp >= sb->u.ext2_sb.s_es->s_r_blocks_count) - put_fs_long (tmp - sb->u.ext2_sb.s_es->s_r_blocks_count, - &buf->f_bavail); - else - put_fs_long (0, &buf->f_bavail); - put_fs_long (sb->u.ext2_sb.s_es->s_inodes_count, &buf->f_files); - put_fs_long (ext2_count_free_inodes (sb), &buf->f_ffree); - put_fs_long (EXT2_NAME_LEN, &buf->f_namelen); - /* Don't know what value to put in buf->f_fsid */ + tmp.f_type = EXT2_SUPER_MAGIC; + tmp.f_bsize = sb->s_blocksize; + tmp.f_blocks = sb->u.ext2_sb.s_es->s_blocks_count - overhead; + tmp.f_bfree = ext2_count_free_blocks (sb); + tmp.f_bavail = tmp.f_bfree - sb->u.ext2_sb.s_es->s_r_blocks_count; + if (tmp.f_bfree < sb->u.ext2_sb.s_es->s_r_blocks_count) + tmp.f_bavail = 0; + tmp.f_files = sb->u.ext2_sb.s_es->s_inodes_count; + tmp.f_ffree = ext2_count_free_inodes (sb); + tmp.f_namelen = EXT2_NAME_LEN; + memcpy_tofs(buf, &tmp, bufsiz); } diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c index 7d85ed74c..66d4ab860 100644 --- a/fs/ext2/symlink.c +++ b/fs/ext2/symlink.c @@ -1,9 +1,10 @@ /* * linux/fs/ext2/symlink.c * - * Copyright (C) 1992, 1993, 1994 Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) + * Copyright (C) 1992, 1993, 1994, 1995 + * Remy Card (card@masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) * * from * diff --git a/fs/ext2/truncate.c b/fs/ext2/truncate.c index 10a1fd236..94a64f3e0 100644 --- a/fs/ext2/truncate.c +++ b/fs/ext2/truncate.c @@ -1,9 +1,10 @@ /* * linux/fs/ext2/truncate.c * - * Copyright (C) 1992, 1993, 1994 Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) + * Copyright (C) 1992, 1993, 1994, 1995 + * Remy Card (card@masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) * * from * @@ -45,8 +46,8 @@ static int ext2_secrm_seed = 152; /* Random generator base */ static int trunc_direct (struct inode * inode) { + u32 * p; int i, tmp; - unsigned long * p; struct buffer_head * bh; unsigned long block_to_free = 0; unsigned long free_count = 0; @@ -102,12 +103,12 @@ repeat: return retry; } -static int trunc_indirect (struct inode * inode, int offset, unsigned long * p) +static int trunc_indirect (struct inode * inode, int offset, u32 * p) { int i, tmp; struct buffer_head * bh; struct buffer_head * ind_bh; - unsigned long * ind; + u32 * ind; unsigned long block_to_free = 0; unsigned long free_count = 0; int retry = 0; @@ -134,7 +135,7 @@ repeat: i = 0; if (i < indirect_block) goto repeat; - ind = i + (unsigned long *) ind_bh->b_data; + ind = i + (u32 *) ind_bh->b_data; tmp = *ind; if (!tmp) continue; @@ -176,7 +177,7 @@ repeat: } if (free_count > 0) ext2_free_blocks (inode->i_sb, block_to_free, free_count); - ind = (unsigned long *) ind_bh->b_data; + ind = (u32 *) ind_bh->b_data; for (i = 0; i < addr_per_block; i++) if (*(ind++)) break; @@ -199,11 +200,11 @@ repeat: } static int trunc_dindirect (struct inode * inode, int offset, - unsigned long * p) + u32 * p) { int i, tmp; struct buffer_head * dind_bh; - unsigned long * dind; + u32 * dind; int retry = 0; int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb); int blocks = inode->i_sb->s_blocksize / 512; @@ -228,7 +229,7 @@ repeat: i = 0; if (i < dindirect_block) goto repeat; - dind = i + (unsigned long *) dind_bh->b_data; + dind = i + (u32 *) dind_bh->b_data; tmp = *dind; if (!tmp) continue; @@ -236,7 +237,7 @@ repeat: dind); mark_buffer_dirty(dind_bh, 1); } - dind = (unsigned long *) dind_bh->b_data; + dind = (u32 *) dind_bh->b_data; for (i = 0; i < addr_per_block; i++) if (*(dind++)) break; @@ -262,7 +263,7 @@ static int trunc_tindirect (struct inode * inode) { int i, tmp; struct buffer_head * tind_bh; - unsigned long * tind, * p; + u32 * tind, * p; int retry = 0; int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb); int blocks = inode->i_sb->s_blocksize / 512; @@ -289,13 +290,13 @@ repeat: i = 0; if (i < tindirect_block) goto repeat; - tind = i + (unsigned long *) tind_bh->b_data; + tind = i + (u32 *) tind_bh->b_data; retry |= trunc_dindirect(inode, EXT2_NDIR_BLOCKS + addr_per_block + (i + 1) * addr_per_block * addr_per_block, tind); mark_buffer_dirty(tind_bh, 1); } - tind = (unsigned long *) tind_bh->b_data; + tind = (u32 *) tind_bh->b_data; for (i = 0; i < addr_per_block; i++) if (*(tind++)) break; @@ -320,6 +321,9 @@ repeat: void ext2_truncate (struct inode * inode) { int retry; + struct buffer_head * bh; + int err; + int offset; if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) @@ -331,10 +335,10 @@ void ext2_truncate (struct inode * inode) down(&inode->i_sem); retry = trunc_direct(inode); retry |= trunc_indirect (inode, EXT2_IND_BLOCK, - (unsigned long *) &inode->u.ext2_i.i_data[EXT2_IND_BLOCK]); + (u32 *) &inode->u.ext2_i.i_data[EXT2_IND_BLOCK]); retry |= trunc_dindirect (inode, EXT2_IND_BLOCK + EXT2_ADDR_PER_BLOCK(inode->i_sb), - (unsigned long *) &inode->u.ext2_i.i_data[EXT2_DIND_BLOCK]); + (u32 *) &inode->u.ext2_i.i_data[EXT2_DIND_BLOCK]); retry |= trunc_tindirect (inode); up(&inode->i_sem); if (!retry) @@ -344,6 +348,23 @@ void ext2_truncate (struct inode * inode) current->counter = 0; schedule (); } + /* + * If the file is not being truncated to a block boundary, the + * contents of the partial block following the end of the file must be + * zeroed in case it ever becomes accessible again because of + * subsequent file growth. + */ + offset = inode->i_size % inode->i_sb->s_blocksize; + if (offset) { + bh = ext2_bread (inode, inode->i_size / inode->i_sb->s_blocksize, + 0, &err); + if (bh) { + memset (bh->b_data + offset, 0, + inode->i_sb->s_blocksize - offset); + mark_buffer_dirty (bh, 0); + brelse (bh); + } + } inode->i_mtime = inode->i_ctime = CURRENT_TIME; inode->i_dirt = 1; } |