ceph: use ihold when we already have an inode ref

We should use ihold whenever we already have a stable inode ref, even
when we aren't holding i_lock.  This avoids adding new and unnecessary
locking dependencies.

Signed-off-by: Sage Weil <sage@newdream.net>
This commit is contained in:
Sage Weil 2011-05-27 09:24:26 -07:00
parent db3540522e
commit 70b666c3b4
10 changed files with 37 additions and 28 deletions

View File

@ -453,7 +453,7 @@ static int ceph_writepage(struct page *page, struct writeback_control *wbc)
int err; int err;
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
BUG_ON(!inode); BUG_ON(!inode);
igrab(inode); ihold(inode);
err = writepage_nounlock(page, wbc); err = writepage_nounlock(page, wbc);
unlock_page(page); unlock_page(page);
iput(inode); iput(inode);

View File

@ -2940,14 +2940,12 @@ void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc)
while (!list_empty(&mdsc->cap_dirty)) { while (!list_empty(&mdsc->cap_dirty)) {
ci = list_first_entry(&mdsc->cap_dirty, struct ceph_inode_info, ci = list_first_entry(&mdsc->cap_dirty, struct ceph_inode_info,
i_dirty_item); i_dirty_item);
inode = igrab(&ci->vfs_inode); inode = &ci->vfs_inode;
ihold(inode);
dout("flush_dirty_caps %p\n", inode); dout("flush_dirty_caps %p\n", inode);
spin_unlock(&mdsc->cap_dirty_lock); spin_unlock(&mdsc->cap_dirty_lock);
if (inode) { ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH, NULL);
ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH, iput(inode);
NULL);
iput(inode);
}
spin_lock(&mdsc->cap_dirty_lock); spin_lock(&mdsc->cap_dirty_lock);
} }
spin_unlock(&mdsc->cap_dirty_lock); spin_unlock(&mdsc->cap_dirty_lock);

View File

@ -308,7 +308,8 @@ more:
req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS); req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
if (IS_ERR(req)) if (IS_ERR(req))
return PTR_ERR(req); return PTR_ERR(req);
req->r_inode = igrab(inode); req->r_inode = inode;
ihold(inode);
req->r_dentry = dget(filp->f_dentry); req->r_dentry = dget(filp->f_dentry);
/* hints to request -> mds selection code */ /* hints to request -> mds selection code */
req->r_direct_mode = USE_AUTH_MDS; req->r_direct_mode = USE_AUTH_MDS;
@ -787,10 +788,12 @@ static int ceph_link(struct dentry *old_dentry, struct inode *dir,
req->r_dentry_drop = CEPH_CAP_FILE_SHARED; req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
req->r_dentry_unless = CEPH_CAP_FILE_EXCL; req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
err = ceph_mdsc_do_request(mdsc, dir, req); err = ceph_mdsc_do_request(mdsc, dir, req);
if (err) if (err) {
d_drop(dentry); d_drop(dentry);
else if (!req->r_reply_info.head->is_dentry) } else if (!req->r_reply_info.head->is_dentry) {
d_instantiate(dentry, igrab(old_dentry->d_inode)); ihold(old_dentry->d_inode);
d_instantiate(dentry, old_dentry->d_inode);
}
ceph_mdsc_put_request(req); ceph_mdsc_put_request(req);
return err; return err;
} }

View File

@ -109,7 +109,7 @@ static struct dentry *__fh_to_dentry(struct super_block *sb,
err = ceph_mdsc_do_request(mdsc, NULL, req); err = ceph_mdsc_do_request(mdsc, NULL, req);
inode = req->r_target_inode; inode = req->r_target_inode;
if (inode) if (inode)
igrab(inode); ihold(inode);
ceph_mdsc_put_request(req); ceph_mdsc_put_request(req);
if (!inode) if (!inode)
return ERR_PTR(-ESTALE); return ERR_PTR(-ESTALE);
@ -167,7 +167,7 @@ static struct dentry *__cfh_to_dentry(struct super_block *sb,
err = ceph_mdsc_do_request(mdsc, NULL, req); err = ceph_mdsc_do_request(mdsc, NULL, req);
inode = req->r_target_inode; inode = req->r_target_inode;
if (inode) if (inode)
igrab(inode); ihold(inode);
ceph_mdsc_put_request(req); ceph_mdsc_put_request(req);
if (!inode) if (!inode)
return ERR_PTR(err ? err : -ESTALE); return ERR_PTR(err ? err : -ESTALE);

View File

@ -191,7 +191,8 @@ int ceph_open(struct inode *inode, struct file *file)
err = PTR_ERR(req); err = PTR_ERR(req);
goto out; goto out;
} }
req->r_inode = igrab(inode); req->r_inode = inode;
ihold(inode);
req->r_num_caps = 1; req->r_num_caps = 1;
err = ceph_mdsc_do_request(mdsc, parent_inode, req); err = ceph_mdsc_do_request(mdsc, parent_inode, req);
if (!err) if (!err)

