[Ocfs2-commits] khackel commits r938 - branches/new-dir-format/src

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Tue May 25 14:54:00 CDT 2004


Author: khackel
Date: 2004-05-25 13:53:58 -0500 (Tue, 25 May 2004)
New Revision: 938

Modified:
   branches/new-dir-format/src/namei.c
Log:
fixed a bug where dir->i_size would change when a directory needed to grow
(and alloc_size was already big enough) but the fe->file_size wasn't changed
for the dir, so it would reload the inode later with a bad i_size



Modified: branches/new-dir-format/src/namei.c
===================================================================
--- branches/new-dir-format/src/namei.c	2004-05-25 02:31:06 UTC (rev 937)
+++ branches/new-dir-format/src/namei.c	2004-05-25 18:53:58 UTC (rev 938)
@@ -32,18 +32,13 @@
 
 static int inline search_dirblock(struct buffer_head * bh, struct inode *dir, struct dentry *dentry, unsigned long offset, struct ocfs2_dir_entry ** res_dir);
 static int ocfs_delete_entry (ocfs_journal_handle *handle, struct inode * dir, struct ocfs2_dir_entry * de_del, struct buffer_head * bh);
-static int ocfs_add_entry (ocfs_journal_handle *handle, struct dentry *dentry, struct inode *inode, __u64 inode_off);
+static int ocfs_add_entry (ocfs_journal_handle *handle, struct dentry *dentry, struct inode *inode, __u64 inode_off, struct buffer_head *parent_fe_bh);
 static inline int ocfs_match (int len, const char * const name, struct ocfs2_dir_entry * de);
 
-
-
-
-static int ocfs_mknod_locked(ocfs_super *osb, struct inode *dir, struct dentry *dentry, int mode, ocfs_dev dev, struct buffer_head **new_fe_bh, ocfs_journal_handle *handle, struct inode *inode);
-
 static int ocfs_mknod_locked(ocfs_super *osb, struct inode *dir, 
 			     struct dentry *dentry, int mode, 
-			     ocfs_dev dev,
-			     struct buffer_head **new_fe_bh, 
+			     ocfs_dev dev, struct buffer_head **new_fe_bh, 
+			     struct buffer_head *parent_fe_bh,
 			     ocfs_journal_handle *handle,
 			     struct inode *inode);
 static int ocfs_double_lock(ocfs_super *osb, ocfs_journal_handle *handle,
@@ -190,7 +185,7 @@
 
 	/* do the real work now. */
 	status = ocfs_mknod_locked(osb, dir, dentry, mode, dev,
-				   &new_fe_bh, handle, inode);
+				   &new_fe_bh, parent_fe_bh, handle, inode);
 	if (status < 0) {
 		if (status != -EINTR)
 			LOG_ERROR_STATUS(status);
@@ -308,6 +303,7 @@
 static int ocfs_mknod_locked(ocfs_super *osb, struct inode *dir, 
 			     struct dentry *dentry, int mode, 
 			     ocfs_dev dev, struct buffer_head **new_fe_bh, 
+			     struct buffer_head *parent_fe_bh,
 			     ocfs_journal_handle *handle,
 			     struct inode *inode)
 {
@@ -405,7 +401,7 @@
 		goto leave;
 	}
 
-	status = ocfs_add_entry (handle, dentry, inode, bitmapOffset);
+	status = ocfs_add_entry (handle, dentry, inode, bitmapOffset, parent_fe_bh);
 	if (status < 0) {
 		LOG_ERROR_STATUS (status);
 		goto leave;
@@ -495,7 +491,6 @@
 	struct buffer_head *parent_node_bh = NULL; /* parent locknode */
 	ocfs_journal_handle *handle = NULL;
 	__u64 parent_off = GET_INODE_FEOFF(parentInode);
-	__u64 parent_dirnode_off = OCFS_I(parentInode)->u.child_dirnode;
 	struct ocfs2_dir_entry *dirent = NULL;
 	struct buffer_head *dirent_bh = NULL;
 	int drop_inode = 0, dec_parent = 0;
@@ -589,7 +584,7 @@
 	 * the dirnode sector first. it won't get passed to
 	 * journal_dirty until ocfs_remove_file so clean up the write
 	 * lock on errors before that */
-	status = ocfs_read_bh(osb, parent_dirnode_off, &parent_node_bh, 
+	status = ocfs_read_bh(osb, parent_off, &parent_node_bh, 
 			      OCFS_BH_CACHED, parentInode);
 	if (status < 0) {
 		LOG_ERROR_STATUS (status);
@@ -1107,7 +1102,7 @@
 
 	} else {
 		/* if the name was not found in new_dir, add it now */
-		status = ocfs_add_entry (handle, new_dentry, old_inode, oldOffset);
+		status = ocfs_add_entry (handle, new_dentry, old_inode, oldOffset, new_dir_bh);
 	} 
 	
 
@@ -1242,6 +1237,7 @@
 	struct super_block *sb;
 	int l;
 	struct buffer_head *new_fe_bh = NULL;
+	struct buffer_head *parent_fe_bh = NULL;
 	ocfs_file_entry *fe = NULL;
 	ocfs_journal_handle *handle = NULL;
 	int got_lock = 0;
@@ -1280,7 +1276,7 @@
 	status = ocfs_acquire_lock (osb, parent_off, 
 				    OCFS_DLM_ENABLE_CACHE_LOCK,
 				    FLAG_FILE_CREATE | FLAG_DIR, 
-				    NULL, dir);
+				    &parent_fe_bh, dir);
 	if (status < 0) {
 		if (status != -EINTR)
 			LOG_ERROR_STATUS (status);
@@ -1290,7 +1286,7 @@
 
 	status = ocfs_mknod_locked(osb, dir, dentry, 
 				  S_IFLNK | S_IRWXUGO, OCFS_NODEV,
-				  &new_fe_bh, handle, inode);
+				  &new_fe_bh, parent_fe_bh, handle, inode);
 	if (status < 0) {
 		LOG_ERROR_STATUS(status);
 		goto abort_trans;
@@ -1351,7 +1347,7 @@
 		tmpstat = ocfs_release_lock (osb, parent_off, 
 					     OCFS_DLM_ENABLE_CACHE_LOCK,
 					     FLAG_FILE_CREATE | FLAG_DIR, 
-					     NULL, dir);
+					     parent_fe_bh, dir);
 		if (tmpstat < 0)
 			LOG_ERROR_STATUS (tmpstat);
 	}
@@ -1362,6 +1358,8 @@
 			OCFS_BH_PUT_DATA(new_fe_bh);
 		brelse(new_fe_bh);
 	}
