Skip to contentSkip to conversation

libxfs: adding attribute fork frees xfs_inode ptr

RFC In review Mark Tinguely 3 participants 6 messages Apr 23, 2014 – Apr 25, 2014 1 message not in the archive

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

RFC 1/1 libxfs: adding attribute fork frees xfs_inode ptr

User space does not currently perform any attribute adding/deleting, but if we do want to fix attributes or use them for parent inode pointers, user space should support attributes.

The adding an attribute fork is done in an embedded transaction inside xfs_attr_set_int(). The xfs_trans_commit in xfs_bmap_add_attrfork() will free the xfs_inode pointer causing xfs_attr_calc_size() in xfs_attr_set_int() to fail.

I don't see that we have any hold counts on the xfs_inode, so this is a dirty FYI/RFC of a work around for this problem by calling xfs_iget() to read back in the just freed inode.

---
 libxfs/xfs_attr.c |    4 ++++
 1 file changed, 4 insertions(+)
libxfs/xfs_attr.c +4 -0
Index: b/libxfs/xfs_attr.c
===================================================================
@@ -223,11 +223,15 @@ xfs_attr_set_int(
 	 * (inode must not be locked when we call this routine)
 	 */
 	if (XFS_IFORK_Q(dp) == 0) {
+		xfs_ino_t	ino = dp->i_ino;
 		int sf_size = sizeof(xfs_attr_sf_hdr_t) +
 			      XFS_ATTR_SF_ENTSIZE_BYNAME(name->len, valuelen);
 
 		if ((error = xfs_bmap_add_attrfork(dp, sf_size, rsvd)))
 			return(error);
+		error = libxfs_iget(mp, NULL, ino, 0, &dp, 0);
+		if (error)
+			return(error);
 	}
 
 	/*

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

#2 lore raw
Quoted 8 lines · Mark Tinguely

User space does not currently perform any attribute adding/deleting, but if we do want to fix attributes or use them for parent inode pointers, user space should support attributes.

The adding an attribute fork is done in an embedded transaction inside xfs_attr_set_int(). The xfs_trans_commit in xfs_bmap_add_attrfork() will free the xfs_inode pointer causing xfs_attr_calc_size() in xfs_attr_set_int() to fail.

It shouldn't. xfs_bmap_add_attrfork() does:

	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);

which in the kernel code sets:

	iip->ili_lock_flags = lock_flags;

The libxfs code doesn't do that, so when xfs_trans_commit() gets to inode_item_unlock():

        if (!iip->ili_lock_flags)
                libxfs_iput(ip, 0);
        else
                iip->ili_lock_flags = 0;

It frees the inode rather than just returning it with the lock flags cleared.

Note that libxfs still has libxfs_trans_ijoin_ref() which sets the lock flags, but this has been removed from the kernel code. IOWs, this is a libxfs/trans.c::xfs_trans_ijoin() bug, not something that needs fixing in the shared kernel/user libxfs code.

Cheers,

Dave.

Signature · 7 lines
Dave Chinner
[email protected]

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
#3 lore raw
Quoted 31 lines · Dave Chinner
Quoted 8 lines · Mark Tinguely

User space does not currently perform any attribute adding/deleting, but if we do want to fix attributes or use them for parent inode pointers, user space should support attributes.

The adding an attribute fork is done in an embedded transaction inside xfs_attr_set_int(). The xfs_trans_commit in xfs_bmap_add_attrfork() will free the xfs_inode pointer causing xfs_attr_calc_size() in xfs_attr_set_int() to fail.

It shouldn't. xfs_bmap_add_attrfork() does:

	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);

which in the kernel code sets:

	iip->ili_lock_flags = lock_flags;

The libxfs code doesn't do that, so when xfs_trans_commit() gets to inode_item_unlock():

         if (!iip->ili_lock_flags)
                 libxfs_iput(ip, 0);
         else
                 iip->ili_lock_flags = 0;

It frees the inode rather than just returning it with the lock flags cleared.

Quoted 8 lines

Note that libxfs still has libxfs_trans_ijoin_ref() which sets the lock flags, but this has been removed from the kernel code. IOWs, this is a libxfs/trans.c::xfs_trans_ijoin() bug, not something that needs fixing in the shared kernel/user libxfs code.

Cheers,

Dave.

nod. That is the correct thing to do.

Since the shared user/kernel code will no longer do a xfs_trans_ihold(), the libxfs_iput() should be factored out out of inode_item_unlock() and have the creator release the inode pointer when it is appropriate.

No one besides me is using this so it can go into the next release of xfs_progs.

--Mark.

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

#4 lore raw
Quoted 2 lines · Mark Tinguely
Quoted 1 line · Dave Chinner

On Wed, Apr 23, 2014 at 04:04:35PM -0500, Mark Tinguely wrote:

...

Note that libxfs still has libxfs_trans_ijoin_ref() which sets the

Quoted 10 lines
Quoted 7 lines

lock flags, but this has been removed from the kernel code. IOWs, this is a libxfs/trans.c::xfs_trans_ijoin() bug, not something that needs fixing in the shared kernel/user libxfs code.

Cheers,

Dave.

nod. That is the correct thing to do.

Quoted 8 lines

Since the shared user/kernel code will no longer do a xfs_trans_ihold(), the libxfs_iput() should be factored out out of inode_item_unlock() and have the creator release the inode pointer when it is appropriate.

No one besides me is using this so it can go into the next release of xfs_progs.

--Mark.

PS. I may not have been very clear, the libxfs_trans_roll() and
inode_item_done() also cause a premature libxfs_iput(). Let me do more testing making any changes and target this for xfsprogs-3.2.1.

--Mark.

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

#5 lore raw
Quoted 4 lines · Mark Tinguely

PS. I may not have been very clear, the libxfs_trans_roll() and
inode_item_done() also cause a premature libxfs_iput(). Let me do more testing making any changes and target this for xfsprogs-3.2.1.

You mean you've fixed the way we handle the attachement of inodes to transaction in userspace to mirror what we do in kernelspace? I'd love to review this if you have patches as it's a somewhat of a pain point to have these work so different in kernel and userspace.

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

#6 lore raw
Quoted 11 lines · Christoph Hellwig
Quoted 4 lines · Mark Tinguely

PS. I may not have been very clear, the libxfs_trans_roll() and
inode_item_done() also cause a premature libxfs_iput(). Let me do more testing making any changes and target this for xfsprogs-3.2.1.

You mean you've fixed the way we handle the attachement of inodes to transaction in userspace to mirror what we do in kernelspace? I'd love to review this if you have patches as it's a somewhat of a pain point to have these work so different in kernel and userspace.

Not yet, I made the changes within the existing code so I can continue with my project. I agree, the user inode transaction code has to be synced with the kernel. I will start looking at it this weekend.

--Mark.

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs