Skip to content

Commit

Permalink
Merge tag 'ceph-for-5.2-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:
 "On the filesystem side we have:

   - a fix to enforce quotas set above the mount point (Luis Henriques)

   - support for exporting snapshots through NFS (Zheng Yan)

   - proper statx implementation (Jeff Layton). statx flags are mapped
     to MDS caps, with AT_STATX_{DONT,FORCE}_SYNC taken into account.

   - some follow-up dentry name handling fixes, in particular
     elimination of our hand-rolled helper and the switch to __getname()
     as suggested by Al (Jeff Layton)

   - a set of MDS client cleanups in preparation for async MDS requests
     in the future (Jeff Layton)

   - a fix to sync the filesystem before remounting (Jeff Layton)

  On the rbd side, work is on-going on object-map and fast-diff image
  features"

* tag 'ceph-for-5.2-rc1' of git://github.com/ceph/ceph-client: (29 commits)
  ceph: flush dirty inodes before proceeding with remount
  ceph: fix unaligned access in ceph_send_cap_releases
  libceph: make ceph_pr_addr take an struct ceph_entity_addr pointer
  libceph: fix unaligned accesses in ceph_entity_addr handling
  rbd: don't assert on writes to snapshots
  rbd: client_mutex is never nested
  ceph: print inode number in __caps_issued_mask debugging messages
  ceph: just call get_session in __ceph_lookup_mds_session
  ceph: simplify arguments and return semantics of try_get_cap_refs
  ceph: fix comment over ceph_drop_caps_for_unlink
  ceph: move wait for mds request into helper function
  ceph: have ceph_mdsc_do_request call ceph_mdsc_submit_request
  ceph: after an MDS request, do callback and completions
  ceph: use pathlen values returned by set_request_path_attr
  ceph: use __getname/__putname in ceph_mdsc_build_path
  ceph: use ceph_mdsc_build_path instead of clone_dentry_name
  ceph: fix potential use-after-free in ceph_mdsc_build_path
  ceph: dump granular cap info in "caps" debugfs file
  ceph: make iterate_session_caps a public symbol
  ceph: fix NULL pointer deref when debugging is enabled
  ...
  • Loading branch information
torvalds committed May 16, 2019
2 parents 2c45e7f + 00abf69 commit 1d9d7cb
Show file tree
Hide file tree
Showing 21 changed files with 845 additions and 351 deletions.
24 changes: 14 additions & 10 deletions drivers/block/rbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,7 @@ static struct rbd_client *rbd_get_client(struct ceph_options *ceph_opts)
struct rbd_client *rbdc;
int ret;

mutex_lock_nested(&client_mutex, SINGLE_DEPTH_NESTING);
mutex_lock(&client_mutex);
rbdc = rbd_client_find(ceph_opts);
if (rbdc) {
ceph_destroy_options(ceph_opts);
Expand Down Expand Up @@ -1326,7 +1326,7 @@ static void rbd_obj_zero_range(struct rbd_obj_request *obj_req, u32 off,
zero_bvecs(&obj_req->bvec_pos, off, bytes);
break;
default:
rbd_assert(0);
BUG();
}
}

Expand Down Expand Up @@ -1581,7 +1581,7 @@ static void rbd_obj_request_destroy(struct kref *kref)
kfree(obj_request->bvec_pos.bvecs);
break;
default:
rbd_assert(0);
BUG();
}

kfree(obj_request->img_extents);
Expand Down Expand Up @@ -1781,7 +1781,7 @@ static void rbd_osd_req_setup_data(struct rbd_obj_request *obj_req, u32 which)
&obj_req->bvec_pos);
break;
default:
rbd_assert(0);
BUG();
}
}

