* [Ocfs2-devel] [PATCH] ocfs2: alloc orphaned inode in ocfs2_symlink
@ 2010-04-08 1:13 Li Dongyang
2010-04-08 21:12 ` Joel Becker
2010-04-08 23:10 ` Mark Fasheh
0 siblings, 2 replies; 5+ messages in thread
From: Li Dongyang @ 2010-04-08 1:13 UTC (permalink / raw)
To: ocfs2-devel
alloc the inode orphaned in ocfs2_symlink so we can delete the inode
in the iput if we meet errors with the inode, e.g. ocfs2_add_inode_data.
or ocfs2_query_inode_wipe will complain the inode is not orphaned on disk.
Signed-off-by: Li Dongyang <lidongyang@novell.com>
---
fs/ocfs2/namei.c | 60 +++++++++++++++++++++++++++++------------------------
1 files changed, 33 insertions(+), 27 deletions(-)
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index f010b22..daf1fdf 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -94,6 +94,8 @@ static int ocfs2_create_symlink_data(struct ocfs2_super
*osb,
struct inode *inode,
const char *symname);
+static int ocfs2_blkno_stringify(u64 blkno, char *name);
+
/* An orphan dir name is an 8 byte value, printed as a hex string */
#define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64)))
@@ -1579,6 +1581,7 @@ static int ocfs2_symlink(struct inode *dir,
u64 newsize;
struct ocfs2_super *osb = NULL;
struct inode *inode = NULL;
+ struct inode *orphan_dir = NULL;
struct super_block *sb;
struct buffer_head *new_fe_bh = NULL;
struct buffer_head *parent_fe_bh = NULL;
@@ -1594,7 +1597,9 @@ static int ocfs2_symlink(struct inode *dir,
.enable = 1,
};
int did_quota = 0, did_quota_inode = 0;
+ char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
struct ocfs2_dir_lookup_result lookup = { NULL, };
+ struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir,
dentry, symname, dentry->d_name.len, dentry->d_name.name);
@@ -1621,14 +1626,9 @@ static int ocfs2_symlink(struct inode *dir,
goto bail;
}
- status = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
- dentry->d_name.len);
- if (status)
- goto bail;
-
- status = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
- dentry->d_name.name,
- dentry->d_name.len, &lookup);
+ status = ocfs2_prepare_orphan_dir(osb, &orphan_dir,
+ osb->root_blkno,
+ orphan_name, &orphan_insert);
if (status < 0) {
mlog_errno(status);
goto bail;
@@ -1709,7 +1709,20 @@ static int ocfs2_symlink(struct inode *dir,
goto bail;
}
+ status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, orphan_name);
+ if (status < 0) {
+ mlog_errno(status);
+ goto bail;
+ }
+
fe = (struct ocfs2_dinode *) new_fe_bh->b_data;
+ status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name,
+ &orphan_insert, orphan_dir);
+ if (status < 0) {
+ mlog_errno(status);
+ goto bail;
+ }
+
inode->i_rdev = 0;
newsize = l - 1;
if (l > ocfs2_fast_symlink_chars(sb)) {
@@ -1768,24 +1781,6 @@ static int ocfs2_symlink(struct inode *dir,
goto bail;
}
}
-
- status = ocfs2_add_entry(handle, dentry, inode,
- le64_to_cpu(fe->i_blkno), parent_fe_bh,
- &lookup);
- if (status < 0) {
- mlog_errno(status);
- goto bail;
- }
-
- status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
- if (status) {
- mlog_errno(status);
- goto bail;
- }
-
- insert_inode_hash(inode);
- dentry->d_op = &ocfs2_dentry_ops;
- d_instantiate(dentry, inode);
bail:
if (status < 0 && did_quota)
vfs_dq_free_space_nodirty(inode,
@@ -1802,13 +1797,24 @@ bail:
kfree(si.name);
kfree(si.value);
ocfs2_free_dir_lookup_result(&lookup);
+ ocfs2_free_dir_lookup_result(&orphan_insert);
if (inode_ac)
ocfs2_free_alloc_context(inode_ac);
if (data_ac)
ocfs2_free_alloc_context(data_ac);
if (xattr_ac)
ocfs2_free_alloc_context(xattr_ac);
- if ((status < 0) && inode) {
+ if (orphan_dir) {
+ ocfs2_inode_unlock(orphan_dir, 1);
+ mutex_unlock(&orphan_dir->i_mutex);
+ iput(orphan_dir);
+ }
+ if (inode && !status) {
+ status = ocfs2_mv_orphaned_inode_to_new(dir, inode, dentry);
+ if (status)
+ mlog_errno(status);
+ }
+ if (inode && status < 0) {
clear_nlink(inode);
iput(inode);
}
--
1.7.0.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Ocfs2-devel] [PATCH] ocfs2: alloc orphaned inode in ocfs2_symlink
2010-04-08 1:13 [Ocfs2-devel] [PATCH] ocfs2: alloc orphaned inode in ocfs2_symlink Li Dongyang
@ 2010-04-08 21:12 ` Joel Becker
2010-04-09 2:32 ` Li Dongyang
2010-04-08 23:10 ` Mark Fasheh
1 sibling, 1 reply; 5+ messages in thread
From: Joel Becker @ 2010-04-08 21:12 UTC (permalink / raw)
To: ocfs2-devel
On Thu, Apr 08, 2010 at 09:13:08AM +0800, Li Dongyang wrote:
> alloc the inode orphaned in ocfs2_symlink so we can delete the inode
> in the iput if we meet errors with the inode, e.g. ocfs2_add_inode_data.
> or ocfs2_query_inode_wipe will complain the inode is not orphaned on disk.
Huh. At first I was sure this was ok, as the iput is sanely
killing the inode. But you're right, the wipe code expects it to be
orphaned.
Do you have a testcase for this?
Joel
--
Life's Little Instruction Book #497
"Go down swinging."
Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Ocfs2-devel] [PATCH] ocfs2: alloc orphaned inode in ocfs2_symlink
2010-04-08 1:13 [Ocfs2-devel] [PATCH] ocfs2: alloc orphaned inode in ocfs2_symlink Li Dongyang
2010-04-08 21:12 ` Joel Becker
@ 2010-04-08 23:10 ` Mark Fasheh
2010-04-09 2:37 ` Li Dongyang
1 sibling, 1 reply; 5+ messages in thread
From: Mark Fasheh @ 2010-04-08 23:10 UTC (permalink / raw)
To: ocfs2-devel
Hi Li,
On Thu, Apr 08, 2010 at 09:13:08AM +0800, Li Dongyang wrote:
> alloc the inode orphaned in ocfs2_symlink so we can delete the inode
> in the iput if we meet errors with the inode, e.g. ocfs2_add_inode_data.
> or ocfs2_query_inode_wipe will complain the inode is not orphaned on disk.
Thanks for the patch. Your solution is too heavy for such a special case -
we can't lock the orphan dir and orphan / de-orphan an inode every time a
symlink is made.
The good news is that I believe there's an easier way to handle this. You
can add a flag to ocfs2_inode_info->ip_flags (see fs/ocfs2/inode.h). I would
call this flag something like OCFS2_INODE_SKIP_ORPHAN_DIR. If the allocation
fails, we could mark the inode with that flag. From a quick look at the
code, the only places that need additional checking for the flag would be:
ocfs2_query_inode_wipe() and ocfs2_wipe_inode().
Ultimately, I think the best solution is for us to delete the inode
"in-place". We actually already have all the locks and journal credits we
need at that point. It's a bit tricky though because we have to be careful
what state the inode gets set in, which is why for a short-term fix, the
above solution is ok.
--Mark
--
Mark Fasheh
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Ocfs2-devel] [PATCH] ocfs2: alloc orphaned inode in ocfs2_symlink
2010-04-08 21:12 ` Joel Becker
@ 2010-04-09 2:32 ` Li Dongyang
0 siblings, 0 replies; 5+ messages in thread
From: Li Dongyang @ 2010-04-09 2:32 UTC (permalink / raw)
To: ocfs2-devel
On Friday 09 April 2010 05:12:22 Joel Becker wrote:
> On Thu, Apr 08, 2010 at 09:13:08AM +0800, Li Dongyang wrote:
> > alloc the inode orphaned in ocfs2_symlink so we can delete the inode
> > in the iput if we meet errors with the inode, e.g. ocfs2_add_inode_data.
> > or ocfs2_query_inode_wipe will complain the inode is not orphaned on
> > disk.
>
> Huh. At first I was sure this was ok, as the iput is sanely
> killing the inode. But you're right, the wipe code expects it to be
> orphaned.
> Do you have a testcase for this?
>
> Joel
>
I found it while trying to reproduce the bug fixed by the patch ocfs2: avoid
direct write if we fall back to buffered.
In my case, just run fsstress on a single node, and when the ocfs2 partition
is out of space, ocfs2_add_inode_data will return -ENOSPC and then will
trigger the error in ocfs2_query_inode_wipe
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Ocfs2-devel] [PATCH] ocfs2: alloc orphaned inode in ocfs2_symlink
2010-04-08 23:10 ` Mark Fasheh
@ 2010-04-09 2:37 ` Li Dongyang
0 siblings, 0 replies; 5+ messages in thread
From: Li Dongyang @ 2010-04-09 2:37 UTC (permalink / raw)
To: ocfs2-devel
On Friday 09 April 2010 07:10:22 Mark Fasheh wrote:
> Hi Li,
>
> On Thu, Apr 08, 2010 at 09:13:08AM +0800, Li Dongyang wrote:
> > alloc the inode orphaned in ocfs2_symlink so we can delete the inode
> > in the iput if we meet errors with the inode, e.g. ocfs2_add_inode_data.
> > or ocfs2_query_inode_wipe will complain the inode is not orphaned on
> > disk.
>
> Thanks for the patch. Your solution is too heavy for such a special case -
> we can't lock the orphan dir and orphan / de-orphan an inode every time a
> symlink is made.
>
Hi, Mark,
Thanks for reviewing, Jan Kara and I also think this is expensive.
> The good news is that I believe there's an easier way to handle this. You
> can add a flag to ocfs2_inode_info->ip_flags (see fs/ocfs2/inode.h). I
> would call this flag something like OCFS2_INODE_SKIP_ORPHAN_DIR. If the
> allocation fails, we could mark the inode with that flag. From a quick
> look at the code, the only places that need additional checking for the
> flag would be: ocfs2_query_inode_wipe() and ocfs2_wipe_inode().
>
Looking into that.
>
> Ultimately, I think the best solution is for us to delete the inode
> "in-place". We actually already have all the locks and journal credits we
> need at that point. It's a bit tricky though because we have to be careful
> what state the inode gets set in, which is why for a short-term fix, the
> above solution is ok.
Glad to know this way, maybe I'll post an updated patch.
> --Mark
>
> --
> Mark Fasheh
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-04-09 2:37 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-08 1:13 [Ocfs2-devel] [PATCH] ocfs2: alloc orphaned inode in ocfs2_symlink Li Dongyang
2010-04-08 21:12 ` Joel Becker
2010-04-09 2:32 ` Li Dongyang
2010-04-08 23:10 ` Mark Fasheh
2010-04-09 2:37 ` Li Dongyang
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.