rpms/kernel/devel linux-2.6-ext3-dir_index-error-out-instead-of-bug-on-corrupt-dx-dirs.patch, NONE, 1.1 linux-2.6-ext34-ensure-do_split-leaves-enough-free-space-in-both-blocks.patch, NONE, 1.1 linux-2.6-xfs-avoid-replaying-inode-buffer-init.patch, NONE, 1.1 linux-2.6-xfs-filesize-updates.patch, NONE, 1.1 linux-2.6-xfs-setfattr-32bit-compat.patch, NONE, 1.1 kernel.spec, 1.169, 1.170
Eric Sandeen (sandeen)
fedora-extras-commits at redhat.com
Tue Sep 18 20:59:23 UTC 2007
- Previous message (by thread): rpms/polyester/FC-6 .cvsignore, 1.3, 1.4 polyester.spec, 1.3, 1.4 sources, 1.3, 1.4
- Next message (by thread): rpms/xfce4-places-plugin/F-7 .cvsignore, 1.4, 1.5 sources, 1.4, 1.5 xfce4-places-plugin.spec, 1.4, 1.5
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: sandeen
Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv2437
Modified Files:
kernel.spec
Added Files:
linux-2.6-ext3-dir_index-error-out-instead-of-bug-on-corrupt-dx-dirs.patch
linux-2.6-ext34-ensure-do_split-leaves-enough-free-space-in-both-blocks.patch
linux-2.6-xfs-avoid-replaying-inode-buffer-init.patch
linux-2.6-xfs-filesize-updates.patch
linux-2.6-xfs-setfattr-32bit-compat.patch
Log Message:
* Tue Sep 18 2007 Eric Sandeen <sandeen at redhat.com>
- ext3 bugfixes: fix potential corruption in do_split dx leaf split (#28650),
handle dx directory corruption gracefully, w/o BUG (#236464).
- xfs bugfixes: setfattr/getfattr/getversion 32-bit compat fixes (#291981),
log replay vs. filesize update fixes from sgi.
linux-2.6-ext3-dir_index-error-out-instead-of-bug-on-corrupt-dx-dirs.patch:
--- NEW FILE linux-2.6-ext3-dir_index-error-out-instead-of-bug-on-corrupt-dx-dirs.patch ---
The patch titled
dir_index: error out instead of BUG on corrupt dx dirs
has been added to the -mm tree. Its filename is
dir_index-error-out-instead-of-bug-on-corrupt-dx-dirs.patch
Index: linux-2.6.22.noarch/fs/ext3/namei.c
===================================================================
--- linux-2.6.22.noarch.orig/fs/ext3/namei.c
+++ linux-2.6.22.noarch/fs/ext3/namei.c
@@ -379,13 +379,28 @@ dx_probe(struct dentry *dentry, struct i
entries = (struct dx_entry *) (((char *)&root->info) +
root->info.info_length);
- assert(dx_get_limit(entries) == dx_root_limit(dir,
- root->info.info_length));
+
+ if (dx_get_limit(entries) != dx_root_limit(dir,
+ root->info.info_length)) {
+ ext3_warning(dir->i_sb, __FUNCTION__,
+ "dx entry: limit != root limit");
+ brelse(bh);
+ *err = ERR_BAD_DX_DIR;
+ goto fail;
+ }
+
dxtrace (printk("Look up %x", hash));
while (1)
{
count = dx_get_count(entries);
- assert (count && count <= dx_get_limit(entries));
+ if (!count || count > dx_get_limit(entries)) {
+ ext3_warning(dir->i_sb, __FUNCTION__,
+ "dx entry: no count or count > limit");
+ brelse(bh);
+ *err = ERR_BAD_DX_DIR;
+ goto fail2;
+ }
+
p = entries + 1;
q = entries + count - 1;
while (p <= q)
@@ -423,8 +438,15 @@ dx_probe(struct dentry *dentry, struct i
if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err)))
goto fail2;
at = entries = ((struct dx_node *) bh->b_data)->entries;
- assert (dx_get_limit(entries) == dx_node_limit (dir));
+ if (dx_get_limit(entries) != dx_node_limit (dir)) {
+ ext3_warning(dir->i_sb, __FUNCTION__,
+ "dx entry: limit != node limit");
+ brelse(bh);
+ *err = ERR_BAD_DX_DIR;
+ goto fail2;
+ }
frame++;
+ frame->bh = NULL;
}
fail2:
while (frame >= frame_in) {
@@ -432,6 +454,10 @@ fail2:
frame--;
}
fail:
+ if (*err == ERR_BAD_DX_DIR)
+ ext3_warning(dir->i_sb, __FUNCTION__,
+ "Corrupt dir inode %ld, running e2fsck is "
+ "recommended.", dir->i_ino);
return NULL;
}
Index: linux-2.6.22.noarch/fs/ext4/namei.c
===================================================================
--- linux-2.6.22.noarch.orig/fs/ext4/namei.c
+++ linux-2.6.22.noarch/fs/ext4/namei.c
@@ -379,13 +379,28 @@ dx_probe(struct dentry *dentry, struct i
entries = (struct dx_entry *) (((char *)&root->info) +
root->info.info_length);
- assert(dx_get_limit(entries) == dx_root_limit(dir,
- root->info.info_length));
+
+ if (dx_get_limit(entries) != dx_root_limit(dir,
+ root->info.info_length)) {
+ ext4_warning(dir->i_sb, __FUNCTION__,
+ "dx entry: limit != root limit");
+ brelse(bh);
+ *err = ERR_BAD_DX_DIR;
+ goto fail;
+ }
+
dxtrace (printk("Look up %x", hash));
while (1)
{
count = dx_get_count(entries);
- assert (count && count <= dx_get_limit(entries));
+ if (!count || count > dx_get_limit(entries)) {
+ ext4_warning(dir->i_sb, __FUNCTION__,
+ "dx entry: no count or count > limit");
+ brelse(bh);
+ *err = ERR_BAD_DX_DIR;
+ goto fail2;
+ }
+
p = entries + 1;
q = entries + count - 1;
while (p <= q)
@@ -423,8 +438,15 @@ dx_probe(struct dentry *dentry, struct i
if (!(bh = ext4_bread (NULL,dir, dx_get_block(at), 0, err)))
goto fail2;
at = entries = ((struct dx_node *) bh->b_data)->entries;
- assert (dx_get_limit(entries) == dx_node_limit (dir));
+ if (dx_get_limit(entries) != dx_node_limit (dir)) {
+ ext4_warning(dir->i_sb, __FUNCTION__,
+ "dx entry: limit != node limit");
+ brelse(bh);
+ *err = ERR_BAD_DX_DIR;
+ goto fail2;
+ }
frame++;
+ frame->bh = NULL;
}
fail2:
while (frame >= frame_in) {
@@ -432,6 +454,10 @@ fail2:
frame--;
}
fail:
+ if (*err == ERR_BAD_DX_DIR)
+ ext4_warning(dir->i_sb, __FUNCTION__,
+ "Corrupt dir inode %ld, running e2fsck is "
+ "recommended.", dir->i_ino);
return NULL;
}
linux-2.6-ext34-ensure-do_split-leaves-enough-free-space-in-both-blocks.patch:
--- NEW FILE linux-2.6-ext34-ensure-do_split-leaves-enough-free-space-in-both-blocks.patch ---
The patch titled
ext34: ensure do_split leaves enough free space in both blocks
has been added to the -mm tree. Its filename is
ext34-ensure-do_split-leaves-enough-free-space-in-both-blocks.patch
Index: linux-2.6.22.noarch/fs/ext3/namei.c
===================================================================
--- linux-2.6.22.noarch.orig/fs/ext3/namei.c
+++ linux-2.6.22.noarch/fs/ext3/namei.c
@@ -140,7 +140,8 @@ struct dx_frame
struct dx_map_entry
{
u32 hash;
- u32 offs;
+ u16 offs;
+ u16 size;
};
#ifdef CONFIG_EXT3_INDEX
@@ -697,6 +698,10 @@ errout:
* Directory block splitting, compacting
*/
+/*
+ * Create map of hash values, offsets, and sizes, stored at end of block.
+ * Returns number of entries mapped.
+ */
static int dx_make_map (struct ext3_dir_entry_2 *de, int size,
struct dx_hash_info *hinfo, struct dx_map_entry *map_tail)
{
@@ -710,7 +715,8 @@ static int dx_make_map (struct ext3_dir_
ext3fs_dirhash(de->name, de->name_len, &h);
map_tail--;
map_tail->hash = h.hash;
- map_tail->offs = (u32) ((char *) de - base);
+ map_tail->offs = (u16) ((char *) de - base);
+ map_tail->size = le16_to_cpu(de->rec_len);
count++;
cond_resched();
}
@@ -720,6 +726,7 @@ static int dx_make_map (struct ext3_dir_
return count;
}
+/* Sort map by hash value */
static void dx_sort_map (struct dx_map_entry *map, unsigned count)
{
struct dx_map_entry *p, *q, *top = map + count - 1;
@@ -1117,6 +1124,10 @@ static inline void ext3_set_de_type(stru
}
#ifdef CONFIG_EXT3_INDEX
+/*
+ * Move count entries from end of map between two memory locations.
+ * Returns pointer to last entry moved.
+ */
static struct ext3_dir_entry_2 *
dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count)
{
@@ -1135,6 +1146,10 @@ dx_move_dirents(char *from, char *to, st
return (struct ext3_dir_entry_2 *) (to - rec_len);
}
+/*
+ * Compact each dir entry in the range to the minimal rec_len.
+ * Returns pointer to last entry in range.
+ */
static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size)
{
struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base;
@@ -1157,6 +1172,11 @@ static struct ext3_dir_entry_2* dx_pack_
return prev;
}
+/*
+ * Split a full leaf block to make room for a new dir entry.
+ * Allocate a new block, and move entries so that they are approx. equally full.
+ * Returns pointer to de in block into which the new entry will be inserted.
+ */
static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
struct buffer_head **bh,struct dx_frame *frame,
struct dx_hash_info *hinfo, int *error)
@@ -1168,7 +1188,7 @@ static struct ext3_dir_entry_2 *do_split
u32 hash2;
struct dx_map_entry *map;
char *data1 = (*bh)->b_data, *data2;
- unsigned split;
+ unsigned split, move, size, i;
struct ext3_dir_entry_2 *de = NULL, *de2;
int err = 0;
@@ -1196,8 +1216,19 @@ static struct ext3_dir_entry_2 *do_split
count = dx_make_map ((struct ext3_dir_entry_2 *) data1,
blocksize, hinfo, map);
map -= count;
- split = count/2; // need to adjust to actual middle
dx_sort_map (map, count);
+ /* Split the existing block in the middle, size-wise */
+ size = 0;
+ move = 0;
+ for (i = count-1; i >= 0; i--) {
+ /* is more than half of this entry in 2nd half of the block? */
+ if (size + map[i].size/2 > blocksize/2)
+ break;
+ size += map[i].size;
+ move++;
+ }
+ /* map index at which we will split */
+ split = count - move;
hash2 = map[split].hash;
continued = hash2 == map[split - 1].hash;
dxtrace(printk("Split block %i at %x, %i/%i\n",
Index: linux-2.6.22.noarch/fs/ext4/namei.c
===================================================================
--- linux-2.6.22.noarch.orig/fs/ext4/namei.c
+++ linux-2.6.22.noarch/fs/ext4/namei.c
@@ -140,7 +140,8 @@ struct dx_frame
struct dx_map_entry
{
u32 hash;
- u32 offs;
+ u16 offs;
+ u16 size;
};
#ifdef CONFIG_EXT4_INDEX
@@ -697,6 +698,10 @@ errout:
* Directory block splitting, compacting
*/
+/*
+ * Create map of hash values, offsets, and sizes, stored at end of block.
+ * Returns number of entries mapped.
+ */
static int dx_make_map (struct ext4_dir_entry_2 *de, int size,
struct dx_hash_info *hinfo, struct dx_map_entry *map_tail)
{
@@ -710,7 +715,8 @@ static int dx_make_map (struct ext4_dir_
ext4fs_dirhash(de->name, de->name_len, &h);
map_tail--;
map_tail->hash = h.hash;
- map_tail->offs = (u32) ((char *) de - base);
+ map_tail->offs = (u16) ((char *) de - base);
+ map_tail->size = le16_to_cpu(de->rec_len);
count++;
cond_resched();
}
@@ -720,6 +726,7 @@ static int dx_make_map (struct ext4_dir_
return count;
}
+/* Sort map by hash value */
static void dx_sort_map (struct dx_map_entry *map, unsigned count)
{
struct dx_map_entry *p, *q, *top = map + count - 1;
@@ -1115,6 +1122,10 @@ static inline void ext4_set_de_type(stru
}
#ifdef CONFIG_EXT4_INDEX
+/*
+ * Move count entries from end of map between two memory locations.
+ * Returns pointer to last entry moved.
+ */
static struct ext4_dir_entry_2 *
dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count)
{
@@ -1133,6 +1144,10 @@ dx_move_dirents(char *from, char *to, st
return (struct ext4_dir_entry_2 *) (to - rec_len);
}
+/*
+ * Compact each dir entry in the range to the minimal rec_len.
+ * Returns pointer to last entry in range.
+ */
static struct ext4_dir_entry_2* dx_pack_dirents(char *base, int size)
{
struct ext4_dir_entry_2 *next, *to, *prev, *de = (struct ext4_dir_entry_2 *) base;
@@ -1155,6 +1170,11 @@ static struct ext4_dir_entry_2* dx_pack_
return prev;
}
+/*
+ * Split a full leaf block to make room for a new dir entry.
+ * Allocate a new block, and move entries so that they are approx. equally full.
+ * Returns pointer to de in block into which the new entry will be inserted.
+ */
static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
struct buffer_head **bh,struct dx_frame *frame,
struct dx_hash_info *hinfo, int *error)
@@ -1166,7 +1186,7 @@ static struct ext4_dir_entry_2 *do_split
u32 hash2;
struct dx_map_entry *map;
char *data1 = (*bh)->b_data, *data2;
- unsigned split;
+ unsigned split, move, size, i;
struct ext4_dir_entry_2 *de = NULL, *de2;
int err = 0;
@@ -1194,8 +1214,19 @@ static struct ext4_dir_entry_2 *do_split
count = dx_make_map ((struct ext4_dir_entry_2 *) data1,
blocksize, hinfo, map);
map -= count;
- split = count/2; // need to adjust to actual middle
dx_sort_map (map, count);
+ /* Split the existing block in the middle, size-wise */
+ size = 0;
+ move = 0;
+ for (i = count-1; i >= 0; i--) {
+ /* is more than half of this entry in 2nd half of the block? */
+ if (size + map[i].size/2 > blocksize/2)
+ break;
+ size += map[i].size;
+ move++;
+ }
+ /* map index at which we will split */
+ split = count - move;
hash2 = map[split].hash;
continued = hash2 == map[split - 1].hash;
dxtrace(printk("Split block %i at %x, %i/%i\n",
linux-2.6-xfs-avoid-replaying-inode-buffer-init.patch:
--- NEW FILE linux-2.6-xfs-avoid-replaying-inode-buffer-init.patch ---
From: Lachlan McIlroy <lachlan at sgi.com>
Date: Fri, 14 Sep 2007 05:23:04 +0000 (+1000)
Subject: [XFS] Avoid replaying inode buffer initialisation log items if on-disk
X-Git-Url: http://oss.sgi.com/cgi-bin/gitweb.cgi?p=xfs%2Fxfs-2.6.git;a=commitdiff_plain;h=4a5fd6f64de88906ceba164e9b002a87f3e55894;hp=8e04f1324e37bd317502c4393d381e5060323c08
[XFS] Avoid replaying inode buffer initialisation log items if on-disk
version is newer.
SGI-PV: 969656
SGI-Modid: xfs-linux-melb:xfs-kern:29676a
Signed-off-by: Lachlan McIlroy <lachlan at sgi.com>
Signed-off-by: David Chinner <dgc at sgi.com>
Signed-off-by: Tim Shimmin <tes at sgi.com>
---
Index: linux-2.6.22.noarch/fs/xfs/xfs_buf_item.h
===================================================================
--- linux-2.6.22.noarch.orig/fs/xfs/xfs_buf_item.h
+++ linux-2.6.22.noarch/fs/xfs/xfs_buf_item.h
@@ -52,6 +52,11 @@ typedef struct xfs_buf_log_format_t {
#define XFS_BLI_UDQUOT_BUF 0x4
#define XFS_BLI_PDQUOT_BUF 0x8
#define XFS_BLI_GDQUOT_BUF 0x10
+/*
+ * This flag indicates that the buffer contains newly allocated
+ * inodes.
+ */
+#define XFS_BLI_INODE_NEW_BUF 0x20
#define XFS_BLI_CHUNK 128
#define XFS_BLI_SHIFT 7
Index: linux-2.6.22.noarch/fs/xfs/xfs_log_recover.c
===================================================================
--- linux-2.6.22.noarch.orig/fs/xfs/xfs_log_recover.c
+++ linux-2.6.22.noarch/fs/xfs/xfs_log_recover.c
@@ -1874,6 +1874,7 @@ xlog_recover_do_inode_buffer(
/*ARGSUSED*/
STATIC void
xlog_recover_do_reg_buffer(
+ xfs_mount_t *mp,
xlog_recover_item_t *item,
xfs_buf_t *bp,
xfs_buf_log_format_t *buf_f)
@@ -1884,6 +1885,50 @@ xlog_recover_do_reg_buffer(
unsigned int *data_map = NULL;
unsigned int map_size = 0;
int error;
+ int stale_buf = 1;
+
+ /*
+ * Scan through the on-disk inode buffer and attempt to
+ * determine if it has been written to since it was logged.
+ *
+ * - If any of the magic numbers are incorrect then the buffer is stale
+ * - If any of the modes are non-zero then the buffer is not stale
+ * - If all of the modes are zero and at least one of the generation
+ * counts is non-zero then the buffer is stale
+ *
+ * If the end result is a stale buffer then the log buffer is replayed
+ * otherwise it is skipped.
+ *
+ * This heuristic is not perfect. It can be improved by scanning the
+ * entire inode chunk for evidence that any of the inode clusters have
+ * been updated. To fix this problem completely we will need a major
+ * architectural change to the logging system.
+ */
+ if (buf_f->blf_flags & XFS_BLI_INODE_NEW_BUF) {
+ xfs_dinode_t *dip;
+ int inodes_per_buf;
+ int mode_count = 0;
+ int gen_count = 0;
+
+ stale_buf = 0;
+ inodes_per_buf = XFS_BUF_COUNT(bp) >> mp->m_sb.sb_inodelog;
+ for (i = 0; i < inodes_per_buf; i++) {
+ dip = (xfs_dinode_t *)xfs_buf_offset(bp,
+ i * mp->m_sb.sb_inodesize);
+ if (be16_to_cpu(dip->di_core.di_magic) !=
+ XFS_DINODE_MAGIC) {
+ stale_buf = 1;
+ break;
+ }
+ if (be16_to_cpu(dip->di_core.di_mode))
+ mode_count++;
+ if (be16_to_cpu(dip->di_core.di_gen))
+ gen_count++;
+ }
+
+ if (!mode_count && gen_count)
+ stale_buf = 1;
+ }
switch (buf_f->blf_type) {
case XFS_LI_BUF:
@@ -1917,7 +1962,7 @@ xlog_recover_do_reg_buffer(
-1, 0, XFS_QMOPT_DOWARN,
"dquot_buf_recover");
}
- if (!error)
+ if (!error && stale_buf)
memcpy(xfs_buf_offset(bp,
(uint)bit << XFS_BLI_SHIFT), /* dest */
item->ri_buf[i].i_addr, /* source */
@@ -2089,7 +2134,7 @@ xlog_recover_do_dquot_buffer(
if (log->l_quotaoffs_flag & type)
return;
- xlog_recover_do_reg_buffer(item, bp, buf_f);
+ xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
}
/*
@@ -2190,7 +2235,7 @@ xlog_recover_do_buffer_trans(
(XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
} else {
- xlog_recover_do_reg_buffer(item, bp, buf_f);
+ xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
}
if (error)
return XFS_ERROR(error);
Index: linux-2.6.22.noarch/fs/xfs/xfs_trans_buf.c
===================================================================
--- linux-2.6.22.noarch.orig/fs/xfs/xfs_trans_buf.c
+++ linux-2.6.22.noarch/fs/xfs/xfs_trans_buf.c
@@ -966,6 +966,7 @@ xfs_trans_inode_alloc_buf(
ASSERT(atomic_read(&bip->bli_refcount) > 0);
bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF;
+ bip->bli_format.blf_flags |= XFS_BLI_INODE_NEW_BUF;
}
linux-2.6-xfs-filesize-updates.patch:
--- NEW FILE linux-2.6-xfs-filesize-updates.patch ---
From: Lachlan McIlroy <lachlan at sgi.com>
Date: Fri, 14 Sep 2007 05:22:50 +0000 (+1000)
Subject: [XFS] Ensure file size updates have been completed before writing inode to
X-Git-Url: http://oss.sgi.com/cgi-bin/gitweb.cgi?p=xfs%2Fxfs-2.6.git;a=commitdiff_plain;h=8e04f1324e37bd317502c4393d381e5060323c08;hp=ef6567a363c5f301c0bc885068d93cd9b3c05cc9
[XFS] Ensure file size updates have been completed before writing inode to
disk.
SGI-PV: 968767
SGI-Modid: xfs-linux-melb:xfs-kern:29675a
Signed-off-by: Lachlan McIlroy <lachlan at sgi.com>
Signed-off-by: David Chinner <dgc at sgi.com>
Signed-off-by: Tim Shimmin <tes at sgi.com>
---
Index: linux-2.6.22.noarch/fs/xfs/linux-2.6/xfs_aops.c
===================================================================
--- linux-2.6.22.noarch.orig/fs/xfs/linux-2.6/xfs_aops.c
+++ linux-2.6.22.noarch/fs/xfs/linux-2.6/xfs_aops.c
@@ -181,6 +181,7 @@ xfs_setfilesize(
ip->i_d.di_size = isize;
ip->i_update_core = 1;
ip->i_update_size = 1;
+ mark_inode_dirty_sync(vn_to_inode(ioend->io_vnode));
}
xfs_iunlock(ip, XFS_ILOCK_EXCL);
Index: linux-2.6.22.noarch/fs/xfs/linux-2.6/xfs_super.c
===================================================================
--- linux-2.6.22.noarch.orig/fs/xfs/linux-2.6/xfs_super.c
+++ linux-2.6.22.noarch/fs/xfs/linux-2.6/xfs_super.c
@@ -415,8 +415,10 @@ xfs_fs_write_inode(
if (vp) {
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
- if (sync)
+ if (sync) {
+ filemap_fdatawait(inode->i_mapping);
flags |= FLUSH_SYNC;
+ }
error = bhv_vop_iflush(vp, flags);
if (error == EAGAIN)
error = sync? bhv_vop_iflush(vp, flags | FLUSH_LOG) : 0;
Index: linux-2.6.22.noarch/fs/xfs/xfs_vnodeops.c
===================================================================
--- linux-2.6.22.noarch.orig/fs/xfs/xfs_vnodeops.c
+++ linux-2.6.22.noarch/fs/xfs/xfs_vnodeops.c
@@ -1082,6 +1082,9 @@ xfs_fsync(
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
return XFS_ERROR(EIO);
+ if (flag & FSYNC_DATA)
+ filemap_fdatawait(vn_to_inode(XFS_ITOV(ip))->i_mapping);
+
/*
* We always need to make sure that the required inode state
* is safe on disk. The vnode might be clean but because
@@ -3769,12 +3772,16 @@ xfs_inode_flush(
sync_lsn = log->l_last_sync_lsn;
GRANT_UNLOCK(log, s);
- if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) <= 0))
- return 0;
+ if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) > 0)) {
+ if (flags & FLUSH_SYNC)
+ log_flags |= XFS_LOG_SYNC;
+ error = xfs_log_force(mp, iip->ili_last_lsn, log_flags);
+ if (error)
+ return error;
+ }
- if (flags & FLUSH_SYNC)
- log_flags |= XFS_LOG_SYNC;
- return xfs_log_force(mp, iip->ili_last_lsn, log_flags);
+ if (ip->i_update_core == 0)
+ return 0;
}
}
@@ -3788,9 +3795,6 @@ xfs_inode_flush(
if (flags & FLUSH_INODE) {
int flush_flags;
- if (xfs_ipincount(ip))
- return EAGAIN;
-
if (flags & FLUSH_SYNC) {
xfs_ilock(ip, XFS_ILOCK_SHARED);
xfs_iflock(ip);
linux-2.6-xfs-setfattr-32bit-compat.patch:
--- NEW FILE linux-2.6-xfs-setfattr-32bit-compat.patch ---
Date: Mon, 17 Sep 2007 12:36:02 -0500
From: Eric Sandeen <sandeen at sandeen.net>
To: Eric Sandeen <sandeen at sandeen.net>
CC: xfs-oss <xfs at oss.sgi.com>
Subject: [PATCH V2] fix 32-bit compat ioctls for GETXFLAGS, SETXFLAGS, GETVERSION
In Red Hat bugzilla #291981, Sami Farin notes that 32-bit-compat
lsattr/chattr does not work on xfs. After investigation, I found:
XFS_IOC_GETVERSION, XFS_IOC_GETXFLAGS and XFS_IOC_SETXFLAGS all
take a "long" which changes size between 32 and 64 bit platforms.
So, the ioctl cmds that come in from a 32-bit app aren't as expected,
for example on GETXFLAGS,
unknown cmd fd(3) cmd(80046601){t:'f';sz:4}
due to the size mismatch.
So, use instead the 32-bit version of the commands for compat ioctls,
and other than that it doesn't take any more manipulation.
Also, for both native and compat versions, just define them to
the values as defined in fs.h
Signed-off-by: Eric Sandeen <sandeen at sandeen.net>
Index: linux-2.6.22/fs/xfs/linux-2.6/xfs_ioctl32.c
===================================================================
--- linux-2.6.22.orig/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ linux-2.6.22/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -376,9 +376,6 @@ xfs_compat_ioctl(
switch (cmd) {
case XFS_IOC_DIOINFO:
case XFS_IOC_FSGEOMETRY:
- case XFS_IOC_GETVERSION:
- case XFS_IOC_GETXFLAGS:
- case XFS_IOC_SETXFLAGS:
case XFS_IOC_FSGETXATTR:
case XFS_IOC_FSSETXATTR:
case XFS_IOC_FSGETXATTRA:
@@ -404,6 +401,11 @@ xfs_compat_ioctl(
case XFS_IOC_ERROR_CLEARALL:
break;
+ case XFS_IOC32_GETXFLAGS:
+ case XFS_IOC32_SETXFLAGS:
+ case XFS_IOC32_GETVERSION:
+ cmd = _NATIVE_IOC(cmd, long);
+ break;
#ifdef BROKEN_X86_ALIGNMENT
/* xfs_flock_t has wrong u32 vs u64 alignment */
case XFS_IOC_ALLOCSP_32:
Index: linux-2.6.22/fs/xfs/xfs_fs.h
===================================================================
--- linux-2.6.22.orig/fs/xfs/xfs_fs.h
+++ linux-2.6.22/fs/xfs/xfs_fs.h
@@ -436,9 +436,13 @@ typedef struct xfs_handle {
/*
* ioctl commands that are used by Linux filesystems
*/
-#define XFS_IOC_GETXFLAGS _IOR('f', 1, long)
-#define XFS_IOC_SETXFLAGS _IOW('f', 2, long)
-#define XFS_IOC_GETVERSION _IOR('v', 1, long)
+#define XFS_IOC_GETXFLAGS FS_IOC_GETFLAGS
+#define XFS_IOC_SETXFLAGS FS_IOC_SETFLAGS
+#define XFS_IOC_GETVERSION FS_IOC_GETVERSION
+/* 32-bit compat counterparts */
+#define XFS_IOC32_GETXFLAGS FS_IOC32_GETFLAGS
+#define XFS_IOC32_SETXFLAGS FS_IOC32_SETFLAGS
+#define XFS_IOC32_GETVERSION FS_IOC32_GETVERSION
/*
* ioctl commands that replace IRIX fcntl()'s
Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.169
retrieving revision 1.170
diff -u -r1.169 -r1.170
--- kernel.spec 18 Sep 2007 14:01:35 -0000 1.169
+++ kernel.spec 18 Sep 2007 20:58:50 -0000 1.170
@@ -668,7 +668,12 @@
Patch1504: linux-2.6-xfs-optimize-away-realtime-tests.patch
Patch1505: linux-2.6-xfs-refactor-xfs_mountfs.patch
Patch1506: linux-2.6-xfs-fix-filestreams-free-func-cast.patch
-Patch1508: linux-2.6-firewire-multi-lun.patch
+Patch1507: linux-2.6-xfs-filesize-updates.patch
+Patch1508: linux-2.6-xfs-avoid-replaying-inode-buffer-init.patch
+Patch1509: linux-2.6-xfs-setfattr-32bit-compat.patch
+Patch1510: linux-2.6-ext3-dir_index-error-out-instead-of-bug-on-corrupt-dx-dirs.patch
+Patch1511: linux-2.6-ext34-ensure-do_split-leaves-enough-free-space-in-both-blocks.patch
+Patch1512: linux-2.6-firewire-multi-lun.patch
Patch1515: linux-2.6-lirc.patch
Patch1600: linux-2.6-x86-edd-maxdrive.patch
@@ -1175,6 +1180,13 @@
ApplyPatch linux-2.6-xfs-optimize-away-realtime-tests.patch
ApplyPatch linux-2.6-xfs-refactor-xfs_mountfs.patch
ApplyPatch linux-2.6-xfs-fix-filestreams-free-func-cast.patch
+ApplyPatch linux-2.6-xfs-filesize-updates.patch
+ApplyPatch linux-2.6-xfs-avoid-replaying-inode-buffer-init.patch
+ApplyPatch linux-2.6-xfs-setfattr-32bit-compat.patch
+
+# ext3 bugfixes
+ApplyPatch linux-2.6-ext3-dir_index-error-out-instead-of-bug-on-corrupt-dx-dirs.patch
+ApplyPatch linux-2.6-ext34-ensure-do_split-leaves-enough-free-space-in-both-blocks.patch
#
# misc small stuff to make things compile
@@ -1799,6 +1811,12 @@
%changelog
+* Tue Sep 18 2007 Eric Sandeen <sandeen at redhat.com>
+- ext3 bugfixes: fix potential corruption in do_split dx leaf split (#28650),
+ handle dx directory corruption gracefully, w/o BUG (#236464).
+- xfs bugfixes: setfattr/getfattr/getversion 32-bit compat fixes (#291981),
+ log replay vs. filesize update fixes from sgi.
+
* Tue Sep 18 2007 John W. Linville <linville at redhat.com>
- Update bits from wireless-2.6 and wireless-dev
- Previous message (by thread): rpms/polyester/FC-6 .cvsignore, 1.3, 1.4 polyester.spec, 1.3, 1.4 sources, 1.3, 1.4
- Next message (by thread): rpms/xfce4-places-plugin/F-7 .cvsignore, 1.4, 1.5 sources, 1.4, 1.5 xfce4-places-plugin.spec, 1.4, 1.5
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-extras-commits
mailing list