From 2a57107a04a4eb2d65043b600faf773f53d8f01e Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 9 Sep 2008 16:31:53 -0700 Subject: [PATCH] kclient: allocate xattr buffer outside of i_lock --- src/kernel/inode.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/kernel/inode.c b/src/kernel/inode.c index 2b778324cecba..2a04c76541e9e 100644 --- a/src/kernel/inode.c +++ b/src/kernel/inode.c @@ -308,11 +308,21 @@ int ceph_fill_inode(struct inode *inode, u32 su = le32_to_cpu(info->layout.fl_stripe_unit); int blkbits = fls(su) - 1; u32 nsplits; + void *xattr_data = 0; + int err = 0; dout(30, "fill_inode %p ino %llx by %d.%d sz=%llu mode 0%o nlink %d\n", inode, info->ino, inode->i_uid, inode->i_gid, inode->i_size, inode->i_mode, inode->i_nlink); + /* prealloc xattr data, if it looks like we'll need it */ + if (iinfo->xattr_len && iinfo->xattr_len != ci->i_xattr_len) { + xattr_data = kmalloc(iinfo->xattr_len, GFP_NOFS); + if (!xattr_data) + derr(10, "ENOMEM on xattr blob %d bytes\n", + ci->i_xattr_len); + } + spin_lock(&inode->i_lock); dout(30, " su %d, blkbits %d. v %llu, had %llu\n", su, blkbits, le64_to_cpu(info->version), ci->i_version); @@ -353,12 +363,8 @@ int ceph_fill_inode(struct inode *inode, if (ci->i_xattr_len != iinfo->xattr_len) { kfree(ci->i_xattr_data); ci->i_xattr_len = iinfo->xattr_len; - ci->i_xattr_data = kmalloc(ci->i_xattr_len, GFP_NOFS); - if (!ci->i_xattr_data) { - derr(10, "ENOMEM on xattr blob %d bytes\n", - ci->i_xattr_len); - ci->i_xattr_len = 0; /* hrmpf */ - } + ci->i_xattr_data = xattr_data; + xattr_data = 0; } if (ci->i_xattr_len) memcpy(ci->i_xattr_data, iinfo->xattr_data, @@ -409,9 +415,10 @@ no_change: inode->i_op = &ceph_symlink_iops; symlen = iinfo->symlink_len; BUG_ON(symlen != ci->vfs_inode.i_size); + err = -ENOMEM; ci->i_symlink = kmalloc(symlen+1, GFP_NOFS); if (ci->i_symlink == NULL) - return -ENOMEM; + goto out; memcpy(ci->i_symlink, iinfo->symlink, symlen); ci->i_symlink[symlen] = 0; break; @@ -433,10 +440,14 @@ no_change: default: derr(0, "BAD mode 0x%x S_IFMT 0x%x\n", inode->i_mode, inode->i_mode & S_IFMT); - return -EINVAL; + err = -EINVAL; + goto out; } + err = 0; - return 0; +out: + kfree(xattr_data); + return err; } /* -- 2.39.5