diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-16 01:07:24 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-16 01:07:24 +0000 |
commit | 95db6b748fc86297827fbd9c9ef174d491c9ad89 (patch) | |
tree | 27a92a942821cde1edda9a1b088718d436b3efe4 /fs/ext2 | |
parent | 45b27b0a0652331d104c953a5b192d843fff88f8 (diff) |
Merge with Linux 2.3.40.
Diffstat (limited to 'fs/ext2')
-rw-r--r-- | fs/ext2/file.c | 6 | ||||
-rw-r--r-- | fs/ext2/fsync.c | 16 | ||||
-rw-r--r-- | fs/ext2/inode.c | 45 | ||||
-rw-r--r-- | fs/ext2/namei.c | 7 | ||||
-rw-r--r-- | fs/ext2/super.c | 3 |
5 files changed, 64 insertions, 13 deletions
diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 1c915e274..df010f223 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -28,7 +28,7 @@ #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) -static long long ext2_file_lseek(struct file *, long long, int); +static loff_t ext2_file_lseek(struct file *, loff_t, int); static int ext2_open_file (struct inode *, struct file *); #define EXT2_MAX_SIZE(bits) \ @@ -45,9 +45,9 @@ EXT2_MAX_SIZE(10), EXT2_MAX_SIZE(11), EXT2_MAX_SIZE(12), EXT2_MAX_SIZE(13) /* * Make sure the offset never goes beyond the 32-bit mark.. */ -static long long ext2_file_lseek( +static loff_t ext2_file_lseek( struct file *file, - long long offset, + loff_t offset, int origin) { struct inode *inode = file->f_dentry->d_inode; diff --git a/fs/ext2/fsync.c b/fs/ext2/fsync.c index f4e02c2e8..c29fef5ea 100644 --- a/fs/ext2/fsync.c +++ b/fs/ext2/fsync.c @@ -23,6 +23,7 @@ */ #include <linux/fs.h> +#include <linux/locks.h> @@ -40,10 +41,21 @@ static int sync_indirect(struct inode * inode, u32 * block, int wait) if (!bh) return 0; if (wait && buffer_req(bh) && !buffer_uptodate(bh)) { - brelse(bh); - return -1; + /* There can be a parallell read(2) that started read-I/O + on the buffer so we can't assume that there's been + an I/O error without first waiting I/O completation. */ + wait_on_buffer(bh); + if (!buffer_uptodate(bh)) + { + brelse (bh); + return -1; + } } if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) { + if (wait) + /* when we return from fsync all the blocks + must be _just_ stored on disk */ + wait_on_buffer(bh); brelse(bh); return 0; } diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index b4f952d07..e92e4080a 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -24,6 +24,7 @@ #include <linux/locks.h> #include <linux/smp_lock.h> #include <linux/sched.h> +#include <linux/highuid.h> @@ -254,6 +255,8 @@ repeat: } if (metadata) { result = getblk (inode->i_dev, tmp, blocksize); + if (!buffer_uptodate(result)) + wait_on_buffer(result); memset(result->b_data, 0, blocksize); mark_buffer_uptodate(result, 1); mark_buffer_dirty(result, 1); @@ -363,6 +366,8 @@ repeat: goto out; if (metadata) { result = getblk (bh->b_dev, tmp, blocksize); + if (!buffer_uptodate(result)) + wait_on_buffer(result); memset(result->b_data, 0, inode->i_sb->s_blocksize); mark_buffer_uptodate(result, 1); mark_buffer_dirty(result, 1); @@ -542,6 +547,8 @@ struct buffer_head * ext2_getblk(struct inode * inode, long block, int create, i struct buffer_head *bh; bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->s_blocksize); if (buffer_new(&dummy)) { + if (!buffer_uptodate(bh)) + wait_on_buffer(bh); memset(bh->b_data, 0, inode->i_sb->s_blocksize); mark_buffer_uptodate(bh, 1); mark_buffer_dirty(bh, 1); @@ -655,8 +662,12 @@ void ext2_read_inode (struct inode * inode) raw_inode = (struct ext2_inode *) (bh->b_data + offset); inode->i_mode = le16_to_cpu(raw_inode->i_mode); - inode->i_uid = le16_to_cpu(raw_inode->i_uid); - inode->i_gid = le16_to_cpu(raw_inode->i_gid); + inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); + inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); + if(!(test_opt (inode->i_sb, NO_UID32))) { + inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; + inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; + } inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); inode->i_size = le32_to_cpu(raw_inode->i_size); inode->i_atime = le32_to_cpu(raw_inode->i_atime); @@ -795,8 +806,26 @@ static int ext2_update_inode(struct inode * inode, int do_sync) raw_inode = (struct ext2_inode *) (bh->b_data + offset); raw_inode->i_mode = cpu_to_le16(inode->i_mode); - raw_inode->i_uid = cpu_to_le16(inode->i_uid); - raw_inode->i_gid = cpu_to_le16(inode->i_gid); + if(!(test_opt(inode->i_sb, NO_UID32))) { + raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); + raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid)); +/* + * Fix up interoperability with old kernels. Otherwise, old inodes get + * re-used with the upper 16 bits of the uid/gid intact + */ + if(!inode->u.ext2_i.i_dtime) { + raw_inode->i_uid_high = cpu_to_le16(high_16_bits(inode->i_uid)); + raw_inode->i_gid_high = cpu_to_le16(high_16_bits(inode->i_gid)); + } else { + raw_inode->i_uid_high = 0; + raw_inode->i_gid_high = 0; + } + } else { + raw_inode->i_uid_low = cpu_to_le16(fs_high2lowuid(inode->i_uid)); + raw_inode->i_gid_low = cpu_to_le16(fs_high2lowgid(inode->i_gid)); + raw_inode->i_uid_high = 0; + raw_inode->i_gid_high = 0; + } raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); raw_inode->i_size = cpu_to_le32(inode->i_size); raw_inode->i_atime = cpu_to_le32(inode->i_atime); @@ -870,28 +899,28 @@ int ext2_notify_change(struct dentry *dentry, struct iattr *iattr) flags = iattr->ia_attr_flags; if (flags & ATTR_FLAG_SYNCRONOUS) { inode->i_flags |= MS_SYNCHRONOUS; - inode->u.ext2_i.i_flags = EXT2_SYNC_FL; + inode->u.ext2_i.i_flags |= EXT2_SYNC_FL; } else { inode->i_flags &= ~MS_SYNCHRONOUS; inode->u.ext2_i.i_flags &= ~EXT2_SYNC_FL; } if (flags & ATTR_FLAG_NOATIME) { inode->i_flags |= MS_NOATIME; - inode->u.ext2_i.i_flags = EXT2_NOATIME_FL; + inode->u.ext2_i.i_flags |= EXT2_NOATIME_FL; } else { inode->i_flags &= ~MS_NOATIME; inode->u.ext2_i.i_flags &= ~EXT2_NOATIME_FL; } if (flags & ATTR_FLAG_APPEND) { inode->i_flags |= S_APPEND; - inode->u.ext2_i.i_flags = EXT2_APPEND_FL; + inode->u.ext2_i.i_flags |= EXT2_APPEND_FL; } else { inode->i_flags &= ~S_APPEND; inode->u.ext2_i.i_flags &= ~EXT2_APPEND_FL; } if (flags & ATTR_FLAG_IMMUTABLE) { inode->i_flags |= S_IMMUTABLE; - inode->u.ext2_i.i_flags = EXT2_IMMUTABLE_FL; + inode->u.ext2_i.i_flags |= EXT2_IMMUTABLE_FL; } else { inode->i_flags &= ~S_IMMUTABLE; inode->u.ext2_i.i_flags &= ~EXT2_IMMUTABLE_FL; diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 87f39796a..57a0be62d 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -832,6 +832,13 @@ int ext2_rename (struct inode * old_dir, struct dentry *old_dentry, new_dir->i_version = ++event; /* + * Like most other Unix systems, set the ctime for inodes on a + * rename. + */ + old_inode->i_ctime = CURRENT_TIME; + mark_inode_dirty(old_inode); + + /* * ok, that's it */ new_de->inode = le32_to_cpu(old_inode->i_ino); diff --git a/fs/ext2/super.c b/fs/ext2/super.c index cefde46fd..8a06df18b 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -151,6 +151,9 @@ static int parse_options (char * options, unsigned long * sb_block, *value++ = 0; if (!strcmp (this_char, "bsddf")) clear_opt (*mount_options, MINIX_DF); + else if (!strcmp (this_char, "nouid32")) { + set_opt (*mount_options, NO_UID32); + } else if (!strcmp (this_char, "check")) { if (!value || !*value) set_opt (*mount_options, CHECK_NORMAL); |