ceph: add a new flag to indicate whether parent is locked
struct ceph_mds_request has an r_locked_dir pointer, which is set to indicate the parent inode and that its i_rwsem is locked. In some critical places, we need to be able to indicate the parent inode to the request handling code, even when its i_rwsem may not be locked. Most of the code that operates on r_locked_dir doesn't require that the i_rwsem be locked. We only really need it to handle manipulation of the dcache. The rest (filling of the inode, updating dentry leases, etc.) already has its own locking. Add a new r_req_flags bit that indicates whether the parent is locked when doing the request, and rename the pointer to "r_parent". For now, all the places that set r_parent also set this flag, but that will change in a later patch. Signed-off-by: Jeff Layton <jlayton@redhat.com> Reviewed-by: Yan, Zheng <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:

committed by
Ilya Dryomov

parent
bc2de10dc4
commit
3dd69aabce
@@ -752,7 +752,8 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
|
||||
mask |= CEPH_CAP_XATTR_SHARED;
|
||||
req->r_args.getattr.mask = cpu_to_le32(mask);
|
||||
|
||||
req->r_locked_dir = dir;
|
||||
req->r_parent = dir;
|
||||
set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
|
||||
err = ceph_mdsc_do_request(mdsc, NULL, req);
|
||||
err = ceph_handle_snapdir(req, dentry, err);
|
||||
dentry = ceph_finish_lookup(req, dentry, err);
|
||||
@@ -813,7 +814,8 @@ static int ceph_mknod(struct inode *dir, struct dentry *dentry,
|
||||
}
|
||||
req->r_dentry = dget(dentry);
|
||||
req->r_num_caps = 2;
|
||||
req->r_locked_dir = dir;
|
||||
req->r_parent = dir;
|
||||
set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
|
||||
req->r_args.mknod.mode = cpu_to_le32(mode);
|
||||
req->r_args.mknod.rdev = cpu_to_le32(rdev);
|
||||
req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
|
||||
@@ -864,7 +866,8 @@ static int ceph_symlink(struct inode *dir, struct dentry *dentry,
|
||||
ceph_mdsc_put_request(req);
|
||||
goto out;
|
||||
}
|
||||
req->r_locked_dir = dir;
|
||||
req->r_parent = dir;
|
||||
set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
|
||||
req->r_dentry = dget(dentry);
|
||||
req->r_num_caps = 2;
|
||||
req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
|
||||
@@ -913,7 +916,8 @@ static int ceph_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||
|
||||
req->r_dentry = dget(dentry);
|
||||
req->r_num_caps = 2;
|
||||
req->r_locked_dir = dir;
|
||||
req->r_parent = dir;
|
||||
set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
|
||||
req->r_args.mkdir.mode = cpu_to_le32(mode);
|
||||
req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
|
||||
req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
|
||||
@@ -957,7 +961,8 @@ static int ceph_link(struct dentry *old_dentry, struct inode *dir,
|
||||
req->r_dentry = dget(dentry);
|
||||
req->r_num_caps = 2;
|
||||
req->r_old_dentry = dget(old_dentry);
|
||||
req->r_locked_dir = dir;
|
||||
req->r_parent = dir;
|
||||
set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
|
||||
req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
|
||||
req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
|
||||
/* release LINK_SHARED on source inode (mds will lock it) */
|
||||
@@ -1023,7 +1028,8 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry)
|
||||
}
|
||||
req->r_dentry = dget(dentry);
|
||||
req->r_num_caps = 2;
|
||||
req->r_locked_dir = dir;
|
||||
req->r_parent = dir;
|
||||
set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
|
||||
req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
|
||||
req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
|
||||
req->r_inode_drop = drop_caps_for_unlink(inode);
|
||||
@@ -1066,7 +1072,8 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
req->r_num_caps = 2;
|
||||
req->r_old_dentry = dget(old_dentry);
|
||||
req->r_old_dentry_dir = old_dir;
|
||||
req->r_locked_dir = new_dir;
|
||||
req->r_parent = new_dir;
|
||||
set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
|
||||
req->r_old_dentry_drop = CEPH_CAP_FILE_SHARED;
|
||||
req->r_old_dentry_unless = CEPH_CAP_FILE_EXCL;
|
||||
req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
|
||||
|
Reference in New Issue
Block a user