Commit 916dbe89 authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/disk1/davem/BK/sparcwork-2.5

into nuts.ninka.net:/disk1/davem/BK/sparc-2.5
parents e286c8f8 14c5d2d2
......@@ -150,6 +150,7 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
struct request *rq;
struct bio *bio;
char sense[SCSI_SENSE_BUFFERSIZE];
unsigned char cdb[BLK_MAX_CDB];
void *buffer;
if (hdr->interface_id != 'S')
......@@ -166,6 +167,9 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
if (hdr->dxfer_len > (q->max_sectors << 9))
return -EIO;
if (copy_from_user(cdb, hdr->cmdp, hdr->cmd_len))
return -EFAULT;
reading = writing = 0;
buffer = NULL;
bio = NULL;
......@@ -216,12 +220,7 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
* fill in request structure
*/
rq->cmd_len = hdr->cmd_len;
if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len)) {
blk_put_request(rq);
return -EFAULT;
}
memcpy(rq->cmd, cdb, hdr->cmd_len);
if (sizeof(rq->cmd) != hdr->cmd_len)
memset(rq->cmd + hdr->cmd_len, 0, sizeof(rq->cmd) - hdr->cmd_len);
......
......@@ -65,6 +65,8 @@ int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
int c1, c2 = 0;
int ret = 0;
lock_kernel();
if (hpfs_sb(inode->i_sb)->sb_chk) {
if (hpfs_chk_sectors(inode->i_sb, inode->i_ino, 1, "dir_fnode")) {
ret = -EFSERROR;
......
......@@ -82,6 +82,8 @@ struct request_list {
wait_queue_head_t wait[2];
};
#define BLK_MAX_CDB 16
/*
* try to put the fields that are referenced together in the same cacheline
*/
......@@ -147,7 +149,7 @@ struct request {
* when request is used as a packet command carrier
*/
unsigned int cmd_len;
unsigned char cmd[16];
unsigned char cmd[BLK_MAX_CDB];
unsigned int data_len;
void *data;
......
......@@ -208,6 +208,18 @@ static inline int list_empty(const struct list_head *head)
return head->next == head;
}
/**
* list_empty_careful - tests whether a list is
* empty _and_ checks that no other CPU might be
* in the process of still modifying either member
* @head: the list to test.
*/
static inline int list_empty_careful(const struct list_head *head)
{
struct list_head *next = head->next;
return (next == head) && (next == head->prev);
}
static inline void __list_splice(struct list_head *list,
struct list_head *head)
{
......
......@@ -159,7 +159,20 @@ void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
unsigned long flags;
__set_current_state(TASK_RUNNING);
if (!list_empty(&wait->task_list)) {
/*
* We can check for list emptiness outside the lock
* IFF:
* - we use the "careful" check that verifies both
* the next and prev pointers, so that there cannot
* be any half-pending updates in progress on other
* CPU's that we haven't seen yet (and that might
* still change the stack area.
* and
* - all other users take the lock (ie we can only
* have _one_ other CPU that looks at or modifies
* the list).
*/
if (!list_empty_careful(&wait->task_list)) {
spin_lock_irqsave(&q->lock, flags);
list_del_init(&wait->task_list);
spin_unlock_irqrestore(&q->lock, flags);
......
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