<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/">
  <channel rdf:about="http://blog.gmane.org/gmane.linux.file-systems.cachefs.general">
    <title>gmane.linux.file-systems.cachefs.general</title>
    <link>http://blog.gmane.org/gmane.linux.file-systems.cachefs.general</link>
    <description/>
    <syn:updatePeriod>hourly</syn:updatePeriod>
    <syn:updateFrequency>1</syn:updateFrequency>
    <syn:updateBase>1901-01-01T00:00+00:00</syn:updateBase>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3103"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3100"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3099"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3098"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3097"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3095"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3094"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3092"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3091"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3090"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3089"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3088"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3087"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3086"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3085"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3084"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3082"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3081"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3080"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3079"/>
      </rdf:Seq>
    </items>
    <image rdf:resource="http://gmane.org/img/gmane-25t.png"/>
    <textinput rdf:resource=""/>
  </channel>
  <image rdf:about="http://gmane.org/img/gmane-25t.png">
    <title>Gmane</title>
    <url>http://gmane.org/img/gmane-25t.png</url>
    <link>http://gmane.org</link>
  </image>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3103">
    <title>Re: [PATCH] fs: cachefiles: Add support for largefiles in filesystem caching</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3103</link>
    <description>&lt;pre&gt;Hello David,

This patch doesn't seem to have made it to linux-next (for May 21),
yet. Could you kindly re-check?

Thanks
Suresh



On Tue, May 1, 2012 at 2:43 PM, David Howells &amp;lt;dhowells&amp;lt; at &amp;gt;redhat.com&amp;gt; wrote:

&lt;/pre&gt;</description>
    <dc:creator>Suresh Jayaraman</dc:creator>
    <dc:date>2012-05-22T05:05:58</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3100">
    <title>NFS caching on the server-side</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3100</link>
    <description>&lt;pre&gt;Hello,
I need help for configuring a NFS version 4 server for caching what clients read
from it. That is, the server has to cache locally (not the client) what any NFS
client reads from this server. The porpouse of this configuration if to relief
the work load of the server HDD.

Any suggestion or recommendation will be appreciated.
Abraham Aldaco
abraham.aldaco&amp;lt; at &amp;gt;gmail.com

&lt;/pre&gt;</description>
    <dc:creator>Abraham Aldaco</dc:creator>
    <dc:date>2012-04-26T16:06:02</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3099">
    <title>nfs/fscache writeback cache</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3099</link>
    <description>&lt;pre&gt;Hi,
First of all, I am not sure if this list is appropriate place to ask that
question but I think it is the most relevant one. I saw this project
proposal[1] on the Fedora Project's GSOC 2012 ideas page few weeks ago. It
proposes to add writeback caching support to NFS. I didn't apply to GSOC
since I am not a student but I want to spend my time working on that
project although this is not accepted by GSOC. I want to learn that is
there any ongoing effort on that side? If any, could you point me to that
so that i will not duplicate work and I can contribute to current project.

[1] -
http://fedoraproject.org/wiki/Summer_coding_ideas_for_2012#Linux_kernel_project

Thanks
&lt;/pre&gt;</description>
    <dc:creator>Sertaç Olgunsoylu</dc:creator>
    <dc:date>2012-04-26T03:10:28</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3098">
    <title>Re: [PATCH] fs: cachefiles: Add support for largefiles in filesystem caching</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3098</link>
    <description>&lt;pre&gt;
While preparing a similar patch to make cachefiles support files larger
than 2GB, I noticed that you had beaten me to it. Confirming that this
patch allows caching of larger files which would not be cached otherwise.

Tested-by: Suresh Jayaraman &amp;lt;sjayaraman&amp;lt; at &amp;gt;suse.com&amp;gt;


diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
&lt;/pre&gt;</description>
    <dc:creator>Suresh Jayaraman</dc:creator>
    <dc:date>2012-04-11T14:57:22</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3097">
    <title>oops when I mount nfs with -o fsc</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3097</link>
    <description>&lt;pre&gt;Hi: in nfs(RHEL6.x), i do as following. 
#cat /etc/exports
    /nfsroot      *(rw,no_root_squash,fsid=0,insecure)
#mount –t nfs4 –o fsc localhost:/   /nfsmnt
#sh create_file.sh

wait a while, i find oops.

PID: 4196   TASK: ffff88012365b580  CPU: 0   COMMAND: "sh"
 #0 [ffff880139435750] machine_kexec at ffffffff810310db
 #1 [ffff8801394357b0] crash_kexec at ffffffff810b63b2
 #2 [ffff880139435880] oops_end at ffffffff814dec50
 #3 [ffff8801394358b0] die at ffffffff8100f2fb
 #4 [ffff8801394358e0] do_trap at ffffffff814de544
 #5 [ffff880139435940] do_invalid_op at ffffffff8100ceb5
 #6 [ffff8801394359e0] invalid_op at ffffffff8100bf5b
    [exception RIP: __nfs_fscache_invalidate_page+121]
 #7 [ffff880139435ab0] nfs_invalidate_page at ffffffffa06fff6e [nfs]
 #8 [ffff880139435ad0] do_invalidatepage at ffffffff811243d5
 #9 [ffff880139435ae0] truncate_inode_page at ffffffff811245f2
#10 [ffff880139435b00] truncate_inode_pages_range at ffffffff811248f0
#11 [ffff880139435bf0] truncate_inode_pages at ffffffff81124c05
#12 [ffff880139435c00] truncate_pagecache at ffffffff81124c57
#13 [ffff880139435c30] nfs_setattr_update_inode at ffffffffa07033ab [nfs]
#14 [ffff880139435c70] nfs4_proc_setattr at ffffffffa071bb45 [nfs]
#15 [ffff880139435cb0] nfs_setattr at ffffffffa07043e0 [nfs]
#16 [ffff880139435cf0] notify_change at ffffffff8118e0c8
#17 [ffff880139435d60] do_truncate at ffffffff81170a84
#18 [ffff880139435dd0] do_filp_open at ffffffff81182ba9
#19 [ffff880139435f20] do_sys_open at ffffffff8116f849
#20 [ffff880139435f70] sys_open at ffffffff8116f960
#21 [ffff880139435f80] tracesys at ffffffff8100b387 (via system_call)
#!/bin/bash
i=0
BEGIN_TIME=$(date +%s)
TIME_OUT=14400 #Set the testTime.
SERVER_FILE="/nfsroot/file"
CLIENT_FILE="/nfsmnt/file"
while :
do
    dd if=/dev/zero of="$SERVER_FILE$i" bs=1b count=1 &amp;amp;&amp;gt;/dev/null
    cat "$CLIENT_FILE$i" &amp;amp;&amp;gt;/dev/null
    echo "good" &amp;gt; "$CLIENT_FILE$i"
    rm -fr "$CLIENT_FILE$i"
    now=$(date +%s)
    if (($now - $BEGIN_TIME &amp;gt; $TIME_OUT))
    then
        break
    fi
        let i=i+1
done

echo "This probleam may be fix.\n"
&lt;/pre&gt;</description>
    <dc:creator>fanchaoting</dc:creator>
    <dc:date>2012-03-28T03:48:38</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3095">
    <title>oops when I mount nfs with -o fsc</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3095</link>
    <description>&lt;pre&gt;Hi: in nfs(RHEL6.x), i do as following. 
#cat /etc/exports
    /nfsroot      *(rw,no_root_squash,fsid=0,insecure)
#mount –t nfs4 –o fsc localhost:/   /nfsmnt
#sh create_file.sh

wait a while, i find oops.

PID: 4196   TASK: ffff88012365b580  CPU: 0   COMMAND: "sh"
 #0 [ffff880139435750] machine_kexec at ffffffff810310db
 #1 [ffff8801394357b0] crash_kexec at ffffffff810b63b2
 #2 [ffff880139435880] oops_end at ffffffff814dec50
 #3 [ffff8801394358b0] die at ffffffff8100f2fb
 #4 [ffff8801394358e0] do_trap at ffffffff814de544
 #5 [ffff880139435940] do_invalid_op at ffffffff8100ceb5
 #6 [ffff8801394359e0] invalid_op at ffffffff8100bf5b
    [exception RIP: __nfs_fscache_invalidate_page+121]
 #7 [ffff880139435ab0] nfs_invalidate_page at ffffffffa06fff6e [nfs]
 #8 [ffff880139435ad0] do_invalidatepage at ffffffff811243d5
 #9 [ffff880139435ae0] truncate_inode_page at ffffffff811245f2
#10 [ffff880139435b00] truncate_inode_pages_range at ffffffff811248f0
#11 [ffff880139435bf0] truncate_inode_pages at ffffffff81124c05
#12 [ffff880139435c00] truncate_pagecache at ffffffff81124c57
#13 [ffff880139435c30] nfs_setattr_update_inode at ffffffffa07033ab [nfs]
#14 [ffff880139435c70] nfs4_proc_setattr at ffffffffa071bb45 [nfs]
#15 [ffff880139435cb0] nfs_setattr at ffffffffa07043e0 [nfs]
#16 [ffff880139435cf0] notify_change at ffffffff8118e0c8
#17 [ffff880139435d60] do_truncate at ffffffff81170a84
#18 [ffff880139435dd0] do_filp_open at ffffffff81182ba9
#19 [ffff880139435f20] do_sys_open at ffffffff8116f849
#20 [ffff880139435f70] sys_open at ffffffff8116f960
#21 [ffff880139435f80] tracesys at ffffffff8100b387 (via system_call)
#!/bin/bash
i=0
BEGIN_TIME=$(date +%s)
TIME_OUT=14400 #Set the testTime.
SERVER_FILE="/nfsroot/file"
CLIENT_FILE="/nfsmnt/file"
while :
do
    dd if=/dev/zero of="$SERVER_FILE$i" bs=1b count=1 &amp;amp;&amp;gt;/dev/null
    cat "$CLIENT_FILE$i" &amp;amp;&amp;gt;/dev/null
    echo "good" &amp;gt; "$CLIENT_FILE$i"
    rm -fr "$CLIENT_FILE$i"
    now=$(date +%s)
    if (($now - $BEGIN_TIME &amp;gt; $TIME_OUT))
    then
        break
    fi
        let i=i+1
done

echo "This probleam may be fix.\n"
&lt;/pre&gt;</description>
    <dc:creator>fanchaoting</dc:creator>
    <dc:date>2012-03-29T01:53:27</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3094">
    <title>Re: oops when I mount nfs with -o fsc</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3094</link>
    <description>&lt;pre&gt;fanchaoting 写道:



--
Linux-cachefs mailing list
Linux-cachefs&amp;lt; at &amp;gt;redhat.com
https://www.redhat.com/mailman/listinfo/linux-cachefs
&lt;/pre&gt;</description>
    <dc:creator>fanchaoting</dc:creator>
    <dc:date>2012-03-29T01:50:46</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3092">
    <title>Rebélate by self-management, first project of free software by which we bet all / Rebélate por la autogestión, primer proyecto de software libre por el que apostamos todas</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3092</link>
    <description>&lt;pre&gt;Inglés :

Many already we have contributed to the first project of free software
dedicated to self-management in this campaign of collective financing,
it collaborates and it spreads!/


Beginning campaign collective financing

http://www.goteo.org/project/rebelaos-publicacion-por-la-autogestion?lang=en


Login to enter with user of social networks and for would register in Goteo :

http://www.goteo.org/user/login?lang=en


Rebelaos! Publication by self-management A massive publication that
floods the public transport, the work centers, the parks, the
consumption centers, by means of distribution of 500,000 gratuitous
units, acting simultaneously in all sides and nowhere.

We announce the main tool of a vestibule Web for the management of
self-sustaining resources by means of Drupal, in addition in the
publication there will be an article dedicated to free software,
hardware, It is being prepared in inglès,  the machinery You can see
more details in the index of the
publication    https://n-1.cc/pg/file/read/1151902/indexresumen-de-los-contenidos-pdf

 . A computer system that allows us to share resources in all the
scopes of our life so that we do not have to generate means different
for each subject nor for each territory.

A point of contact digitalis to generate projects of life outside
Capitalism and to margin of the State.


A tool to spread and to impel the social transformation through the
resources that will set out in their contents around self-management,
the autoorganización, the disobedience and the collective action.

In which the capitalist system goes to the collapse, in a while
immersed in a deep systemic crisis (ecological, political and
economic, but mainly of values), where individual and collective of
people they are being lacking of his fundamental rights, is necessary
to develop a horizontal collective process where all the human beings
we pruned to interact in equality of conditions and freedom.


