afs/fs/cachefs super.c,1.40,1.41 kcachefs_jnld.c,1.7,1.8
journal.c,1.45,1.46 interface.c,1.17,1.18 index.c,1.31,1.32
cachefs-int.h,1.43,1.44 block.c,1.11,1.12
dwh at infradead.org
dwh at infradead.org
Tue Sep 16 18:49:28 BST 2003
Update of /home/cvs/afs/fs/cachefs
In directory phoenix.infradead.org:/tmp/cvs-serv19856/fs/cachefs
Modified Files:
super.c kcachefs_jnld.c journal.c interface.c index.c
cachefs-int.h block.c
Log Message:
added unjournalled block alteration and cookie index data update capability
Index: super.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/super.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- super.c 15 Sep 2003 18:00:19 -0000 1.40
+++ super.c 16 Sep 2003 16:49:25 -0000 1.41
@@ -293,10 +293,9 @@
INIT_LIST_HEAD(&super->ujnl_markq);
INIT_LIST_HEAD(&super->ujnl_commitq);
INIT_LIST_HEAD(&super->ujnl_writeq);
- INIT_LIST_HEAD(&super->ujnl_ackq);
- INIT_LIST_HEAD(&super->ujnl_ackwq);
INIT_LIST_HEAD(&super->ujnl_replayq);
+ spin_lock_init(&super->njalt_lock);
INIT_LIST_HEAD(&super->jnld_link);
init_MUTEX(&super->batch_sem);
Index: kcachefs_jnld.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/kcachefs_jnld.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- kcachefs_jnld.c 3 Sep 2003 12:44:19 -0000 1.7
+++ kcachefs_jnld.c 16 Sep 2003 16:49:25 -0000 1.8
@@ -115,11 +115,7 @@
down(&kcachefs_jnld_list_sem);
#if 0
- list_for_each(_p, &kcachefs_jnld_list) {
- super = list_entry(_p,
- struct cachefs_super,
- jnld_link);
-
+ list_for_each_entry(super, &kcachefs_jnld_list, jnld_link) {
cachefs_trans_write_batch(super);
if (super->ujnl_do_acks)
Index: journal.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/journal.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -r1.45 -r1.46
--- journal.c 15 Sep 2003 18:00:19 -0000 1.45
+++ journal.c 16 Sep 2003 16:49:25 -0000 1.46
@@ -301,30 +301,9 @@
BUG_ON(!effect->block->page);
-#ifndef CACHEFS_BLOCK_USE_COW
- /* wait for the page to be written back */
- if (test_bit(CACHEFS_BLOCK_WRITEBACK, &effect->block->flags)) {
- set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&effect->block->writewq, &myself);
-
- while (test_bit(CACHEFS_BLOCK_WRITEBACK,
- &effect->block->flags)) {
- if (signal_pending(current))
- break;
-
- schedule();
- set_current_state(TASK_INTERRUPTIBLE);
- }
-
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&effect->block->writewq, &myself);
- }
-
-#else
- /* duplicate the page */
+ /* duplicate the page if being written out */
if (test_bit(CACHEFS_BLOCK_COW, &effect->block->flags))
cachefs_block_cow(super, effect->block);
-#endif
get_page(effect->block->page);
effect->held_page = effect->block->page;
@@ -536,7 +515,7 @@
/*****************************************************************************/
/*
- * commit a replay transaction
+ * commit a replay transaction
* - discard any transaction that is "ineffective"
*/
void cachefs_trans_commit_replay(struct cachefs_transaction *trans)
@@ -565,6 +544,126 @@
/*****************************************************************************/
/*
+ * begin an unjournalled alteration of a block
+ */
+int cachefs_block_begin_alter(struct cachefs_block *block)
+{
+ struct cachefs_alteration *alter;
+ struct cachefs_super *super = block->super;
+
+ _enter("{%u}", block->bix);
+
+ BUG_ON(!block->page);
+ BUG_ON(!block->page->private);
+ BUG_ON(test_bit(CACHEFS_BLOCK_NETFSDATA, &block->flags));
+
+ alter = kmalloc(sizeof(*alter), GFP_KERNEL);
+ if (!alter) {
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
+ }
+
+ down_read(&super->batch_ctrl_sem);
+
+ alter->effect.block = block;
+ alter->effect.held_page = block->page;
+
+ if (!test_and_set_bit(CACHEFS_BLOCK_ALTERED, &block->flags)) {
+ cachefs_block_get(block);
+ get_page(alter->effect.held_page);
+
+ spin_lock(&super->njalt_lock);
+ alter->next = super->njalt_markq;
+ super->njalt_markq = alter;
+ spin_unlock(&super->njalt_lock);
+
+ SetPageWriteback(alter->effect.held_page);
+ }
+ else {
+ kfree(alter);
+ }
+
+ /* duplicate the page if it's currently being written out */
+ if (test_bit(CACHEFS_BLOCK_COW, &block->flags))
+ cachefs_block_cow(super, block);
+
+ _leave("");
+ return 0;
+} /* end cachefs_block_begin_alter() */
+
+/*****************************************************************************/
+/*
+ * end an unjournalled alteration of a block
+ */
+void cachefs_block_end_alter(struct cachefs_block *block)
+{
+ struct cachefs_super *super = block->super;
+
+ _enter("{%u}", block->bix);
+
+ up_read(&super->batch_ctrl_sem);
+
+ _leave("");
+} /* end cachefs_block_end_alter() */
+
+/*****************************************************************************/
+/*
+ * prepare a block for writing
+ */
+static inline void cachefs_trans_batch_prep_block(struct cachefs_super *super,
+ struct cachefs_trans_effect *effect)
+{
+ struct cachefs_block *block = effect->block;
+ struct list_head *plist;
+
+ BUG_ON(!block->page);
+ BUG_ON(!block->page->private);
+
+ if (test_bit(CACHEFS_BLOCK_WRITEBACK, &block->flags))
+ return;
+
+ set_bit(CACHEFS_BLOCK_COW , &block->flags);
+ set_bit(CACHEFS_BLOCK_WRITEBACK , &block->flags);
+
+ plist = &super->batch_writeq;
+ if (test_bit(CACHEFS_BLOCK_NETFSDATA, &block->flags)) {
+ plist = &super->batch_doneq;
+ _debug("skip meta block %u", block->bix);
+ }
+
+ list_add_tail(&block->batch_link, plist);
+ block->writeback = block->page;
+ get_page(block->writeback);
+ flush_dcache_page(block->writeback);
+
+} /* end cachefs_trans_batch_prep_block() */
+
+/*****************************************************************************/
+/*
+ * prepare the unjournalled block alterations for writing
+ */
+static void cachefs_trans_batch_prep_njalt(struct cachefs_super *super)
+{
+ struct cachefs_alteration *alter;
+
+ _enter("");
+
+ BUG_ON(super->njalt_writeq);
+
+ alter = super->njalt_markq;
+ super->njalt_markq = NULL;
+ super->njalt_writeq = alter;
+
+ for (; alter; alter = alter->next) {
+ _debug("- %x", alter->effect.block->bix);
+ cachefs_trans_batch_prep_block(super, &alter->effect);
+ }
+
+ _leave("");
+} /* end cachefs_trans_batch_prep_njalt() */
+
+/*****************************************************************************/
+/*
* prepare a transaction for writing
* - mark all modified journalling and data blocks for writeback
* - mark data for COW
@@ -592,32 +691,11 @@
}
/* mark data blocks */
- for (loop = 0; loop < CACHEFS_EFFECTS_PER_TRANS; loop++) {
- block = trans->effects[loop].block;
- if (!block)
- continue;
-
- BUG_ON(!block->page);
- BUG_ON(!block->page->private);
-
- if (!test_bit(CACHEFS_BLOCK_WRITEBACK, &block->flags)) {
- struct list_head *plist;
-
- set_bit(CACHEFS_BLOCK_COW ,&block->flags);
- set_bit(CACHEFS_BLOCK_WRITEBACK ,&block->flags);
-
- plist = &super->batch_writeq;
- if (test_bit(CACHEFS_BLOCK_NETFSDATA, &block->flags)) {
- plist = &super->batch_doneq;
- _debug("skip meta block %u", block->bix);
- }
+ for (loop = 0; loop < CACHEFS_EFFECTS_PER_TRANS; loop++)
+ if (trans->effects[loop].block)
+ cachefs_trans_batch_prep_block(super,
+ &trans->effects[loop]);
- list_add_tail(&block->batch_link, plist);
- block->writeback = block->page;
- get_page(block->writeback);
- flush_dcache_page(block->writeback);
- }
- }
} /* end cachefs_trans_batch_write_prep_trans() */
/*****************************************************************************/
@@ -628,6 +706,7 @@
{
struct cachefs_ondisc_update_journal *ajentry;
struct cachefs_transaction *trans;
+ struct cachefs_alteration *alter;
struct cachefs_block *block;
unsigned short jstop;
unsigned long flags;
@@ -653,7 +732,7 @@
* out */
down_write(&super->batch_ctrl_sem);
- if (list_empty(&super->ujnl_commitq))
+ if (list_empty(&super->ujnl_commitq) && !super->njalt_markq)
goto nothing_to_do;
BUG_ON(!list_empty(&super->ujnl_markq));
@@ -662,6 +741,8 @@
cachefs_trans_batch_write_prep_trans(super, trans);
}
+ cachefs_trans_batch_prep_njalt(super);
+
spin_lock_irqsave(&super->ujnl_mk_lock, flags);
list_splice_init(&super->ujnl_commitq, &super->ujnl_writeq);
spin_unlock_irqrestore(&super->ujnl_mk_lock, flags);
@@ -698,45 +779,61 @@
up_write(&super->batch_ctrl_sem);
- /* write to the update journal with a barrier if we're not replaying
- * and then write the data (if we're replaying, all the journal entries
- * bar the ACK already reside on disc) */
- if (!test_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags))
+ /* write to the update journal with a barrier if there are any
+ * transactions to record and if we're not replaying them (if we're
+ * replaying, all the journal entries bar the ACK already reside on
+ * disc) */
+ if (!test_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags) &&
+ !list_empty(&super->ujnl_writeq)
+ ) {
cachefs_trans_batch_write_ujnl(super, jstop);
- ajentry->mark = CACHEFS_ONDISC_UJNL_BATCH;
+ ajentry->mark = CACHEFS_ONDISC_UJNL_BATCH;
- if (!test_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags))
cachefs_trans_batch_write_marker(super, jstop, ajentry);
- else
+ }
+ else {
up(&super->batch_uj_sem);
+ }
cachefs_trans_batch_write_data(super);
cachefs_trans_batch_process_written_blocks(super, 2);
- /* polish off with an ACK */
- if (!test_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags))
- jstop = UJNL_WRAP(jstop + 1);
-
- ajentry->mark = CACHEFS_ONDISC_UJNL_ACK;
- ajentry->serial++;
-
- cachefs_trans_batch_write_ack(super, jstop, ajentry);
- kfree(ajentry);
-
- super->ujnl_tail = UJNL_WRAP(jstop + 1);
-
- /* clean up the transactions that we've now written */
- while (!list_empty(&super->ujnl_writeq)) {
- trans = list_entry(super->ujnl_writeq.next,
- struct cachefs_transaction, sblink);
- list_del_init(&trans->sblink);
+ /* polish off with an ACK if any entries were recorded */
+ if (!list_empty(&super->ujnl_writeq)) {
+ if (!test_bit(CACHEFS_SUPER_REPLAYING_UJNL, &super->flags))
+ jstop = UJNL_WRAP(jstop + 1);
+
+ ajentry->mark = CACHEFS_ONDISC_UJNL_ACK;
+ ajentry->serial++;
+
+ cachefs_trans_batch_write_ack(super, jstop, ajentry);
+ kfree(ajentry);
+
+ super->ujnl_tail = UJNL_WRAP(jstop + 1);
+
+ /* clean up the transactions that we've now written */
+ while (!list_empty(&super->ujnl_writeq)) {
+ trans = list_entry(super->ujnl_writeq.next,
+ struct cachefs_transaction, sblink);
+ list_del_init(&trans->sblink);
+
+ cachefs_ujnl_set_phase(trans,
+ CACHEFS_TRANS_DEAD,
+ CACHEFS_TRANS_COMMITTING);
- cachefs_ujnl_set_phase(trans,
- CACHEFS_TRANS_DEAD,
- CACHEFS_TRANS_COMMITTING);
+ cachefs_trans_put(trans);
+ }
+ }
- cachefs_trans_put(trans);
+ /* clean up any unjournalled alterations we may have written */
+ while (super->njalt_writeq) {
+ alter = super->njalt_writeq;
+ super->njalt_writeq = alter->next;
+
+ cachefs_block_put(alter->effect.block);
+ cachefs_put_page(alter->effect.held_page);
+ kfree(alter);
}
done:
@@ -1105,8 +1202,8 @@
try_again:
ret = cachefs_block_read(super, NULL, bix, 1, &jblock, &jpage);
- if (ret<0)
- goto cant_read_block;;
+ if (ret < 0)
+ goto cant_read_block;
set_bit(CACHEFS_BLOCK_UJOURNAL, &jblock->flags);
set_bit(CACHEFS_BLOCK_WRITEBACK, &jblock->flags);
@@ -1139,10 +1236,6 @@
//dump_bio(bio,1);
-#if 0
- BUG(); /* TODO: remove (for replay testing) */
-#endif
-
submit_bio(WRITE | (1 << BIO_RW_BARRIER), bio);
/* wait for I/O completion */
@@ -1276,11 +1369,12 @@
_debug(" wrote block %05u fl=%04lx pg=%p wb=%p",
block->bix, block->flags, block->page, block->writeback);
+ wbpage = xchg(&block->writeback, NULL);
+
clear_bit(CACHEFS_BLOCK_COW, &block->flags);
clear_bit(CACHEFS_BLOCK_WRITEBACK, &block->flags);
wake_up_all(&block->writewq);
- wbpage = xchg(&block->writeback, NULL);
BUG_ON(!wbpage);
end_page_writeback(wbpage);
put_page(wbpage);
Index: interface.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/interface.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- interface.c 19 Aug 2003 13:37:07 -0000 1.17
+++ interface.c 16 Sep 2003 16:49:26 -0000 1.18
@@ -808,6 +808,37 @@
/*****************************************************************************/
/*
+ * update the index entries backing a cookie
+ */
+void __cachefs_update_cookie(struct cachefs_cookie *cookie)
+{
+ struct cachefs_inode *inode;
+
+ _enter("{%s}",
+ cookie &&
+ cookie->idef ? (char *) cookie->idef->name : "<file>");
+
+ if (!cookie) {
+ _leave(" [no cookie]");
+ return;
+ }
+
+ down_read(&cookie->sem);
+ down_read(&cookie->iparent->sem);
+
+ list_for_each_entry(inode, &cookie->backing_inodes, cookie_link) {
+ cachefs_index_update(inode);
+ }
+
+ up_read(&cookie->iparent->sem);
+ up_read(&cookie->sem);
+ _leave("");
+} /* end __cachefs_update_cookie() */
+
+EXPORT_SYMBOL(__cachefs_update_cookie);
+
+/*****************************************************************************/
+/*
* see if the netfs definition matches
*/
static cachefs_match_val_t cachefs_fsdef_index_match(void *target,
Index: index.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/index.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- index.c 12 Sep 2003 13:01:17 -0000 1.31
+++ index.c 16 Sep 2003 16:49:26 -0000 1.32
@@ -686,6 +686,79 @@
/*****************************************************************************/
/*
+ * update the index entry for an index or data file from the associated netfs
+ * data
+ */
+int cachefs_index_update(struct cachefs_inode *inode)
+{
+ struct cachefs_ondisc_index_entry *xent;
+ struct cachefs_ondisc_metadata *meta;
+ struct cachefs_cookie *cookie = inode->cookie;
+ struct cachefs_super *super;
+ struct cachefs_inode *index;
+ struct cachefs_block *block;
+ struct page *ixpage;
+ unsigned offs;
+ int ret;
+
+ _enter("");
+
+ super = inode->vfs_inode.i_sb->s_fs_info;
+
+ if (test_bit(CACHEFS_SUPER_WITHDRAWN, &super->flags))
+ return 0;
+
+ /* find the parent index inode */
+ list_for_each_entry(index,
+ &cookie->iparent->backing_inodes,
+ cookie_link) {
+ if (index->vfs_inode.i_sb == inode->vfs_inode.i_sb)
+ goto found;
+ }
+
+ /* hmmm... parent inode is strangely absent */
+ BUG();
+ return -ENOENT;
+
+ found:
+ meta = cachefs_metadata_preread(inode);
+ offs = meta->pindex_entry;
+ cachefs_metadata_postread(inode);
+
+ /* get the page holding the index data */
+ ret = cachefs_get_page(index, offs / index->index_epp, &ixpage);
+ if (ret < 0) {
+ _leave(" = %d",ret);
+ return ret;
+ }
+
+ offs = (offs % index->index_epp) * index->index_esize;
+
+ _debug("update ino=%lx pg={%lu}+%x",
+ index->vfs_inode.i_ino, ixpage->index, offs);
+
+ block = __cachefs_get_page_block(ixpage);
+ ret = cachefs_block_begin_alter(block);
+ if (ret < 0)
+ goto error_page;
+
+ cachefs_block_modify(super, block, &ixpage);
+
+ xent = kmap(ixpage) + offs;
+ cookie->iparent->idef->update(cookie->netfs_data, xent->data);
+ kunmap(ixpage);
+
+ cachefs_block_end_alter(block);
+
+ error_page:
+ cachefs_put_page(ixpage);
+ _leave(" = %d", ret);
+ return ret;
+
+} /* end cachefs_index_update() */
+
+/*****************************************************************************/
+/*
* mark the next inode pinned by an entry in the index currently being
* reclaimed as being obsolete
*/
Index: cachefs-int.h
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/cachefs-int.h,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- cachefs-int.h 15 Sep 2003 13:53:25 -0000 1.43
+++ cachefs-int.h 16 Sep 2003 16:49:26 -0000 1.44
@@ -142,10 +142,12 @@
struct list_head ujnl_markq; /* marked transactions */
struct list_head ujnl_commitq; /* committed transactions */
struct list_head ujnl_writeq; /* transactions being written */
- struct list_head ujnl_ackq; /* marks ACK'd by transaction completion */
- struct list_head ujnl_ackwq; /* marks awaiting on-disc ACK */
struct list_head ujnl_replayq; /* blocks having allocation replayed */
+ struct cachefs_alteration *njalt_markq; /* unjournalled alterations - marked */
+ struct cachefs_alteration *njalt_writeq; /* unjournalled alterations - writing */
+ spinlock_t njalt_lock;
+
struct semaphore batch_sem; /* batching mutex */
struct semaphore batch_uj_sem; /* ujnl written sync mutex */
struct rw_semaphore batch_ctrl_sem; /* marking/batching interleave control */
@@ -227,6 +229,7 @@
#define CACHEFS_BLOCK_WITHDRAWN 7 /* [bit] backing cache withdrawn from service */
#define CACHEFS_BLOCK_NETFSDATA 8 /* [bit] netfs data block (discard metadata) */
#define CACHEFS_BLOCK_NETFSBUSY 9 /* [bit] netfs is accessing the block */
+#define CACHEFS_BLOCK_ALTERED 10 /* [bit] unjournalled alteration made */
#define _CACHEFS_BLOCK_ALLOC (1 << CACHEFS_BLOCK_ALLOC)
#define _CACHEFS_BLOCK_COW (1 << CACHEFS_BLOCK_COW)
@@ -279,6 +282,9 @@
extern int cachefs_block_cow(struct cachefs_super *super,
struct cachefs_block *block);
+extern int cachefs_block_begin_alter(struct cachefs_block *block);
+extern void cachefs_block_end_alter(struct cachefs_block *block);
+
static inline
struct cachefs_block *cachefs_block_get(struct cachefs_block *block)
{
@@ -451,6 +457,8 @@
struct cachefs_cookie *cookie,
unsigned *_newino);
+extern int cachefs_index_update(struct cachefs_inode *index);
+
extern int cachefs_index_reclaim_one_entry(struct cachefs_super *super,
struct cachefs_transaction **_trans);
@@ -484,7 +492,7 @@
/*****************************************************************************/
/*
- * transaction record and tracking structure
+ * transaction record and tracking structures
* - these record the modification of metadata (and not, generally, ordinary data)
*/
enum cachefs_trans_phase {
@@ -532,6 +540,13 @@
/* tracking for blocks being modified by this transaction */
unsigned eff_active;
struct cachefs_trans_effect effects[CACHEFS_EFFECTS_PER_TRANS];
+};
+
+/* record of unjournalled alteration */
+struct cachefs_alteration
+{
+ struct cachefs_alteration *next;
+ struct cachefs_trans_effect effect;
};
extern
Index: block.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/block.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- block.c 15 Sep 2003 13:53:25 -0000 1.11
+++ block.c 16 Sep 2003 16:49:26 -0000 1.12
@@ -222,8 +222,8 @@
/* get a page for it if it doesn't already exist */
if (!block->page) {
/* if the block is marked as currently undergoing writeback
- * then there was an ENOMEM encountered whilst trying to COW
- * the block */
+ * then there must have been an ENOMEM encountered whilst
+ * trying to COW the block */
if (test_bit(CACHEFS_BLOCK_WRITEBACK,&block->flags)) {
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&block->writewq,&myself);
@@ -302,17 +302,44 @@
/*****************************************************************************/
/*
- * copy a block upon attempting to modify it and finding that it's busy being written
+ * copy a block upon attempting to modify it and finding that it's busy being
+ * written out
*/
int cachefs_block_cow(struct cachefs_super *super, struct cachefs_block *block)
{
-// struct address_space *mapping;
- struct page *page; //, *newpage;
- filler_t filler;
-// int ret;
+ _enter(",{%u}", block->bix);
DECLARE_WAITQUEUE(myself, current);
+#ifndef CACHEFS_BLOCK_USE_COW
+
+ /* if COW is not permitted, then simply wait for the page to finish
+ * being written back */
+ if (test_bit(CACHEFS_BLOCK_COW, &block->flags)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ add_wait_queue(&block->writewq, &myself);
+
+ while (test_bit(CACHEFS_BLOCK_COW, &block->flags)) {
+ if (signal_pending(current))
+ break;
+
+ schedule();
+ set_current_state(TASK_INTERRUPTIBLE);
+ }
+
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&block->writewq, &myself);
+ }
+
+ _leave(" = 0");
+ return 0;
+
+#else
+ struct address_space *mapping;
+ struct page *page, *newpage;
+ filler_t filler;
+ int ret;
+
_enter(",%u", block->bix);
/* get the page alloc lock for this block */
@@ -331,19 +358,18 @@
/* duplicate the page if it's flagged copy-on-write */
if (test_bit(CACHEFS_BLOCK_COW, &block->flags)) {
- BUG();
-#if 0
struct cachefs_page *newpageio;
mapping = super->imisc->i_mapping;
+ ret = -ENOMEM;
newpage = page_cache_alloc_cold(mapping);
if (!newpage)
- goto nomem;
+ goto error;
- if (cachefs_get_page_private(newpage, &newpageio,
- mapping->gfp_mask) < 0)
- goto nomem_page;
+ if (cachefs_page_get_private(newpage, &newpageio,
+ mapping_gfp_mask(mapping)) < 0)
+ goto error_page;
newpageio->mapped_block =
cachefs_block_get(
@@ -362,15 +388,13 @@
page = NULL;
ret = add_to_page_cache_lru(newpage, mapping, block->bix,
- GFP_KERNEL);
- if (ret<0) {
+ mapping_gfp_mask(mapping));
+ if (ret < 0) {
BUG_ON(ret == -EEXIST);
- page_cache_release(newpage);
- return ret;
+ goto error_page;
}
block->page = newpage;
-#endif
}
else {
page = block->page;
@@ -383,15 +407,14 @@
_leave(" = 0");
return 0;
-#if 0
- nomem_page:
+ error_page:
page_cache_release(newpage);
- nomem:
+ error:
clear_bit(CACHEFS_BLOCK_ALLOC, &block->flags);
wake_up_all(&block->writewq);
- _leave(" = -ENOMEM");
- return -ENOMEM;
+ _leave(" = %d", ret);
+ return ret;
#endif
} /* end cachefs_block_cow() */
More information about the linux-afs-cvs
mailing list