+++ /dev/null
-From: Tiger Yang <tiger.yang@oracle.com>
-Date: Fri, 14 Nov 2008 11:15:44 +0800
-Subject: ocfs2: move new inode allocation out of the transaction
-Patch-mainline: 2.6.29
-
-Move out inode allocation from ocfs2_mknod_locked() because
-vfs_dq_init() must be called outside of a transaction.
-
-Signed-off-by: Jan Kara <jack@suse.cz>
-Signed-off-by: Tiger Yang <tiger.yang@oracle.com>
-Signed-off-by: Mark Fasheh <mfasheh@suse.com>
----
- fs/ocfs2/namei.c | 108 ++++++++++++++++++++++++++++++++----------------------
- 1 files changed, 64 insertions(+), 44 deletions(-)
-
-diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
-index 2545e74..e8ff0ba 100644
---- a/fs/ocfs2/namei.c
-+++ b/fs/ocfs2/namei.c
-@@ -66,12 +66,12 @@
-
- static int ocfs2_mknod_locked(struct ocfs2_super *osb,
- struct inode *dir,
-- struct dentry *dentry, int mode,
-+ struct inode *inode,
-+ struct dentry *dentry,
- dev_t dev,
- struct buffer_head **new_fe_bh,
- struct buffer_head *parent_fe_bh,
- handle_t *handle,
-- struct inode **ret_inode,
- struct ocfs2_alloc_context *inode_ac);
-
- static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
-@@ -186,6 +186,34 @@ bail:
- return ret;
- }
-
-+static struct inode *ocfs2_get_init_inode(struct inode *dir, int mode)
-+{
-+ struct inode *inode;
-+
-+ inode = new_inode(dir->i_sb);
-+ if (!inode) {
-+ mlog(ML_ERROR, "new_inode failed!\n");
-+ return NULL;
-+ }
-+
-+ /* populate as many fields early on as possible - many of
-+ * these are used by the support functions here and in
-+ * callers. */
-+ if (S_ISDIR(mode))
-+ inode->i_nlink = 2;
-+ else
-+ inode->i_nlink = 1;
-+ inode->i_uid = current->fsuid;
-+ if (dir->i_mode & S_ISGID) {
-+ inode->i_gid = dir->i_gid;
-+ if (S_ISDIR(mode))
-+ mode |= S_ISGID;
-+ } else
-+ inode->i_gid = current->fsgid;
-+ inode->i_mode = mode;
-+ return inode;
-+}
-+
- static int ocfs2_mknod(struct inode *dir,
- struct dentry *dentry,
- int mode,
-@@ -250,6 +278,13 @@ static int ocfs2_mknod(struct inode *dir,
- goto leave;
- }
-
-+ inode = ocfs2_get_init_inode(dir, mode);
-+ if (!inode) {
-+ status = -ENOMEM;
-+ mlog_errno(status);
-+ goto leave;
-+ }
-+
- /* Reserve a cluster if creating an extent based directory. */
- if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) {
- status = ocfs2_reserve_clusters(osb, 1, &data_ac);
-@@ -269,9 +304,9 @@ static int ocfs2_mknod(struct inode *dir,
- }
-
- /* do the real work now. */
-- status = ocfs2_mknod_locked(osb, dir, dentry, mode, dev,
-+ status = ocfs2_mknod_locked(osb, dir, inode, dentry, dev,
- &new_fe_bh, parent_fe_bh, handle,
-- &inode, inode_ac);
-+ inode_ac);
- if (status < 0) {
- mlog_errno(status);
- goto leave;
-@@ -332,8 +367,10 @@ leave:
- brelse(de_bh);
- brelse(parent_fe_bh);
-
-- if ((status < 0) && inode)
-+ if ((status < 0) && inode) {
-+ clear_nlink(inode);
- iput(inode);
-+ }
-
- if (inode_ac)
- ocfs2_free_alloc_context(inode_ac);
-@@ -348,12 +385,12 @@ leave:
-
- static int ocfs2_mknod_locked(struct ocfs2_super *osb,
- struct inode *dir,
-- struct dentry *dentry, int mode,
-+ struct inode *inode,
-+ struct dentry *dentry,
- dev_t dev,
- struct buffer_head **new_fe_bh,
- struct buffer_head *parent_fe_bh,
- handle_t *handle,
-- struct inode **ret_inode,
- struct ocfs2_alloc_context *inode_ac)
- {
- int status = 0;
-@@ -361,14 +398,12 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
- struct ocfs2_extent_list *fel;
- u64 fe_blkno = 0;
- u16 suballoc_bit;
-- struct inode *inode = NULL;
-
-- mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode,
-- (unsigned long)dev, dentry->d_name.len,
-+ mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry,
-+ inode->i_mode, (unsigned long)dev, dentry->d_name.len,
- dentry->d_name.name);
-
- *new_fe_bh = NULL;
-- *ret_inode = NULL;
-
- status = ocfs2_claim_new_inode(osb, handle, inode_ac, &suballoc_bit,
- &fe_blkno);
-@@ -377,23 +412,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
- goto leave;
- }
-
-- inode = new_inode(dir->i_sb);
-- if (!inode) {
-- status = -ENOMEM;
-- mlog(ML_ERROR, "new_inode failed!\n");
-- goto leave;
-- }
--
- /* populate as many fields early on as possible - many of
- * these are used by the support functions here and in
- * callers. */
- inode->i_ino = ino_from_blkno(osb->sb, fe_blkno);
- OCFS2_I(inode)->ip_blkno = fe_blkno;
-- if (S_ISDIR(mode))
-- inode->i_nlink = 2;
-- else
-- inode->i_nlink = 1;
-- inode->i_mode = mode;
- spin_lock(&osb->osb_lock);
- inode->i_generation = osb->s_next_generation++;
- spin_unlock(&osb->osb_lock);
-@@ -421,17 +444,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
- fe->i_blkno = cpu_to_le64(fe_blkno);
- fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
- fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
-- fe->i_uid = cpu_to_le32(current->fsuid);
-- if (dir->i_mode & S_ISGID) {
-- fe->i_gid = cpu_to_le32(dir->i_gid);
-- if (S_ISDIR(mode))
-- mode |= S_ISGID;
-- } else
-- fe->i_gid = cpu_to_le32(current->fsgid);
-- fe->i_mode = cpu_to_le16(mode);
-- if (S_ISCHR(mode) || S_ISBLK(mode))
-+ fe->i_uid = cpu_to_le32(inode->i_uid);
-+ fe->i_gid = cpu_to_le32(inode->i_gid);
-+ fe->i_mode = cpu_to_le16(inode->i_mode);
-+ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
- fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
--
- fe->i_links_count = cpu_to_le16(inode->i_nlink);
-
- fe->i_last_eb_blk = 0;
-@@ -446,7 +463,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
- /*
- * If supported, directories start with inline data.
- */
-- if (S_ISDIR(mode) && ocfs2_supports_inline_data(osb)) {
-+ if (S_ISDIR(inode->i_mode) && ocfs2_supports_inline_data(osb)) {
- u16 feat = le16_to_cpu(fe->i_dyn_features);
-
- fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL);
-@@ -484,17 +501,12 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
- status = 0; /* error in ocfs2_create_new_inode_locks is not
- * critical */
-
-- *ret_inode = inode;
- leave:
- if (status < 0) {
- if (*new_fe_bh) {
- brelse(*new_fe_bh);
- *new_fe_bh = NULL;
- }
-- if (inode) {
-- clear_nlink(inode);
-- iput(inode);
-- }
- }
-
- mlog_exit(status);
-@@ -1542,6 +1554,13 @@ static int ocfs2_symlink(struct inode *dir,
- goto bail;
- }
-
-+ inode = ocfs2_get_init_inode(dir, S_IFLNK | S_IRWXUGO);
-+ if (!inode) {
-+ status = -ENOMEM;
-+ mlog_errno(status);
-+ goto bail;
-+ }
-+
- /* don't reserve bitmap space for fast symlinks. */
- if (l > ocfs2_fast_symlink_chars(sb)) {
- status = ocfs2_reserve_clusters(osb, 1, &data_ac);
-@@ -1560,10 +1579,9 @@ static int ocfs2_symlink(struct inode *dir,
- goto bail;
- }
-
-- status = ocfs2_mknod_locked(osb, dir, dentry,
-- S_IFLNK | S_IRWXUGO, 0,
-- &new_fe_bh, parent_fe_bh, handle,
-- &inode, inode_ac);
-+ status = ocfs2_mknod_locked(osb, dir, inode, dentry,
-+ 0, &new_fe_bh, parent_fe_bh, handle,
-+ inode_ac);
- if (status < 0) {
- mlog_errno(status);
- goto bail;
-@@ -1644,8 +1662,10 @@ bail:
- ocfs2_free_alloc_context(inode_ac);
- if (data_ac)
- ocfs2_free_alloc_context(data_ac);
-- if ((status < 0) && inode)
-+ if ((status < 0) && inode) {
-+ clear_nlink(inode);
- iput(inode);
-+ }
-
- mlog_exit(status);
-
---
-1.5.6
-