summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-04-21 17:12:16 +0900
committerPaul Mundt <lethal@linux-sh.org>2009-04-21 17:12:16 +0900
commit4db25d496c09fdf094d52d11a90ae51f9ee473c6 (patch)
tree77ab8003db1d6ccbcf3a9acafad26002fba37b63 /fs
parentb8c193f88ebd8705b3e916532539031cd9fc0b4c (diff)
parent8c31813f31cd4403b46802866949a95a6e8fa584 (diff)
downloadkernel-crypto-4db25d496c09fdf094d52d11a90ae51f9ee473c6.tar.gz
kernel-crypto-4db25d496c09fdf094d52d11a90ae51f9ee473c6.tar.xz
kernel-crypto-4db25d496c09fdf094d52d11a90ae51f9ee473c6.zip
Merge branch 'sh/stable-updates' into sh/for-2.6.30
Diffstat (limited to 'fs')
-rw-r--r--fs/afs/file.c2
-rw-r--r--fs/buffer.c45
-rw-r--r--fs/fat/Kconfig3
-rw-r--r--fs/proc/base.c4
-rw-r--r--fs/splice.c3
-rw-r--r--fs/sysfs/file.c16
6 files changed, 55 insertions, 18 deletions
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 7a1d942ef68..0149dab365e 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -102,6 +102,7 @@ int afs_release(struct inode *inode, struct file *file)
return 0;
}
+#ifdef CONFIG_AFS_FSCACHE
/*
* deal with notification that a page was read from the cache
*/
@@ -117,6 +118,7 @@ static void afs_file_readpage_read_complete(struct page *page,
SetPageUptodate(page);
unlock_page(page);
}
+#endif
/*
* AFS read page from file, directory or symlink
diff --git a/fs/buffer.c b/fs/buffer.c
index ff8bb1f2333..b3e5be7514f 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -360,7 +360,7 @@ still_busy:
* Completion handler for block_write_full_page() - pages which are unlocked
* during I/O, and which have PageWriteback cleared upon I/O completion.
*/
-static void end_buffer_async_write(struct buffer_head *bh, int uptodate)
+void end_buffer_async_write(struct buffer_head *bh, int uptodate)
{
char b[BDEVNAME_SIZE];
unsigned long flags;
@@ -438,11 +438,17 @@ static void mark_buffer_async_read(struct buffer_head *bh)
set_buffer_async_read(bh);
}
-void mark_buffer_async_write(struct buffer_head *bh)
+void mark_buffer_async_write_endio(struct buffer_head *bh,
+ bh_end_io_t *handler)
{
- bh->b_end_io = end_buffer_async_write;
+ bh->b_end_io = handler;
set_buffer_async_write(bh);
}
+
+void mark_buffer_async_write(struct buffer_head *bh)
+{
+ mark_buffer_async_write_endio(bh, end_buffer_async_write);
+}
EXPORT_SYMBOL(mark_buffer_async_write);
@@ -1615,7 +1621,8 @@ EXPORT_SYMBOL(unmap_underlying_metadata);
* unplugging the device queue.
*/
static int __block_write_full_page(struct inode *inode, struct page *page,
- get_block_t *get_block, struct writeback_control *wbc)
+ get_block_t *get_block, struct writeback_control *wbc,
+ bh_end_io_t *handler)
{
int err;
sector_t block;
@@ -1700,7 +1707,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
continue;
}
if (test_clear_buffer_dirty(bh)) {
- mark_buffer_async_write(bh);
+ mark_buffer_async_write_endio(bh, handler);
} else {
unlock_buffer(bh);
}
@@ -1753,7 +1760,7 @@ recover:
if (buffer_mapped(bh) && buffer_dirty(bh) &&
!buffer_delay(bh)) {
lock_buffer(bh);
- mark_buffer_async_write(bh);
+ mark_buffer_async_write_endio(bh, handler);
} else {
/*
* The buffer may have been set dirty during
@@ -2679,7 +2686,8 @@ int nobh_writepage(struct page *page, get_block_t *get_block,
out:
ret = mpage_writepage(page, get_block, wbc);
if (ret == -EAGAIN)
- ret = __block_write_full_page(inode, page, get_block, wbc);
+ ret = __block_write_full_page(inode, page, get_block, wbc,
+ end_buffer_async_write);
return ret;
}
EXPORT_SYMBOL(nobh_writepage);
@@ -2837,9 +2845,10 @@ out:
/*
* The generic ->writepage function for buffer-backed address_spaces
+ * this form passes in the end_io handler used to finish the IO.
*/
-int block_write_full_page(struct page *page, get_block_t *get_block,
- struct writeback_control *wbc)
+int block_write_full_page_endio(struct page *page, get_block_t *get_block,
+ struct writeback_control *wbc, bh_end_io_t *handler)
{
struct inode * const inode = page->mapping->host;
loff_t i_size = i_size_read(inode);
@@ -2848,7 +2857,8 @@ int block_write_full_page(struct page *page, get_block_t *get_block,
/* Is the page fully inside i_size? */
if (page->index < end_index)
- return __block_write_full_page(inode, page, get_block, wbc);
+ return __block_write_full_page(inode, page, get_block, wbc,
+ handler);
/* Is the page fully outside i_size? (truncate in progress) */
offset = i_size & (PAGE_CACHE_SIZE-1);
@@ -2871,9 +2881,20 @@ int block_write_full_page(struct page *page, get_block_t *get_block,
* writes to that region are not written out to the file."
*/
zero_user_segment(page, offset, PAGE_CACHE_SIZE);
- return __block_write_full_page(inode, page, get_block, wbc);
+ return __block_write_full_page(inode, page, get_block, wbc, handler);
}
+/*
+ * The generic ->writepage function for buffer-backed address_spaces
+ */
+int block_write_full_page(struct page *page, get_block_t *get_block,
+ struct writeback_control *wbc)
+{
+ return block_write_full_page_endio(page, get_block, wbc,
+ end_buffer_async_write);
+}
+
+
sector_t generic_block_bmap(struct address_space *mapping, sector_t block,
get_block_t *get_block)
{
@@ -3342,9 +3363,11 @@ EXPORT_SYMBOL(block_read_full_page);
EXPORT_SYMBOL(block_sync_page);
EXPORT_SYMBOL(block_truncate_page);
EXPORT_SYMBOL(block_write_full_page);
+EXPORT_SYMBOL(block_write_full_page_endio);
EXPORT_SYMBOL(cont_write_begin);
EXPORT_SYMBOL(end_buffer_read_sync);
EXPORT_SYMBOL(end_buffer_write_sync);
+EXPORT_SYMBOL(end_buffer_async_write);
EXPORT_SYMBOL(file_fsync);
EXPORT_SYMBOL(generic_block_bmap);
EXPORT_SYMBOL(generic_cont_expand_simple);
diff --git a/fs/fat/Kconfig b/fs/fat/Kconfig
index d0a69ff2537..182f9ffe2b5 100644
--- a/fs/fat/Kconfig
+++ b/fs/fat/Kconfig
@@ -95,3 +95,6 @@ config FAT_DEFAULT_IOCHARSET
Note that "utf8" is not recommended for FAT filesystems.
If unsure, you shouldn't set "utf8" here.
See <file:Documentation/filesystems/vfat.txt> for more information.
+
+ Enable any character sets you need in File Systems/Native Language
+ Support.
diff --git a/fs/proc/base.c b/fs/proc/base.c
index f71559784bf..aa763ab0077 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -648,14 +648,14 @@ static unsigned mounts_poll(struct file *file, poll_table *wait)
{
struct proc_mounts *p = file->private_data;
struct mnt_namespace *ns = p->ns;
- unsigned res = 0;
+ unsigned res = POLLIN | POLLRDNORM;
poll_wait(file, &ns->poll, wait);
spin_lock(&vfsmount_lock);
if (p->event != ns->event) {
p->event = ns->event;
- res = POLLERR;
+ res |= POLLERR | POLLPRI;
}
spin_unlock(&vfsmount_lock);
diff --git a/fs/splice.c b/fs/splice.c
index 5384a90665d..666953d59a3 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -614,7 +614,6 @@ static void wakeup_pipe_writers(struct pipe_inode_info *pipe)
* @actor: handler that splices the data
*
* Description:
-
* This function loops over the pipe and calls @actor to do the
* actual moving of a single struct pipe_buffer to the desired
* destination. It returns when there's no more buffers left in
@@ -711,7 +710,7 @@ EXPORT_SYMBOL(splice_from_pipe_next);
/**
* splice_from_pipe_begin - start splicing from pipe
- * @pipe: pipe to splice from
+ * @sd: information about the splice operation
*
* Description:
* This function should be called before a loop containing
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 289c43a4726..b1606e07b7a 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -446,11 +446,11 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
if (buffer->event != atomic_read(&od->event))
goto trigger;
- return 0;
+ return DEFAULT_POLLMASK;
trigger:
buffer->needs_read_fill = 1;
- return POLLERR|POLLPRI;
+ return DEFAULT_POLLMASK|POLLERR|POLLPRI;
}
void sysfs_notify_dirent(struct sysfs_dirent *sd)
@@ -667,6 +667,7 @@ struct sysfs_schedule_callback_struct {
struct work_struct work;
};
+static struct workqueue_struct *sysfs_workqueue;
static DEFINE_MUTEX(sysfs_workq_mutex);
static LIST_HEAD(sysfs_workq);
static void sysfs_schedule_callback_work(struct work_struct *work)
@@ -715,11 +716,20 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
mutex_lock(&sysfs_workq_mutex);
list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list)
if (ss->kobj == kobj) {
+ module_put(owner);
mutex_unlock(&sysfs_workq_mutex);
return -EAGAIN;
}
mutex_unlock(&sysfs_workq_mutex);
+ if (sysfs_workqueue == NULL) {
+ sysfs_workqueue = create_workqueue("sysfsd");
+ if (sysfs_workqueue == NULL) {
+ module_put(owner);
+ return -ENOMEM;
+ }
+ }
+
ss = kmalloc(sizeof(*ss), GFP_KERNEL);
if (!ss) {
module_put(owner);
@@ -735,7 +745,7 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
mutex_lock(&sysfs_workq_mutex);
list_add_tail(&ss->workq_list, &sysfs_workq);
mutex_unlock(&sysfs_workq_mutex);
- schedule_work(&ss->work);
+ queue_work(sysfs_workqueue, &ss->work);
return 0;
}
EXPORT_SYMBOL_GPL(sysfs_schedule_callback);