Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
422 giacomo 1
/*
2
 * linux/include/linux/nfs_page.h
3
 *
4
 * Copyright (C) 2000 Trond Myklebust
5
 *
6
 * NFS page cache wrapper.
7
 */
8
 
9
#ifndef _LINUX_NFS_PAGE_H
10
#define _LINUX_NFS_PAGE_H
11
 
12
 
13
#include <linux/list.h>
14
#include <linux/pagemap.h>
15
#include <linux/wait.h>
16
#include <linux/nfs_fs_sb.h>
17
#include <linux/sunrpc/auth.h>
18
#include <linux/nfs_xdr.h>
19
 
20
/*
21
 * Valid flags for a dirty buffer
22
 */
23
#define PG_BUSY                 0
24
 
25
struct nfs_page {
26
        struct list_head        wb_list,        /* Defines state of page: */
27
                                *wb_list_head;  /*      read/write/commit */
28
        struct file             *wb_file;
29
        struct inode            *wb_inode;
30
        struct rpc_cred         *wb_cred;
31
        struct nfs4_state       *wb_state;
32
        struct page             *wb_page;       /* page to read in/write out */
33
        wait_queue_head_t       wb_wait;        /* wait queue */
34
        unsigned long           wb_index;       /* Offset >> PAGE_CACHE_SHIFT */
35
        unsigned int            wb_offset,      /* Offset & ~PAGE_CACHE_MASK */
36
                                wb_pgbase,      /* Start of page data */
37
                                wb_bytes,       /* Length of request */
38
                                wb_count;       /* reference count */
39
        unsigned long           wb_flags;
40
        struct nfs_writeverf    wb_verf;        /* Commit cookie */
41
};
42
 
43
#define NFS_WBACK_BUSY(req)     (test_bit(PG_BUSY,&(req)->wb_flags))
44
 
45
extern  struct nfs_page *nfs_create_request(struct file *, struct inode *,
46
                                            struct page *,
47
                                            unsigned int, unsigned int);
48
extern  void nfs_clear_request(struct nfs_page *req);
49
extern  void nfs_release_request(struct nfs_page *req);
50
 
51
 
52
extern  void nfs_list_add_request(struct nfs_page *, struct list_head *);
53
 
54
extern  int nfs_scan_list(struct list_head *, struct list_head *,
55
                          struct file *, unsigned long, unsigned int);
56
extern  int nfs_coalesce_requests(struct list_head *, struct list_head *,
57
                                  unsigned int);
58
extern  int nfs_wait_on_request(struct nfs_page *);
59
 
60
extern  spinlock_t nfs_wreq_lock;
61
 
62
/*
63
 * Lock the page of an asynchronous request without incrementing the wb_count
64
 */
65
static inline int
66
nfs_lock_request_dontget(struct nfs_page *req)
67
{
68
        if (test_and_set_bit(PG_BUSY, &req->wb_flags))
69
                return 0;
70
        return 1;
71
}
72
 
73
/*
74
 * Lock the page of an asynchronous request
75
 */
76
static inline int
77
nfs_lock_request(struct nfs_page *req)
78
{
79
        if (test_and_set_bit(PG_BUSY, &req->wb_flags))
80
                return 0;
81
        req->wb_count++;
82
        return 1;
83
}
84
 
85
static inline void
86
nfs_unlock_request(struct nfs_page *req)
87
{
88
        if (!NFS_WBACK_BUSY(req)) {
89
                printk(KERN_ERR "NFS: Invalid unlock attempted\n");
90
                BUG();
91
        }
92
        smp_mb__before_clear_bit();
93
        clear_bit(PG_BUSY, &req->wb_flags);
94
        smp_mb__after_clear_bit();
95
        if (waitqueue_active(&req->wb_wait))
96
                wake_up_all(&req->wb_wait);
97
        nfs_release_request(req);
98
}
99
 
100
/**
101
 * nfs_list_remove_request - Remove a request from its wb_list
102
 * @req: request
103
 */
104
static inline void
105
nfs_list_remove_request(struct nfs_page *req)
106
{
107
        if (list_empty(&req->wb_list))
108
                return;
109
        if (!NFS_WBACK_BUSY(req)) {
110
                printk(KERN_ERR "NFS: unlocked request attempted removed from list!\n");
111
                BUG();
112
        }
113
        list_del_init(&req->wb_list);
114
        req->wb_list_head = NULL;
115
}
116
 
117
static inline struct nfs_page *
118
nfs_list_entry(struct list_head *head)
119
{
120
        return list_entry(head, struct nfs_page, wb_list);
121
}
122
 
123
static inline
124
loff_t req_offset(struct nfs_page *req)
125
{
126
        return (((loff_t)req->wb_index) << PAGE_CACHE_SHIFT) + req->wb_offset;
127
}
128
 
129
#endif /* _LINUX_NFS_PAGE_H */