Re: [PATCH 001 of 7] md: Support 'external' metadata for md arrays.

2007-12-25 Thread Andrew Morton
On Fri, 14 Dec 2007 17:26:08 +1100 NeilBrown <[EMAIL PROTECTED]> wrote:

> + if (strncmp(buf, "external:", 9) == 0) {
> + int namelen = len-9;
> + if (namelen >= sizeof(mddev->metadata_type))
> + namelen = sizeof(mddev->metadata_type)-1;
> + strncpy(mddev->metadata_type, buf+9, namelen);
> + mddev->metadata_type[namelen] = 0;
> + if (namelen && mddev->metadata_type[namelen-1] == '\n')
> + mddev->metadata_type[--namelen] = 0;
> + mddev->persistent = 0;
> + mddev->external = 1;

size_t would be a more appropriate type for `namelen'.
-
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 001 of 7] md: Support 'external' metadata for md arrays.

2007-12-13 Thread NeilBrown

- Add a state flag 'external' to indicate that the metadata is managed
  externally (by user-space) so important changes need to be 
  left of user-space to handle.
  Alternates are non-persistant ('none') where there is no stable metadata -
  after the  array is stopped there is no record of it's status - and 
  internal which can be version 0.90 or version 1.x
  These are selected by writing to the 'metadata' attribute.



- move the updating of superblocks (sync_sbs) to after we have checked if
  there are any superblocks or not.

- New array state 'write_pending'.  This means that the metadata records
  the array as 'clean', but a write has been requested, so the metadata has
  to be updated to record a 'dirty' array before the write can continue.
  This change is reported to md by writing 'active' to the array_state
  attribute.

- tidy up marking of sb_dirty:
   - don't set sb_dirty when resync finishes as md_check_recovery
 calls md_update_sb when the sync thread finishes anyway.
   - Don't set sb_dirty in multipath_run as the array might not be dirty.
   - don't mark superblock dirty when switching to 'clean' if there
 is no internal superblock (if external, userspace can choose to
 update the superblock whenever it chooses to).

Signed-off-by: Neil Brown <[EMAIL PROTECTED]>

### Diffstat output
 ./drivers/md/md.c   |   77 +---
 ./include/linux/raid/md_k.h |3 +
 2 files changed, 61 insertions(+), 19 deletions(-)

diff .prev/drivers/md/md.c ./drivers/md/md.c
--- .prev/drivers/md/md.c   2007-12-14 16:07:51.0 +1100
+++ ./drivers/md/md.c   2007-12-14 16:08:28.0 +1100
@@ -778,7 +778,8 @@ static int super_90_validate(mddev_t *md
mddev->major_version = 0;
mddev->minor_version = sb->minor_version;
mddev->patch_version = sb->patch_version;
-   mddev->persistent = ! sb->not_persistent;
+   mddev->persistent = 1;
+   mddev->external = 0;
mddev->chunk_size = sb->chunk_size;
mddev->ctime = sb->ctime;
mddev->utime = sb->utime;
@@ -904,7 +905,7 @@ static void super_90_sync(mddev_t *mddev
sb->size  = mddev->size;
sb->raid_disks = mddev->raid_disks;
sb->md_minor = mddev->md_minor;
-   sb->not_persistent = !mddev->persistent;
+   sb->not_persistent = 0;
sb->utime = mddev->utime;
sb->state = 0;
sb->events_hi = (mddev->events>>32);
@@ -1158,6 +1159,7 @@ static int super_1_validate(mddev_t *mdd
mddev->major_version = 1;
mddev->patch_version = 0;
mddev->persistent = 1;
+   mddev->external = 0;
mddev->chunk_size = le32_to_cpu(sb->chunksize) << 9;
mddev->ctime = le64_to_cpu(sb->ctime) & ((1ULL << 32)-1);
mddev->utime = le64_to_cpu(sb->utime) & ((1ULL << 32)-1);
@@ -1699,18 +1701,20 @@ repeat:
MD_BUG();
mddev->events --;
}
-   sync_sbs(mddev, nospares);
 
/*
 * do not write anything to disk if using
 * nonpersistent superblocks
 */
if (!mddev->persistent) {
-   clear_bit(MD_CHANGE_PENDING, &mddev->flags);
+   if (!mddev->external)
+   clear_bit(MD_CHANGE_PENDING, &mddev->flags);
+
spin_unlock_irq(&mddev->write_lock);
wake_up(&mddev->sb_wait);
return;
}
+   sync_sbs(mddev, nospares);
spin_unlock_irq(&mddev->write_lock);
 
dprintk(KERN_INFO 
@@ -2430,6 +2434,8 @@ array_state_show(mddev_t *mddev, char *p
case 0:
if (mddev->in_sync)
st = clean;
+   else if (test_bit(MD_CHANGE_CLEAN, &mddev->flags))
+   st = write_pending;
else if (mddev->safemode)
st = active_idle;
else
@@ -2460,11 +2466,9 @@ array_state_store(mddev_t *mddev, const 
break;
case clear:
/* stopping an active array */
-   if (mddev->pers) {
-   if (atomic_read(&mddev->active) > 1)
-   return -EBUSY;
-   err = do_md_stop(mddev, 0);
-   }
+   if (atomic_read(&mddev->active) > 1)
+   return -EBUSY;
+   err = do_md_stop(mddev, 0);
break;
case inactive:
/* stopping an active array */
@@ -2472,7 +2476,8 @@ array_state_store(mddev_t *mddev, const 
if (atomic_read(&mddev->active) > 1)
return -EBUSY;
err = do_md_stop(mddev, 2);
-   }
+   } else
+   err = 0; /* already