[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