summaryrefslogtreecommitdiff
path: root/fs/logfs/readwrite.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-03-05 14:07:33 (GMT)
committerTakashi Iwai <tiwai@suse.de>2012-03-05 14:07:33 (GMT)
commit650d6e25cde82fda425995ba77ed4b0ad3be5b8d (patch)
tree44ed9829a0b1797d4eea907aa1ed68273f7e3692 /fs/logfs/readwrite.c
parent6b21ed851624a03f11ea9ed3f229f56419e03686 (diff)
parentad20ff920c1fd217578e2c637dd50c1878a21c06 (diff)
downloadlinux-fsl-qoriq-650d6e25cde82fda425995ba77ed4b0ad3be5b8d.tar.xz
Merge tag 'asoc-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into topic/asoc
This has been a very active release for ASoC, as well as the usual raft of bugfixes and driver updates there's quite a few framework enhancements. Most are either small or are laying the groundwork for user visible features (especially dynamic PCM), the most directly visible change is the dmaengine library. There's also a bunch of regmap API enhancements pulled into the tree so that either the framework or drivers can take advantage of the new features. Changes include: - Support for widgets not associated with a CODEC, an important part of the dynamic PCM framework. - A library factoring out the common code shared by dmaengine based DMA drivers contributed by Lars-Peter Clausen. This will save a lot of code and make it much easier to deploy enhancements to dmaengine. - Support for binary controls, used for providing runtime configuration of algorithm coefficients. - A new DAPM widget type for regulator supplies allowing drivers for devices that can power down unused supplies while active to do without any per-driver code. - DAPM widgets for DAIs, initially giving a speed boost for playback startup and shutdown and also the basis for CODEC<->CODEC DAI link support. - Support for specifying the number of significant bits on audio interfaces, useful for allowing applications to know how much effort to put into generating data for a larger sample format. - Conversion of the FSI driver used on some SH processors to DMAEngine. - New CODEC drivers for Maxim MAX9768 and Wolfson Microelectronics WM2200.
Diffstat (limited to 'fs/logfs/readwrite.c')
-rw-r--r--fs/logfs/readwrite.c51
1 files changed, 34 insertions, 17 deletions
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c
index 2ac4217..4153e65 100644
--- a/fs/logfs/readwrite.c
+++ b/fs/logfs/readwrite.c
@@ -244,8 +244,7 @@ static void preunlock_page(struct super_block *sb, struct page *page, int lock)
* is waiting for s_write_mutex. We annotate this fact by setting PG_pre_locked
* in addition to PG_locked.
*/
-static void logfs_get_wblocks(struct super_block *sb, struct page *page,
- int lock)
+void logfs_get_wblocks(struct super_block *sb, struct page *page, int lock)
{
struct logfs_super *super = logfs_super(sb);
@@ -260,8 +259,7 @@ static void logfs_get_wblocks(struct super_block *sb, struct page *page,
}
}
-static void logfs_put_wblocks(struct super_block *sb, struct page *page,
- int lock)
+void logfs_put_wblocks(struct super_block *sb, struct page *page, int lock)
{
struct logfs_super *super = logfs_super(sb);
@@ -424,7 +422,7 @@ static void inode_write_block(struct logfs_block *block)
if (inode->i_ino == LOGFS_INO_MASTER)
logfs_write_anchor(inode->i_sb);
else {
- ret = __logfs_write_inode(inode, 0);
+ ret = __logfs_write_inode(inode, NULL, 0);
/* see indirect_write_block comment */
BUG_ON(ret);
}
@@ -560,8 +558,13 @@ static void inode_free_block(struct super_block *sb, struct logfs_block *block)
static void indirect_free_block(struct super_block *sb,
struct logfs_block *block)
{
- ClearPagePrivate(block->page);
- block->page->private = 0;
+ struct page *page = block->page;
+
+ if (PagePrivate(page)) {
+ ClearPagePrivate(page);
+ page_cache_release(page);
+ set_page_private(page, 0);
+ }
__free_block(sb, block);
}
@@ -650,8 +653,11 @@ static void alloc_data_block(struct inode *inode, struct page *page)
logfs_unpack_index(page->index, &bix, &level);
block = __alloc_block(inode->i_sb, inode->i_ino, bix, level);
block->page = page;
+
SetPagePrivate(page);
- page->private = (unsigned long)block;
+ page_cache_get(page);
+ set_page_private(page, (unsigned long) block);
+
block->ops = &indirect_block_ops;
}
@@ -1570,11 +1576,15 @@ int logfs_write_buf(struct inode *inode, struct page *page, long flags)
static int __logfs_delete(struct inode *inode, struct page *page)
{
long flags = WF_DELETE;
+ int err;
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
if (page->index < I0_BLOCKS)
return logfs_write_direct(inode, page, flags);
+ err = grow_inode(inode, page->index, 0);
+ if (err)
+ return err;
return logfs_write_rec(inode, page, page->index, 0, flags);
}
@@ -1623,7 +1633,7 @@ int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs,
if (inode->i_ino == LOGFS_INO_MASTER)
logfs_write_anchor(inode->i_sb);
else {
- err = __logfs_write_inode(inode, flags);
+ err = __logfs_write_inode(inode, page, flags);
}
}
}
@@ -1873,7 +1883,7 @@ int logfs_truncate(struct inode *inode, u64 target)
logfs_get_wblocks(sb, NULL, 1);
err = __logfs_truncate(inode, size);
if (!err)
- err = __logfs_write_inode(inode, 0);
+ err = __logfs_write_inode(inode, NULL, 0);
logfs_put_wblocks(sb, NULL, 1);
}
@@ -1901,8 +1911,11 @@ static void move_page_to_inode(struct inode *inode, struct page *page)
li->li_block = block;
block->page = NULL;
- page->private = 0;
- ClearPagePrivate(page);
+ if (PagePrivate(page)) {
+ ClearPagePrivate(page);
+ page_cache_release(page);
+ set_page_private(page, 0);
+ }
}
static void move_inode_to_page(struct page *page, struct inode *inode)
@@ -1918,8 +1931,12 @@ static void move_inode_to_page(struct page *page, struct inode *inode)
BUG_ON(PagePrivate(page));
block->ops = &indirect_block_ops;
block->page = page;
- page->private = (unsigned long)block;
- SetPagePrivate(page);
+
+ if (!PagePrivate(page)) {
+ SetPagePrivate(page);
+ page_cache_get(page);
+ set_page_private(page, (unsigned long) block);
+ }
block->inode = NULL;
li->li_block = NULL;
@@ -2106,14 +2123,14 @@ void logfs_set_segment_unreserved(struct super_block *sb, u32 segno, u32 ec)
ec_level);
}
-int __logfs_write_inode(struct inode *inode, long flags)
+int __logfs_write_inode(struct inode *inode, struct page *page, long flags)
{
struct super_block *sb = inode->i_sb;
int ret;
- logfs_get_wblocks(sb, NULL, flags & WF_LOCK);
+ logfs_get_wblocks(sb, page, flags & WF_LOCK);
ret = do_write_inode(inode);
- logfs_put_wblocks(sb, NULL, flags & WF_LOCK);
+ logfs_put_wblocks(sb, page, flags & WF_LOCK);
return ret;
}