To interact means to relate to us (as much human as economically), to
communicate to us, to cover our basic needs, to generate and to
protect communal properties, to know and to provide collective
solutions us problematic that our lives interfere. We want abrir a
breach within normality in the monotonous life state-capitalist, a day
anyone, that finally will not be any day.


By means of this publication we try:

- To drive a horizontal collective process where all and all we pruned
to interact in equality of conditions and freedom.

 - To create communications network between the people it jeopardize
with the change and arranged to act.


 - To find collective solutions to problematic that our lives interfere


- To facilitate the access to resources that make possible self-management.

- To participate in the construction of networks of mutual support,
generated horizontals, asamblearias and from the base.


 - To publish all this information in an attractive format stops to
facilitate the access to all the society.



There are 15 days remaining for the upcoming March 15, the day that
will come Rebelaos!, Magazine for the selfmanagement

Today, we issue the cover of Rebelaos! (Castilian version) that can be
displayed on the following link:
https://n-1.cc/pg/file/read/1200503/portada-15-de-marzo-rebelaos
The contents of the store owners to us by 15 March. Do you? Do you
keep on 15 March?

In addition, we have over 200 distribution nodes, distributed
throughout the Spanish state. Check the map:
https://afinidadrebelde.crowdmap.com/

On the other hand, the funding campaign continues to move and still
have 12 days to collect the remaining 6,000 euros. We can all make a
bit for all the grains of sand become a great beach on March 15. You
can access the co-financing campaign:
http://www.goteo.org/project/rebelaos-publicacion-por-la-autogestion

Rebel Affinity group
www.rebelaos.net


-------------------------------------------------------------------------------
Castellano:

Muchos ya hemos aportado al primer proyecto de software libre dedicado
a la la financiación colectiva, colabora y diffunde !!!!!

Inicio campaña financiación colectiva goteo.org

www.goteo.org/project/rebelaos-publicacion-por-la-autogestion


Link para registrarse en Goteo y acceder a redes sociales para
colaborar en la difusín

http://www.goteo.org/user/login

¡Rebelaos! Publicación por la autogestión

Una publicación masiva que inunde el transporte público, los centros
de trabajo, los parques, los centros de consumo, mediante la
distribución de 500.000 ejemplares gratuitos, actuando simultáneamente
en todos lados y en ninguna parte.


Anunciamos la herramienta principal de un  portal web para la gestión
de recursos autogestionados mediante Drupal, además en  la publicación
habrá un artículo dedicado al software libre, el hardware, la
maquinaria... Puedes ver más detalles en el índice de la publicación
https://n-1.cc/pg/file/read/1151902/indexresumen-de-los-contenidos-pdf

Un sistema infórmatico que nos permita compartir recursos en todos los
ámbitos de nuestra vida de forma que no tengamos que generar un medio
distinto para cada tema ni para cada territorio. Un punto de encuentro
digital para generar proyectos de vida fuera del capitalismo y al
margen del Estado.


Una herramienta para difundir e impulsar la transformación social a
través de los recursos que se propondrán en sus contenidos en torno a
la autogestión, la autoorganización, la desobediencia y la acción
colectiva.

En un momento en que el sistema capitalista se dirige al colapso,
inmerso en una profunda crisis sistémica (ecológica, política y
económica, pero principalmente de valores), donde individuos y
colectivos de personas están siendo desprovistos de sus derechos
fundamentales, es necesario desarrollar un proceso colectivo
horizontal donde todos los seres humanos podamos interactuar en
igualdad de condiciones y en libertad.

Interactuar significa relacionarnos (tanto humana como
económicamente), comunicarnos, cubrir nuestras necesidades básicas,
generar y proteger bienes comunes, conocernos y dar soluciones
colectivas a problemáticas que interfieren nuestras vidas. Queremos
abrir una brecha dentro de la normalidad en la monótona vida
estatal-capitalista, un día cualquiera, que finalmente no será
cualquier día.

Mediante esta publicación pretendemos:

- Impulsar un proceso colectivo horizontal donde todos y todas podamos
interactuar en igualdad de condiciones y en libertad.

- Crear red de comunicaciones entre las personas comprometidas con el
cambio y dispuestas a actuar.

- Encontrar soluciones colectivas a problemáticas que interfieren
nuestras vidas.

- Facilitar el acceso a recursos que posibiliten la autogestión.

- Participar en la construcción de redes de apoyo mutuo, horizontales,
asamblearias y generadas desde la base.

- Publicar toda esta información en un formato atractivo para
facilitar el acceso a toda la sociedad.

Son 15 los días que restan para el próximo 15 de marzo, día en el que
verá la luz ¡Rebelaos!, publicación por la autogestión.

Hoy, hacemos pública la portada de ¡Rebelaos! (versión en castellano)
que podéis visualizar en el siguiente enlace:
https://n-1.cc/pg/file/read/1200503/portada-15-de-marzo-rebelaos
El contenido de los titulares nos los guardamos para el 15 de marzo.
¿Y tú? ¿Te guardas el 15 de marzo?

Además, ya hemos superado los 200 nodos de distribución, repartidos
por todo el estado español. Ver el mapa:
https://afinidadrebelde.crowdmap.com/

Por otro lado, la campaña de financiación continúa avanzando y todavía
quedan 12 días para reunir los 6.000 euros que restan. Todas podemos
aportar un poco para que todos los granitos de arena se conviertan en
una gran playa el 15 de marzo. Podéis acceder a la campaña de
cofinanciación en:
http://www.goteo.org/project/rebelaos-publicacion-por-la-autogestion

Colectivo Afinidad Rebelde
www.rebelaos.net

&lt;/pre&gt;</description>
    <dc:creator>Orquidea Salt mas</dc:creator>
    <dc:date>2012-03-02T19:22:05</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3091">
    <title>Re: FS-Cache "Netfs" (nfs) Fedora 15/16/17</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3091</link>
    <description>&lt;pre&gt;

Unless you're mounting an NFS fs with -o fsc immediately thereafter it should
do very little at this point, and even so, it shouldn't do much more unless
you've also loaded the cachefiles module and started up a cache.

Try:

echo 65535 &amp;gt;/sys/module/fscache/parameters/debug

David

&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-02-21T18:14:26</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3090">
    <title>FS-Cache "Netfs" (nfs) Fedora 15/16/17</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3090</link>
    <description>&lt;pre&gt;Hi,

Am trying to figure out why during bootup,
at the following point across real and virt boxes.

eb 19 11:22:07 frank01 kernel: [  482.640618] FS-Cache: Loaded
Feb 19 11:22:07 frank01 kernel: [  482.672487] FS-Cache: Netfs 'nfs' 
registered for caching

It sits there for about 10 seconds, with no indication as to what's 
happening.


nfs mount during bootup can be autofs or fstab depending on box.


Is this still relevant for debugging FS-Cache:
https://www.redhat.com/archives/linux-cachefs/2010-February/msg00022.html

" You can also turn on NFS debugging for FS-Cache to see what it's doing:

echo $((0x800)) &amp;gt;/proc/sys/sunrpc/nfs_debug  "


kernels across boxes: 3.2* 3.3*

&lt;/pre&gt;</description>
    <dc:creator>Frank Murphy</dc:creator>
    <dc:date>2012-02-21T17:41:39</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3089">
    <title>[PATCH 17/17] NFS: nfs_migrate_page() does not wait for FS-Cache to finish with a page</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3089</link>
    <description>&lt;pre&gt;nfs_migrate_page() does not wait for FS-Cache to finish with a page, probably
leading to the following bad-page-state:

 BUG: Bad page state in process python-bin  pfn:17d39b
 page:ffffea00053649e8 flags:004000000000100c count:0 mapcount:0 mapping:(null)
index:38686 (Tainted: G    B      ---------------- )
 Pid: 31053, comm: python-bin Tainted: G    B      ----------------
2.6.32-71.24.1.el6.x86_64 #1
 Call Trace:
 [&amp;lt;ffffffff8111bfe7&amp;gt;] bad_page+0x107/0x160
 [&amp;lt;ffffffff8111ee69&amp;gt;] free_hot_cold_page+0x1c9/0x220
 [&amp;lt;ffffffff8111ef19&amp;gt;] __pagevec_free+0x59/0xb0
 [&amp;lt;ffffffff8104b988&amp;gt;] ? flush_tlb_others_ipi+0x128/0x130
 [&amp;lt;ffffffff8112230c&amp;gt;] release_pages+0x21c/0x250
 [&amp;lt;ffffffff8115b92a&amp;gt;] ? remove_migration_pte+0x28a/0x2b0
 [&amp;lt;ffffffff8115f3f8&amp;gt;] ? mem_cgroup_get_reclaim_stat_from_page+0x18/0x70
 [&amp;lt;ffffffff81122687&amp;gt;] ____pagevec_lru_add+0x167/0x180
 [&amp;lt;ffffffff811226f8&amp;gt;] __lru_cache_add+0x58/0x70
 [&amp;lt;ffffffff81122731&amp;gt;] lru_cache_add_lru+0x21/0x40
 [&amp;lt;ffffffff81123f49&amp;gt;] putback_lru_page+0x69/0x100
 [&amp;lt;ffffffff8115c0bd&amp;gt;] migrate_pages+0x13d/0x5d0
 [&amp;lt;ffffffff81122687&amp;gt;] ? ____pagevec_lru_add+0x167/0x180
 [&amp;lt;ffffffff81152ab0&amp;gt;] ? compaction_alloc+0x0/0x370
 [&amp;lt;ffffffff8115255c&amp;gt;] compact_zone+0x4cc/0x600
 [&amp;lt;ffffffff8111cfac&amp;gt;] ? get_page_from_freelist+0x15c/0x820
 [&amp;lt;ffffffff810672f4&amp;gt;] ? check_preempt_wakeup+0x1c4/0x3c0
 [&amp;lt;ffffffff8115290e&amp;gt;] compact_zone_order+0x7e/0xb0
 [&amp;lt;ffffffff81152a49&amp;gt;] try_to_compact_pages+0x109/0x170
 [&amp;lt;ffffffff8111e94d&amp;gt;] __alloc_pages_nodemask+0x5ed/0x850
 [&amp;lt;ffffffff814c9136&amp;gt;] ? thread_return+0x4e/0x778
 [&amp;lt;ffffffff81150d43&amp;gt;] alloc_pages_vma+0x93/0x150
 [&amp;lt;ffffffff81167ea5&amp;gt;] do_huge_pmd_anonymous_page+0x135/0x340
 [&amp;lt;ffffffff814cb6f6&amp;gt;] ? rwsem_down_read_failed+0x26/0x30
 [&amp;lt;ffffffff81136755&amp;gt;] handle_mm_fault+0x245/0x2b0
 [&amp;lt;ffffffff814ce383&amp;gt;] do_page_fault+0x123/0x3a0
 [&amp;lt;ffffffff814cbdf5&amp;gt;] page_fault+0x25/0x30

nfs_migrate_page() calls nfs_fscache_release_page() which doesn't actually wait
- even if __GFP_WAIT is set.  The reason that doesn't wait is that
fscache_maybe_release_page() might deadlock the allocator as the work threads
writing to the cache may all end up sleeping on memory allocation.

However, I wonder if that is actually a problem.  There are a number of things
I can do to deal with this:

 (1) Make nfs_migrate_page() wait.

 (2) Make fscache_maybe_release_page() honour the __GFP_WAIT flag.

 (3) Set a timeout around the wait.

 (4) Make nfs_migrate_page() return an error if the page is still busy.

For the moment, I'll select (2) and (4).

Signed-off-by: David Howells &amp;lt;dhowells&amp;lt; at &amp;gt;redhat.com&amp;gt;
Acked-by: Jeff Layton &amp;lt;jlayton&amp;lt; at &amp;gt;redhat.com&amp;gt;
---

 fs/fscache/internal.h |    1 +
 fs/fscache/page.c     |   19 ++++++++++++++-----
 fs/fscache/stats.c    |    6 ++++--
 fs/nfs/write.c        |    4 +++-
 4 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h
index dcb3e1d..88a48cc 100644
--- a/fs/fscache/internal.h
+++ b/fs/fscache/internal.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -200,6 +200,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern atomic_t fscache_n_store_vmscan_not_storing;
 extern atomic_t fscache_n_store_vmscan_gone;
 extern atomic_t fscache_n_store_vmscan_busy;
 extern atomic_t fscache_n_store_vmscan_cancelled;
