Commit d1c8fac1 authored by James Simmons's avatar James Simmons

Merge bk://linux.bkbits.net/linux-2.5

into maxwell.earthlink.net:/usr/src/linus-2.5
parents 7999a2d4 6a839d30
......@@ -30,6 +30,10 @@ static struct file_operations raw_ctl_fops;
/*
* Open/close code for raw IO.
*
* We just rewrite the i_mapping for the /dev/raw/rawN file descriptor to
* point at the blockdev's address_space and set the file handle to use
* O_DIRECT.
*
* Set the device's soft blocksize to the minimum possible. This gives the
* finest possible alignment and has no adverse impact on performance.
*/
......@@ -56,7 +60,12 @@ static int raw_open(struct inode *inode, struct file *filp)
err = blkdev_get(bdev, filp->f_mode, 0, BDEV_RAW);
if (!err) {
err = set_blocksize(bdev, bdev_hardsect_size(bdev));
raw_devices[minor].inuse++;
if (err == 0) {
raw_devices[minor].inuse++;
filp->f_dentry->d_inode->i_mapping =
bdev->bd_inode->i_mapping;
filp->f_flags |= O_DIRECT;
}
}
}
up(&raw_mutex);
......@@ -200,72 +209,22 @@ raw_ctl_ioctl(struct inode *inode, struct file *filp,
return err;
}
static ssize_t
rw_raw_dev(int rw, struct file *filp, const struct iovec *iov, unsigned long nr_segs, loff_t *offp)
{
const int minor = minor(filp->f_dentry->d_inode->i_rdev);
struct block_device *bdev = raw_devices[minor].binding;
struct inode *inode = bdev->bd_inode;
size_t count = iov_length(iov, nr_segs);
ssize_t ret = 0;
if (count == 0)
goto out;
if ((ssize_t)count < 0)
return -EINVAL;
if (*offp >= inode->i_size)
return -ENXIO;
if (count + *offp > inode->i_size) {
count = inode->i_size - *offp;
nr_segs = iov_shorten((struct iovec *)iov, nr_segs, count);
}
ret = generic_file_direct_IO(rw, filp, iov, *offp, nr_segs);
if (ret > 0)
*offp += ret;
out:
return ret;
}
static ssize_t
raw_read(struct file *filp, char *buf, size_t size, loff_t *offp)
{
struct iovec local_iov = { .iov_base = buf, .iov_len = size};
return rw_raw_dev(READ, filp, &local_iov, 1, offp);
}
static ssize_t
raw_write(struct file *filp, const char *buf, size_t size, loff_t *offp)
static ssize_t raw_file_write(struct file *file, const char *buf,
size_t count, loff_t *ppos)
{
struct iovec local_iov = { .iov_base = (char *)buf, .iov_len = size};
struct iovec local_iov = { .iov_base = (void *)buf, .iov_len = count };
return rw_raw_dev(WRITE, filp, &local_iov, 1, offp);
}
static ssize_t
raw_readv(struct file *filp, const struct iovec *iov, unsigned long nr_segs, loff_t *offp)
{
return rw_raw_dev(READ, filp, iov, nr_segs, offp);
}
static ssize_t
raw_writev(struct file *filp, const struct iovec *iov, unsigned long nr_segs, loff_t *offp)
{
return rw_raw_dev(WRITE, filp, iov, nr_segs, offp);
return generic_file_write_nolock(file, &local_iov, 1, ppos);
}
static struct file_operations raw_fops = {
.read = raw_read,
.write = raw_write,
.read = generic_file_read,
.write = raw_file_write,
.open = raw_open,
.release= raw_release,
.ioctl = raw_ioctl,
.readv = raw_readv,
.writev = raw_writev,
.readv = generic_file_readv,
.writev = generic_file_writev,
.owner = THIS_MODULE,
};
......
......@@ -1434,9 +1434,10 @@ int journal_stop(handle_t *handle)
* by 30x or more...
*/
if (handle->h_sync) {
set_current_state(TASK_RUNNING);
do {
old_handle_count = transaction->t_handle_count;
yield();
schedule();
} while (old_handle_count != transaction->t_handle_count);
}
......
......@@ -316,7 +316,7 @@ static ssize_t do_readv_writev(int type, struct file *file,
size_t tot_len;
struct iovec iovstack[UIO_FASTIOV];
struct iovec *iov=iovstack;
ssize_t ret = -EINVAL;
ssize_t ret;
int seg;
io_fn_t fn;
iov_fn_t fnv;
......@@ -325,8 +325,9 @@ static ssize_t do_readv_writev(int type, struct file *file,
/*
* SuS says "The readv() function *may* fail if the iovcnt argument
* was less than or equal to 0, or greater than {IOV_MAX}. Linux has
* traditionally returned -EINVAL for zero segments, so...
* traditionally returned zero for zero segments, so...
*/
ret = 0;
if (nr_segs == 0)
goto out;
......@@ -334,6 +335,7 @@ static ssize_t do_readv_writev(int type, struct file *file,
* First get the "struct iovec" from user memory and
* verify all the pointers
*/
ret = -EINVAL;
if ((nr_segs > UIO_MAXIOV) || (nr_segs <= 0))
goto out;
if (!file->f_op)
......
......@@ -259,12 +259,21 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
#define pte_offset_kernel(dir, address) \
((pte_t *) pmd_page_kernel(*(dir)) + __pte_offset(address))
#if defined(CONFIG_HIGHPTE)
#define pte_offset_map(dir, address) \
((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + __pte_offset(address))
#define pte_offset_map_nested(dir, address) \
((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE1) + __pte_offset(address))
#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1)
#else
#define pte_offset_map(dir, address) \
((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address)
#define pte_unmap(pte) do { } while (0)
#define pte_unmap_nested(pte) do { } while (0)
#endif
#if defined(CONFIG_HIGHPTE) && defined(CONFIG_HIGHMEM4G)
typedef u32 pte_addr_t;
......
......@@ -21,8 +21,6 @@
struct radix_tree_node;
#define RADIX_TREE_SLOT_RESERVED ((void *)~0UL)
struct radix_tree_root {
unsigned int height;
int gfp_mask;
......@@ -41,7 +39,6 @@ do { \
(root)->rnode = NULL; \
} while (0)
extern int radix_tree_reserve(struct radix_tree_root *, unsigned long, void ***);
extern int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
extern void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
extern int radix_tree_delete(struct radix_tree_root *, unsigned long);
......
......@@ -266,29 +266,31 @@ int del_timer(timer_t *timer)
int del_timer_sync(timer_t *timer)
{
tvec_base_t *base = tvec_bases;
int i, ret;
int i, ret = 0;
ret = del_timer(timer);
del_again:
ret += del_timer(timer);
for (i = 0; i < NR_CPUS; i++) {
for (i = 0; i < NR_CPUS; i++, base++) {
if (!cpu_online(i))
continue;
if (base->running_timer == timer) {
while (base->running_timer == timer) {
cpu_relax();
preempt_disable();
preempt_enable();
preempt_check_resched();
}
break;
}
base++;
}
if (timer_pending(timer))
goto del_again;
return ret;
}
#endif
static void cascade(tvec_base_t *base, tvec_t *tv)
static int cascade(tvec_base_t *base, tvec_t *tv)
{
/* cascade all the timers from tv up one level */
struct list_head *head, *curr, *next;
......@@ -310,7 +312,8 @@ static void cascade(tvec_base_t *base, tvec_t *tv)
curr = next;
}
INIT_LIST_HEAD(head);
tv->index = (tv->index + 1) & TVN_MASK;
return tv->index = (tv->index + 1) & TVN_MASK;
}
/***
......@@ -322,26 +325,18 @@ static void cascade(tvec_base_t *base, tvec_t *tv)
*/
static inline void __run_timers(tvec_base_t *base)
{
unsigned long flags;
spin_lock_irqsave(&base->lock, flags);
spin_lock_irq(&base->lock);
while ((long)(jiffies - base->timer_jiffies) >= 0) {
struct list_head *head, *curr;
/*
* Cascade timers:
*/
if (!base->tv1.index) {
cascade(base, &base->tv2);
if (base->tv2.index == 1) {
cascade(base, &base->tv3);
if (base->tv3.index == 1) {
cascade(base, &base->tv4);
if (base->tv4.index == 1)
cascade(base, &base->tv5);
}
}
}
if (!base->tv1.index &&
(cascade(base, &base->tv2) == 1) &&
(cascade(base, &base->tv3) == 1) &&
cascade(base, &base->tv4) == 1)
cascade(base, &base->tv5);
repeat:
head = base->tv1.vec + base->tv1.index;
curr = head->next;
......@@ -360,7 +355,10 @@ static inline void __run_timers(tvec_base_t *base)
base->running_timer = timer;
#endif
spin_unlock_irq(&base->lock);
fn(data);
if (!fn)
printk("Bad: timer %p has NULL fn. (data: %08lx)\n", timer, data);
else
fn(data);
spin_lock_irq(&base->lock);
goto repeat;
}
......@@ -370,7 +368,7 @@ static inline void __run_timers(tvec_base_t *base)
#if CONFIG_SMP
base->running_timer = NULL;
#endif
spin_unlock_irqrestore(&base->lock, flags);
spin_unlock_irq(&base->lock);
}
/******************************************************************/
......
......@@ -77,7 +77,6 @@ static inline unsigned long radix_tree_maxindex(unsigned int height)
return index;
}
/*
* Extend a radix tree so it can store key @index.
*/
......@@ -109,16 +108,15 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index)
return 0;
}
/**
* radix_tree_reserve - reserve space in a radix tree
* radix_tree_insert - insert into a radix tree
* @root: radix tree root
* @index: index key
* @pslot: pointer to reserved slot
* @item: item to insert
*
* Reserve a slot in a radix tree for the key @index.
* Insert an item into the radix tree at position @index.
*/
int radix_tree_reserve(struct radix_tree_root *root, unsigned long index, void ***pslot)
int radix_tree_insert(struct radix_tree_root *root, unsigned long index, void *item)
{
struct radix_tree_node *node = NULL, *tmp, **slot;
unsigned int height, shift;
......@@ -158,36 +156,11 @@ int radix_tree_reserve(struct radix_tree_root *root, unsigned long index, void *
if (node)
node->count++;
*pslot = (void **)slot;
**pslot = RADIX_TREE_SLOT_RESERVED;
*slot = item;
return 0;
}
EXPORT_SYMBOL(radix_tree_reserve);
/**
* radix_tree_insert - insert into a radix tree
* @root: radix tree root
* @index: index key
* @item: item to insert
*
* Insert an item into the radix tree at position @index.
*/
int radix_tree_insert(struct radix_tree_root *root, unsigned long index, void *item)
{
void **slot;
int error;
error = radix_tree_reserve(root, index, &slot);
if (!error)
*slot = item;
return error;
}
EXPORT_SYMBOL(radix_tree_insert);
/**
* radix_tree_lookup - perform lookup operation on a radix tree
* @root: radix tree root
......@@ -267,8 +240,8 @@ __lookup(struct radix_tree_root *root, void **results, unsigned long index,
out:
*next_index = index;
return nr_found;
}
/**
* radix_tree_gang_lookup - perform multiple lookup on a radix tree
* @root: radix tree root
......@@ -371,7 +344,6 @@ int radix_tree_delete(struct radix_tree_root *root, unsigned long index)
return 0;
}
EXPORT_SYMBOL(radix_tree_delete);
static void radix_tree_node_ctor(void *node, kmem_cache_t *cachep, unsigned long flags)
......
......@@ -194,7 +194,8 @@ static inline unsigned long move_vma(struct vm_area_struct * vma,
prev->vm_end = next->vm_end;
__vma_unlink(mm, next, prev);
spin_unlock(&mm->page_table_lock);
if (vma == next)
vma = prev;
mm->map_count--;
kmem_cache_free(vm_area_cachep, next);
}
......
......@@ -199,16 +199,14 @@ void delete_from_swap_cache(struct page *page)
int move_to_swap_cache(struct page *page, swp_entry_t entry)
{
struct address_space *mapping = page->mapping;
void **pslot;
int err;
write_lock(&swapper_space.page_lock);
write_lock(&mapping->page_lock);
err = radix_tree_reserve(&swapper_space.page_tree, entry.val, &pslot);
err = radix_tree_insert(&swapper_space.page_tree, entry.val, page);
if (!err) {
__remove_from_page_cache(page);
*pslot = page;
___add_to_page_cache(page, &swapper_space, entry.val);
}
......@@ -231,7 +229,6 @@ int move_from_swap_cache(struct page *page, unsigned long index,
struct address_space *mapping)
{
swp_entry_t entry;
void **pslot;
int err;
BUG_ON(!PageLocked(page));
......@@ -243,10 +240,9 @@ int move_from_swap_cache(struct page *page, unsigned long index,
write_lock(&swapper_space.page_lock);
write_lock(&mapping->page_lock);
err = radix_tree_reserve(&mapping->page_tree, index, &pslot);
err = radix_tree_insert(&mapping->page_tree, index, page);
if (!err) {
__delete_from_swap_cache(page);
*pslot = page;
___add_to_page_cache(page, mapping, index);
}
......
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