diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2024-01-08 10:05:24 +1100 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2024-01-08 10:05:24 +1100 |
commit | c488a6e76a008d19b8562d664610dc7f7d98f578 (patch) | |
tree | 6528a76617911fb52f2dfbaf19a82c0aa083916f | |
parent | 67b778890edbf4858998b267d073a3b151a6ae5a (diff) | |
parent | d30d7c57a64dac6c179d87d12f4350d11731bcb5 (diff) | |
download | linux-next-c488a6e76a008d19b8562d664610dc7f7d98f578.tar.gz |
Merge branch 'master' of git://github.com/ceph/ceph-client.git
-rw-r--r-- | fs/ceph/Kconfig | 1 | ||||
-rw-r--r-- | fs/ceph/caps.c | 9 | ||||
-rw-r--r-- | include/linux/ceph/osd_client.h | 3 | ||||
-rw-r--r-- | net/ceph/osd_client.c | 32 |
4 files changed, 24 insertions, 21 deletions
diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig index 94df854147d359..7249d70e1a43fa 100644 --- a/fs/ceph/Kconfig +++ b/fs/ceph/Kconfig @@ -7,6 +7,7 @@ config CEPH_FS select CRYPTO_AES select CRYPTO select NETFS_SUPPORT + select FS_ENCRYPTION_ALGS if FS_ENCRYPTION default n help Choose Y or M here to include support for mounting the diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 2c0b8dc3dd0d80..9c02f328c966cb 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -4887,13 +4887,15 @@ int ceph_encode_dentry_release(void **p, struct dentry *dentry, struct inode *dir, int mds, int drop, int unless) { - struct dentry *parent = NULL; struct ceph_mds_request_release *rel = *p; struct ceph_dentry_info *di = ceph_dentry(dentry); struct ceph_client *cl; int force = 0; int ret; + /* This shouldn't happen */ + BUG_ON(!dir); + /* * force an record for the directory caps if we have a dentry lease. * this is racy (can't take i_ceph_lock and d_lock together), but it @@ -4903,14 +4905,9 @@ int ceph_encode_dentry_release(void **p, struct dentry *dentry, spin_lock(&dentry->d_lock); if (di->lease_session && di->lease_session->s_mds == mds) force = 1; - if (!dir) { - parent = dget(dentry->d_parent); - dir = d_inode(parent); - } spin_unlock(&dentry->d_lock); ret = ceph_encode_inode_release(p, dir, mds, drop, unless, force); - dput(parent); cl = ceph_inode_to_client(dir); spin_lock(&dentry->d_lock); diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h index b8610e9d2471f5..5edf9fffa0973c 100644 --- a/include/linux/ceph/osd_client.h +++ b/include/linux/ceph/osd_client.h @@ -45,6 +45,7 @@ enum ceph_sparse_read_state { CEPH_SPARSE_READ_HDR = 0, CEPH_SPARSE_READ_EXTENTS, CEPH_SPARSE_READ_DATA_LEN, + CEPH_SPARSE_READ_DATA_PRE, CEPH_SPARSE_READ_DATA, }; @@ -64,7 +65,7 @@ struct ceph_sparse_read { u64 sr_req_len; /* orig request length */ u64 sr_pos; /* current pos in buffer */ int sr_index; /* current extent index */ - __le32 sr_datalen; /* length of actual data */ + u32 sr_datalen; /* length of actual data */ u32 sr_count; /* extent count in reply */ int sr_ext_len; /* length of extent array */ struct ceph_sparse_extent *sr_extent; /* extent array */ diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index d3a759e052c81f..6db2880e928a4a 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -5850,8 +5850,6 @@ static inline void convert_extent_map(struct ceph_sparse_read *sr) } #endif -#define MAX_EXTENTS 4096 - static int osd_sparse_read(struct ceph_connection *con, struct ceph_msg_data_cursor *cursor, char **pbuf) @@ -5882,23 +5880,16 @@ next_op: if (count > 0) { if (!sr->sr_extent || count > sr->sr_ext_len) { - /* - * Apply a hard cap to the number of extents. - * If we have more, assume something is wrong. - */ - if (count > MAX_EXTENTS) { - dout("%s: OSD returned 0x%x extents in a single reply!\n", - __func__, count); - return -EREMOTEIO; - } - /* no extent array provided, or too short */ kfree(sr->sr_extent); sr->sr_extent = kmalloc_array(count, sizeof(*sr->sr_extent), GFP_NOIO); - if (!sr->sr_extent) + if (!sr->sr_extent) { + pr_err("%s: failed to allocate %u extents\n", + __func__, count); return -ENOMEM; + } sr->sr_ext_len = count; } ret = count * sizeof(*sr->sr_extent); @@ -5912,10 +5903,21 @@ next_op: convert_extent_map(sr); ret = sizeof(sr->sr_datalen); *pbuf = (char *)&sr->sr_datalen; - sr->sr_state = CEPH_SPARSE_READ_DATA; + sr->sr_state = CEPH_SPARSE_READ_DATA_PRE; break; + case CEPH_SPARSE_READ_DATA_PRE: + /* Convert sr_datalen to host-endian */ + sr->sr_datalen = le32_to_cpu((__force __le32)sr->sr_datalen); + sr->sr_state = CEPH_SPARSE_READ_DATA; + fallthrough; case CEPH_SPARSE_READ_DATA: if (sr->sr_index >= count) { + if (sr->sr_datalen && count) { + pr_err("%s: datalen mismatch, %u bytes left\n", + __func__, sr->sr_datalen); + return -EREMOTEIO; + } + sr->sr_state = CEPH_SPARSE_READ_HDR; goto next_op; } @@ -5932,6 +5934,8 @@ next_op: return -EREMOTEIO; } + sr->sr_datalen -= elen; + /* zero out anything from sr_pos to start of extent */ if (sr->sr_pos < eoff) advance_cursor(cursor, eoff - sr->sr_pos, true); |