[Ocfs2-commits] rev 27 - in trunk/src: . inc
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Thu Feb 5 20:50:03 CST 2004
Author: manish
Date: 2004-02-05 20:50:01 -0600 (Thu, 05 Feb 2004)
New Revision: 27
Modified:
trunk/src/dcache.c
trunk/src/file.c
trunk/src/inc/proto.h
trunk/src/inode.c
trunk/src/namei.c
trunk/src/nm.c
trunk/src/oin.c
Log:
fixes nasty deadlock with truncate_inode_pages while holding oin main_res, removes ofile for non-directories and thus fixes problem in file close where oin was
being taken from ofile
Modified: trunk/src/dcache.c
===================================================================
--- trunk/src/dcache.c 2004-02-06 02:44:32 UTC (rev 26)
+++ trunk/src/dcache.c 2004-02-06 02:50:01 UTC (rev 27)
@@ -20,6 +20,7 @@
ocfs_find_inode_args args;
struct qstr q;
struct buffer_head *fe_bh = NULL;
+ int needs_trunc;
LOG_ENTRY_ARGS ("(0x%08x, %d, '%*s')\n", dentry, flags,
dentry->d_name.len, dentry->d_name.name);
@@ -53,10 +54,12 @@
/* TODO: optimize */
ocfs_down_sem (&(oin->main_res), true);
oin->needs_verification = true;
- tmpstat = ocfs_verify_update_oin(osb, oin);
+ tmpstat = ocfs_verify_update_oin(osb, oin, &needs_trunc);
if (tmpstat < 0)
LOG_ERROR_STATUS (tmpstat);
ocfs_up_sem (&(oin->main_res));
+ if (needs_trunc)
+ ocfs_truncate_inode_pages(inode, 0);
goto bail;
}
Modified: trunk/src/file.c
===================================================================
--- trunk/src/file.c 2004-02-06 02:44:32 UTC (rev 26)
+++ trunk/src/file.c 2004-02-06 02:50:01 UTC (rev 27)
@@ -28,7 +28,6 @@
{
struct dentry *dentry = file->f_dentry;
struct inode *parent = dentry->d_parent->d_inode;
- ocfs_file *ofile = NULL;
int ret =0, err = 0, status = 0;
int mode = file->f_flags;
ocfs_super *osb = NULL;
@@ -40,6 +39,7 @@
struct buffer_head *fe_bh = NULL;
__u64 parent_off;
ocfs_sem *oin_sem = NULL;
+ int truncate_pages = 0;
LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, '%*s')\n", inode, file,
file->f_dentry->d_name.len, file->f_dentry->d_name.name);
@@ -154,7 +154,7 @@
/* only call ocfs_verify_update_oin if there's a good inode */
if (oin->inode == inode && OIN_NEEDS_VERIFICATION(oin)) {
- status = ocfs_verify_update_oin (osb, oin);
+ status = ocfs_verify_update_oin (osb, oin, &truncate_pages);
if (status < 0) {
/* disable VOLUME TODO */
LOG_ERROR_STATUS (status);
@@ -194,23 +194,11 @@
OCFS_SET_FLAG(oin->oin_flags, OCFS_OIN_OPEN_FOR_DIRECTIO);
else {
OCFS_CLEAR_FLAG(oin->oin_flags, OCFS_OIN_OPEN_FOR_DIRECTIO);
- fsync_inode_buffers(inode);
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,18)
- fsync_inode_data_buffers(inode);
-#endif
- if (inode->i_data.nrpages)
- ocfs_truncate_inode_pages(inode, 0);
+ truncate_pages = 1;
}
}
- ofile = ocfs_allocate_ofile (OCFS_ATTRIB_REG);
- if (ofile == NULL) {
- LOG_ERROR_STATUS (status = -ENOMEM);
- goto leave;
- }
-
oin->open_hndl_cnt++;
- ofile->oin = oin;
/* We should clear the in use now as we are safe from the case */
/* where the voting thread can vote and we have an open in */
@@ -224,6 +212,16 @@
bAcquiredOIN = false;
}
+ if (truncate_pages) {
+ fsync_inode_buffers(inode);
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,18)
+ fsync_inode_data_buffers(inode);
+#endif
+ if (inode->i_data.nrpages)
+ ocfs_truncate_inode_pages(inode, 0);
+ }
+
+
status = 0;
leave:
@@ -258,7 +256,6 @@
ret = status;
atomic_dec (&parent->i_count);
} else {
- file->private_data = (void *) ofile;
ret = 0;
}
@@ -276,10 +273,9 @@
*/
int ocfs_file_release (struct inode *inode, struct file *file)
{
- //int nbhs = KIO_MAX_SECTORS;
ocfs_file *ofile = NULL;
ocfs_super * osb;
- ocfs_inode *oin;
+ ocfs_inode *oin = NULL;
struct dentry *dentry;
struct inode *parent;
@@ -312,24 +308,15 @@
ocfs_safefree (ofile->curr_dir_buf);
ofile->curr_dir_buf = NULL;
}
- // hmm
- // if (ofile->f_iobuf)
- // free_kiovec_sz(1, &ofile->f_iobuf, &nbhs);
ocfs_release_ofile (ofile);
}
goto bail;
}
/* file */
- oin = NULL;
-
- if (ofile == NULL) {
- if (inode_data_is_oin(inode))
- oin = GET_INODE_OIN(inode);
- } else {
- oin = ofile->oin;
- ocfs_release_ofile (ofile);
- }
+ if (inode_data_is_oin(inode))
+ oin = GET_INODE_OIN(inode);
+
if (oin == NULL)
goto do_parent_dec;
@@ -338,8 +325,8 @@
oin->main_res.magic != OCFS_SEM_MAGIC) {
int i;
- LOG_ERROR_ARGS("oin appears to have been freed! oin=%p, ofile=%p, inode->oin=%p\n",
- oin, ofile, GET_INODE_OIN(inode));
+ LOG_ERROR_ARGS("oin appears to have been freed! oin=%p, inode->oin=%p\n",
+ oin, GET_INODE_OIN(inode));
for (i=0; i<sizeof (ocfs_inode); i++) {
printk("%03x ", ((char *)oin)[i]);
}
@@ -364,13 +351,6 @@
/* for the inode, but here I just check this one becuz I'm lz */
/* no hard links yet so who cares */
if (!atomic_read(&dentry->d_count)) {
- fsync_inode_buffers(inode);
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,18)
- fsync_inode_data_buffers(inode);
-#endif
- if (inode->i_data.nrpages)
- ocfs_truncate_inode_pages(inode, 0);
-
if (oin->oin_flags & OCFS_OIN_OPEN_FOR_DIRECTIO) {
OCFS_CLEAR_FLAG(oin->oin_flags, OCFS_OIN_OPEN_FOR_DIRECTIO);
}
@@ -382,16 +362,23 @@
ocfs_up_sem (&(oin->main_res));
ocfs_release_oin (oin, true);
- } else {
fsync_inode_buffers(inode);
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,18)
fsync_inode_data_buffers(inode);
#endif
if (inode->i_data.nrpages)
ocfs_truncate_inode_pages(inode, 0);
-
+ } else {
ocfs_up_sem (&(oin->main_res));
ocfs_release_cached_oin (osb, oin);
+ fsync_inode_buffers(inode);
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,18)
+ fsync_inode_data_buffers(inode);
+#endif
+ if (inode->i_data.nrpages)
+ ocfs_truncate_inode_pages(inode, 0);
+
+
}
do_parent_dec:
@@ -597,6 +584,7 @@
__u64 newsize;
ocfs_lock_res *lockres = NULL;
struct super_block *sb = inode->i_sb;
+ int needs_trunc = 0;
LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, %d, '%*s')\n", filp, buf, count,
filp->f_dentry->d_name.len, filp->f_dentry->d_name.name);
@@ -672,8 +660,10 @@
if (OIN_NEEDS_VERIFICATION (oin)) {
LOG_TRACE_STR ("OIN_NEEDS_VERIFICATION");
ocfs_down_sem (&(oin->main_res), true);
- status = ocfs_verify_update_oin (osb, oin);
+ status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
ocfs_up_sem (&(oin->main_res));
+ if (needs_trunc)
+ ocfs_truncate_inode_pages(inode, 0);
if (status < 0) {
LOG_TRACE_STR ("ocfs_verify_update_oin failed");
LOG_TRACE_STR ("TODO: disable volume");
@@ -772,7 +762,7 @@
ocfs_inode *oin = NULL;
ocfs_super *osb = NULL;
struct inode *inode = filp->f_dentry->d_inode;
- int status;
+ int status = 0, needs_trunc = 0;
LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, %d, '%*s')\n", filp, buf, count,
filp->f_dentry->d_name.len, filp->f_dentry->d_name.name);
@@ -798,8 +788,10 @@
if (OIN_NEEDS_VERIFICATION (oin)) {
ocfs_down_sem (&(oin->main_res), true);
- status = ocfs_verify_update_oin (osb, oin);
+ status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
ocfs_up_sem (&(oin->main_res));
+ if (needs_trunc)
+ ocfs_truncate_inode_pages(inode, 0);
if (status < 0) {
LOG_TRACE_STR ("ocfs_verify_update_oin failed");
LOG_TRACE_STR ("TODO: disable volume");
@@ -1305,6 +1297,7 @@
__u64 parentOff, fileOff;
struct super_block *sb = inode->i_sb;
bool extended = false;
+ int needs_trunc = 0;
LOG_ENTRY_ARGS ("(0x%08x, '%*s')\n", dentry,
dentry->d_name.len, dentry->d_name.name);
@@ -1358,7 +1351,7 @@
ocfs_down_sem (&(oin->main_res), true);
if (OIN_NEEDS_VERIFICATION (oin)) {
LOG_TRACE_STR ("OIN_NEEDS_VERIFICATION");
- status = ocfs_verify_update_oin (osb, oin);
+ status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
if (status < 0) {
LOG_ERROR_STATUS (status);
LOG_TRACE_STR ("TODO: disable volume");
@@ -1368,6 +1361,8 @@
}
}
ocfs_up_sem (&(oin->main_res));
+ if (needs_trunc)
+ ocfs_truncate_inode_pages(inode, 0);
}
if (inode->i_size > newsize)
@@ -1478,7 +1473,7 @@
ocfs_inode *oin;
struct inode *inode;
struct super_block *sb = dentry->d_inode->i_sb;
- int status;
+ int status, needs_trunc = 0;
LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, '%*s')\n", dentry, attr,
dentry->d_name.len, dentry->d_name.name);
@@ -1491,8 +1486,10 @@
goto bail;
if (oin != NULL) {
ocfs_down_sem (&(oin->main_res), true);
- status = ocfs_verify_update_oin (oin->osb, oin);
+ status = ocfs_verify_update_oin (oin->osb, oin, &needs_trunc);
ocfs_up_sem (&(oin->main_res));
+ if (needs_trunc)
+ ocfs_truncate_inode_pages(inode, 0);
if (status < 0)
LOG_ERROR_STATUS (status);
}
Modified: trunk/src/inc/proto.h
===================================================================
--- trunk/src/inc/proto.h 2004-02-06 02:44:32 UTC (rev 26)
+++ trunk/src/inc/proto.h 2004-02-06 02:50:01 UTC (rev 27)
@@ -113,7 +113,7 @@
void ocfs_linux_dbg_free (const void *Buffer);
-int ocfs_verify_update_oin (ocfs_super * osb, ocfs_inode * oin);
+int ocfs_verify_update_oin (ocfs_super * osb, ocfs_inode * oin, int *needs_trunc);
int ocfs_create_oin_from_entry (ocfs_super * osb, struct buffer_head * fe_bh, ocfs_inode ** new_oin, __u64 parent_dir_off, struct inode *inode);
int ocfs_initialize_oin (ocfs_inode * oin, ocfs_super * osb, __u32 flags, __u64 file_off, __u64 lock_id, bool new_file, struct inode *inode);
int ocfs_create_new_oin (ocfs_inode ** Returnedoin, __u64 alloc_size, ocfs_super * osb);
Modified: trunk/src/inode.c
===================================================================
--- trunk/src/inode.c 2004-02-06 02:44:32 UTC (rev 26)
+++ trunk/src/inode.c 2004-02-06 02:50:01 UTC (rev 27)
@@ -1193,6 +1193,7 @@
int set_new = 0; /* flag */
u32 new_size; /* In sectors, the size of the contiguous block */
unsigned char blocksize_bits;
+ int needs_trunc = 0;
if (!inode || !bh_result) {
LOG_ERROR_STR("ocfs_direct_IO_get_blocks: inode or bh_result is null");
@@ -1209,7 +1210,9 @@
/* make sure we're up to date... */
if (OIN_NEEDS_VERIFICATION (oin)) {
LOG_TRACE_STR ("ocfs_direct_IO_get_blocks: verify oin.");
- status = ocfs_verify_update_oin (osb, oin);
+ status = ocfs_verify_update_oin (osb, oin, &needs_trunc);
+ if (needs_trunc)
+ ocfs_truncate_inode_pages(inode, 0);
if (status < 0) {
LOG_TRACE_STR ("ocfs_verify_update_oin failed");
ret = -EIO;
Modified: trunk/src/namei.c
===================================================================
--- trunk/src/namei.c 2004-02-06 02:44:32 UTC (rev 26)
+++ trunk/src/namei.c 2004-02-06 02:50:01 UTC (rev 27)
@@ -867,6 +867,7 @@
__u32 oldfe_lockid = 0;
__u32 newfe_flags = 0;
__u32 newfe_lockid = 0;
+ int needs_trunc = 0;
LOG_ENTRY_ARGS ("(0x%08x, 0x%08x, 0x%08x, 0x%08x, from='%*s' to='%*s')\n",
old_dir, old_dentry, new_dir, new_dentry,
@@ -933,9 +934,11 @@
/* OIN exists and it's not marked for deletion! */
ocfs_down_sem (&(newOIN->main_res), true);
OCFS_SET_FLAG (newOIN->oin_flags, OCFS_OIN_IN_USE);
+ status = ocfs_verify_update_oin (osb, newOIN, &needs_trunc);
ocfs_up_sem (&(newOIN->main_res));
- status = ocfs_verify_update_oin (osb, newOIN);
delete_target_oin = true;
+ if (needs_trunc)
+ ocfs_truncate_inode_pages(new_inode, 0);
}
}
Modified: trunk/src/nm.c
===================================================================
--- trunk/src/nm.c 2004-02-06 02:44:32 UTC (rev 26)
+++ trunk/src/nm.c 2004-02-06 02:50:01 UTC (rev 27)
@@ -713,6 +713,7 @@
ocfs_dlm_msg *dlm_msg = (comm_vote ? ctxt->u.dlm_msg : NULL);
__u32 node_num = ctxt->node_num;
__u64 lock_id, seq_num;
+ int needs_trunc = 0;
LOG_ENTRY_ARGS ("(0x%08x, 0x%08x)\n", osb, ctxt);
@@ -802,10 +803,16 @@
LOG_TRACE_STR("UPDATE_OIN_INODE");
ocfs_down_sem (&(oin->main_res), true);
oin->needs_verification = true;
- tmpstat = ocfs_verify_update_oin(osb, oin);
+ tmpstat = ocfs_verify_update_oin(osb, oin, &needs_trunc);
if (tmpstat < 0)
LOG_ERROR_STATUS (tmpstat);
ocfs_up_sem (&(oin->main_res));
+ if (needs_trunc) {
+ if (inode)
+ ocfs_truncate_inode_pages(inode, 0);
+ else
+ LOG_ERROR_STR("cannot truncate inode pages, inode NULL!");
+ }
vote_response = FLAG_VOTE_OIN_UPDATED;
break;
@@ -820,13 +827,17 @@
oin_sem = &(oin->main_res);
ocfs_down_sem (oin_sem, true);
oin->needs_verification = true;
- tmpstat = ocfs_verify_update_oin(osb, oin);
+ tmpstat = ocfs_verify_update_oin(osb, oin, &needs_trunc);
if (tmpstat < 0)
LOG_ERROR_STATUS (tmpstat);
/* If OIN_IN_USE is set we should go back and retry */
for (i=0; i<5 && oin->oin_flags & OCFS_OIN_IN_USE; i++) {
ocfs_up_sem (oin_sem);
+ if (needs_trunc) {
+ ocfs_truncate_inode_pages(inode, 0);
+ needs_trunc = 0;
+ }
ocfs_sleep (20);
ocfs_down_sem (oin_sem, true);
}
@@ -844,6 +855,10 @@
ocfs_release_lockres (lockres);
lockres = NULL;
oin_sem = NULL;
+ if (needs_trunc) {
+ ocfs_truncate_inode_pages(inode, 0);
+ needs_trunc = 0;
+ }
}
}
if (inode && (flags & FLAG_ACQUIRE_LOCK)) {
@@ -893,6 +908,11 @@
if (oin_sem)
ocfs_up_sem (oin_sem);
+ if (needs_trunc) {
+ ocfs_truncate_inode_pages(inode, 0);
+ needs_trunc = 0;
+ }
+
break;
case RELEASE_CACHE:
Modified: trunk/src/oin.c
===================================================================
--- trunk/src/oin.c 2004-02-06 02:44:32 UTC (rev 26)
+++ trunk/src/oin.c 2004-02-06 02:50:01 UTC (rev 27)
@@ -11,7 +11,7 @@
* filename. We currently cache all the oin's. We should hash this list.
*
*/
-int ocfs_verify_update_oin (ocfs_super * osb, ocfs_inode * oin)
+int ocfs_verify_update_oin (ocfs_super * osb, ocfs_inode * oin, int *needs_trunc)
{
int status = 0;
struct buffer_head *fe_bh = NULL;
@@ -27,6 +27,8 @@
OCFS_ASSERT (oin);
+ *needs_trunc = 0;
+
status = ocfs_read_bh(osb, oin->file_disk_off, &fe_bh, OCFS_BH_COND_CACHED, oin->inode);
if (status < 0) {
LOG_ERROR_STATUS (status);
@@ -102,8 +104,11 @@
OCFS_SET_INODE_TIME(inode, i_ctime, fe->create_time);
OCFS_SET_INODE_TIME(inode, i_atime, fe->modify_time);
OCFS_SET_INODE_TIME(inode, i_mtime, fe->modify_time);
- if (!S_ISDIR (inode->i_mode)) {
- ocfs_truncate_inode_pages(inode, 0);
+ if (!S_ISDIR (inode->i_mode) &&
+ (oin->alloc_size != (__s64) fe->alloc_size ||
+ inode->i_size != (__s64) fe->file_size ||
+ oin->chng_seq_num != DISK_LOCK_SEQNUM (fe))) {
+ *needs_trunc = 1;
}
switch (fe->attribs) {
More information about the Ocfs2-commits
mailing list