+	if (parent_fe_bh)
+		brelse(parent_fe_bh);
 
 #ifndef BH_SEM_LEAK_CHECKING
 	if (status < 0)
@@ -1407,7 +1405,7 @@
 }
 
 
-static int ocfs_add_entry (ocfs_journal_handle *handle, struct dentry *dentry, struct inode *inode, __u64 inode_off)
+static int ocfs_add_entry (ocfs_journal_handle *handle, struct dentry *dentry, struct inode *inode, __u64 inode_off, struct buffer_head *parent_fe_bh)
 {
 	struct inode *dir = dentry->d_parent->d_inode;
 	const char *name = dentry->d_name.name;
@@ -1419,6 +1417,7 @@
 	struct super_block * sb;
 	int retval, status;
 	char *buf = NULL;
+	ocfs_file_entry *fe = NULL;
 
 	sb = dir->i_sb;
 
@@ -1436,20 +1435,15 @@
 			bh = NULL;
 			bh = ocfs_bread (handle, dir, offset >> sb->s_blocksize_bits, 1, &retval, 0);
 			if (!bh)
-				return retval;
+				goto bail;
 			if (dir->i_size <= offset) {
 				if (dir->i_size == 0) {
-					brelse(bh);
-					return -ENOENT;
+					retval = -ENOENT;
+					goto bail;
 				}
 
 				/* create next block */
 				status = ocfs_journal_access(handle, bh, OCFS_JOURNAL_ACCESS_WRITE);
-				if (buf) {
-#warning removemelater
-					LOG_ERROR_ARGS("oops.  block=%lu\n", bh->b_blocknr);
-					BUG();
-				}
 				buf = OCFS_BH_GET_DATA_WRITE(bh); /* write */
 				de = (struct ocfs2_dir_entry *) bh->b_data;
 				de->inode = 0;
@@ -1457,6 +1451,15 @@
 				dir->i_size = offset + sb->s_blocksize;
 				OCFS_BH_PUT_DATA(bh);
 				buf = NULL;
+
+				/* update the parent file entry file size */
+				status = ocfs_journal_access(handle, parent_fe_bh, OCFS_JOURNAL_ACCESS_WRITE);
+				buf = OCFS_BH_GET_DATA_WRITE(parent_fe_bh); /* write */
+				fe = (ocfs_file_entry *)buf;
+				fe->file_size = dir->i_size;
+				OCFS_BH_PUT_DATA(parent_fe_bh);
+				buf = NULL;
+				status = ocfs_journal_dirty(handle, parent_fe_bh);
 			} else {
 				/* move to next block */
 				buf = OCFS_BH_GET_DATA_READ(bh); /* read */
@@ -1466,23 +1469,14 @@
 			}
 			
 		}