Expand Down Expand Up @@ -2036,7 +2036,7 @@ static int __rbd_img_fill_request(struct rbd_img_request *img_req)
ret = rbd_obj_setup_zeroout(obj_req);
break;
default:
rbd_assert(0);
BUG();
}
if (ret < 0)
return ret;
Expand Down Expand Up @@ -2383,7 +2383,7 @@ static int rbd_obj_read_from_parent(struct rbd_obj_request *obj_req)
&obj_req->bvec_pos);
break;
default:
rbd_assert(0);
BUG();
}
} else {
ret = rbd_img_fill_from_bvecs(child_img_req,
Expand Down Expand Up @@ -2515,7 +2515,7 @@ static int rbd_obj_issue_copyup_ops(struct rbd_obj_request *obj_req, u32 bytes)
num_osd_ops += count_zeroout_ops(obj_req);
break;
default:
rbd_assert(0);
BUG();
}

obj_req->osd_req = rbd_osd_req_create(obj_req, num_osd_ops);
Expand All @@ -2542,7 +2542,7 @@ static int rbd_obj_issue_copyup_ops(struct rbd_obj_request *obj_req, u32 bytes)
__rbd_obj_setup_zeroout(obj_req, which);
break;
default:
rbd_assert(0);
BUG();
}

ret = ceph_osdc_alloc_messages(obj_req->osd_req, GFP_NOIO);
Expand Down Expand Up @@ -3842,8 +3842,12 @@ static void rbd_queue_workfn(struct work_struct *work)
goto err_rq;
}

rbd_assert(op_type == OBJ_OP_READ ||
rbd_dev->spec->snap_id == CEPH_NOSNAP);
if (op_type != OBJ_OP_READ && rbd_dev->spec->snap_id != CEPH_NOSNAP) {
rbd_warn(rbd_dev, "%s on read-only snapshot",
obj_op_name(op_type));
result = -EIO;
goto err;
}

