Skip to content

Commit

Permalink
Merge tag 'ceph-for-4.19-rc1' of git://github.com/ceph/ceph-client
Browse files Browse the repository at this point in the history
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
  ...
  • Loading branch information
torvalds committed Aug 21, 2018
2 parents bfebeb1 + 0fcf6c0 commit 0a78ac4
Show file tree
Hide file tree
Showing 37 changed files with 737 additions and 408 deletions.
125 changes: 88 additions & 37 deletions drivers/block/rbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ struct rbd_image_header {
struct rbd_spec {
u64 pool_id;
const char *pool_name;
const char *pool_ns; /* NULL if default, never "" */

const char *image_id;
const char *image_name;
Expand Down Expand Up @@ -735,6 +736,7 @@ enum {
Opt_lock_timeout,
Opt_last_int,
/* int args above */
Opt_pool_ns,
Opt_last_string,
/* string args above */
Opt_read_only,
Expand All @@ -749,6 +751,7 @@ static match_table_t rbd_opts_tokens = {
{Opt_queue_depth, "queue_depth=%d"},
{Opt_lock_timeout, "lock_timeout=%d"},
/* int args above */
{Opt_pool_ns, "_pool_ns=%s"},
/* string args above */
{Opt_read_only, "read_only"},
{Opt_read_only, "ro"}, /* Alternate spelling */
Expand Down Expand Up @@ -776,17 +779,22 @@ struct rbd_options {
#define RBD_EXCLUSIVE_DEFAULT false
#define RBD_TRIM_DEFAULT true

struct parse_rbd_opts_ctx {
struct rbd_spec *spec;
struct rbd_options *opts;
};

static int parse_rbd_opts_token(char *c, void *private)
{
struct rbd_options *rbd_opts = private;
struct parse_rbd_opts_ctx *pctx = private;
substring_t argstr[MAX_OPT_ARGS];
int token, intval, ret;

token = match_token(c, rbd_opts_tokens, argstr);
if (token < Opt_last_int) {
ret = match_int(&argstr[0], &intval);
if (ret < 0) {
pr_err("bad mount option arg (not int) at '%s'\n", c);
pr_err("bad option arg (not int) at '%s'\n", c);
return ret;
}
dout("got int token %d val %d\n", token, intval);
Expand All @@ -802,30 +810,36 @@ static int parse_rbd_opts_token(char *c, void *private)
pr_err("queue_depth out of range\n");
return -EINVAL;
}
rbd_opts->queue_depth = intval;
pctx->opts->queue_depth = intval;
break;
case Opt_lock_timeout:
/* 0 is "wait forever" (i.e. infinite timeout) */
if (intval < 0 || intval > INT_MAX / 1000) {
pr_err("lock_timeout out of range\n");
return -EINVAL;
}
rbd_opts->lock_timeout = msecs_to_jiffies(intval * 1000);
pctx->opts->lock_timeout = msecs_to_jiffies(intval * 1000);
break;
case Opt_pool_ns:
kfree(pctx->spec->pool_ns);
pctx->spec->pool_ns = match_strdup(argstr);
if (!pctx->spec->pool_ns)
return -ENOMEM;
break;
case Opt_read_only:
rbd_opts->read_only = true;
pctx->opts->read_only = true;
break;
case Opt_read_write:
rbd_opts->read_only = false;
pctx->opts->read_only = false;
break;
case Opt_lock_on_read:
rbd_opts->lock_on_read = true;
pctx->opts->lock_on_read = true;
break;
case Opt_exclusive:
rbd_opts->exclusive = true;
pctx->opts->exclusive = true;
break;
case Opt_notrim:
rbd_opts->trim = false;
pctx->opts->trim = false;
break;
default:
/* libceph prints "bad option" msg */
Expand Down Expand Up @@ -1452,7 +1466,7 @@ static void rbd_osd_req_format_write(struct rbd_obj_request *obj_request)
struct ceph_osd_request *osd_req = obj_request->osd_req;

osd_req->r_flags = CEPH_OSD_FLAG_WRITE;
ktime_get_real_ts(&osd_req->r_mtime);
ktime_get_real_ts64(&osd_req->r_mtime);
osd_req->r_data_offset = obj_request->ex.oe_off;
}

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

/*
* Data objects may be stored in a separate pool, but always in
* the same namespace in that pool as the header in its pool.
*/
ceph_oloc_copy(&req->r_base_oloc, &rbd_dev->header_oloc);
req->r_base_oloc.pool = rbd_dev->layout.pool_id;

if (ceph_oid_aprintf(&req->r_base_oid, GFP_NOIO, name_format,
rbd_dev->header.object_prefix, obj_req->ex.oe_objno))
goto err_req;
Expand Down Expand Up @@ -4119,6 +4139,14 @@ static ssize_t rbd_pool_id_show(struct device *dev,
(unsigned long long) rbd_dev->spec->pool_id);
}

static ssize_t rbd_pool_ns_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);

return sprintf(buf, "%s\n", rbd_dev->spec->pool_ns ?: "");
}

static ssize_t rbd_name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
Expand Down Expand Up @@ -4217,6 +4245,7 @@ static DEVICE_ATTR(cluster_fsid, 0444, rbd_cluster_fsid_show, NULL);
static DEVICE_ATTR(config_info, 0400, rbd_config_info_show, NULL);
static DEVICE_ATTR(pool, 0444, rbd_pool_show, NULL);
static DEVICE_ATTR(pool_id, 0444, rbd_pool_id_show, NULL);
static DEVICE_ATTR(pool_ns, 0444, rbd_pool_ns_show, NULL);
static DEVICE_ATTR(name, 0444, rbd_name_show, NULL);
static DEVICE_ATTR(image_id, 0444, rbd_image_id_show, NULL);
static DEVICE_ATTR(refresh, 0200, NULL, rbd_image_refresh);
Expand All @@ -4235,6 +4264,7 @@ static struct attribute *rbd_attrs[] = {
&dev_attr_config_info.attr,
&dev_attr_pool.attr,
&dev_attr_pool_id.attr,
&dev_attr_pool_ns.attr,
&dev_attr_name.attr,
&dev_attr_image_id.attr,
&dev_attr_current_snap.attr,
Expand Down Expand Up @@ -4295,6 +4325,7 @@ static void rbd_spec_free(struct kref *kref)
struct rbd_spec *spec = container_of(kref, struct rbd_spec, kref);

kfree(spec->pool_name);
kfree(spec->pool_ns);
kfree(spec->image_id);
kfree(spec->image_name);
kfree(spec->snap_name);
Expand Down Expand Up @@ -4353,6 +4384,12 @@ static struct rbd_device *__rbd_dev_create(struct rbd_client *rbdc,
rbd_dev->header.data_pool_id = CEPH_NOPOOL;
ceph_oid_init(&rbd_dev->header_oid);
rbd_dev->header_oloc.pool = spec->pool_id;
if (spec->pool_ns) {
WARN_ON(!*spec->pool_ns);
rbd_dev->header_oloc.pool_ns =
ceph_find_or_create_string(spec->pool_ns,
strlen(spec->pool_ns));
}

mutex_init(&rbd_dev->watch_mutex);
rbd_dev->watch_state = RBD_WATCH_STATE_UNREGISTERED;
Expand Down Expand Up @@ -4633,6 +4670,17 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
parent_spec->pool_id = pool_id;
parent_spec->image_id = image_id;
parent_spec->snap_id = snap_id;

/* TODO: support cloning across namespaces */
if (rbd_dev->spec->pool_ns) {
parent_spec->pool_ns = kstrdup(rbd_dev->spec->pool_ns,
GFP_KERNEL);
if (!parent_spec->pool_ns) {
ret = -ENOMEM;
goto out_err;
}
}

rbd_dev->parent_spec = parent_spec;
parent_spec = NULL; /* rbd_dev now owns this */
} else {
Expand Down Expand Up @@ -5146,8 +5194,7 @@ static int rbd_add_parse_args(const char *buf,
const char *mon_addrs;
char *snap_name;
size_t mon_addrs_size;
struct rbd_spec *spec = NULL;
struct rbd_options *rbd_opts = NULL;
struct parse_rbd_opts_ctx pctx = { 0 };
struct ceph_options *copts;
int ret;

Expand All @@ -5171,22 +5218,22 @@ static int rbd_add_parse_args(const char *buf,
goto out_err;
}

spec = rbd_spec_alloc();
if (!spec)
pctx.spec = rbd_spec_alloc();
if (!pctx.spec)
goto out_mem;

spec->pool_name = dup_token(&buf, NULL);
if (!spec->pool_name)
pctx.spec->pool_name = dup_token(&buf, NULL);
if (!pctx.spec->pool_name)
goto out_mem;
if (!*spec->pool_name) {
if (!*pctx.spec->pool_name) {
rbd_warn(NULL, "no pool name provided");
goto out_err;
}

spec->image_name = dup_token(&buf, NULL);
if (!spec->image_name)
pctx.spec->image_name = dup_token(&buf, NULL);
if (!pctx.spec->image_name)
goto out_mem;
if (!*spec->image_name) {
if (!*pctx.spec->image_name) {
rbd_warn(NULL, "no image name provided");
goto out_err;
}
Expand All @@ -5207,40 +5254,40 @@ static int rbd_add_parse_args(const char *buf,
if (!snap_name)
goto out_mem;
*(snap_name + len) = '\0';
spec->snap_name = snap_name;
pctx.spec->snap_name = snap_name;

/* Initialize all rbd options to the defaults */

rbd_opts = kzalloc(sizeof (*rbd_opts), GFP_KERNEL);
if (!rbd_opts)
pctx.opts = kzalloc(sizeof(*pctx.opts), GFP_KERNEL);
if (!pctx.opts)
goto out_mem;

rbd_opts->read_only = RBD_READ_ONLY_DEFAULT;
rbd_opts->queue_depth = RBD_QUEUE_DEPTH_DEFAULT;
rbd_opts->lock_timeout = RBD_LOCK_TIMEOUT_DEFAULT;
rbd_opts->lock_on_read = RBD_LOCK_ON_READ_DEFAULT;
rbd_opts->exclusive = RBD_EXCLUSIVE_DEFAULT;
rbd_opts->trim = RBD_TRIM_DEFAULT;
pctx.opts->read_only = RBD_READ_ONLY_DEFAULT;
pctx.opts->queue_depth = RBD_QUEUE_DEPTH_DEFAULT;
pctx.opts->lock_timeout = RBD_LOCK_TIMEOUT_DEFAULT;
pctx.opts->lock_on_read = RBD_LOCK_ON_READ_DEFAULT;
pctx.opts->exclusive = RBD_EXCLUSIVE_DEFAULT;
pctx.opts->trim = RBD_TRIM_DEFAULT;

copts = ceph_parse_options(options, mon_addrs,
mon_addrs + mon_addrs_size - 1,
parse_rbd_opts_token, rbd_opts);
mon_addrs + mon_addrs_size - 1,
parse_rbd_opts_token, &pctx);
if (IS_ERR(copts)) {
ret = PTR_ERR(copts);
goto out_err;
}
kfree(options);

*ceph_opts = copts;
*opts = rbd_opts;
*rbd_spec = spec;
*opts = pctx.opts;
*rbd_spec = pctx.spec;

return 0;
out_mem:
ret = -ENOMEM;
out_err:
kfree(rbd_opts);
rbd_spec_put(spec);
kfree(pctx.opts);
rbd_spec_put(pctx.spec);
kfree(options);

return ret;
Expand Down Expand Up @@ -5586,8 +5633,10 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
ret = rbd_register_watch(rbd_dev);
if (ret) {
if (ret == -ENOENT)
pr_info("image %s/%s does not exist\n",
pr_info("image %s/%s%s%s does not exist\n",
rbd_dev->spec->pool_name,
rbd_dev->spec->pool_ns ?: "",
rbd_dev->spec->pool_ns ? "/" : "",
rbd_dev->spec->image_name);
goto err_out_format;
}
Expand All @@ -5609,8 +5658,10 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
ret = rbd_spec_fill_names(rbd_dev);
if (ret) {
if (ret == -ENOENT)
pr_info("snap %s/%s@%s does not exist\n",
pr_info("snap %s/%s%s%s@%s does not exist\n",
rbd_dev->spec->pool_name,
rbd_dev->spec->pool_ns ?: "",
rbd_dev->spec->pool_ns ? "/" : "",
rbd_dev->spec->image_name,
rbd_dev->spec->snap_name);
goto err_out_probe;
Expand Down
30 changes: 22 additions & 8 deletions fs/ceph/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ static inline void ceph_set_cached_acl(struct inode *inode,
struct posix_acl *ceph_get_acl(struct inode *inode, int type)
{
int size;
unsigned int retry_cnt = 0;
const char *name;
char *value = NULL;
struct posix_acl *acl;
Expand All @@ -60,6 +61,7 @@ struct posix_acl *ceph_get_acl(struct inode *inode, int type)
BUG();
}

retry:
size = __ceph_getxattr(inode, name, "", 0);
if (size > 0) {
value = kzalloc(size, GFP_NOFS);
Expand All @@ -68,12 +70,22 @@ struct posix_acl *ceph_get_acl(struct inode *inode, int type)
size = __ceph_getxattr(inode, name, value, size);
}

if (size > 0)
if (size == -ERANGE && retry_cnt < 10) {
retry_cnt++;
kfree(value);
value = NULL;
goto retry;
}

if (size > 0) {
acl = posix_acl_from_xattr(&init_user_ns, value, size);
else if (size == -ERANGE || size == -ENODATA || size == 0)
} else if (size == -ENODATA || size == 0) {
acl = NULL;
else
} else {
pr_err_ratelimited("get acl %llx.%llx failed, err=%d\n",
ceph_vinop(inode), size);
acl = ERR_PTR(-EIO);
}

kfree(value);

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

switch (type) {
Expand Down Expand Up @@ -133,7 +146,7 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
if (new_mode != old_mode) {
newattrs.ia_ctime = current_time(inode);
newattrs.ia_mode = new_mode;
newattrs.ia_valid = ATTR_MODE;
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
ret = __ceph_setattr(inode, &newattrs);
if (ret)
goto out_free;
Expand All @@ -142,8 +155,9 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
ret = __ceph_setxattr(inode, name, value, size, 0);
if (ret) {
if (new_mode != old_mode) {
newattrs.ia_ctime = old_ctime;
newattrs.ia_mode = old_mode;
newattrs.ia_valid = ATTR_MODE;
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
__ceph_setattr(inode, &newattrs);
}
goto out_free;
Expand Down Expand Up @@ -171,10 +185,10 @@ int ceph_pre_init_acls(struct inode *dir, umode_t *mode,
return err;

if (acl) {
int ret = posix_acl_equiv_mode(acl, mode);
if (ret < 0)
err = posix_acl_equiv_mode(acl, mode);
if (err < 0)
goto out_err;
if (ret == 0) {
if (err == 0) {
posix_acl_release(acl);
acl = NULL;
}
Expand Down
Loading

0 comments on commit 0a78ac4

Please sign in to comment.