View File

@ -1101,10 +1101,10 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
goto done; goto done;
} }
req->r_dentry = dn; /* may have spliced */ req->r_dentry = dn; /* may have spliced */
igrab(in); ihold(in);
} else if (ceph_ino(in) == vino.ino && } else if (ceph_ino(in) == vino.ino &&
ceph_snap(in) == vino.snap) { ceph_snap(in) == vino.snap) {
igrab(in); ihold(in);
} else { } else {
dout(" %p links to %p %llx.%llx, not %llx.%llx\n", dout(" %p links to %p %llx.%llx, not %llx.%llx\n",
dn, in, ceph_ino(in), ceph_snap(in), dn, in, ceph_ino(in), ceph_snap(in),
@ -1144,7 +1144,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
goto done; goto done;
} }
req->r_dentry = dn; /* may have spliced */ req->r_dentry = dn; /* may have spliced */
igrab(in); ihold(in);
rinfo->head->is_dentry = 1; /* fool notrace handlers */ rinfo->head->is_dentry = 1; /* fool notrace handlers */
} }
@ -1328,7 +1328,7 @@ void ceph_queue_writeback(struct inode *inode)
if (queue_work(ceph_inode_to_client(inode)->wb_wq, if (queue_work(ceph_inode_to_client(inode)->wb_wq,
&ceph_inode(inode)->i_wb_work)) { &ceph_inode(inode)->i_wb_work)) {
dout("ceph_queue_writeback %p\n", inode); dout("ceph_queue_writeback %p\n", inode);
igrab(inode); ihold(inode);
} else { } else {
dout("ceph_queue_writeback %p failed\n", inode); dout("ceph_queue_writeback %p failed\n", inode);
} }
@ -1353,7 +1353,7 @@ void ceph_queue_invalidate(struct inode *inode)
if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq, if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq,
&ceph_inode(inode)->i_pg_inv_work)) { &ceph_inode(inode)->i_pg_inv_work)) {
dout("ceph_queue_invalidate %p\n", inode); dout("ceph_queue_invalidate %p\n", inode);
igrab(inode); ihold(inode);
} else { } else {
dout("ceph_queue_invalidate %p failed\n", inode); dout("ceph_queue_invalidate %p failed\n", inode);
} }
@ -1477,7 +1477,7 @@ void ceph_queue_vmtruncate(struct inode *inode)
if (queue_work(ceph_sb_to_client(inode->i_sb)->trunc_wq, if (queue_work(ceph_sb_to_client(inode->i_sb)->trunc_wq,
&ci->i_vmtruncate_work)) { &ci->i_vmtruncate_work)) {
dout("ceph_queue_vmtruncate %p\n", inode); dout("ceph_queue_vmtruncate %p\n", inode);
igrab(inode); ihold(inode);
} else { } else {
dout("ceph_queue_vmtruncate %p failed, pending=%d\n", dout("ceph_queue_vmtruncate %p failed, pending=%d\n",
inode, ci->i_truncate_pending); inode, ci->i_truncate_pending);
@ -1738,7 +1738,8 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
__mark_inode_dirty(inode, inode_dirty_flags); __mark_inode_dirty(inode, inode_dirty_flags);
if (mask) { if (mask) {
req->r_inode = igrab(inode); req->r_inode = inode;
ihold(inode);
req->r_inode_drop = release; req->r_inode_drop = release;
req->r_args.setattr.mask = cpu_to_le32(mask); req->r_args.setattr.mask = cpu_to_le32(mask);
req->r_num_caps = 1; req->r_num_caps = 1;
@ -1779,7 +1780,8 @@ int ceph_do_getattr(struct inode *inode, int mask)
req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS); req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS);
if (IS_ERR(req)) if (IS_ERR(req))
return PTR_ERR(req); return PTR_ERR(req);
req->r_inode = igrab(inode); req->r_inode = inode;
ihold(inode);
req->r_num_caps = 1; req->r_num_caps = 1;
req->r_args.getattr.mask = cpu_to_le32(mask); req->r_args.getattr.mask = cpu_to_le32(mask);
err = ceph_mdsc_do_request(mdsc, NULL, req); err = ceph_mdsc_do_request(mdsc, NULL, req);

View File

@ -73,7 +73,8 @@ static long ceph_ioctl_set_layout(struct file *file, void __user *arg)
USE_AUTH_MDS); USE_AUTH_MDS);
if (IS_ERR(req)) if (IS_ERR(req))
return PTR_ERR(req); return PTR_ERR(req);
req->r_inode = igrab(inode); req->r_inode = inode;
ihold(inode);
req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL; req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL;
req->r_args.setlayout.layout.fl_stripe_unit = req->r_args.setlayout.layout.fl_stripe_unit =
@ -135,7 +136,8 @@ static long ceph_ioctl_set_layout_policy (struct file *file, void __user *arg)
if (IS_ERR(req)) if (IS_ERR(req))
return PTR_ERR(req); return PTR_ERR(req);
req->r_inode = igrab(inode); req->r_inode = inode;
ihold(inode);
req->r_args.setlayout.layout.fl_stripe_unit = req->r_args.setlayout.layout.fl_stripe_unit =
cpu_to_le32(l.stripe_unit); cpu_to_le32(l.stripe_unit);