/*
* Quit early if the mapped snapshot no longer exists. It's
Expand Down
93 changes: 37 additions & 56 deletions fs/ceph/caps.c
Original file line number Diff line number Diff line change
Expand Up @@ -892,8 +892,8 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
int have = ci->i_snap_caps;

if ((have & mask) == mask) {
dout("__ceph_caps_issued_mask %p snap issued %s"
" (mask %s)\n", &ci->vfs_inode,
dout("__ceph_caps_issued_mask ino 0x%lx snap issued %s"
" (mask %s)\n", ci->vfs_inode.i_ino,
ceph_cap_string(have),
ceph_cap_string(mask));
return 1;
Expand All @@ -904,8 +904,8 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
if (!__cap_is_valid(cap))
continue;
if ((cap->issued & mask) == mask) {
dout("__ceph_caps_issued_mask %p cap %p issued %s"
" (mask %s)\n", &ci->vfs_inode, cap,
dout("__ceph_caps_issued_mask ino 0x%lx cap %p issued %s"
" (mask %s)\n", ci->vfs_inode.i_ino, cap,
ceph_cap_string(cap->issued),
ceph_cap_string(mask));
if (touch)
Expand All @@ -916,8 +916,8 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
/* does a combination of caps satisfy mask? */
have |= cap->issued;
if ((have & mask) == mask) {
dout("__ceph_caps_issued_mask %p combo issued %s"
" (mask %s)\n", &ci->vfs_inode,
dout("__ceph_caps_issued_mask ino 0x%lx combo issued %s"
" (mask %s)\n", ci->vfs_inode.i_ino,
ceph_cap_string(cap->issued),
ceph_cap_string(mask));
if (touch) {
Expand Down Expand Up @@ -2257,8 +2257,6 @@ int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
if (datasync)
goto out;

inode_lock(inode);

dirty = try_flush_caps(inode, &flush_tid);
dout("fsync dirty caps are %s\n", ceph_cap_string(dirty));

Expand All @@ -2273,7 +2271,6 @@ int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
ret = wait_event_interruptible(ci->i_cap_wq,
caps_are_flushed(inode, flush_tid));
}
inode_unlock(inode);
out:
dout("fsync %p%s result=%d\n", inode, datasync ? " datasync" : "", ret);
return ret;
Expand Down Expand Up @@ -2528,9 +2525,14 @@ static void __take_cap_refs(struct ceph_inode_info *ci, int got,
* to (when applicable), and check against max_size here as well.
* Note that caller is responsible for ensuring max_size increases are
* requested from the MDS.
*
* Returns 0 if caps were not able to be acquired (yet), a 1 if they were,
* or a negative error code.
*
* FIXME: how does a 0 return differ from -EAGAIN?
*/
static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want,
loff_t endoff, bool nonblock, int *got, int *err)
loff_t endoff, bool nonblock, int *got)
{
struct inode *inode = &ci->vfs_inode;
struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
Expand All @@ -2550,8 +2552,7 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want,
if ((file_wanted & need) != need) {
dout("try_get_cap_refs need %s file_wanted %s, EBADF\n",
ceph_cap_string(need), ceph_cap_string(file_wanted));
*err = -EBADF;
ret = 1;
ret = -EBADF;
goto out_unlock;
}

Expand All @@ -2572,10 +2573,8 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want,
if (endoff >= 0 && endoff > (loff_t)ci->i_max_size) {
dout("get_cap_refs %p endoff %llu > maxsize %llu\n",
inode, endoff, ci->i_max_size);
if (endoff > ci->i_requested_max_size) {
*err = -EAGAIN;
ret = 1;
}
if (endoff > ci->i_requested_max_size)
ret = -EAGAIN;
goto out_unlock;
}
/*
Expand Down Expand Up @@ -2610,8 +2609,7 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want,
* task isn't in TASK_RUNNING state
*/
if (nonblock) {
*err = -EAGAIN;
ret = 1;
ret = -EAGAIN;
goto out_unlock;
}

Expand Down Expand Up @@ -2640,8 +2638,7 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want,
if (session_readonly) {
dout("get_cap_refs %p needed %s but mds%d readonly\n",
inode, ceph_cap_string(need), ci->i_auth_cap->mds);
*err = -EROFS;
ret = 1;
ret = -EROFS;
goto out_unlock;
}

Expand All @@ -2650,16 +2647,14 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want,
if (READ_ONCE(mdsc->fsc->mount_state) ==
CEPH_MOUNT_SHUTDOWN) {
dout("get_cap_refs %p forced umount\n", inode);
*err = -EIO;
ret = 1;
ret = -EIO;
goto out_unlock;
}
mds_wanted = __ceph_caps_mds_wanted(ci, false);
if (need & ~(mds_wanted & need)) {
dout("get_cap_refs %p caps were dropped"
" (session killed?)\n", inode);
*err = -ESTALE;
ret = 1;
ret = -ESTALE;
goto out_unlock;
}
if (!(file_wanted & ~mds_wanted))
Expand Down Expand Up @@ -2710,23 +2705,16 @@ static void check_max_size(struct inode *inode, loff_t endoff)
int ceph_try_get_caps(struct ceph_inode_info *ci, int need, int want,
bool nonblock, int *got)
{
int ret, err = 0;
int ret;

BUG_ON(need & ~CEPH_CAP_FILE_RD);
BUG_ON(want & ~(CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO|CEPH_CAP_FILE_SHARED));
ret = ceph_pool_perm_check(ci, need);
if (ret < 0)
return ret;

ret = try_get_cap_refs(ci, need, want, 0, nonblock, got, &err);
if (ret) {
if (err == -EAGAIN) {
ret = 0;
} else if (err < 0) {
ret = err;
}
}
return ret;
ret = try_get_cap_refs(ci, need, want, 0, nonblock, got);
return ret == -EAGAIN ? 0 : ret;
}

/*
Expand All @@ -2737,7 +2725,7 @@ int ceph_try_get_caps(struct ceph_inode_info *ci, int need, int want,
int ceph_get_caps(struct ceph_inode_info *ci, int need, int want,
loff_t endoff, int *got, struct page **pinned_page)
{
int _got, ret, err = 0;
int _got, ret;

ret = ceph_pool_perm_check(ci, need);
if (ret < 0)
Expand All @@ -2747,21 +2735,19 @@ int ceph_get_caps(struct ceph_inode_info *ci, int need, int want,
if (endoff > 0)
check_max_size(&ci->vfs_inode, endoff);

err = 0;
_got = 0;
ret = try_get_cap_refs(ci, need, want, endoff,
false, &_got, &err);
if (ret) {
if (err == -EAGAIN)
continue;
if (err < 0)
ret = err;
} else {
false, &_got);
if (ret == -EAGAIN) {
continue;
} else if (!ret) {
int err;

DEFINE_WAIT_FUNC(wait, woken_wake_function);
add_wait_queue(&ci->i_cap_wq, &wait);

while (!try_get_cap_refs(ci, need, want, endoff,
true, &_got, &err)) {
while (!(err = try_get_cap_refs(ci, need, want, endoff,
true, &_got))) {
if (signal_pending(current)) {
ret = -ERESTARTSYS;
break;
Expand All @@ -2770,19 +2756,14 @@ int ceph_get_caps(struct ceph_inode_info *ci, int need, int want,
}

remove_wait_queue(&ci->i_cap_wq, &wait);

if (err == -EAGAIN)
continue;
if (err < 0)
ret = err;
}
if (ret < 0) {
if (err == -ESTALE) {
/* session was killed, try renew caps */
ret = ceph_renew_caps(&ci->vfs_inode);
if (ret == 0)
continue;
}
if (ret == -ESTALE) {
/* session was killed, try renew caps */
ret = ceph_renew_caps(&ci->vfs_inode);
if (ret == 0)
continue;
return ret;
}

Expand Down Expand Up @@ -4099,7 +4080,7 @@ void ceph_put_fmode(struct ceph_inode_info *ci, int fmode)
}