+extern atomic_t fscache_n_store_vmscan_wait;
 
 extern atomic_t fscache_n_marks;
 extern atomic_t fscache_n_uncaches;
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index 4dbbca1..f9b2fb3 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -56,6 +56,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; bool __fscache_maybe_release_page(struct fscache_cookie *cookie,
 
 _enter("%p,%p,%x", cookie, page, gfp);
 
+try_again:
 rcu_read_lock();
 val = radix_tree_lookup(&amp;amp;cookie-&amp;gt;stores, page-&amp;gt;index);
 if (!val) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -104,11 +105,19 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; bool __fscache_maybe_release_page(struct fscache_cookie *cookie,
 return true;
 
 page_busy:
-/* we might want to wait here, but that could deadlock the allocator as
- * the work threads writing to the cache may all end up sleeping
- * on memory allocation */
-fscache_stat(&amp;amp;fscache_n_store_vmscan_busy);
-return false;
+/* We will wait here if we're allowed to, but that could deadlock the
+ * allocator as the work threads writing to the cache may all end up
+ * sleeping on memory allocation, so we may need to impose a timeout
+ * too. */
+if (!(gfp &amp;amp; __GFP_WAIT)) {
+fscache_stat(&amp;amp;fscache_n_store_vmscan_busy);
+return false;
+}
+
+fscache_stat(&amp;amp;fscache_n_store_vmscan_wait);
+__fscache_wait_on_page_write(cookie, page);
+gfp &amp;amp;= ~__GFP_WAIT;
+goto try_again;
 }
 EXPORT_SYMBOL(__fscache_maybe_release_page);
 
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c
index 51cdaee..8179e8b 100644
--- a/fs/fscache/stats.c
+++ b/fs/fscache/stats.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -69,6 +69,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; atomic_t fscache_n_store_vmscan_not_storing;
 atomic_t fscache_n_store_vmscan_gone;
 atomic_t fscache_n_store_vmscan_busy;
 atomic_t fscache_n_store_vmscan_cancelled;
+atomic_t fscache_n_store_vmscan_wait;
 
 atomic_t fscache_n_marks;
 atomic_t fscache_n_uncaches;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -232,11 +233,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int fscache_stats_show(struct seq_file *m, void *v)
    atomic_read(&amp;amp;fscache_n_store_radix_deletes),
    atomic_read(&amp;amp;fscache_n_store_pages_over_limit));
 
-seq_printf(m, "VmScan : nos=%u gon=%u bsy=%u can=%u\n",
+seq_printf(m, "VmScan : nos=%u gon=%u bsy=%u can=%u wt=%u\n",
    atomic_read(&amp;amp;fscache_n_store_vmscan_not_storing),
    atomic_read(&amp;amp;fscache_n_store_vmscan_gone),
    atomic_read(&amp;amp;fscache_n_store_vmscan_busy),
-   atomic_read(&amp;amp;fscache_n_store_vmscan_cancelled));
+   atomic_read(&amp;amp;fscache_n_store_vmscan_cancelled),
+   atomic_read(&amp;amp;fscache_n_store_vmscan_wait));
 
 seq_printf(m, "Ops    : pend=%u run=%u enq=%u can=%u rej=%u\n",
    atomic_read(&amp;amp;fscache_n_op_pend),
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 834f0fe..5fbee48 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1701,7 +1701,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
 if (PagePrivate(page))
 return -EBUSY;
 
-nfs_fscache_release_page(page, GFP_KERNEL);
+ret = -EBUSY;
+if (!nfs_fscache_release_page(page, GFP_KERNEL))
+goto out;
 
 return migrate_page(mapping, newpage, page, mode);
 }

&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-02-08T21:19:35</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3088">
    <title>[PATCH 16/17] FS-Cache: Exclusive op submission can BUG if there's been an I/O error</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3088</link>
    <description>&lt;pre&gt;The function to submit an exclusive op (fscache_submit_exclusive_op()) can BUG
if there's been an I/O error because it may see the parent cache object in an
unexpected state.  It should only BUG if there hasn't been an I/O error.

In this case the problem was produced by remounting the cache partition to be
R/O.  The EROFS state was detected and the cache was aborted, but not
everything handled the aborting correctly.

