Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 176558
b: refs/heads/master
c: 1d0f3ce
h: refs/heads/master
v: v3
  • Loading branch information
Mike Snitzer authored and Alasdair G Kergon committed Dec 10, 2009
1 parent fb80eeb commit bdb363b
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 12fc0f49dc994d8d90dcf3df13f5b1ee5441288d
refs/heads/master: 1d0f3ce83200edc5d43723c77c62b09ad6560294
70 changes: 57 additions & 13 deletions trunk/drivers/md/dm-ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,8 +523,6 @@ static int list_versions(struct dm_ioctl *param, size_t param_size)
return 0;
}



static int check_name(const char *name)
{
if (strchr(name, '/')) {
Expand All @@ -535,6 +533,40 @@ static int check_name(const char *name)
return 0;
}

/*
* On successful return, the caller must not attempt to acquire
* _hash_lock without first calling dm_table_put, because dm_table_destroy
* waits for this dm_table_put and could be called under this lock.
*/
static struct dm_table *dm_get_inactive_table(struct mapped_device *md)
{
struct hash_cell *hc;
struct dm_table *table = NULL;

down_read(&_hash_lock);
hc = dm_get_mdptr(md);
if (!hc || hc->md != md) {
DMWARN("device has been removed from the dev hash table.");
goto out;
}

table = hc->new_map;
if (table)
dm_table_get(table);

out:
up_read(&_hash_lock);

return table;
}

static struct dm_table *dm_get_live_or_inactive_table(struct mapped_device *md,
struct dm_ioctl *param)
{
return (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) ?
dm_get_inactive_table(md) : dm_get_live_table(md);
}

/*
* Fills in a dm_ioctl structure, ready for sending back to
* userland.
Expand All @@ -559,18 +591,30 @@ static int __dev_status(struct mapped_device *md, struct dm_ioctl *param)
*/
param->open_count = dm_open_count(md);

if (get_disk_ro(disk))
param->flags |= DM_READONLY_FLAG;

param->event_nr = dm_get_event_nr(md);
param->target_count = 0;

table = dm_get_live_table(md);
if (table) {
param->flags |= DM_ACTIVE_PRESENT_FLAG;
param->target_count = dm_table_get_num_targets(table);
if (!(param->flags & DM_QUERY_INACTIVE_TABLE_FLAG)) {
if (get_disk_ro(disk))
param->flags |= DM_READONLY_FLAG;
param->target_count = dm_table_get_num_targets(table);
}
dm_table_put(table);
} else
param->target_count = 0;

param->flags |= DM_ACTIVE_PRESENT_FLAG;
}

if (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) {
table = dm_get_inactive_table(md);
if (table) {
if (!(dm_table_get_mode(table) & FMODE_WRITE))
param->flags |= DM_READONLY_FLAG;
param->target_count = dm_table_get_num_targets(table);
dm_table_put(table);
}
}

return 0;
}
Expand Down Expand Up @@ -993,7 +1037,7 @@ static int dev_wait(struct dm_ioctl *param, size_t param_size)
if (r)
goto out;

table = dm_get_live_table(md);
table = dm_get_live_or_inactive_table(md, param);
if (table) {
retrieve_status(table, param, param_size);
dm_table_put(table);
Expand Down Expand Up @@ -1226,7 +1270,7 @@ static int table_deps(struct dm_ioctl *param, size_t param_size)
if (r)
goto out;

table = dm_get_live_table(md);
table = dm_get_live_or_inactive_table(md, param);
if (table) {
retrieve_deps(table, param, param_size);
dm_table_put(table);
Expand Down Expand Up @@ -1255,13 +1299,13 @@ static int table_status(struct dm_ioctl *param, size_t param_size)
if (r)
goto out;

table = dm_get_live_table(md);
table = dm_get_live_or_inactive_table(md, param);
if (table) {
retrieve_status(table, param, param_size);
dm_table_put(table);
}

out:
out:
dm_put(md);
return r;
}
Expand Down
13 changes: 10 additions & 3 deletions trunk/include/linux/dm-ioctl.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001 - 2003 Sistina Software (UK) Limited.
* Copyright (C) 2004 - 2005 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004 - 2009 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
*/
Expand Down Expand Up @@ -266,9 +266,9 @@ enum {
#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)

#define DM_VERSION_MAJOR 4
#define DM_VERSION_MINOR 15
#define DM_VERSION_MINOR 16
#define DM_VERSION_PATCHLEVEL 0
#define DM_VERSION_EXTRA "-ioctl (2009-04-01)"
#define DM_VERSION_EXTRA "-ioctl (2009-11-05)"

/* Status bits */
#define DM_READONLY_FLAG (1 << 0) /* In/Out */
Expand Down Expand Up @@ -309,4 +309,11 @@ enum {
*/
#define DM_NOFLUSH_FLAG (1 << 11) /* In */

/*
* If set, any table information returned will relate to the inactive
* table instead of the live one. Always check DM_INACTIVE_PRESENT_FLAG
* is set before using the data returned.
*/
#define DM_QUERY_INACTIVE_TABLE_FLAG (1 << 12) /* In */

#endif /* _LINUX_DM_IOCTL_H */

0 comments on commit bdb363b

Please sign in to comment.