Commit 8d49a775 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-2.6.39/drivers' of git://git.kernel.dk/linux-2.6-block

* 'for-2.6.39/drivers' of git://git.kernel.dk/linux-2.6-block: (122 commits)
  cciss: fix lost command issue
  drbd: need include for bitops functions declarations
  Revert "cciss: Add missing allocation in scsi_cmd_stack_setup and  corresponding deallocation"
  cciss: fix missed command status value CMD_UNABORTABLE
  cciss: remove unnecessary casts
  cciss: Mask off error bits of c->busaddr in cmd_special_free when calling pci_free_consistent
  cciss: Inform controller we are using 32-bit tags.
  cciss: hoist tag masking out of loop
  cciss: Add missing allocation in scsi_cmd_stack_setup and  corresponding deallocation
  cciss: export resettable host attribute
  drbd: drop code present under #ifdef which is relevant to 2.6.28 and below
  drbd: Fixed handling of read errors on a 'VerifyS' node
  drbd: Fixed handling of read errors on a 'VerifyT' node
  drbd: Implemented real timeout checking for request processing time
  drbd: Remove unused function atodb_endio()
  drbd: improve log message if received sector offset exceeds local capacity
  drbd: kill dead code
  drbd: don't BUG_ON, if bio_add_page of a single page to an empty bio fails
  drbd: Removed left over, now wrong comments
  drbd: serialize admin requests for new verify run with pending bitmap io
  ...