SysRq : Emergency Remount R/O
EXT4-fs (sda6): re-mounted. Opts: (null)
Emergency Remount complete
CacheFiles: I/O Error: Failed to update xattr with error -30
FS-Cache: Cache cachefiles stopped due to I/O error
------------[ cut here ]------------
kernel BUG at fs/fscache/operation.c:128!
invalid opcode: 0000 [#1] SMP 
CPU 0 
Modules linked in: cachefiles nfs fscache auth_rpcgss nfs_acl lockd sunrpc

Pid: 6612, comm: kworker/u:2 Not tainted 3.1.0-rc8-fsdevel+ #1093                  /DG965RY
RIP: 0010:[&amp;lt;ffffffffa00739c0&amp;gt;]  [&amp;lt;ffffffffa00739c0&amp;gt;] fscache_submit_exclusive_op+0x2ad/0x2c2 [fscache]
RSP: 0018:ffff880000853d40  EFLAGS: 00010206
RAX: ffff880038ac72a8 RBX: ffff8800181f2260 RCX: ffffffff81f2b2b0
RDX: 0000000000000001 RSI: ffffffff8179a478 RDI: ffff8800181f2280
RBP: ffff880000853d60 R08: 0000000000000002 R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000001 R12: ffff880038ac7268
R13: ffff8800181f2280 R14: ffff88003a359190 R15: 000000010122b162
FS:  0000000000000000(0000) GS:ffff88003bc00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00000034cc4a77f0 CR3: 0000000010e96000 CR4: 00000000000006f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process kworker/u:2 (pid: 6612, threadinfo ffff880000852000, task ffff880014c3c040)
Stack:
 ffff8800181f2260 ffff8800181f2310 ffff880038ac7268 ffff8800181f2260
 ffff880000853dc0 ffffffffa0072375 ffff880037ecfe00 ffff88003a359198
 ffff880000853dc0 0000000000000246 0000000000000000 ffff88000a91d308
Call Trace:
 [&amp;lt;ffffffffa0072375&amp;gt;] fscache_object_work_func+0x792/0xe65 [fscache]
 [&amp;lt;ffffffff81047e44&amp;gt;] process_one_work+0x1eb/0x37f
 [&amp;lt;ffffffff81047de6&amp;gt;] ? process_one_work+0x18d/0x37f
 [&amp;lt;ffffffffa0071be3&amp;gt;] ? fscache_enqueue_dependents+0xd8/0xd8 [fscache]
 [&amp;lt;ffffffff810482e4&amp;gt;] worker_thread+0x15a/0x21a
 [&amp;lt;ffffffff8104818a&amp;gt;] ? rescuer_thread+0x188/0x188
 [&amp;lt;ffffffff8104bf96&amp;gt;] kthread+0x7f/0x87
 [&amp;lt;ffffffff813ad6f4&amp;gt;] kernel_thread_helper+0x4/0x10
 [&amp;lt;ffffffff81026b98&amp;gt;] ? finish_task_switch+0x45/0xc0
 [&amp;lt;ffffffff813abd1d&amp;gt;] ? retint_restore_args+0xe/0xe
 [&amp;lt;ffffffff8104bf17&amp;gt;] ? __init_kthread_worker+0x53/0x53
 [&amp;lt;ffffffff813ad6f0&amp;gt;] ? gs_change+0xb/0xb


Signed-off-by: David Howells &amp;lt;dhowells&amp;lt; at &amp;gt;redhat.com&amp;gt;
---

 fs/fscache/internal.h  |    1 +
 fs/fscache/object.c    |   23 +++++++++++++++++------
 fs/fscache/operation.c |   13 ++++++++++---
 3 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h
index c811793..dcb3e1d 100644
--- a/fs/fscache/internal.h
+++ b/fs/fscache/internal.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -288,6 +288,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern const struct file_operations fscache_stats_fops;
 static inline void fscache_raise_event(struct fscache_object *object,
        unsigned event)
 {
+BUG_ON(event &amp;gt;= NR_FSCACHE_OBJECT_EVENTS);
 if (!test_and_set_bit(event, &amp;amp;object-&amp;gt;events) &amp;amp;&amp;amp;
     test_bit(event, &amp;amp;object-&amp;gt;event_mask))
 fscache_enqueue_object(object);
diff --git a/fs/fscache/object.c b/fs/fscache/object.c
index 2ef8a08..2c512cb 100644
--- a/fs/fscache/object.c
+++ b/fs/fscache/object.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -103,6 +103,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void fscache_object_state_machine(struct fscache_object *object)
 {
 enum fscache_object_state new_state;
 struct fscache_cookie *cookie;
+int event;
 
 ASSERT(object != NULL);
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -275,7 +276,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void fscache_object_state_machine(struct fscache_object *object)
 
 /* determine the transition from a lookup state */
 lookup_transit:
-switch (fls(object-&amp;gt;events &amp;amp; object-&amp;gt;event_mask) - 1) {
+event = fls(object-&amp;gt;events &amp;amp; object-&amp;gt;event_mask) - 1;
+switch (event) {
 case FSCACHE_OBJECT_EV_WITHDRAW:
 case FSCACHE_OBJECT_EV_RETIRE:
 case FSCACHE_OBJECT_EV_RELEASE:
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -292,7 +294,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; lookup_transit:
 
 /* determine the transition from an active state */
 active_transit:
-switch (fls(object-&amp;gt;events &amp;amp; object-&amp;gt;event_mask) - 1) {
+event = fls(object-&amp;gt;events &amp;amp; object-&amp;gt;event_mask) - 1;
+switch (event) {
 case FSCACHE_OBJECT_EV_WITHDRAW:
 case FSCACHE_OBJECT_EV_RETIRE:
 case FSCACHE_OBJECT_EV_RELEASE:
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -314,7 +317,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; active_transit:
 
 /* determine the transition from a terminal state */
 terminal_transit:
-switch (fls(object-&amp;gt;events &amp;amp; object-&amp;gt;event_mask) - 1) {
+event = fls(object-&amp;gt;events &amp;amp; object-&amp;gt;event_mask) - 1;
+switch (event) {
 case FSCACHE_OBJECT_EV_WITHDRAW:
 new_state = FSCACHE_OBJECT_WITHDRAWING;
 goto change_state;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -347,8 +351,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; done:
 
 unsupported_event:
 printk(KERN_ERR "FS-Cache:"
-       " Unsupported event %lx [mask %lx] in state %s\n",
-       object-&amp;gt;events, object-&amp;gt;event_mask,
+       " Unsupported event %d [%lx/%lx] in state %s\n",
+       event, object-&amp;gt;events, object-&amp;gt;event_mask,
        fscache_object_states[object-&amp;gt;state]);
 BUG();
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -945,7 +949,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void fscache_invalidate_object(struct fscache_object *object)
 
 spin_lock(&amp;amp;cookie-&amp;gt;lock);
 if (fscache_submit_exclusive_op(object, op) &amp;lt; 0)
-BUG();
+goto submit_op_failed;
 spin_unlock(&amp;amp;cookie-&amp;gt;lock);
 fscache_put_operation(op);
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -960,4 +964,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void fscache_invalidate_object(struct fscache_object *object)
  */
 fscache_invalidation_complete(cookie);
 _leave("");
+return;
+
+submit_op_failed:
+spin_unlock(&amp;amp;cookie-&amp;gt;lock);
+kfree(op);
+fscache_raise_event(object, FSCACHE_OBJECT_EV_ERROR);
+_leave(" [EIO]");
 }
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c
index c58dbe6..9e6b7d2 100644
--- a/fs/fscache/operation.c
+++ b/fs/fscache/operation.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -84,6 +84,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void fscache_run_op(struct fscache_object *object,
 int fscache_submit_exclusive_op(struct fscache_object *object,
 struct fscache_operation *op)
 {
+int ret;
+
 _enter("{OBJ%x OP%x},", object-&amp;gt;debug_id, op-&amp;gt;debug_id);
 
 ASSERTCMP(op-&amp;gt;state, ==, FSCACHE_OP_ST_INITIALISED);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -116,6 +118,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int fscache_submit_exclusive_op(struct fscache_object *object,
 
 /* need to issue a new write op after this */
 clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &amp;amp;object-&amp;gt;flags);
+ret = 0;
 } else if (object-&amp;gt;state == FSCACHE_OBJECT_CREATING) {
 op-&amp;gt;object = object;
 object-&amp;gt;n_ops++;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -123,13 +126,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int fscache_submit_exclusive_op(struct fscache_object *object,
 atomic_inc(&amp;amp;op-&amp;gt;usage);
 list_add_tail(&amp;amp;op-&amp;gt;pend_link, &amp;amp;object-&amp;gt;pending_ops);
 fscache_stat(&amp;amp;fscache_n_op_pend);
+ret = 0;
 } else {
-/* not allowed to submit ops in any other state */
-BUG();
+/* If we're in any other state, there must have been an I/O
+ * error of some nature.
+ */
+ASSERT(test_bit(FSCACHE_IOERROR, &amp;amp;object-&amp;gt;cache-&amp;gt;flags));
+ret = -EIO;
 }
 
 spin_unlock(&amp;amp;object-&amp;gt;lock);
-return 0;
+return ret;
 }
 
 /*

&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-02-08T21:19:24</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3087">
    <title>[PATCH 15/17] FS-Cache: Limit the number of I/O error reports for a cache</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3087</link>
    <description>&lt;pre&gt;Limit the number of I/O error reports for a cache to 1 to prevent massive
amounts of noise.  After the first I/O error the cache is taken off line
automatically, so must be restarted to resume caching.

Signed-off-by: David Howells &amp;lt;dhowells&amp;lt; at &amp;gt;redhat.com&amp;gt;
---

 fs/fscache/cache.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/fscache/cache.c b/fs/fscache/cache.c
index 6a3c48a..b52aed1 100644
--- a/fs/fscache/cache.c
+++ b/fs/fscache/cache.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -314,10 +314,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; EXPORT_SYMBOL(fscache_add_cache);
  */
 void fscache_io_error(struct fscache_cache *cache)
 {
-set_bit(FSCACHE_IOERROR, &amp;amp;cache-&amp;gt;flags);
-
-printk(KERN_ERR "FS-Cache: Cache %s stopped due to I/O error\n",
-       cache-&amp;gt;ops-&amp;gt;name);
+if (!test_and_set_bit(FSCACHE_IOERROR, &amp;amp;cache-&amp;gt;flags))
+printk(KERN_ERR "FS-Cache:"
+       " Cache '%s' stopped due to I/O error\n",
+       cache-&amp;gt;ops-&amp;gt;name);
 }
 EXPORT_SYMBOL(fscache_io_error);
 

&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-02-08T21:19:15</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3086">
    <title>[PATCH 14/17] FS-Cache: Don't mask off the object event mask when printing it</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3086</link>
    <description>&lt;pre&gt;Don't mask off the object event mask when printing it.  That way it can be seen
if threre are bits set that shouldn't be.

Signed-off-by: David Howells &amp;lt;dhowells&amp;lt; at &amp;gt;redhat.com&amp;gt;
---

 fs/cachefiles/namei.c    |    3 +--
 fs/fscache/object-list.c |    2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index a0358c2..0fd9b6d 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -40,8 +40,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void __cachefiles_printk_object(struct cachefiles_object *object,
 printk(KERN_ERR "%sobjstate=%s fl=%lx wbusy=%x ev=%lx[%lx]\n",
        prefix, fscache_object_states[object-&amp;gt;fscache.state],
        object-&amp;gt;fscache.flags, work_busy(&amp;amp;object-&amp;gt;fscache.work),
-       object-&amp;gt;fscache.events,
-       object-&amp;gt;fscache.event_mask &amp;amp; FSCACHE_OBJECT_EVENTS_MASK);
+       object-&amp;gt;fscache.events, object-&amp;gt;fscache.event_mask);
 printk(KERN_ERR "%sops=%u inp=%u exc=%u\n",
        prefix, object-&amp;gt;fscache.n_ops, object-&amp;gt;fscache.n_in_progress,
        object-&amp;gt;fscache.n_exclusive);
diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c
index ebe29c5..f27c89d 100644
--- a/fs/fscache/object-list.c
+++ b/fs/fscache/object-list.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -245,7 +245,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int fscache_objlist_show(struct seq_file *m, void *v)
    obj-&amp;gt;n_in_progress,
    obj-&amp;gt;n_exclusive,
    atomic_read(&amp;amp;obj-&amp;gt;n_reads),
-   obj-&amp;gt;event_mask &amp;amp; FSCACHE_OBJECT_EVENTS_MASK,
+   obj-&amp;gt;event_mask,
    obj-&amp;gt;events,
    obj-&amp;gt;flags,
    work_busy(&amp;amp;obj-&amp;gt;work));

&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-02-08T21:19:03</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3085">
    <title>[PATCH 13/17] FS-Cache: Initialise the object event mask with the calculated mask</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3085</link>
    <description>&lt;pre&gt;Initialise the object event mask with the calculated mask rather than unmasking
undefined events also.

Signed-off-by: David Howells &amp;lt;dhowells&amp;lt; at &amp;gt;redhat.com&amp;gt;
---

 fs/fscache/object.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/fs/fscache/object.c b/fs/fscache/object.c
index 80b5491..2ef8a08 100644
--- a/fs/fscache/object.c
+++ b/fs/fscache/object.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -114,7 +114,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void fscache_object_state_machine(struct fscache_object *object)
 /* wait for the parent object to become ready */
 case FSCACHE_OBJECT_INIT:
 object-&amp;gt;event_mask =
-ULONG_MAX &amp;amp; ~(1 &amp;lt;&amp;lt; FSCACHE_OBJECT_EV_CLEARED);
+FSCACHE_OBJECT_EVENTS_MASK &amp;amp;
+~(1 &amp;lt;&amp;lt; FSCACHE_OBJECT_EV_CLEARED);
 fscache_initialise_object(object);
 goto done;
 

&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-02-08T21:18:53</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3084">
    <title>[PATCH 12/17] FS-Cache: Convert the object event ID #defines into an enum</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3084</link>
    <description>&lt;pre&gt;Convert the fscache_object event IDs from #defines into an enum.  Also add an
extra label to the enum to carry the event count and redefine the event mask
in terms of that.

Signed-off-by: David Howells &amp;lt;dhowells&amp;lt; at &amp;gt;redhat.com&amp;gt;
---

 include/linux/fscache-cache.h |   26 +++++++++++++++++---------
 1 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index 1e454ad..73e68c8 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -338,6 +338,23 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct fscache_cookie {
 extern struct fscache_cookie fscache_fsdef_index;
 
 /*
+ * Event list for fscache_object::{event_mask,events}
+ */
+enum {
+FSCACHE_OBJECT_EV_REQUEUE,/* T if object should be requeued */
+FSCACHE_OBJECT_EV_UPDATE,/* T if object should be updated */
+FSCACHE_OBJECT_EV_INVALIDATE,/* T if cache requested object invalidation */
+FSCACHE_OBJECT_EV_CLEARED,/* T if accessors all gone */
+FSCACHE_OBJECT_EV_ERROR,/* T if fatal error occurred during processing */
+FSCACHE_OBJECT_EV_RELEASE,/* T if netfs requested object release */
+FSCACHE_OBJECT_EV_RETIRE,/* T if netfs requested object retirement */
+FSCACHE_OBJECT_EV_WITHDRAW,/* T if cache requested object withdrawal */
+NR_FSCACHE_OBJECT_EVENTS
+};
+
+#define FSCACHE_OBJECT_EVENTS_MASK ((1UL &amp;lt;&amp;lt; NR_FSCACHE_OBJECT_EVENTS) - 1)
+
+/*
  * on-disk cache file or index handle
  */
 struct fscache_object {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -376,15 +393,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct fscache_object {
 unsigned longevent_mask;/* events this object is interested in */
 unsigned longevents;/* events to be processed by this object
  * (order is important - using fls) */
-#define FSCACHE_OBJECT_EV_REQUEUE0/* T if object should be requeued */
-#define FSCACHE_OBJECT_EV_UPDATE1/* T if object should be updated */
-#define FSCACHE_OBJECT_EV_CLEARED2/* T if accessors all gone */
-#define FSCACHE_OBJECT_EV_ERROR3/* T if fatal error occurred during processing */
-#define FSCACHE_OBJECT_EV_RELEASE4/* T if netfs requested object release */
-#define FSCACHE_OBJECT_EV_RETIRE5/* T if netfs requested object retirement */
-#define FSCACHE_OBJECT_EV_WITHDRAW6/* T if cache requested object withdrawal */
-#define FSCACHE_OBJECT_EV_INVALIDATE7/* T if cache requested object invalidation */
-#define FSCACHE_OBJECT_EVENTS_MASK0xff/* mask of all events*/
 
 unsigned longflags;
 #define FSCACHE_OBJECT_LOCK0/* T if object is busy being processed */

&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-02-08T21:18:44</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3082">
    <title>[PATCH 10/17] NFS: Use FS-Cache invalidation</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3082</link>
    <description>&lt;pre&gt;Use the new FS-Cache invalidation facility from NFS to deal with foreign
changes being detected on the server rather than attempting to retire the old
cookie and get a new one.

The problem with the old method was that NFS did not wait for all outstanding
storage and retrieval ops on the cache to complete.  There was no automatic
wait between the calls to -&amp;gt;readpages() and calls to invalidate_inode_pages2()
as the latter can only wait on locked pages that have been added to the
pagecache (which they haven't yet on entry to -&amp;gt;readpages()).

This was leading to oopses like the one below when an outstanding read got cut
off from its cookie by a premature release.

BUG: unable to handle kernel NULL pointer dereference at 00000000000000a8
IP: [&amp;lt;ffffffffa0075118&amp;gt;] __fscache_read_or_alloc_pages+0x1dd/0x315 [fscache]
PGD 15889067 PUD 15890067 PMD 0
Oops: 0000 [#1] SMP
CPU 0
Modules linked in: cachefiles nfs fscache auth_rpcgss nfs_acl lockd sunrpc

Pid: 4544, comm: tar Not tainted 3.1.0-rc4-fsdevel+ #1064                  /DG965RY
RIP: 0010:[&amp;lt;ffffffffa0075118&amp;gt;]  [&amp;lt;ffffffffa0075118&amp;gt;] __fscache_read_or_alloc_pages+0x1dd/0x315 [fscache]
RSP: 0018:ffff8800158799e8  EFLAGS: 00010246
RAX: 0000000000000000 RBX: ffff8800070d41e0 RCX: ffff8800083dc1b0
RDX: 0000000000000000 RSI: ffff880015879960 RDI: ffff88003e627b90
RBP: ffff880015879a28 R08: 0000000000000002 R09: 0000000000000002
R10: 0000000000000001 R11: ffff880015879950 R12: ffff880015879aa4
R13: 0000000000000000 R14: ffff8800083dc158 R15: ffff880015879be8
FS:  00007f671e9d87c0(0000) GS:ffff88003bc00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00000000000000a8 CR3: 000000001587f000 CR4: 00000000000006f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process tar (pid: 4544, threadinfo ffff880015878000, task ffff880015875040)
Stack:
 ffffffffa00b1759 ffff8800070dc158 ffff8800000213da ffff88002a286508
 ffff880015879aa4 ffff880015879be8 0000000000000001 ffff88002a2866e8
 ffff880015879a88 ffffffffa00b20be 00000000000200da ffff880015875040
Call Trace:
 [&amp;lt;ffffffffa00b1759&amp;gt;] ? nfs_fscache_wait_bit+0xd/0xd [nfs]
 [&amp;lt;ffffffffa00b20be&amp;gt;] __nfs_readpages_from_fscache+0x7e/0x13f [nfs]
 [&amp;lt;ffffffff81095fe7&amp;gt;] ? __alloc_pages_nodemask+0x156/0x662
 [&amp;lt;ffffffffa0098763&amp;gt;] nfs_readpages+0xee/0x187 [nfs]
 [&amp;lt;ffffffff81098a5e&amp;gt;] __do_page_cache_readahead+0x1be/0x267
 [&amp;lt;ffffffff81098942&amp;gt;] ? __do_page_cache_readahead+0xa2/0x267
 [&amp;lt;ffffffff81098d7b&amp;gt;] ra_submit+0x1c/0x20
 [&amp;lt;ffffffff8109900a&amp;gt;] ondemand_readahead+0x28b/0x29a
 [&amp;lt;ffffffff810990ce&amp;gt;] page_cache_sync_readahead+0x38/0x3a
 [&amp;lt;ffffffff81091d8a&amp;gt;] generic_file_aio_read+0x2ab/0x67e
 [&amp;lt;ffffffffa008cfbe&amp;gt;] nfs_file_read+0xa4/0xc9 [nfs]
 [&amp;lt;ffffffff810c22c4&amp;gt;] do_sync_read+0xba/0xfa
 [&amp;lt;ffffffff810a62c9&amp;gt;] ? might_fault+0x4e/0x9e
 [&amp;lt;ffffffff81177a47&amp;gt;] ? security_file_permission+0x7b/0x84
 [&amp;lt;ffffffff810c25dd&amp;gt;] ? rw_verify_area+0xab/0xc8
 [&amp;lt;ffffffff810c29a4&amp;gt;] vfs_read+0xaa/0x13a
 [&amp;lt;ffffffff810c2a79&amp;gt;] sys_read+0x45/0x6c
 [&amp;lt;ffffffff813ac37b&amp;gt;] system_call_fastpath+0x16/0x1b

Reported-by: Mark Moseley &amp;lt;moseleymark&amp;lt; at &amp;gt;gmail.com&amp;gt;
Signed-off-by: David Howells &amp;lt;dhowells&amp;lt; at &amp;gt;redhat.com&amp;gt;
---

 fs/nfs/fscache.h  |   20 +++++++++++++++++++-
 fs/nfs/inode.c    |   20 ++++++++++++++++----
 fs/nfs/nfs4proc.c |    2 ++
 3 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/fs/nfs/fscache.h b/fs/nfs/fscache.h
index b9c572d..851fee1 100644
--- a/fs/nfs/fscache.h
+++ b/fs/nfs/fscache.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -155,6 +155,22 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline void nfs_readpage_to_fscache(struct inode *inode,
 }
 
 /*
+ * Invalidate the contents of fscache for this inode.  This will not sleep.
+ */
+static inline void nfs_fscache_invalidate(struct inode *inode)
+{
+fscache_invalidate(NFS_I(inode)-&amp;gt;fscache);
+}
+
+/*
+ * Wait for an object to finish being invalidated.
+ */
+static inline void nfs_fscache_wait_on_invalidate(struct inode *inode)
+{
+fscache_wait_on_invalidate(NFS_I(inode)-&amp;gt;fscache);
+}
+
+/*
  * indicate the client caching state as readable text
  */
 static inline const char *nfs_server_fscache_state(struct nfs_server *server)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -164,7 +180,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline const char *nfs_server_fscache_state(struct nfs_server *server)
 return "no ";
 }
 
-
 #else /* CONFIG_NFS_FSCACHE */
 static inline int nfs_fscache_register(void) { return 0; }
 static inline void nfs_fscache_unregister(void) {}
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -213,6 +228,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline int nfs_readpages_from_fscache(struct nfs_open_context *ctx,
 static inline void nfs_readpage_to_fscache(struct inode *inode,
    struct page *page, int sync) {}
 
+
+static inline void nfs_fscache_invalidate(struct inode *inode) {}
+
 static inline const char *nfs_server_fscache_state(struct nfs_server *server)
 {
 return "no ";
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index f649fba..54383e9 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -152,10 +152,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void nfs_zap_caches_locked(struct inode *inode)
 nfsi-&amp;gt;attrtimeo_timestamp = jiffies;
 
 memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
-if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))
+if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) {
 nfsi-&amp;gt;cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
-else
+nfs_fscache_invalidate(inode);
+} else {
 nfsi-&amp;gt;cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
+}
 }
 
 void nfs_zap_caches(struct inode *inode)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -170,6 +172,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
 if (mapping-&amp;gt;nrpages != 0) {
 spin_lock(&amp;amp;inode-&amp;gt;i_lock);
 NFS_I(inode)-&amp;gt;cache_validity |= NFS_INO_INVALID_DATA;
+nfs_fscache_invalidate(inode);
 spin_unlock(&amp;amp;inode-&amp;gt;i_lock);
 }
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -862,7 +865,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map
 memset(nfsi-&amp;gt;cookieverf, 0, sizeof(nfsi-&amp;gt;cookieverf));
 spin_unlock(&amp;amp;inode-&amp;gt;i_lock);
 nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
-nfs_fscache_reset_inode_cookie(inode);
+nfs_fscache_wait_on_invalidate(inode);
 dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
 inode-&amp;gt;i_sb-&amp;gt;s_id, (long long)NFS_FILEID(inode));
 return 0;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -927,6 +930,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
 i_size_write(inode, nfs_size_to_loff_t(fattr-&amp;gt;size));
 ret |= NFS_INO_INVALID_ATTR;
 }
+
+if (nfsi-&amp;gt;cache_validity &amp;amp; NFS_INO_INVALID_DATA)
+nfs_fscache_invalidate(inode);
+
 return ret;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1108,8 +1115,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr
 struct nfs_inode *nfsi = NFS_I(inode);
 
 nfsi-&amp;gt;cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
-if (S_ISDIR(inode-&amp;gt;i_mode))
+if (S_ISDIR(inode-&amp;gt;i_mode)) {
 nfsi-&amp;gt;cache_validity |= NFS_INO_INVALID_DATA;
+nfs_fscache_invalidate(inode);
+}
 if ((fattr-&amp;gt;valid &amp;amp; NFS_ATTR_FATTR) == 0)
 return 0;
 return nfs_refresh_inode_locked(inode, fattr);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1401,6 +1410,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 (save_cache_validity &amp;amp; NFS_INO_REVAL_FORCED))
 nfsi-&amp;gt;cache_validity |= invalid;
 
+if (invalid &amp;amp; NFS_INO_INVALID_DATA)
+nfs_fscache_invalidate(inode);
+
 return 0;
  out_changed:
 /*
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f0c849c..2b98a35 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -64,6 +64,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 #include "iostat.h"
 #include "callback.h"
 #include "pnfs.h"
+#include "fscache.h"
 
 #define NFSDBG_FACILITYNFSDBG_PROC
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -753,6 +754,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
 if (!cinfo-&amp;gt;atomic || cinfo-&amp;gt;before != dir-&amp;gt;i_version)
 nfs_force_lookup_revalidate(dir);
 dir-&amp;gt;i_version = cinfo-&amp;gt;after;
+nfs_fscache_invalidate(dir);
 spin_unlock(&amp;amp;dir-&amp;gt;i_lock);
 }
 

&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-02-08T21:18:23</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3081">
    <title>[PATCH 09/17] CacheFiles: Implement invalidation</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3081</link>
    <description>&lt;pre&gt;Implement invalidation for CacheFiles.  This is in two parts:

 (1) Provide an invalidation method (which just truncates the backing file).

 (2) Abort attempts to copy anything read from the backing file whilst
     invalidation is in progress.

Question: CacheFiles uses truncation in a couple of places.  It has been using
notify_change() rather than sys_truncate() or something similar.  This means
it bypasses a bunch of checks and suchlike that it possibly should be making
(security, file locking, lease breaking, vfsmount write).  Should it be using
vfs_truncate() as added by a preceding patch or should it use notify_write()
and assume that anyone poking around in the cache files on disk gets
everything they deserve?

Signed-off-by: David Howells &amp;lt;dhowells&amp;lt; at &amp;gt;redhat.com&amp;gt;
---

 fs/cachefiles/interface.c |   49 +++++++++++++++++++++++++++++++++++++++++++++
 fs/cachefiles/rdwr.c      |    5 ++++-
 2 files changed, 53 insertions(+), 1 deletions(-)

diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index 9bff0f8..7a9d574 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -441,6 +441,54 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; truncate_failed:
 }
 
 /*
+ * Invalidate an object
+ */
+static void cachefiles_invalidate_object(struct fscache_operation *op)
+{
+struct cachefiles_object *object;
+struct cachefiles_cache *cache;
+const struct cred *saved_cred;
+struct path path;
+uint64_t ni_size;
+int ret;
+
+object = container_of(op-&amp;gt;object, struct cachefiles_object, fscache);
+cache = container_of(object-&amp;gt;fscache.cache,
+     struct cachefiles_cache, cache);
+
+op-&amp;gt;object-&amp;gt;cookie-&amp;gt;def-&amp;gt;get_attr(op-&amp;gt;object-&amp;gt;cookie-&amp;gt;netfs_data,
+  &amp;amp;ni_size);
+
+_enter("{OBJ%x},[%llu]",
+       op-&amp;gt;object-&amp;gt;debug_id, (unsigned long long)ni_size);
+
+if (object-&amp;gt;backer) {
+ASSERT(S_ISREG(object-&amp;gt;backer-&amp;gt;d_inode-&amp;gt;i_mode));
+
+fscache_set_store_limit(&amp;amp;object-&amp;gt;fscache, ni_size);
+
+path.dentry = object-&amp;gt;backer;
+path.mnt = cache-&amp;gt;mnt;
+
+cachefiles_begin_secure(cache, &amp;amp;saved_cred);
+ret = vfs_truncate(&amp;amp;path, 0);
+if (ret == 0)
+ret = vfs_truncate(&amp;amp;path, ni_size);
+cachefiles_end_secure(cache, saved_cred);
+
+if (ret != 0) {
+fscache_set_store_limit(&amp;amp;object-&amp;gt;fscache, 0);
+if (ret == -EIO)
+cachefiles_io_error_obj(object,
+"Invalidate failed");
+}
+}
+
+fscache_op_complete(op);
+_leave("");
+}
+
+/*
  * dissociate a cache from all the pages it was backing
  */
 static void cachefiles_dissociate_pages(struct fscache_cache *cache)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -455,6 +503,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; const struct fscache_cache_ops cachefiles_cache_ops = {
 .lookup_complete= cachefiles_lookup_complete,
 .grab_object= cachefiles_grab_object,
 .update_object= cachefiles_update_object,
+.invalidate_object= cachefiles_invalidate_object,
 .drop_object= cachefiles_drop_object,
 .put_object= cachefiles_put_object,
 .sync_cache= cachefiles_sync_cache,
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
index 31cda81..f437e97 100644
--- a/fs/cachefiles/rdwr.c
+++ b/fs/cachefiles/rdwr.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -174,7 +174,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cachefiles_read_copier(struct fscache_operation *_op)
 _debug("- copy {%lu}", monitor-&amp;gt;back_page-&amp;gt;index);
 
 recheck:
-if (PageUptodate(monitor-&amp;gt;back_page)) {
+if (test_bit(FSCACHE_COOKIE_INVALIDATING,
+     &amp;amp;object-&amp;gt;fscache.cookie-&amp;gt;flags)) {
+error = -ESTALE;
+} else if (PageUptodate(monitor-&amp;gt;back_page)) {
 copy_highpage(monitor-&amp;gt;netfs_page, monitor-&amp;gt;back_page);
 fscache_mark_page_cached(monitor-&amp;gt;op,
  monitor-&amp;gt;netfs_page);

&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-02-08T21:18:13</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3080">
    <title>[PATCH 08/17] VFS: Make more complete truncate operation available to CacheFiles</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3080</link>
    <description>&lt;pre&gt;Make a more complete truncate operation available to CacheFiles (including
security checks and suchlike) so that it can use this to clear invalidated
cache files.

Signed-off-by: David Howells &amp;lt;dhowells&amp;lt; at &amp;gt;redhat.com&amp;gt;
---

 fs/open.c          |   50 +++++++++++++++++++++++++++-----------------------
 include/linux/fs.h |    1 +
 2 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index 77becc0..7535620 100644
--- a/fs/open.c
+++ b/fs/open.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -61,33 +61,22 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
 return ret;
 }
 
-static long do_sys_truncate(const char __user *pathname, loff_t length)
+long vfs_truncate(struct path *path, loff_t length)
 {
-struct path path;
 struct inode *inode;
-int error;
-
-error = -EINVAL;
-if (length &amp;lt; 0)/* sorry, but loff_t says... */
-goto out;
+long error;
 
-error = user_path(pathname, &amp;amp;path);
-if (error)
-goto out;
-inode = path.dentry-&amp;gt;d_inode;
+inode = path-&amp;gt;dentry-&amp;gt;d_inode;
 
 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
-error = -EISDIR;
 if (S_ISDIR(inode-&amp;gt;i_mode))
-goto dput_and_out;
-
-error = -EINVAL;
+return -EISDIR;
 if (!S_ISREG(inode-&amp;gt;i_mode))
-goto dput_and_out;
+return -EINVAL;
 
-error = mnt_want_write(path.mnt);
+error = mnt_want_write(path-&amp;gt;mnt);
 if (error)
-goto dput_and_out;
+goto out;
 
 error = inode_permission(inode, MAY_WRITE);
 if (error)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -111,19 +100,34 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static long do_sys_truncate(const char __user *pathname, loff_t length)
 
 error = locks_verify_truncate(inode, NULL, length);
 if (!error)
-error = security_path_truncate(&amp;amp;path);
+error = security_path_truncate(path);
 if (!error)
-error = do_truncate(path.dentry, length, 0, NULL);
+error = do_truncate(path-&amp;gt;dentry, length, 0, NULL);
 
 put_write_and_out:
 put_write_access(inode);
 mnt_drop_write_and_out:
-mnt_drop_write(path.mnt);
-dput_and_out:
-path_put(&amp;amp;path);
+mnt_drop_write(path-&amp;gt;mnt);
 out:
 return error;
 }
+EXPORT_SYMBOL_GPL(vfs_truncate);
+
+static long do_sys_truncate(const char __user *pathname, loff_t length)
+{
+struct path path;
+int error;
+
+if (length &amp;lt; 0)/* sorry, but loff_t says... */
+return -EINVAL;
+
+error = user_path(pathname, &amp;amp;path);
+if (!error) {
+error = vfs_truncate(&amp;amp;path, length);
+path_put(&amp;amp;path);
+}
+return error;
+}
 
 SYSCALL_DEFINE2(truncate, const char __user *, path, long, length)
 {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 386da09..79449e4 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -2014,6 +2014,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline int break_lease(struct inode *inode, unsigned int mode)
 
 /* fs/open.c */
 
+extern long vfs_truncate(struct path *, loff_t);
 extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
        struct file *filp);
 extern int do_fallocate(struct file *file, int mode, loff_t offset,

&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-02-08T21:18:03</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3079">
    <title>[PATCH 07/17] FS-Cache: Provide proper invalidation</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3079</link>
    <description>&lt;pre&gt;Provide a proper invalidation method rather than relying on the netfs retiring
the cookie it has and getting a new one.  The problem with this is that isn't
easy for the netfs to make sure that it has completed/cancelled all its
outstanding storage and retrieval operations on the cookie it is retiring.

Instead, have the cache provide an invalidation method that will cancel or wait
for all currently outstanding operations before invalidating the cache, and
will cause new operations to queue up behind that.  Whilst invalidation is in
progress, some requests will be rejected until the cache can stack a barrier on
the operation queue to cause new operations to be deferred behind it.

Signed-off-by: David Howells &amp;lt;dhowells&amp;lt; at &amp;gt;redhat.com&amp;gt;
---

 Documentation/filesystems/caching/backend-api.txt |   12 ++++
 Documentation/filesystems/caching/netfs-api.txt   |   46 +++++++++++--
 Documentation/filesystems/caching/object.txt      |   23 ++++---
 fs/fscache/cookie.c                               |   60 ++++++++++++++++++
 fs/fscache/internal.h                             |   10 +++
 fs/fscache/object.c                               |   72 +++++++++++++++++++++
 fs/fscache/operation.c                            |   32 +++++++++
 fs/fscache/page.c                                 |   51 +++++++++++++++
 fs/fscache/stats.c                                |   11 +++
 include/linux/fscache-cache.h                     |    8 ++
 include/linux/fscache.h                           |   38 +++++++++++
 11 files changed, 345 insertions(+), 18 deletions(-)

diff --git a/Documentation/filesystems/caching/backend-api.txt b/Documentation/filesystems/caching/backend-api.txt
index f4769b9..d78bab9 100644
--- a/Documentation/filesystems/caching/backend-api.txt
+++ b/Documentation/filesystems/caching/backend-api.txt
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -308,6 +308,18 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; performed on the denizens of the cache.  These are held in a structure of type:
      obtained by calling object-&amp;gt;cookie-&amp;gt;def-&amp;gt;get_aux()/get_attr().
 
 
+ (*) Invalidate data object [mandatory]:
+
+int (*invalidate_object)(struct fscache_operation *op)
+
+     This is called to invalidate a data object (as pointed to by op-&amp;gt;object).
+     All the data stored for this object should be discarded and an
+     attr_changed operation should be performed.  The caller will follow up
+     with an object update operation.
+
+     fscache_op_complete() must be called on op before returning.
+
+
  (*) Discard object [mandatory]:
 
 void (*drop_object)(struct fscache_object *object)
diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt
index 7cc6bf2..97e6c0e 100644
--- a/Documentation/filesystems/caching/netfs-api.txt
+++ b/Documentation/filesystems/caching/netfs-api.txt
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -35,8 +35,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; This document contains the following sections:
 (12) Index and data file update
 (13) Miscellaneous cookie operations
 (14) Cookie unregistration
-(15) Index and data file invalidation
-(16) FS-Cache specific page flags.
+(15) Index invalidation
+(16) Data file invalidation
+(17) FS-Cache specific page flags.
 
 
 =============================
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -767,13 +768,42 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; the cookies for "child" indices, objects and pages have been relinquished
 first.
 
 
-================================
-INDEX AND DATA FILE INVALIDATION
-================================
+==================
+INDEX INVALIDATION
+==================
+
+There is no direct way to invalidate an index subtree.  To do this, the caller
+should relinquish and retire the cookie they have, and then acquire a new one.
+
+
+======================
+DATA FILE INVALIDATION
+======================
+
+Sometimes it will be necessary to invalidate an object that contains data.
+Typically this will be necessary when the server tells the netfs of a foreign
+change - at which point the netfs has to throw away all the state it had for an
+inode and reload from the server.
+
+To indicate that a cache object should be invalidated, the following function
+can be called:
+
+void fscache_invalidate(struct fscache_cookie *cookie);
+
+This can be called with spinlocks held as it defers the work to a thread pool.
+All extant storage, retrieval and attribute change ops at this point are
+cancelled and discarded.  Some future operations will be rejected until the
+cache has had a chance to insert a barrier in the operations queue.  After
+that, operations will be queued again behind the invalidation operation.
+
+The invalidation operation will perform an attribute change operation and an
+auxiliary data update operation as it is very likely these will have changed.
+
+Using the following function, the netfs can wait for the invalidation operation
+to have reached a point at which it can start submitting ordinary operations
+once again:
 
-There is no direct way to invalidate an index subtree or a data file.  To do
-this, the caller should relinquish and retire the cookie they have, and then
-acquire a new one.
+void fscache_wait_on_invalidate(struct fscache_cookie *cookie);
 
 
 ===========================
diff --git a/Documentation/filesystems/caching/object.txt b/Documentation/filesystems/caching/object.txt
index 5831334..100ff41 100644
--- a/Documentation/filesystems/caching/object.txt
+++ b/Documentation/filesystems/caching/object.txt
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -216,7 +216,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; servicing netfs requests:
      The normal running state.  In this state, requests the netfs makes will be
      passed on to the cache.
 
- (6) State FSCACHE_OBJECT_UPDATING.
+ (6) State FSCACHE_OBJECT_INVALIDATING.
+
+     The object is undergoing invalidation.  When the state comes here, it
+     discards all pending read, write and attribute change operations as it is
+     going to clear out the cache entirely and reinitialise it.  It will then
+     continue to the FSCACHE_OBJECT_UPDATING state.
+
+ (7) State FSCACHE_OBJECT_UPDATING.
 
      The state machine comes here to update the object in the cache from the
      netfs's records.  This involves updating the auxiliary data that is used
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -225,13 +232,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; servicing netfs requests:
 And there are terminal states in which an object cleans itself up, deallocates
 memory and potentially deletes stuff from disk:
 
- (7) State FSCACHE_OBJECT_LC_DYING.
+ (8) State FSCACHE_OBJECT_LC_DYING.
 
      The object comes here if it is dying because of a lookup or creation
      error.  This would be due to a disk error or system error of some sort.
      Temporary data is cleaned up, and the parent is released.
 
- (8) State FSCACHE_OBJECT_DYING.
+ (9) State FSCACHE_OBJECT_DYING.
 
      The object comes here if it is dying due to an error, because its parent
      cookie has been relinquished by the netfs or because the cache is being
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -241,27 +248,27 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; memory and potentially deletes stuff from disk:
      can destroy themselves.  This object waits for all its children to go away
      before advancing to the next state.
 
- (9) State FSCACHE_OBJECT_ABORT_INIT.
+(10) State FSCACHE_OBJECT_ABORT_INIT.
 
      The object comes to this state if it was waiting on its parent in
      FSCACHE_OBJECT_INIT, but its parent died.  The object will destroy itself
      so that the parent may proceed from the FSCACHE_OBJECT_DYING state.
 
-(10) State FSCACHE_OBJECT_RELEASING.
-(11) State FSCACHE_OBJECT_RECYCLING.
+(11) State FSCACHE_OBJECT_RELEASING.
+(12) State FSCACHE_OBJECT_RECYCLING.
 
      The object comes to one of these two states when dying once it is rid of
      all its children, if it is dying because the netfs relinquished its
      cookie.  In the first state, the cached data is expected to persist, and
      in the second it will be deleted.
 
-(12) State FSCACHE_OBJECT_WITHDRAWING.
+(13) State FSCACHE_OBJECT_WITHDRAWING.
 
      The object transits to this state if the cache decides it wants to
      withdraw the object from service, perhaps to make space, but also due to
      error or just because the whole cache is being withdrawn.
 
-(13) State FSCACHE_OBJECT_DEAD.
+(14) State FSCACHE_OBJECT_DEAD.
 
      The object transits to this state when the in-memory object record is
      ready to be deleted.  The object processor shouldn't ever see an object in
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
index 66be9ec..8dcb114 100644
--- a/fs/fscache/cookie.c
+++ b/fs/fscache/cookie.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -370,6 +370,66 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; cant_attach_object:
 }
 
 /*
+ * Invalidate an object.  Callable with spinlocks held.
+ */
+void __fscache_invalidate(struct fscache_cookie *cookie)
+{
+struct fscache_object *object;
+
+_enter("{%s}", cookie-&amp;gt;def-&amp;gt;name);
+
+fscache_stat(&amp;amp;fscache_n_invalidates);
+
+/* Only permit invalidation of data files.  Invalidating an index will
+ * require the caller to release all its attachments to the tree rooted
+ * there, and if it's doing that, it may as well just retire the
+ * cookie.
+ */
+ASSERTCMP(cookie-&amp;gt;def-&amp;gt;type, ==, FSCACHE_COOKIE_TYPE_DATAFILE);
+
+/* We will be updating the cookie too. */
+BUG_ON(!cookie-&amp;gt;def-&amp;gt;get_aux);
+
+/* If there's an object, we tell the object state machine to handle the
+ * invalidation on our behalf, otherwise there's nothing to do.
+ */
+if (!hlist_empty(&amp;amp;cookie-&amp;gt;backing_objects)) {
+spin_lock(&amp;amp;cookie-&amp;gt;lock);
+
+if (!hlist_empty(&amp;amp;cookie-&amp;gt;backing_objects) &amp;amp;&amp;amp;
+    !test_and_set_bit(FSCACHE_COOKIE_INVALIDATING,
+      &amp;amp;cookie-&amp;gt;flags)) {
+object = hlist_entry(cookie-&amp;gt;backing_objects.first,
+     struct fscache_object,
+     cookie_link);
+if (object-&amp;gt;state &amp;lt; FSCACHE_OBJECT_DYING)
+fscache_raise_event(
+object, FSCACHE_OBJECT_EV_INVALIDATE);
+}
+
+spin_unlock(&amp;amp;cookie-&amp;gt;lock);
+}
+
+_leave("");
+}
+EXPORT_SYMBOL(__fscache_invalidate);
+
+/*
+ * Wait for object invalidation to complete.
+ */
+void __fscache_wait_on_invalidate(struct fscache_cookie *cookie)
+{
+_enter("%p", cookie);
+
+wait_on_bit(&amp;amp;cookie-&amp;gt;flags, FSCACHE_COOKIE_INVALIDATING,
+    fscache_wait_bit_interruptible,
+    TASK_UNINTERRUPTIBLE);
+
+_leave("");
+}
+EXPORT_SYMBOL(__fscache_wait_on_invalidate);
+
+/*
  * update the index entries backing a cookie
  */
 void __fscache_update_cookie(struct fscache_cookie *cookie)
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h
index f6aad48..c811793 100644
--- a/fs/fscache/internal.h
+++ b/fs/fscache/internal.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -122,11 +122,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern int fscache_submit_exclusive_op(struct fscache_object *,
 extern int fscache_submit_op(struct fscache_object *,
      struct fscache_operation *);
 extern int fscache_cancel_op(struct fscache_operation *);
+extern void fscache_cancel_all_ops(struct fscache_object *);
 extern void fscache_abort_object(struct fscache_object *);
 extern void fscache_start_operations(struct fscache_object *);
 extern void fscache_operation_gc(struct work_struct *);
 
 /*
+ * page.c
+ */
+extern void fscache_invalidate_writes(struct fscache_cookie *);
+
+/*
  * proc.c
  */
 #ifdef CONFIG_PROC_FS
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -205,6 +211,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern atomic_t fscache_n_acquires_ok;
 extern atomic_t fscache_n_acquires_nobufs;
 extern atomic_t fscache_n_acquires_oom;
 
+extern atomic_t fscache_n_invalidates;
+extern atomic_t fscache_n_invalidates_run;
+
 extern atomic_t fscache_n_updates;
 extern atomic_t fscache_n_updates_null;
 extern atomic_t fscache_n_updates_run;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -237,6 +246,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern atomic_t fscache_n_cop_alloc_object;
 extern atomic_t fscache_n_cop_lookup_object;
 extern atomic_t fscache_n_cop_lookup_complete;
 extern atomic_t fscache_n_cop_grab_object;
+extern atomic_t fscache_n_cop_invalidate_object;
 extern atomic_t fscache_n_cop_update_object;
 extern atomic_t fscache_n_cop_drop_object;
 extern atomic_t fscache_n_cop_put_object;
diff --git a/fs/fscache/object.c b/fs/fscache/object.c
index 773bc79..80b5491 100644
--- a/fs/fscache/object.c
+++ b/fs/fscache/object.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -14,6 +14,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 #define FSCACHE_DEBUG_LEVEL COOKIE
 #include &amp;lt;linux/module.h&amp;gt;
+#include &amp;lt;linux/slab.h&amp;gt;
 #include "internal.h"
 
 const char *fscache_object_states[FSCACHE_OBJECT__NSTATES] = {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -22,6 +23,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; const char *fscache_object_states[FSCACHE_OBJECT__NSTATES] = {
 [FSCACHE_OBJECT_CREATING]= "OBJECT_CREATING",
 [FSCACHE_OBJECT_AVAILABLE]= "OBJECT_AVAILABLE",
 [FSCACHE_OBJECT_ACTIVE]= "OBJECT_ACTIVE",
+[FSCACHE_OBJECT_INVALIDATING]= "OBJECT_INVALIDATING",
 [FSCACHE_OBJECT_UPDATING]= "OBJECT_UPDATING",
 [FSCACHE_OBJECT_DYING]= "OBJECT_DYING",
 [FSCACHE_OBJECT_LC_DYING]= "OBJECT_LC_DYING",
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -39,6 +41,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5] = {
 [FSCACHE_OBJECT_CREATING]= "CRTN",
 [FSCACHE_OBJECT_AVAILABLE]= "AVBL",
 [FSCACHE_OBJECT_ACTIVE]= "ACTV",
+[FSCACHE_OBJECT_INVALIDATING]= "INVL",
 [FSCACHE_OBJECT_UPDATING]= "UPDT",
 [FSCACHE_OBJECT_DYING]= "DYNG",
 [FSCACHE_OBJECT_LC_DYING]= "LCDY",
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -54,6 +57,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void fscache_put_object(struct fscache_object *);
 static void fscache_initialise_object(struct fscache_object *);
 static void fscache_lookup_object(struct fscache_object *);
 static void fscache_object_available(struct fscache_object *);
+static void fscache_invalidate_object(struct fscache_object *);
 static void fscache_release_object(struct fscache_object *);
 static void fscache_withdraw_object(struct fscache_object *);
 static void fscache_enqueue_dependents(struct fscache_object *);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -79,6 +83,15 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline void fscache_done_parent_op(struct fscache_object *object)
 }
 
 /*
+ * Notify netfs of invalidation completion.
+ */
+static inline void fscache_invalidation_complete(struct fscache_cookie *cookie)
+{
+if (test_and_clear_bit(FSCACHE_COOKIE_INVALIDATING, &amp;amp;cookie-&amp;gt;flags))
+wake_up_bit(&amp;amp;cookie-&amp;gt;flags, FSCACHE_COOKIE_INVALIDATING);
+}
+
+/*
  * process events that have been sent to an object's state machine
  * - initiates parent lookup
  * - does object lookup
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -125,6 +138,16 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void fscache_object_state_machine(struct fscache_object *object)
 case FSCACHE_OBJECT_ACTIVE:
 goto active_transit;
 
+/* Invalidate an object on disk */
+case FSCACHE_OBJECT_INVALIDATING:
+clear_bit(FSCACHE_OBJECT_EV_INVALIDATE, &amp;amp;object-&amp;gt;events);
+fscache_stat(&amp;amp;fscache_n_invalidates_run);
+fscache_stat(&amp;amp;fscache_n_cop_invalidate_object);
+fscache_invalidate_object(object);
+fscache_stat_d(&amp;amp;fscache_n_cop_invalidate_object);
+fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE);
+goto active_transit;
+
 /* update the object metadata on disk */
 case FSCACHE_OBJECT_UPDATING:
 clear_bit(FSCACHE_OBJECT_EV_UPDATE, &amp;amp;object-&amp;gt;events);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -275,6 +298,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; active_transit:
 case FSCACHE_OBJECT_EV_ERROR:
 new_state = FSCACHE_OBJECT_DYING;
 goto change_state;
+case FSCACHE_OBJECT_EV_INVALIDATE:
+new_state = FSCACHE_OBJECT_INVALIDATING;
+goto change_state;
 case FSCACHE_OBJECT_EV_UPDATE:
 new_state = FSCACHE_OBJECT_UPDATING;
 goto change_state;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -679,6 +705,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void fscache_withdraw_object(struct fscache_object *object)
 if (object-&amp;gt;cookie == cookie) {
 hlist_del_init(&amp;amp;object-&amp;gt;cookie_link);
 object-&amp;gt;cookie = NULL;
+fscache_invalidation_complete(cookie);
 detached = true;
 }
 spin_unlock(&amp;amp;cookie-&amp;gt;lock);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -888,3 +915,48 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
 return result;
 }
 EXPORT_SYMBOL(fscache_check_aux);
+
+/*
+ * Asynchronously invalidate an object.
+ */
+static void fscache_invalidate_object(struct fscache_object *object)
+{
+struct fscache_operation *op;
+struct fscache_cookie *cookie = object-&amp;gt;cookie;
+
+_enter("{OBJ%x}", object-&amp;gt;debug_id);
+
+/* Reject any new read/write ops and abort any that are pending. */
+fscache_invalidate_writes(cookie);
+clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &amp;amp;object-&amp;gt;flags);
+fscache_cancel_all_ops(object);
+
+/* Now we have to wait for in-progress reads and writes */
+op = kzalloc(sizeof(*op), GFP_KERNEL);
+if (!op) {
+fscache_raise_event(object, FSCACHE_OBJECT_EV_ERROR);
+_leave(" [ENOMEM]");
+return;
+}
+
+fscache_operation_init(op, object-&amp;gt;cache-&amp;gt;ops-&amp;gt;invalidate_object, NULL);
+op-&amp;gt;flags = FSCACHE_OP_ASYNC | (1 &amp;lt;&amp;lt; FSCACHE_OP_EXCLUSIVE);
+
+spin_lock(&amp;amp;cookie-&amp;gt;lock);
+if (fscache_submit_exclusive_op(object, op) &amp;lt; 0)
+BUG();
+spin_unlock(&amp;amp;cookie-&amp;gt;lock);
+fscache_put_operation(op);
+
+/* Once we've completed the invalidation, we know there will be no data
+ * stored in the cache and thus we can reinstate the data-check-skip
+ * optimisation.
+ */
+set_bit(FSCACHE_COOKIE_NO_DATA_YET, &amp;amp;cookie-&amp;gt;flags);
+
+/* We can allow read and write requests to come in once again.  They'll
+ * queue up behind our exclusive invalidation operation.
+ */
+fscache_invalidation_complete(cookie);
+_leave("");
+}
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c
index 748f955..c58dbe6 100644
--- a/fs/fscache/operation.c
+++ b/fs/fscache/operation.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -324,6 +324,38 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int fscache_cancel_op(struct fscache_operation *op)
 }
 
 /*
+ * Cancel all pending operations on an object
+ */
+void fscache_cancel_all_ops(struct fscache_object *object)
+{
+struct fscache_operation *op;
+
+_enter("OBJ%x", object-&amp;gt;debug_id);
+
+spin_lock(&amp;amp;object-&amp;gt;lock);
+
+while (!list_empty(&amp;amp;object-&amp;gt;pending_ops)) {
+op = list_entry(object-&amp;gt;pending_ops.next,
+struct fscache_operation, pend_link);
+fscache_stat(&amp;amp;fscache_n_op_cancelled);
+list_del_init(&amp;amp;op-&amp;gt;pend_link);
+
+ASSERTCMP(op-&amp;gt;state, ==, FSCACHE_OP_ST_PENDING);
+op-&amp;gt;state = FSCACHE_OP_ST_CANCELLED;
+
+if (test_bit(FSCACHE_OP_EXCLUSIVE, &amp;amp;op-&amp;gt;flags))
+object-&amp;gt;n_exclusive--;
+if (test_and_clear_bit(FSCACHE_OP_WAITING, &amp;amp;op-&amp;gt;flags))
+wake_up_bit(&amp;amp;op-&amp;gt;flags, FSCACHE_OP_WAITING);
+fscache_put_operation(op);
+cond_resched_lock(&amp;amp;object-&amp;gt;lock);
+}
+
+spin_unlock(&amp;amp;object-&amp;gt;lock);
+_leave("");
+}
+
+/*
  * Record the completion of an in-progress operation.
  */
 void fscache_op_complete(struct fscache_operation *op)
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index b38b13d..7bf9d25 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -361,6 +361,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
 if (hlist_empty(&amp;amp;cookie-&amp;gt;backing_objects))
 goto nobufs;
 
+if (test_bit(FSCACHE_COOKIE_INVALIDATING, &amp;amp;cookie-&amp;gt;flags)) {
+_leave(" = -ENOBUFS [invalidating]");
+return -ENOBUFS;
+}
+
 ASSERTCMP(cookie-&amp;gt;def-&amp;gt;type, !=, FSCACHE_COOKIE_TYPE_INDEX);
 ASSERTCMP(page, !=, NULL);
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -483,6 +488,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
 if (hlist_empty(&amp;amp;cookie-&amp;gt;backing_objects))
 goto nobufs;
 
+if (test_bit(FSCACHE_COOKIE_INVALIDATING, &amp;amp;cookie-&amp;gt;flags)) {
+_leave(" = -ENOBUFS [invalidating]");
+return -ENOBUFS;
+}
+
 ASSERTCMP(cookie-&amp;gt;def-&amp;gt;type, !=, FSCACHE_COOKIE_TYPE_INDEX);
 ASSERTCMP(*nr_pages, &amp;gt;, 0);
 ASSERT(!list_empty(pages));
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -591,6 +601,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int __fscache_alloc_page(struct fscache_cookie *cookie,
 ASSERTCMP(cookie-&amp;gt;def-&amp;gt;type, !=, FSCACHE_COOKIE_TYPE_INDEX);
 ASSERTCMP(page, !=, NULL);
 
+if (test_bit(FSCACHE_COOKIE_INVALIDATING, &amp;amp;cookie-&amp;gt;flags)) {
+_leave(" = -ENOBUFS [invalidating]");
+return -ENOBUFS;
+}
+
 if (fscache_wait_for_deferred_lookup(cookie) &amp;lt; 0)
 return -ERESTARTSYS;
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -731,6 +746,37 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; superseded:
 }
 
 /*
+ * Clear the pages pending writing for invalidation
+ */
+void fscache_invalidate_writes(struct fscache_cookie *cookie)
+{
+struct page *page;
+void *results[16];
+int n, i;
+
+_enter("");
+
+while (spin_lock(&amp;amp;cookie-&amp;gt;stores_lock),
+       n = radix_tree_gang_lookup_tag(&amp;amp;cookie-&amp;gt;stores, results, 0,
+      ARRAY_SIZE(results),
+      FSCACHE_COOKIE_PENDING_TAG),
+       n &amp;gt; 0) {
+for (i = n - 1; i &amp;gt;= 0; i--) {
+page = results[i];
+radix_tree_delete(&amp;amp;cookie-&amp;gt;stores, page-&amp;gt;index);
+}
+
+spin_unlock(&amp;amp;cookie-&amp;gt;stores_lock);
+
+for (i = n - 1; i &amp;gt;= 0; i--)
+page_cache_release(results[i]);
+}
+
+spin_unlock(&amp;amp;cookie-&amp;gt;stores_lock);
+_leave("");
+}
+
+/*
  * request a page be stored in the cache
  * - returns:
  *   -ENOMEM- out of memory, nothing done
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -776,6 +822,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int __fscache_write_page(struct fscache_cookie *cookie,
 
 fscache_stat(&amp;amp;fscache_n_stores);
 
+if (test_bit(FSCACHE_COOKIE_INVALIDATING, &amp;amp;cookie-&amp;gt;flags)) {
+_leave(" = -ENOBUFS [invalidating]");
+return -ENOBUFS;
+}
+
 op = kzalloc(sizeof(*op), GFP_NOIO | __GFP_NOMEMALLOC | __GFP_NORETRY);
 if (!op)
 goto nomem;
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c
index 4765190..51cdaee 100644
--- a/fs/fscache/stats.c
+++ b/fs/fscache/stats.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -80,6 +80,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; atomic_t fscache_n_acquires_ok;
 atomic_t fscache_n_acquires_nobufs;
 atomic_t fscache_n_acquires_oom;
 
+atomic_t fscache_n_invalidates;
+atomic_t fscache_n_invalidates_run;
+
 atomic_t fscache_n_updates;
 atomic_t fscache_n_updates_null;
 atomic_t fscache_n_updates_run;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -112,6 +115,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; atomic_t fscache_n_cop_alloc_object;
 atomic_t fscache_n_cop_lookup_object;
 atomic_t fscache_n_cop_lookup_complete;
 atomic_t fscache_n_cop_grab_object;
+atomic_t fscache_n_cop_invalidate_object;
 atomic_t fscache_n_cop_update_object;
 atomic_t fscache_n_cop_drop_object;
 atomic_t fscache_n_cop_put_object;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -168,6 +172,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int fscache_stats_show(struct seq_file *m, void *v)
    atomic_read(&amp;amp;fscache_n_object_created),
    atomic_read(&amp;amp;fscache_n_object_lookups_timed_out));
 
+seq_printf(m, "Invals : n=%u run=%u\n",
+   atomic_read(&amp;amp;fscache_n_invalidates),
+   atomic_read(&amp;amp;fscache_n_invalidates_run));
+
 seq_printf(m, "Updates: n=%u nul=%u run=%u\n",
    atomic_read(&amp;amp;fscache_n_updates),
    atomic_read(&amp;amp;fscache_n_updates_null),
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -246,7 +254,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int fscache_stats_show(struct seq_file *m, void *v)
    atomic_read(&amp;amp;fscache_n_cop_lookup_object),
    atomic_read(&amp;amp;fscache_n_cop_lookup_complete),
    atomic_read(&amp;amp;fscache_n_cop_grab_object));
-seq_printf(m, "CacheOp: upo=%d dro=%d pto=%d atc=%d syn=%d\n",
+seq_printf(m, "CacheOp: inv=%d upo=%d dro=%d pto=%d atc=%d syn=%d\n",
+   atomic_read(&amp;amp;fscache_n_cop_invalidate_object),
    atomic_read(&amp;amp;fscache_n_cop_update_object),
    atomic_read(&amp;amp;fscache_n_cop_drop_object),
    atomic_read(&amp;amp;fscache_n_cop_put_object),
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index f5facd1..1e454ad 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -254,6 +254,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct fscache_cache_ops {
 /* store the updated auxiliary data on an object */
 void (*update_object)(struct fscache_object *object);
 
+/* Invalidate an object */
+void (*invalidate_object)(struct fscache_operation *op);
+
 /* discard the resources pinned by an object and effect retirement if
  * necessary */
 void (*drop_object)(struct fscache_object *object);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -329,6 +332,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct fscache_cookie {
 #define FSCACHE_COOKIE_FILLING4/* T if filling object incrementally */
 #define FSCACHE_COOKIE_UNAVAILABLE5/* T if cookie is unavailable (error, etc) */
 #define FSCACHE_COOKIE_WAITING_ON_READS6/* T if cookie is waiting on reads */
+#define FSCACHE_COOKIE_INVALIDATING7/* T if cookie is being invalidated */
 };
 
 extern struct fscache_cookie fscache_fsdef_index;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -345,6 +349,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct fscache_object {
 /* active states */
 FSCACHE_OBJECT_AVAILABLE,/* cleaning up object after creation */
 FSCACHE_OBJECT_ACTIVE,/* object is usable */
+FSCACHE_OBJECT_INVALIDATING,/* object is invalidating */
 FSCACHE_OBJECT_UPDATING,/* object is updating */
 
 /* terminal states */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -378,7 +383,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct fscache_object {
 #define FSCACHE_OBJECT_EV_RELEASE4/* T if netfs requested object release */
 #define FSCACHE_OBJECT_EV_RETIRE5/* T if netfs requested object retirement */
 #define FSCACHE_OBJECT_EV_WITHDRAW6/* T if cache requested object withdrawal */
-#define FSCACHE_OBJECT_EVENTS_MASK0x7f/* mask of all events*/
+#define FSCACHE_OBJECT_EV_INVALIDATE7/* T if cache requested object invalidation */
+#define FSCACHE_OBJECT_EVENTS_MASK0xff/* mask of all events*/
 
 unsigned longflags;
 #define FSCACHE_OBJECT_LOCK0/* T if object is busy being processed */
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
index f4b6353..7a08623 100644
--- a/include/linux/fscache.h
+++ b/include/linux/fscache.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -185,6 +185,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern struct fscache_cookie *__fscache_acquire_cookie(
 extern void __fscache_relinquish_cookie(struct fscache_cookie *, int);
 extern void __fscache_update_cookie(struct fscache_cookie *);
 extern int __fscache_attr_changed(struct fscache_cookie *);
+extern void __fscache_invalidate(struct fscache_cookie *);
+extern void __fscache_wait_on_invalidate(struct fscache_cookie *);
 extern int __fscache_read_or_alloc_page(struct fscache_cookie *,
 struct page *,
 fscache_rw_complete_t,
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -390,6 +392,42 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int fscache_attr_changed(struct fscache_cookie *cookie)
 }
 
 /**
+ * fscache_invalidate - Notify cache that an object needs invalidation
+ * &amp;lt; at &amp;gt;cookie: The cookie representing the cache object
+ *
+ * Notify the cache that an object is needs to be invalidated and that it
+ * should abort any retrievals or stores it is doing on the cache.  The object
+ * is then marked non-caching until such time as the invalidation is complete.
+ *
+ * This can be called with spinlocks held.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_invalidate(struct fscache_cookie *cookie)
+{
+if (fscache_cookie_valid(cookie))
+__fscache_invalidate(cookie);
+}
+
+/**
+ * fscache_wait_on_invalidate - Wait for invalidation to complete
+ * &amp;lt; at &amp;gt;cookie: The cookie representing the cache object
+ *
+ * Wait for the invalidation of an object to complete.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_wait_on_invalidate(struct fscache_cookie *cookie)
+{
+if (fscache_cookie_valid(cookie))
+__fscache_wait_on_invalidate(cookie);
+}
+
+/**
  * fscache_reserve_space - Reserve data space for a cached object
  * &amp;lt; at &amp;gt;cookie: The cookie representing the cache object
  * &amp;lt; at &amp;gt;i_size: The amount of space to be reserved

&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-02-08T21:17:52</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3077">
    <title>[PATCH 05/17] FS-Cache: Make cookie relinquishment wait for outstanding reads</title>
    <link>http://permalink.gmane.org/gmane.linux.file-systems.cachefs.general/3077</link>
    <description>&lt;pre&gt;Make fscache_relinquish_cookie() log a warning and wait if there are any
outstanding reads left on the cookie it was given.

Signed-off-by: David Howells &amp;lt;dhowells&amp;lt; at &amp;gt;redhat.com&amp;gt;
---

 fs/fscache/cookie.c           |   18 ++++++++++++++----
 fs/fscache/operation.c        |   10 ++++++++--
 include/linux/fscache-cache.h |    1 +
 3 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
index 0666996..66be9ec 100644
--- a/fs/fscache/cookie.c
+++ b/fs/fscache/cookie.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -442,22 +442,32 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
 
 event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE;
 
+try_again:
 spin_lock(&amp;amp;cookie-&amp;gt;lock);
 
 /* break links with all the active objects */
 while (!hlist_empty(&amp;amp;cookie-&amp;gt;backing_objects)) {
+int n_reads;
 object = hlist_entry(cookie-&amp;gt;backing_objects.first,
      struct fscache_object,
      cookie_link);
 
 _debug("RELEASE OBJ%x", object-&amp;gt;debug_id);
 
-if (atomic_read(&amp;amp;object-&amp;gt;n_reads)) {
+set_bit(FSCACHE_COOKIE_WAITING_ON_READS, &amp;amp;cookie-&amp;gt;flags);
+n_reads = atomic_read(&amp;amp;object-&amp;gt;n_reads);
+if (n_reads) {
+int n_ops = object-&amp;gt;n_ops;
+int n_in_progress = object-&amp;gt;n_in_progress;
 spin_unlock(&amp;amp;cookie-&amp;gt;lock);
 printk(KERN_ERR "FS-Cache:"
-       " Cookie '%s' still has %d outstanding reads\n",
-       cookie-&amp;gt;def-&amp;gt;name, atomic_read(&amp;amp;object-&amp;gt;n_reads));
-BUG();
+       " Cookie '%s' still has %d outstanding reads (%d,%d)\n",
+       cookie-&amp;gt;def-&amp;gt;name,
+       n_reads, n_ops, n_in_progress);
+wait_on_bit(&amp;amp;cookie-&amp;gt;flags, FSCACHE_COOKIE_WAITING_ON_READS,
+    fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+printk("Wait finished\n");
+goto try_again;
 }
 
 /* detach each cache object from the object cookie */
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c
index 30afdfa..c857ab8 100644
--- a/fs/fscache/operation.c
+++ b/fs/fscache/operation.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -340,8 +340,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void fscache_put_operation(struct fscache_operation *op)
 
 object = op-&amp;gt;object;
 
-if (test_bit(FSCACHE_OP_DEC_READ_CNT, &amp;amp;op-&amp;gt;flags))
-atomic_dec(&amp;amp;object-&amp;gt;n_reads);
+if (test_bit(FSCACHE_OP_DEC_READ_CNT, &amp;amp;op-&amp;gt;flags)) {
+if (atomic_dec_and_test(&amp;amp;object-&amp;gt;n_reads)) {
+clear_bit(FSCACHE_COOKIE_WAITING_ON_READS,
+  &amp;amp;object-&amp;gt;cookie-&amp;gt;flags);
+wake_up_bit(&amp;amp;object-&amp;gt;cookie-&amp;gt;flags,
+    FSCACHE_COOKIE_WAITING_ON_READS);
+}
+}
 
 /* now... we may get called with the object spinlock held, so we
  * complete the cleanup here only if we can immediately acquire the
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index 9879183..e3d6d93 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -301,6 +301,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct fscache_cookie {
 #define FSCACHE_COOKIE_PENDING_FILL3/* T if pending initial fill on object */
 #define FSCACHE_COOKIE_FILLING4/* T if filling object incrementally */
 #define FSCACHE_COOKIE_UNAVAILABLE5/* T if cookie is unavailable (error, etc) */
+#define FSCACHE_COOKIE_WAITING_ON_READS6/* T if cookie is waiting on reads */
 };
 
 extern struct fscache_cookie fscache_fsdef_index;

&lt;/pre&gt;</description>
    <dc:creator>David Howells</dc:creator>
    <dc:date>2012-02-08T21:17:31</dc:date>
  </item>
  <textinput rdf:about="http://search.gmane.org/?group=$group=gmane.linux.file-systems.cachefs.general">
    <title>Search Engine</title>
    <description>Search the mailing list at Gmane</description>
    <name>query</name>
    <link>http://search.gmane.org/?group=$group=gmane.linux.file-systems.cachefs.general</link>
  </textinput>
</rdf:RDF>

