diff options
Diffstat (limited to 'fs/ext2')
-rw-r--r-- | fs/ext2/acl.c | 2 | ||||
-rw-r--r-- | fs/ext2/file.c | 8 | ||||
-rw-r--r-- | fs/ext2/ioctl.c | 4 | ||||
-rw-r--r-- | fs/ext2/super.c | 31 |
4 files changed, 25 insertions, 20 deletions
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index 7c420b800c34..e58669e1b87c 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -464,7 +464,7 @@ ext2_xattr_set_acl(struct inode *inode, int type, const void *value, if (!test_opt(inode->i_sb, POSIX_ACL)) return -EOPNOTSUPP; - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) + if (!is_owner_or_cap(inode)) return -EPERM; if (value) { diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 566d4e2d3852..ab7961260c49 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -24,9 +24,9 @@ #include "acl.h" /* - * Called when an inode is released. Note that this is different - * from ext2_open_file: open gets called at every open, but release - * gets called only when /all/ the files are closed. + * Called when filp is released. This happens when all file descriptors + * for a single struct file are closed. Note that different open() calls + * for the same file yield different struct file structures. */ static int ext2_release_file (struct inode * inode, struct file * filp) { @@ -53,7 +53,6 @@ const struct file_operations ext2_file_operations = { .open = generic_file_open, .release = ext2_release_file, .fsync = ext2_sync_file, - .sendfile = generic_file_sendfile, .splice_read = generic_file_splice_read, .splice_write = generic_file_splice_write, }; @@ -71,7 +70,6 @@ const struct file_operations ext2_xip_file_operations = { .open = generic_file_open, .release = ext2_release_file, .fsync = ext2_sync_file, - .sendfile = xip_file_sendfile, }; #endif diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index e85c48218239..3bcd25422ee4 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c @@ -36,7 +36,7 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, if (IS_RDONLY(inode)) return -EROFS; - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) + if (!is_owner_or_cap(inode)) return -EACCES; if (get_user(flags, (int __user *) arg)) @@ -74,7 +74,7 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, case EXT2_IOC_GETVERSION: return put_user(inode->i_generation, (int __user *) arg); case EXT2_IOC_SETVERSION: - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) + if (!is_owner_or_cap(inode)) return -EPERM; if (IS_RDONLY(inode)) return -EROFS; diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 5de5061eb331..639a32c3c9c1 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -25,6 +25,7 @@ #include <linux/parser.h> #include <linux/random.h> #include <linux/buffer_head.h> +#include <linux/exportfs.h> #include <linux/smp_lock.h> #include <linux/vfs.h> #include <linux/seq_file.h> @@ -166,14 +167,14 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag #endif inode_init_once(&ei->vfs_inode); } - + static int init_inodecache(void) { ext2_inode_cachep = kmem_cache_create("ext2_inode_cache", sizeof(struct ext2_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), - init_once, NULL); + init_once); if (ext2_inode_cachep == NULL) return -ENOMEM; return 0; @@ -579,7 +580,7 @@ static int ext2_check_descriptors (struct super_block * sb) return 0; } if (le32_to_cpu(gdp->bg_inode_table) < first_block || - le32_to_cpu(gdp->bg_inode_table) + sbi->s_itb_per_group > + le32_to_cpu(gdp->bg_inode_table) + sbi->s_itb_per_group - 1 > last_block) { ext2_error (sb, "ext2_check_descriptors", @@ -882,13 +883,11 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) goto failed_mount; } bgl_lock_init(&sbi->s_blockgroup_lock); - sbi->s_debts = kmalloc(sbi->s_groups_count * sizeof(*sbi->s_debts), - GFP_KERNEL); + sbi->s_debts = kcalloc(sbi->s_groups_count, sizeof(*sbi->s_debts), GFP_KERNEL); if (!sbi->s_debts) { printk ("EXT2-fs: not enough memory\n"); goto failed_mount_group_desc; } - memset(sbi->s_debts, 0, sbi->s_groups_count * sizeof(*sbi->s_debts)); for (i = 0; i < db_count; i++) { block = descriptor_loc(sb, logic_sb_block, i); sbi->s_group_desc[i] = sb_bread(sb, block); @@ -1099,15 +1098,18 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) struct super_block *sb = dentry->d_sb; struct ext2_sb_info *sbi = EXT2_SB(sb); struct ext2_super_block *es = sbi->s_es; - unsigned long overhead; - int i; u64 fsid; if (test_opt (sb, MINIX_DF)) - overhead = 0; - else { + sbi->s_overhead_last = 0; + else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) { + unsigned long i, overhead = 0; + smp_rmb(); + /* - * Compute the overhead (FS structures) + * Compute the overhead (FS structures). This is constant + * for a given filesystem unless the number of block groups + * changes so we cache the previous value until it does. */ /* @@ -1131,17 +1133,22 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) */ overhead += (sbi->s_groups_count * (2 + sbi->s_itb_per_group)); + sbi->s_overhead_last = overhead; + smp_wmb(); + sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count); } buf->f_type = EXT2_SUPER_MAGIC; buf->f_bsize = sb->s_blocksize; - buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead; + buf->f_blocks = le32_to_cpu(es->s_blocks_count) - sbi->s_overhead_last; buf->f_bfree = ext2_count_free_blocks(sb); + es->s_free_blocks_count = cpu_to_le32(buf->f_bfree); buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count); if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count)) buf->f_bavail = 0; buf->f_files = le32_to_cpu(es->s_inodes_count); buf->f_ffree = ext2_count_free_inodes(sb); + es->s_free_inodes_count = cpu_to_le32(buf->f_ffree); buf->f_namelen = EXT2_NAME_LEN; fsid = le64_to_cpup((void *)es->s_uuid) ^ le64_to_cpup((void *)es->s_uuid + sizeof(u64)); |