aboutsummaryrefslogtreecommitdiffstats
path: root/mm/filemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/filemap.c')
-rw-r--r--mm/filemap.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index 93595c327bbd..d5fdae2eb183 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -123,8 +123,7 @@ void remove_from_page_cache(struct page *page)
123{ 123{
124 struct address_space *mapping = page->mapping; 124 struct address_space *mapping = page->mapping;
125 125
126 if (unlikely(!PageLocked(page))) 126 BUG_ON(!PageLocked(page));
127 PAGE_BUG(page);
128 127
129 write_lock_irq(&mapping->tree_lock); 128 write_lock_irq(&mapping->tree_lock);
130 __remove_from_page_cache(page); 129 __remove_from_page_cache(page);
@@ -139,7 +138,25 @@ static int sync_page(void *word)
139 page = container_of((page_flags_t *)word, struct page, flags); 138 page = container_of((page_flags_t *)word, struct page, flags);
140 139
141 /* 140 /*
142 * FIXME, fercrissake. What is this barrier here for? 141 * page_mapping() is being called without PG_locked held.
142 * Some knowledge of the state and use of the page is used to
143 * reduce the requirements down to a memory barrier.
144 * The danger here is of a stale page_mapping() return value
145 * indicating a struct address_space different from the one it's
146 * associated with when it is associated with one.
147 * After smp_mb(), it's either the correct page_mapping() for
148 * the page, or an old page_mapping() and the page's own
149 * page_mapping() has gone NULL.
150 * The ->sync_page() address_space operation must tolerate
151 * page_mapping() going NULL. By an amazing coincidence,
152 * this comes about because none of the users of the page
153 * in the ->sync_page() methods make essential use of the
154 * page_mapping(), merely passing the page down to the backing
155 * device's unplug functions when it's non-NULL, which in turn
156 * ignore it for all cases but swap, where only page->private is
157 * of interest. When page_mapping() does go NULL, the entire
158 * call stack gracefully ignores the page and returns.
159 * -- wli
143 */ 160 */
144 smp_mb(); 161 smp_mb();
145 mapping = page_mapping(page); 162 mapping = page_mapping(page);
@@ -152,9 +169,10 @@ static int sync_page(void *word)
152/** 169/**
153 * filemap_fdatawrite_range - start writeback against all of a mapping's 170 * filemap_fdatawrite_range - start writeback against all of a mapping's
154 * dirty pages that lie within the byte offsets <start, end> 171 * dirty pages that lie within the byte offsets <start, end>
155 * @mapping: address space structure to write 172 * @mapping: address space structure to write
156 * @start: offset in bytes where the range starts 173 * @start: offset in bytes where the range starts
157 * @end : offset in bytes where the range ends 174 * @end: offset in bytes where the range ends
175 * @sync_mode: enable synchronous operation
158 * 176 *
159 * If sync_mode is WB_SYNC_ALL then this is a "data integrity" operation, as 177 * If sync_mode is WB_SYNC_ALL then this is a "data integrity" operation, as
160 * opposed to a regular memory * cleansing writeback. The difference between 178 * opposed to a regular memory * cleansing writeback. The difference between
@@ -518,8 +536,8 @@ EXPORT_SYMBOL(find_trylock_page);
518/** 536/**
519 * find_lock_page - locate, pin and lock a pagecache page 537 * find_lock_page - locate, pin and lock a pagecache page
520 * 538 *
521 * @mapping - the address_space to search 539 * @mapping: the address_space to search
522 * @offset - the page index 540 * @offset: the page index
523 * 541 *
524 * Locates the desired pagecache page, locks it, increments its reference 542 * Locates the desired pagecache page, locks it, increments its reference
525 * count and returns its address. 543 * count and returns its address.
@@ -558,9 +576,9 @@ EXPORT_SYMBOL(find_lock_page);
558/** 576/**
559 * find_or_create_page - locate or add a pagecache page 577 * find_or_create_page - locate or add a pagecache page
560 * 578 *
561 * @mapping - the page's address_space 579 * @mapping: the page's address_space
562 * @index - the page's index into the mapping 580 * @index: the page's index into the mapping
563 * @gfp_mask - page allocation mode 581 * @gfp_mask: page allocation mode
564 * 582 *
565 * Locates a page in the pagecache. If the page is not present, a new page 583 * Locates a page in the pagecache. If the page is not present, a new page
566 * is allocated using @gfp_mask and is added to the pagecache and to the VM's 584 * is allocated using @gfp_mask and is added to the pagecache and to the VM's
@@ -1949,7 +1967,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
1949 buf = iov->iov_base + written; 1967 buf = iov->iov_base + written;
1950 else { 1968 else {
1951 filemap_set_next_iovec(&cur_iov, &iov_base, written); 1969 filemap_set_next_iovec(&cur_iov, &iov_base, written);
1952 buf = iov->iov_base + iov_base; 1970 buf = cur_iov->iov_base + iov_base;
1953 } 1971 }
1954 1972
1955 do { 1973 do {
@@ -2007,9 +2025,11 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
2007 count -= status; 2025 count -= status;
2008 pos += status; 2026 pos += status;
2009 buf += status; 2027 buf += status;
2010 if (unlikely(nr_segs > 1)) 2028 if (unlikely(nr_segs > 1)) {
2011 filemap_set_next_iovec(&cur_iov, 2029 filemap_set_next_iovec(&cur_iov,
2012 &iov_base, status); 2030 &iov_base, status);
2031 buf = cur_iov->iov_base + iov_base;
2032 }
2013 } 2033 }
2014 } 2034 }
2015 if (unlikely(copied != bytes)) 2035 if (unlikely(copied != bytes))
cgi/litmus-rt-budgetable-locks.git/.git/commit/include/linux/elevator.h?h=update_litmus_2019&id=796d5116c407690b14fd5bda136aa67a39e7061a'>796d5116c407
2e662b65f05d



1da177e4c3f4











797e7dbbee0a
ae1b1539622f
5e84ea3a9c66
1da177e4c3f4









2e46e8b27aa5
2e662b65f05d
1b47f531e244
1fbfdfcddff4
c7c22e4d5c1f
1fbfdfcddff4

c7c22e4d5c1f

1fbfdfcddff4


c7c22e4d5c1f
1fbfdfcddff4

9361401eb761
1da177e4c3f4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210


                         

                         

                   

             
                                                                           

                                               
                                                                                                  
 
                                                                                  
 
                                                                                               
 


                                                                                
                                                                 
 
                                                                              


                                                                                              
 
                                                     
                                                     

                                                                            
                                                      

                                                                                     
 
                                                        
                                                          





                                                     
                                                         
                                                       
 
                                                   
                                                 
                                                           

                                                               




                                                             

                                                                             
 










                                                     

                              

                                                                        

  




                                                      



                                                        
                                

                                                     
                                            

                                         


                                                                        
                              


  
                                                      


                     
                                   

                            
                                
                                
                                  




                           

                                                                            

                                                                             

                                                                              
                                                 
                                                                              

                                                                     
                                                                          




                                                                                    
                                                    
                                                                            

                                                                       
                                                                      
                                                       



                            
                                                




                                                   

                                                                               
 
                                                         
                                                   
                                                                 
                                                            

  

                    

                                                                                       



                        
                                                           



                                                               











                                     
                                 
                                 
                                         









                                           
                                                                     
                                                                         
 
  
                                                                     

                                                                    

                                                                              


                                                                            
                                                 

                   
                         
      
#ifndef _LINUX_ELEVATOR_H
#define _LINUX_ELEVATOR_H

#include <linux/percpu.h>

#ifdef CONFIG_BLOCK

struct io_cq;

typedef int (elevator_merge_fn) (struct request_queue *, struct request **,
				 struct bio *);

typedef void (elevator_merge_req_fn) (struct request_queue *, struct request *, struct request *);

typedef void (elevator_merged_fn) (struct request_queue *, struct request *, int);

typedef int (elevator_allow_merge_fn) (struct request_queue *, struct request *, struct bio *);

typedef void (elevator_bio_merged_fn) (struct request_queue *,
						struct request *, struct bio *);

typedef int (elevator_dispatch_fn) (struct request_queue *, int);

typedef void (elevator_add_req_fn) (struct request_queue *, struct request *);
typedef struct request *(elevator_request_list_fn) (struct request_queue *, struct request *);
typedef void (elevator_completed_req_fn) (struct request_queue *, struct request *);
typedef int (elevator_may_queue_fn) (struct request_queue *, int);

typedef void (elevator_init_icq_fn) (struct io_cq *);
typedef void (elevator_exit_icq_fn) (struct io_cq *);
typedef int (elevator_set_req_fn) (struct request_queue *, struct request *,
				   struct bio *, gfp_t);
typedef void (elevator_put_req_fn) (struct request *);
typedef void (elevator_activate_req_fn) (struct request_queue *, struct request *);
typedef void (elevator_deactivate_req_fn) (struct request_queue *, struct request *);

typedef int (elevator_init_fn) (struct request_queue *);
typedef void (elevator_exit_fn) (struct elevator_queue *);

struct elevator_ops
{
	elevator_merge_fn *elevator_merge_fn;
	elevator_merged_fn *elevator_merged_fn;
	elevator_merge_req_fn *elevator_merge_req_fn;
	elevator_allow_merge_fn *elevator_allow_merge_fn;
	elevator_bio_merged_fn *elevator_bio_merged_fn;

	elevator_dispatch_fn *elevator_dispatch_fn;
	elevator_add_req_fn *elevator_add_req_fn;
	elevator_activate_req_fn *elevator_activate_req_fn;
	elevator_deactivate_req_fn *elevator_deactivate_req_fn;

	elevator_completed_req_fn *elevator_completed_req_fn;

	elevator_request_list_fn *elevator_former_req_fn;
	elevator_request_list_fn *elevator_latter_req_fn;

	elevator_init_icq_fn *elevator_init_icq_fn;	/* see iocontext.h */
	elevator_exit_icq_fn *elevator_exit_icq_fn;	/* ditto */

	elevator_set_req_fn *elevator_set_req_fn;
	elevator_put_req_fn *elevator_put_req_fn;

	elevator_may_queue_fn *elevator_may_queue_fn;

	elevator_init_fn *elevator_init_fn;
	elevator_exit_fn *elevator_exit_fn;
};

#define ELV_NAME_MAX	(16)

struct elv_fs_entry {
	struct attribute attr;
	ssize_t (*show)(struct elevator_queue *, char *);
	ssize_t (*store)(struct elevator_queue *, const char *, size_t);
};

/*
 * identifies an elevator type, such as AS or deadline
 */
struct elevator_type
{
	/* managed by elevator core */
	struct kmem_cache *icq_cache;

	/* fields provided by elevator implementation */
	struct elevator_ops ops;
	size_t icq_size;	/* see iocontext.h */
	size_t icq_align;	/* ditto */
	struct elv_fs_entry *elevator_attrs;
	char elevator_name[ELV_NAME_MAX];
	struct module *elevator_owner;

	/* managed by elevator core */
	char icq_cache_name[ELV_NAME_MAX + 5];	/* elvname + "_io_cq" */
	struct list_head list;
};

/*
 * each queue has an elevator_queue associated with it
 */
struct elevator_queue
{
	struct elevator_type *type;
	void *elevator_data;
	struct kobject kobj;
	struct mutex sysfs_lock;
	struct hlist_head *hash;
	unsigned int registered:1;
};

/*
 * block elevator interface
 */
extern void elv_dispatch_sort(struct request_queue *, struct request *);
extern void elv_dispatch_add_tail(struct request_queue *, struct request *);
extern void elv_add_request(struct request_queue *, struct request *, int);
extern void __elv_add_request(struct request_queue *, struct request *, int);
extern int elv_merge(struct request_queue *, struct request **, struct bio *);
extern void elv_merge_requests(struct request_queue *, struct request *,
			       struct request *);
extern void elv_merged_request(struct request_queue *, struct request *, int);
extern void elv_bio_merged(struct request_queue *q, struct request *,
				struct bio *);
extern void elv_requeue_request(struct request_queue *, struct request *);
extern struct request *elv_former_request(struct request_queue *, struct request *);
extern struct request *elv_latter_request(struct request_queue *, struct request *);
extern int elv_register_queue(struct request_queue *q);
extern void elv_unregister_queue(struct request_queue *q);
extern int elv_may_queue(struct request_queue *, int);
extern void elv_abort_queue(struct request_queue *);
extern void elv_completed_request(struct request_queue *, struct request *);
extern int elv_set_request(struct request_queue *q, struct request *rq,
			   struct bio *bio, gfp_t gfp_mask);
extern void elv_put_request(struct request_queue *, struct request *);
extern void elv_drain_elevator(struct request_queue *);

/*
 * io scheduler registration
 */
extern int elv_register(struct elevator_type *);
extern void elv_unregister(struct elevator_type *);

/*
 * io scheduler sysfs switching
 */
extern ssize_t elv_iosched_show(struct request_queue *, char *);
extern ssize_t elv_iosched_store(struct request_queue *, const char *, size_t);

extern int elevator_init(struct request_queue *, char *);
extern void elevator_exit(struct elevator_queue *);
extern int elevator_change(struct request_queue *, const char *);
extern bool elv_rq_merge_ok(struct request *, struct bio *);

/*
 * Helper functions.
 */