FS-Cache: Fix lock misorder in fscache_write_op()
[linux-2.6.git] / include / linux / fscache-cache.h
index 84d3532..f3aa4bd 100644 (file)
@@ -91,6 +91,8 @@ struct fscache_operation {
 #define FSCACHE_OP_WAITING     4       /* cleared when op is woken */
 #define FSCACHE_OP_EXCLUSIVE   5       /* exclusive op, other ops must wait */
 #define FSCACHE_OP_DEAD                6       /* op is now dead */
+#define FSCACHE_OP_DEC_READ_CNT        7       /* decrement object->n_reads on destruction */
+#define FSCACHE_OP_KEEP_FLAGS  0xc0    /* flags to keep when repurposing an op */
 
        atomic_t                usage;
        unsigned                debug_id;       /* debugging ID */
@@ -102,6 +104,16 @@ struct fscache_operation {
 
        /* operation releaser */
        fscache_operation_release_t release;
+
+#ifdef CONFIG_SLOW_WORK_PROC
+       const char *name;               /* operation name */
+       const char *state;              /* operation state */
+#define fscache_set_op_name(OP, N)     do { (OP)->name  = (N); } while(0)
+#define fscache_set_op_state(OP, S)    do { (OP)->state = (S); } while(0)
+#else
+#define fscache_set_op_name(OP, N)     do { } while(0)
+#define fscache_set_op_state(OP, S)    do { } while(0)
+#endif
 };
 
 extern atomic_t fscache_op_debug_id;
@@ -125,6 +137,7 @@ static inline void fscache_operation_init(struct fscache_operation *op,
        op->debug_id = atomic_inc_return(&fscache_op_debug_id);
        op->release = release;
        INIT_LIST_HEAD(&op->pend_link);
+       fscache_set_op_state(op, "Init");
 }
 
 /**
@@ -297,6 +310,7 @@ struct fscache_cookie {
        atomic_t                        usage;          /* number of users of this cookie */
        atomic_t                        n_children;     /* number of children of this cookie */
        spinlock_t                      lock;
+       spinlock_t                      stores_lock;    /* lock on page store tree */
        struct hlist_head               backing_objects; /* object(s) backing this file/index */
        const struct fscache_cookie_def *def;           /* definition */
        struct fscache_cookie           *parent;        /* parent of this entry */
@@ -337,6 +351,7 @@ struct fscache_object {
                FSCACHE_OBJECT_RECYCLING,       /* retiring object */
                FSCACHE_OBJECT_WITHDRAWING,     /* withdrawing object */
                FSCACHE_OBJECT_DEAD,            /* object is now dead */
+               FSCACHE_OBJECT__NSTATES
        } state;
 
        int                     debug_id;       /* debugging ID */
@@ -345,6 +360,7 @@ struct fscache_object {
        int                     n_obj_ops;      /* number of object ops outstanding on object */
        int                     n_in_progress;  /* number of ops in progress */
        int                     n_exclusive;    /* number of exclusive ops queued */
+       atomic_t                n_reads;        /* number of read ops in progress */
        spinlock_t              lock;           /* state and operations lock */
 
        unsigned long           lookup_jif;     /* time at which lookup started */
@@ -358,6 +374,7 @@ struct fscache_object {
 #define FSCACHE_OBJECT_EV_RELEASE      4       /* T if netfs requested object release */
 #define FSCACHE_OBJECT_EV_RETIRE       5       /* T if netfs requested object retirement */
 #define FSCACHE_OBJECT_EV_WITHDRAW     6       /* T if cache requested object withdrawal */
+#define FSCACHE_OBJECT_EVENTS_MASK     0x7f    /* mask of all events*/
 
        unsigned long           flags;
 #define FSCACHE_OBJECT_LOCK            0       /* T if object is busy being processed */
@@ -373,6 +390,9 @@ struct fscache_object {
        struct list_head        dependents;     /* FIFO of dependent objects */
        struct list_head        dep_link;       /* link in parent's dependents list */
        struct list_head        pending_ops;    /* unstarted operations on this object */
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+       struct rb_node          objlist_link;   /* link in global object list */
+#endif
        pgoff_t                 store_limit;    /* current storage limit */
 };
 
@@ -422,6 +442,12 @@ void fscache_object_init(struct fscache_object *object,
 extern void fscache_object_lookup_negative(struct fscache_object *object);
 extern void fscache_obtained_object(struct fscache_object *object);
 
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+extern void fscache_object_destroy(struct fscache_object *object);
+#else
+#define fscache_object_destroy(object) do {} while(0)
+#endif
+
 /**
  * fscache_object_destroyed - Note destruction of an object in a cache
  * @cache: The cache from which the object came