View File

@ -23,7 +23,8 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS); req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS);
if (IS_ERR(req)) if (IS_ERR(req))
return PTR_ERR(req); return PTR_ERR(req);
req->r_inode = igrab(inode); req->r_inode = inode;
ihold(inode);
/* mds requires start and length rather than start and end */ /* mds requires start and length rather than start and end */
if (LLONG_MAX == fl->fl_end) if (LLONG_MAX == fl->fl_end)

View File

@ -722,7 +722,7 @@ static void flush_snaps(struct ceph_mds_client *mdsc)
ci = list_first_entry(&mdsc->snap_flush_list, ci = list_first_entry(&mdsc->snap_flush_list,
struct ceph_inode_info, i_snap_flush_item); struct ceph_inode_info, i_snap_flush_item);
inode = &ci->vfs_inode; inode = &ci->vfs_inode;
igrab(inode); ihold(inode);
spin_unlock(&mdsc->snap_flush_lock); spin_unlock(&mdsc->snap_flush_lock);
spin_lock(&inode->i_lock); spin_lock(&inode->i_lock);
__ceph_flush_snaps(ci, &session, 0); __ceph_flush_snaps(ci, &session, 0);

View File

@ -665,7 +665,8 @@ static int ceph_sync_setxattr(struct dentry *dentry, const char *name,
err = PTR_ERR(req); err = PTR_ERR(req);
goto out; goto out;
} }
req->r_inode = igrab(inode); req->r_inode = inode;
ihold(inode);
req->r_inode_drop = CEPH_CAP_XATTR_SHARED; req->r_inode_drop = CEPH_CAP_XATTR_SHARED;
req->r_num_caps = 1; req->r_num_caps = 1;
req->r_args.setxattr.flags = cpu_to_le32(flags); req->r_args.setxattr.flags = cpu_to_le32(flags);
@ -795,7 +796,8 @@ static int ceph_send_removexattr(struct dentry *dentry, const char *name)
USE_AUTH_MDS); USE_AUTH_MDS);
if (IS_ERR(req)) if (IS_ERR(req))
return PTR_ERR(req); return PTR_ERR(req);
req->r_inode = igrab(inode); req->r_inode = inode;
ihold(inode);
req->r_inode_drop = CEPH_CAP_XATTR_SHARED; req->r_inode_drop = CEPH_CAP_XATTR_SHARED;
req->r_num_caps = 1; req->r_num_caps = 1;
req->r_path2 = kstrdup(name, GFP_NOFS); req->r_path2 = kstrdup(name, GFP_NOFS);