/*
* For a soon-to-be unlinked file, drop the AUTH_RDCACHE caps. If it
* For a soon-to-be unlinked file, drop the LINK caps. If it
* looks like the link count will hit 0, drop any other caps (other
* than PIN) we don't specifically want (due to the file still being
* open).
Expand Down
40 changes: 35 additions & 5 deletions fs/ceph/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static int mdsmap_show(struct seq_file *s, void *p)
struct ceph_entity_addr *addr = &mdsmap->m_info[i].addr;
int state = mdsmap->m_info[i].state;
seq_printf(s, "\tmds%d\t%s\t(%s)\n", i,
ceph_pr_addr(&addr->in_addr),
ceph_pr_addr(addr),
ceph_mds_state_name(state));
}
return 0;
Expand Down Expand Up @@ -88,7 +88,7 @@ static int mdsc_show(struct seq_file *s, void *p)
req->r_dentry,
path ? path : "");
spin_unlock(&req->r_dentry->d_lock);
kfree(path);
ceph_mdsc_free_path(path, pathlen);
} else if (req->r_path1) {
seq_printf(s, " #%llx/%s", req->r_ino1.ino,
req->r_path1);
Expand All @@ -108,7 +108,7 @@ static int mdsc_show(struct seq_file *s, void *p)
req->r_old_dentry,
path ? path : "");
spin_unlock(&req->r_old_dentry->d_lock);
kfree(path);
ceph_mdsc_free_path(path, pathlen);
} else if (req->r_path2 && req->r_op != CEPH_MDS_OP_SYMLINK) {
if (req->r_ino2.ino)
seq_printf(s, " #%llx/%s", req->r_ino2.ino,
Expand All @@ -124,18 +124,48 @@ static int mdsc_show(struct seq_file *s, void *p)
return 0;
}

static int caps_show_cb(struct inode *inode, struct ceph_cap *cap, void *p)
{
struct seq_file *s = p;

seq_printf(s, "0x%-17lx%-17s%-17s\n", inode->i_ino,
ceph_cap_string(cap->issued),
ceph_cap_string(cap->implemented));
return 0;
}

static int caps_show(struct seq_file *s, void *p)
{
struct ceph_fs_client *fsc = s->private;
int total, avail, used, reserved, min;
struct ceph_mds_client *mdsc = fsc->mdsc;
int total, avail, used, reserved, min, i;

ceph_reservation_status(fsc, &total, &avail, &used, &reserved, &min);
seq_printf(s, "total\t\t%d\n"
"avail\t\t%d\n"
"used\t\t%d\n"
"reserved\t%d\n"
"min\t%d\n",
"min\t\t%d\n\n",
total, avail, used, reserved, min);
seq_printf(s, "ino issued implemented\n");
seq_printf(s, "-----------------------------------------------\n");

mutex_lock(&mdsc->mutex);
for (i = 0; i < mdsc->max_sessions; i++) {
struct ceph_mds_session *session;

session = __ceph_lookup_mds_session(mdsc, i);
if (!session)
continue;
mutex_unlock(&mdsc->mutex);
mutex_lock(&session->s_mutex);
ceph_iterate_session_caps(session, caps_show_cb, s);
mutex_unlock(&session->s_mutex);
ceph_put_mds_session(session);
mutex_lock(&mdsc->mutex);
}
mutex_unlock(&mdsc->mutex);

return 0;
}

Expand Down
Loading

0 comments on commit 1d9d7cb

Please sign in to comment.