Skip to content

Commit 0a78ac4

Browse files
committed
Merge tag 'ceph-for-4.19-rc1' of git://github.com/ceph/ceph-client
Pull ceph updates from Ilya Dryomov: "The main things are support for cephx v2 authentication protocol and basic support for rbd images within namespaces (myself). Also included are y2038 conversion patches from Arnd, a pile of miscellaneous fixes from Chengguang and Zheng's feature bit infrastructure for the filesystem" * tag 'ceph-for-4.19-rc1' of git://github.com/ceph/ceph-client: (40 commits) ceph: don't drop message if it contains more data than expected ceph: support cephfs' own feature bits crush: fix using plain integer as NULL warning libceph: remove unnecessary non NULL check for request_key ceph: refactor error handling code in ceph_reserve_caps() ceph: refactor ceph_unreserve_caps() ceph: change to void return type for __do_request() ceph: compare fsc->max_file_size and inode->i_size for max file size limit ceph: add additional size check in ceph_setattr() ceph: add additional offset check in ceph_write_iter() ceph: add additional range check in ceph_fallocate() ceph: add new field max_file_size in ceph_fs_client libceph: weaken sizeof check in ceph_x_verify_authorizer_reply() libceph: check authorizer reply/challenge length before reading libceph: implement CEPHX_V2 calculation mode libceph: add authorizer challenge libceph: factor out encrypt_authorizer() libceph: factor out __ceph_x_decrypt() libceph: factor out __prepare_write_connect() libceph: store ceph_auth_handshake pointer in ceph_connection ...
2 parents bfebeb1 + 0fcf6c0 commit 0a78ac4

37 files changed

+737
-408
lines changed

drivers/block/rbd.c