-		if (buf) {
-#warning removemelater
-			LOG_ERROR_ARGS("oops.  block=%lu\n", bh->b_blocknr);
-			BUG();
-		}
 		buf = OCFS_BH_GET_DATA_READ(bh); /* read */
 		if (!ocfs_check_dir_entry (dir, de, bh, offset)) {
-			OCFS_BH_PUT_DATA(bh);
-			buf = NULL;
-			brelse (bh);
-			return -ENOENT;
+			retval = -ENOENT;
+			goto bail;
 		}
 		if (ocfs_match (namelen, name, de)) {
-			OCFS_BH_PUT_DATA(bh);
-			buf = NULL;
-			brelse (bh);
-			return -EEXIST;
+			retval = -EEXIST;
+			goto bail;
 		}
 		if ((le64_to_cpu(de->inode) == 0 && le16_to_cpu(de->rec_len) >= rec_len) ||
 		    (le16_to_cpu(de->rec_len) >= OCFS_DIR_REC_LEN(de->name_len) + rec_len)) {
@@ -1515,19 +1509,22 @@
 			dir->i_mtime = dir->i_ctime = CURRENT_TIME;
 			dir->i_version = ++event;
 			status = ocfs_journal_dirty(handle, bh);
-			brelse(bh);
-			return 0;
+			retval = 0;
+			goto bail;
 		}
 		offset += le16_to_cpu(de->rec_len);
 		de = (struct ocfs2_dir_entry *) ((char *) de + le16_to_cpu(de->rec_len));
 		OCFS_BH_PUT_DATA(bh);
 		buf = NULL;
 	}
+
+	retval = -ENOSPC;
+bail:
 	if (buf)
 		OCFS_BH_PUT_DATA(bh);
 	buf = NULL;
 	brelse (bh);
-	return -ENOSPC;
+	return retval;
 }
 
 
@@ -1744,6 +1741,7 @@
 	__u64 parent_off=0ULL, fe_off=0ULL;
 	int tmpstat;
 	struct buffer_head *bh = NULL;
+	struct buffer_head *parent_fe_bh = NULL;
 	ocfs_file_entry *fe = NULL;
 
 	if (S_ISDIR(inode->i_mode))
@@ -1763,7 +1761,7 @@
 	err = ocfs_acquire_lock (osb, parent_off, 
 				    OCFS_DLM_ENABLE_CACHE_LOCK,
 				    FLAG_FILE_CREATE | FLAG_DIR, 
-				    NULL, dir);
+				    &parent_fe_bh, dir);
 	if (err < 0) {
 		parent_off = 0ULL;
 		if (err != -EINTR)
@@ -1801,7 +1799,7 @@
 		goto bail;
 	}
 
-	err = ocfs_add_entry(handle, dentry, inode);
+	err = ocfs_add_entry(handle, dentry, inode, parent_fe_bh);
 	if (err)
 		inode->i_nlink--;
 	else 	
@@ -1816,7 +1814,7 @@
 		tmpstat = ocfs_release_lock (osb, parent_off, 
 					     OCFS_DLM_ENABLE_CACHE_LOCK,
 					     FLAG_FILE_CREATE | FLAG_DIR, 
-					     NULL, dir);
+					     parent_fe_bh, dir);
 		if (tmpstat < 0)
 			LOG_ERROR_STATUS (tmpstat);
 	}
@@ -1831,6 +1829,8 @@
 
 	if (bh)
 		brelse(bh);
+	if (parent_fe_bh)
+		brelse(parent_fe_bh);
 
 	// is this right?!
 	if (err)



More information about the Ocfs2-commits mailing list