aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-07-23 05:20:10 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2007-07-23 05:20:10 -0400
commit39fe5434cb9de5da40510028b17b96bc4eb312b3 (patch)
tree7a02a317b9ad57da51ca99887c119e779ccf3f13 /fs/ext2
parent0fc72b81d3111d114ab378935b1cf07680ca1289 (diff)
parentf695baf2df9e0413d3521661070103711545207a (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'fs/ext2')
-rw-r--r--fs/ext2/acl.c2
-rw-r--r--fs/ext2/file.c6
-rw-r--r--fs/ext2/ioctl.c4
-rw-r--r--fs/ext2/super.c29
4 files changed, 24 insertions, 17 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,
464 464
465 if (!test_opt(inode->i_sb, POSIX_ACL)) 465 if (!test_opt(inode->i_sb, POSIX_ACL))
466 return -EOPNOTSUPP; 466 return -EOPNOTSUPP;
467 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) 467 if (!is_owner_or_cap(inode))
468 return -EPERM; 468 return -EPERM;
469 469
470 if (value) { 470 if (value) {
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 04afeecaaef3..ab7961260c49 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -24,9 +24,9 @@
24#include "acl.h" 24#include "acl.h"
25 25
26/* 26/*
27 * Called when an inode is released. Note that this is different 27 * Called when filp is released. This happens when all file descriptors
28 * from ext2_open_file: open gets called at every open, but release 28 * for a single struct file are closed. Note that different open() calls
29 * gets called only when /all/ the files are closed. 29 * for the same file yield different struct file structures.
30 */ 30 */
31static int ext2_release_file (struct inode * inode, struct file * filp) 31static int ext2_release_file (struct inode * inode, struct file * filp)
32{ 32{
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,
36 if (IS_RDONLY(inode)) 36 if (IS_RDONLY(inode))
37 return -EROFS; 37 return -EROFS;
38 38
39 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) 39 if (!is_owner_or_cap(inode))
40 return -EACCES; 40 return -EACCES;
41 41
42 if (get_user(flags, (int __user *) arg)) 42 if (get_user(flags, (int __user *) arg))
@@ -74,7 +74,7 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
74 case EXT2_IOC_GETVERSION: 74 case EXT2_IOC_GETVERSION:
75 return put_user(inode->i_generation, (int __user *) arg); 75 return put_user(inode->i_generation, (int __user *) arg);
76 case EXT2_IOC_SETVERSION: 76 case EXT2_IOC_SETVERSION:
77 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) 77 if (!is_owner_or_cap(inode))
78 return -EPERM; 78 return -EPERM;
79 if (IS_RDONLY(inode)) 79 if (IS_RDONLY(inode))
80 return -EROFS; 80 return -EROFS;
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 5de5061eb331..68579a0ed3f0 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -25,6 +25,7 @@
25#include <linux/parser.h> 25#include <linux/parser.h>
26#include <linux/random.h> 26#include <linux/random.h>
27#include <linux/buffer_head.h> 27#include <linux/buffer_head.h>
28#include <linux/exportfs.h>
28#include <linux/smp_lock.h> 29#include <linux/smp_lock.h>
29#include <linux/vfs.h> 30#include <linux/vfs.h>
30#include <linux/seq_file.h> 31#include <linux/seq_file.h>
@@ -166,14 +167,14 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
166#endif 167#endif
167 inode_init_once(&ei->vfs_inode); 168 inode_init_once(&ei->vfs_inode);
168} 169}
169 170
170static int init_inodecache(void) 171static int init_inodecache(void)
171{ 172{
172 ext2_inode_cachep = kmem_cache_create("ext2_inode_cache", 173 ext2_inode_cachep = kmem_cache_create("ext2_inode_cache",
173 sizeof(struct ext2_inode_info), 174 sizeof(struct ext2_inode_info),
174 0, (SLAB_RECLAIM_ACCOUNT| 175 0, (SLAB_RECLAIM_ACCOUNT|
175 SLAB_MEM_SPREAD), 176 SLAB_MEM_SPREAD),
176 init_once, NULL); 177 init_once);
177 if (ext2_inode_cachep == NULL) 178 if (ext2_inode_cachep == NULL)
178 return -ENOMEM; 179 return -ENOMEM;
179 return 0; 180 return 0;
@@ -882,13 +883,11 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
882 goto failed_mount; 883 goto failed_mount;
883 } 884 }
884 bgl_lock_init(&sbi->s_blockgroup_lock); 885 bgl_lock_init(&sbi->s_blockgroup_lock);
885 sbi->s_debts = kmalloc(sbi->s_groups_count * sizeof(*sbi->s_debts), 886 sbi->s_debts = kcalloc(sbi->s_groups_count, sizeof(*sbi->s_debts), GFP_KERNEL);
886 GFP_KERNEL);
887 if (!sbi->s_debts) { 887 if (!sbi->s_debts) {
888 printk ("EXT2-fs: not enough memory\n"); 888 printk ("EXT2-fs: not enough memory\n");
889 goto failed_mount_group_desc; 889 goto failed_mount_group_desc;
890 } 890 }
891 memset(sbi->s_debts, 0, sbi->s_groups_count * sizeof(*sbi->s_debts));
892 for (i = 0; i < db_count; i++) { 891 for (i = 0; i < db_count; i++) {
893 block = descriptor_loc(sb, logic_sb_block, i); 892 block = descriptor_loc(sb, logic_sb_block, i);
894 sbi->s_group_desc[i] = sb_bread(sb, block); 893 sbi->s_group_desc[i] = sb_bread(sb, block);
@@ -1099,15 +1098,18 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf)
1099 struct super_block *sb = dentry->d_sb; 1098 struct super_block *sb = dentry->d_sb;
1100 struct ext2_sb_info *sbi = EXT2_SB(sb); 1099 struct ext2_sb_info *sbi = EXT2_SB(sb);
1101 struct ext2_super_block *es = sbi->s_es; 1100 struct ext2_super_block *es = sbi->s_es;
1102 unsigned long overhead;
1103 int i;
1104 u64 fsid; 1101 u64 fsid;
1105 1102
1106 if (test_opt (sb, MINIX_DF)) 1103 if (test_opt (sb, MINIX_DF))
1107 overhead = 0; 1104 sbi->s_overhead_last = 0;
1108 else { 1105 else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) {
1106 unsigned long i, overhead = 0;
1107 smp_rmb();
1108
1109 /* 1109 /*
1110 * Compute the overhead (FS structures) 1110 * Compute the overhead (FS structures). This is constant
1111 * for a given filesystem unless the number of block groups
1112 * changes so we cache the previous value until it does.
1111 */ 1113 */
1112 1114
1113 /* 1115 /*
@@ -1131,17 +1133,22 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf)
1131 */ 1133 */
1132 overhead += (sbi->s_groups_count * 1134 overhead += (sbi->s_groups_count *
1133 (2 + sbi->s_itb_per_group)); 1135 (2 + sbi->s_itb_per_group));
1136 sbi->s_overhead_last = overhead;
1137 smp_wmb();
1138 sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count);
1134 } 1139 }
1135 1140
1136 buf->f_type = EXT2_SUPER_MAGIC; 1141 buf->f_type = EXT2_SUPER_MAGIC;
1137 buf->f_bsize = sb->s_blocksize; 1142 buf->f_bsize = sb->s_blocksize;
1138 buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead; 1143 buf->f_blocks = le32_to_cpu(es->s_blocks_count) - sbi->s_overhead_last;
1139 buf->f_bfree = ext2_count_free_blocks(sb); 1144 buf->f_bfree = ext2_count_free_blocks(sb);
1145 es->s_free_blocks_count = cpu_to_le32(buf->f_bfree);
1140 buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count); 1146 buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count);
1141 if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count)) 1147 if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count))
1142 buf->f_bavail = 0; 1148 buf->f_bavail = 0;
1143 buf->f_files = le32_to_cpu(es->s_inodes_count); 1149 buf->f_files = le32_to_cpu(es->s_inodes_count);
1144 buf->f_ffree = ext2_count_free_inodes(sb); 1150 buf->f_ffree = ext2_count_free_inodes(sb);
1151 es->s_free_inodes_count = cpu_to_le32(buf->f_ffree);
1145 buf->f_namelen = EXT2_NAME_LEN; 1152 buf->f_namelen = EXT2_NAME_LEN;
1146 fsid = le64_to_cpup((void *)es->s_uuid) ^ 1153 fsid = le64_to_cpup((void *)es->s_uuid) ^
1147 le64_to_cpup((void *)es->s_uuid + sizeof(u64)); 1154 le64_to_cpup((void *)es->s_uuid + sizeof(u64));