Lines changed: 88 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ struct rbd_image_header {
181181
struct rbd_spec {
182182
u64 pool_id;
183183
const char *pool_name;
184+
const char *pool_ns; /* NULL if default, never "" */
184185

185186
const char *image_id;
186187
const char *image_name;
@@ -735,6 +736,7 @@ enum {
735736
Opt_lock_timeout,
736737
Opt_last_int,
737738
/* int args above */
739+
Opt_pool_ns,
738740
Opt_last_string,
739741
/* string args above */
740742
Opt_read_only,
@@ -749,6 +751,7 @@ static match_table_t rbd_opts_tokens = {
749751
{Opt_queue_depth, "queue_depth=%d"},
750752
{Opt_lock_timeout, "lock_timeout=%d"},
751753
/* int args above */
754+
{Opt_pool_ns, "_pool_ns=%s"},
752755
/* string args above */
753756
{Opt_read_only, "read_only"},
754757
{Opt_read_only, "ro"}, /* Alternate spelling */
@@ -776,17 +779,22 @@ struct rbd_options {
776779
#define RBD_EXCLUSIVE_DEFAULT false
777780
#define RBD_TRIM_DEFAULT true
778781

782+
struct parse_rbd_opts_ctx {
783+
struct rbd_spec *spec;
784+
struct rbd_options *opts;
785+
};
786+
779787
static int parse_rbd_opts_token(char *c, void *private)
780788
{
781-
struct rbd_options *rbd_opts = private;
789+
struct parse_rbd_opts_ctx *pctx = private;
782790
substring_t argstr[MAX_OPT_ARGS];
783791
int token, intval, ret;
784792

785793
token = match_token(c, rbd_opts_tokens, argstr);
786794
if (token < Opt_last_int) {
787795
ret = match_int(&argstr[0], &intval);
788796
if (ret < 0) {
789-
pr_err("bad mount option arg (not int) at '%s'\n", c);
797+
pr_err("bad option arg (not int) at '%s'\n", c);
790798
return ret;
791799
}
792800
dout("got int token %d val %d\n", token, intval);
@@ -802,30 +810,36 @@ static int parse_rbd_opts_token(char *c, void *private)
802810
pr_err("queue_depth out of range\n");
803811
return -EINVAL;
804812
}
805-
rbd_opts->queue_depth = intval;
813+
pctx->opts->queue_depth = intval;
806814
break;
807815
case Opt_lock_timeout:
808816
/* 0 is "wait forever" (i.e. infinite timeout) */
809817
if (intval < 0 || intval > INT_MAX / 1000) {
810818
pr_err("lock_timeout out of range\n");
811819
return -EINVAL;
812820
}
813-
rbd_opts->lock_timeout = msecs_to_jiffies(intval * 1000);
821+
pctx->opts->lock_timeout = msecs_to_jiffies(intval * 1000);
822+
break;
823+
case Opt_pool_ns:
824+
kfree(pctx->spec->pool_ns);
825+
pctx->spec->pool_ns = match_strdup(argstr);
826+
if (!pctx->spec->pool_ns)
827+
return -ENOMEM;
814828
break;
815829
case Opt_read_only:
816-
rbd_opts->read_only = true;
830+
pctx->opts->read_only = true;
817831
break;
818832
case Opt_read_write:
819-
rbd_opts->read_only = false;
833+
pctx->opts->read_only = false;
820834
break;
821835
case Opt_lock_on_read:
822-
rbd_opts->lock_on_read = true;
836+
pctx->opts->lock_on_read = true;
823837
break;
824838
case Opt_exclusive:
825-
rbd_opts->exclusive = true;
839+
pctx->opts->exclusive = true;
826840
break;
827841
case Opt_notrim:
828-
rbd_opts->trim = false;
842+
pctx->opts->trim = false;
829843
break;
830844
default:
831845
/* libceph prints "bad option" msg */
@@ -1452,7 +1466,7 @@ static void rbd_osd_req_format_write(struct rbd_obj_request *obj_request)
14521466
struct ceph_osd_request *osd_req = obj_request->osd_req;
14531467

14541468
osd_req->r_flags = CEPH_OSD_FLAG_WRITE;
1455-
ktime_get_real_ts(&osd_req->r_mtime);
1469+
ktime_get_real_ts64(&osd_req->r_mtime);
14561470
osd_req->r_data_offset = obj_request->ex.oe_off;
14571471
}
14581472

@@ -1475,7 +1489,13 @@ rbd_osd_req_create(struct rbd_obj_request *obj_req, unsigned int num_ops)
14751489
req->r_callback = rbd_osd_req_callback;
14761490
req->r_priv = obj_req;
14771491

1492+
/*
1493+
* Data objects may be stored in a separate pool, but always in
1494+
* the same namespace in that pool as the header in its pool.
1495+
*/
1496+
ceph_oloc_copy(&req->r_base_oloc, &rbd_dev->header_oloc);
14781497
req->r_base_oloc.pool = rbd_dev->layout.pool_id;
1498+
14791499
if (ceph_oid_aprintf(&req->r_base_oid, GFP_NOIO, name_format,
14801500
rbd_dev->header.object_prefix, obj_req->ex.oe_objno))
14811501
goto err_req;
@@ -4119,6 +4139,14 @@ static ssize_t rbd_pool_id_show(struct device *dev,
41194139
(unsigned long long) rbd_dev->spec->pool_id);
41204140
}
41214141

4142+
static ssize_t rbd_pool_ns_show(struct device *dev,
4143+
struct device_attribute *attr, char *buf)
4144+
{
4145+
struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
4146+
4147+
return sprintf(buf, "%s\n", rbd_dev->spec->pool_ns ?: "");
4148+
}
4149+
41224150
static ssize_t rbd_name_show(struct device *dev,
41234151
struct device_attribute *attr, char *buf)
41244152
{
@@ -4217,6 +4245,7 @@ static DEVICE_ATTR(cluster_fsid, 0444, rbd_cluster_fsid_show, NULL);
42174245
static DEVICE_ATTR(config_info, 0400, rbd_config_info_show, NULL);
42184246
static DEVICE_ATTR(pool, 0444, rbd_pool_show, NULL);
42194247
static DEVICE_ATTR(pool_id, 0444, rbd_pool_id_show, NULL);
4248+
static DEVICE_ATTR(pool_ns, 0444, rbd_pool_ns_show, NULL);
42204249
static DEVICE_ATTR(name, 0444, rbd_name_show, NULL);
42214250
static DEVICE_ATTR(image_id, 0444, rbd_image_id_show, NULL);
42224251
static DEVICE_ATTR(refresh, 0200, NULL, rbd_image_refresh);
@@ -4235,6 +4264,7 @@ static struct attribute *rbd_attrs[] = {
42354264
&dev_attr_config_info.attr,
42364265
&dev_attr_pool.attr,
42374266
&dev_attr_pool_id.attr,
4267+
&dev_attr_pool_ns.attr,
42384268
&dev_attr_name.attr,
42394269
&dev_attr_image_id.attr,
42404270
&dev_attr_current_snap.attr,
@@ -4295,6 +4325,7 @@ static void rbd_spec_free(struct kref *kref)
42954325
struct rbd_spec *spec = container_of(kref, struct rbd_spec, kref);
42964326

42974327
kfree(spec->pool_name);
4328+
kfree(spec->pool_ns);
42984329
kfree(spec->image_id);
42994330
kfree(spec->image_name);
43004331
kfree(spec->snap_name);
@@ -4353,6 +4384,12 @@ static struct rbd_device *__rbd_dev_create(struct rbd_client *rbdc,
43534384
rbd_dev->header.data_pool_id = CEPH_NOPOOL;
43544385
ceph_oid_init(&rbd_dev->header_oid);
43554386
rbd_dev->header_oloc.pool = spec->pool_id;
4387+
if (spec->pool_ns) {
4388+
WARN_ON(!*spec->pool_ns);
4389+
rbd_dev->header_oloc.pool_ns =
4390+
ceph_find_or_create_string(spec->pool_ns,
4391+
strlen(spec->pool_ns));
4392+
}
43564393

43574394
mutex_init(&rbd_dev->watch_mutex);
43584395
rbd_dev->watch_state = RBD_WATCH_STATE_UNREGISTERED;
@@ -4633,6 +4670,17 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
46334670
parent_spec->pool_id = pool_id;
46344671
parent_spec->image_id = image_id;
46354672
parent_spec->snap_id = snap_id;
4673+
4674+
/* TODO: support cloning across namespaces */
4675+
if (rbd_dev->spec->pool_ns) {
4676+
parent_spec->pool_ns = kstrdup(rbd_dev->spec->pool_ns,
4677+
GFP_KERNEL);
4678+
if (!parent_spec->pool_ns) {
4679+
ret = -ENOMEM;
4680+
goto out_err;
4681+
}
4682+
}
4683+
46364684
rbd_dev->parent_spec = parent_spec;
46374685
parent_spec = NULL; /* rbd_dev now owns this */
46384686
} else {
@@ -5146,8 +5194,7 @@ static int rbd_add_parse_args(const char *buf,
51465194
const char *mon_addrs;
51475195
char *snap_name;
51485196
size_t mon_addrs_size;
5149-
struct rbd_spec *spec = NULL;
5150-
struct rbd_options *rbd_opts = NULL;
5197+
struct parse_rbd_opts_ctx pctx = { 0 };
51515198
struct ceph_options *copts;
51525199
int ret;
51535200

@@ -5171,22 +5218,22 @@ static int rbd_add_parse_args(const char *buf,
51715218
goto out_err;
51725219
}
51735220

5174-
spec = rbd_spec_alloc();
5175-
if (!spec)
5221+
pctx.spec = rbd_spec_alloc();
5222+
if (!pctx.spec)
51765223
goto out_mem;
51775224

5178-
spec->pool_name = dup_token(&buf, NULL);
5179-
if (!spec->pool_name)
5225+
pctx.spec->pool_name = dup_token(&buf, NULL);
5226+
if (!pctx.spec->pool_name)
51805227
goto out_mem;
5181-
if (!*spec->pool_name) {
5228+
if (!*pctx.spec->pool_name) {
51825229
rbd_warn(NULL, "no pool name provided");
51835230
goto out_err;
51845231
}
51855232

5186-
spec->image_name = dup_token(&buf, NULL);
5187-
if (!spec->image_name)
5233+
pctx.spec->image_name = dup_token(&buf, NULL);
5234+
if (!pctx.spec->image_name)
51885235
goto out_mem;
5189-
if (!*spec->image_name) {
5236+
if (!*pctx.spec->image_name) {
51905237
rbd_warn(NULL, "no image name provided");
51915238
goto out_err;
51925239
}
@@ -5207,40 +5254,40 @@ static int rbd_add_parse_args(const char *buf,
52075254
if (!snap_name)
52085255
goto out_mem;
52095256
*(snap_name + len) = '\0';
5210-
spec->snap_name = snap_name;
5257+
pctx.spec->snap_name = snap_name;
52115258

52125259
/* Initialize all rbd options to the defaults */
52135260

5214-
rbd_opts = kzalloc(sizeof (*rbd_opts), GFP_KERNEL);
5215-
if (!rbd_opts)
5261+
pctx.opts = kzalloc(sizeof(*pctx.opts), GFP_KERNEL);
5262+
if (!pctx.opts)
52165263
goto out_mem;
52175264

5218-
rbd_opts->read_only = RBD_READ_ONLY_DEFAULT;
5219-
rbd_opts->queue_depth = RBD_QUEUE_DEPTH_DEFAULT;
5220-
rbd_opts->lock_timeout = RBD_LOCK_TIMEOUT_DEFAULT;
5221-
rbd_opts->lock_on_read = RBD_LOCK_ON_READ_DEFAULT;
5222-
rbd_opts->exclusive = RBD_EXCLUSIVE_DEFAULT;
5223-
rbd_opts->trim = RBD_TRIM_DEFAULT;
5265+
pctx.opts->read_only = RBD_READ_ONLY_DEFAULT;
5266+
pctx.opts->queue_depth = RBD_QUEUE_DEPTH_DEFAULT;
5267+
pctx.opts->lock_timeout = RBD_LOCK_TIMEOUT_DEFAULT;
5268+
pctx.opts->lock_on_read = RBD_LOCK_ON_READ_DEFAULT;
5269+
pctx.opts->exclusive = RBD_EXCLUSIVE_DEFAULT;
5270+
pctx.opts->trim = RBD_TRIM_DEFAULT;
52245271

52255272
copts = ceph_parse_options(options, mon_addrs,
5226-
mon_addrs + mon_addrs_size - 1,
5227-
parse_rbd_opts_token, rbd_opts);
5273+
mon_addrs + mon_addrs_size - 1,
5274+
parse_rbd_opts_token, &pctx);
52285275
if (IS_ERR(copts)) {
52295276
ret = PTR_ERR(copts);
52305277
goto out_err;
52315278
}
52325279
kfree(options);
52335280

52345281
*ceph_opts = copts;
5235-
*opts = rbd_opts;
5236-
*rbd_spec = spec;
5282+
*opts = pctx.opts;
5283+
*rbd_spec = pctx.spec;
52375284

52385285
return 0;
52395286
out_mem:
52405287
ret = -ENOMEM;
52415288
out_err:
5242-
kfree(rbd_opts);
5243-
rbd_spec_put(spec);
5289+
kfree(pctx.opts);
5290+
rbd_spec_put(pctx.spec);
52445291
kfree(options);
52455292

52465293
return ret;
@@ -5586,8 +5633,10 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
55865633
ret = rbd_register_watch(rbd_dev);
55875634
if (ret) {
55885635
if (ret == -ENOENT)
5589-
pr_info("image %s/%s does not exist\n",
5636+
pr_info("image %s/%s%s%s does not exist\n",
55905637
rbd_dev->spec->pool_name,
5638+
rbd_dev->spec->pool_ns ?: "",
5639+
rbd_dev->spec->pool_ns ? "/" : "",
55915640
rbd_dev->spec->image_name);
55925641
goto err_out_format;
55935642
}
@@ -5609,8 +5658,10 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
56095658
ret = rbd_spec_fill_names(rbd_dev);
56105659
if (ret) {
56115660
if (ret == -ENOENT)
5612-
pr_info("snap %s/%s@%s does not exist\n",
5661+
pr_info("snap %s/%s%s%s@%s does not exist\n",
56135662
rbd_dev->spec->pool_name,
5663+
rbd_dev->spec->pool_ns ?: "",
5664+
rbd_dev->spec->pool_ns ? "/" : "",
56145665
rbd_dev->spec->image_name,
56155666
rbd_dev->spec->snap_name);
56165667
goto err_out_probe;

fs/ceph/acl.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ static inline void ceph_set_cached_acl(struct inode *inode,
4545
struct posix_acl *ceph_get_acl(struct inode *inode, int type)
4646
{
4747
int size;
48+
unsigned int retry_cnt = 0;
4849
const char *name;
4950
char *value = NULL;
5051
struct posix_acl *acl;
@@ -60,6 +61,7 @@ struct posix_acl *ceph_get_acl(struct inode *inode, int type)
6061
BUG();
6162
}
6263

64+
retry:
6365
size = __ceph_getxattr(inode, name, "", 0);
6466
if (size > 0) {
6567
value = kzalloc(size, GFP_NOFS);
@@ -68,12 +70,22 @@ struct posix_acl *ceph_get_acl(struct inode *inode, int type)
6870
size = __ceph_getxattr(inode, name, value, size);
6971
}
7072

71-
if (size > 0)
73+
if (size == -ERANGE && retry_cnt < 10) {
74+
retry_cnt++;
75+
kfree(value);
76+
value = NULL;
77+
goto retry;
78+
}
79+
80+
if (size > 0) {
7281
acl = posix_acl_from_xattr(&init_user_ns, value, size);
73-
else if (size == -ERANGE || size == -ENODATA || size == 0)
82+
} else if (size == -ENODATA || size == 0) {
7483
acl = NULL;
75-
else
84+
} else {
85+
pr_err_ratelimited("get acl %llx.%llx failed, err=%d\n",
86+
ceph_vinop(inode), size);
7687
acl = ERR_PTR(-EIO);
88+
}
7789

7890
kfree(value);
7991

@@ -89,6 +101,7 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
89101
const char *name = NULL;
90102
char *value = NULL;
91103
struct iattr newattrs;
104+
struct timespec64 old_ctime = inode->i_ctime;
92105
umode_t new_mode = inode->i_mode, old_mode = inode->i_mode;
93106

94107
switch (type) {
@@ -133,7 +146,7 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
133146
if (new_mode != old_mode) {
134147
newattrs.ia_ctime = current_time(inode);
135148
newattrs.ia_mode = new_mode;
136-
newattrs.ia_valid = ATTR_MODE;
149+
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
137150
ret = __ceph_setattr(inode, &newattrs);
138151
if (ret)
139152
goto out_free;
@@ -142,8 +155,9 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
142155
ret = __ceph_setxattr(inode, name, value, size, 0);
143156
if (ret) {
144157
if (new_mode != old_mode) {
158+
newattrs.ia_ctime = old_ctime;
145159
newattrs.ia_mode = old_mode;
146-
newattrs.ia_valid = ATTR_MODE;
160+
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
147161
__ceph_setattr(inode, &newattrs);
148162
}
149163
goto out_free;
@@ -171,10 +185,10 @@ int ceph_pre_init_acls(struct inode *dir, umode_t *mode,
171185
return err;
172186

173187
if (acl) {
174-
int ret = posix_acl_equiv_mode(acl, mode);
175-
if (ret < 0)
188+
err = posix_acl_equiv_mode(acl, mode);
189+
if (err < 0)
176190
goto out_err;
177-
if (ret == 0) {
191+
if (err == 0) {
178192
posix_acl_release(acl);
179193
acl = NULL;
180194
}

0 commit comments

Comments
 (0)