ceph: set pool_ns in new inode layout for async creates
authorJeff Layton <jlayton@kernel.org>
Wed, 26 Jan 2022 17:36:49 +0000 (12:36 -0500)
committerIlya Dryomov <idryomov@gmail.com>
Wed, 26 Jan 2022 19:17:50 +0000 (20:17 +0100)
Dan reported that he was unable to write to files that had been
asynchronously created when the client's OSD caps are restricted to a
particular namespace.

The issue is that the layout for the new inode is only partially being
filled. Ensure that we populate the pool_ns_data and pool_ns_len in the
iinfo before calling ceph_fill_inode.

Cc: stable@vger.kernel.org
URL: https://tracker.ceph.com/issues/54013
Fixes: 9a8d03ca2e2c ("ceph: attempt to do async create when possible")
Reported-by: Dan van der Ster <dan@vanderster.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
fs/ceph/file.c

index 6afae97..bbed322 100644 (file)
@@ -583,6 +583,7 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry,
        struct ceph_inode_info *ci = ceph_inode(dir);
        struct inode *inode;
        struct timespec64 now;
+       struct ceph_string *pool_ns;
        struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(dir->i_sb);
        struct ceph_vino vino = { .ino = req->r_deleg_ino,
                                  .snap = CEPH_NOSNAP };
@@ -632,6 +633,12 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry,
        in.max_size = cpu_to_le64(lo->stripe_unit);
 
        ceph_file_layout_to_legacy(lo, &in.layout);
+       /* lo is private, so pool_ns can't change */
+       pool_ns = rcu_dereference_raw(lo->pool_ns);
+       if (pool_ns) {
+               iinfo.pool_ns_len = pool_ns->len;
+               iinfo.pool_ns_data = pool_ns->str;
+       }
 
        down_read(&mdsc->snap_rwsem);
        ret = ceph_fill_inode(inode, NULL, &iinfo, NULL, req->r_session,