librbd: fix snap_exists API overflow issue

The original one may overflow and thus not be safe.

Fixes: #14129
Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
This commit is contained in:
xiexingguo 2015-12-20 16:19:59 +08:00
parent a2befde278
commit c97b1a68ae
5 changed files with 54 additions and 5 deletions

View File

@ -206,7 +206,9 @@ public:
/* snapshots */
int snap_list(std::vector<snap_info_t>& snaps);
bool snap_exists(const char *snapname);
/* DEPRECATED; use snap_exists2 */
bool snap_exists(const char *snapname) __attribute__ ((deprecated));
int snap_exists2(const char *snapname, bool *exists);
int snap_create(const char *snapname);
int snap_remove(const char *snapname);
int snap_rollback(const char *snap_name);

View File

@ -2223,7 +2223,7 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
return 0;
}
bool snap_exists(ImageCtx *ictx, const char *snap_name)
int snap_exists(ImageCtx *ictx, const char *snap_name, bool *exists)
{
ldout(ictx->cct, 20) << "snap_exists " << ictx << " " << snap_name << dendl;
@ -2232,7 +2232,8 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
return r;
RWLock::RLocker l(ictx->snap_lock);
return ictx->get_snap_id(snap_name) != CEPH_NOSNAP;
*exists = ictx->get_snap_id(snap_name) != CEPH_NOSNAP;
return 0;
}
int snap_rollback(ImageCtx *ictx, const char *snap_name,

View File

@ -126,7 +126,7 @@ namespace librbd {
int snap_create(ImageCtx *ictx, const char *snap_name);
void snap_create_helper(ImageCtx *ictx, Context* ctx, const char *snap_name);
int snap_list(ImageCtx *ictx, std::vector<snap_info_t>& snaps);
bool snap_exists(ImageCtx *ictx, const char *snap_name);
int snap_exists(ImageCtx *ictx, const char *snap_name, bool *exists);
int snap_rollback(ImageCtx *ictx, const char *snap_name,
ProgressContext& prog_ctx);
int snap_remove(ImageCtx *ictx, const char *snap_name);

View File

@ -816,7 +816,27 @@ namespace librbd {
bool Image::snap_exists(const char *snap_name)
{
ImageCtx *ictx = (ImageCtx *)ctx;
return librbd::snap_exists(ictx, snap_name);
tracepoint(librbd, snap_exists_enter, ictx, ictx->name.c_str(),
ictx->snap_name.c_str(), ictx->read_only, snap_name);
bool exists;
int r = librbd::snap_exists(ictx, snap_name, &exists);
tracepoint(librbd, snap_exists_exit, r, exists);
if (r < 0) {
// lie to caller since we don't know the real answer yet.
return false;
}
return exists;
}
// A safer verion of snap_exists.
int Image::snap_exists2(const char *snap_name, bool *exists)
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_exists_enter, ictx, ictx->name.c_str(),
ictx->snap_name.c_str(), ictx->read_only, snap_name);
int r = librbd::snap_exists(ictx, snap_name, exists);
tracepoint(librbd, snap_exists_exit, r, *exists);
return r;
}
int Image::snap_set(const char *snap_name)

View File

@ -1217,6 +1217,32 @@ TRACEPOINT_EVENT(librbd, snap_is_protected_exit,
)
)
TRACEPOINT_EVENT(librbd, snap_exists_enter,
TP_ARGS(
void*, imagectx,
const char*, name,
const char*, snap_name,
char, read_only,
const char*, snap_name_to_check),
TP_FIELDS(
ctf_integer_hex(void*, imagectx, imagectx)
ctf_string(name, name)
ctf_string(snap_name, snap_name)
ctf_integer(char, read_only, read_only)
ctf_string(snap_name_to_check, snap_name_to_check)
)
)
TRACEPOINT_EVENT(librbd, snap_exists_exit,
TP_ARGS(
int, retval,
int, exists),
TP_FIELDS(
ctf_integer(int, retval, retval)
ctf_integer(int, exists, exists)
)
)
TRACEPOINT_EVENT(librbd, snap_set_enter,
TP_ARGS(
void*, imagectx,