parents 93567c43 1ddd5049
...@@ -59,3 +59,15 @@ Kernel Version: 2.6.31 ...@@ -59,3 +59,15 @@ Kernel Version: 2.6.31
Contact: iss_storagedev@hp.com Contact: iss_storagedev@hp.com
Description: Displays the usage count (number of opens) of logical drive Y Description: Displays the usage count (number of opens) of logical drive Y
of controller X. of controller X.
Where: /sys/bus/pci/devices/<dev>/ccissX/resettable
Date: February 2011
Kernel Version: 2.6.38
Contact: iss_storagedev@hp.com
Description: Value of 1 indicates the controller can honor the reset_devices
kernel parameter. Value of 0 indicates reset_devices cannot be
honored. This is to allow, for example, kexec tools to be able
to warn the user if they designate an unresettable device as
a dump device, as kdump requires resetting the device in order
to work reliably.
...@@ -193,7 +193,7 @@ static int __devinit cciss_find_cfg_addrs(struct pci_dev *pdev, ...@@ -193,7 +193,7 @@ static int __devinit cciss_find_cfg_addrs(struct pci_dev *pdev,
u64 *cfg_offset); u64 *cfg_offset);
static int __devinit cciss_pci_find_memory_BAR(struct pci_dev *pdev, static int __devinit cciss_pci_find_memory_BAR(struct pci_dev *pdev,
unsigned long *memory_bar); unsigned long *memory_bar);
static inline u32 cciss_tag_discard_error_bits(ctlr_info_t *h, u32 tag);
/* performant mode helper functions */ /* performant mode helper functions */
static void calc_bucket_map(int *bucket, int num_buckets, int nsgs, static void calc_bucket_map(int *bucket, int num_buckets, int nsgs,
...@@ -231,7 +231,7 @@ static const struct block_device_operations cciss_fops = { ...@@ -231,7 +231,7 @@ static const struct block_device_operations cciss_fops = {
*/ */
static void set_performant_mode(ctlr_info_t *h, CommandList_struct *c) static void set_performant_mode(ctlr_info_t *h, CommandList_struct *c)
{ {
if (likely(h->transMethod == CFGTBL_Trans_Performant)) if (likely(h->transMethod & CFGTBL_Trans_Performant))
c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1); c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1);
} }
...@@ -556,6 +556,44 @@ static void __devinit cciss_procinit(ctlr_info_t *h) ...@@ -556,6 +556,44 @@ static void __devinit cciss_procinit(ctlr_info_t *h)
#define to_hba(n) container_of(n, struct ctlr_info, dev) #define to_hba(n) container_of(n, struct ctlr_info, dev)
#define to_drv(n) container_of(n, drive_info_struct, dev) #define to_drv(n) container_of(n, drive_info_struct, dev)
/* List of controllers which cannot be reset on kexec with reset_devices */
static u32 unresettable_controller[] = {
0x324a103C, /* Smart Array P712m */
0x324b103C, /* SmartArray P711m */
0x3223103C, /* Smart Array P800 */
0x3234103C, /* Smart Array P400 */
0x3235103C, /* Smart Array P400i */
0x3211103C, /* Smart Array E200i */
0x3212103C, /* Smart Array E200 */
0x3213103C, /* Smart Array E200i */
0x3214103C, /* Smart Array E200i */
0x3215103C, /* Smart Array E200i */
0x3237103C, /* Smart Array E500 */
0x323D103C, /* Smart Array P700m */
0x409C0E11, /* Smart Array 6400 */
0x409D0E11, /* Smart Array 6400 EM */
};
static int ctlr_is_resettable(struct ctlr_info *h)
{
int i;
for (i = 0; i < ARRAY_SIZE(unresettable_controller); i++)
if (unresettable_controller[i] == h->board_id)
return 0;
return 1;
}
static ssize_t host_show_resettable(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct ctlr_info *h = to_hba(dev);
return snprintf(buf, 20, "%d\n", ctlr_is_resettable(h));
}
static DEVICE_ATTR(resettable, S_IRUGO, host_show_resettable, NULL);
static ssize_t host_store_rescan(struct device *dev, static ssize_t host_store_rescan(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
...@@ -741,6 +779,7 @@ static DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL); ...@@ -741,6 +779,7 @@ static DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL);
static struct attribute *cciss_host_attrs[] = { static struct attribute *cciss_host_attrs[] = {
&dev_attr_rescan.attr, &dev_attr_rescan.attr,
&dev_attr_resettable.attr,
NULL NULL
}; };
...@@ -973,8 +1012,8 @@ static void cmd_special_free(ctlr_info_t *h, CommandList_struct *c) ...@@ -973,8 +1012,8 @@ static void cmd_special_free(ctlr_info_t *h, CommandList_struct *c)
temp64.val32.upper = c->ErrDesc.Addr.upper; temp64.val32.upper = c->ErrDesc.Addr.upper;
pci_free_consistent(h->pdev, sizeof(ErrorInfo_struct), pci_free_consistent(h->pdev, sizeof(ErrorInfo_struct),
c->err_info, (dma_addr_t) temp64.val); c->err_info, (dma_addr_t) temp64.val);
pci_free_consistent(h->pdev, sizeof(CommandList_struct), pci_free_consistent(h->pdev, sizeof(CommandList_struct), c,
c, (dma_addr_t) c->busaddr); (dma_addr_t) cciss_tag_discard_error_bits(h, (u32) c->busaddr));
} }
static inline ctlr_info_t *get_host(struct gendisk *disk) static inline ctlr_info_t *get_host(struct gendisk *disk)
...@@ -1490,8 +1529,7 @@ static int cciss_bigpassthru(ctlr_info_t *h, void __user *argp) ...@@ -1490,8 +1529,7 @@ static int cciss_bigpassthru(ctlr_info_t *h, void __user *argp)
return -EINVAL; return -EINVAL;
if (!capable(CAP_SYS_RAWIO)) if (!capable(CAP_SYS_RAWIO))
return -EPERM; return -EPERM;
ioc = (BIG_IOCTL_Command_struct *) ioc = kmalloc(sizeof(*ioc), GFP_KERNEL);
kmalloc(sizeof(*ioc), GFP_KERNEL);
if (!ioc) { if (!ioc) {
status = -ENOMEM; status = -ENOMEM;
goto cleanup1; goto cleanup1;
...@@ -2653,6 +2691,10 @@ static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c) ...@@ -2653,6 +2691,10 @@ static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c)
c->Request.CDB[0]); c->Request.CDB[0]);
return_status = IO_NEEDS_RETRY; return_status = IO_NEEDS_RETRY;
break; break;
case CMD_UNABORTABLE:
dev_warn(&h->pdev->dev, "cmd unabortable\n");
return_status = IO_ERROR;
break;
default: default:
dev_warn(&h->pdev->dev, "cmd 0x%02x returned " dev_warn(&h->pdev->dev, "cmd 0x%02x returned "
"unknown status %x\n", c->Request.CDB[0], "unknown status %x\n", c->Request.CDB[0],
...@@ -3103,6 +3145,13 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, ...@@ -3103,6 +3145,13 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
(cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
DID_PASSTHROUGH : DID_ERROR); DID_PASSTHROUGH : DID_ERROR);
break; break;
case CMD_UNABORTABLE:
dev_warn(&h->pdev->dev, "cmd %p unabortable\n", cmd);
rq->errors = make_status_bytes(SAM_STAT_GOOD,
cmd->err_info->CommandStatus, DRIVER_OK,
cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC ?
DID_PASSTHROUGH : DID_ERROR);
break;
default: default:
dev_warn(&h->pdev->dev, "cmd %p returned " dev_warn(&h->pdev->dev, "cmd %p returned "
"unknown status %x\n", cmd, "unknown status %x\n", cmd,
...@@ -3136,10 +3185,13 @@ static inline u32 cciss_tag_to_index(u32 tag) ...@@ -3136,10 +3185,13 @@ static inline u32 cciss_tag_to_index(u32 tag)
return tag >> DIRECT_LOOKUP_SHIFT; return tag >> DIRECT_LOOKUP_SHIFT;
} }
static inline u32 cciss_tag_discard_error_bits(u32 tag) static inline u32 cciss_tag_discard_error_bits(ctlr_info_t *h, u32 tag)
{ {
#define CCISS_ERROR_BITS 0x03 #define CCISS_PERF_ERROR_BITS ((1 << DIRECT_LOOKUP_SHIFT) - 1)
return tag & ~CCISS_ERROR_BITS; #define CCISS_SIMPLE_ERROR_BITS 0x03
if (likely(h->transMethod & CFGTBL_Trans_Performant))
return tag & ~CCISS_PERF_ERROR_BITS;
return tag & ~CCISS_SIMPLE_ERROR_BITS;
} }
static inline void cciss_mark_tag_indexed(u32 *tag) static inline void cciss_mark_tag_indexed(u32 *tag)
...@@ -3359,7 +3411,7 @@ static inline u32 next_command(ctlr_info_t *h) ...@@ -3359,7 +3411,7 @@ static inline u32 next_command(ctlr_info_t *h)
{ {
u32 a; u32 a;
if (unlikely(h->transMethod != CFGTBL_Trans_Performant)) if (unlikely(!(h->transMethod & CFGTBL_Trans_Performant)))
return h->access.command_completed(h); return h->access.command_completed(h);
if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) { if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) {
...@@ -3394,14 +3446,12 @@ static inline u32 process_indexed_cmd(ctlr_info_t *h, u32 raw_tag) ...@@ -3394,14 +3446,12 @@ static inline u32 process_indexed_cmd(ctlr_info_t *h, u32 raw_tag)
/* process completion of a non-indexed command */ /* process completion of a non-indexed command */
static inline u32 process_nonindexed_cmd(ctlr_info_t *h, u32 raw_tag) static inline u32 process_nonindexed_cmd(ctlr_info_t *h, u32 raw_tag)
{ {
u32 tag;
CommandList_struct *c = NULL; CommandList_struct *c = NULL;
__u32 busaddr_masked, tag_masked; __u32 busaddr_masked, tag_masked;
tag = cciss_tag_discard_error_bits(raw_tag); tag_masked = cciss_tag_discard_error_bits(h, raw_tag);
list_for_each_entry(c, &h->cmpQ, list) { list_for_each_entry(c, &h->cmpQ, list) {
busaddr_masked = cciss_tag_discard_error_bits(c->busaddr); busaddr_masked = cciss_tag_discard_error_bits(h, c->busaddr);
tag_masked = cciss_tag_discard_error_bits(tag);
if (busaddr_masked == tag_masked) { if (busaddr_masked == tag_masked) {
finish_cmd(h, c, raw_tag); finish_cmd(h, c, raw_tag);
return next_command(h); return next_command(h);
...@@ -3753,7 +3803,8 @@ static void __devinit cciss_wait_for_mode_change_ack(ctlr_info_t *h) ...@@ -3753,7 +3803,8 @@ static void __devinit cciss_wait_for_mode_change_ack(ctlr_info_t *h)
} }
} }
static __devinit void cciss_enter_performant_mode(ctlr_info_t *h) static __devinit void cciss_enter_performant_mode(ctlr_info_t *h,
u32 use_short_tags)
{ {
/* This is a bit complicated. There are 8 registers on /* This is a bit complicated. There are 8 registers on
* the controller which we write to to tell it 8 different * the controller which we write to to tell it 8 different
...@@ -3808,7 +3859,7 @@ static __devinit void cciss_enter_performant_mode(ctlr_info_t *h) ...@@ -3808,7 +3859,7 @@ static __devinit void cciss_enter_performant_mode(ctlr_info_t *h)
writel(0, &h->transtable->RepQCtrAddrHigh32); writel(0, &h->transtable->RepQCtrAddrHigh32);
writel(h->reply_pool_dhandle, &h->transtable->RepQAddr0Low32); writel(h->reply_pool_dhandle, &h->transtable->RepQAddr0Low32);
writel(0, &h->transtable->RepQAddr0High32); writel(0, &h->transtable->RepQAddr0High32);
writel(CFGTBL_Trans_Performant, writel(CFGTBL_Trans_Performant | use_short_tags,
&(h->cfgtable->HostWrite.TransportRequest)); &(h->cfgtable->HostWrite.TransportRequest));
writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
...@@ -3855,7 +3906,8 @@ static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h) ...@@ -3855,7 +3906,8 @@ static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h)
if ((h->reply_pool == NULL) || (h->blockFetchTable == NULL)) if ((h->reply_pool == NULL) || (h->blockFetchTable == NULL))
goto clean_up; goto clean_up;
cciss_enter_performant_mode(h); cciss_enter_performant_mode(h,
trans_support & CFGTBL_Trans_use_short_tags);
/* Change the access methods to the performant access methods */ /* Change the access methods to the performant access methods */
h->access = SA5_performant_access; h->access = SA5_performant_access;
......
...@@ -222,6 +222,7 @@ static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c) ...@@ -222,6 +222,7 @@ static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c)
h->ctlr, c->busaddr); h->ctlr, c->busaddr);
#endif /* CCISS_DEBUG */ #endif /* CCISS_DEBUG */
writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
readl(h->vaddr + SA5_REQUEST_PORT_OFFSET);
h->commands_outstanding++; h->commands_outstanding++;
if ( h->commands_outstanding > h->max_outstanding) if ( h->commands_outstanding > h->max_outstanding)
h->max_outstanding = h->commands_outstanding; h->max_outstanding = h->commands_outstanding;
......
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
#define CFGTBL_Trans_Simple 0x00000002l #define CFGTBL_Trans_Simple 0x00000002l
#define CFGTBL_Trans_Performant 0x00000004l #define CFGTBL_Trans_Performant 0x00000004l
#define CFGTBL_Trans_use_short_tags 0x20000000l
#define CFGTBL_BusType_Ultra2 0x00000001l #define CFGTBL_BusType_Ultra2 0x00000001l
#define CFGTBL_BusType_Ultra3 0x00000002l #define CFGTBL_BusType_Ultra3 0x00000002l
......
...@@ -824,13 +824,18 @@ static void complete_scsi_command(CommandList_struct *c, int timeout, ...@@ -824,13 +824,18 @@ static void complete_scsi_command(CommandList_struct *c, int timeout,
break; break;
case CMD_UNSOLICITED_ABORT: case CMD_UNSOLICITED_ABORT:
cmd->result = DID_ABORT << 16; cmd->result = DID_ABORT << 16;
dev_warn(&h->pdev->dev, "%p aborted do to an " dev_warn(&h->pdev->dev, "%p aborted due to an "
"unsolicited abort\n", c); "unsolicited abort\n", c);
break; break;
case CMD_TIMEOUT: case CMD_TIMEOUT:
cmd->result = DID_TIME_OUT << 16; cmd->result = DID_TIME_OUT << 16;
dev_warn(&h->pdev->dev, "%p timedout\n", c); dev_warn(&h->pdev->dev, "%p timedout\n", c);
break; break;
case CMD_UNABORTABLE:
cmd->result = DID_ERROR << 16;
dev_warn(&h->pdev->dev, "c %p command "
"unabortable\n", c);
break;
default: default:
cmd->result = DID_ERROR << 16; cmd->result = DID_ERROR << 16;
dev_warn(&h->pdev->dev, dev_warn(&h->pdev->dev,
...@@ -1007,11 +1012,15 @@ cciss_scsi_interpret_error(ctlr_info_t *h, CommandList_struct *c) ...@@ -1007,11 +1012,15 @@ cciss_scsi_interpret_error(ctlr_info_t *h, CommandList_struct *c)
break; break;
case CMD_UNSOLICITED_ABORT: case CMD_UNSOLICITED_ABORT:
dev_warn(&h->pdev->dev, dev_warn(&h->pdev->dev,
"%p aborted do to an unsolicited abort\n", c); "%p aborted due to an unsolicited abort\n", c);
break; break;
case CMD_TIMEOUT: case CMD_TIMEOUT:
dev_warn(&h->pdev->dev, "%p timedout\n", c); dev_warn(&h->pdev->dev, "%p timedout\n", c);
break; break;
case CMD_UNABORTABLE:
dev_warn(&h->pdev->dev,
"%p unabortable\n", c);
break;
default: default:
dev_warn(&h->pdev->dev, dev_warn(&h->pdev->dev,
"%p returned unknown status %x\n", "%p returned unknown status %x\n",
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "drbd_int.h" #include "drbd_int.h"
static int drbd_proc_open(struct inode *inode, struct file *file); static int drbd_proc_open(struct inode *inode, struct file *file);
static int drbd_proc_release(struct inode *inode, struct file *file);
struct proc_dir_entry *drbd_proc; struct proc_dir_entry *drbd_proc;
...@@ -42,9 +43,22 @@ const struct file_operations drbd_proc_fops = { ...@@ -42,9 +43,22 @@ const struct file_operations drbd_proc_fops = {
.open = drbd_proc_open, .open = drbd_proc_open,
.read = seq_read, .read = seq_read,
.llseek = seq_lseek, .llseek = seq_lseek,
.release = single_release, .release = drbd_proc_release,
}; };
void seq_printf_with_thousands_grouping(struct seq_file *seq, long v)
{
/* v is in kB/sec. We don't expect TiByte/sec yet. */
if (unlikely(v >= 1000000)) {
/* cool: > GiByte/s */
seq_printf(seq, "%ld,", v / 1000000);
v /= 1000000;
seq_printf(seq, "%03ld,%03ld", v/1000, v % 1000);
} else if (likely(v >= 1000))
seq_printf(seq, "%ld,%03ld", v/1000, v % 1000);
else
seq_printf(seq, "%ld", v);
}
/*lge /*lge
* progress bars shamelessly adapted from driver/md/md.c * progress bars shamelessly adapted from driver/md/md.c
...@@ -71,10 +85,15 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) ...@@ -71,10 +85,15 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq)
seq_printf(seq, "."); seq_printf(seq, ".");
seq_printf(seq, "] "); seq_printf(seq, "] ");
seq_printf(seq, "sync'ed:%3u.%u%% ", res / 10, res % 10); if (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T)
/* if more than 1 GB display in MB */ seq_printf(seq, "verified:");
if (mdev->rs_total > 0x100000L) else
seq_printf(seq, "(%lu/%lu)M\n\t", seq_printf(seq, "sync'ed:");
seq_printf(seq, "%3u.%u%% ", res / 10, res % 10);
/* if more than a few GB, display in MB */
if (mdev->rs_total > (4UL << (30 - BM_BLOCK_SHIFT)))
seq_printf(seq, "(%lu/%lu)M",
(unsigned long) Bit2KB(rs_left >> 10), (unsigned long) Bit2KB(rs_left >> 10),
(unsigned long) Bit2KB(mdev->rs_total >> 10)); (unsigned long) Bit2KB(mdev->rs_total >> 10));
else else
...@@ -94,6 +113,7 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) ...@@ -94,6 +113,7 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq)
/* Rolling marks. last_mark+1 may just now be modified. last_mark+2 is /* Rolling marks. last_mark+1 may just now be modified. last_mark+2 is
* at least (DRBD_SYNC_MARKS-2)*DRBD_SYNC_MARK_STEP old, and has at * at least (DRBD_SYNC_MARKS-2)*DRBD_SYNC_MARK_STEP old, and has at
* least DRBD_SYNC_MARK_STEP time before it will be modified. */ * least DRBD_SYNC_MARK_STEP time before it will be modified. */
/* ------------------------ ~18s average ------------------------ */
i = (mdev->rs_last_mark + 2) % DRBD_SYNC_MARKS; i = (mdev->rs_last_mark + 2) % DRBD_SYNC_MARKS;
dt = (jiffies - mdev->rs_mark_time[i]) / HZ; dt = (jiffies - mdev->rs_mark_time[i]) / HZ;
if (dt > (DRBD_SYNC_MARK_STEP * DRBD_SYNC_MARKS)) if (dt > (DRBD_SYNC_MARK_STEP * DRBD_SYNC_MARKS))
...@@ -107,14 +127,24 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) ...@@ -107,14 +127,24 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq)
seq_printf(seq, "finish: %lu:%02lu:%02lu", seq_printf(seq, "finish: %lu:%02lu:%02lu",
rt / 3600, (rt % 3600) / 60, rt % 60); rt / 3600, (rt % 3600) / 60, rt % 60);
/* current speed average over (SYNC_MARKS * SYNC_MARK_STEP) jiffies */
dbdt = Bit2KB(db/dt); dbdt = Bit2KB(db/dt);
if (dbdt > 1000) seq_printf(seq, " speed: ");
seq_printf(seq, " speed: %ld,%03ld", seq_printf_with_thousands_grouping(seq, dbdt);
dbdt/1000, dbdt % 1000); seq_printf(seq, " (");
else /* ------------------------- ~3s average ------------------------ */
seq_printf(seq, " speed: %ld", dbdt); if (proc_details >= 1) {
/* this is what drbd_rs_should_slow_down() uses */
i = (mdev->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS;
dt = (jiffies - mdev->rs_mark_time[i]) / HZ;
if (!dt)
dt++;
db = mdev->rs_mark_left[i] - rs_left;
dbdt = Bit2KB(db/dt);
seq_printf_with_thousands_grouping(seq, dbdt);
seq_printf(seq, " -- ");
}
/* --------------------- long term average ---------------------- */
/* mean speed since syncer started /* mean speed since syncer started
* we do account for PausedSync periods */ * we do account for PausedSync periods */
dt = (jiffies - mdev->rs_start - mdev->rs_paused) / HZ; dt = (jiffies - mdev->rs_start - mdev->rs_paused) / HZ;
...@@ -122,20 +152,34 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) ...@@ -122,20 +152,34 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq)
dt = 1; dt = 1;
db = mdev->rs_total - rs_left; db = mdev->rs_total - rs_left;
dbdt = Bit2KB(db/dt); dbdt = Bit2KB(db/dt);
if (dbdt > 1000) seq_printf_with_thousands_grouping(seq, dbdt);
seq_printf(seq, " (%ld,%03ld)", seq_printf(seq, ")");
dbdt/1000, dbdt % 1000);
else
seq_printf(seq, " (%ld)", dbdt);
if (mdev->state.conn == C_SYNC_TARGET) { if (mdev->state.conn == C_SYNC_TARGET ||
if (mdev->c_sync_rate > 1000) mdev->state.conn == C_VERIFY_S) {
seq_printf(seq, " want: %d,%03d", seq_printf(seq, " want: ");
mdev->c_sync_rate / 1000, mdev->c_sync_rate % 1000); seq_printf_with_thousands_grouping(seq, mdev->c_sync_rate);
else
seq_printf(seq, " want: %d", mdev->c_sync_rate);
} }
seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : ""); seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : "");
if (proc_details >= 1) {
/* 64 bit:
* we convert to sectors in the display below. */
unsigned long bm_bits = drbd_bm_bits(mdev);
unsigned long bit_pos;
if (mdev->state.conn == C_VERIFY_S ||
mdev->state.conn == C_VERIFY_T)
bit_pos = bm_bits - mdev->ov_left;
else
bit_pos = mdev->bm_resync_fo;
/* Total sectors may be slightly off for oddly
* sized devices. So what. */
seq_printf(seq,
"\t%3d%% sector pos: %llu/%llu\n",
(int)(bit_pos / (bm_bits/100+1)),
(unsigned long long)bit_pos * BM_SECT_PER_BIT,
(unsigned long long)bm_bits * BM_SECT_PER_BIT);
}
} }
static void resync_dump_detail(struct seq_file *seq, struct lc_element *e) static void resync_dump_detail(struct seq_file *seq, struct lc_element *e)
...@@ -232,20 +276,16 @@ static int drbd_seq_show(struct seq_file *seq, void *v) ...@@ -232,20 +276,16 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
mdev->epochs, mdev->epochs,
write_ordering_chars[mdev->write_ordering] write_ordering_chars[mdev->write_ordering]
); );
seq_printf(seq, " oos:%lu\n", seq_printf(seq, " oos:%llu\n",
Bit2KB(drbd_bm_total_weight(mdev))); Bit2KB((unsigned long long)
drbd_bm_total_weight(mdev)));
} }
if (mdev->state.conn == C_SYNC_SOURCE || if (mdev->state.conn == C_SYNC_SOURCE ||
mdev->state.conn == C_SYNC_TARGET) mdev->state.conn == C_SYNC_TARGET ||
mdev->state.conn == C_VERIFY_S ||
mdev->state.conn == C_VERIFY_T)
drbd_syncer_progress(mdev, seq); drbd_syncer_progress(mdev, seq);
if (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T)
seq_printf(seq, "\t%3d%% %lu/%lu\n",
(int)((mdev->rs_total-mdev->ov_left) /
(mdev->rs_total/100+1)),
mdev->rs_total - mdev->ov_left,
mdev->rs_total);
if (proc_details >= 1 && get_ldev_if_state(mdev, D_FAILED)) { if (proc_details >= 1 && get_ldev_if_state(mdev, D_FAILED)) {
lc_seq_printf_stats(seq, mdev->resync); lc_seq_printf_stats(seq, mdev->resync);
lc_seq_printf_stats(seq, mdev->act_log); lc_seq_printf_stats(seq, mdev->act_log);
...@@ -265,7 +305,15 @@ static int drbd_seq_show(struct seq_file *seq, void *v) ...@@ -265,7 +305,15 @@ static int drbd_seq_show(struct seq_file *seq, void *v)
static int drbd_proc_open(struct inode *inode, struct file *file) static int drbd_proc_open(struct inode *inode, struct file *file)
{ {
if (try_module_get(THIS_MODULE))
return single_open(file, drbd_seq_show, PDE(inode)->data); return single_open(file, drbd_seq_show, PDE(inode)->data);
return -ENODEV;
}
static int drbd_proc_release(struct inode *inode, struct file *file)
{
module_put(THIS_MODULE);
return single_release(inode, file);
} }
/* PROC FS stuff end */ /* PROC FS stuff end */
This diff is collapsed.
This diff is collapsed.
...@@ -82,14 +82,16 @@ enum drbd_req_event { ...@@ -82,14 +82,16 @@ enum drbd_req_event {
to_be_submitted, to_be_submitted,
/* XXX yes, now I am inconsistent... /* XXX yes, now I am inconsistent...
* these two are not "events" but "actions" * these are not "events" but "actions"
* oh, well... */ * oh, well... */
queue_for_net_write, queue_for_net_write,
queue_for_net_read, queue_for_net_read,
queue_for_send_oos,
send_canceled, send_canceled,
send_failed, send_failed,
handed_over_to_network, handed_over_to_network,
oos_handed_to_network,
connection_lost_while_pending, connection_lost_while_pending,
read_retry_remote_canceled, read_retry_remote_canceled,
recv_acked_by_peer, recv_acked_by_peer,
...@@ -289,7 +291,6 @@ static inline struct drbd_request *drbd_req_new(struct drbd_conf *mdev, ...@@ -289,7 +291,6 @@ static inline struct drbd_request *drbd_req_new(struct drbd_conf *mdev,
req->epoch = 0; req->epoch = 0;
req->sector = bio_src->bi_sector; req->sector = bio_src->bi_sector;
req->size = bio_src->bi_size; req->size = bio_src->bi_size;
req->start_time = jiffies;
INIT_HLIST_NODE(&req->colision); INIT_HLIST_NODE(&req->colision);
INIT_LIST_HEAD(&req->tl_requests); INIT_LIST_HEAD(&req->tl_requests);
INIT_LIST_HEAD(&req->w.list); INIT_LIST_HEAD(&req->w.list);
...@@ -321,6 +322,7 @@ extern int __req_mod(struct drbd_request *req, enum drbd_req_event what, ...@@ -321,6 +322,7 @@ extern int __req_mod(struct drbd_request *req, enum drbd_req_event what,
struct bio_and_error *m); struct bio_and_error *m);
extern void complete_master_bio(struct drbd_conf *mdev, extern void complete_master_bio(struct drbd_conf *mdev,
struct bio_and_error *m); struct bio_and_error *m);
extern void request_timer_fn(unsigned long data);
/* use this if you don't want to deal with calling complete_master_bio() /* use this if you don't want to deal with calling complete_master_bio()
* outside the spinlock, e.g. when walking some list on cleanup. */ * outside the spinlock, e.g. when walking some list on cleanup. */
...@@ -338,23 +340,43 @@ static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what) ...@@ -338,23 +340,43 @@ static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what)
return rv; return rv;
} }
/* completion of master bio is outside of spinlock. /* completion of master bio is outside of our spinlock.
* If you need it irqsave, do it your self! * We still may or may not be inside some irqs disabled section
* Which means: don't use from bio endio callback. */ * of the lower level driver completion callback, so we need to
* spin_lock_irqsave here. */
static inline int req_mod(struct drbd_request *req, static inline int req_mod(struct drbd_request *req,
enum drbd_req_event what) enum drbd_req_event what)
{ {
unsigned long flags;
struct drbd_conf *mdev = req->mdev; struct drbd_conf *mdev = req->mdev;
struct bio_and_error m; struct bio_and_error m;
int rv; int rv;
spin_lock_irq(&mdev->req_lock); spin_lock_irqsave(&mdev->req_lock, flags);
rv = __req_mod(req, what, &m); rv = __req_mod(req, what, &m);
spin_unlock_irq(&mdev->req_lock); spin_unlock_irqrestore(&mdev->req_lock, flags);
if (m.bio) if (m.bio)
complete_master_bio(mdev, &m); complete_master_bio(mdev, &m);
return rv; return rv;
} }
static inline bool drbd_should_do_remote(union drbd_state s)
{
return s.pdsk == D_UP_TO_DATE ||
(s.pdsk >= D_INCONSISTENT &&
s.conn >= C_WF_BITMAP_T &&
s.conn < C_AHEAD);
/* Before proto 96 that was >= CONNECTED instead of >= C_WF_BITMAP_T.
That is equivalent since before 96 IO was frozen in the C_WF_BITMAP*
states. */
}
static inline bool drbd_should_send_oos(union drbd_state s)
{
return s.conn == C_AHEAD || s.conn == C_WF_BITMAP_S;
/* pdsk = D_INCONSISTENT as a consequence. Protocol 96 check not necessary
since we enter state C_AHEAD only if proto >= 96 */
}
#endif #endif
...@@ -48,6 +48,8 @@ static const char *drbd_conn_s_names[] = { ...@@ -48,6 +48,8 @@ static const char *drbd_conn_s_names[] = {
[C_PAUSED_SYNC_T] = "PausedSyncT", [C_PAUSED_SYNC_T] = "PausedSyncT",
[C_VERIFY_S] = "VerifyS", [C_VERIFY_S] = "VerifyS",
[C_VERIFY_T] = "VerifyT", [C_VERIFY_T] = "VerifyT",
[C_AHEAD] = "Ahead",
[C_BEHIND] = "Behind",
}; };
static const char *drbd_role_s_names[] = { static const char *drbd_role_s_names[] = {
...@@ -92,7 +94,7 @@ static const char *drbd_state_sw_errors[] = { ...@@ -92,7 +94,7 @@ static const char *drbd_state_sw_errors[] = {
const char *drbd_conn_str(enum drbd_conns s) const char *drbd_conn_str(enum drbd_conns s)
{ {
/* enums are unsigned... */ /* enums are unsigned... */
return s > C_PAUSED_SYNC_T ? "TOO_LARGE" : drbd_conn_s_names[s]; return s > C_BEHIND ? "TOO_LARGE" : drbd_conn_s_names[s];
} }
const char *drbd_role_str(enum drbd_role s) const char *drbd_role_str(enum drbd_role s)
...@@ -105,7 +107,7 @@ const char *drbd_disk_str(enum drbd_disk_state s) ...@@ -105,7 +107,7 @@ const char *drbd_disk_str(enum drbd_disk_state s)
return s > D_UP_TO_DATE ? "TOO_LARGE" : drbd_disk_s_names[s]; return s > D_UP_TO_DATE ? "TOO_LARGE" : drbd_disk_s_names[s];
} }
const char *drbd_set_st_err_str(enum drbd_state_ret_codes err) const char *drbd_set_st_err_str(enum drbd_state_rv err)
{ {
return err <= SS_AFTER_LAST_ERROR ? "TOO_SMALL" : return err <= SS_AFTER_LAST_ERROR ? "TOO_SMALL" :
err > SS_TWO_PRIMARIES ? "TOO_LARGE" err > SS_TWO_PRIMARIES ? "TOO_LARGE"
......
This diff is collapsed.
...@@ -39,7 +39,7 @@ static inline void drbd_generic_make_request(struct drbd_conf *mdev, ...@@ -39,7 +39,7 @@ static inline void drbd_generic_make_request(struct drbd_conf *mdev,
return; return;
} }
if (FAULT_ACTIVE(mdev, fault_type)) if (drbd_insert_fault(mdev, fault_type))
bio_endio(bio, -EIO); bio_endio(bio, -EIO);
else else
generic_make_request(bio); generic_make_request(bio);
......
...@@ -53,10 +53,10 @@ ...@@ -53,10 +53,10 @@
extern const char *drbd_buildtag(void); extern const char *drbd_buildtag(void);
#define REL_VERSION "8.3.9" #define REL_VERSION "8.3.10"
#define API_VERSION 88 #define API_VERSION 88
#define PRO_VERSION_MIN 86 #define PRO_VERSION_MIN 86
#define PRO_VERSION_MAX 95 #define PRO_VERSION_MAX 96
enum drbd_io_error_p { enum drbd_io_error_p {
...@@ -96,8 +96,14 @@ enum drbd_on_no_data { ...@@ -96,8 +96,14 @@ enum drbd_on_no_data {
OND_SUSPEND_IO OND_SUSPEND_IO
}; };
enum drbd_on_congestion {
OC_BLOCK,
OC_PULL_AHEAD,
OC_DISCONNECT,
};
/* KEEP the order, do not delete or insert. Only append. */ /* KEEP the order, do not delete or insert. Only append. */
enum drbd_ret_codes { enum drbd_ret_code {
ERR_CODE_BASE = 100, ERR_CODE_BASE = 100,
NO_ERROR = 101, NO_ERROR = 101,
ERR_LOCAL_ADDR = 102, ERR_LOCAL_ADDR = 102,
...@@ -146,6 +152,9 @@ enum drbd_ret_codes { ...@@ -146,6 +152,9 @@ enum drbd_ret_codes {
ERR_PERM = 152, ERR_PERM = 152,
ERR_NEED_APV_93 = 153, ERR_NEED_APV_93 = 153,
ERR_STONITH_AND_PROT_A = 154, ERR_STONITH_AND_PROT_A = 154,
ERR_CONG_NOT_PROTO_A = 155,
ERR_PIC_AFTER_DEP = 156,
ERR_PIC_PEER_DEP = 157,
/* insert new ones above this line */ /* insert new ones above this line */
AFTER_LAST_ERR_CODE AFTER_LAST_ERR_CODE
...@@ -199,6 +208,10 @@ enum drbd_conns { ...@@ -199,6 +208,10 @@ enum drbd_conns {
C_VERIFY_T, C_VERIFY_T,
C_PAUSED_SYNC_S, C_PAUSED_SYNC_S,
C_PAUSED_SYNC_T, C_PAUSED_SYNC_T,
C_AHEAD,
C_BEHIND,
C_MASK = 31 C_MASK = 31
}; };
...@@ -259,7 +272,7 @@ union drbd_state { ...@@ -259,7 +272,7 @@ union drbd_state {
unsigned int i; unsigned int i;
}; };
enum drbd_state_ret_codes { enum drbd_state_rv {
SS_CW_NO_NEED = 4, SS_CW_NO_NEED = 4,
SS_CW_SUCCESS = 3, SS_CW_SUCCESS = 3,
SS_NOTHING_TO_DO = 2, SS_NOTHING_TO_DO = 2,
...@@ -290,7 +303,7 @@ enum drbd_state_ret_codes { ...@@ -290,7 +303,7 @@ enum drbd_state_ret_codes {
extern const char *drbd_conn_str(enum drbd_conns); extern const char *drbd_conn_str(enum drbd_conns);
extern const char *drbd_role_str(enum drbd_role); extern const char *drbd_role_str(enum drbd_role);
extern const char *drbd_disk_str(enum drbd_disk_state); extern const char *drbd_disk_str(enum drbd_disk_state);
extern const char *drbd_set_st_err_str(enum drbd_state_ret_codes); extern const char *drbd_set_st_err_str(enum drbd_state_rv);
#define SHARED_SECRET_MAX 64 #define SHARED_SECRET_MAX 64
......
...@@ -16,7 +16,8 @@ ...@@ -16,7 +16,8 @@
#define DEBUG_RANGE_CHECK 0 #define DEBUG_RANGE_CHECK 0
#define DRBD_MINOR_COUNT_MIN 1 #define DRBD_MINOR_COUNT_MIN 1
#define DRBD_MINOR_COUNT_MAX 255 #define DRBD_MINOR_COUNT_MAX 256
#define DRBD_MINOR_COUNT_DEF 32
#define DRBD_DIALOG_REFRESH_MIN 0 #define DRBD_DIALOG_REFRESH_MIN 0
#define DRBD_DIALOG_REFRESH_MAX 600 #define DRBD_DIALOG_REFRESH_MAX 600
...@@ -129,6 +130,7 @@ ...@@ -129,6 +130,7 @@
#define DRBD_AFTER_SB_2P_DEF ASB_DISCONNECT #define DRBD_AFTER_SB_2P_DEF ASB_DISCONNECT
#define DRBD_RR_CONFLICT_DEF ASB_DISCONNECT #define DRBD_RR_CONFLICT_DEF ASB_DISCONNECT
#define DRBD_ON_NO_DATA_DEF OND_IO_ERROR #define DRBD_ON_NO_DATA_DEF OND_IO_ERROR
#define DRBD_ON_CONGESTION_DEF OC_BLOCK
#define DRBD_MAX_BIO_BVECS_MIN 0 #define DRBD_MAX_BIO_BVECS_MIN 0
#define DRBD_MAX_BIO_BVECS_MAX 128 #define DRBD_MAX_BIO_BVECS_MAX 128
...@@ -154,5 +156,13 @@ ...@@ -154,5 +156,13 @@
#define DRBD_C_MIN_RATE_MAX (4 << 20) #define DRBD_C_MIN_RATE_MAX (4 << 20)
#define DRBD_C_MIN_RATE_DEF 4096 #define DRBD_C_MIN_RATE_DEF 4096
#define DRBD_CONG_FILL_MIN 0
#define DRBD_CONG_FILL_MAX (10<<21) /* 10GByte in sectors */
#define DRBD_CONG_FILL_DEF 0
#define DRBD_CONG_EXTENTS_MIN DRBD_AL_EXTENTS_MIN
#define DRBD_CONG_EXTENTS_MAX DRBD_AL_EXTENTS_MAX
#define DRBD_CONG_EXTENTS_DEF DRBD_AL_EXTENTS_DEF
#undef RANGE #undef RANGE
#endif #endif
...@@ -56,6 +56,9 @@ NL_PACKET(net_conf, 5, ...@@ -56,6 +56,9 @@ NL_PACKET(net_conf, 5,
NL_INTEGER( 39, T_MAY_IGNORE, rr_conflict) NL_INTEGER( 39, T_MAY_IGNORE, rr_conflict)
NL_INTEGER( 40, T_MAY_IGNORE, ping_timeo) NL_INTEGER( 40, T_MAY_IGNORE, ping_timeo)
NL_INTEGER( 67, T_MAY_IGNORE, rcvbuf_size) NL_INTEGER( 67, T_MAY_IGNORE, rcvbuf_size)
NL_INTEGER( 81, T_MAY_IGNORE, on_congestion)
NL_INTEGER( 82, T_MAY_IGNORE, cong_fill)
NL_INTEGER( 83, T_MAY_IGNORE, cong_extents)
/* 59 addr_family was available in GIT, never released */ /* 59 addr_family was available in GIT, never released */
NL_BIT( 60, T_MANDATORY, mind_af) NL_BIT( 60, T_MANDATORY, mind_af)
NL_BIT( 27, T_MAY_IGNORE, want_lose) NL_BIT( 27, T_MAY_IGNORE, want_lose)
...@@ -66,7 +69,9 @@ NL_PACKET(net_conf, 5, ...@@ -66,7 +69,9 @@ NL_PACKET(net_conf, 5,
NL_BIT( 70, T_MANDATORY, dry_run) NL_BIT( 70, T_MANDATORY, dry_run)
) )
NL_PACKET(disconnect, 6, ) NL_PACKET(disconnect, 6,
NL_BIT( 84, T_MAY_IGNORE, force)
)
NL_PACKET(resize, 7, NL_PACKET(resize, 7,
NL_INT64( 29, T_MAY_IGNORE, resize_size) NL_INT64( 29, T_MAY_IGNORE, resize_size)
...@@ -143,9 +148,13 @@ NL_PACKET(new_c_uuid, 26, ...@@ -143,9 +148,13 @@ NL_PACKET(new_c_uuid, 26,
NL_BIT( 63, T_MANDATORY, clear_bm) NL_BIT( 63, T_MANDATORY, clear_bm)
) )
#ifdef NL_RESPONSE
NL_RESPONSE(return_code_only, 27)
#endif
#undef NL_PACKET #undef NL_PACKET
#undef NL_INTEGER #undef NL_INTEGER
#undef NL_INT64 #undef NL_INT64
#undef NL_BIT #undef NL_BIT
#undef NL_STRING #undef NL_STRING
#undef NL_RESPONSE
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
/* declare packet_type enums */ /* declare packet_type enums */
enum packet_types { enum packet_types {
#define NL_PACKET(name, number, fields) P_ ## name = number, #define NL_PACKET(name, number, fields) P_ ## name = number,
#define NL_RESPONSE(name, number) P_ ## name = number,
#define NL_INTEGER(pn, pr, member) #define NL_INTEGER(pn, pr, member)
#define NL_INT64(pn, pr, member) #define NL_INT64(pn, pr, member)
#define NL_BIT(pn, pr, member) #define NL_BIT(pn, pr, member)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment