Commit c9f6a6bbc284ba87337876086f7e2e6e0b0d50dd
1 parent
9cabcdbd46
Exists in
master
and in
20 other branches
[GFS2] Remove support for unused and pointless flag
The ability to mark files for direct i/o access when opened normally is both unused and pointless, so this patch removes support for that feature. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Showing 5 changed files with 2 additions and 26 deletions Inline Diff
fs/gfs2/incore.h
1 | /* | 1 | /* |
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. | 3 | * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This copyrighted material is made available to anyone wishing to use, | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | * modify, copy, or redistribute it subject to the terms and conditions | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
7 | * of the GNU General Public License version 2. | 7 | * of the GNU General Public License version 2. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #ifndef __INCORE_DOT_H__ | 10 | #ifndef __INCORE_DOT_H__ |
11 | #define __INCORE_DOT_H__ | 11 | #define __INCORE_DOT_H__ |
12 | 12 | ||
13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
14 | #include <linux/workqueue.h> | 14 | #include <linux/workqueue.h> |
15 | 15 | ||
16 | #define DIO_WAIT 0x00000010 | 16 | #define DIO_WAIT 0x00000010 |
17 | #define DIO_METADATA 0x00000020 | 17 | #define DIO_METADATA 0x00000020 |
18 | #define DIO_ALL 0x00000100 | 18 | #define DIO_ALL 0x00000100 |
19 | 19 | ||
20 | struct gfs2_log_operations; | 20 | struct gfs2_log_operations; |
21 | struct gfs2_log_element; | 21 | struct gfs2_log_element; |
22 | struct gfs2_holder; | 22 | struct gfs2_holder; |
23 | struct gfs2_glock; | 23 | struct gfs2_glock; |
24 | struct gfs2_quota_data; | 24 | struct gfs2_quota_data; |
25 | struct gfs2_trans; | 25 | struct gfs2_trans; |
26 | struct gfs2_ail; | 26 | struct gfs2_ail; |
27 | struct gfs2_jdesc; | 27 | struct gfs2_jdesc; |
28 | struct gfs2_sbd; | 28 | struct gfs2_sbd; |
29 | 29 | ||
30 | typedef void (*gfs2_glop_bh_t) (struct gfs2_glock *gl, unsigned int ret); | 30 | typedef void (*gfs2_glop_bh_t) (struct gfs2_glock *gl, unsigned int ret); |
31 | 31 | ||
32 | struct gfs2_log_header_host { | 32 | struct gfs2_log_header_host { |
33 | u64 lh_sequence; /* Sequence number of this transaction */ | 33 | u64 lh_sequence; /* Sequence number of this transaction */ |
34 | u32 lh_flags; /* GFS2_LOG_HEAD_... */ | 34 | u32 lh_flags; /* GFS2_LOG_HEAD_... */ |
35 | u32 lh_tail; /* Block number of log tail */ | 35 | u32 lh_tail; /* Block number of log tail */ |
36 | u32 lh_blkno; | 36 | u32 lh_blkno; |
37 | u32 lh_hash; | 37 | u32 lh_hash; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * Structure of operations that are associated with each | 41 | * Structure of operations that are associated with each |
42 | * type of element in the log. | 42 | * type of element in the log. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | struct gfs2_log_operations { | 45 | struct gfs2_log_operations { |
46 | void (*lo_add) (struct gfs2_sbd *sdp, struct gfs2_log_element *le); | 46 | void (*lo_add) (struct gfs2_sbd *sdp, struct gfs2_log_element *le); |
47 | void (*lo_before_commit) (struct gfs2_sbd *sdp); | 47 | void (*lo_before_commit) (struct gfs2_sbd *sdp); |
48 | void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_ail *ai); | 48 | void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_ail *ai); |
49 | void (*lo_before_scan) (struct gfs2_jdesc *jd, | 49 | void (*lo_before_scan) (struct gfs2_jdesc *jd, |
50 | struct gfs2_log_header_host *head, int pass); | 50 | struct gfs2_log_header_host *head, int pass); |
51 | int (*lo_scan_elements) (struct gfs2_jdesc *jd, unsigned int start, | 51 | int (*lo_scan_elements) (struct gfs2_jdesc *jd, unsigned int start, |
52 | struct gfs2_log_descriptor *ld, __be64 *ptr, | 52 | struct gfs2_log_descriptor *ld, __be64 *ptr, |
53 | int pass); | 53 | int pass); |
54 | void (*lo_after_scan) (struct gfs2_jdesc *jd, int error, int pass); | 54 | void (*lo_after_scan) (struct gfs2_jdesc *jd, int error, int pass); |
55 | const char *lo_name; | 55 | const char *lo_name; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | struct gfs2_log_element { | 58 | struct gfs2_log_element { |
59 | struct list_head le_list; | 59 | struct list_head le_list; |
60 | const struct gfs2_log_operations *le_ops; | 60 | const struct gfs2_log_operations *le_ops; |
61 | }; | 61 | }; |
62 | 62 | ||
63 | struct gfs2_bitmap { | 63 | struct gfs2_bitmap { |
64 | struct buffer_head *bi_bh; | 64 | struct buffer_head *bi_bh; |
65 | char *bi_clone; | 65 | char *bi_clone; |
66 | u32 bi_offset; | 66 | u32 bi_offset; |
67 | u32 bi_start; | 67 | u32 bi_start; |
68 | u32 bi_len; | 68 | u32 bi_len; |
69 | }; | 69 | }; |
70 | 70 | ||
71 | struct gfs2_rgrp_host { | 71 | struct gfs2_rgrp_host { |
72 | u32 rg_free; | 72 | u32 rg_free; |
73 | u32 rg_dinodes; | 73 | u32 rg_dinodes; |
74 | u64 rg_igeneration; | 74 | u64 rg_igeneration; |
75 | }; | 75 | }; |
76 | 76 | ||
77 | struct gfs2_rgrpd { | 77 | struct gfs2_rgrpd { |
78 | struct list_head rd_list; /* Link with superblock */ | 78 | struct list_head rd_list; /* Link with superblock */ |
79 | struct list_head rd_list_mru; | 79 | struct list_head rd_list_mru; |
80 | struct gfs2_glock *rd_gl; /* Glock for this rgrp */ | 80 | struct gfs2_glock *rd_gl; /* Glock for this rgrp */ |
81 | u64 rd_addr; /* grp block disk address */ | 81 | u64 rd_addr; /* grp block disk address */ |
82 | u64 rd_data0; /* first data location */ | 82 | u64 rd_data0; /* first data location */ |
83 | u32 rd_length; /* length of rgrp header in fs blocks */ | 83 | u32 rd_length; /* length of rgrp header in fs blocks */ |
84 | u32 rd_data; /* num of data blocks in rgrp */ | 84 | u32 rd_data; /* num of data blocks in rgrp */ |
85 | u32 rd_bitbytes; /* number of bytes in data bitmaps */ | 85 | u32 rd_bitbytes; /* number of bytes in data bitmaps */ |
86 | struct gfs2_rgrp_host rd_rg; | 86 | struct gfs2_rgrp_host rd_rg; |
87 | struct gfs2_bitmap *rd_bits; | 87 | struct gfs2_bitmap *rd_bits; |
88 | unsigned int rd_bh_count; | 88 | unsigned int rd_bh_count; |
89 | struct mutex rd_mutex; | 89 | struct mutex rd_mutex; |
90 | u32 rd_free_clone; | 90 | u32 rd_free_clone; |
91 | struct gfs2_log_element rd_le; | 91 | struct gfs2_log_element rd_le; |
92 | u32 rd_last_alloc; | 92 | u32 rd_last_alloc; |
93 | struct gfs2_sbd *rd_sbd; | 93 | struct gfs2_sbd *rd_sbd; |
94 | unsigned char rd_flags; | 94 | unsigned char rd_flags; |
95 | #define GFS2_RDF_CHECK 0x01 /* Need to check for unlinked inodes */ | 95 | #define GFS2_RDF_CHECK 0x01 /* Need to check for unlinked inodes */ |
96 | #define GFS2_RDF_NOALLOC 0x02 /* rg prohibits allocation */ | 96 | #define GFS2_RDF_NOALLOC 0x02 /* rg prohibits allocation */ |
97 | #define GFS2_RDF_UPTODATE 0x04 /* rg is up to date */ | 97 | #define GFS2_RDF_UPTODATE 0x04 /* rg is up to date */ |
98 | }; | 98 | }; |
99 | 99 | ||
100 | enum gfs2_state_bits { | 100 | enum gfs2_state_bits { |
101 | BH_Pinned = BH_PrivateStart, | 101 | BH_Pinned = BH_PrivateStart, |
102 | BH_Escaped = BH_PrivateStart + 1, | 102 | BH_Escaped = BH_PrivateStart + 1, |
103 | }; | 103 | }; |
104 | 104 | ||
105 | BUFFER_FNS(Pinned, pinned) | 105 | BUFFER_FNS(Pinned, pinned) |
106 | TAS_BUFFER_FNS(Pinned, pinned) | 106 | TAS_BUFFER_FNS(Pinned, pinned) |
107 | BUFFER_FNS(Escaped, escaped) | 107 | BUFFER_FNS(Escaped, escaped) |
108 | TAS_BUFFER_FNS(Escaped, escaped) | 108 | TAS_BUFFER_FNS(Escaped, escaped) |
109 | 109 | ||
110 | struct gfs2_bufdata { | 110 | struct gfs2_bufdata { |
111 | struct buffer_head *bd_bh; | 111 | struct buffer_head *bd_bh; |
112 | struct gfs2_glock *bd_gl; | 112 | struct gfs2_glock *bd_gl; |
113 | 113 | ||
114 | union { | 114 | union { |
115 | struct list_head list_tr; | 115 | struct list_head list_tr; |
116 | u64 blkno; | 116 | u64 blkno; |
117 | } u; | 117 | } u; |
118 | #define bd_list_tr u.list_tr | 118 | #define bd_list_tr u.list_tr |
119 | #define bd_blkno u.blkno | 119 | #define bd_blkno u.blkno |
120 | 120 | ||
121 | struct gfs2_log_element bd_le; | 121 | struct gfs2_log_element bd_le; |
122 | 122 | ||
123 | struct gfs2_ail *bd_ail; | 123 | struct gfs2_ail *bd_ail; |
124 | struct list_head bd_ail_st_list; | 124 | struct list_head bd_ail_st_list; |
125 | struct list_head bd_ail_gl_list; | 125 | struct list_head bd_ail_gl_list; |
126 | }; | 126 | }; |
127 | 127 | ||
128 | struct gfs2_glock_operations { | 128 | struct gfs2_glock_operations { |
129 | void (*go_xmote_th) (struct gfs2_glock *gl); | 129 | void (*go_xmote_th) (struct gfs2_glock *gl); |
130 | int (*go_xmote_bh) (struct gfs2_glock *gl, struct gfs2_holder *gh); | 130 | int (*go_xmote_bh) (struct gfs2_glock *gl, struct gfs2_holder *gh); |
131 | void (*go_inval) (struct gfs2_glock *gl, int flags); | 131 | void (*go_inval) (struct gfs2_glock *gl, int flags); |
132 | int (*go_demote_ok) (struct gfs2_glock *gl); | 132 | int (*go_demote_ok) (struct gfs2_glock *gl); |
133 | int (*go_lock) (struct gfs2_holder *gh); | 133 | int (*go_lock) (struct gfs2_holder *gh); |
134 | void (*go_unlock) (struct gfs2_holder *gh); | 134 | void (*go_unlock) (struct gfs2_holder *gh); |
135 | int (*go_dump)(struct seq_file *seq, const struct gfs2_glock *gl); | 135 | int (*go_dump)(struct seq_file *seq, const struct gfs2_glock *gl); |
136 | const int go_type; | 136 | const int go_type; |
137 | const unsigned long go_min_hold_time; | 137 | const unsigned long go_min_hold_time; |
138 | }; | 138 | }; |
139 | 139 | ||
140 | enum { | 140 | enum { |
141 | /* States */ | 141 | /* States */ |
142 | HIF_HOLDER = 6, /* Set for gh that "holds" the glock */ | 142 | HIF_HOLDER = 6, /* Set for gh that "holds" the glock */ |
143 | HIF_FIRST = 7, | 143 | HIF_FIRST = 7, |
144 | HIF_WAIT = 10, | 144 | HIF_WAIT = 10, |
145 | }; | 145 | }; |
146 | 146 | ||
147 | struct gfs2_holder { | 147 | struct gfs2_holder { |
148 | struct list_head gh_list; | 148 | struct list_head gh_list; |
149 | 149 | ||
150 | struct gfs2_glock *gh_gl; | 150 | struct gfs2_glock *gh_gl; |
151 | struct pid *gh_owner_pid; | 151 | struct pid *gh_owner_pid; |
152 | unsigned int gh_state; | 152 | unsigned int gh_state; |
153 | unsigned gh_flags; | 153 | unsigned gh_flags; |
154 | 154 | ||
155 | int gh_error; | 155 | int gh_error; |
156 | unsigned long gh_iflags; /* HIF_... */ | 156 | unsigned long gh_iflags; /* HIF_... */ |
157 | unsigned long gh_ip; | 157 | unsigned long gh_ip; |
158 | }; | 158 | }; |
159 | 159 | ||
160 | enum { | 160 | enum { |
161 | GLF_LOCK = 1, | 161 | GLF_LOCK = 1, |
162 | GLF_STICKY = 2, | 162 | GLF_STICKY = 2, |
163 | GLF_DEMOTE = 3, | 163 | GLF_DEMOTE = 3, |
164 | GLF_PENDING_DEMOTE = 4, | 164 | GLF_PENDING_DEMOTE = 4, |
165 | GLF_DEMOTE_IN_PROGRESS = 5, | 165 | GLF_DEMOTE_IN_PROGRESS = 5, |
166 | GLF_DIRTY = 6, | 166 | GLF_DIRTY = 6, |
167 | GLF_LFLUSH = 7, | 167 | GLF_LFLUSH = 7, |
168 | GLF_INVALIDATE_IN_PROGRESS = 8, | 168 | GLF_INVALIDATE_IN_PROGRESS = 8, |
169 | GLF_REPLY_PENDING = 9, | 169 | GLF_REPLY_PENDING = 9, |
170 | }; | 170 | }; |
171 | 171 | ||
172 | struct gfs2_glock { | 172 | struct gfs2_glock { |
173 | struct hlist_node gl_list; | 173 | struct hlist_node gl_list; |
174 | unsigned long gl_flags; /* GLF_... */ | 174 | unsigned long gl_flags; /* GLF_... */ |
175 | struct lm_lockname gl_name; | 175 | struct lm_lockname gl_name; |
176 | atomic_t gl_ref; | 176 | atomic_t gl_ref; |
177 | 177 | ||
178 | spinlock_t gl_spin; | 178 | spinlock_t gl_spin; |
179 | 179 | ||
180 | unsigned int gl_state; | 180 | unsigned int gl_state; |
181 | unsigned int gl_target; | 181 | unsigned int gl_target; |
182 | unsigned int gl_reply; | 182 | unsigned int gl_reply; |
183 | unsigned int gl_hash; | 183 | unsigned int gl_hash; |
184 | unsigned int gl_demote_state; /* state requested by remote node */ | 184 | unsigned int gl_demote_state; /* state requested by remote node */ |
185 | unsigned long gl_demote_time; /* time of first demote request */ | 185 | unsigned long gl_demote_time; /* time of first demote request */ |
186 | struct list_head gl_holders; | 186 | struct list_head gl_holders; |
187 | 187 | ||
188 | const struct gfs2_glock_operations *gl_ops; | 188 | const struct gfs2_glock_operations *gl_ops; |
189 | void *gl_lock; | 189 | void *gl_lock; |
190 | char *gl_lvb; | 190 | char *gl_lvb; |
191 | atomic_t gl_lvb_count; | 191 | atomic_t gl_lvb_count; |
192 | 192 | ||
193 | unsigned long gl_stamp; | 193 | unsigned long gl_stamp; |
194 | unsigned long gl_tchange; | 194 | unsigned long gl_tchange; |
195 | void *gl_object; | 195 | void *gl_object; |
196 | 196 | ||
197 | struct list_head gl_reclaim; | 197 | struct list_head gl_reclaim; |
198 | 198 | ||
199 | struct gfs2_sbd *gl_sbd; | 199 | struct gfs2_sbd *gl_sbd; |
200 | 200 | ||
201 | struct inode *gl_aspace; | 201 | struct inode *gl_aspace; |
202 | struct list_head gl_ail_list; | 202 | struct list_head gl_ail_list; |
203 | atomic_t gl_ail_count; | 203 | atomic_t gl_ail_count; |
204 | struct delayed_work gl_work; | 204 | struct delayed_work gl_work; |
205 | }; | 205 | }; |
206 | 206 | ||
207 | #define GFS2_MIN_LVB_SIZE 32 /* Min size of LVB that gfs2 supports */ | 207 | #define GFS2_MIN_LVB_SIZE 32 /* Min size of LVB that gfs2 supports */ |
208 | 208 | ||
209 | struct gfs2_alloc { | 209 | struct gfs2_alloc { |
210 | /* Quota stuff */ | 210 | /* Quota stuff */ |
211 | 211 | ||
212 | struct gfs2_quota_data *al_qd[2*MAXQUOTAS]; | 212 | struct gfs2_quota_data *al_qd[2*MAXQUOTAS]; |
213 | struct gfs2_holder al_qd_ghs[2*MAXQUOTAS]; | 213 | struct gfs2_holder al_qd_ghs[2*MAXQUOTAS]; |
214 | unsigned int al_qd_num; | 214 | unsigned int al_qd_num; |
215 | 215 | ||
216 | u32 al_requested; /* Filled in by caller of gfs2_inplace_reserve() */ | 216 | u32 al_requested; /* Filled in by caller of gfs2_inplace_reserve() */ |
217 | u32 al_alloced; /* Filled in by gfs2_alloc_*() */ | 217 | u32 al_alloced; /* Filled in by gfs2_alloc_*() */ |
218 | 218 | ||
219 | /* Filled in by gfs2_inplace_reserve() */ | 219 | /* Filled in by gfs2_inplace_reserve() */ |
220 | 220 | ||
221 | unsigned int al_line; | 221 | unsigned int al_line; |
222 | char *al_file; | 222 | char *al_file; |
223 | struct gfs2_holder al_ri_gh; | 223 | struct gfs2_holder al_ri_gh; |
224 | struct gfs2_holder al_rgd_gh; | 224 | struct gfs2_holder al_rgd_gh; |
225 | struct gfs2_rgrpd *al_rgd; | 225 | struct gfs2_rgrpd *al_rgd; |
226 | 226 | ||
227 | }; | 227 | }; |
228 | 228 | ||
229 | enum { | 229 | enum { |
230 | GIF_INVALID = 0, | 230 | GIF_INVALID = 0, |
231 | GIF_QD_LOCKED = 1, | 231 | GIF_QD_LOCKED = 1, |
232 | GIF_SW_PAGED = 3, | 232 | GIF_SW_PAGED = 3, |
233 | GIF_USER = 4, /* user inode, not metadata addr space */ | 233 | GIF_USER = 4, /* user inode, not metadata addr space */ |
234 | }; | 234 | }; |
235 | 235 | ||
236 | struct gfs2_dinode_host { | 236 | struct gfs2_dinode_host { |
237 | u64 di_size; /* number of bytes in file */ | 237 | u64 di_size; /* number of bytes in file */ |
238 | u64 di_generation; /* generation number for NFS */ | 238 | u64 di_generation; /* generation number for NFS */ |
239 | u32 di_flags; /* GFS2_DIF_... */ | 239 | u32 di_flags; /* GFS2_DIF_... */ |
240 | /* These only apply to directories */ | 240 | /* These only apply to directories */ |
241 | u32 di_entries; /* The number of entries in the directory */ | 241 | u32 di_entries; /* The number of entries in the directory */ |
242 | u64 di_eattr; /* extended attribute block number */ | 242 | u64 di_eattr; /* extended attribute block number */ |
243 | }; | 243 | }; |
244 | 244 | ||
245 | struct gfs2_inode { | 245 | struct gfs2_inode { |
246 | struct inode i_inode; | 246 | struct inode i_inode; |
247 | u64 i_no_addr; | 247 | u64 i_no_addr; |
248 | u64 i_no_formal_ino; | 248 | u64 i_no_formal_ino; |
249 | unsigned long i_flags; /* GIF_... */ | 249 | unsigned long i_flags; /* GIF_... */ |
250 | 250 | ||
251 | struct gfs2_dinode_host i_di; /* To be replaced by ref to block */ | 251 | struct gfs2_dinode_host i_di; /* To be replaced by ref to block */ |
252 | 252 | ||
253 | struct gfs2_glock *i_gl; /* Move into i_gh? */ | 253 | struct gfs2_glock *i_gl; /* Move into i_gh? */ |
254 | struct gfs2_holder i_iopen_gh; | 254 | struct gfs2_holder i_iopen_gh; |
255 | struct gfs2_holder i_gh; /* for prepare/commit_write only */ | 255 | struct gfs2_holder i_gh; /* for prepare/commit_write only */ |
256 | struct gfs2_alloc *i_alloc; | 256 | struct gfs2_alloc *i_alloc; |
257 | u64 i_goal; /* goal block for allocations */ | 257 | u64 i_goal; /* goal block for allocations */ |
258 | struct rw_semaphore i_rw_mutex; | 258 | struct rw_semaphore i_rw_mutex; |
259 | u8 i_height; | 259 | u8 i_height; |
260 | u8 i_depth; | 260 | u8 i_depth; |
261 | }; | 261 | }; |
262 | 262 | ||
263 | /* | 263 | /* |
264 | * Since i_inode is the first element of struct gfs2_inode, | 264 | * Since i_inode is the first element of struct gfs2_inode, |
265 | * this is effectively a cast. | 265 | * this is effectively a cast. |
266 | */ | 266 | */ |
267 | static inline struct gfs2_inode *GFS2_I(struct inode *inode) | 267 | static inline struct gfs2_inode *GFS2_I(struct inode *inode) |
268 | { | 268 | { |
269 | return container_of(inode, struct gfs2_inode, i_inode); | 269 | return container_of(inode, struct gfs2_inode, i_inode); |
270 | } | 270 | } |
271 | 271 | ||
272 | static inline struct gfs2_sbd *GFS2_SB(const struct inode *inode) | 272 | static inline struct gfs2_sbd *GFS2_SB(const struct inode *inode) |
273 | { | 273 | { |
274 | return inode->i_sb->s_fs_info; | 274 | return inode->i_sb->s_fs_info; |
275 | } | 275 | } |
276 | 276 | ||
277 | struct gfs2_file { | 277 | struct gfs2_file { |
278 | struct mutex f_fl_mutex; | 278 | struct mutex f_fl_mutex; |
279 | struct gfs2_holder f_fl_gh; | 279 | struct gfs2_holder f_fl_gh; |
280 | }; | 280 | }; |
281 | 281 | ||
282 | struct gfs2_revoke_replay { | 282 | struct gfs2_revoke_replay { |
283 | struct list_head rr_list; | 283 | struct list_head rr_list; |
284 | u64 rr_blkno; | 284 | u64 rr_blkno; |
285 | unsigned int rr_where; | 285 | unsigned int rr_where; |
286 | }; | 286 | }; |
287 | 287 | ||
288 | enum { | 288 | enum { |
289 | QDF_USER = 0, | 289 | QDF_USER = 0, |
290 | QDF_CHANGE = 1, | 290 | QDF_CHANGE = 1, |
291 | QDF_LOCKED = 2, | 291 | QDF_LOCKED = 2, |
292 | }; | 292 | }; |
293 | 293 | ||
294 | struct gfs2_quota_data { | 294 | struct gfs2_quota_data { |
295 | struct list_head qd_list; | 295 | struct list_head qd_list; |
296 | unsigned int qd_count; | 296 | unsigned int qd_count; |
297 | 297 | ||
298 | u32 qd_id; | 298 | u32 qd_id; |
299 | unsigned long qd_flags; /* QDF_... */ | 299 | unsigned long qd_flags; /* QDF_... */ |
300 | 300 | ||
301 | s64 qd_change; | 301 | s64 qd_change; |
302 | s64 qd_change_sync; | 302 | s64 qd_change_sync; |
303 | 303 | ||
304 | unsigned int qd_slot; | 304 | unsigned int qd_slot; |
305 | unsigned int qd_slot_count; | 305 | unsigned int qd_slot_count; |
306 | 306 | ||
307 | struct buffer_head *qd_bh; | 307 | struct buffer_head *qd_bh; |
308 | struct gfs2_quota_change *qd_bh_qc; | 308 | struct gfs2_quota_change *qd_bh_qc; |
309 | unsigned int qd_bh_count; | 309 | unsigned int qd_bh_count; |
310 | 310 | ||
311 | struct gfs2_glock *qd_gl; | 311 | struct gfs2_glock *qd_gl; |
312 | struct gfs2_quota_lvb qd_qb; | 312 | struct gfs2_quota_lvb qd_qb; |
313 | 313 | ||
314 | u64 qd_sync_gen; | 314 | u64 qd_sync_gen; |
315 | unsigned long qd_last_warn; | 315 | unsigned long qd_last_warn; |
316 | unsigned long qd_last_touched; | 316 | unsigned long qd_last_touched; |
317 | }; | 317 | }; |
318 | 318 | ||
319 | struct gfs2_trans { | 319 | struct gfs2_trans { |
320 | unsigned long tr_ip; | 320 | unsigned long tr_ip; |
321 | 321 | ||
322 | unsigned int tr_blocks; | 322 | unsigned int tr_blocks; |
323 | unsigned int tr_revokes; | 323 | unsigned int tr_revokes; |
324 | unsigned int tr_reserved; | 324 | unsigned int tr_reserved; |
325 | 325 | ||
326 | struct gfs2_holder tr_t_gh; | 326 | struct gfs2_holder tr_t_gh; |
327 | 327 | ||
328 | int tr_touched; | 328 | int tr_touched; |
329 | 329 | ||
330 | unsigned int tr_num_buf; | 330 | unsigned int tr_num_buf; |
331 | unsigned int tr_num_buf_new; | 331 | unsigned int tr_num_buf_new; |
332 | unsigned int tr_num_databuf_new; | 332 | unsigned int tr_num_databuf_new; |
333 | unsigned int tr_num_buf_rm; | 333 | unsigned int tr_num_buf_rm; |
334 | unsigned int tr_num_databuf_rm; | 334 | unsigned int tr_num_databuf_rm; |
335 | struct list_head tr_list_buf; | 335 | struct list_head tr_list_buf; |
336 | 336 | ||
337 | unsigned int tr_num_revoke; | 337 | unsigned int tr_num_revoke; |
338 | unsigned int tr_num_revoke_rm; | 338 | unsigned int tr_num_revoke_rm; |
339 | }; | 339 | }; |
340 | 340 | ||
341 | struct gfs2_ail { | 341 | struct gfs2_ail { |
342 | struct list_head ai_list; | 342 | struct list_head ai_list; |
343 | 343 | ||
344 | unsigned int ai_first; | 344 | unsigned int ai_first; |
345 | struct list_head ai_ail1_list; | 345 | struct list_head ai_ail1_list; |
346 | struct list_head ai_ail2_list; | 346 | struct list_head ai_ail2_list; |
347 | 347 | ||
348 | u64 ai_sync_gen; | 348 | u64 ai_sync_gen; |
349 | }; | 349 | }; |
350 | 350 | ||
351 | struct gfs2_journal_extent { | 351 | struct gfs2_journal_extent { |
352 | struct list_head extent_list; | 352 | struct list_head extent_list; |
353 | 353 | ||
354 | unsigned int lblock; /* First logical block */ | 354 | unsigned int lblock; /* First logical block */ |
355 | u64 dblock; /* First disk block */ | 355 | u64 dblock; /* First disk block */ |
356 | u64 blocks; | 356 | u64 blocks; |
357 | }; | 357 | }; |
358 | 358 | ||
359 | struct gfs2_jdesc { | 359 | struct gfs2_jdesc { |
360 | struct list_head jd_list; | 360 | struct list_head jd_list; |
361 | struct list_head extent_list; | 361 | struct list_head extent_list; |
362 | 362 | ||
363 | struct inode *jd_inode; | 363 | struct inode *jd_inode; |
364 | unsigned int jd_jid; | 364 | unsigned int jd_jid; |
365 | int jd_dirty; | 365 | int jd_dirty; |
366 | 366 | ||
367 | unsigned int jd_blocks; | 367 | unsigned int jd_blocks; |
368 | }; | 368 | }; |
369 | 369 | ||
370 | struct gfs2_statfs_change_host { | 370 | struct gfs2_statfs_change_host { |
371 | s64 sc_total; | 371 | s64 sc_total; |
372 | s64 sc_free; | 372 | s64 sc_free; |
373 | s64 sc_dinodes; | 373 | s64 sc_dinodes; |
374 | }; | 374 | }; |
375 | 375 | ||
376 | #define GFS2_GLOCKD_DEFAULT 1 | 376 | #define GFS2_GLOCKD_DEFAULT 1 |
377 | #define GFS2_GLOCKD_MAX 16 | 377 | #define GFS2_GLOCKD_MAX 16 |
378 | 378 | ||
379 | #define GFS2_QUOTA_DEFAULT GFS2_QUOTA_OFF | 379 | #define GFS2_QUOTA_DEFAULT GFS2_QUOTA_OFF |
380 | #define GFS2_QUOTA_OFF 0 | 380 | #define GFS2_QUOTA_OFF 0 |
381 | #define GFS2_QUOTA_ACCOUNT 1 | 381 | #define GFS2_QUOTA_ACCOUNT 1 |
382 | #define GFS2_QUOTA_ON 2 | 382 | #define GFS2_QUOTA_ON 2 |
383 | 383 | ||
384 | #define GFS2_DATA_DEFAULT GFS2_DATA_ORDERED | 384 | #define GFS2_DATA_DEFAULT GFS2_DATA_ORDERED |
385 | #define GFS2_DATA_WRITEBACK 1 | 385 | #define GFS2_DATA_WRITEBACK 1 |
386 | #define GFS2_DATA_ORDERED 2 | 386 | #define GFS2_DATA_ORDERED 2 |
387 | 387 | ||
388 | struct gfs2_args { | 388 | struct gfs2_args { |
389 | char ar_lockproto[GFS2_LOCKNAME_LEN]; /* Name of the Lock Protocol */ | 389 | char ar_lockproto[GFS2_LOCKNAME_LEN]; /* Name of the Lock Protocol */ |
390 | char ar_locktable[GFS2_LOCKNAME_LEN]; /* Name of the Lock Table */ | 390 | char ar_locktable[GFS2_LOCKNAME_LEN]; /* Name of the Lock Table */ |
391 | char ar_hostdata[GFS2_LOCKNAME_LEN]; /* Host specific data */ | 391 | char ar_hostdata[GFS2_LOCKNAME_LEN]; /* Host specific data */ |
392 | int ar_spectator; /* Don't get a journal because we're always RO */ | 392 | int ar_spectator; /* Don't get a journal because we're always RO */ |
393 | int ar_ignore_local_fs; /* Don't optimize even if local_fs is 1 */ | 393 | int ar_ignore_local_fs; /* Don't optimize even if local_fs is 1 */ |
394 | int ar_localflocks; /* Let the VFS do flock|fcntl locks for us */ | 394 | int ar_localflocks; /* Let the VFS do flock|fcntl locks for us */ |
395 | int ar_localcaching; /* Local-style caching (dangerous on multihost) */ | 395 | int ar_localcaching; /* Local-style caching (dangerous on multihost) */ |
396 | int ar_debug; /* Oops on errors instead of trying to be graceful */ | 396 | int ar_debug; /* Oops on errors instead of trying to be graceful */ |
397 | int ar_upgrade; /* Upgrade ondisk/multihost format */ | 397 | int ar_upgrade; /* Upgrade ondisk/multihost format */ |
398 | unsigned int ar_num_glockd; /* Number of glockd threads */ | 398 | unsigned int ar_num_glockd; /* Number of glockd threads */ |
399 | int ar_posix_acl; /* Enable posix acls */ | 399 | int ar_posix_acl; /* Enable posix acls */ |
400 | int ar_quota; /* off/account/on */ | 400 | int ar_quota; /* off/account/on */ |
401 | int ar_suiddir; /* suiddir support */ | 401 | int ar_suiddir; /* suiddir support */ |
402 | int ar_data; /* ordered/writeback */ | 402 | int ar_data; /* ordered/writeback */ |
403 | }; | 403 | }; |
404 | 404 | ||
405 | struct gfs2_tune { | 405 | struct gfs2_tune { |
406 | spinlock_t gt_spin; | 406 | spinlock_t gt_spin; |
407 | 407 | ||
408 | unsigned int gt_demote_secs; /* Cache retention for unheld glock */ | 408 | unsigned int gt_demote_secs; /* Cache retention for unheld glock */ |
409 | unsigned int gt_incore_log_blocks; | 409 | unsigned int gt_incore_log_blocks; |
410 | unsigned int gt_log_flush_secs; | 410 | unsigned int gt_log_flush_secs; |
411 | 411 | ||
412 | unsigned int gt_recoverd_secs; | 412 | unsigned int gt_recoverd_secs; |
413 | unsigned int gt_logd_secs; | 413 | unsigned int gt_logd_secs; |
414 | unsigned int gt_quotad_secs; | 414 | unsigned int gt_quotad_secs; |
415 | 415 | ||
416 | unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */ | 416 | unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */ |
417 | unsigned int gt_quota_warn_period; /* Secs between quota warn msgs */ | 417 | unsigned int gt_quota_warn_period; /* Secs between quota warn msgs */ |
418 | unsigned int gt_quota_scale_num; /* Numerator */ | 418 | unsigned int gt_quota_scale_num; /* Numerator */ |
419 | unsigned int gt_quota_scale_den; /* Denominator */ | 419 | unsigned int gt_quota_scale_den; /* Denominator */ |
420 | unsigned int gt_quota_cache_secs; | 420 | unsigned int gt_quota_cache_secs; |
421 | unsigned int gt_quota_quantum; /* Secs between syncs to quota file */ | 421 | unsigned int gt_quota_quantum; /* Secs between syncs to quota file */ |
422 | unsigned int gt_atime_quantum; /* Min secs between atime updates */ | 422 | unsigned int gt_atime_quantum; /* Min secs between atime updates */ |
423 | unsigned int gt_new_files_jdata; | 423 | unsigned int gt_new_files_jdata; |
424 | unsigned int gt_new_files_directio; | ||
425 | unsigned int gt_max_readahead; /* Max bytes to read-ahead from disk */ | 424 | unsigned int gt_max_readahead; /* Max bytes to read-ahead from disk */ |
426 | unsigned int gt_stall_secs; /* Detects trouble! */ | 425 | unsigned int gt_stall_secs; /* Detects trouble! */ |
427 | unsigned int gt_complain_secs; | 426 | unsigned int gt_complain_secs; |
428 | unsigned int gt_statfs_quantum; | 427 | unsigned int gt_statfs_quantum; |
429 | unsigned int gt_statfs_slow; | 428 | unsigned int gt_statfs_slow; |
430 | }; | 429 | }; |
431 | 430 | ||
432 | enum { | 431 | enum { |
433 | SDF_JOURNAL_CHECKED = 0, | 432 | SDF_JOURNAL_CHECKED = 0, |
434 | SDF_JOURNAL_LIVE = 1, | 433 | SDF_JOURNAL_LIVE = 1, |
435 | SDF_SHUTDOWN = 2, | 434 | SDF_SHUTDOWN = 2, |
436 | SDF_NOATIME = 3, | 435 | SDF_NOATIME = 3, |
437 | }; | 436 | }; |
438 | 437 | ||
439 | #define GFS2_FSNAME_LEN 256 | 438 | #define GFS2_FSNAME_LEN 256 |
440 | 439 | ||
441 | struct gfs2_inum_host { | 440 | struct gfs2_inum_host { |
442 | u64 no_formal_ino; | 441 | u64 no_formal_ino; |
443 | u64 no_addr; | 442 | u64 no_addr; |
444 | }; | 443 | }; |
445 | 444 | ||
446 | struct gfs2_sb_host { | 445 | struct gfs2_sb_host { |
447 | u32 sb_magic; | 446 | u32 sb_magic; |
448 | u32 sb_type; | 447 | u32 sb_type; |
449 | u32 sb_format; | 448 | u32 sb_format; |
450 | 449 | ||
451 | u32 sb_fs_format; | 450 | u32 sb_fs_format; |
452 | u32 sb_multihost_format; | 451 | u32 sb_multihost_format; |
453 | u32 sb_bsize; | 452 | u32 sb_bsize; |
454 | u32 sb_bsize_shift; | 453 | u32 sb_bsize_shift; |
455 | 454 | ||
456 | struct gfs2_inum_host sb_master_dir; | 455 | struct gfs2_inum_host sb_master_dir; |
457 | struct gfs2_inum_host sb_root_dir; | 456 | struct gfs2_inum_host sb_root_dir; |
458 | 457 | ||
459 | char sb_lockproto[GFS2_LOCKNAME_LEN]; | 458 | char sb_lockproto[GFS2_LOCKNAME_LEN]; |
460 | char sb_locktable[GFS2_LOCKNAME_LEN]; | 459 | char sb_locktable[GFS2_LOCKNAME_LEN]; |
461 | }; | 460 | }; |
462 | 461 | ||
463 | struct gfs2_sbd { | 462 | struct gfs2_sbd { |
464 | struct super_block *sd_vfs; | 463 | struct super_block *sd_vfs; |
465 | struct super_block *sd_vfs_meta; | 464 | struct super_block *sd_vfs_meta; |
466 | struct kobject sd_kobj; | 465 | struct kobject sd_kobj; |
467 | unsigned long sd_flags; /* SDF_... */ | 466 | unsigned long sd_flags; /* SDF_... */ |
468 | struct gfs2_sb_host sd_sb; | 467 | struct gfs2_sb_host sd_sb; |
469 | 468 | ||
470 | /* Constants computed on mount */ | 469 | /* Constants computed on mount */ |
471 | 470 | ||
472 | u32 sd_fsb2bb; | 471 | u32 sd_fsb2bb; |
473 | u32 sd_fsb2bb_shift; | 472 | u32 sd_fsb2bb_shift; |
474 | u32 sd_diptrs; /* Number of pointers in a dinode */ | 473 | u32 sd_diptrs; /* Number of pointers in a dinode */ |
475 | u32 sd_inptrs; /* Number of pointers in a indirect block */ | 474 | u32 sd_inptrs; /* Number of pointers in a indirect block */ |
476 | u32 sd_jbsize; /* Size of a journaled data block */ | 475 | u32 sd_jbsize; /* Size of a journaled data block */ |
477 | u32 sd_hash_bsize; /* sizeof(exhash block) */ | 476 | u32 sd_hash_bsize; /* sizeof(exhash block) */ |
478 | u32 sd_hash_bsize_shift; | 477 | u32 sd_hash_bsize_shift; |
479 | u32 sd_hash_ptrs; /* Number of pointers in a hash block */ | 478 | u32 sd_hash_ptrs; /* Number of pointers in a hash block */ |
480 | u32 sd_qc_per_block; | 479 | u32 sd_qc_per_block; |
481 | u32 sd_max_dirres; /* Max blocks needed to add a directory entry */ | 480 | u32 sd_max_dirres; /* Max blocks needed to add a directory entry */ |
482 | u32 sd_max_height; /* Max height of a file's metadata tree */ | 481 | u32 sd_max_height; /* Max height of a file's metadata tree */ |
483 | u64 sd_heightsize[GFS2_MAX_META_HEIGHT + 1]; | 482 | u64 sd_heightsize[GFS2_MAX_META_HEIGHT + 1]; |
484 | u32 sd_max_jheight; /* Max height of journaled file's meta tree */ | 483 | u32 sd_max_jheight; /* Max height of journaled file's meta tree */ |
485 | u64 sd_jheightsize[GFS2_MAX_META_HEIGHT + 1]; | 484 | u64 sd_jheightsize[GFS2_MAX_META_HEIGHT + 1]; |
486 | 485 | ||
487 | struct gfs2_args sd_args; /* Mount arguments */ | 486 | struct gfs2_args sd_args; /* Mount arguments */ |
488 | struct gfs2_tune sd_tune; /* Filesystem tuning structure */ | 487 | struct gfs2_tune sd_tune; /* Filesystem tuning structure */ |
489 | 488 | ||
490 | /* Lock Stuff */ | 489 | /* Lock Stuff */ |
491 | 490 | ||
492 | struct lm_lockstruct sd_lockstruct; | 491 | struct lm_lockstruct sd_lockstruct; |
493 | struct list_head sd_reclaim_list; | 492 | struct list_head sd_reclaim_list; |
494 | spinlock_t sd_reclaim_lock; | 493 | spinlock_t sd_reclaim_lock; |
495 | wait_queue_head_t sd_reclaim_wq; | 494 | wait_queue_head_t sd_reclaim_wq; |
496 | atomic_t sd_reclaim_count; | 495 | atomic_t sd_reclaim_count; |
497 | struct gfs2_holder sd_live_gh; | 496 | struct gfs2_holder sd_live_gh; |
498 | struct gfs2_glock *sd_rename_gl; | 497 | struct gfs2_glock *sd_rename_gl; |
499 | struct gfs2_glock *sd_trans_gl; | 498 | struct gfs2_glock *sd_trans_gl; |
500 | 499 | ||
501 | /* Inode Stuff */ | 500 | /* Inode Stuff */ |
502 | 501 | ||
503 | struct inode *sd_master_dir; | 502 | struct inode *sd_master_dir; |
504 | struct inode *sd_jindex; | 503 | struct inode *sd_jindex; |
505 | struct inode *sd_inum_inode; | 504 | struct inode *sd_inum_inode; |
506 | struct inode *sd_statfs_inode; | 505 | struct inode *sd_statfs_inode; |
507 | struct inode *sd_ir_inode; | 506 | struct inode *sd_ir_inode; |
508 | struct inode *sd_sc_inode; | 507 | struct inode *sd_sc_inode; |
509 | struct inode *sd_qc_inode; | 508 | struct inode *sd_qc_inode; |
510 | struct inode *sd_rindex; | 509 | struct inode *sd_rindex; |
511 | struct inode *sd_quota_inode; | 510 | struct inode *sd_quota_inode; |
512 | 511 | ||
513 | /* Inum stuff */ | 512 | /* Inum stuff */ |
514 | 513 | ||
515 | struct mutex sd_inum_mutex; | 514 | struct mutex sd_inum_mutex; |
516 | 515 | ||
517 | /* StatFS stuff */ | 516 | /* StatFS stuff */ |
518 | 517 | ||
519 | spinlock_t sd_statfs_spin; | 518 | spinlock_t sd_statfs_spin; |
520 | struct gfs2_statfs_change_host sd_statfs_master; | 519 | struct gfs2_statfs_change_host sd_statfs_master; |
521 | struct gfs2_statfs_change_host sd_statfs_local; | 520 | struct gfs2_statfs_change_host sd_statfs_local; |
522 | unsigned long sd_statfs_sync_time; | 521 | unsigned long sd_statfs_sync_time; |
523 | 522 | ||
524 | /* Resource group stuff */ | 523 | /* Resource group stuff */ |
525 | 524 | ||
526 | int sd_rindex_uptodate; | 525 | int sd_rindex_uptodate; |
527 | spinlock_t sd_rindex_spin; | 526 | spinlock_t sd_rindex_spin; |
528 | struct mutex sd_rindex_mutex; | 527 | struct mutex sd_rindex_mutex; |
529 | struct list_head sd_rindex_list; | 528 | struct list_head sd_rindex_list; |
530 | struct list_head sd_rindex_mru_list; | 529 | struct list_head sd_rindex_mru_list; |
531 | struct gfs2_rgrpd *sd_rindex_forward; | 530 | struct gfs2_rgrpd *sd_rindex_forward; |
532 | unsigned int sd_rgrps; | 531 | unsigned int sd_rgrps; |
533 | 532 | ||
534 | /* Journal index stuff */ | 533 | /* Journal index stuff */ |
535 | 534 | ||
536 | struct list_head sd_jindex_list; | 535 | struct list_head sd_jindex_list; |
537 | spinlock_t sd_jindex_spin; | 536 | spinlock_t sd_jindex_spin; |
538 | struct mutex sd_jindex_mutex; | 537 | struct mutex sd_jindex_mutex; |
539 | unsigned int sd_journals; | 538 | unsigned int sd_journals; |
540 | unsigned long sd_jindex_refresh_time; | 539 | unsigned long sd_jindex_refresh_time; |
541 | 540 | ||
542 | struct gfs2_jdesc *sd_jdesc; | 541 | struct gfs2_jdesc *sd_jdesc; |
543 | struct gfs2_holder sd_journal_gh; | 542 | struct gfs2_holder sd_journal_gh; |
544 | struct gfs2_holder sd_jinode_gh; | 543 | struct gfs2_holder sd_jinode_gh; |
545 | 544 | ||
546 | struct gfs2_holder sd_ir_gh; | 545 | struct gfs2_holder sd_ir_gh; |
547 | struct gfs2_holder sd_sc_gh; | 546 | struct gfs2_holder sd_sc_gh; |
548 | struct gfs2_holder sd_qc_gh; | 547 | struct gfs2_holder sd_qc_gh; |
549 | 548 | ||
550 | /* Daemon stuff */ | 549 | /* Daemon stuff */ |
551 | 550 | ||
552 | struct task_struct *sd_recoverd_process; | 551 | struct task_struct *sd_recoverd_process; |
553 | struct task_struct *sd_logd_process; | 552 | struct task_struct *sd_logd_process; |
554 | struct task_struct *sd_quotad_process; | 553 | struct task_struct *sd_quotad_process; |
555 | struct task_struct *sd_glockd_process[GFS2_GLOCKD_MAX]; | 554 | struct task_struct *sd_glockd_process[GFS2_GLOCKD_MAX]; |
556 | unsigned int sd_glockd_num; | 555 | unsigned int sd_glockd_num; |
557 | 556 | ||
558 | /* Quota stuff */ | 557 | /* Quota stuff */ |
559 | 558 | ||
560 | struct list_head sd_quota_list; | 559 | struct list_head sd_quota_list; |
561 | atomic_t sd_quota_count; | 560 | atomic_t sd_quota_count; |
562 | spinlock_t sd_quota_spin; | 561 | spinlock_t sd_quota_spin; |
563 | struct mutex sd_quota_mutex; | 562 | struct mutex sd_quota_mutex; |
564 | 563 | ||
565 | unsigned int sd_quota_slots; | 564 | unsigned int sd_quota_slots; |
566 | unsigned int sd_quota_chunks; | 565 | unsigned int sd_quota_chunks; |
567 | unsigned char **sd_quota_bitmap; | 566 | unsigned char **sd_quota_bitmap; |
568 | 567 | ||
569 | u64 sd_quota_sync_gen; | 568 | u64 sd_quota_sync_gen; |
570 | unsigned long sd_quota_sync_time; | 569 | unsigned long sd_quota_sync_time; |
571 | 570 | ||
572 | /* Log stuff */ | 571 | /* Log stuff */ |
573 | 572 | ||
574 | spinlock_t sd_log_lock; | 573 | spinlock_t sd_log_lock; |
575 | 574 | ||
576 | unsigned int sd_log_blks_reserved; | 575 | unsigned int sd_log_blks_reserved; |
577 | unsigned int sd_log_commited_buf; | 576 | unsigned int sd_log_commited_buf; |
578 | unsigned int sd_log_commited_databuf; | 577 | unsigned int sd_log_commited_databuf; |
579 | unsigned int sd_log_commited_revoke; | 578 | unsigned int sd_log_commited_revoke; |
580 | 579 | ||
581 | unsigned int sd_log_num_buf; | 580 | unsigned int sd_log_num_buf; |
582 | unsigned int sd_log_num_revoke; | 581 | unsigned int sd_log_num_revoke; |
583 | unsigned int sd_log_num_rg; | 582 | unsigned int sd_log_num_rg; |
584 | unsigned int sd_log_num_databuf; | 583 | unsigned int sd_log_num_databuf; |
585 | 584 | ||
586 | struct list_head sd_log_le_buf; | 585 | struct list_head sd_log_le_buf; |
587 | struct list_head sd_log_le_revoke; | 586 | struct list_head sd_log_le_revoke; |
588 | struct list_head sd_log_le_rg; | 587 | struct list_head sd_log_le_rg; |
589 | struct list_head sd_log_le_databuf; | 588 | struct list_head sd_log_le_databuf; |
590 | struct list_head sd_log_le_ordered; | 589 | struct list_head sd_log_le_ordered; |
591 | 590 | ||
592 | atomic_t sd_log_blks_free; | 591 | atomic_t sd_log_blks_free; |
593 | struct mutex sd_log_reserve_mutex; | 592 | struct mutex sd_log_reserve_mutex; |
594 | 593 | ||
595 | u64 sd_log_sequence; | 594 | u64 sd_log_sequence; |
596 | unsigned int sd_log_head; | 595 | unsigned int sd_log_head; |
597 | unsigned int sd_log_tail; | 596 | unsigned int sd_log_tail; |
598 | int sd_log_idle; | 597 | int sd_log_idle; |
599 | 598 | ||
600 | unsigned long sd_log_flush_time; | 599 | unsigned long sd_log_flush_time; |
601 | struct rw_semaphore sd_log_flush_lock; | 600 | struct rw_semaphore sd_log_flush_lock; |
602 | atomic_t sd_log_in_flight; | 601 | atomic_t sd_log_in_flight; |
603 | wait_queue_head_t sd_log_flush_wait; | 602 | wait_queue_head_t sd_log_flush_wait; |
604 | 603 | ||
605 | unsigned int sd_log_flush_head; | 604 | unsigned int sd_log_flush_head; |
606 | u64 sd_log_flush_wrapped; | 605 | u64 sd_log_flush_wrapped; |
607 | 606 | ||
608 | struct list_head sd_ail1_list; | 607 | struct list_head sd_ail1_list; |
609 | struct list_head sd_ail2_list; | 608 | struct list_head sd_ail2_list; |
610 | u64 sd_ail_sync_gen; | 609 | u64 sd_ail_sync_gen; |
611 | 610 | ||
612 | /* Replay stuff */ | 611 | /* Replay stuff */ |
613 | 612 | ||
614 | struct list_head sd_revoke_list; | 613 | struct list_head sd_revoke_list; |
615 | unsigned int sd_replay_tail; | 614 | unsigned int sd_replay_tail; |
616 | 615 | ||
617 | unsigned int sd_found_blocks; | 616 | unsigned int sd_found_blocks; |
618 | unsigned int sd_found_revokes; | 617 | unsigned int sd_found_revokes; |
619 | unsigned int sd_replayed_blocks; | 618 | unsigned int sd_replayed_blocks; |
620 | 619 | ||
621 | /* For quiescing the filesystem */ | 620 | /* For quiescing the filesystem */ |
622 | 621 | ||
623 | struct gfs2_holder sd_freeze_gh; | 622 | struct gfs2_holder sd_freeze_gh; |
624 | struct mutex sd_freeze_lock; | 623 | struct mutex sd_freeze_lock; |
625 | unsigned int sd_freeze_count; | 624 | unsigned int sd_freeze_count; |
626 | 625 | ||
627 | /* Counters */ | 626 | /* Counters */ |
628 | 627 | ||
629 | atomic_t sd_reclaimed; | 628 | atomic_t sd_reclaimed; |
630 | 629 | ||
631 | char sd_fsname[GFS2_FSNAME_LEN]; | 630 | char sd_fsname[GFS2_FSNAME_LEN]; |
632 | char sd_table_name[GFS2_FSNAME_LEN]; | 631 | char sd_table_name[GFS2_FSNAME_LEN]; |
633 | char sd_proto_name[GFS2_FSNAME_LEN]; | 632 | char sd_proto_name[GFS2_FSNAME_LEN]; |
634 | 633 | ||
635 | /* Debugging crud */ | 634 | /* Debugging crud */ |
636 | 635 | ||
637 | unsigned long sd_last_warning; | 636 | unsigned long sd_last_warning; |
638 | struct vfsmount *sd_gfs2mnt; | 637 | struct vfsmount *sd_gfs2mnt; |
639 | struct dentry *debugfs_dir; /* debugfs directory */ | 638 | struct dentry *debugfs_dir; /* debugfs directory */ |
640 | struct dentry *debugfs_dentry_glocks; /* for debugfs */ | 639 | struct dentry *debugfs_dentry_glocks; /* for debugfs */ |
641 | }; | 640 | }; |
642 | 641 | ||
643 | #endif /* __INCORE_DOT_H__ */ | 642 | #endif /* __INCORE_DOT_H__ */ |
644 | 643 | ||
645 | 644 |
fs/gfs2/inode.c
1 | /* | 1 | /* |
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. | 3 | * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This copyrighted material is made available to anyone wishing to use, | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | * modify, copy, or redistribute it subject to the terms and conditions | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
7 | * of the GNU General Public License version 2. | 7 | * of the GNU General Public License version 2. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
13 | #include <linux/completion.h> | 13 | #include <linux/completion.h> |
14 | #include <linux/buffer_head.h> | 14 | #include <linux/buffer_head.h> |
15 | #include <linux/posix_acl.h> | 15 | #include <linux/posix_acl.h> |
16 | #include <linux/sort.h> | 16 | #include <linux/sort.h> |
17 | #include <linux/gfs2_ondisk.h> | 17 | #include <linux/gfs2_ondisk.h> |
18 | #include <linux/crc32.h> | 18 | #include <linux/crc32.h> |
19 | #include <linux/lm_interface.h> | 19 | #include <linux/lm_interface.h> |
20 | #include <linux/security.h> | 20 | #include <linux/security.h> |
21 | 21 | ||
22 | #include "gfs2.h" | 22 | #include "gfs2.h" |
23 | #include "incore.h" | 23 | #include "incore.h" |
24 | #include "acl.h" | 24 | #include "acl.h" |
25 | #include "bmap.h" | 25 | #include "bmap.h" |
26 | #include "dir.h" | 26 | #include "dir.h" |
27 | #include "eattr.h" | 27 | #include "eattr.h" |
28 | #include "glock.h" | 28 | #include "glock.h" |
29 | #include "glops.h" | 29 | #include "glops.h" |
30 | #include "inode.h" | 30 | #include "inode.h" |
31 | #include "log.h" | 31 | #include "log.h" |
32 | #include "meta_io.h" | 32 | #include "meta_io.h" |
33 | #include "ops_address.h" | 33 | #include "ops_address.h" |
34 | #include "ops_inode.h" | 34 | #include "ops_inode.h" |
35 | #include "quota.h" | 35 | #include "quota.h" |
36 | #include "rgrp.h" | 36 | #include "rgrp.h" |
37 | #include "trans.h" | 37 | #include "trans.h" |
38 | #include "util.h" | 38 | #include "util.h" |
39 | 39 | ||
40 | struct gfs2_inum_range_host { | 40 | struct gfs2_inum_range_host { |
41 | u64 ir_start; | 41 | u64 ir_start; |
42 | u64 ir_length; | 42 | u64 ir_length; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | static int iget_test(struct inode *inode, void *opaque) | 45 | static int iget_test(struct inode *inode, void *opaque) |
46 | { | 46 | { |
47 | struct gfs2_inode *ip = GFS2_I(inode); | 47 | struct gfs2_inode *ip = GFS2_I(inode); |
48 | u64 *no_addr = opaque; | 48 | u64 *no_addr = opaque; |
49 | 49 | ||
50 | if (ip->i_no_addr == *no_addr && test_bit(GIF_USER, &ip->i_flags)) | 50 | if (ip->i_no_addr == *no_addr && test_bit(GIF_USER, &ip->i_flags)) |
51 | return 1; | 51 | return 1; |
52 | 52 | ||
53 | return 0; | 53 | return 0; |
54 | } | 54 | } |
55 | 55 | ||
56 | static int iget_set(struct inode *inode, void *opaque) | 56 | static int iget_set(struct inode *inode, void *opaque) |
57 | { | 57 | { |
58 | struct gfs2_inode *ip = GFS2_I(inode); | 58 | struct gfs2_inode *ip = GFS2_I(inode); |
59 | u64 *no_addr = opaque; | 59 | u64 *no_addr = opaque; |
60 | 60 | ||
61 | inode->i_ino = (unsigned long)*no_addr; | 61 | inode->i_ino = (unsigned long)*no_addr; |
62 | ip->i_no_addr = *no_addr; | 62 | ip->i_no_addr = *no_addr; |
63 | set_bit(GIF_USER, &ip->i_flags); | 63 | set_bit(GIF_USER, &ip->i_flags); |
64 | return 0; | 64 | return 0; |
65 | } | 65 | } |
66 | 66 | ||
67 | struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr) | 67 | struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr) |
68 | { | 68 | { |
69 | unsigned long hash = (unsigned long)no_addr; | 69 | unsigned long hash = (unsigned long)no_addr; |
70 | return ilookup5(sb, hash, iget_test, &no_addr); | 70 | return ilookup5(sb, hash, iget_test, &no_addr); |
71 | } | 71 | } |
72 | 72 | ||
73 | static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) | 73 | static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) |
74 | { | 74 | { |
75 | unsigned long hash = (unsigned long)no_addr; | 75 | unsigned long hash = (unsigned long)no_addr; |
76 | return iget5_locked(sb, hash, iget_test, iget_set, &no_addr); | 76 | return iget5_locked(sb, hash, iget_test, iget_set, &no_addr); |
77 | } | 77 | } |
78 | 78 | ||
79 | struct gfs2_skip_data { | 79 | struct gfs2_skip_data { |
80 | u64 no_addr; | 80 | u64 no_addr; |
81 | int skipped; | 81 | int skipped; |
82 | }; | 82 | }; |
83 | 83 | ||
84 | static int iget_skip_test(struct inode *inode, void *opaque) | 84 | static int iget_skip_test(struct inode *inode, void *opaque) |
85 | { | 85 | { |
86 | struct gfs2_inode *ip = GFS2_I(inode); | 86 | struct gfs2_inode *ip = GFS2_I(inode); |
87 | struct gfs2_skip_data *data = opaque; | 87 | struct gfs2_skip_data *data = opaque; |
88 | 88 | ||
89 | if (ip->i_no_addr == data->no_addr && test_bit(GIF_USER, &ip->i_flags)){ | 89 | if (ip->i_no_addr == data->no_addr && test_bit(GIF_USER, &ip->i_flags)){ |
90 | if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)){ | 90 | if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)){ |
91 | data->skipped = 1; | 91 | data->skipped = 1; |
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | return 1; | 94 | return 1; |
95 | } | 95 | } |
96 | return 0; | 96 | return 0; |
97 | } | 97 | } |
98 | 98 | ||
99 | static int iget_skip_set(struct inode *inode, void *opaque) | 99 | static int iget_skip_set(struct inode *inode, void *opaque) |
100 | { | 100 | { |
101 | struct gfs2_inode *ip = GFS2_I(inode); | 101 | struct gfs2_inode *ip = GFS2_I(inode); |
102 | struct gfs2_skip_data *data = opaque; | 102 | struct gfs2_skip_data *data = opaque; |
103 | 103 | ||
104 | if (data->skipped) | 104 | if (data->skipped) |
105 | return 1; | 105 | return 1; |
106 | inode->i_ino = (unsigned long)(data->no_addr); | 106 | inode->i_ino = (unsigned long)(data->no_addr); |
107 | ip->i_no_addr = data->no_addr; | 107 | ip->i_no_addr = data->no_addr; |
108 | set_bit(GIF_USER, &ip->i_flags); | 108 | set_bit(GIF_USER, &ip->i_flags); |
109 | return 0; | 109 | return 0; |
110 | } | 110 | } |
111 | 111 | ||
112 | static struct inode *gfs2_iget_skip(struct super_block *sb, | 112 | static struct inode *gfs2_iget_skip(struct super_block *sb, |
113 | u64 no_addr) | 113 | u64 no_addr) |
114 | { | 114 | { |
115 | struct gfs2_skip_data data; | 115 | struct gfs2_skip_data data; |
116 | unsigned long hash = (unsigned long)no_addr; | 116 | unsigned long hash = (unsigned long)no_addr; |
117 | 117 | ||
118 | data.no_addr = no_addr; | 118 | data.no_addr = no_addr; |
119 | data.skipped = 0; | 119 | data.skipped = 0; |
120 | return iget5_locked(sb, hash, iget_skip_test, iget_skip_set, &data); | 120 | return iget5_locked(sb, hash, iget_skip_test, iget_skip_set, &data); |
121 | } | 121 | } |
122 | 122 | ||
123 | /** | 123 | /** |
124 | * GFS2 lookup code fills in vfs inode contents based on info obtained | 124 | * GFS2 lookup code fills in vfs inode contents based on info obtained |
125 | * from directory entry inside gfs2_inode_lookup(). This has caused issues | 125 | * from directory entry inside gfs2_inode_lookup(). This has caused issues |
126 | * with NFS code path since its get_dentry routine doesn't have the relevant | 126 | * with NFS code path since its get_dentry routine doesn't have the relevant |
127 | * directory entry when gfs2_inode_lookup() is invoked. Part of the code | 127 | * directory entry when gfs2_inode_lookup() is invoked. Part of the code |
128 | * segment inside gfs2_inode_lookup code needs to get moved around. | 128 | * segment inside gfs2_inode_lookup code needs to get moved around. |
129 | * | 129 | * |
130 | * Clean up I_LOCK and I_NEW as well. | 130 | * Clean up I_LOCK and I_NEW as well. |
131 | **/ | 131 | **/ |
132 | 132 | ||
133 | void gfs2_set_iop(struct inode *inode) | 133 | void gfs2_set_iop(struct inode *inode) |
134 | { | 134 | { |
135 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 135 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
136 | umode_t mode = inode->i_mode; | 136 | umode_t mode = inode->i_mode; |
137 | 137 | ||
138 | if (S_ISREG(mode)) { | 138 | if (S_ISREG(mode)) { |
139 | inode->i_op = &gfs2_file_iops; | 139 | inode->i_op = &gfs2_file_iops; |
140 | if (sdp->sd_args.ar_localflocks) | 140 | if (sdp->sd_args.ar_localflocks) |
141 | inode->i_fop = &gfs2_file_fops_nolock; | 141 | inode->i_fop = &gfs2_file_fops_nolock; |
142 | else | 142 | else |
143 | inode->i_fop = &gfs2_file_fops; | 143 | inode->i_fop = &gfs2_file_fops; |
144 | } else if (S_ISDIR(mode)) { | 144 | } else if (S_ISDIR(mode)) { |
145 | inode->i_op = &gfs2_dir_iops; | 145 | inode->i_op = &gfs2_dir_iops; |
146 | if (sdp->sd_args.ar_localflocks) | 146 | if (sdp->sd_args.ar_localflocks) |
147 | inode->i_fop = &gfs2_dir_fops_nolock; | 147 | inode->i_fop = &gfs2_dir_fops_nolock; |
148 | else | 148 | else |
149 | inode->i_fop = &gfs2_dir_fops; | 149 | inode->i_fop = &gfs2_dir_fops; |
150 | } else if (S_ISLNK(mode)) { | 150 | } else if (S_ISLNK(mode)) { |
151 | inode->i_op = &gfs2_symlink_iops; | 151 | inode->i_op = &gfs2_symlink_iops; |
152 | } else { | 152 | } else { |
153 | inode->i_op = &gfs2_file_iops; | 153 | inode->i_op = &gfs2_file_iops; |
154 | init_special_inode(inode, inode->i_mode, inode->i_rdev); | 154 | init_special_inode(inode, inode->i_mode, inode->i_rdev); |
155 | } | 155 | } |
156 | 156 | ||
157 | unlock_new_inode(inode); | 157 | unlock_new_inode(inode); |
158 | } | 158 | } |
159 | 159 | ||
160 | /** | 160 | /** |
161 | * gfs2_inode_lookup - Lookup an inode | 161 | * gfs2_inode_lookup - Lookup an inode |
162 | * @sb: The super block | 162 | * @sb: The super block |
163 | * @no_addr: The inode number | 163 | * @no_addr: The inode number |
164 | * @type: The type of the inode | 164 | * @type: The type of the inode |
165 | * @skip_freeing: set this not return an inode if it is currently being freed. | 165 | * @skip_freeing: set this not return an inode if it is currently being freed. |
166 | * | 166 | * |
167 | * Returns: A VFS inode, or an error | 167 | * Returns: A VFS inode, or an error |
168 | */ | 168 | */ |
169 | 169 | ||
170 | struct inode *gfs2_inode_lookup(struct super_block *sb, | 170 | struct inode *gfs2_inode_lookup(struct super_block *sb, |
171 | unsigned int type, | 171 | unsigned int type, |
172 | u64 no_addr, | 172 | u64 no_addr, |
173 | u64 no_formal_ino, int skip_freeing) | 173 | u64 no_formal_ino, int skip_freeing) |
174 | { | 174 | { |
175 | struct inode *inode; | 175 | struct inode *inode; |
176 | struct gfs2_inode *ip; | 176 | struct gfs2_inode *ip; |
177 | struct gfs2_glock *io_gl; | 177 | struct gfs2_glock *io_gl; |
178 | int error; | 178 | int error; |
179 | 179 | ||
180 | if (skip_freeing) | 180 | if (skip_freeing) |
181 | inode = gfs2_iget_skip(sb, no_addr); | 181 | inode = gfs2_iget_skip(sb, no_addr); |
182 | else | 182 | else |
183 | inode = gfs2_iget(sb, no_addr); | 183 | inode = gfs2_iget(sb, no_addr); |
184 | ip = GFS2_I(inode); | 184 | ip = GFS2_I(inode); |
185 | 185 | ||
186 | if (!inode) | 186 | if (!inode) |
187 | return ERR_PTR(-ENOBUFS); | 187 | return ERR_PTR(-ENOBUFS); |
188 | 188 | ||
189 | if (inode->i_state & I_NEW) { | 189 | if (inode->i_state & I_NEW) { |
190 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 190 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
191 | ip->i_no_formal_ino = no_formal_ino; | 191 | ip->i_no_formal_ino = no_formal_ino; |
192 | 192 | ||
193 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); | 193 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); |
194 | if (unlikely(error)) | 194 | if (unlikely(error)) |
195 | goto fail; | 195 | goto fail; |
196 | ip->i_gl->gl_object = ip; | 196 | ip->i_gl->gl_object = ip; |
197 | 197 | ||
198 | error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); | 198 | error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); |
199 | if (unlikely(error)) | 199 | if (unlikely(error)) |
200 | goto fail_put; | 200 | goto fail_put; |
201 | 201 | ||
202 | set_bit(GIF_INVALID, &ip->i_flags); | 202 | set_bit(GIF_INVALID, &ip->i_flags); |
203 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); | 203 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); |
204 | if (unlikely(error)) | 204 | if (unlikely(error)) |
205 | goto fail_iopen; | 205 | goto fail_iopen; |
206 | ip->i_iopen_gh.gh_gl->gl_object = ip; | 206 | ip->i_iopen_gh.gh_gl->gl_object = ip; |
207 | 207 | ||
208 | gfs2_glock_put(io_gl); | 208 | gfs2_glock_put(io_gl); |
209 | 209 | ||
210 | if ((type == DT_UNKNOWN) && (no_formal_ino == 0)) | 210 | if ((type == DT_UNKNOWN) && (no_formal_ino == 0)) |
211 | goto gfs2_nfsbypass; | 211 | goto gfs2_nfsbypass; |
212 | 212 | ||
213 | inode->i_mode = DT2IF(type); | 213 | inode->i_mode = DT2IF(type); |
214 | 214 | ||
215 | /* | 215 | /* |
216 | * We must read the inode in order to work out its type in | 216 | * We must read the inode in order to work out its type in |
217 | * this case. Note that this doesn't happen often as we normally | 217 | * this case. Note that this doesn't happen often as we normally |
218 | * know the type beforehand. This code path only occurs during | 218 | * know the type beforehand. This code path only occurs during |
219 | * unlinked inode recovery (where it is safe to do this glock, | 219 | * unlinked inode recovery (where it is safe to do this glock, |
220 | * which is not true in the general case). | 220 | * which is not true in the general case). |
221 | */ | 221 | */ |
222 | if (type == DT_UNKNOWN) { | 222 | if (type == DT_UNKNOWN) { |
223 | struct gfs2_holder gh; | 223 | struct gfs2_holder gh; |
224 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 224 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
225 | if (unlikely(error)) | 225 | if (unlikely(error)) |
226 | goto fail_glock; | 226 | goto fail_glock; |
227 | /* Inode is now uptodate */ | 227 | /* Inode is now uptodate */ |
228 | gfs2_glock_dq_uninit(&gh); | 228 | gfs2_glock_dq_uninit(&gh); |
229 | } | 229 | } |
230 | 230 | ||
231 | gfs2_set_iop(inode); | 231 | gfs2_set_iop(inode); |
232 | } | 232 | } |
233 | 233 | ||
234 | gfs2_nfsbypass: | 234 | gfs2_nfsbypass: |
235 | return inode; | 235 | return inode; |
236 | fail_glock: | 236 | fail_glock: |
237 | gfs2_glock_dq(&ip->i_iopen_gh); | 237 | gfs2_glock_dq(&ip->i_iopen_gh); |
238 | fail_iopen: | 238 | fail_iopen: |
239 | gfs2_glock_put(io_gl); | 239 | gfs2_glock_put(io_gl); |
240 | fail_put: | 240 | fail_put: |
241 | ip->i_gl->gl_object = NULL; | 241 | ip->i_gl->gl_object = NULL; |
242 | gfs2_glock_put(ip->i_gl); | 242 | gfs2_glock_put(ip->i_gl); |
243 | fail: | 243 | fail: |
244 | iget_failed(inode); | 244 | iget_failed(inode); |
245 | return ERR_PTR(error); | 245 | return ERR_PTR(error); |
246 | } | 246 | } |
247 | 247 | ||
248 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | 248 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) |
249 | { | 249 | { |
250 | struct gfs2_dinode_host *di = &ip->i_di; | 250 | struct gfs2_dinode_host *di = &ip->i_di; |
251 | const struct gfs2_dinode *str = buf; | 251 | const struct gfs2_dinode *str = buf; |
252 | u16 height, depth; | 252 | u16 height, depth; |
253 | 253 | ||
254 | if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) | 254 | if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) |
255 | goto corrupt; | 255 | goto corrupt; |
256 | ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); | 256 | ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); |
257 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); | 257 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); |
258 | ip->i_inode.i_rdev = 0; | 258 | ip->i_inode.i_rdev = 0; |
259 | switch (ip->i_inode.i_mode & S_IFMT) { | 259 | switch (ip->i_inode.i_mode & S_IFMT) { |
260 | case S_IFBLK: | 260 | case S_IFBLK: |
261 | case S_IFCHR: | 261 | case S_IFCHR: |
262 | ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major), | 262 | ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major), |
263 | be32_to_cpu(str->di_minor)); | 263 | be32_to_cpu(str->di_minor)); |
264 | break; | 264 | break; |
265 | }; | 265 | }; |
266 | 266 | ||
267 | ip->i_inode.i_uid = be32_to_cpu(str->di_uid); | 267 | ip->i_inode.i_uid = be32_to_cpu(str->di_uid); |
268 | ip->i_inode.i_gid = be32_to_cpu(str->di_gid); | 268 | ip->i_inode.i_gid = be32_to_cpu(str->di_gid); |
269 | /* | 269 | /* |
270 | * We will need to review setting the nlink count here in the | 270 | * We will need to review setting the nlink count here in the |
271 | * light of the forthcoming ro bind mount work. This is a reminder | 271 | * light of the forthcoming ro bind mount work. This is a reminder |
272 | * to do that. | 272 | * to do that. |
273 | */ | 273 | */ |
274 | ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink); | 274 | ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink); |
275 | di->di_size = be64_to_cpu(str->di_size); | 275 | di->di_size = be64_to_cpu(str->di_size); |
276 | i_size_write(&ip->i_inode, di->di_size); | 276 | i_size_write(&ip->i_inode, di->di_size); |
277 | gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); | 277 | gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); |
278 | ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime); | 278 | ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime); |
279 | ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); | 279 | ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); |
280 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); | 280 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); |
281 | ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec); | 281 | ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec); |
282 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); | 282 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); |
283 | ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec); | 283 | ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec); |
284 | 284 | ||
285 | ip->i_goal = be64_to_cpu(str->di_goal_meta); | 285 | ip->i_goal = be64_to_cpu(str->di_goal_meta); |
286 | di->di_generation = be64_to_cpu(str->di_generation); | 286 | di->di_generation = be64_to_cpu(str->di_generation); |
287 | 287 | ||
288 | di->di_flags = be32_to_cpu(str->di_flags); | 288 | di->di_flags = be32_to_cpu(str->di_flags); |
289 | gfs2_set_inode_flags(&ip->i_inode); | 289 | gfs2_set_inode_flags(&ip->i_inode); |
290 | height = be16_to_cpu(str->di_height); | 290 | height = be16_to_cpu(str->di_height); |
291 | if (unlikely(height > GFS2_MAX_META_HEIGHT)) | 291 | if (unlikely(height > GFS2_MAX_META_HEIGHT)) |
292 | goto corrupt; | 292 | goto corrupt; |
293 | ip->i_height = (u8)height; | 293 | ip->i_height = (u8)height; |
294 | 294 | ||
295 | depth = be16_to_cpu(str->di_depth); | 295 | depth = be16_to_cpu(str->di_depth); |
296 | if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) | 296 | if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) |
297 | goto corrupt; | 297 | goto corrupt; |
298 | ip->i_depth = (u8)depth; | 298 | ip->i_depth = (u8)depth; |
299 | di->di_entries = be32_to_cpu(str->di_entries); | 299 | di->di_entries = be32_to_cpu(str->di_entries); |
300 | 300 | ||
301 | di->di_eattr = be64_to_cpu(str->di_eattr); | 301 | di->di_eattr = be64_to_cpu(str->di_eattr); |
302 | if (S_ISREG(ip->i_inode.i_mode)) | 302 | if (S_ISREG(ip->i_inode.i_mode)) |
303 | gfs2_set_aops(&ip->i_inode); | 303 | gfs2_set_aops(&ip->i_inode); |
304 | 304 | ||
305 | return 0; | 305 | return 0; |
306 | corrupt: | 306 | corrupt: |
307 | if (gfs2_consist_inode(ip)) | 307 | if (gfs2_consist_inode(ip)) |
308 | gfs2_dinode_print(ip); | 308 | gfs2_dinode_print(ip); |
309 | return -EIO; | 309 | return -EIO; |
310 | } | 310 | } |
311 | 311 | ||
312 | /** | 312 | /** |
313 | * gfs2_inode_refresh - Refresh the incore copy of the dinode | 313 | * gfs2_inode_refresh - Refresh the incore copy of the dinode |
314 | * @ip: The GFS2 inode | 314 | * @ip: The GFS2 inode |
315 | * | 315 | * |
316 | * Returns: errno | 316 | * Returns: errno |
317 | */ | 317 | */ |
318 | 318 | ||
319 | int gfs2_inode_refresh(struct gfs2_inode *ip) | 319 | int gfs2_inode_refresh(struct gfs2_inode *ip) |
320 | { | 320 | { |
321 | struct buffer_head *dibh; | 321 | struct buffer_head *dibh; |
322 | int error; | 322 | int error; |
323 | 323 | ||
324 | error = gfs2_meta_inode_buffer(ip, &dibh); | 324 | error = gfs2_meta_inode_buffer(ip, &dibh); |
325 | if (error) | 325 | if (error) |
326 | return error; | 326 | return error; |
327 | 327 | ||
328 | if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), dibh, GFS2_METATYPE_DI)) { | 328 | if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), dibh, GFS2_METATYPE_DI)) { |
329 | brelse(dibh); | 329 | brelse(dibh); |
330 | return -EIO; | 330 | return -EIO; |
331 | } | 331 | } |
332 | 332 | ||
333 | error = gfs2_dinode_in(ip, dibh->b_data); | 333 | error = gfs2_dinode_in(ip, dibh->b_data); |
334 | brelse(dibh); | 334 | brelse(dibh); |
335 | clear_bit(GIF_INVALID, &ip->i_flags); | 335 | clear_bit(GIF_INVALID, &ip->i_flags); |
336 | 336 | ||
337 | return error; | 337 | return error; |
338 | } | 338 | } |
339 | 339 | ||
340 | int gfs2_dinode_dealloc(struct gfs2_inode *ip) | 340 | int gfs2_dinode_dealloc(struct gfs2_inode *ip) |
341 | { | 341 | { |
342 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 342 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
343 | struct gfs2_alloc *al; | 343 | struct gfs2_alloc *al; |
344 | struct gfs2_rgrpd *rgd; | 344 | struct gfs2_rgrpd *rgd; |
345 | int error; | 345 | int error; |
346 | 346 | ||
347 | if (gfs2_get_inode_blocks(&ip->i_inode) != 1) { | 347 | if (gfs2_get_inode_blocks(&ip->i_inode) != 1) { |
348 | if (gfs2_consist_inode(ip)) | 348 | if (gfs2_consist_inode(ip)) |
349 | gfs2_dinode_print(ip); | 349 | gfs2_dinode_print(ip); |
350 | return -EIO; | 350 | return -EIO; |
351 | } | 351 | } |
352 | 352 | ||
353 | al = gfs2_alloc_get(ip); | 353 | al = gfs2_alloc_get(ip); |
354 | if (!al) | 354 | if (!al) |
355 | return -ENOMEM; | 355 | return -ENOMEM; |
356 | 356 | ||
357 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 357 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); |
358 | if (error) | 358 | if (error) |
359 | goto out; | 359 | goto out; |
360 | 360 | ||
361 | error = gfs2_rindex_hold(sdp, &al->al_ri_gh); | 361 | error = gfs2_rindex_hold(sdp, &al->al_ri_gh); |
362 | if (error) | 362 | if (error) |
363 | goto out_qs; | 363 | goto out_qs; |
364 | 364 | ||
365 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); | 365 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); |
366 | if (!rgd) { | 366 | if (!rgd) { |
367 | gfs2_consist_inode(ip); | 367 | gfs2_consist_inode(ip); |
368 | error = -EIO; | 368 | error = -EIO; |
369 | goto out_rindex_relse; | 369 | goto out_rindex_relse; |
370 | } | 370 | } |
371 | 371 | ||
372 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, | 372 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, |
373 | &al->al_rgd_gh); | 373 | &al->al_rgd_gh); |
374 | if (error) | 374 | if (error) |
375 | goto out_rindex_relse; | 375 | goto out_rindex_relse; |
376 | 376 | ||
377 | error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA, 1); | 377 | error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA, 1); |
378 | if (error) | 378 | if (error) |
379 | goto out_rg_gunlock; | 379 | goto out_rg_gunlock; |
380 | 380 | ||
381 | set_bit(GLF_DIRTY, &ip->i_gl->gl_flags); | 381 | set_bit(GLF_DIRTY, &ip->i_gl->gl_flags); |
382 | set_bit(GLF_LFLUSH, &ip->i_gl->gl_flags); | 382 | set_bit(GLF_LFLUSH, &ip->i_gl->gl_flags); |
383 | 383 | ||
384 | gfs2_free_di(rgd, ip); | 384 | gfs2_free_di(rgd, ip); |
385 | 385 | ||
386 | gfs2_trans_end(sdp); | 386 | gfs2_trans_end(sdp); |
387 | clear_bit(GLF_STICKY, &ip->i_gl->gl_flags); | 387 | clear_bit(GLF_STICKY, &ip->i_gl->gl_flags); |
388 | 388 | ||
389 | out_rg_gunlock: | 389 | out_rg_gunlock: |
390 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | 390 | gfs2_glock_dq_uninit(&al->al_rgd_gh); |
391 | out_rindex_relse: | 391 | out_rindex_relse: |
392 | gfs2_glock_dq_uninit(&al->al_ri_gh); | 392 | gfs2_glock_dq_uninit(&al->al_ri_gh); |
393 | out_qs: | 393 | out_qs: |
394 | gfs2_quota_unhold(ip); | 394 | gfs2_quota_unhold(ip); |
395 | out: | 395 | out: |
396 | gfs2_alloc_put(ip); | 396 | gfs2_alloc_put(ip); |
397 | return error; | 397 | return error; |
398 | } | 398 | } |
399 | 399 | ||
400 | /** | 400 | /** |
401 | * gfs2_change_nlink - Change nlink count on inode | 401 | * gfs2_change_nlink - Change nlink count on inode |
402 | * @ip: The GFS2 inode | 402 | * @ip: The GFS2 inode |
403 | * @diff: The change in the nlink count required | 403 | * @diff: The change in the nlink count required |
404 | * | 404 | * |
405 | * Returns: errno | 405 | * Returns: errno |
406 | */ | 406 | */ |
407 | int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | 407 | int gfs2_change_nlink(struct gfs2_inode *ip, int diff) |
408 | { | 408 | { |
409 | struct buffer_head *dibh; | 409 | struct buffer_head *dibh; |
410 | u32 nlink; | 410 | u32 nlink; |
411 | int error; | 411 | int error; |
412 | 412 | ||
413 | BUG_ON(diff != 1 && diff != -1); | 413 | BUG_ON(diff != 1 && diff != -1); |
414 | nlink = ip->i_inode.i_nlink + diff; | 414 | nlink = ip->i_inode.i_nlink + diff; |
415 | 415 | ||
416 | /* If we are reducing the nlink count, but the new value ends up being | 416 | /* If we are reducing the nlink count, but the new value ends up being |
417 | bigger than the old one, we must have underflowed. */ | 417 | bigger than the old one, we must have underflowed. */ |
418 | if (diff < 0 && nlink > ip->i_inode.i_nlink) { | 418 | if (diff < 0 && nlink > ip->i_inode.i_nlink) { |
419 | if (gfs2_consist_inode(ip)) | 419 | if (gfs2_consist_inode(ip)) |
420 | gfs2_dinode_print(ip); | 420 | gfs2_dinode_print(ip); |
421 | return -EIO; | 421 | return -EIO; |
422 | } | 422 | } |
423 | 423 | ||
424 | error = gfs2_meta_inode_buffer(ip, &dibh); | 424 | error = gfs2_meta_inode_buffer(ip, &dibh); |
425 | if (error) | 425 | if (error) |
426 | return error; | 426 | return error; |
427 | 427 | ||
428 | if (diff > 0) | 428 | if (diff > 0) |
429 | inc_nlink(&ip->i_inode); | 429 | inc_nlink(&ip->i_inode); |
430 | else | 430 | else |
431 | drop_nlink(&ip->i_inode); | 431 | drop_nlink(&ip->i_inode); |
432 | 432 | ||
433 | ip->i_inode.i_ctime = CURRENT_TIME; | 433 | ip->i_inode.i_ctime = CURRENT_TIME; |
434 | 434 | ||
435 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 435 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
436 | gfs2_dinode_out(ip, dibh->b_data); | 436 | gfs2_dinode_out(ip, dibh->b_data); |
437 | brelse(dibh); | 437 | brelse(dibh); |
438 | mark_inode_dirty(&ip->i_inode); | 438 | mark_inode_dirty(&ip->i_inode); |
439 | 439 | ||
440 | if (ip->i_inode.i_nlink == 0) | 440 | if (ip->i_inode.i_nlink == 0) |
441 | gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */ | 441 | gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */ |
442 | 442 | ||
443 | return error; | 443 | return error; |
444 | } | 444 | } |
445 | 445 | ||
446 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name) | 446 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name) |
447 | { | 447 | { |
448 | struct qstr qstr; | 448 | struct qstr qstr; |
449 | struct inode *inode; | 449 | struct inode *inode; |
450 | gfs2_str2qstr(&qstr, name); | 450 | gfs2_str2qstr(&qstr, name); |
451 | inode = gfs2_lookupi(dip, &qstr, 1, NULL); | 451 | inode = gfs2_lookupi(dip, &qstr, 1, NULL); |
452 | /* gfs2_lookupi has inconsistent callers: vfs | 452 | /* gfs2_lookupi has inconsistent callers: vfs |
453 | * related routines expect NULL for no entry found, | 453 | * related routines expect NULL for no entry found, |
454 | * gfs2_lookup_simple callers expect ENOENT | 454 | * gfs2_lookup_simple callers expect ENOENT |
455 | * and do not check for NULL. | 455 | * and do not check for NULL. |
456 | */ | 456 | */ |
457 | if (inode == NULL) | 457 | if (inode == NULL) |
458 | return ERR_PTR(-ENOENT); | 458 | return ERR_PTR(-ENOENT); |
459 | else | 459 | else |
460 | return inode; | 460 | return inode; |
461 | } | 461 | } |
462 | 462 | ||
463 | 463 | ||
464 | /** | 464 | /** |
465 | * gfs2_lookupi - Look up a filename in a directory and return its inode | 465 | * gfs2_lookupi - Look up a filename in a directory and return its inode |
466 | * @d_gh: An initialized holder for the directory glock | 466 | * @d_gh: An initialized holder for the directory glock |
467 | * @name: The name of the inode to look for | 467 | * @name: The name of the inode to look for |
468 | * @is_root: If 1, ignore the caller's permissions | 468 | * @is_root: If 1, ignore the caller's permissions |
469 | * @i_gh: An uninitialized holder for the new inode glock | 469 | * @i_gh: An uninitialized holder for the new inode glock |
470 | * | 470 | * |
471 | * This can be called via the VFS filldir function when NFS is doing | 471 | * This can be called via the VFS filldir function when NFS is doing |
472 | * a readdirplus and the inode which its intending to stat isn't | 472 | * a readdirplus and the inode which its intending to stat isn't |
473 | * already in cache. In this case we must not take the directory glock | 473 | * already in cache. In this case we must not take the directory glock |
474 | * again, since the readdir call will have already taken that lock. | 474 | * again, since the readdir call will have already taken that lock. |
475 | * | 475 | * |
476 | * Returns: errno | 476 | * Returns: errno |
477 | */ | 477 | */ |
478 | 478 | ||
479 | struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | 479 | struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, |
480 | int is_root, struct nameidata *nd) | 480 | int is_root, struct nameidata *nd) |
481 | { | 481 | { |
482 | struct super_block *sb = dir->i_sb; | 482 | struct super_block *sb = dir->i_sb; |
483 | struct gfs2_inode *dip = GFS2_I(dir); | 483 | struct gfs2_inode *dip = GFS2_I(dir); |
484 | struct gfs2_holder d_gh; | 484 | struct gfs2_holder d_gh; |
485 | int error = 0; | 485 | int error = 0; |
486 | struct inode *inode = NULL; | 486 | struct inode *inode = NULL; |
487 | int unlock = 0; | 487 | int unlock = 0; |
488 | 488 | ||
489 | if (!name->len || name->len > GFS2_FNAMESIZE) | 489 | if (!name->len || name->len > GFS2_FNAMESIZE) |
490 | return ERR_PTR(-ENAMETOOLONG); | 490 | return ERR_PTR(-ENAMETOOLONG); |
491 | 491 | ||
492 | if ((name->len == 1 && memcmp(name->name, ".", 1) == 0) || | 492 | if ((name->len == 1 && memcmp(name->name, ".", 1) == 0) || |
493 | (name->len == 2 && memcmp(name->name, "..", 2) == 0 && | 493 | (name->len == 2 && memcmp(name->name, "..", 2) == 0 && |
494 | dir == sb->s_root->d_inode)) { | 494 | dir == sb->s_root->d_inode)) { |
495 | igrab(dir); | 495 | igrab(dir); |
496 | return dir; | 496 | return dir; |
497 | } | 497 | } |
498 | 498 | ||
499 | if (gfs2_glock_is_locked_by_me(dip->i_gl) == NULL) { | 499 | if (gfs2_glock_is_locked_by_me(dip->i_gl) == NULL) { |
500 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); | 500 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); |
501 | if (error) | 501 | if (error) |
502 | return ERR_PTR(error); | 502 | return ERR_PTR(error); |
503 | unlock = 1; | 503 | unlock = 1; |
504 | } | 504 | } |
505 | 505 | ||
506 | if (!is_root) { | 506 | if (!is_root) { |
507 | error = gfs2_permission(dir, MAY_EXEC); | 507 | error = gfs2_permission(dir, MAY_EXEC); |
508 | if (error) | 508 | if (error) |
509 | goto out; | 509 | goto out; |
510 | } | 510 | } |
511 | 511 | ||
512 | inode = gfs2_dir_search(dir, name); | 512 | inode = gfs2_dir_search(dir, name); |
513 | if (IS_ERR(inode)) | 513 | if (IS_ERR(inode)) |
514 | error = PTR_ERR(inode); | 514 | error = PTR_ERR(inode); |
515 | out: | 515 | out: |
516 | if (unlock) | 516 | if (unlock) |
517 | gfs2_glock_dq_uninit(&d_gh); | 517 | gfs2_glock_dq_uninit(&d_gh); |
518 | if (error == -ENOENT) | 518 | if (error == -ENOENT) |
519 | return NULL; | 519 | return NULL; |
520 | return inode ? inode : ERR_PTR(error); | 520 | return inode ? inode : ERR_PTR(error); |
521 | } | 521 | } |
522 | 522 | ||
523 | static void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf) | 523 | static void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf) |
524 | { | 524 | { |
525 | const struct gfs2_inum_range *str = buf; | 525 | const struct gfs2_inum_range *str = buf; |
526 | 526 | ||
527 | ir->ir_start = be64_to_cpu(str->ir_start); | 527 | ir->ir_start = be64_to_cpu(str->ir_start); |
528 | ir->ir_length = be64_to_cpu(str->ir_length); | 528 | ir->ir_length = be64_to_cpu(str->ir_length); |
529 | } | 529 | } |
530 | 530 | ||
531 | static void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf) | 531 | static void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf) |
532 | { | 532 | { |
533 | struct gfs2_inum_range *str = buf; | 533 | struct gfs2_inum_range *str = buf; |
534 | 534 | ||
535 | str->ir_start = cpu_to_be64(ir->ir_start); | 535 | str->ir_start = cpu_to_be64(ir->ir_start); |
536 | str->ir_length = cpu_to_be64(ir->ir_length); | 536 | str->ir_length = cpu_to_be64(ir->ir_length); |
537 | } | 537 | } |
538 | 538 | ||
539 | static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino) | 539 | static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino) |
540 | { | 540 | { |
541 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); | 541 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); |
542 | struct buffer_head *bh; | 542 | struct buffer_head *bh; |
543 | struct gfs2_inum_range_host ir; | 543 | struct gfs2_inum_range_host ir; |
544 | int error; | 544 | int error; |
545 | 545 | ||
546 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); | 546 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); |
547 | if (error) | 547 | if (error) |
548 | return error; | 548 | return error; |
549 | mutex_lock(&sdp->sd_inum_mutex); | 549 | mutex_lock(&sdp->sd_inum_mutex); |
550 | 550 | ||
551 | error = gfs2_meta_inode_buffer(ip, &bh); | 551 | error = gfs2_meta_inode_buffer(ip, &bh); |
552 | if (error) { | 552 | if (error) { |
553 | mutex_unlock(&sdp->sd_inum_mutex); | 553 | mutex_unlock(&sdp->sd_inum_mutex); |
554 | gfs2_trans_end(sdp); | 554 | gfs2_trans_end(sdp); |
555 | return error; | 555 | return error; |
556 | } | 556 | } |
557 | 557 | ||
558 | gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode)); | 558 | gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode)); |
559 | 559 | ||
560 | if (ir.ir_length) { | 560 | if (ir.ir_length) { |
561 | *formal_ino = ir.ir_start++; | 561 | *formal_ino = ir.ir_start++; |
562 | ir.ir_length--; | 562 | ir.ir_length--; |
563 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 563 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
564 | gfs2_inum_range_out(&ir, | 564 | gfs2_inum_range_out(&ir, |
565 | bh->b_data + sizeof(struct gfs2_dinode)); | 565 | bh->b_data + sizeof(struct gfs2_dinode)); |
566 | brelse(bh); | 566 | brelse(bh); |
567 | mutex_unlock(&sdp->sd_inum_mutex); | 567 | mutex_unlock(&sdp->sd_inum_mutex); |
568 | gfs2_trans_end(sdp); | 568 | gfs2_trans_end(sdp); |
569 | return 0; | 569 | return 0; |
570 | } | 570 | } |
571 | 571 | ||
572 | brelse(bh); | 572 | brelse(bh); |
573 | 573 | ||
574 | mutex_unlock(&sdp->sd_inum_mutex); | 574 | mutex_unlock(&sdp->sd_inum_mutex); |
575 | gfs2_trans_end(sdp); | 575 | gfs2_trans_end(sdp); |
576 | 576 | ||
577 | return 1; | 577 | return 1; |
578 | } | 578 | } |
579 | 579 | ||
580 | static int pick_formal_ino_2(struct gfs2_sbd *sdp, u64 *formal_ino) | 580 | static int pick_formal_ino_2(struct gfs2_sbd *sdp, u64 *formal_ino) |
581 | { | 581 | { |
582 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); | 582 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); |
583 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode); | 583 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode); |
584 | struct gfs2_holder gh; | 584 | struct gfs2_holder gh; |
585 | struct buffer_head *bh; | 585 | struct buffer_head *bh; |
586 | struct gfs2_inum_range_host ir; | 586 | struct gfs2_inum_range_host ir; |
587 | int error; | 587 | int error; |
588 | 588 | ||
589 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 589 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
590 | if (error) | 590 | if (error) |
591 | return error; | 591 | return error; |
592 | 592 | ||
593 | error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0); | 593 | error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0); |
594 | if (error) | 594 | if (error) |
595 | goto out; | 595 | goto out; |
596 | mutex_lock(&sdp->sd_inum_mutex); | 596 | mutex_lock(&sdp->sd_inum_mutex); |
597 | 597 | ||
598 | error = gfs2_meta_inode_buffer(ip, &bh); | 598 | error = gfs2_meta_inode_buffer(ip, &bh); |
599 | if (error) | 599 | if (error) |
600 | goto out_end_trans; | 600 | goto out_end_trans; |
601 | 601 | ||
602 | gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode)); | 602 | gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode)); |
603 | 603 | ||
604 | if (!ir.ir_length) { | 604 | if (!ir.ir_length) { |
605 | struct buffer_head *m_bh; | 605 | struct buffer_head *m_bh; |
606 | u64 x, y; | 606 | u64 x, y; |
607 | __be64 z; | 607 | __be64 z; |
608 | 608 | ||
609 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); | 609 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); |
610 | if (error) | 610 | if (error) |
611 | goto out_brelse; | 611 | goto out_brelse; |
612 | 612 | ||
613 | z = *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)); | 613 | z = *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)); |
614 | x = y = be64_to_cpu(z); | 614 | x = y = be64_to_cpu(z); |
615 | ir.ir_start = x; | 615 | ir.ir_start = x; |
616 | ir.ir_length = GFS2_INUM_QUANTUM; | 616 | ir.ir_length = GFS2_INUM_QUANTUM; |
617 | x += GFS2_INUM_QUANTUM; | 617 | x += GFS2_INUM_QUANTUM; |
618 | if (x < y) | 618 | if (x < y) |
619 | gfs2_consist_inode(m_ip); | 619 | gfs2_consist_inode(m_ip); |
620 | z = cpu_to_be64(x); | 620 | z = cpu_to_be64(x); |
621 | gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); | 621 | gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); |
622 | *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = z; | 622 | *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = z; |
623 | 623 | ||
624 | brelse(m_bh); | 624 | brelse(m_bh); |
625 | } | 625 | } |
626 | 626 | ||
627 | *formal_ino = ir.ir_start++; | 627 | *formal_ino = ir.ir_start++; |
628 | ir.ir_length--; | 628 | ir.ir_length--; |
629 | 629 | ||
630 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 630 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
631 | gfs2_inum_range_out(&ir, bh->b_data + sizeof(struct gfs2_dinode)); | 631 | gfs2_inum_range_out(&ir, bh->b_data + sizeof(struct gfs2_dinode)); |
632 | 632 | ||
633 | out_brelse: | 633 | out_brelse: |
634 | brelse(bh); | 634 | brelse(bh); |
635 | out_end_trans: | 635 | out_end_trans: |
636 | mutex_unlock(&sdp->sd_inum_mutex); | 636 | mutex_unlock(&sdp->sd_inum_mutex); |
637 | gfs2_trans_end(sdp); | 637 | gfs2_trans_end(sdp); |
638 | out: | 638 | out: |
639 | gfs2_glock_dq_uninit(&gh); | 639 | gfs2_glock_dq_uninit(&gh); |
640 | return error; | 640 | return error; |
641 | } | 641 | } |
642 | 642 | ||
643 | static int pick_formal_ino(struct gfs2_sbd *sdp, u64 *inum) | 643 | static int pick_formal_ino(struct gfs2_sbd *sdp, u64 *inum) |
644 | { | 644 | { |
645 | int error; | 645 | int error; |
646 | 646 | ||
647 | error = pick_formal_ino_1(sdp, inum); | 647 | error = pick_formal_ino_1(sdp, inum); |
648 | if (error <= 0) | 648 | if (error <= 0) |
649 | return error; | 649 | return error; |
650 | 650 | ||
651 | error = pick_formal_ino_2(sdp, inum); | 651 | error = pick_formal_ino_2(sdp, inum); |
652 | 652 | ||
653 | return error; | 653 | return error; |
654 | } | 654 | } |
655 | 655 | ||
656 | /** | 656 | /** |
657 | * create_ok - OK to create a new on-disk inode here? | 657 | * create_ok - OK to create a new on-disk inode here? |
658 | * @dip: Directory in which dinode is to be created | 658 | * @dip: Directory in which dinode is to be created |
659 | * @name: Name of new dinode | 659 | * @name: Name of new dinode |
660 | * @mode: | 660 | * @mode: |
661 | * | 661 | * |
662 | * Returns: errno | 662 | * Returns: errno |
663 | */ | 663 | */ |
664 | 664 | ||
665 | static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | 665 | static int create_ok(struct gfs2_inode *dip, const struct qstr *name, |
666 | unsigned int mode) | 666 | unsigned int mode) |
667 | { | 667 | { |
668 | int error; | 668 | int error; |
669 | 669 | ||
670 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); | 670 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); |
671 | if (error) | 671 | if (error) |
672 | return error; | 672 | return error; |
673 | 673 | ||
674 | /* Don't create entries in an unlinked directory */ | 674 | /* Don't create entries in an unlinked directory */ |
675 | if (!dip->i_inode.i_nlink) | 675 | if (!dip->i_inode.i_nlink) |
676 | return -EPERM; | 676 | return -EPERM; |
677 | 677 | ||
678 | error = gfs2_dir_check(&dip->i_inode, name, NULL); | 678 | error = gfs2_dir_check(&dip->i_inode, name, NULL); |
679 | switch (error) { | 679 | switch (error) { |
680 | case -ENOENT: | 680 | case -ENOENT: |
681 | error = 0; | 681 | error = 0; |
682 | break; | 682 | break; |
683 | case 0: | 683 | case 0: |
684 | return -EEXIST; | 684 | return -EEXIST; |
685 | default: | 685 | default: |
686 | return error; | 686 | return error; |
687 | } | 687 | } |
688 | 688 | ||
689 | if (dip->i_di.di_entries == (u32)-1) | 689 | if (dip->i_di.di_entries == (u32)-1) |
690 | return -EFBIG; | 690 | return -EFBIG; |
691 | if (S_ISDIR(mode) && dip->i_inode.i_nlink == (u32)-1) | 691 | if (S_ISDIR(mode) && dip->i_inode.i_nlink == (u32)-1) |
692 | return -EMLINK; | 692 | return -EMLINK; |
693 | 693 | ||
694 | return 0; | 694 | return 0; |
695 | } | 695 | } |
696 | 696 | ||
697 | static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode, | 697 | static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode, |
698 | unsigned int *uid, unsigned int *gid) | 698 | unsigned int *uid, unsigned int *gid) |
699 | { | 699 | { |
700 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && | 700 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && |
701 | (dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) { | 701 | (dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) { |
702 | if (S_ISDIR(*mode)) | 702 | if (S_ISDIR(*mode)) |
703 | *mode |= S_ISUID; | 703 | *mode |= S_ISUID; |
704 | else if (dip->i_inode.i_uid != current->fsuid) | 704 | else if (dip->i_inode.i_uid != current->fsuid) |
705 | *mode &= ~07111; | 705 | *mode &= ~07111; |
706 | *uid = dip->i_inode.i_uid; | 706 | *uid = dip->i_inode.i_uid; |
707 | } else | 707 | } else |
708 | *uid = current->fsuid; | 708 | *uid = current->fsuid; |
709 | 709 | ||
710 | if (dip->i_inode.i_mode & S_ISGID) { | 710 | if (dip->i_inode.i_mode & S_ISGID) { |
711 | if (S_ISDIR(*mode)) | 711 | if (S_ISDIR(*mode)) |
712 | *mode |= S_ISGID; | 712 | *mode |= S_ISGID; |
713 | *gid = dip->i_inode.i_gid; | 713 | *gid = dip->i_inode.i_gid; |
714 | } else | 714 | } else |
715 | *gid = current->fsgid; | 715 | *gid = current->fsgid; |
716 | } | 716 | } |
717 | 717 | ||
718 | static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation) | 718 | static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation) |
719 | { | 719 | { |
720 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 720 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
721 | int error; | 721 | int error; |
722 | 722 | ||
723 | if (gfs2_alloc_get(dip) == NULL) | 723 | if (gfs2_alloc_get(dip) == NULL) |
724 | return -ENOMEM; | 724 | return -ENOMEM; |
725 | 725 | ||
726 | dip->i_alloc->al_requested = RES_DINODE; | 726 | dip->i_alloc->al_requested = RES_DINODE; |
727 | error = gfs2_inplace_reserve(dip); | 727 | error = gfs2_inplace_reserve(dip); |
728 | if (error) | 728 | if (error) |
729 | goto out; | 729 | goto out; |
730 | 730 | ||
731 | error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS, 0); | 731 | error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS, 0); |
732 | if (error) | 732 | if (error) |
733 | goto out_ipreserv; | 733 | goto out_ipreserv; |
734 | 734 | ||
735 | *no_addr = gfs2_alloc_di(dip, generation); | 735 | *no_addr = gfs2_alloc_di(dip, generation); |
736 | 736 | ||
737 | gfs2_trans_end(sdp); | 737 | gfs2_trans_end(sdp); |
738 | 738 | ||
739 | out_ipreserv: | 739 | out_ipreserv: |
740 | gfs2_inplace_release(dip); | 740 | gfs2_inplace_release(dip); |
741 | out: | 741 | out: |
742 | gfs2_alloc_put(dip); | 742 | gfs2_alloc_put(dip); |
743 | return error; | 743 | return error; |
744 | } | 744 | } |
745 | 745 | ||
746 | /** | 746 | /** |
747 | * init_dinode - Fill in a new dinode structure | 747 | * init_dinode - Fill in a new dinode structure |
748 | * @dip: the directory this inode is being created in | 748 | * @dip: the directory this inode is being created in |
749 | * @gl: The glock covering the new inode | 749 | * @gl: The glock covering the new inode |
750 | * @inum: the inode number | 750 | * @inum: the inode number |
751 | * @mode: the file permissions | 751 | * @mode: the file permissions |
752 | * @uid: | 752 | * @uid: |
753 | * @gid: | 753 | * @gid: |
754 | * | 754 | * |
755 | */ | 755 | */ |
756 | 756 | ||
757 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 757 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, |
758 | const struct gfs2_inum_host *inum, unsigned int mode, | 758 | const struct gfs2_inum_host *inum, unsigned int mode, |
759 | unsigned int uid, unsigned int gid, | 759 | unsigned int uid, unsigned int gid, |
760 | const u64 *generation, dev_t dev, struct buffer_head **bhp) | 760 | const u64 *generation, dev_t dev, struct buffer_head **bhp) |
761 | { | 761 | { |
762 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 762 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
763 | struct gfs2_dinode *di; | 763 | struct gfs2_dinode *di; |
764 | struct buffer_head *dibh; | 764 | struct buffer_head *dibh; |
765 | struct timespec tv = CURRENT_TIME; | 765 | struct timespec tv = CURRENT_TIME; |
766 | 766 | ||
767 | dibh = gfs2_meta_new(gl, inum->no_addr); | 767 | dibh = gfs2_meta_new(gl, inum->no_addr); |
768 | gfs2_trans_add_bh(gl, dibh, 1); | 768 | gfs2_trans_add_bh(gl, dibh, 1); |
769 | gfs2_metatype_set(dibh, GFS2_METATYPE_DI, GFS2_FORMAT_DI); | 769 | gfs2_metatype_set(dibh, GFS2_METATYPE_DI, GFS2_FORMAT_DI); |
770 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | 770 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); |
771 | di = (struct gfs2_dinode *)dibh->b_data; | 771 | di = (struct gfs2_dinode *)dibh->b_data; |
772 | 772 | ||
773 | di->di_num.no_formal_ino = cpu_to_be64(inum->no_formal_ino); | 773 | di->di_num.no_formal_ino = cpu_to_be64(inum->no_formal_ino); |
774 | di->di_num.no_addr = cpu_to_be64(inum->no_addr); | 774 | di->di_num.no_addr = cpu_to_be64(inum->no_addr); |
775 | di->di_mode = cpu_to_be32(mode); | 775 | di->di_mode = cpu_to_be32(mode); |
776 | di->di_uid = cpu_to_be32(uid); | 776 | di->di_uid = cpu_to_be32(uid); |
777 | di->di_gid = cpu_to_be32(gid); | 777 | di->di_gid = cpu_to_be32(gid); |
778 | di->di_nlink = 0; | 778 | di->di_nlink = 0; |
779 | di->di_size = 0; | 779 | di->di_size = 0; |
780 | di->di_blocks = cpu_to_be64(1); | 780 | di->di_blocks = cpu_to_be64(1); |
781 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); | 781 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); |
782 | di->di_major = cpu_to_be32(MAJOR(dev)); | 782 | di->di_major = cpu_to_be32(MAJOR(dev)); |
783 | di->di_minor = cpu_to_be32(MINOR(dev)); | 783 | di->di_minor = cpu_to_be32(MINOR(dev)); |
784 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); | 784 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); |
785 | di->di_generation = cpu_to_be64(*generation); | 785 | di->di_generation = cpu_to_be64(*generation); |
786 | di->di_flags = 0; | 786 | di->di_flags = 0; |
787 | 787 | ||
788 | if (S_ISREG(mode)) { | 788 | if (S_ISREG(mode)) { |
789 | if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA) || | 789 | if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA) || |
790 | gfs2_tune_get(sdp, gt_new_files_jdata)) | 790 | gfs2_tune_get(sdp, gt_new_files_jdata)) |
791 | di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); | 791 | di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); |
792 | if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_DIRECTIO) || | ||
793 | gfs2_tune_get(sdp, gt_new_files_directio)) | ||
794 | di->di_flags |= cpu_to_be32(GFS2_DIF_DIRECTIO); | ||
795 | } else if (S_ISDIR(mode)) { | 792 | } else if (S_ISDIR(mode)) { |
796 | di->di_flags |= cpu_to_be32(dip->i_di.di_flags & | ||
797 | GFS2_DIF_INHERIT_DIRECTIO); | ||
798 | di->di_flags |= cpu_to_be32(dip->i_di.di_flags & | 793 | di->di_flags |= cpu_to_be32(dip->i_di.di_flags & |
799 | GFS2_DIF_INHERIT_JDATA); | 794 | GFS2_DIF_INHERIT_JDATA); |
800 | } | 795 | } |
801 | 796 | ||
802 | di->__pad1 = 0; | 797 | di->__pad1 = 0; |
803 | di->di_payload_format = cpu_to_be32(S_ISDIR(mode) ? GFS2_FORMAT_DE : 0); | 798 | di->di_payload_format = cpu_to_be32(S_ISDIR(mode) ? GFS2_FORMAT_DE : 0); |
804 | di->di_height = 0; | 799 | di->di_height = 0; |
805 | di->__pad2 = 0; | 800 | di->__pad2 = 0; |
806 | di->__pad3 = 0; | 801 | di->__pad3 = 0; |
807 | di->di_depth = 0; | 802 | di->di_depth = 0; |
808 | di->di_entries = 0; | 803 | di->di_entries = 0; |
809 | memset(&di->__pad4, 0, sizeof(di->__pad4)); | 804 | memset(&di->__pad4, 0, sizeof(di->__pad4)); |
810 | di->di_eattr = 0; | 805 | di->di_eattr = 0; |
811 | di->di_atime_nsec = cpu_to_be32(tv.tv_nsec); | 806 | di->di_atime_nsec = cpu_to_be32(tv.tv_nsec); |
812 | di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec); | 807 | di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec); |
813 | di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); | 808 | di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); |
814 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); | 809 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); |
815 | 810 | ||
816 | set_buffer_uptodate(dibh); | 811 | set_buffer_uptodate(dibh); |
817 | 812 | ||
818 | *bhp = dibh; | 813 | *bhp = dibh; |
819 | } | 814 | } |
820 | 815 | ||
821 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 816 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, |
822 | unsigned int mode, const struct gfs2_inum_host *inum, | 817 | unsigned int mode, const struct gfs2_inum_host *inum, |
823 | const u64 *generation, dev_t dev, struct buffer_head **bhp) | 818 | const u64 *generation, dev_t dev, struct buffer_head **bhp) |
824 | { | 819 | { |
825 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 820 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
826 | unsigned int uid, gid; | 821 | unsigned int uid, gid; |
827 | int error; | 822 | int error; |
828 | 823 | ||
829 | munge_mode_uid_gid(dip, &mode, &uid, &gid); | 824 | munge_mode_uid_gid(dip, &mode, &uid, &gid); |
830 | if (!gfs2_alloc_get(dip)) | 825 | if (!gfs2_alloc_get(dip)) |
831 | return -ENOMEM; | 826 | return -ENOMEM; |
832 | 827 | ||
833 | error = gfs2_quota_lock(dip, uid, gid); | 828 | error = gfs2_quota_lock(dip, uid, gid); |
834 | if (error) | 829 | if (error) |
835 | goto out; | 830 | goto out; |
836 | 831 | ||
837 | error = gfs2_quota_check(dip, uid, gid); | 832 | error = gfs2_quota_check(dip, uid, gid); |
838 | if (error) | 833 | if (error) |
839 | goto out_quota; | 834 | goto out_quota; |
840 | 835 | ||
841 | error = gfs2_trans_begin(sdp, RES_DINODE + RES_QUOTA, 0); | 836 | error = gfs2_trans_begin(sdp, RES_DINODE + RES_QUOTA, 0); |
842 | if (error) | 837 | if (error) |
843 | goto out_quota; | 838 | goto out_quota; |
844 | 839 | ||
845 | init_dinode(dip, gl, inum, mode, uid, gid, generation, dev, bhp); | 840 | init_dinode(dip, gl, inum, mode, uid, gid, generation, dev, bhp); |
846 | gfs2_quota_change(dip, +1, uid, gid); | 841 | gfs2_quota_change(dip, +1, uid, gid); |
847 | gfs2_trans_end(sdp); | 842 | gfs2_trans_end(sdp); |
848 | 843 | ||
849 | out_quota: | 844 | out_quota: |
850 | gfs2_quota_unlock(dip); | 845 | gfs2_quota_unlock(dip); |
851 | out: | 846 | out: |
852 | gfs2_alloc_put(dip); | 847 | gfs2_alloc_put(dip); |
853 | return error; | 848 | return error; |
854 | } | 849 | } |
855 | 850 | ||
856 | static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | 851 | static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, |
857 | struct gfs2_inode *ip) | 852 | struct gfs2_inode *ip) |
858 | { | 853 | { |
859 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 854 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
860 | struct gfs2_alloc *al; | 855 | struct gfs2_alloc *al; |
861 | int alloc_required; | 856 | int alloc_required; |
862 | struct buffer_head *dibh; | 857 | struct buffer_head *dibh; |
863 | int error; | 858 | int error; |
864 | 859 | ||
865 | al = gfs2_alloc_get(dip); | 860 | al = gfs2_alloc_get(dip); |
866 | if (!al) | 861 | if (!al) |
867 | return -ENOMEM; | 862 | return -ENOMEM; |
868 | 863 | ||
869 | error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 864 | error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); |
870 | if (error) | 865 | if (error) |
871 | goto fail; | 866 | goto fail; |
872 | 867 | ||
873 | error = alloc_required = gfs2_diradd_alloc_required(&dip->i_inode, name); | 868 | error = alloc_required = gfs2_diradd_alloc_required(&dip->i_inode, name); |
874 | if (alloc_required < 0) | 869 | if (alloc_required < 0) |
875 | goto fail_quota_locks; | 870 | goto fail_quota_locks; |
876 | if (alloc_required) { | 871 | if (alloc_required) { |
877 | error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid); | 872 | error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid); |
878 | if (error) | 873 | if (error) |
879 | goto fail_quota_locks; | 874 | goto fail_quota_locks; |
880 | 875 | ||
881 | al->al_requested = sdp->sd_max_dirres; | 876 | al->al_requested = sdp->sd_max_dirres; |
882 | 877 | ||
883 | error = gfs2_inplace_reserve(dip); | 878 | error = gfs2_inplace_reserve(dip); |
884 | if (error) | 879 | if (error) |
885 | goto fail_quota_locks; | 880 | goto fail_quota_locks; |
886 | 881 | ||
887 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + | 882 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + |
888 | al->al_rgd->rd_length + | 883 | al->al_rgd->rd_length + |
889 | 2 * RES_DINODE + | 884 | 2 * RES_DINODE + |
890 | RES_STATFS + RES_QUOTA, 0); | 885 | RES_STATFS + RES_QUOTA, 0); |
891 | if (error) | 886 | if (error) |
892 | goto fail_ipreserv; | 887 | goto fail_ipreserv; |
893 | } else { | 888 | } else { |
894 | error = gfs2_trans_begin(sdp, RES_LEAF + 2 * RES_DINODE, 0); | 889 | error = gfs2_trans_begin(sdp, RES_LEAF + 2 * RES_DINODE, 0); |
895 | if (error) | 890 | if (error) |
896 | goto fail_quota_locks; | 891 | goto fail_quota_locks; |
897 | } | 892 | } |
898 | 893 | ||
899 | error = gfs2_dir_add(&dip->i_inode, name, ip, IF2DT(ip->i_inode.i_mode)); | 894 | error = gfs2_dir_add(&dip->i_inode, name, ip, IF2DT(ip->i_inode.i_mode)); |
900 | if (error) | 895 | if (error) |
901 | goto fail_end_trans; | 896 | goto fail_end_trans; |
902 | 897 | ||
903 | error = gfs2_meta_inode_buffer(ip, &dibh); | 898 | error = gfs2_meta_inode_buffer(ip, &dibh); |
904 | if (error) | 899 | if (error) |
905 | goto fail_end_trans; | 900 | goto fail_end_trans; |
906 | ip->i_inode.i_nlink = 1; | 901 | ip->i_inode.i_nlink = 1; |
907 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 902 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
908 | gfs2_dinode_out(ip, dibh->b_data); | 903 | gfs2_dinode_out(ip, dibh->b_data); |
909 | brelse(dibh); | 904 | brelse(dibh); |
910 | return 0; | 905 | return 0; |
911 | 906 | ||
912 | fail_end_trans: | 907 | fail_end_trans: |
913 | gfs2_trans_end(sdp); | 908 | gfs2_trans_end(sdp); |
914 | 909 | ||
915 | fail_ipreserv: | 910 | fail_ipreserv: |
916 | if (dip->i_alloc->al_rgd) | 911 | if (dip->i_alloc->al_rgd) |
917 | gfs2_inplace_release(dip); | 912 | gfs2_inplace_release(dip); |
918 | 913 | ||
919 | fail_quota_locks: | 914 | fail_quota_locks: |
920 | gfs2_quota_unlock(dip); | 915 | gfs2_quota_unlock(dip); |
921 | 916 | ||
922 | fail: | 917 | fail: |
923 | gfs2_alloc_put(dip); | 918 | gfs2_alloc_put(dip); |
924 | return error; | 919 | return error; |
925 | } | 920 | } |
926 | 921 | ||
927 | static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip) | 922 | static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip) |
928 | { | 923 | { |
929 | int err; | 924 | int err; |
930 | size_t len; | 925 | size_t len; |
931 | void *value; | 926 | void *value; |
932 | char *name; | 927 | char *name; |
933 | struct gfs2_ea_request er; | 928 | struct gfs2_ea_request er; |
934 | 929 | ||
935 | err = security_inode_init_security(&ip->i_inode, &dip->i_inode, | 930 | err = security_inode_init_security(&ip->i_inode, &dip->i_inode, |
936 | &name, &value, &len); | 931 | &name, &value, &len); |
937 | 932 | ||
938 | if (err) { | 933 | if (err) { |
939 | if (err == -EOPNOTSUPP) | 934 | if (err == -EOPNOTSUPP) |
940 | return 0; | 935 | return 0; |
941 | return err; | 936 | return err; |
942 | } | 937 | } |
943 | 938 | ||
944 | memset(&er, 0, sizeof(struct gfs2_ea_request)); | 939 | memset(&er, 0, sizeof(struct gfs2_ea_request)); |
945 | 940 | ||
946 | er.er_type = GFS2_EATYPE_SECURITY; | 941 | er.er_type = GFS2_EATYPE_SECURITY; |
947 | er.er_name = name; | 942 | er.er_name = name; |
948 | er.er_data = value; | 943 | er.er_data = value; |
949 | er.er_name_len = strlen(name); | 944 | er.er_name_len = strlen(name); |
950 | er.er_data_len = len; | 945 | er.er_data_len = len; |
951 | 946 | ||
952 | err = gfs2_ea_set_i(ip, &er); | 947 | err = gfs2_ea_set_i(ip, &er); |
953 | 948 | ||
954 | kfree(value); | 949 | kfree(value); |
955 | kfree(name); | 950 | kfree(name); |
956 | 951 | ||
957 | return err; | 952 | return err; |
958 | } | 953 | } |
959 | 954 | ||
960 | /** | 955 | /** |
961 | * gfs2_createi - Create a new inode | 956 | * gfs2_createi - Create a new inode |
962 | * @ghs: An array of two holders | 957 | * @ghs: An array of two holders |
963 | * @name: The name of the new file | 958 | * @name: The name of the new file |
964 | * @mode: the permissions on the new inode | 959 | * @mode: the permissions on the new inode |
965 | * | 960 | * |
966 | * @ghs[0] is an initialized holder for the directory | 961 | * @ghs[0] is an initialized holder for the directory |
967 | * @ghs[1] is the holder for the inode lock | 962 | * @ghs[1] is the holder for the inode lock |
968 | * | 963 | * |
969 | * If the return value is not NULL, the glocks on both the directory and the new | 964 | * If the return value is not NULL, the glocks on both the directory and the new |
970 | * file are held. A transaction has been started and an inplace reservation | 965 | * file are held. A transaction has been started and an inplace reservation |
971 | * is held, as well. | 966 | * is held, as well. |
972 | * | 967 | * |
973 | * Returns: An inode | 968 | * Returns: An inode |
974 | */ | 969 | */ |
975 | 970 | ||
976 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | 971 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, |
977 | unsigned int mode, dev_t dev) | 972 | unsigned int mode, dev_t dev) |
978 | { | 973 | { |
979 | struct inode *inode = NULL; | 974 | struct inode *inode = NULL; |
980 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; | 975 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; |
981 | struct inode *dir = &dip->i_inode; | 976 | struct inode *dir = &dip->i_inode; |
982 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 977 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
983 | struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; | 978 | struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; |
984 | int error; | 979 | int error; |
985 | u64 generation; | 980 | u64 generation; |
986 | struct buffer_head *bh = NULL; | 981 | struct buffer_head *bh = NULL; |
987 | 982 | ||
988 | if (!name->len || name->len > GFS2_FNAMESIZE) | 983 | if (!name->len || name->len > GFS2_FNAMESIZE) |
989 | return ERR_PTR(-ENAMETOOLONG); | 984 | return ERR_PTR(-ENAMETOOLONG); |
990 | 985 | ||
991 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs); | 986 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs); |
992 | error = gfs2_glock_nq(ghs); | 987 | error = gfs2_glock_nq(ghs); |
993 | if (error) | 988 | if (error) |
994 | goto fail; | 989 | goto fail; |
995 | 990 | ||
996 | error = create_ok(dip, name, mode); | 991 | error = create_ok(dip, name, mode); |
997 | if (error) | 992 | if (error) |
998 | goto fail_gunlock; | 993 | goto fail_gunlock; |
999 | 994 | ||
1000 | error = pick_formal_ino(sdp, &inum.no_formal_ino); | 995 | error = pick_formal_ino(sdp, &inum.no_formal_ino); |
1001 | if (error) | 996 | if (error) |
1002 | goto fail_gunlock; | 997 | goto fail_gunlock; |
1003 | 998 | ||
1004 | error = alloc_dinode(dip, &inum.no_addr, &generation); | 999 | error = alloc_dinode(dip, &inum.no_addr, &generation); |
1005 | if (error) | 1000 | if (error) |
1006 | goto fail_gunlock; | 1001 | goto fail_gunlock; |
1007 | 1002 | ||
1008 | error = gfs2_glock_nq_num(sdp, inum.no_addr, &gfs2_inode_glops, | 1003 | error = gfs2_glock_nq_num(sdp, inum.no_addr, &gfs2_inode_glops, |
1009 | LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); | 1004 | LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); |
1010 | if (error) | 1005 | if (error) |
1011 | goto fail_gunlock; | 1006 | goto fail_gunlock; |
1012 | 1007 | ||
1013 | error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev, &bh); | 1008 | error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev, &bh); |
1014 | if (error) | 1009 | if (error) |
1015 | goto fail_gunlock2; | 1010 | goto fail_gunlock2; |
1016 | 1011 | ||
1017 | inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), | 1012 | inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), |
1018 | inum.no_addr, | 1013 | inum.no_addr, |
1019 | inum.no_formal_ino, 0); | 1014 | inum.no_formal_ino, 0); |
1020 | if (IS_ERR(inode)) | 1015 | if (IS_ERR(inode)) |
1021 | goto fail_gunlock2; | 1016 | goto fail_gunlock2; |
1022 | 1017 | ||
1023 | error = gfs2_inode_refresh(GFS2_I(inode)); | 1018 | error = gfs2_inode_refresh(GFS2_I(inode)); |
1024 | if (error) | 1019 | if (error) |
1025 | goto fail_gunlock2; | 1020 | goto fail_gunlock2; |
1026 | 1021 | ||
1027 | error = gfs2_acl_create(dip, GFS2_I(inode)); | 1022 | error = gfs2_acl_create(dip, GFS2_I(inode)); |
1028 | if (error) | 1023 | if (error) |
1029 | goto fail_gunlock2; | 1024 | goto fail_gunlock2; |
1030 | 1025 | ||
1031 | error = gfs2_security_init(dip, GFS2_I(inode)); | 1026 | error = gfs2_security_init(dip, GFS2_I(inode)); |
1032 | if (error) | 1027 | if (error) |
1033 | goto fail_gunlock2; | 1028 | goto fail_gunlock2; |
1034 | 1029 | ||
1035 | error = link_dinode(dip, name, GFS2_I(inode)); | 1030 | error = link_dinode(dip, name, GFS2_I(inode)); |
1036 | if (error) | 1031 | if (error) |
1037 | goto fail_gunlock2; | 1032 | goto fail_gunlock2; |
1038 | 1033 | ||
1039 | if (bh) | 1034 | if (bh) |
1040 | brelse(bh); | 1035 | brelse(bh); |
1041 | if (!inode) | 1036 | if (!inode) |
1042 | return ERR_PTR(-ENOMEM); | 1037 | return ERR_PTR(-ENOMEM); |
1043 | return inode; | 1038 | return inode; |
1044 | 1039 | ||
1045 | fail_gunlock2: | 1040 | fail_gunlock2: |
1046 | gfs2_glock_dq_uninit(ghs + 1); | 1041 | gfs2_glock_dq_uninit(ghs + 1); |
1047 | if (inode) | 1042 | if (inode) |
1048 | iput(inode); | 1043 | iput(inode); |
1049 | fail_gunlock: | 1044 | fail_gunlock: |
1050 | gfs2_glock_dq(ghs); | 1045 | gfs2_glock_dq(ghs); |
1051 | fail: | 1046 | fail: |
1052 | if (bh) | 1047 | if (bh) |
1053 | brelse(bh); | 1048 | brelse(bh); |
1054 | return ERR_PTR(error); | 1049 | return ERR_PTR(error); |
1055 | } | 1050 | } |
1056 | 1051 | ||
1057 | /** | 1052 | /** |
1058 | * gfs2_rmdiri - Remove a directory | 1053 | * gfs2_rmdiri - Remove a directory |
1059 | * @dip: The parent directory of the directory to be removed | 1054 | * @dip: The parent directory of the directory to be removed |
1060 | * @name: The name of the directory to be removed | 1055 | * @name: The name of the directory to be removed |
1061 | * @ip: The GFS2 inode of the directory to be removed | 1056 | * @ip: The GFS2 inode of the directory to be removed |
1062 | * | 1057 | * |
1063 | * Assumes Glocks on dip and ip are held | 1058 | * Assumes Glocks on dip and ip are held |
1064 | * | 1059 | * |
1065 | * Returns: errno | 1060 | * Returns: errno |
1066 | */ | 1061 | */ |
1067 | 1062 | ||
1068 | int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | 1063 | int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, |
1069 | struct gfs2_inode *ip) | 1064 | struct gfs2_inode *ip) |
1070 | { | 1065 | { |
1071 | struct qstr dotname; | 1066 | struct qstr dotname; |
1072 | int error; | 1067 | int error; |
1073 | 1068 | ||
1074 | if (ip->i_di.di_entries != 2) { | 1069 | if (ip->i_di.di_entries != 2) { |
1075 | if (gfs2_consist_inode(ip)) | 1070 | if (gfs2_consist_inode(ip)) |
1076 | gfs2_dinode_print(ip); | 1071 | gfs2_dinode_print(ip); |
1077 | return -EIO; | 1072 | return -EIO; |
1078 | } | 1073 | } |
1079 | 1074 | ||
1080 | error = gfs2_dir_del(dip, name); | 1075 | error = gfs2_dir_del(dip, name); |
1081 | if (error) | 1076 | if (error) |
1082 | return error; | 1077 | return error; |
1083 | 1078 | ||
1084 | error = gfs2_change_nlink(dip, -1); | 1079 | error = gfs2_change_nlink(dip, -1); |
1085 | if (error) | 1080 | if (error) |
1086 | return error; | 1081 | return error; |
1087 | 1082 | ||
1088 | gfs2_str2qstr(&dotname, "."); | 1083 | gfs2_str2qstr(&dotname, "."); |
1089 | error = gfs2_dir_del(ip, &dotname); | 1084 | error = gfs2_dir_del(ip, &dotname); |
1090 | if (error) | 1085 | if (error) |
1091 | return error; | 1086 | return error; |
1092 | 1087 | ||
1093 | gfs2_str2qstr(&dotname, ".."); | 1088 | gfs2_str2qstr(&dotname, ".."); |
1094 | error = gfs2_dir_del(ip, &dotname); | 1089 | error = gfs2_dir_del(ip, &dotname); |
1095 | if (error) | 1090 | if (error) |
1096 | return error; | 1091 | return error; |
1097 | 1092 | ||
1098 | /* It looks odd, but it really should be done twice */ | 1093 | /* It looks odd, but it really should be done twice */ |
1099 | error = gfs2_change_nlink(ip, -1); | 1094 | error = gfs2_change_nlink(ip, -1); |
1100 | if (error) | 1095 | if (error) |
1101 | return error; | 1096 | return error; |
1102 | 1097 | ||
1103 | error = gfs2_change_nlink(ip, -1); | 1098 | error = gfs2_change_nlink(ip, -1); |
1104 | if (error) | 1099 | if (error) |
1105 | return error; | 1100 | return error; |
1106 | 1101 | ||
1107 | return error; | 1102 | return error; |
1108 | } | 1103 | } |
1109 | 1104 | ||
1110 | /* | 1105 | /* |
1111 | * gfs2_unlink_ok - check to see that a inode is still in a directory | 1106 | * gfs2_unlink_ok - check to see that a inode is still in a directory |
1112 | * @dip: the directory | 1107 | * @dip: the directory |
1113 | * @name: the name of the file | 1108 | * @name: the name of the file |
1114 | * @ip: the inode | 1109 | * @ip: the inode |
1115 | * | 1110 | * |
1116 | * Assumes that the lock on (at least) @dip is held. | 1111 | * Assumes that the lock on (at least) @dip is held. |
1117 | * | 1112 | * |
1118 | * Returns: 0 if the parent/child relationship is correct, errno if it isn't | 1113 | * Returns: 0 if the parent/child relationship is correct, errno if it isn't |
1119 | */ | 1114 | */ |
1120 | 1115 | ||
1121 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | 1116 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, |
1122 | const struct gfs2_inode *ip) | 1117 | const struct gfs2_inode *ip) |
1123 | { | 1118 | { |
1124 | int error; | 1119 | int error; |
1125 | 1120 | ||
1126 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | 1121 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) |
1127 | return -EPERM; | 1122 | return -EPERM; |
1128 | 1123 | ||
1129 | if ((dip->i_inode.i_mode & S_ISVTX) && | 1124 | if ((dip->i_inode.i_mode & S_ISVTX) && |
1130 | dip->i_inode.i_uid != current->fsuid && | 1125 | dip->i_inode.i_uid != current->fsuid && |
1131 | ip->i_inode.i_uid != current->fsuid && !capable(CAP_FOWNER)) | 1126 | ip->i_inode.i_uid != current->fsuid && !capable(CAP_FOWNER)) |
1132 | return -EPERM; | 1127 | return -EPERM; |
1133 | 1128 | ||
1134 | if (IS_APPEND(&dip->i_inode)) | 1129 | if (IS_APPEND(&dip->i_inode)) |
1135 | return -EPERM; | 1130 | return -EPERM; |
1136 | 1131 | ||
1137 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); | 1132 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); |
1138 | if (error) | 1133 | if (error) |
1139 | return error; | 1134 | return error; |
1140 | 1135 | ||
1141 | error = gfs2_dir_check(&dip->i_inode, name, ip); | 1136 | error = gfs2_dir_check(&dip->i_inode, name, ip); |
1142 | if (error) | 1137 | if (error) |
1143 | return error; | 1138 | return error; |
1144 | 1139 | ||
1145 | return 0; | 1140 | return 0; |
1146 | } | 1141 | } |
1147 | 1142 | ||
1148 | /* | 1143 | /* |
1149 | * gfs2_ok_to_move - check if it's ok to move a directory to another directory | 1144 | * gfs2_ok_to_move - check if it's ok to move a directory to another directory |
1150 | * @this: move this | 1145 | * @this: move this |
1151 | * @to: to here | 1146 | * @to: to here |
1152 | * | 1147 | * |
1153 | * Follow @to back to the root and make sure we don't encounter @this | 1148 | * Follow @to back to the root and make sure we don't encounter @this |
1154 | * Assumes we already hold the rename lock. | 1149 | * Assumes we already hold the rename lock. |
1155 | * | 1150 | * |
1156 | * Returns: errno | 1151 | * Returns: errno |
1157 | */ | 1152 | */ |
1158 | 1153 | ||
1159 | int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to) | 1154 | int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to) |
1160 | { | 1155 | { |
1161 | struct inode *dir = &to->i_inode; | 1156 | struct inode *dir = &to->i_inode; |
1162 | struct super_block *sb = dir->i_sb; | 1157 | struct super_block *sb = dir->i_sb; |
1163 | struct inode *tmp; | 1158 | struct inode *tmp; |
1164 | struct qstr dotdot; | 1159 | struct qstr dotdot; |
1165 | int error = 0; | 1160 | int error = 0; |
1166 | 1161 | ||
1167 | gfs2_str2qstr(&dotdot, ".."); | 1162 | gfs2_str2qstr(&dotdot, ".."); |
1168 | 1163 | ||
1169 | igrab(dir); | 1164 | igrab(dir); |
1170 | 1165 | ||
1171 | for (;;) { | 1166 | for (;;) { |
1172 | if (dir == &this->i_inode) { | 1167 | if (dir == &this->i_inode) { |
1173 | error = -EINVAL; | 1168 | error = -EINVAL; |
1174 | break; | 1169 | break; |
1175 | } | 1170 | } |
1176 | if (dir == sb->s_root->d_inode) { | 1171 | if (dir == sb->s_root->d_inode) { |
1177 | error = 0; | 1172 | error = 0; |
1178 | break; | 1173 | break; |
1179 | } | 1174 | } |
1180 | 1175 | ||
1181 | tmp = gfs2_lookupi(dir, &dotdot, 1, NULL); | 1176 | tmp = gfs2_lookupi(dir, &dotdot, 1, NULL); |
1182 | if (IS_ERR(tmp)) { | 1177 | if (IS_ERR(tmp)) { |
1183 | error = PTR_ERR(tmp); | 1178 | error = PTR_ERR(tmp); |
1184 | break; | 1179 | break; |
1185 | } | 1180 | } |
1186 | 1181 | ||
1187 | iput(dir); | 1182 | iput(dir); |
1188 | dir = tmp; | 1183 | dir = tmp; |
1189 | } | 1184 | } |
1190 | 1185 | ||
1191 | iput(dir); | 1186 | iput(dir); |
1192 | 1187 | ||
1193 | return error; | 1188 | return error; |
1194 | } | 1189 | } |
1195 | 1190 | ||
1196 | /** | 1191 | /** |
1197 | * gfs2_readlinki - return the contents of a symlink | 1192 | * gfs2_readlinki - return the contents of a symlink |
1198 | * @ip: the symlink's inode | 1193 | * @ip: the symlink's inode |
1199 | * @buf: a pointer to the buffer to be filled | 1194 | * @buf: a pointer to the buffer to be filled |
1200 | * @len: a pointer to the length of @buf | 1195 | * @len: a pointer to the length of @buf |
1201 | * | 1196 | * |
1202 | * If @buf is too small, a piece of memory is kmalloc()ed and needs | 1197 | * If @buf is too small, a piece of memory is kmalloc()ed and needs |
1203 | * to be freed by the caller. | 1198 | * to be freed by the caller. |
1204 | * | 1199 | * |
1205 | * Returns: errno | 1200 | * Returns: errno |
1206 | */ | 1201 | */ |
1207 | 1202 | ||
1208 | int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len) | 1203 | int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len) |
1209 | { | 1204 | { |
1210 | struct gfs2_holder i_gh; | 1205 | struct gfs2_holder i_gh; |
1211 | struct buffer_head *dibh; | 1206 | struct buffer_head *dibh; |
1212 | unsigned int x; | 1207 | unsigned int x; |
1213 | int error; | 1208 | int error; |
1214 | 1209 | ||
1215 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh); | 1210 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh); |
1216 | error = gfs2_glock_nq_atime(&i_gh); | 1211 | error = gfs2_glock_nq_atime(&i_gh); |
1217 | if (error) { | 1212 | if (error) { |
1218 | gfs2_holder_uninit(&i_gh); | 1213 | gfs2_holder_uninit(&i_gh); |
1219 | return error; | 1214 | return error; |
1220 | } | 1215 | } |
1221 | 1216 | ||
1222 | if (!ip->i_di.di_size) { | 1217 | if (!ip->i_di.di_size) { |
1223 | gfs2_consist_inode(ip); | 1218 | gfs2_consist_inode(ip); |
1224 | error = -EIO; | 1219 | error = -EIO; |
1225 | goto out; | 1220 | goto out; |
1226 | } | 1221 | } |
1227 | 1222 | ||
1228 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1223 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1229 | if (error) | 1224 | if (error) |
1230 | goto out; | 1225 | goto out; |
1231 | 1226 | ||
1232 | x = ip->i_di.di_size + 1; | 1227 | x = ip->i_di.di_size + 1; |
1233 | if (x > *len) { | 1228 | if (x > *len) { |
1234 | *buf = kmalloc(x, GFP_NOFS); | 1229 | *buf = kmalloc(x, GFP_NOFS); |
1235 | if (!*buf) { | 1230 | if (!*buf) { |
1236 | error = -ENOMEM; | 1231 | error = -ENOMEM; |
1237 | goto out_brelse; | 1232 | goto out_brelse; |
1238 | } | 1233 | } |
1239 | } | 1234 | } |
1240 | 1235 | ||
1241 | memcpy(*buf, dibh->b_data + sizeof(struct gfs2_dinode), x); | 1236 | memcpy(*buf, dibh->b_data + sizeof(struct gfs2_dinode), x); |
1242 | *len = x; | 1237 | *len = x; |
1243 | 1238 | ||
1244 | out_brelse: | 1239 | out_brelse: |
1245 | brelse(dibh); | 1240 | brelse(dibh); |
1246 | out: | 1241 | out: |
1247 | gfs2_glock_dq_uninit(&i_gh); | 1242 | gfs2_glock_dq_uninit(&i_gh); |
1248 | return error; | 1243 | return error; |
1249 | } | 1244 | } |
1250 | 1245 | ||
1251 | /** | 1246 | /** |
1252 | * gfs2_glock_nq_atime - Acquire a hold on an inode's glock, and | 1247 | * gfs2_glock_nq_atime - Acquire a hold on an inode's glock, and |
1253 | * conditionally update the inode's atime | 1248 | * conditionally update the inode's atime |
1254 | * @gh: the holder to acquire | 1249 | * @gh: the holder to acquire |
1255 | * | 1250 | * |
1256 | * Tests atime (access time) for gfs2_read, gfs2_readdir and gfs2_mmap | 1251 | * Tests atime (access time) for gfs2_read, gfs2_readdir and gfs2_mmap |
1257 | * Update if the difference between the current time and the inode's current | 1252 | * Update if the difference between the current time and the inode's current |
1258 | * atime is greater than an interval specified at mount. | 1253 | * atime is greater than an interval specified at mount. |
1259 | * | 1254 | * |
1260 | * Returns: errno | 1255 | * Returns: errno |
1261 | */ | 1256 | */ |
1262 | 1257 | ||
1263 | int gfs2_glock_nq_atime(struct gfs2_holder *gh) | 1258 | int gfs2_glock_nq_atime(struct gfs2_holder *gh) |
1264 | { | 1259 | { |
1265 | struct gfs2_glock *gl = gh->gh_gl; | 1260 | struct gfs2_glock *gl = gh->gh_gl; |
1266 | struct gfs2_sbd *sdp = gl->gl_sbd; | 1261 | struct gfs2_sbd *sdp = gl->gl_sbd; |
1267 | struct gfs2_inode *ip = gl->gl_object; | 1262 | struct gfs2_inode *ip = gl->gl_object; |
1268 | s64 quantum = gfs2_tune_get(sdp, gt_atime_quantum); | 1263 | s64 quantum = gfs2_tune_get(sdp, gt_atime_quantum); |
1269 | unsigned int state; | 1264 | unsigned int state; |
1270 | int flags; | 1265 | int flags; |
1271 | int error; | 1266 | int error; |
1272 | struct timespec tv = CURRENT_TIME; | 1267 | struct timespec tv = CURRENT_TIME; |
1273 | 1268 | ||
1274 | if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) || | 1269 | if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) || |
1275 | gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) || | 1270 | gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) || |
1276 | gfs2_assert_warn(sdp, gl->gl_ops == &gfs2_inode_glops)) | 1271 | gfs2_assert_warn(sdp, gl->gl_ops == &gfs2_inode_glops)) |
1277 | return -EINVAL; | 1272 | return -EINVAL; |
1278 | 1273 | ||
1279 | state = gh->gh_state; | 1274 | state = gh->gh_state; |
1280 | flags = gh->gh_flags; | 1275 | flags = gh->gh_flags; |
1281 | 1276 | ||
1282 | error = gfs2_glock_nq(gh); | 1277 | error = gfs2_glock_nq(gh); |
1283 | if (error) | 1278 | if (error) |
1284 | return error; | 1279 | return error; |
1285 | 1280 | ||
1286 | if (test_bit(SDF_NOATIME, &sdp->sd_flags) || | 1281 | if (test_bit(SDF_NOATIME, &sdp->sd_flags) || |
1287 | (sdp->sd_vfs->s_flags & MS_RDONLY)) | 1282 | (sdp->sd_vfs->s_flags & MS_RDONLY)) |
1288 | return 0; | 1283 | return 0; |
1289 | 1284 | ||
1290 | if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) { | 1285 | if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) { |
1291 | gfs2_glock_dq(gh); | 1286 | gfs2_glock_dq(gh); |
1292 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, | 1287 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, |
1293 | gh); | 1288 | gh); |
1294 | error = gfs2_glock_nq(gh); | 1289 | error = gfs2_glock_nq(gh); |
1295 | if (error) | 1290 | if (error) |
1296 | return error; | 1291 | return error; |
1297 | 1292 | ||
1298 | /* Verify that atime hasn't been updated while we were | 1293 | /* Verify that atime hasn't been updated while we were |
1299 | trying to get exclusive lock. */ | 1294 | trying to get exclusive lock. */ |
1300 | 1295 | ||
1301 | tv = CURRENT_TIME; | 1296 | tv = CURRENT_TIME; |
1302 | if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) { | 1297 | if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) { |
1303 | struct buffer_head *dibh; | 1298 | struct buffer_head *dibh; |
1304 | struct gfs2_dinode *di; | 1299 | struct gfs2_dinode *di; |
1305 | 1300 | ||
1306 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); | 1301 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); |
1307 | if (error == -EROFS) | 1302 | if (error == -EROFS) |
1308 | return 0; | 1303 | return 0; |
1309 | if (error) | 1304 | if (error) |
1310 | goto fail; | 1305 | goto fail; |
1311 | 1306 | ||
1312 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1307 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1313 | if (error) | 1308 | if (error) |
1314 | goto fail_end_trans; | 1309 | goto fail_end_trans; |
1315 | 1310 | ||
1316 | ip->i_inode.i_atime = tv; | 1311 | ip->i_inode.i_atime = tv; |
1317 | 1312 | ||
1318 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1313 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1319 | di = (struct gfs2_dinode *)dibh->b_data; | 1314 | di = (struct gfs2_dinode *)dibh->b_data; |
1320 | di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); | 1315 | di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); |
1321 | di->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); | 1316 | di->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); |
1322 | brelse(dibh); | 1317 | brelse(dibh); |
1323 | 1318 | ||
1324 | gfs2_trans_end(sdp); | 1319 | gfs2_trans_end(sdp); |
1325 | } | 1320 | } |
1326 | 1321 | ||
1327 | /* If someone else has asked for the glock, | 1322 | /* If someone else has asked for the glock, |
1328 | unlock and let them have it. Then reacquire | 1323 | unlock and let them have it. Then reacquire |
1329 | in the original state. */ | 1324 | in the original state. */ |
1330 | if (gfs2_glock_is_blocking(gl)) { | 1325 | if (gfs2_glock_is_blocking(gl)) { |
1331 | gfs2_glock_dq(gh); | 1326 | gfs2_glock_dq(gh); |
1332 | gfs2_holder_reinit(state, flags, gh); | 1327 | gfs2_holder_reinit(state, flags, gh); |
1333 | return gfs2_glock_nq(gh); | 1328 | return gfs2_glock_nq(gh); |
1334 | } | 1329 | } |
1335 | } | 1330 | } |
1336 | 1331 | ||
1337 | return 0; | 1332 | return 0; |
1338 | 1333 | ||
1339 | fail_end_trans: | 1334 | fail_end_trans: |
1340 | gfs2_trans_end(sdp); | 1335 | gfs2_trans_end(sdp); |
1341 | fail: | 1336 | fail: |
1342 | gfs2_glock_dq(gh); | 1337 | gfs2_glock_dq(gh); |
1343 | return error; | 1338 | return error; |
1344 | } | 1339 | } |
1345 | 1340 | ||
1346 | static int | 1341 | static int |
1347 | __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | 1342 | __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) |
1348 | { | 1343 | { |
1349 | struct buffer_head *dibh; | 1344 | struct buffer_head *dibh; |
1350 | int error; | 1345 | int error; |
1351 | 1346 | ||
1352 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1347 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1353 | if (!error) { | 1348 | if (!error) { |
1354 | error = inode_setattr(&ip->i_inode, attr); | 1349 | error = inode_setattr(&ip->i_inode, attr); |
1355 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); | 1350 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); |
1356 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1351 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1357 | gfs2_dinode_out(ip, dibh->b_data); | 1352 | gfs2_dinode_out(ip, dibh->b_data); |
1358 | brelse(dibh); | 1353 | brelse(dibh); |
1359 | } | 1354 | } |
1360 | return error; | 1355 | return error; |
1361 | } | 1356 | } |
1362 | 1357 | ||
1363 | /** | 1358 | /** |
1364 | * gfs2_setattr_simple - | 1359 | * gfs2_setattr_simple - |
1365 | * @ip: | 1360 | * @ip: |
1366 | * @attr: | 1361 | * @attr: |
1367 | * | 1362 | * |
1368 | * Called with a reference on the vnode. | 1363 | * Called with a reference on the vnode. |
1369 | * | 1364 | * |
1370 | * Returns: errno | 1365 | * Returns: errno |
1371 | */ | 1366 | */ |
1372 | 1367 | ||
1373 | int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | 1368 | int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) |
1374 | { | 1369 | { |
1375 | int error; | 1370 | int error; |
1376 | 1371 | ||
1377 | if (current->journal_info) | 1372 | if (current->journal_info) |
1378 | return __gfs2_setattr_simple(ip, attr); | 1373 | return __gfs2_setattr_simple(ip, attr); |
1379 | 1374 | ||
1380 | error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE, 0); | 1375 | error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE, 0); |
1381 | if (error) | 1376 | if (error) |
1382 | return error; | 1377 | return error; |
1383 | 1378 | ||
1384 | error = __gfs2_setattr_simple(ip, attr); | 1379 | error = __gfs2_setattr_simple(ip, attr); |
1385 | gfs2_trans_end(GFS2_SB(&ip->i_inode)); | 1380 | gfs2_trans_end(GFS2_SB(&ip->i_inode)); |
1386 | return error; | 1381 | return error; |
1387 | } | 1382 | } |
1388 | 1383 | ||
1389 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) | 1384 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) |
1390 | { | 1385 | { |
1391 | const struct gfs2_dinode_host *di = &ip->i_di; | 1386 | const struct gfs2_dinode_host *di = &ip->i_di; |
1392 | struct gfs2_dinode *str = buf; | 1387 | struct gfs2_dinode *str = buf; |
1393 | 1388 | ||
1394 | str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); | 1389 | str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); |
1395 | str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI); | 1390 | str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI); |
1396 | str->di_header.__pad0 = 0; | 1391 | str->di_header.__pad0 = 0; |
1397 | str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); | 1392 | str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); |
1398 | str->di_header.__pad1 = 0; | 1393 | str->di_header.__pad1 = 0; |
1399 | str->di_num.no_addr = cpu_to_be64(ip->i_no_addr); | 1394 | str->di_num.no_addr = cpu_to_be64(ip->i_no_addr); |
1400 | str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); | 1395 | str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); |
1401 | str->di_mode = cpu_to_be32(ip->i_inode.i_mode); | 1396 | str->di_mode = cpu_to_be32(ip->i_inode.i_mode); |
1402 | str->di_uid = cpu_to_be32(ip->i_inode.i_uid); | 1397 | str->di_uid = cpu_to_be32(ip->i_inode.i_uid); |
1403 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); | 1398 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); |
1404 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); | 1399 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); |
1405 | str->di_size = cpu_to_be64(di->di_size); | 1400 | str->di_size = cpu_to_be64(di->di_size); |
1406 | str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); | 1401 | str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); |
1407 | str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); | 1402 | str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); |
1408 | str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); | 1403 | str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); |
1409 | str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); | 1404 | str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); |
1410 | 1405 | ||
1411 | str->di_goal_meta = cpu_to_be64(ip->i_goal); | 1406 | str->di_goal_meta = cpu_to_be64(ip->i_goal); |
1412 | str->di_goal_data = cpu_to_be64(ip->i_goal); | 1407 | str->di_goal_data = cpu_to_be64(ip->i_goal); |
1413 | str->di_generation = cpu_to_be64(di->di_generation); | 1408 | str->di_generation = cpu_to_be64(di->di_generation); |
1414 | 1409 | ||
1415 | str->di_flags = cpu_to_be32(di->di_flags); | 1410 | str->di_flags = cpu_to_be32(di->di_flags); |
1416 | str->di_height = cpu_to_be16(ip->i_height); | 1411 | str->di_height = cpu_to_be16(ip->i_height); |
1417 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && | 1412 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && |
1418 | !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ? | 1413 | !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ? |
1419 | GFS2_FORMAT_DE : 0); | 1414 | GFS2_FORMAT_DE : 0); |
1420 | str->di_depth = cpu_to_be16(ip->i_depth); | 1415 | str->di_depth = cpu_to_be16(ip->i_depth); |
1421 | str->di_entries = cpu_to_be32(di->di_entries); | 1416 | str->di_entries = cpu_to_be32(di->di_entries); |
1422 | 1417 | ||
1423 | str->di_eattr = cpu_to_be64(di->di_eattr); | 1418 | str->di_eattr = cpu_to_be64(di->di_eattr); |
1424 | str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); | 1419 | str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); |
1425 | str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec); | 1420 | str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec); |
1426 | str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec); | 1421 | str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec); |
1427 | } | 1422 | } |
1428 | 1423 | ||
1429 | void gfs2_dinode_print(const struct gfs2_inode *ip) | 1424 | void gfs2_dinode_print(const struct gfs2_inode *ip) |
1430 | { | 1425 | { |
1431 | const struct gfs2_dinode_host *di = &ip->i_di; | 1426 | const struct gfs2_dinode_host *di = &ip->i_di; |
1432 | 1427 | ||
1433 | printk(KERN_INFO " no_formal_ino = %llu\n", | 1428 | printk(KERN_INFO " no_formal_ino = %llu\n", |
1434 | (unsigned long long)ip->i_no_formal_ino); | 1429 | (unsigned long long)ip->i_no_formal_ino); |
1435 | printk(KERN_INFO " no_addr = %llu\n", | 1430 | printk(KERN_INFO " no_addr = %llu\n", |
1436 | (unsigned long long)ip->i_no_addr); | 1431 | (unsigned long long)ip->i_no_addr); |
1437 | printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); | 1432 | printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); |
1438 | printk(KERN_INFO " blocks = %llu\n", | 1433 | printk(KERN_INFO " blocks = %llu\n", |
1439 | (unsigned long long)gfs2_get_inode_blocks(&ip->i_inode)); | 1434 | (unsigned long long)gfs2_get_inode_blocks(&ip->i_inode)); |
1440 | printk(KERN_INFO " i_goal = %llu\n", | 1435 | printk(KERN_INFO " i_goal = %llu\n", |
1441 | (unsigned long long)ip->i_goal); | 1436 | (unsigned long long)ip->i_goal); |
1442 | printk(KERN_INFO " di_flags = 0x%.8X\n", di->di_flags); | 1437 | printk(KERN_INFO " di_flags = 0x%.8X\n", di->di_flags); |
1443 | printk(KERN_INFO " i_height = %u\n", ip->i_height); | 1438 | printk(KERN_INFO " i_height = %u\n", ip->i_height); |
1444 | printk(KERN_INFO " i_depth = %u\n", ip->i_depth); | 1439 | printk(KERN_INFO " i_depth = %u\n", ip->i_depth); |
1445 | printk(KERN_INFO " di_entries = %u\n", di->di_entries); | 1440 | printk(KERN_INFO " di_entries = %u\n", di->di_entries); |
1446 | printk(KERN_INFO " di_eattr = %llu\n", | 1441 | printk(KERN_INFO " di_eattr = %llu\n", |
1447 | (unsigned long long)di->di_eattr); | 1442 | (unsigned long long)di->di_eattr); |
1448 | } | 1443 | } |
1449 | 1444 | ||
1450 | 1445 |
fs/gfs2/ops_file.c
1 | /* | 1 | /* |
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | 3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This copyrighted material is made available to anyone wishing to use, | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | * modify, copy, or redistribute it subject to the terms and conditions | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
7 | * of the GNU General Public License version 2. | 7 | * of the GNU General Public License version 2. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
11 | #include <linux/spinlock.h> | 11 | #include <linux/spinlock.h> |
12 | #include <linux/completion.h> | 12 | #include <linux/completion.h> |
13 | #include <linux/buffer_head.h> | 13 | #include <linux/buffer_head.h> |
14 | #include <linux/pagemap.h> | 14 | #include <linux/pagemap.h> |
15 | #include <linux/uio.h> | 15 | #include <linux/uio.h> |
16 | #include <linux/blkdev.h> | 16 | #include <linux/blkdev.h> |
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/mount.h> | 18 | #include <linux/mount.h> |
19 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
20 | #include <linux/gfs2_ondisk.h> | 20 | #include <linux/gfs2_ondisk.h> |
21 | #include <linux/ext2_fs.h> | 21 | #include <linux/ext2_fs.h> |
22 | #include <linux/crc32.h> | 22 | #include <linux/crc32.h> |
23 | #include <linux/lm_interface.h> | 23 | #include <linux/lm_interface.h> |
24 | #include <linux/writeback.h> | 24 | #include <linux/writeback.h> |
25 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
26 | 26 | ||
27 | #include "gfs2.h" | 27 | #include "gfs2.h" |
28 | #include "incore.h" | 28 | #include "incore.h" |
29 | #include "bmap.h" | 29 | #include "bmap.h" |
30 | #include "dir.h" | 30 | #include "dir.h" |
31 | #include "glock.h" | 31 | #include "glock.h" |
32 | #include "glops.h" | 32 | #include "glops.h" |
33 | #include "inode.h" | 33 | #include "inode.h" |
34 | #include "log.h" | 34 | #include "log.h" |
35 | #include "meta_io.h" | 35 | #include "meta_io.h" |
36 | #include "quota.h" | 36 | #include "quota.h" |
37 | #include "rgrp.h" | 37 | #include "rgrp.h" |
38 | #include "trans.h" | 38 | #include "trans.h" |
39 | #include "util.h" | 39 | #include "util.h" |
40 | #include "eaops.h" | 40 | #include "eaops.h" |
41 | #include "ops_address.h" | 41 | #include "ops_address.h" |
42 | #include "ops_inode.h" | 42 | #include "ops_inode.h" |
43 | 43 | ||
44 | /** | 44 | /** |
45 | * gfs2_llseek - seek to a location in a file | 45 | * gfs2_llseek - seek to a location in a file |
46 | * @file: the file | 46 | * @file: the file |
47 | * @offset: the offset | 47 | * @offset: the offset |
48 | * @origin: Where to seek from (SEEK_SET, SEEK_CUR, or SEEK_END) | 48 | * @origin: Where to seek from (SEEK_SET, SEEK_CUR, or SEEK_END) |
49 | * | 49 | * |
50 | * SEEK_END requires the glock for the file because it references the | 50 | * SEEK_END requires the glock for the file because it references the |
51 | * file's size. | 51 | * file's size. |
52 | * | 52 | * |
53 | * Returns: The new offset, or errno | 53 | * Returns: The new offset, or errno |
54 | */ | 54 | */ |
55 | 55 | ||
56 | static loff_t gfs2_llseek(struct file *file, loff_t offset, int origin) | 56 | static loff_t gfs2_llseek(struct file *file, loff_t offset, int origin) |
57 | { | 57 | { |
58 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); | 58 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); |
59 | struct gfs2_holder i_gh; | 59 | struct gfs2_holder i_gh; |
60 | loff_t error; | 60 | loff_t error; |
61 | 61 | ||
62 | if (origin == 2) { | 62 | if (origin == 2) { |
63 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, | 63 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, |
64 | &i_gh); | 64 | &i_gh); |
65 | if (!error) { | 65 | if (!error) { |
66 | error = remote_llseek(file, offset, origin); | 66 | error = remote_llseek(file, offset, origin); |
67 | gfs2_glock_dq_uninit(&i_gh); | 67 | gfs2_glock_dq_uninit(&i_gh); |
68 | } | 68 | } |
69 | } else | 69 | } else |
70 | error = remote_llseek(file, offset, origin); | 70 | error = remote_llseek(file, offset, origin); |
71 | 71 | ||
72 | return error; | 72 | return error; |
73 | } | 73 | } |
74 | 74 | ||
75 | /** | 75 | /** |
76 | * gfs2_readdir - Read directory entries from a directory | 76 | * gfs2_readdir - Read directory entries from a directory |
77 | * @file: The directory to read from | 77 | * @file: The directory to read from |
78 | * @dirent: Buffer for dirents | 78 | * @dirent: Buffer for dirents |
79 | * @filldir: Function used to do the copying | 79 | * @filldir: Function used to do the copying |
80 | * | 80 | * |
81 | * Returns: errno | 81 | * Returns: errno |
82 | */ | 82 | */ |
83 | 83 | ||
84 | static int gfs2_readdir(struct file *file, void *dirent, filldir_t filldir) | 84 | static int gfs2_readdir(struct file *file, void *dirent, filldir_t filldir) |
85 | { | 85 | { |
86 | struct inode *dir = file->f_mapping->host; | 86 | struct inode *dir = file->f_mapping->host; |
87 | struct gfs2_inode *dip = GFS2_I(dir); | 87 | struct gfs2_inode *dip = GFS2_I(dir); |
88 | struct gfs2_holder d_gh; | 88 | struct gfs2_holder d_gh; |
89 | u64 offset = file->f_pos; | 89 | u64 offset = file->f_pos; |
90 | int error; | 90 | int error; |
91 | 91 | ||
92 | gfs2_holder_init(dip->i_gl, LM_ST_SHARED, GL_ATIME, &d_gh); | 92 | gfs2_holder_init(dip->i_gl, LM_ST_SHARED, GL_ATIME, &d_gh); |
93 | error = gfs2_glock_nq_atime(&d_gh); | 93 | error = gfs2_glock_nq_atime(&d_gh); |
94 | if (error) { | 94 | if (error) { |
95 | gfs2_holder_uninit(&d_gh); | 95 | gfs2_holder_uninit(&d_gh); |
96 | return error; | 96 | return error; |
97 | } | 97 | } |
98 | 98 | ||
99 | error = gfs2_dir_read(dir, &offset, dirent, filldir); | 99 | error = gfs2_dir_read(dir, &offset, dirent, filldir); |
100 | 100 | ||
101 | gfs2_glock_dq_uninit(&d_gh); | 101 | gfs2_glock_dq_uninit(&d_gh); |
102 | 102 | ||
103 | file->f_pos = offset; | 103 | file->f_pos = offset; |
104 | 104 | ||
105 | return error; | 105 | return error; |
106 | } | 106 | } |
107 | 107 | ||
108 | /** | 108 | /** |
109 | * fsflags_cvt | 109 | * fsflags_cvt |
110 | * @table: A table of 32 u32 flags | 110 | * @table: A table of 32 u32 flags |
111 | * @val: a 32 bit value to convert | 111 | * @val: a 32 bit value to convert |
112 | * | 112 | * |
113 | * This function can be used to convert between fsflags values and | 113 | * This function can be used to convert between fsflags values and |
114 | * GFS2's own flags values. | 114 | * GFS2's own flags values. |
115 | * | 115 | * |
116 | * Returns: the converted flags | 116 | * Returns: the converted flags |
117 | */ | 117 | */ |
118 | static u32 fsflags_cvt(const u32 *table, u32 val) | 118 | static u32 fsflags_cvt(const u32 *table, u32 val) |
119 | { | 119 | { |
120 | u32 res = 0; | 120 | u32 res = 0; |
121 | while(val) { | 121 | while(val) { |
122 | if (val & 1) | 122 | if (val & 1) |
123 | res |= *table; | 123 | res |= *table; |
124 | table++; | 124 | table++; |
125 | val >>= 1; | 125 | val >>= 1; |
126 | } | 126 | } |
127 | return res; | 127 | return res; |
128 | } | 128 | } |
129 | 129 | ||
130 | static const u32 fsflags_to_gfs2[32] = { | 130 | static const u32 fsflags_to_gfs2[32] = { |
131 | [3] = GFS2_DIF_SYNC, | 131 | [3] = GFS2_DIF_SYNC, |
132 | [4] = GFS2_DIF_IMMUTABLE, | 132 | [4] = GFS2_DIF_IMMUTABLE, |
133 | [5] = GFS2_DIF_APPENDONLY, | 133 | [5] = GFS2_DIF_APPENDONLY, |
134 | [7] = GFS2_DIF_NOATIME, | 134 | [7] = GFS2_DIF_NOATIME, |
135 | [12] = GFS2_DIF_EXHASH, | 135 | [12] = GFS2_DIF_EXHASH, |
136 | [14] = GFS2_DIF_INHERIT_JDATA, | 136 | [14] = GFS2_DIF_INHERIT_JDATA, |
137 | [20] = GFS2_DIF_INHERIT_DIRECTIO, | ||
138 | }; | 137 | }; |
139 | 138 | ||
140 | static const u32 gfs2_to_fsflags[32] = { | 139 | static const u32 gfs2_to_fsflags[32] = { |
141 | [gfs2fl_Sync] = FS_SYNC_FL, | 140 | [gfs2fl_Sync] = FS_SYNC_FL, |
142 | [gfs2fl_Immutable] = FS_IMMUTABLE_FL, | 141 | [gfs2fl_Immutable] = FS_IMMUTABLE_FL, |
143 | [gfs2fl_AppendOnly] = FS_APPEND_FL, | 142 | [gfs2fl_AppendOnly] = FS_APPEND_FL, |
144 | [gfs2fl_NoAtime] = FS_NOATIME_FL, | 143 | [gfs2fl_NoAtime] = FS_NOATIME_FL, |
145 | [gfs2fl_ExHash] = FS_INDEX_FL, | 144 | [gfs2fl_ExHash] = FS_INDEX_FL, |
146 | [gfs2fl_InheritDirectio] = FS_DIRECTIO_FL, | ||
147 | [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL, | 145 | [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL, |
148 | }; | 146 | }; |
149 | 147 | ||
150 | static int gfs2_get_flags(struct file *filp, u32 __user *ptr) | 148 | static int gfs2_get_flags(struct file *filp, u32 __user *ptr) |
151 | { | 149 | { |
152 | struct inode *inode = filp->f_path.dentry->d_inode; | 150 | struct inode *inode = filp->f_path.dentry->d_inode; |
153 | struct gfs2_inode *ip = GFS2_I(inode); | 151 | struct gfs2_inode *ip = GFS2_I(inode); |
154 | struct gfs2_holder gh; | 152 | struct gfs2_holder gh; |
155 | int error; | 153 | int error; |
156 | u32 fsflags; | 154 | u32 fsflags; |
157 | 155 | ||
158 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); | 156 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); |
159 | error = gfs2_glock_nq_atime(&gh); | 157 | error = gfs2_glock_nq_atime(&gh); |
160 | if (error) | 158 | if (error) |
161 | return error; | 159 | return error; |
162 | 160 | ||
163 | fsflags = fsflags_cvt(gfs2_to_fsflags, ip->i_di.di_flags); | 161 | fsflags = fsflags_cvt(gfs2_to_fsflags, ip->i_di.di_flags); |
164 | if (!S_ISDIR(inode->i_mode)) { | 162 | if (!S_ISDIR(inode->i_mode) && ip->i_di.di_flags & GFS2_DIF_JDATA) |
165 | if (ip->i_di.di_flags & GFS2_DIF_JDATA) | 163 | fsflags |= FS_JOURNAL_DATA_FL; |
166 | fsflags |= FS_JOURNAL_DATA_FL; | ||
167 | if (ip->i_di.di_flags & GFS2_DIF_DIRECTIO) | ||
168 | fsflags |= FS_DIRECTIO_FL; | ||
169 | } | ||
170 | if (put_user(fsflags, ptr)) | 164 | if (put_user(fsflags, ptr)) |
171 | error = -EFAULT; | 165 | error = -EFAULT; |
172 | 166 | ||
173 | gfs2_glock_dq(&gh); | 167 | gfs2_glock_dq(&gh); |
174 | gfs2_holder_uninit(&gh); | 168 | gfs2_holder_uninit(&gh); |
175 | return error; | 169 | return error; |
176 | } | 170 | } |
177 | 171 | ||
178 | void gfs2_set_inode_flags(struct inode *inode) | 172 | void gfs2_set_inode_flags(struct inode *inode) |
179 | { | 173 | { |
180 | struct gfs2_inode *ip = GFS2_I(inode); | 174 | struct gfs2_inode *ip = GFS2_I(inode); |
181 | struct gfs2_dinode_host *di = &ip->i_di; | 175 | struct gfs2_dinode_host *di = &ip->i_di; |
182 | unsigned int flags = inode->i_flags; | 176 | unsigned int flags = inode->i_flags; |
183 | 177 | ||
184 | flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); | 178 | flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); |
185 | if (di->di_flags & GFS2_DIF_IMMUTABLE) | 179 | if (di->di_flags & GFS2_DIF_IMMUTABLE) |
186 | flags |= S_IMMUTABLE; | 180 | flags |= S_IMMUTABLE; |
187 | if (di->di_flags & GFS2_DIF_APPENDONLY) | 181 | if (di->di_flags & GFS2_DIF_APPENDONLY) |
188 | flags |= S_APPEND; | 182 | flags |= S_APPEND; |
189 | if (di->di_flags & GFS2_DIF_NOATIME) | 183 | if (di->di_flags & GFS2_DIF_NOATIME) |
190 | flags |= S_NOATIME; | 184 | flags |= S_NOATIME; |
191 | if (di->di_flags & GFS2_DIF_SYNC) | 185 | if (di->di_flags & GFS2_DIF_SYNC) |
192 | flags |= S_SYNC; | 186 | flags |= S_SYNC; |
193 | inode->i_flags = flags; | 187 | inode->i_flags = flags; |
194 | } | 188 | } |
195 | 189 | ||
196 | /* Flags that can be set by user space */ | 190 | /* Flags that can be set by user space */ |
197 | #define GFS2_FLAGS_USER_SET (GFS2_DIF_JDATA| \ | 191 | #define GFS2_FLAGS_USER_SET (GFS2_DIF_JDATA| \ |
198 | GFS2_DIF_DIRECTIO| \ | ||
199 | GFS2_DIF_IMMUTABLE| \ | 192 | GFS2_DIF_IMMUTABLE| \ |
200 | GFS2_DIF_APPENDONLY| \ | 193 | GFS2_DIF_APPENDONLY| \ |
201 | GFS2_DIF_NOATIME| \ | 194 | GFS2_DIF_NOATIME| \ |
202 | GFS2_DIF_SYNC| \ | 195 | GFS2_DIF_SYNC| \ |
203 | GFS2_DIF_SYSTEM| \ | 196 | GFS2_DIF_SYSTEM| \ |
204 | GFS2_DIF_INHERIT_DIRECTIO| \ | ||
205 | GFS2_DIF_INHERIT_JDATA) | 197 | GFS2_DIF_INHERIT_JDATA) |
206 | 198 | ||
207 | /** | 199 | /** |
208 | * gfs2_set_flags - set flags on an inode | 200 | * gfs2_set_flags - set flags on an inode |
209 | * @inode: The inode | 201 | * @inode: The inode |
210 | * @flags: The flags to set | 202 | * @flags: The flags to set |
211 | * @mask: Indicates which flags are valid | 203 | * @mask: Indicates which flags are valid |
212 | * | 204 | * |
213 | */ | 205 | */ |
214 | static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) | 206 | static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) |
215 | { | 207 | { |
216 | struct inode *inode = filp->f_path.dentry->d_inode; | 208 | struct inode *inode = filp->f_path.dentry->d_inode; |
217 | struct gfs2_inode *ip = GFS2_I(inode); | 209 | struct gfs2_inode *ip = GFS2_I(inode); |
218 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 210 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
219 | struct buffer_head *bh; | 211 | struct buffer_head *bh; |
220 | struct gfs2_holder gh; | 212 | struct gfs2_holder gh; |
221 | int error; | 213 | int error; |
222 | u32 new_flags, flags; | 214 | u32 new_flags, flags; |
223 | 215 | ||
224 | error = mnt_want_write(filp->f_path.mnt); | 216 | error = mnt_want_write(filp->f_path.mnt); |
225 | if (error) | 217 | if (error) |
226 | return error; | 218 | return error; |
227 | 219 | ||
228 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 220 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
229 | if (error) | 221 | if (error) |
230 | goto out_drop_write; | 222 | goto out_drop_write; |
231 | 223 | ||
232 | flags = ip->i_di.di_flags; | 224 | flags = ip->i_di.di_flags; |
233 | new_flags = (flags & ~mask) | (reqflags & mask); | 225 | new_flags = (flags & ~mask) | (reqflags & mask); |
234 | if ((new_flags ^ flags) == 0) | 226 | if ((new_flags ^ flags) == 0) |
235 | goto out; | 227 | goto out; |
236 | 228 | ||
237 | error = -EINVAL; | 229 | error = -EINVAL; |
238 | if ((new_flags ^ flags) & ~GFS2_FLAGS_USER_SET) | 230 | if ((new_flags ^ flags) & ~GFS2_FLAGS_USER_SET) |
239 | goto out; | 231 | goto out; |
240 | 232 | ||
241 | error = -EPERM; | 233 | error = -EPERM; |
242 | if (IS_IMMUTABLE(inode) && (new_flags & GFS2_DIF_IMMUTABLE)) | 234 | if (IS_IMMUTABLE(inode) && (new_flags & GFS2_DIF_IMMUTABLE)) |
243 | goto out; | 235 | goto out; |
244 | if (IS_APPEND(inode) && (new_flags & GFS2_DIF_APPENDONLY)) | 236 | if (IS_APPEND(inode) && (new_flags & GFS2_DIF_APPENDONLY)) |
245 | goto out; | 237 | goto out; |
246 | if (((new_flags ^ flags) & GFS2_DIF_IMMUTABLE) && | 238 | if (((new_flags ^ flags) & GFS2_DIF_IMMUTABLE) && |
247 | !capable(CAP_LINUX_IMMUTABLE)) | 239 | !capable(CAP_LINUX_IMMUTABLE)) |
248 | goto out; | 240 | goto out; |
249 | if (!IS_IMMUTABLE(inode)) { | 241 | if (!IS_IMMUTABLE(inode)) { |
250 | error = gfs2_permission(inode, MAY_WRITE); | 242 | error = gfs2_permission(inode, MAY_WRITE); |
251 | if (error) | 243 | if (error) |
252 | goto out; | 244 | goto out; |
253 | } | 245 | } |
254 | if ((flags ^ new_flags) & GFS2_DIF_JDATA) { | 246 | if ((flags ^ new_flags) & GFS2_DIF_JDATA) { |
255 | if (flags & GFS2_DIF_JDATA) | 247 | if (flags & GFS2_DIF_JDATA) |
256 | gfs2_log_flush(sdp, ip->i_gl); | 248 | gfs2_log_flush(sdp, ip->i_gl); |
257 | error = filemap_fdatawrite(inode->i_mapping); | 249 | error = filemap_fdatawrite(inode->i_mapping); |
258 | if (error) | 250 | if (error) |
259 | goto out; | 251 | goto out; |
260 | error = filemap_fdatawait(inode->i_mapping); | 252 | error = filemap_fdatawait(inode->i_mapping); |
261 | if (error) | 253 | if (error) |
262 | goto out; | 254 | goto out; |
263 | } | 255 | } |
264 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); | 256 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); |
265 | if (error) | 257 | if (error) |
266 | goto out; | 258 | goto out; |
267 | error = gfs2_meta_inode_buffer(ip, &bh); | 259 | error = gfs2_meta_inode_buffer(ip, &bh); |
268 | if (error) | 260 | if (error) |
269 | goto out_trans_end; | 261 | goto out_trans_end; |
270 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 262 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
271 | ip->i_di.di_flags = new_flags; | 263 | ip->i_di.di_flags = new_flags; |
272 | gfs2_dinode_out(ip, bh->b_data); | 264 | gfs2_dinode_out(ip, bh->b_data); |
273 | brelse(bh); | 265 | brelse(bh); |
274 | gfs2_set_inode_flags(inode); | 266 | gfs2_set_inode_flags(inode); |
275 | gfs2_set_aops(inode); | 267 | gfs2_set_aops(inode); |
276 | out_trans_end: | 268 | out_trans_end: |
277 | gfs2_trans_end(sdp); | 269 | gfs2_trans_end(sdp); |
278 | out: | 270 | out: |
279 | gfs2_glock_dq_uninit(&gh); | 271 | gfs2_glock_dq_uninit(&gh); |
280 | out_drop_write: | 272 | out_drop_write: |
281 | mnt_drop_write(filp->f_path.mnt); | 273 | mnt_drop_write(filp->f_path.mnt); |
282 | return error; | 274 | return error; |
283 | } | 275 | } |
284 | 276 | ||
285 | static int gfs2_set_flags(struct file *filp, u32 __user *ptr) | 277 | static int gfs2_set_flags(struct file *filp, u32 __user *ptr) |
286 | { | 278 | { |
287 | struct inode *inode = filp->f_path.dentry->d_inode; | 279 | struct inode *inode = filp->f_path.dentry->d_inode; |
288 | u32 fsflags, gfsflags; | 280 | u32 fsflags, gfsflags; |
289 | if (get_user(fsflags, ptr)) | 281 | if (get_user(fsflags, ptr)) |
290 | return -EFAULT; | 282 | return -EFAULT; |
291 | gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags); | 283 | gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags); |
292 | if (!S_ISDIR(inode->i_mode)) { | 284 | if (!S_ISDIR(inode->i_mode)) { |
293 | if (gfsflags & GFS2_DIF_INHERIT_JDATA) | 285 | if (gfsflags & GFS2_DIF_INHERIT_JDATA) |
294 | gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA); | 286 | gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA); |
295 | if (gfsflags & GFS2_DIF_INHERIT_DIRECTIO) | ||
296 | gfsflags ^= (GFS2_DIF_DIRECTIO | GFS2_DIF_INHERIT_DIRECTIO); | ||
297 | return do_gfs2_set_flags(filp, gfsflags, ~0); | 287 | return do_gfs2_set_flags(filp, gfsflags, ~0); |
298 | } | 288 | } |
299 | return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA); | 289 | return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA); |
300 | } | 290 | } |
301 | 291 | ||
302 | static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 292 | static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
303 | { | 293 | { |
304 | switch(cmd) { | 294 | switch(cmd) { |
305 | case FS_IOC_GETFLAGS: | 295 | case FS_IOC_GETFLAGS: |
306 | return gfs2_get_flags(filp, (u32 __user *)arg); | 296 | return gfs2_get_flags(filp, (u32 __user *)arg); |
307 | case FS_IOC_SETFLAGS: | 297 | case FS_IOC_SETFLAGS: |
308 | return gfs2_set_flags(filp, (u32 __user *)arg); | 298 | return gfs2_set_flags(filp, (u32 __user *)arg); |
309 | } | 299 | } |
310 | return -ENOTTY; | 300 | return -ENOTTY; |
311 | } | 301 | } |
312 | 302 | ||
313 | /** | 303 | /** |
314 | * gfs2_allocate_page_backing - Use bmap to allocate blocks | 304 | * gfs2_allocate_page_backing - Use bmap to allocate blocks |
315 | * @page: The (locked) page to allocate backing for | 305 | * @page: The (locked) page to allocate backing for |
316 | * | 306 | * |
317 | * We try to allocate all the blocks required for the page in | 307 | * We try to allocate all the blocks required for the page in |
318 | * one go. This might fail for various reasons, so we keep | 308 | * one go. This might fail for various reasons, so we keep |
319 | * trying until all the blocks to back this page are allocated. | 309 | * trying until all the blocks to back this page are allocated. |
320 | * If some of the blocks are already allocated, thats ok too. | 310 | * If some of the blocks are already allocated, thats ok too. |
321 | */ | 311 | */ |
322 | 312 | ||
323 | static int gfs2_allocate_page_backing(struct page *page) | 313 | static int gfs2_allocate_page_backing(struct page *page) |
324 | { | 314 | { |
325 | struct inode *inode = page->mapping->host; | 315 | struct inode *inode = page->mapping->host; |
326 | struct buffer_head bh; | 316 | struct buffer_head bh; |
327 | unsigned long size = PAGE_CACHE_SIZE; | 317 | unsigned long size = PAGE_CACHE_SIZE; |
328 | u64 lblock = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); | 318 | u64 lblock = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); |
329 | 319 | ||
330 | do { | 320 | do { |
331 | bh.b_state = 0; | 321 | bh.b_state = 0; |
332 | bh.b_size = size; | 322 | bh.b_size = size; |
333 | gfs2_block_map(inode, lblock, &bh, 1); | 323 | gfs2_block_map(inode, lblock, &bh, 1); |
334 | if (!buffer_mapped(&bh)) | 324 | if (!buffer_mapped(&bh)) |
335 | return -EIO; | 325 | return -EIO; |
336 | size -= bh.b_size; | 326 | size -= bh.b_size; |
337 | lblock += (bh.b_size >> inode->i_blkbits); | 327 | lblock += (bh.b_size >> inode->i_blkbits); |
338 | } while(size > 0); | 328 | } while(size > 0); |
339 | return 0; | 329 | return 0; |
340 | } | 330 | } |
341 | 331 | ||
342 | /** | 332 | /** |
343 | * gfs2_page_mkwrite - Make a shared, mmap()ed, page writable | 333 | * gfs2_page_mkwrite - Make a shared, mmap()ed, page writable |
344 | * @vma: The virtual memory area | 334 | * @vma: The virtual memory area |
345 | * @page: The page which is about to become writable | 335 | * @page: The page which is about to become writable |
346 | * | 336 | * |
347 | * When the page becomes writable, we need to ensure that we have | 337 | * When the page becomes writable, we need to ensure that we have |
348 | * blocks allocated on disk to back that page. | 338 | * blocks allocated on disk to back that page. |
349 | */ | 339 | */ |
350 | 340 | ||
351 | static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) | 341 | static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) |
352 | { | 342 | { |
353 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; | 343 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; |
354 | struct gfs2_inode *ip = GFS2_I(inode); | 344 | struct gfs2_inode *ip = GFS2_I(inode); |
355 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 345 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
356 | unsigned long last_index; | 346 | unsigned long last_index; |
357 | u64 pos = page->index << (PAGE_CACHE_SIZE - inode->i_blkbits); | 347 | u64 pos = page->index << (PAGE_CACHE_SIZE - inode->i_blkbits); |
358 | unsigned int data_blocks, ind_blocks, rblocks; | 348 | unsigned int data_blocks, ind_blocks, rblocks; |
359 | int alloc_required = 0; | 349 | int alloc_required = 0; |
360 | struct gfs2_holder gh; | 350 | struct gfs2_holder gh; |
361 | struct gfs2_alloc *al; | 351 | struct gfs2_alloc *al; |
362 | int ret; | 352 | int ret; |
363 | 353 | ||
364 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME, &gh); | 354 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME, &gh); |
365 | ret = gfs2_glock_nq_atime(&gh); | 355 | ret = gfs2_glock_nq_atime(&gh); |
366 | if (ret) | 356 | if (ret) |
367 | goto out; | 357 | goto out; |
368 | 358 | ||
369 | set_bit(GIF_SW_PAGED, &ip->i_flags); | 359 | set_bit(GIF_SW_PAGED, &ip->i_flags); |
370 | gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); | 360 | gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); |
371 | ret = gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE, &alloc_required); | 361 | ret = gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE, &alloc_required); |
372 | if (ret || !alloc_required) | 362 | if (ret || !alloc_required) |
373 | goto out_unlock; | 363 | goto out_unlock; |
374 | ret = -ENOMEM; | 364 | ret = -ENOMEM; |
375 | al = gfs2_alloc_get(ip); | 365 | al = gfs2_alloc_get(ip); |
376 | if (al == NULL) | 366 | if (al == NULL) |
377 | goto out_unlock; | 367 | goto out_unlock; |
378 | 368 | ||
379 | ret = gfs2_quota_lock_check(ip); | 369 | ret = gfs2_quota_lock_check(ip); |
380 | if (ret) | 370 | if (ret) |
381 | goto out_alloc_put; | 371 | goto out_alloc_put; |
382 | al->al_requested = data_blocks + ind_blocks; | 372 | al->al_requested = data_blocks + ind_blocks; |
383 | ret = gfs2_inplace_reserve(ip); | 373 | ret = gfs2_inplace_reserve(ip); |
384 | if (ret) | 374 | if (ret) |
385 | goto out_quota_unlock; | 375 | goto out_quota_unlock; |
386 | 376 | ||
387 | rblocks = RES_DINODE + ind_blocks; | 377 | rblocks = RES_DINODE + ind_blocks; |
388 | if (gfs2_is_jdata(ip)) | 378 | if (gfs2_is_jdata(ip)) |
389 | rblocks += data_blocks ? data_blocks : 1; | 379 | rblocks += data_blocks ? data_blocks : 1; |
390 | if (ind_blocks || data_blocks) | 380 | if (ind_blocks || data_blocks) |
391 | rblocks += RES_STATFS + RES_QUOTA; | 381 | rblocks += RES_STATFS + RES_QUOTA; |
392 | ret = gfs2_trans_begin(sdp, rblocks, 0); | 382 | ret = gfs2_trans_begin(sdp, rblocks, 0); |
393 | if (ret) | 383 | if (ret) |
394 | goto out_trans_fail; | 384 | goto out_trans_fail; |
395 | 385 | ||
396 | lock_page(page); | 386 | lock_page(page); |
397 | ret = -EINVAL; | 387 | ret = -EINVAL; |
398 | last_index = ip->i_inode.i_size >> PAGE_CACHE_SHIFT; | 388 | last_index = ip->i_inode.i_size >> PAGE_CACHE_SHIFT; |
399 | if (page->index > last_index) | 389 | if (page->index > last_index) |
400 | goto out_unlock_page; | 390 | goto out_unlock_page; |
401 | ret = 0; | 391 | ret = 0; |
402 | if (!PageUptodate(page) || page->mapping != ip->i_inode.i_mapping) | 392 | if (!PageUptodate(page) || page->mapping != ip->i_inode.i_mapping) |
403 | goto out_unlock_page; | 393 | goto out_unlock_page; |
404 | if (gfs2_is_stuffed(ip)) { | 394 | if (gfs2_is_stuffed(ip)) { |
405 | ret = gfs2_unstuff_dinode(ip, page); | 395 | ret = gfs2_unstuff_dinode(ip, page); |
406 | if (ret) | 396 | if (ret) |
407 | goto out_unlock_page; | 397 | goto out_unlock_page; |
408 | } | 398 | } |
409 | ret = gfs2_allocate_page_backing(page); | 399 | ret = gfs2_allocate_page_backing(page); |
410 | 400 | ||
411 | out_unlock_page: | 401 | out_unlock_page: |
412 | unlock_page(page); | 402 | unlock_page(page); |
413 | gfs2_trans_end(sdp); | 403 | gfs2_trans_end(sdp); |
414 | out_trans_fail: | 404 | out_trans_fail: |
415 | gfs2_inplace_release(ip); | 405 | gfs2_inplace_release(ip); |
416 | out_quota_unlock: | 406 | out_quota_unlock: |
417 | gfs2_quota_unlock(ip); | 407 | gfs2_quota_unlock(ip); |
418 | out_alloc_put: | 408 | out_alloc_put: |
419 | gfs2_alloc_put(ip); | 409 | gfs2_alloc_put(ip); |
420 | out_unlock: | 410 | out_unlock: |
421 | gfs2_glock_dq(&gh); | 411 | gfs2_glock_dq(&gh); |
422 | out: | 412 | out: |
423 | gfs2_holder_uninit(&gh); | 413 | gfs2_holder_uninit(&gh); |
424 | return ret; | 414 | return ret; |
425 | } | 415 | } |
426 | 416 | ||
427 | static struct vm_operations_struct gfs2_vm_ops = { | 417 | static struct vm_operations_struct gfs2_vm_ops = { |
428 | .fault = filemap_fault, | 418 | .fault = filemap_fault, |
429 | .page_mkwrite = gfs2_page_mkwrite, | 419 | .page_mkwrite = gfs2_page_mkwrite, |
430 | }; | 420 | }; |
431 | 421 | ||
432 | 422 | ||
433 | /** | 423 | /** |
434 | * gfs2_mmap - | 424 | * gfs2_mmap - |
435 | * @file: The file to map | 425 | * @file: The file to map |
436 | * @vma: The VMA which described the mapping | 426 | * @vma: The VMA which described the mapping |
437 | * | 427 | * |
438 | * Returns: 0 or error code | 428 | * Returns: 0 or error code |
439 | */ | 429 | */ |
440 | 430 | ||
441 | static int gfs2_mmap(struct file *file, struct vm_area_struct *vma) | 431 | static int gfs2_mmap(struct file *file, struct vm_area_struct *vma) |
442 | { | 432 | { |
443 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); | 433 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); |
444 | struct gfs2_holder i_gh; | 434 | struct gfs2_holder i_gh; |
445 | int error; | 435 | int error; |
446 | 436 | ||
447 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh); | 437 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh); |
448 | error = gfs2_glock_nq_atime(&i_gh); | 438 | error = gfs2_glock_nq_atime(&i_gh); |
449 | if (error) { | 439 | if (error) { |
450 | gfs2_holder_uninit(&i_gh); | 440 | gfs2_holder_uninit(&i_gh); |
451 | return error; | 441 | return error; |
452 | } | 442 | } |
453 | 443 | ||
454 | vma->vm_ops = &gfs2_vm_ops; | 444 | vma->vm_ops = &gfs2_vm_ops; |
455 | 445 | ||
456 | gfs2_glock_dq_uninit(&i_gh); | 446 | gfs2_glock_dq_uninit(&i_gh); |
457 | 447 | ||
458 | return error; | 448 | return error; |
459 | } | 449 | } |
460 | 450 | ||
461 | /** | 451 | /** |
462 | * gfs2_open - open a file | 452 | * gfs2_open - open a file |
463 | * @inode: the inode to open | 453 | * @inode: the inode to open |
464 | * @file: the struct file for this opening | 454 | * @file: the struct file for this opening |
465 | * | 455 | * |
466 | * Returns: errno | 456 | * Returns: errno |
467 | */ | 457 | */ |
468 | 458 | ||
469 | static int gfs2_open(struct inode *inode, struct file *file) | 459 | static int gfs2_open(struct inode *inode, struct file *file) |
470 | { | 460 | { |
471 | struct gfs2_inode *ip = GFS2_I(inode); | 461 | struct gfs2_inode *ip = GFS2_I(inode); |
472 | struct gfs2_holder i_gh; | 462 | struct gfs2_holder i_gh; |
473 | struct gfs2_file *fp; | 463 | struct gfs2_file *fp; |
474 | int error; | 464 | int error; |
475 | 465 | ||
476 | fp = kzalloc(sizeof(struct gfs2_file), GFP_KERNEL); | 466 | fp = kzalloc(sizeof(struct gfs2_file), GFP_KERNEL); |
477 | if (!fp) | 467 | if (!fp) |
478 | return -ENOMEM; | 468 | return -ENOMEM; |
479 | 469 | ||
480 | mutex_init(&fp->f_fl_mutex); | 470 | mutex_init(&fp->f_fl_mutex); |
481 | 471 | ||
482 | gfs2_assert_warn(GFS2_SB(inode), !file->private_data); | 472 | gfs2_assert_warn(GFS2_SB(inode), !file->private_data); |
483 | file->private_data = fp; | 473 | file->private_data = fp; |
484 | 474 | ||
485 | if (S_ISREG(ip->i_inode.i_mode)) { | 475 | if (S_ISREG(ip->i_inode.i_mode)) { |
486 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, | 476 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, |
487 | &i_gh); | 477 | &i_gh); |
488 | if (error) | 478 | if (error) |
489 | goto fail; | 479 | goto fail; |
490 | 480 | ||
491 | if (!(file->f_flags & O_LARGEFILE) && | 481 | if (!(file->f_flags & O_LARGEFILE) && |
492 | ip->i_di.di_size > MAX_NON_LFS) { | 482 | ip->i_di.di_size > MAX_NON_LFS) { |
493 | error = -EOVERFLOW; | 483 | error = -EOVERFLOW; |
494 | goto fail_gunlock; | 484 | goto fail_gunlock; |
495 | } | 485 | } |
496 | |||
497 | /* Listen to the Direct I/O flag */ | ||
498 | |||
499 | if (ip->i_di.di_flags & GFS2_DIF_DIRECTIO) | ||
500 | file->f_flags |= O_DIRECT; | ||
501 | 486 | ||
502 | gfs2_glock_dq_uninit(&i_gh); | 487 | gfs2_glock_dq_uninit(&i_gh); |
503 | } | 488 | } |
504 | 489 | ||
505 | return 0; | 490 | return 0; |
506 | 491 | ||
507 | fail_gunlock: | 492 | fail_gunlock: |
508 | gfs2_glock_dq_uninit(&i_gh); | 493 | gfs2_glock_dq_uninit(&i_gh); |
509 | fail: | 494 | fail: |
510 | file->private_data = NULL; | 495 | file->private_data = NULL; |
511 | kfree(fp); | 496 | kfree(fp); |
512 | return error; | 497 | return error; |
513 | } | 498 | } |
514 | 499 | ||
515 | /** | 500 | /** |
516 | * gfs2_close - called to close a struct file | 501 | * gfs2_close - called to close a struct file |
517 | * @inode: the inode the struct file belongs to | 502 | * @inode: the inode the struct file belongs to |
518 | * @file: the struct file being closed | 503 | * @file: the struct file being closed |
519 | * | 504 | * |
520 | * Returns: errno | 505 | * Returns: errno |
521 | */ | 506 | */ |
522 | 507 | ||
523 | static int gfs2_close(struct inode *inode, struct file *file) | 508 | static int gfs2_close(struct inode *inode, struct file *file) |
524 | { | 509 | { |
525 | struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; | 510 | struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; |
526 | struct gfs2_file *fp; | 511 | struct gfs2_file *fp; |
527 | 512 | ||
528 | fp = file->private_data; | 513 | fp = file->private_data; |
529 | file->private_data = NULL; | 514 | file->private_data = NULL; |
530 | 515 | ||
531 | if (gfs2_assert_warn(sdp, fp)) | 516 | if (gfs2_assert_warn(sdp, fp)) |
532 | return -EIO; | 517 | return -EIO; |
533 | 518 | ||
534 | kfree(fp); | 519 | kfree(fp); |
535 | 520 | ||
536 | return 0; | 521 | return 0; |
537 | } | 522 | } |
538 | 523 | ||
539 | /** | 524 | /** |
540 | * gfs2_fsync - sync the dirty data for a file (across the cluster) | 525 | * gfs2_fsync - sync the dirty data for a file (across the cluster) |
541 | * @file: the file that points to the dentry (we ignore this) | 526 | * @file: the file that points to the dentry (we ignore this) |
542 | * @dentry: the dentry that points to the inode to sync | 527 | * @dentry: the dentry that points to the inode to sync |
543 | * | 528 | * |
544 | * The VFS will flush "normal" data for us. We only need to worry | 529 | * The VFS will flush "normal" data for us. We only need to worry |
545 | * about metadata here. For journaled data, we just do a log flush | 530 | * about metadata here. For journaled data, we just do a log flush |
546 | * as we can't avoid it. Otherwise we can just bale out if datasync | 531 | * as we can't avoid it. Otherwise we can just bale out if datasync |
547 | * is set. For stuffed inodes we must flush the log in order to | 532 | * is set. For stuffed inodes we must flush the log in order to |
548 | * ensure that all data is on disk. | 533 | * ensure that all data is on disk. |
549 | * | 534 | * |
550 | * The call to write_inode_now() is there to write back metadata and | 535 | * The call to write_inode_now() is there to write back metadata and |
551 | * the inode itself. It does also try and write the data, but thats | 536 | * the inode itself. It does also try and write the data, but thats |
552 | * (hopefully) a no-op due to the VFS having already called filemap_fdatawrite() | 537 | * (hopefully) a no-op due to the VFS having already called filemap_fdatawrite() |
553 | * for us. | 538 | * for us. |
554 | * | 539 | * |
555 | * Returns: errno | 540 | * Returns: errno |
556 | */ | 541 | */ |
557 | 542 | ||
558 | static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) | 543 | static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) |
559 | { | 544 | { |
560 | struct inode *inode = dentry->d_inode; | 545 | struct inode *inode = dentry->d_inode; |
561 | int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); | 546 | int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); |
562 | int ret = 0; | 547 | int ret = 0; |
563 | 548 | ||
564 | if (gfs2_is_jdata(GFS2_I(inode))) { | 549 | if (gfs2_is_jdata(GFS2_I(inode))) { |
565 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); | 550 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); |
566 | return 0; | 551 | return 0; |
567 | } | 552 | } |
568 | 553 | ||
569 | if (sync_state != 0) { | 554 | if (sync_state != 0) { |
570 | if (!datasync) | 555 | if (!datasync) |
571 | ret = write_inode_now(inode, 0); | 556 | ret = write_inode_now(inode, 0); |
572 | 557 | ||
573 | if (gfs2_is_stuffed(GFS2_I(inode))) | 558 | if (gfs2_is_stuffed(GFS2_I(inode))) |
574 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); | 559 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); |
575 | } | 560 | } |
576 | 561 | ||
577 | return ret; | 562 | return ret; |
578 | } | 563 | } |
579 | 564 | ||
580 | /** | 565 | /** |
581 | * gfs2_setlease - acquire/release a file lease | 566 | * gfs2_setlease - acquire/release a file lease |
582 | * @file: the file pointer | 567 | * @file: the file pointer |
583 | * @arg: lease type | 568 | * @arg: lease type |
584 | * @fl: file lock | 569 | * @fl: file lock |
585 | * | 570 | * |
586 | * Returns: errno | 571 | * Returns: errno |
587 | */ | 572 | */ |
588 | 573 | ||
589 | static int gfs2_setlease(struct file *file, long arg, struct file_lock **fl) | 574 | static int gfs2_setlease(struct file *file, long arg, struct file_lock **fl) |
590 | { | 575 | { |
591 | struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host); | 576 | struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host); |
592 | 577 | ||
593 | /* | 578 | /* |
594 | * We don't currently have a way to enforce a lease across the whole | 579 | * We don't currently have a way to enforce a lease across the whole |
595 | * cluster; until we do, disable leases (by just returning -EINVAL), | 580 | * cluster; until we do, disable leases (by just returning -EINVAL), |
596 | * unless the administrator has requested purely local locking. | 581 | * unless the administrator has requested purely local locking. |
597 | */ | 582 | */ |
598 | if (!sdp->sd_args.ar_localflocks) | 583 | if (!sdp->sd_args.ar_localflocks) |
599 | return -EINVAL; | 584 | return -EINVAL; |
600 | return generic_setlease(file, arg, fl); | 585 | return generic_setlease(file, arg, fl); |
601 | } | 586 | } |
602 | 587 | ||
603 | static int gfs2_lm_plock_get(struct gfs2_sbd *sdp, struct lm_lockname *name, | 588 | static int gfs2_lm_plock_get(struct gfs2_sbd *sdp, struct lm_lockname *name, |
604 | struct file *file, struct file_lock *fl) | 589 | struct file *file, struct file_lock *fl) |
605 | { | 590 | { |
606 | int error = -EIO; | 591 | int error = -EIO; |
607 | if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | 592 | if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) |
608 | error = sdp->sd_lockstruct.ls_ops->lm_plock_get( | 593 | error = sdp->sd_lockstruct.ls_ops->lm_plock_get( |
609 | sdp->sd_lockstruct.ls_lockspace, name, file, fl); | 594 | sdp->sd_lockstruct.ls_lockspace, name, file, fl); |
610 | return error; | 595 | return error; |
611 | } | 596 | } |
612 | 597 | ||
613 | static int gfs2_lm_plock(struct gfs2_sbd *sdp, struct lm_lockname *name, | 598 | static int gfs2_lm_plock(struct gfs2_sbd *sdp, struct lm_lockname *name, |
614 | struct file *file, int cmd, struct file_lock *fl) | 599 | struct file *file, int cmd, struct file_lock *fl) |
615 | { | 600 | { |
616 | int error = -EIO; | 601 | int error = -EIO; |
617 | if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | 602 | if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) |
618 | error = sdp->sd_lockstruct.ls_ops->lm_plock( | 603 | error = sdp->sd_lockstruct.ls_ops->lm_plock( |
619 | sdp->sd_lockstruct.ls_lockspace, name, file, cmd, fl); | 604 | sdp->sd_lockstruct.ls_lockspace, name, file, cmd, fl); |
620 | return error; | 605 | return error; |
621 | } | 606 | } |
622 | 607 | ||
623 | static int gfs2_lm_punlock(struct gfs2_sbd *sdp, struct lm_lockname *name, | 608 | static int gfs2_lm_punlock(struct gfs2_sbd *sdp, struct lm_lockname *name, |
624 | struct file *file, struct file_lock *fl) | 609 | struct file *file, struct file_lock *fl) |
625 | { | 610 | { |
626 | int error = -EIO; | 611 | int error = -EIO; |
627 | if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | 612 | if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) |
628 | error = sdp->sd_lockstruct.ls_ops->lm_punlock( | 613 | error = sdp->sd_lockstruct.ls_ops->lm_punlock( |
629 | sdp->sd_lockstruct.ls_lockspace, name, file, fl); | 614 | sdp->sd_lockstruct.ls_lockspace, name, file, fl); |
630 | return error; | 615 | return error; |
631 | } | 616 | } |
632 | 617 | ||
633 | /** | 618 | /** |
634 | * gfs2_lock - acquire/release a posix lock on a file | 619 | * gfs2_lock - acquire/release a posix lock on a file |
635 | * @file: the file pointer | 620 | * @file: the file pointer |
636 | * @cmd: either modify or retrieve lock state, possibly wait | 621 | * @cmd: either modify or retrieve lock state, possibly wait |
637 | * @fl: type and range of lock | 622 | * @fl: type and range of lock |
638 | * | 623 | * |
639 | * Returns: errno | 624 | * Returns: errno |
640 | */ | 625 | */ |
641 | 626 | ||
642 | static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) | 627 | static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) |
643 | { | 628 | { |
644 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); | 629 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); |
645 | struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host); | 630 | struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host); |
646 | struct lm_lockname name = | 631 | struct lm_lockname name = |
647 | { .ln_number = ip->i_no_addr, | 632 | { .ln_number = ip->i_no_addr, |
648 | .ln_type = LM_TYPE_PLOCK }; | 633 | .ln_type = LM_TYPE_PLOCK }; |
649 | 634 | ||
650 | if (!(fl->fl_flags & FL_POSIX)) | 635 | if (!(fl->fl_flags & FL_POSIX)) |
651 | return -ENOLCK; | 636 | return -ENOLCK; |
652 | if (__mandatory_lock(&ip->i_inode)) | 637 | if (__mandatory_lock(&ip->i_inode)) |
653 | return -ENOLCK; | 638 | return -ENOLCK; |
654 | 639 | ||
655 | if (cmd == F_CANCELLK) { | 640 | if (cmd == F_CANCELLK) { |
656 | /* Hack: */ | 641 | /* Hack: */ |
657 | cmd = F_SETLK; | 642 | cmd = F_SETLK; |
658 | fl->fl_type = F_UNLCK; | 643 | fl->fl_type = F_UNLCK; |
659 | } | 644 | } |
660 | if (IS_GETLK(cmd)) | 645 | if (IS_GETLK(cmd)) |
661 | return gfs2_lm_plock_get(sdp, &name, file, fl); | 646 | return gfs2_lm_plock_get(sdp, &name, file, fl); |
662 | else if (fl->fl_type == F_UNLCK) | 647 | else if (fl->fl_type == F_UNLCK) |
663 | return gfs2_lm_punlock(sdp, &name, file, fl); | 648 | return gfs2_lm_punlock(sdp, &name, file, fl); |
664 | else | 649 | else |
665 | return gfs2_lm_plock(sdp, &name, file, cmd, fl); | 650 | return gfs2_lm_plock(sdp, &name, file, cmd, fl); |
666 | } | 651 | } |
667 | 652 | ||
668 | static int do_flock(struct file *file, int cmd, struct file_lock *fl) | 653 | static int do_flock(struct file *file, int cmd, struct file_lock *fl) |
669 | { | 654 | { |
670 | struct gfs2_file *fp = file->private_data; | 655 | struct gfs2_file *fp = file->private_data; |
671 | struct gfs2_holder *fl_gh = &fp->f_fl_gh; | 656 | struct gfs2_holder *fl_gh = &fp->f_fl_gh; |
672 | struct gfs2_inode *ip = GFS2_I(file->f_path.dentry->d_inode); | 657 | struct gfs2_inode *ip = GFS2_I(file->f_path.dentry->d_inode); |
673 | struct gfs2_glock *gl; | 658 | struct gfs2_glock *gl; |
674 | unsigned int state; | 659 | unsigned int state; |
675 | int flags; | 660 | int flags; |
676 | int error = 0; | 661 | int error = 0; |
677 | 662 | ||
678 | state = (fl->fl_type == F_WRLCK) ? LM_ST_EXCLUSIVE : LM_ST_SHARED; | 663 | state = (fl->fl_type == F_WRLCK) ? LM_ST_EXCLUSIVE : LM_ST_SHARED; |
679 | flags = (IS_SETLKW(cmd) ? 0 : LM_FLAG_TRY) | GL_EXACT | GL_NOCACHE; | 664 | flags = (IS_SETLKW(cmd) ? 0 : LM_FLAG_TRY) | GL_EXACT | GL_NOCACHE; |
680 | 665 | ||
681 | mutex_lock(&fp->f_fl_mutex); | 666 | mutex_lock(&fp->f_fl_mutex); |
682 | 667 | ||
683 | gl = fl_gh->gh_gl; | 668 | gl = fl_gh->gh_gl; |
684 | if (gl) { | 669 | if (gl) { |
685 | if (fl_gh->gh_state == state) | 670 | if (fl_gh->gh_state == state) |
686 | goto out; | 671 | goto out; |
687 | flock_lock_file_wait(file, | 672 | flock_lock_file_wait(file, |
688 | &(struct file_lock){.fl_type = F_UNLCK}); | 673 | &(struct file_lock){.fl_type = F_UNLCK}); |
689 | gfs2_glock_dq_wait(fl_gh); | 674 | gfs2_glock_dq_wait(fl_gh); |
690 | gfs2_holder_reinit(state, flags, fl_gh); | 675 | gfs2_holder_reinit(state, flags, fl_gh); |
691 | } else { | 676 | } else { |
692 | error = gfs2_glock_get(GFS2_SB(&ip->i_inode), ip->i_no_addr, | 677 | error = gfs2_glock_get(GFS2_SB(&ip->i_inode), ip->i_no_addr, |
693 | &gfs2_flock_glops, CREATE, &gl); | 678 | &gfs2_flock_glops, CREATE, &gl); |
694 | if (error) | 679 | if (error) |
695 | goto out; | 680 | goto out; |
696 | gfs2_holder_init(gl, state, flags, fl_gh); | 681 | gfs2_holder_init(gl, state, flags, fl_gh); |
697 | gfs2_glock_put(gl); | 682 | gfs2_glock_put(gl); |
698 | } | 683 | } |
699 | error = gfs2_glock_nq(fl_gh); | 684 | error = gfs2_glock_nq(fl_gh); |
700 | if (error) { | 685 | if (error) { |
701 | gfs2_holder_uninit(fl_gh); | 686 | gfs2_holder_uninit(fl_gh); |
702 | if (error == GLR_TRYFAILED) | 687 | if (error == GLR_TRYFAILED) |
703 | error = -EAGAIN; | 688 | error = -EAGAIN; |
704 | } else { | 689 | } else { |
705 | error = flock_lock_file_wait(file, fl); | 690 | error = flock_lock_file_wait(file, fl); |
706 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); | 691 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); |
707 | } | 692 | } |
708 | 693 | ||
709 | out: | 694 | out: |
710 | mutex_unlock(&fp->f_fl_mutex); | 695 | mutex_unlock(&fp->f_fl_mutex); |
711 | return error; | 696 | return error; |
712 | } | 697 | } |
713 | 698 | ||
714 | static void do_unflock(struct file *file, struct file_lock *fl) | 699 | static void do_unflock(struct file *file, struct file_lock *fl) |
715 | { | 700 | { |
716 | struct gfs2_file *fp = file->private_data; | 701 | struct gfs2_file *fp = file->private_data; |
717 | struct gfs2_holder *fl_gh = &fp->f_fl_gh; | 702 | struct gfs2_holder *fl_gh = &fp->f_fl_gh; |
718 | 703 | ||
719 | mutex_lock(&fp->f_fl_mutex); | 704 | mutex_lock(&fp->f_fl_mutex); |
720 | flock_lock_file_wait(file, fl); | 705 | flock_lock_file_wait(file, fl); |
721 | if (fl_gh->gh_gl) | 706 | if (fl_gh->gh_gl) |
722 | gfs2_glock_dq_uninit(fl_gh); | 707 | gfs2_glock_dq_uninit(fl_gh); |
723 | mutex_unlock(&fp->f_fl_mutex); | 708 | mutex_unlock(&fp->f_fl_mutex); |
724 | } | 709 | } |
725 | 710 | ||
726 | /** | 711 | /** |
727 | * gfs2_flock - acquire/release a flock lock on a file | 712 | * gfs2_flock - acquire/release a flock lock on a file |
728 | * @file: the file pointer | 713 | * @file: the file pointer |
729 | * @cmd: either modify or retrieve lock state, possibly wait | 714 | * @cmd: either modify or retrieve lock state, possibly wait |
730 | * @fl: type and range of lock | 715 | * @fl: type and range of lock |
731 | * | 716 | * |
732 | * Returns: errno | 717 | * Returns: errno |
733 | */ | 718 | */ |
734 | 719 | ||
735 | static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl) | 720 | static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl) |
736 | { | 721 | { |
737 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); | 722 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); |
738 | 723 | ||
739 | if (!(fl->fl_flags & FL_FLOCK)) | 724 | if (!(fl->fl_flags & FL_FLOCK)) |
740 | return -ENOLCK; | 725 | return -ENOLCK; |
741 | if (__mandatory_lock(&ip->i_inode)) | 726 | if (__mandatory_lock(&ip->i_inode)) |
742 | return -ENOLCK; | 727 | return -ENOLCK; |
743 | 728 | ||
744 | if (fl->fl_type == F_UNLCK) { | 729 | if (fl->fl_type == F_UNLCK) { |
745 | do_unflock(file, fl); | 730 | do_unflock(file, fl); |
746 | return 0; | 731 | return 0; |
747 | } else { | 732 | } else { |
748 | return do_flock(file, cmd, fl); | 733 | return do_flock(file, cmd, fl); |
749 | } | 734 | } |
750 | } | 735 | } |
751 | 736 | ||
752 | const struct file_operations gfs2_file_fops = { | 737 | const struct file_operations gfs2_file_fops = { |
753 | .llseek = gfs2_llseek, | 738 | .llseek = gfs2_llseek, |
754 | .read = do_sync_read, | 739 | .read = do_sync_read, |
755 | .aio_read = generic_file_aio_read, | 740 | .aio_read = generic_file_aio_read, |
756 | .write = do_sync_write, | 741 | .write = do_sync_write, |
757 | .aio_write = generic_file_aio_write, | 742 | .aio_write = generic_file_aio_write, |
758 | .unlocked_ioctl = gfs2_ioctl, | 743 | .unlocked_ioctl = gfs2_ioctl, |
759 | .mmap = gfs2_mmap, | 744 | .mmap = gfs2_mmap, |
760 | .open = gfs2_open, | 745 | .open = gfs2_open, |
761 | .release = gfs2_close, | 746 | .release = gfs2_close, |
762 | .fsync = gfs2_fsync, | 747 | .fsync = gfs2_fsync, |
763 | .lock = gfs2_lock, | 748 | .lock = gfs2_lock, |
764 | .flock = gfs2_flock, | 749 | .flock = gfs2_flock, |
765 | .splice_read = generic_file_splice_read, | 750 | .splice_read = generic_file_splice_read, |
766 | .splice_write = generic_file_splice_write, | 751 | .splice_write = generic_file_splice_write, |
767 | .setlease = gfs2_setlease, | 752 | .setlease = gfs2_setlease, |
768 | }; | 753 | }; |
769 | 754 | ||
770 | const struct file_operations gfs2_dir_fops = { | 755 | const struct file_operations gfs2_dir_fops = { |
771 | .readdir = gfs2_readdir, | 756 | .readdir = gfs2_readdir, |
772 | .unlocked_ioctl = gfs2_ioctl, | 757 | .unlocked_ioctl = gfs2_ioctl, |
773 | .open = gfs2_open, | 758 | .open = gfs2_open, |
774 | .release = gfs2_close, | 759 | .release = gfs2_close, |
775 | .fsync = gfs2_fsync, | 760 | .fsync = gfs2_fsync, |
776 | .lock = gfs2_lock, | 761 | .lock = gfs2_lock, |
777 | .flock = gfs2_flock, | 762 | .flock = gfs2_flock, |
778 | }; | 763 | }; |
779 | 764 | ||
780 | const struct file_operations gfs2_file_fops_nolock = { | 765 | const struct file_operations gfs2_file_fops_nolock = { |
781 | .llseek = gfs2_llseek, | 766 | .llseek = gfs2_llseek, |
782 | .read = do_sync_read, | 767 | .read = do_sync_read, |
783 | .aio_read = generic_file_aio_read, | 768 | .aio_read = generic_file_aio_read, |
784 | .write = do_sync_write, | 769 | .write = do_sync_write, |
785 | .aio_write = generic_file_aio_write, | 770 | .aio_write = generic_file_aio_write, |
786 | .unlocked_ioctl = gfs2_ioctl, | 771 | .unlocked_ioctl = gfs2_ioctl, |
787 | .mmap = gfs2_mmap, | 772 | .mmap = gfs2_mmap, |
788 | .open = gfs2_open, | 773 | .open = gfs2_open, |
789 | .release = gfs2_close, | 774 | .release = gfs2_close, |
790 | .fsync = gfs2_fsync, | 775 | .fsync = gfs2_fsync, |
791 | .splice_read = generic_file_splice_read, | 776 | .splice_read = generic_file_splice_read, |
792 | .splice_write = generic_file_splice_write, | 777 | .splice_write = generic_file_splice_write, |
793 | .setlease = gfs2_setlease, | 778 | .setlease = gfs2_setlease, |
794 | }; | 779 | }; |
795 | 780 | ||
796 | const struct file_operations gfs2_dir_fops_nolock = { | 781 | const struct file_operations gfs2_dir_fops_nolock = { |
797 | .readdir = gfs2_readdir, | 782 | .readdir = gfs2_readdir, |
798 | .unlocked_ioctl = gfs2_ioctl, | 783 | .unlocked_ioctl = gfs2_ioctl, |
799 | .open = gfs2_open, | 784 | .open = gfs2_open, |
800 | .release = gfs2_close, | 785 | .release = gfs2_close, |
801 | .fsync = gfs2_fsync, | 786 | .fsync = gfs2_fsync, |
802 | }; | 787 | }; |
803 | 788 | ||
804 | 789 |
fs/gfs2/super.c
1 | /* | 1 | /* |
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. | 3 | * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This copyrighted material is made available to anyone wishing to use, | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | * modify, copy, or redistribute it subject to the terms and conditions | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
7 | * of the GNU General Public License version 2. | 7 | * of the GNU General Public License version 2. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
13 | #include <linux/completion.h> | 13 | #include <linux/completion.h> |
14 | #include <linux/buffer_head.h> | 14 | #include <linux/buffer_head.h> |
15 | #include <linux/crc32.h> | 15 | #include <linux/crc32.h> |
16 | #include <linux/gfs2_ondisk.h> | 16 | #include <linux/gfs2_ondisk.h> |
17 | #include <linux/bio.h> | 17 | #include <linux/bio.h> |
18 | #include <linux/lm_interface.h> | 18 | #include <linux/lm_interface.h> |
19 | 19 | ||
20 | #include "gfs2.h" | 20 | #include "gfs2.h" |
21 | #include "incore.h" | 21 | #include "incore.h" |
22 | #include "bmap.h" | 22 | #include "bmap.h" |
23 | #include "dir.h" | 23 | #include "dir.h" |
24 | #include "glock.h" | 24 | #include "glock.h" |
25 | #include "glops.h" | 25 | #include "glops.h" |
26 | #include "inode.h" | 26 | #include "inode.h" |
27 | #include "log.h" | 27 | #include "log.h" |
28 | #include "meta_io.h" | 28 | #include "meta_io.h" |
29 | #include "quota.h" | 29 | #include "quota.h" |
30 | #include "recovery.h" | 30 | #include "recovery.h" |
31 | #include "rgrp.h" | 31 | #include "rgrp.h" |
32 | #include "super.h" | 32 | #include "super.h" |
33 | #include "trans.h" | 33 | #include "trans.h" |
34 | #include "util.h" | 34 | #include "util.h" |
35 | 35 | ||
36 | static const u32 gfs2_old_fs_formats[] = { | 36 | static const u32 gfs2_old_fs_formats[] = { |
37 | 0 | 37 | 0 |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static const u32 gfs2_old_multihost_formats[] = { | 40 | static const u32 gfs2_old_multihost_formats[] = { |
41 | 0 | 41 | 0 |
42 | }; | 42 | }; |
43 | 43 | ||
44 | /** | 44 | /** |
45 | * gfs2_tune_init - Fill a gfs2_tune structure with default values | 45 | * gfs2_tune_init - Fill a gfs2_tune structure with default values |
46 | * @gt: tune | 46 | * @gt: tune |
47 | * | 47 | * |
48 | */ | 48 | */ |
49 | 49 | ||
50 | void gfs2_tune_init(struct gfs2_tune *gt) | 50 | void gfs2_tune_init(struct gfs2_tune *gt) |
51 | { | 51 | { |
52 | spin_lock_init(>->gt_spin); | 52 | spin_lock_init(>->gt_spin); |
53 | 53 | ||
54 | gt->gt_demote_secs = 300; | 54 | gt->gt_demote_secs = 300; |
55 | gt->gt_incore_log_blocks = 1024; | 55 | gt->gt_incore_log_blocks = 1024; |
56 | gt->gt_log_flush_secs = 60; | 56 | gt->gt_log_flush_secs = 60; |
57 | gt->gt_recoverd_secs = 60; | 57 | gt->gt_recoverd_secs = 60; |
58 | gt->gt_logd_secs = 1; | 58 | gt->gt_logd_secs = 1; |
59 | gt->gt_quotad_secs = 5; | 59 | gt->gt_quotad_secs = 5; |
60 | gt->gt_quota_simul_sync = 64; | 60 | gt->gt_quota_simul_sync = 64; |
61 | gt->gt_quota_warn_period = 10; | 61 | gt->gt_quota_warn_period = 10; |
62 | gt->gt_quota_scale_num = 1; | 62 | gt->gt_quota_scale_num = 1; |
63 | gt->gt_quota_scale_den = 1; | 63 | gt->gt_quota_scale_den = 1; |
64 | gt->gt_quota_cache_secs = 300; | 64 | gt->gt_quota_cache_secs = 300; |
65 | gt->gt_quota_quantum = 60; | 65 | gt->gt_quota_quantum = 60; |
66 | gt->gt_atime_quantum = 3600; | 66 | gt->gt_atime_quantum = 3600; |
67 | gt->gt_new_files_jdata = 0; | 67 | gt->gt_new_files_jdata = 0; |
68 | gt->gt_new_files_directio = 0; | ||
69 | gt->gt_max_readahead = 1 << 18; | 68 | gt->gt_max_readahead = 1 << 18; |
70 | gt->gt_stall_secs = 600; | 69 | gt->gt_stall_secs = 600; |
71 | gt->gt_complain_secs = 10; | 70 | gt->gt_complain_secs = 10; |
72 | gt->gt_statfs_quantum = 30; | 71 | gt->gt_statfs_quantum = 30; |
73 | gt->gt_statfs_slow = 0; | 72 | gt->gt_statfs_slow = 0; |
74 | } | 73 | } |
75 | 74 | ||
76 | /** | 75 | /** |
77 | * gfs2_check_sb - Check superblock | 76 | * gfs2_check_sb - Check superblock |
78 | * @sdp: the filesystem | 77 | * @sdp: the filesystem |
79 | * @sb: The superblock | 78 | * @sb: The superblock |
80 | * @silent: Don't print a message if the check fails | 79 | * @silent: Don't print a message if the check fails |
81 | * | 80 | * |
82 | * Checks the version code of the FS is one that we understand how to | 81 | * Checks the version code of the FS is one that we understand how to |
83 | * read and that the sizes of the various on-disk structures have not | 82 | * read and that the sizes of the various on-disk structures have not |
84 | * changed. | 83 | * changed. |
85 | */ | 84 | */ |
86 | 85 | ||
87 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent) | 86 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent) |
88 | { | 87 | { |
89 | unsigned int x; | 88 | unsigned int x; |
90 | 89 | ||
91 | if (sb->sb_magic != GFS2_MAGIC || | 90 | if (sb->sb_magic != GFS2_MAGIC || |
92 | sb->sb_type != GFS2_METATYPE_SB) { | 91 | sb->sb_type != GFS2_METATYPE_SB) { |
93 | if (!silent) | 92 | if (!silent) |
94 | printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n"); | 93 | printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n"); |
95 | return -EINVAL; | 94 | return -EINVAL; |
96 | } | 95 | } |
97 | 96 | ||
98 | /* If format numbers match exactly, we're done. */ | 97 | /* If format numbers match exactly, we're done. */ |
99 | 98 | ||
100 | if (sb->sb_fs_format == GFS2_FORMAT_FS && | 99 | if (sb->sb_fs_format == GFS2_FORMAT_FS && |
101 | sb->sb_multihost_format == GFS2_FORMAT_MULTI) | 100 | sb->sb_multihost_format == GFS2_FORMAT_MULTI) |
102 | return 0; | 101 | return 0; |
103 | 102 | ||
104 | if (sb->sb_fs_format != GFS2_FORMAT_FS) { | 103 | if (sb->sb_fs_format != GFS2_FORMAT_FS) { |
105 | for (x = 0; gfs2_old_fs_formats[x]; x++) | 104 | for (x = 0; gfs2_old_fs_formats[x]; x++) |
106 | if (gfs2_old_fs_formats[x] == sb->sb_fs_format) | 105 | if (gfs2_old_fs_formats[x] == sb->sb_fs_format) |
107 | break; | 106 | break; |
108 | 107 | ||
109 | if (!gfs2_old_fs_formats[x]) { | 108 | if (!gfs2_old_fs_formats[x]) { |
110 | printk(KERN_WARNING | 109 | printk(KERN_WARNING |
111 | "GFS2: code version (%u, %u) is incompatible " | 110 | "GFS2: code version (%u, %u) is incompatible " |
112 | "with ondisk format (%u, %u)\n", | 111 | "with ondisk format (%u, %u)\n", |
113 | GFS2_FORMAT_FS, GFS2_FORMAT_MULTI, | 112 | GFS2_FORMAT_FS, GFS2_FORMAT_MULTI, |
114 | sb->sb_fs_format, sb->sb_multihost_format); | 113 | sb->sb_fs_format, sb->sb_multihost_format); |
115 | printk(KERN_WARNING | 114 | printk(KERN_WARNING |
116 | "GFS2: I don't know how to upgrade this FS\n"); | 115 | "GFS2: I don't know how to upgrade this FS\n"); |
117 | return -EINVAL; | 116 | return -EINVAL; |
118 | } | 117 | } |
119 | } | 118 | } |
120 | 119 | ||
121 | if (sb->sb_multihost_format != GFS2_FORMAT_MULTI) { | 120 | if (sb->sb_multihost_format != GFS2_FORMAT_MULTI) { |
122 | for (x = 0; gfs2_old_multihost_formats[x]; x++) | 121 | for (x = 0; gfs2_old_multihost_formats[x]; x++) |
123 | if (gfs2_old_multihost_formats[x] == | 122 | if (gfs2_old_multihost_formats[x] == |
124 | sb->sb_multihost_format) | 123 | sb->sb_multihost_format) |
125 | break; | 124 | break; |
126 | 125 | ||
127 | if (!gfs2_old_multihost_formats[x]) { | 126 | if (!gfs2_old_multihost_formats[x]) { |
128 | printk(KERN_WARNING | 127 | printk(KERN_WARNING |
129 | "GFS2: code version (%u, %u) is incompatible " | 128 | "GFS2: code version (%u, %u) is incompatible " |
130 | "with ondisk format (%u, %u)\n", | 129 | "with ondisk format (%u, %u)\n", |
131 | GFS2_FORMAT_FS, GFS2_FORMAT_MULTI, | 130 | GFS2_FORMAT_FS, GFS2_FORMAT_MULTI, |
132 | sb->sb_fs_format, sb->sb_multihost_format); | 131 | sb->sb_fs_format, sb->sb_multihost_format); |
133 | printk(KERN_WARNING | 132 | printk(KERN_WARNING |
134 | "GFS2: I don't know how to upgrade this FS\n"); | 133 | "GFS2: I don't know how to upgrade this FS\n"); |
135 | return -EINVAL; | 134 | return -EINVAL; |
136 | } | 135 | } |
137 | } | 136 | } |
138 | 137 | ||
139 | if (!sdp->sd_args.ar_upgrade) { | 138 | if (!sdp->sd_args.ar_upgrade) { |
140 | printk(KERN_WARNING | 139 | printk(KERN_WARNING |
141 | "GFS2: code version (%u, %u) is incompatible " | 140 | "GFS2: code version (%u, %u) is incompatible " |
142 | "with ondisk format (%u, %u)\n", | 141 | "with ondisk format (%u, %u)\n", |
143 | GFS2_FORMAT_FS, GFS2_FORMAT_MULTI, | 142 | GFS2_FORMAT_FS, GFS2_FORMAT_MULTI, |
144 | sb->sb_fs_format, sb->sb_multihost_format); | 143 | sb->sb_fs_format, sb->sb_multihost_format); |
145 | printk(KERN_INFO | 144 | printk(KERN_INFO |
146 | "GFS2: Use the \"upgrade\" mount option to upgrade " | 145 | "GFS2: Use the \"upgrade\" mount option to upgrade " |
147 | "the FS\n"); | 146 | "the FS\n"); |
148 | printk(KERN_INFO "GFS2: See the manual for more details\n"); | 147 | printk(KERN_INFO "GFS2: See the manual for more details\n"); |
149 | return -EINVAL; | 148 | return -EINVAL; |
150 | } | 149 | } |
151 | 150 | ||
152 | return 0; | 151 | return 0; |
153 | } | 152 | } |
154 | 153 | ||
155 | 154 | ||
156 | static void end_bio_io_page(struct bio *bio, int error) | 155 | static void end_bio_io_page(struct bio *bio, int error) |
157 | { | 156 | { |
158 | struct page *page = bio->bi_private; | 157 | struct page *page = bio->bi_private; |
159 | 158 | ||
160 | if (!error) | 159 | if (!error) |
161 | SetPageUptodate(page); | 160 | SetPageUptodate(page); |
162 | else | 161 | else |
163 | printk(KERN_WARNING "gfs2: error %d reading superblock\n", error); | 162 | printk(KERN_WARNING "gfs2: error %d reading superblock\n", error); |
164 | unlock_page(page); | 163 | unlock_page(page); |
165 | } | 164 | } |
166 | 165 | ||
167 | static void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) | 166 | static void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) |
168 | { | 167 | { |
169 | const struct gfs2_sb *str = buf; | 168 | const struct gfs2_sb *str = buf; |
170 | 169 | ||
171 | sb->sb_magic = be32_to_cpu(str->sb_header.mh_magic); | 170 | sb->sb_magic = be32_to_cpu(str->sb_header.mh_magic); |
172 | sb->sb_type = be32_to_cpu(str->sb_header.mh_type); | 171 | sb->sb_type = be32_to_cpu(str->sb_header.mh_type); |
173 | sb->sb_format = be32_to_cpu(str->sb_header.mh_format); | 172 | sb->sb_format = be32_to_cpu(str->sb_header.mh_format); |
174 | sb->sb_fs_format = be32_to_cpu(str->sb_fs_format); | 173 | sb->sb_fs_format = be32_to_cpu(str->sb_fs_format); |
175 | sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format); | 174 | sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format); |
176 | sb->sb_bsize = be32_to_cpu(str->sb_bsize); | 175 | sb->sb_bsize = be32_to_cpu(str->sb_bsize); |
177 | sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift); | 176 | sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift); |
178 | sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr); | 177 | sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr); |
179 | sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino); | 178 | sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino); |
180 | sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr); | 179 | sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr); |
181 | sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino); | 180 | sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino); |
182 | 181 | ||
183 | memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN); | 182 | memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN); |
184 | memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); | 183 | memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); |
185 | } | 184 | } |
186 | 185 | ||
187 | /** | 186 | /** |
188 | * gfs2_read_super - Read the gfs2 super block from disk | 187 | * gfs2_read_super - Read the gfs2 super block from disk |
189 | * @sdp: The GFS2 super block | 188 | * @sdp: The GFS2 super block |
190 | * @sector: The location of the super block | 189 | * @sector: The location of the super block |
191 | * @error: The error code to return | 190 | * @error: The error code to return |
192 | * | 191 | * |
193 | * This uses the bio functions to read the super block from disk | 192 | * This uses the bio functions to read the super block from disk |
194 | * because we want to be 100% sure that we never read cached data. | 193 | * because we want to be 100% sure that we never read cached data. |
195 | * A super block is read twice only during each GFS2 mount and is | 194 | * A super block is read twice only during each GFS2 mount and is |
196 | * never written to by the filesystem. The first time its read no | 195 | * never written to by the filesystem. The first time its read no |
197 | * locks are held, and the only details which are looked at are those | 196 | * locks are held, and the only details which are looked at are those |
198 | * relating to the locking protocol. Once locking is up and working, | 197 | * relating to the locking protocol. Once locking is up and working, |
199 | * the sb is read again under the lock to establish the location of | 198 | * the sb is read again under the lock to establish the location of |
200 | * the master directory (contains pointers to journals etc) and the | 199 | * the master directory (contains pointers to journals etc) and the |
201 | * root directory. | 200 | * root directory. |
202 | * | 201 | * |
203 | * Returns: 0 on success or error | 202 | * Returns: 0 on success or error |
204 | */ | 203 | */ |
205 | 204 | ||
206 | int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector) | 205 | int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector) |
207 | { | 206 | { |
208 | struct super_block *sb = sdp->sd_vfs; | 207 | struct super_block *sb = sdp->sd_vfs; |
209 | struct gfs2_sb *p; | 208 | struct gfs2_sb *p; |
210 | struct page *page; | 209 | struct page *page; |
211 | struct bio *bio; | 210 | struct bio *bio; |
212 | 211 | ||
213 | page = alloc_page(GFP_NOFS); | 212 | page = alloc_page(GFP_NOFS); |
214 | if (unlikely(!page)) | 213 | if (unlikely(!page)) |
215 | return -ENOBUFS; | 214 | return -ENOBUFS; |
216 | 215 | ||
217 | ClearPageUptodate(page); | 216 | ClearPageUptodate(page); |
218 | ClearPageDirty(page); | 217 | ClearPageDirty(page); |
219 | lock_page(page); | 218 | lock_page(page); |
220 | 219 | ||
221 | bio = bio_alloc(GFP_NOFS, 1); | 220 | bio = bio_alloc(GFP_NOFS, 1); |
222 | if (unlikely(!bio)) { | 221 | if (unlikely(!bio)) { |
223 | __free_page(page); | 222 | __free_page(page); |
224 | return -ENOBUFS; | 223 | return -ENOBUFS; |
225 | } | 224 | } |
226 | 225 | ||
227 | bio->bi_sector = sector * (sb->s_blocksize >> 9); | 226 | bio->bi_sector = sector * (sb->s_blocksize >> 9); |
228 | bio->bi_bdev = sb->s_bdev; | 227 | bio->bi_bdev = sb->s_bdev; |
229 | bio_add_page(bio, page, PAGE_SIZE, 0); | 228 | bio_add_page(bio, page, PAGE_SIZE, 0); |
230 | 229 | ||
231 | bio->bi_end_io = end_bio_io_page; | 230 | bio->bi_end_io = end_bio_io_page; |
232 | bio->bi_private = page; | 231 | bio->bi_private = page; |
233 | submit_bio(READ_SYNC | (1 << BIO_RW_META), bio); | 232 | submit_bio(READ_SYNC | (1 << BIO_RW_META), bio); |
234 | wait_on_page_locked(page); | 233 | wait_on_page_locked(page); |
235 | bio_put(bio); | 234 | bio_put(bio); |
236 | if (!PageUptodate(page)) { | 235 | if (!PageUptodate(page)) { |
237 | __free_page(page); | 236 | __free_page(page); |
238 | return -EIO; | 237 | return -EIO; |
239 | } | 238 | } |
240 | p = kmap(page); | 239 | p = kmap(page); |
241 | gfs2_sb_in(&sdp->sd_sb, p); | 240 | gfs2_sb_in(&sdp->sd_sb, p); |
242 | kunmap(page); | 241 | kunmap(page); |
243 | __free_page(page); | 242 | __free_page(page); |
244 | return 0; | 243 | return 0; |
245 | } | 244 | } |
246 | 245 | ||
247 | /** | 246 | /** |
248 | * gfs2_read_sb - Read super block | 247 | * gfs2_read_sb - Read super block |
249 | * @sdp: The GFS2 superblock | 248 | * @sdp: The GFS2 superblock |
250 | * @gl: the glock for the superblock (assumed to be held) | 249 | * @gl: the glock for the superblock (assumed to be held) |
251 | * @silent: Don't print message if mount fails | 250 | * @silent: Don't print message if mount fails |
252 | * | 251 | * |
253 | */ | 252 | */ |
254 | 253 | ||
255 | int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent) | 254 | int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent) |
256 | { | 255 | { |
257 | u32 hash_blocks, ind_blocks, leaf_blocks; | 256 | u32 hash_blocks, ind_blocks, leaf_blocks; |
258 | u32 tmp_blocks; | 257 | u32 tmp_blocks; |
259 | unsigned int x; | 258 | unsigned int x; |
260 | int error; | 259 | int error; |
261 | 260 | ||
262 | error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); | 261 | error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); |
263 | if (error) { | 262 | if (error) { |
264 | if (!silent) | 263 | if (!silent) |
265 | fs_err(sdp, "can't read superblock\n"); | 264 | fs_err(sdp, "can't read superblock\n"); |
266 | return error; | 265 | return error; |
267 | } | 266 | } |
268 | 267 | ||
269 | error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); | 268 | error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); |
270 | if (error) | 269 | if (error) |
271 | return error; | 270 | return error; |
272 | 271 | ||
273 | sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - | 272 | sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - |
274 | GFS2_BASIC_BLOCK_SHIFT; | 273 | GFS2_BASIC_BLOCK_SHIFT; |
275 | sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; | 274 | sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; |
276 | sdp->sd_diptrs = (sdp->sd_sb.sb_bsize - | 275 | sdp->sd_diptrs = (sdp->sd_sb.sb_bsize - |
277 | sizeof(struct gfs2_dinode)) / sizeof(u64); | 276 | sizeof(struct gfs2_dinode)) / sizeof(u64); |
278 | sdp->sd_inptrs = (sdp->sd_sb.sb_bsize - | 277 | sdp->sd_inptrs = (sdp->sd_sb.sb_bsize - |
279 | sizeof(struct gfs2_meta_header)) / sizeof(u64); | 278 | sizeof(struct gfs2_meta_header)) / sizeof(u64); |
280 | sdp->sd_jbsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header); | 279 | sdp->sd_jbsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header); |
281 | sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2; | 280 | sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2; |
282 | sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1; | 281 | sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1; |
283 | sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(u64); | 282 | sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(u64); |
284 | sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize - | 283 | sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize - |
285 | sizeof(struct gfs2_meta_header)) / | 284 | sizeof(struct gfs2_meta_header)) / |
286 | sizeof(struct gfs2_quota_change); | 285 | sizeof(struct gfs2_quota_change); |
287 | 286 | ||
288 | /* Compute maximum reservation required to add a entry to a directory */ | 287 | /* Compute maximum reservation required to add a entry to a directory */ |
289 | 288 | ||
290 | hash_blocks = DIV_ROUND_UP(sizeof(u64) * (1 << GFS2_DIR_MAX_DEPTH), | 289 | hash_blocks = DIV_ROUND_UP(sizeof(u64) * (1 << GFS2_DIR_MAX_DEPTH), |
291 | sdp->sd_jbsize); | 290 | sdp->sd_jbsize); |
292 | 291 | ||
293 | ind_blocks = 0; | 292 | ind_blocks = 0; |
294 | for (tmp_blocks = hash_blocks; tmp_blocks > sdp->sd_diptrs;) { | 293 | for (tmp_blocks = hash_blocks; tmp_blocks > sdp->sd_diptrs;) { |
295 | tmp_blocks = DIV_ROUND_UP(tmp_blocks, sdp->sd_inptrs); | 294 | tmp_blocks = DIV_ROUND_UP(tmp_blocks, sdp->sd_inptrs); |
296 | ind_blocks += tmp_blocks; | 295 | ind_blocks += tmp_blocks; |
297 | } | 296 | } |
298 | 297 | ||
299 | leaf_blocks = 2 + GFS2_DIR_MAX_DEPTH; | 298 | leaf_blocks = 2 + GFS2_DIR_MAX_DEPTH; |
300 | 299 | ||
301 | sdp->sd_max_dirres = hash_blocks + ind_blocks + leaf_blocks; | 300 | sdp->sd_max_dirres = hash_blocks + ind_blocks + leaf_blocks; |
302 | 301 | ||
303 | sdp->sd_heightsize[0] = sdp->sd_sb.sb_bsize - | 302 | sdp->sd_heightsize[0] = sdp->sd_sb.sb_bsize - |
304 | sizeof(struct gfs2_dinode); | 303 | sizeof(struct gfs2_dinode); |
305 | sdp->sd_heightsize[1] = sdp->sd_sb.sb_bsize * sdp->sd_diptrs; | 304 | sdp->sd_heightsize[1] = sdp->sd_sb.sb_bsize * sdp->sd_diptrs; |
306 | for (x = 2;; x++) { | 305 | for (x = 2;; x++) { |
307 | u64 space, d; | 306 | u64 space, d; |
308 | u32 m; | 307 | u32 m; |
309 | 308 | ||
310 | space = sdp->sd_heightsize[x - 1] * sdp->sd_inptrs; | 309 | space = sdp->sd_heightsize[x - 1] * sdp->sd_inptrs; |
311 | d = space; | 310 | d = space; |
312 | m = do_div(d, sdp->sd_inptrs); | 311 | m = do_div(d, sdp->sd_inptrs); |
313 | 312 | ||
314 | if (d != sdp->sd_heightsize[x - 1] || m) | 313 | if (d != sdp->sd_heightsize[x - 1] || m) |
315 | break; | 314 | break; |
316 | sdp->sd_heightsize[x] = space; | 315 | sdp->sd_heightsize[x] = space; |
317 | } | 316 | } |
318 | sdp->sd_max_height = x; | 317 | sdp->sd_max_height = x; |
319 | sdp->sd_heightsize[x] = ~0; | 318 | sdp->sd_heightsize[x] = ~0; |
320 | gfs2_assert(sdp, sdp->sd_max_height <= GFS2_MAX_META_HEIGHT); | 319 | gfs2_assert(sdp, sdp->sd_max_height <= GFS2_MAX_META_HEIGHT); |
321 | 320 | ||
322 | sdp->sd_jheightsize[0] = sdp->sd_sb.sb_bsize - | 321 | sdp->sd_jheightsize[0] = sdp->sd_sb.sb_bsize - |
323 | sizeof(struct gfs2_dinode); | 322 | sizeof(struct gfs2_dinode); |
324 | sdp->sd_jheightsize[1] = sdp->sd_jbsize * sdp->sd_diptrs; | 323 | sdp->sd_jheightsize[1] = sdp->sd_jbsize * sdp->sd_diptrs; |
325 | for (x = 2;; x++) { | 324 | for (x = 2;; x++) { |
326 | u64 space, d; | 325 | u64 space, d; |
327 | u32 m; | 326 | u32 m; |
328 | 327 | ||
329 | space = sdp->sd_jheightsize[x - 1] * sdp->sd_inptrs; | 328 | space = sdp->sd_jheightsize[x - 1] * sdp->sd_inptrs; |
330 | d = space; | 329 | d = space; |
331 | m = do_div(d, sdp->sd_inptrs); | 330 | m = do_div(d, sdp->sd_inptrs); |
332 | 331 | ||
333 | if (d != sdp->sd_jheightsize[x - 1] || m) | 332 | if (d != sdp->sd_jheightsize[x - 1] || m) |
334 | break; | 333 | break; |
335 | sdp->sd_jheightsize[x] = space; | 334 | sdp->sd_jheightsize[x] = space; |
336 | } | 335 | } |
337 | sdp->sd_max_jheight = x; | 336 | sdp->sd_max_jheight = x; |
338 | sdp->sd_jheightsize[x] = ~0; | 337 | sdp->sd_jheightsize[x] = ~0; |
339 | gfs2_assert(sdp, sdp->sd_max_jheight <= GFS2_MAX_META_HEIGHT); | 338 | gfs2_assert(sdp, sdp->sd_max_jheight <= GFS2_MAX_META_HEIGHT); |
340 | 339 | ||
341 | return 0; | 340 | return 0; |
342 | } | 341 | } |
343 | 342 | ||
344 | /** | 343 | /** |
345 | * gfs2_jindex_hold - Grab a lock on the jindex | 344 | * gfs2_jindex_hold - Grab a lock on the jindex |
346 | * @sdp: The GFS2 superblock | 345 | * @sdp: The GFS2 superblock |
347 | * @ji_gh: the holder for the jindex glock | 346 | * @ji_gh: the holder for the jindex glock |
348 | * | 347 | * |
349 | * This is very similar to the gfs2_rindex_hold() function, except that | 348 | * This is very similar to the gfs2_rindex_hold() function, except that |
350 | * in general we hold the jindex lock for longer periods of time and | 349 | * in general we hold the jindex lock for longer periods of time and |
351 | * we grab it far less frequently (in general) then the rgrp lock. | 350 | * we grab it far less frequently (in general) then the rgrp lock. |
352 | * | 351 | * |
353 | * Returns: errno | 352 | * Returns: errno |
354 | */ | 353 | */ |
355 | 354 | ||
356 | int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) | 355 | int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) |
357 | { | 356 | { |
358 | struct gfs2_inode *dip = GFS2_I(sdp->sd_jindex); | 357 | struct gfs2_inode *dip = GFS2_I(sdp->sd_jindex); |
359 | struct qstr name; | 358 | struct qstr name; |
360 | char buf[20]; | 359 | char buf[20]; |
361 | struct gfs2_jdesc *jd; | 360 | struct gfs2_jdesc *jd; |
362 | int error; | 361 | int error; |
363 | 362 | ||
364 | name.name = buf; | 363 | name.name = buf; |
365 | 364 | ||
366 | mutex_lock(&sdp->sd_jindex_mutex); | 365 | mutex_lock(&sdp->sd_jindex_mutex); |
367 | 366 | ||
368 | for (;;) { | 367 | for (;;) { |
369 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, ji_gh); | 368 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, ji_gh); |
370 | if (error) | 369 | if (error) |
371 | break; | 370 | break; |
372 | 371 | ||
373 | name.len = sprintf(buf, "journal%u", sdp->sd_journals); | 372 | name.len = sprintf(buf, "journal%u", sdp->sd_journals); |
374 | name.hash = gfs2_disk_hash(name.name, name.len); | 373 | name.hash = gfs2_disk_hash(name.name, name.len); |
375 | 374 | ||
376 | error = gfs2_dir_check(sdp->sd_jindex, &name, NULL); | 375 | error = gfs2_dir_check(sdp->sd_jindex, &name, NULL); |
377 | if (error == -ENOENT) { | 376 | if (error == -ENOENT) { |
378 | error = 0; | 377 | error = 0; |
379 | break; | 378 | break; |
380 | } | 379 | } |
381 | 380 | ||
382 | gfs2_glock_dq_uninit(ji_gh); | 381 | gfs2_glock_dq_uninit(ji_gh); |
383 | 382 | ||
384 | if (error) | 383 | if (error) |
385 | break; | 384 | break; |
386 | 385 | ||
387 | error = -ENOMEM; | 386 | error = -ENOMEM; |
388 | jd = kzalloc(sizeof(struct gfs2_jdesc), GFP_KERNEL); | 387 | jd = kzalloc(sizeof(struct gfs2_jdesc), GFP_KERNEL); |
389 | if (!jd) | 388 | if (!jd) |
390 | break; | 389 | break; |
391 | 390 | ||
392 | INIT_LIST_HEAD(&jd->extent_list); | 391 | INIT_LIST_HEAD(&jd->extent_list); |
393 | jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1, NULL); | 392 | jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1, NULL); |
394 | if (!jd->jd_inode || IS_ERR(jd->jd_inode)) { | 393 | if (!jd->jd_inode || IS_ERR(jd->jd_inode)) { |
395 | if (!jd->jd_inode) | 394 | if (!jd->jd_inode) |
396 | error = -ENOENT; | 395 | error = -ENOENT; |
397 | else | 396 | else |
398 | error = PTR_ERR(jd->jd_inode); | 397 | error = PTR_ERR(jd->jd_inode); |
399 | kfree(jd); | 398 | kfree(jd); |
400 | break; | 399 | break; |
401 | } | 400 | } |
402 | 401 | ||
403 | spin_lock(&sdp->sd_jindex_spin); | 402 | spin_lock(&sdp->sd_jindex_spin); |
404 | jd->jd_jid = sdp->sd_journals++; | 403 | jd->jd_jid = sdp->sd_journals++; |
405 | list_add_tail(&jd->jd_list, &sdp->sd_jindex_list); | 404 | list_add_tail(&jd->jd_list, &sdp->sd_jindex_list); |
406 | spin_unlock(&sdp->sd_jindex_spin); | 405 | spin_unlock(&sdp->sd_jindex_spin); |
407 | } | 406 | } |
408 | 407 | ||
409 | mutex_unlock(&sdp->sd_jindex_mutex); | 408 | mutex_unlock(&sdp->sd_jindex_mutex); |
410 | 409 | ||
411 | return error; | 410 | return error; |
412 | } | 411 | } |
413 | 412 | ||
414 | /** | 413 | /** |
415 | * gfs2_jindex_free - Clear all the journal index information | 414 | * gfs2_jindex_free - Clear all the journal index information |
416 | * @sdp: The GFS2 superblock | 415 | * @sdp: The GFS2 superblock |
417 | * | 416 | * |
418 | */ | 417 | */ |
419 | 418 | ||
420 | void gfs2_jindex_free(struct gfs2_sbd *sdp) | 419 | void gfs2_jindex_free(struct gfs2_sbd *sdp) |
421 | { | 420 | { |
422 | struct list_head list, *head; | 421 | struct list_head list, *head; |
423 | struct gfs2_jdesc *jd; | 422 | struct gfs2_jdesc *jd; |
424 | struct gfs2_journal_extent *jext; | 423 | struct gfs2_journal_extent *jext; |
425 | 424 | ||
426 | spin_lock(&sdp->sd_jindex_spin); | 425 | spin_lock(&sdp->sd_jindex_spin); |
427 | list_add(&list, &sdp->sd_jindex_list); | 426 | list_add(&list, &sdp->sd_jindex_list); |
428 | list_del_init(&sdp->sd_jindex_list); | 427 | list_del_init(&sdp->sd_jindex_list); |
429 | sdp->sd_journals = 0; | 428 | sdp->sd_journals = 0; |
430 | spin_unlock(&sdp->sd_jindex_spin); | 429 | spin_unlock(&sdp->sd_jindex_spin); |
431 | 430 | ||
432 | while (!list_empty(&list)) { | 431 | while (!list_empty(&list)) { |
433 | jd = list_entry(list.next, struct gfs2_jdesc, jd_list); | 432 | jd = list_entry(list.next, struct gfs2_jdesc, jd_list); |
434 | head = &jd->extent_list; | 433 | head = &jd->extent_list; |
435 | while (!list_empty(head)) { | 434 | while (!list_empty(head)) { |
436 | jext = list_entry(head->next, | 435 | jext = list_entry(head->next, |
437 | struct gfs2_journal_extent, | 436 | struct gfs2_journal_extent, |
438 | extent_list); | 437 | extent_list); |
439 | list_del(&jext->extent_list); | 438 | list_del(&jext->extent_list); |
440 | kfree(jext); | 439 | kfree(jext); |
441 | } | 440 | } |
442 | list_del(&jd->jd_list); | 441 | list_del(&jd->jd_list); |
443 | iput(jd->jd_inode); | 442 | iput(jd->jd_inode); |
444 | kfree(jd); | 443 | kfree(jd); |
445 | } | 444 | } |
446 | } | 445 | } |
447 | 446 | ||
448 | static struct gfs2_jdesc *jdesc_find_i(struct list_head *head, unsigned int jid) | 447 | static struct gfs2_jdesc *jdesc_find_i(struct list_head *head, unsigned int jid) |
449 | { | 448 | { |
450 | struct gfs2_jdesc *jd; | 449 | struct gfs2_jdesc *jd; |
451 | int found = 0; | 450 | int found = 0; |
452 | 451 | ||
453 | list_for_each_entry(jd, head, jd_list) { | 452 | list_for_each_entry(jd, head, jd_list) { |
454 | if (jd->jd_jid == jid) { | 453 | if (jd->jd_jid == jid) { |
455 | found = 1; | 454 | found = 1; |
456 | break; | 455 | break; |
457 | } | 456 | } |
458 | } | 457 | } |
459 | 458 | ||
460 | if (!found) | 459 | if (!found) |
461 | jd = NULL; | 460 | jd = NULL; |
462 | 461 | ||
463 | return jd; | 462 | return jd; |
464 | } | 463 | } |
465 | 464 | ||
466 | struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid) | 465 | struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid) |
467 | { | 466 | { |
468 | struct gfs2_jdesc *jd; | 467 | struct gfs2_jdesc *jd; |
469 | 468 | ||
470 | spin_lock(&sdp->sd_jindex_spin); | 469 | spin_lock(&sdp->sd_jindex_spin); |
471 | jd = jdesc_find_i(&sdp->sd_jindex_list, jid); | 470 | jd = jdesc_find_i(&sdp->sd_jindex_list, jid); |
472 | spin_unlock(&sdp->sd_jindex_spin); | 471 | spin_unlock(&sdp->sd_jindex_spin); |
473 | 472 | ||
474 | return jd; | 473 | return jd; |
475 | } | 474 | } |
476 | 475 | ||
477 | void gfs2_jdesc_make_dirty(struct gfs2_sbd *sdp, unsigned int jid) | 476 | void gfs2_jdesc_make_dirty(struct gfs2_sbd *sdp, unsigned int jid) |
478 | { | 477 | { |
479 | struct gfs2_jdesc *jd; | 478 | struct gfs2_jdesc *jd; |
480 | 479 | ||
481 | spin_lock(&sdp->sd_jindex_spin); | 480 | spin_lock(&sdp->sd_jindex_spin); |
482 | jd = jdesc_find_i(&sdp->sd_jindex_list, jid); | 481 | jd = jdesc_find_i(&sdp->sd_jindex_list, jid); |
483 | if (jd) | 482 | if (jd) |
484 | jd->jd_dirty = 1; | 483 | jd->jd_dirty = 1; |
485 | spin_unlock(&sdp->sd_jindex_spin); | 484 | spin_unlock(&sdp->sd_jindex_spin); |
486 | } | 485 | } |
487 | 486 | ||
488 | struct gfs2_jdesc *gfs2_jdesc_find_dirty(struct gfs2_sbd *sdp) | 487 | struct gfs2_jdesc *gfs2_jdesc_find_dirty(struct gfs2_sbd *sdp) |
489 | { | 488 | { |
490 | struct gfs2_jdesc *jd; | 489 | struct gfs2_jdesc *jd; |
491 | int found = 0; | 490 | int found = 0; |
492 | 491 | ||
493 | spin_lock(&sdp->sd_jindex_spin); | 492 | spin_lock(&sdp->sd_jindex_spin); |
494 | 493 | ||
495 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | 494 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { |
496 | if (jd->jd_dirty) { | 495 | if (jd->jd_dirty) { |
497 | jd->jd_dirty = 0; | 496 | jd->jd_dirty = 0; |
498 | found = 1; | 497 | found = 1; |
499 | break; | 498 | break; |
500 | } | 499 | } |
501 | } | 500 | } |
502 | spin_unlock(&sdp->sd_jindex_spin); | 501 | spin_unlock(&sdp->sd_jindex_spin); |
503 | 502 | ||
504 | if (!found) | 503 | if (!found) |
505 | jd = NULL; | 504 | jd = NULL; |
506 | 505 | ||
507 | return jd; | 506 | return jd; |
508 | } | 507 | } |
509 | 508 | ||
510 | int gfs2_jdesc_check(struct gfs2_jdesc *jd) | 509 | int gfs2_jdesc_check(struct gfs2_jdesc *jd) |
511 | { | 510 | { |
512 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); | 511 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); |
513 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); | 512 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
514 | int ar; | 513 | int ar; |
515 | int error; | 514 | int error; |
516 | 515 | ||
517 | if (ip->i_di.di_size < (8 << 20) || ip->i_di.di_size > (1 << 30) || | 516 | if (ip->i_di.di_size < (8 << 20) || ip->i_di.di_size > (1 << 30) || |
518 | (ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1))) { | 517 | (ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1))) { |
519 | gfs2_consist_inode(ip); | 518 | gfs2_consist_inode(ip); |
520 | return -EIO; | 519 | return -EIO; |
521 | } | 520 | } |
522 | jd->jd_blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift; | 521 | jd->jd_blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift; |
523 | 522 | ||
524 | error = gfs2_write_alloc_required(ip, 0, ip->i_di.di_size, &ar); | 523 | error = gfs2_write_alloc_required(ip, 0, ip->i_di.di_size, &ar); |
525 | if (!error && ar) { | 524 | if (!error && ar) { |
526 | gfs2_consist_inode(ip); | 525 | gfs2_consist_inode(ip); |
527 | error = -EIO; | 526 | error = -EIO; |
528 | } | 527 | } |
529 | 528 | ||
530 | return error; | 529 | return error; |
531 | } | 530 | } |
532 | 531 | ||
533 | /** | 532 | /** |
534 | * gfs2_make_fs_rw - Turn a Read-Only FS into a Read-Write one | 533 | * gfs2_make_fs_rw - Turn a Read-Only FS into a Read-Write one |
535 | * @sdp: the filesystem | 534 | * @sdp: the filesystem |
536 | * | 535 | * |
537 | * Returns: errno | 536 | * Returns: errno |
538 | */ | 537 | */ |
539 | 538 | ||
540 | int gfs2_make_fs_rw(struct gfs2_sbd *sdp) | 539 | int gfs2_make_fs_rw(struct gfs2_sbd *sdp) |
541 | { | 540 | { |
542 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); | 541 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); |
543 | struct gfs2_glock *j_gl = ip->i_gl; | 542 | struct gfs2_glock *j_gl = ip->i_gl; |
544 | struct gfs2_holder t_gh; | 543 | struct gfs2_holder t_gh; |
545 | struct gfs2_log_header_host head; | 544 | struct gfs2_log_header_host head; |
546 | int error; | 545 | int error; |
547 | 546 | ||
548 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &t_gh); | 547 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &t_gh); |
549 | if (error) | 548 | if (error) |
550 | return error; | 549 | return error; |
551 | 550 | ||
552 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); | 551 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); |
553 | 552 | ||
554 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); | 553 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); |
555 | if (error) | 554 | if (error) |
556 | goto fail; | 555 | goto fail; |
557 | 556 | ||
558 | if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) { | 557 | if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) { |
559 | gfs2_consist(sdp); | 558 | gfs2_consist(sdp); |
560 | error = -EIO; | 559 | error = -EIO; |
561 | goto fail; | 560 | goto fail; |
562 | } | 561 | } |
563 | 562 | ||
564 | /* Initialize some head of the log stuff */ | 563 | /* Initialize some head of the log stuff */ |
565 | sdp->sd_log_sequence = head.lh_sequence + 1; | 564 | sdp->sd_log_sequence = head.lh_sequence + 1; |
566 | gfs2_log_pointers_init(sdp, head.lh_blkno); | 565 | gfs2_log_pointers_init(sdp, head.lh_blkno); |
567 | 566 | ||
568 | error = gfs2_quota_init(sdp); | 567 | error = gfs2_quota_init(sdp); |
569 | if (error) | 568 | if (error) |
570 | goto fail; | 569 | goto fail; |
571 | 570 | ||
572 | set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); | 571 | set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); |
573 | 572 | ||
574 | gfs2_glock_dq_uninit(&t_gh); | 573 | gfs2_glock_dq_uninit(&t_gh); |
575 | 574 | ||
576 | return 0; | 575 | return 0; |
577 | 576 | ||
578 | fail: | 577 | fail: |
579 | t_gh.gh_flags |= GL_NOCACHE; | 578 | t_gh.gh_flags |= GL_NOCACHE; |
580 | gfs2_glock_dq_uninit(&t_gh); | 579 | gfs2_glock_dq_uninit(&t_gh); |
581 | 580 | ||
582 | return error; | 581 | return error; |
583 | } | 582 | } |
584 | 583 | ||
585 | /** | 584 | /** |
586 | * gfs2_make_fs_ro - Turn a Read-Write FS into a Read-Only one | 585 | * gfs2_make_fs_ro - Turn a Read-Write FS into a Read-Only one |
587 | * @sdp: the filesystem | 586 | * @sdp: the filesystem |
588 | * | 587 | * |
589 | * Returns: errno | 588 | * Returns: errno |
590 | */ | 589 | */ |
591 | 590 | ||
592 | int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | 591 | int gfs2_make_fs_ro(struct gfs2_sbd *sdp) |
593 | { | 592 | { |
594 | struct gfs2_holder t_gh; | 593 | struct gfs2_holder t_gh; |
595 | int error; | 594 | int error; |
596 | 595 | ||
597 | gfs2_quota_sync(sdp); | 596 | gfs2_quota_sync(sdp); |
598 | gfs2_statfs_sync(sdp); | 597 | gfs2_statfs_sync(sdp); |
599 | 598 | ||
600 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE, | 599 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE, |
601 | &t_gh); | 600 | &t_gh); |
602 | if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) | 601 | if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) |
603 | return error; | 602 | return error; |
604 | 603 | ||
605 | gfs2_meta_syncfs(sdp); | 604 | gfs2_meta_syncfs(sdp); |
606 | gfs2_log_shutdown(sdp); | 605 | gfs2_log_shutdown(sdp); |
607 | 606 | ||
608 | clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); | 607 | clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); |
609 | 608 | ||
610 | if (t_gh.gh_gl) | 609 | if (t_gh.gh_gl) |
611 | gfs2_glock_dq_uninit(&t_gh); | 610 | gfs2_glock_dq_uninit(&t_gh); |
612 | 611 | ||
613 | gfs2_quota_cleanup(sdp); | 612 | gfs2_quota_cleanup(sdp); |
614 | 613 | ||
615 | return error; | 614 | return error; |
616 | } | 615 | } |
617 | 616 | ||
618 | static void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) | 617 | static void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) |
619 | { | 618 | { |
620 | const struct gfs2_statfs_change *str = buf; | 619 | const struct gfs2_statfs_change *str = buf; |
621 | 620 | ||
622 | sc->sc_total = be64_to_cpu(str->sc_total); | 621 | sc->sc_total = be64_to_cpu(str->sc_total); |
623 | sc->sc_free = be64_to_cpu(str->sc_free); | 622 | sc->sc_free = be64_to_cpu(str->sc_free); |
624 | sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); | 623 | sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); |
625 | } | 624 | } |
626 | 625 | ||
627 | static void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf) | 626 | static void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf) |
628 | { | 627 | { |
629 | struct gfs2_statfs_change *str = buf; | 628 | struct gfs2_statfs_change *str = buf; |
630 | 629 | ||
631 | str->sc_total = cpu_to_be64(sc->sc_total); | 630 | str->sc_total = cpu_to_be64(sc->sc_total); |
632 | str->sc_free = cpu_to_be64(sc->sc_free); | 631 | str->sc_free = cpu_to_be64(sc->sc_free); |
633 | str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); | 632 | str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); |
634 | } | 633 | } |
635 | 634 | ||
636 | int gfs2_statfs_init(struct gfs2_sbd *sdp) | 635 | int gfs2_statfs_init(struct gfs2_sbd *sdp) |
637 | { | 636 | { |
638 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); | 637 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); |
639 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; | 638 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; |
640 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 639 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
641 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; | 640 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
642 | struct buffer_head *m_bh, *l_bh; | 641 | struct buffer_head *m_bh, *l_bh; |
643 | struct gfs2_holder gh; | 642 | struct gfs2_holder gh; |
644 | int error; | 643 | int error; |
645 | 644 | ||
646 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE, | 645 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE, |
647 | &gh); | 646 | &gh); |
648 | if (error) | 647 | if (error) |
649 | return error; | 648 | return error; |
650 | 649 | ||
651 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); | 650 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); |
652 | if (error) | 651 | if (error) |
653 | goto out; | 652 | goto out; |
654 | 653 | ||
655 | if (sdp->sd_args.ar_spectator) { | 654 | if (sdp->sd_args.ar_spectator) { |
656 | spin_lock(&sdp->sd_statfs_spin); | 655 | spin_lock(&sdp->sd_statfs_spin); |
657 | gfs2_statfs_change_in(m_sc, m_bh->b_data + | 656 | gfs2_statfs_change_in(m_sc, m_bh->b_data + |
658 | sizeof(struct gfs2_dinode)); | 657 | sizeof(struct gfs2_dinode)); |
659 | spin_unlock(&sdp->sd_statfs_spin); | 658 | spin_unlock(&sdp->sd_statfs_spin); |
660 | } else { | 659 | } else { |
661 | error = gfs2_meta_inode_buffer(l_ip, &l_bh); | 660 | error = gfs2_meta_inode_buffer(l_ip, &l_bh); |
662 | if (error) | 661 | if (error) |
663 | goto out_m_bh; | 662 | goto out_m_bh; |
664 | 663 | ||
665 | spin_lock(&sdp->sd_statfs_spin); | 664 | spin_lock(&sdp->sd_statfs_spin); |
666 | gfs2_statfs_change_in(m_sc, m_bh->b_data + | 665 | gfs2_statfs_change_in(m_sc, m_bh->b_data + |
667 | sizeof(struct gfs2_dinode)); | 666 | sizeof(struct gfs2_dinode)); |
668 | gfs2_statfs_change_in(l_sc, l_bh->b_data + | 667 | gfs2_statfs_change_in(l_sc, l_bh->b_data + |
669 | sizeof(struct gfs2_dinode)); | 668 | sizeof(struct gfs2_dinode)); |
670 | spin_unlock(&sdp->sd_statfs_spin); | 669 | spin_unlock(&sdp->sd_statfs_spin); |
671 | 670 | ||
672 | brelse(l_bh); | 671 | brelse(l_bh); |
673 | } | 672 | } |
674 | 673 | ||
675 | out_m_bh: | 674 | out_m_bh: |
676 | brelse(m_bh); | 675 | brelse(m_bh); |
677 | out: | 676 | out: |
678 | gfs2_glock_dq_uninit(&gh); | 677 | gfs2_glock_dq_uninit(&gh); |
679 | return 0; | 678 | return 0; |
680 | } | 679 | } |
681 | 680 | ||
682 | void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, | 681 | void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, |
683 | s64 dinodes) | 682 | s64 dinodes) |
684 | { | 683 | { |
685 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 684 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
686 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; | 685 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
687 | struct buffer_head *l_bh; | 686 | struct buffer_head *l_bh; |
688 | int error; | 687 | int error; |
689 | 688 | ||
690 | error = gfs2_meta_inode_buffer(l_ip, &l_bh); | 689 | error = gfs2_meta_inode_buffer(l_ip, &l_bh); |
691 | if (error) | 690 | if (error) |
692 | return; | 691 | return; |
693 | 692 | ||
694 | gfs2_trans_add_bh(l_ip->i_gl, l_bh, 1); | 693 | gfs2_trans_add_bh(l_ip->i_gl, l_bh, 1); |
695 | 694 | ||
696 | spin_lock(&sdp->sd_statfs_spin); | 695 | spin_lock(&sdp->sd_statfs_spin); |
697 | l_sc->sc_total += total; | 696 | l_sc->sc_total += total; |
698 | l_sc->sc_free += free; | 697 | l_sc->sc_free += free; |
699 | l_sc->sc_dinodes += dinodes; | 698 | l_sc->sc_dinodes += dinodes; |
700 | gfs2_statfs_change_out(l_sc, l_bh->b_data + sizeof(struct gfs2_dinode)); | 699 | gfs2_statfs_change_out(l_sc, l_bh->b_data + sizeof(struct gfs2_dinode)); |
701 | spin_unlock(&sdp->sd_statfs_spin); | 700 | spin_unlock(&sdp->sd_statfs_spin); |
702 | 701 | ||
703 | brelse(l_bh); | 702 | brelse(l_bh); |
704 | } | 703 | } |
705 | 704 | ||
706 | int gfs2_statfs_sync(struct gfs2_sbd *sdp) | 705 | int gfs2_statfs_sync(struct gfs2_sbd *sdp) |
707 | { | 706 | { |
708 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); | 707 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); |
709 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 708 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
710 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; | 709 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; |
711 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; | 710 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
712 | struct gfs2_holder gh; | 711 | struct gfs2_holder gh; |
713 | struct buffer_head *m_bh, *l_bh; | 712 | struct buffer_head *m_bh, *l_bh; |
714 | int error; | 713 | int error; |
715 | 714 | ||
716 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE, | 715 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE, |
717 | &gh); | 716 | &gh); |
718 | if (error) | 717 | if (error) |
719 | return error; | 718 | return error; |
720 | 719 | ||
721 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); | 720 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); |
722 | if (error) | 721 | if (error) |
723 | goto out; | 722 | goto out; |
724 | 723 | ||
725 | spin_lock(&sdp->sd_statfs_spin); | 724 | spin_lock(&sdp->sd_statfs_spin); |
726 | gfs2_statfs_change_in(m_sc, m_bh->b_data + | 725 | gfs2_statfs_change_in(m_sc, m_bh->b_data + |
727 | sizeof(struct gfs2_dinode)); | 726 | sizeof(struct gfs2_dinode)); |
728 | if (!l_sc->sc_total && !l_sc->sc_free && !l_sc->sc_dinodes) { | 727 | if (!l_sc->sc_total && !l_sc->sc_free && !l_sc->sc_dinodes) { |
729 | spin_unlock(&sdp->sd_statfs_spin); | 728 | spin_unlock(&sdp->sd_statfs_spin); |
730 | goto out_bh; | 729 | goto out_bh; |
731 | } | 730 | } |
732 | spin_unlock(&sdp->sd_statfs_spin); | 731 | spin_unlock(&sdp->sd_statfs_spin); |
733 | 732 | ||
734 | error = gfs2_meta_inode_buffer(l_ip, &l_bh); | 733 | error = gfs2_meta_inode_buffer(l_ip, &l_bh); |
735 | if (error) | 734 | if (error) |
736 | goto out_bh; | 735 | goto out_bh; |
737 | 736 | ||
738 | error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0); | 737 | error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0); |
739 | if (error) | 738 | if (error) |
740 | goto out_bh2; | 739 | goto out_bh2; |
741 | 740 | ||
742 | gfs2_trans_add_bh(l_ip->i_gl, l_bh, 1); | 741 | gfs2_trans_add_bh(l_ip->i_gl, l_bh, 1); |
743 | 742 | ||
744 | spin_lock(&sdp->sd_statfs_spin); | 743 | spin_lock(&sdp->sd_statfs_spin); |
745 | m_sc->sc_total += l_sc->sc_total; | 744 | m_sc->sc_total += l_sc->sc_total; |
746 | m_sc->sc_free += l_sc->sc_free; | 745 | m_sc->sc_free += l_sc->sc_free; |
747 | m_sc->sc_dinodes += l_sc->sc_dinodes; | 746 | m_sc->sc_dinodes += l_sc->sc_dinodes; |
748 | memset(l_sc, 0, sizeof(struct gfs2_statfs_change)); | 747 | memset(l_sc, 0, sizeof(struct gfs2_statfs_change)); |
749 | memset(l_bh->b_data + sizeof(struct gfs2_dinode), | 748 | memset(l_bh->b_data + sizeof(struct gfs2_dinode), |
750 | 0, sizeof(struct gfs2_statfs_change)); | 749 | 0, sizeof(struct gfs2_statfs_change)); |
751 | spin_unlock(&sdp->sd_statfs_spin); | 750 | spin_unlock(&sdp->sd_statfs_spin); |
752 | 751 | ||
753 | gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); | 752 | gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); |
754 | gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode)); | 753 | gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode)); |
755 | 754 | ||
756 | gfs2_trans_end(sdp); | 755 | gfs2_trans_end(sdp); |
757 | 756 | ||
758 | out_bh2: | 757 | out_bh2: |
759 | brelse(l_bh); | 758 | brelse(l_bh); |
760 | out_bh: | 759 | out_bh: |
761 | brelse(m_bh); | 760 | brelse(m_bh); |
762 | out: | 761 | out: |
763 | gfs2_glock_dq_uninit(&gh); | 762 | gfs2_glock_dq_uninit(&gh); |
764 | return error; | 763 | return error; |
765 | } | 764 | } |
766 | 765 | ||
767 | /** | 766 | /** |
768 | * gfs2_statfs_i - Do a statfs | 767 | * gfs2_statfs_i - Do a statfs |
769 | * @sdp: the filesystem | 768 | * @sdp: the filesystem |
770 | * @sg: the sg structure | 769 | * @sg: the sg structure |
771 | * | 770 | * |
772 | * Returns: errno | 771 | * Returns: errno |
773 | */ | 772 | */ |
774 | 773 | ||
775 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) | 774 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) |
776 | { | 775 | { |
777 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; | 776 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; |
778 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; | 777 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
779 | 778 | ||
780 | spin_lock(&sdp->sd_statfs_spin); | 779 | spin_lock(&sdp->sd_statfs_spin); |
781 | 780 | ||
782 | *sc = *m_sc; | 781 | *sc = *m_sc; |
783 | sc->sc_total += l_sc->sc_total; | 782 | sc->sc_total += l_sc->sc_total; |
784 | sc->sc_free += l_sc->sc_free; | 783 | sc->sc_free += l_sc->sc_free; |
785 | sc->sc_dinodes += l_sc->sc_dinodes; | 784 | sc->sc_dinodes += l_sc->sc_dinodes; |
786 | 785 | ||
787 | spin_unlock(&sdp->sd_statfs_spin); | 786 | spin_unlock(&sdp->sd_statfs_spin); |
788 | 787 | ||
789 | if (sc->sc_free < 0) | 788 | if (sc->sc_free < 0) |
790 | sc->sc_free = 0; | 789 | sc->sc_free = 0; |
791 | if (sc->sc_free > sc->sc_total) | 790 | if (sc->sc_free > sc->sc_total) |
792 | sc->sc_free = sc->sc_total; | 791 | sc->sc_free = sc->sc_total; |
793 | if (sc->sc_dinodes < 0) | 792 | if (sc->sc_dinodes < 0) |
794 | sc->sc_dinodes = 0; | 793 | sc->sc_dinodes = 0; |
795 | 794 | ||
796 | return 0; | 795 | return 0; |
797 | } | 796 | } |
798 | 797 | ||
799 | /** | 798 | /** |
800 | * statfs_fill - fill in the sg for a given RG | 799 | * statfs_fill - fill in the sg for a given RG |
801 | * @rgd: the RG | 800 | * @rgd: the RG |
802 | * @sc: the sc structure | 801 | * @sc: the sc structure |
803 | * | 802 | * |
804 | * Returns: 0 on success, -ESTALE if the LVB is invalid | 803 | * Returns: 0 on success, -ESTALE if the LVB is invalid |
805 | */ | 804 | */ |
806 | 805 | ||
807 | static int statfs_slow_fill(struct gfs2_rgrpd *rgd, | 806 | static int statfs_slow_fill(struct gfs2_rgrpd *rgd, |
808 | struct gfs2_statfs_change_host *sc) | 807 | struct gfs2_statfs_change_host *sc) |
809 | { | 808 | { |
810 | gfs2_rgrp_verify(rgd); | 809 | gfs2_rgrp_verify(rgd); |
811 | sc->sc_total += rgd->rd_data; | 810 | sc->sc_total += rgd->rd_data; |
812 | sc->sc_free += rgd->rd_rg.rg_free; | 811 | sc->sc_free += rgd->rd_rg.rg_free; |
813 | sc->sc_dinodes += rgd->rd_rg.rg_dinodes; | 812 | sc->sc_dinodes += rgd->rd_rg.rg_dinodes; |
814 | return 0; | 813 | return 0; |
815 | } | 814 | } |
816 | 815 | ||
817 | /** | 816 | /** |
818 | * gfs2_statfs_slow - Stat a filesystem using asynchronous locking | 817 | * gfs2_statfs_slow - Stat a filesystem using asynchronous locking |
819 | * @sdp: the filesystem | 818 | * @sdp: the filesystem |
820 | * @sc: the sc info that will be returned | 819 | * @sc: the sc info that will be returned |
821 | * | 820 | * |
822 | * Any error (other than a signal) will cause this routine to fall back | 821 | * Any error (other than a signal) will cause this routine to fall back |
823 | * to the synchronous version. | 822 | * to the synchronous version. |
824 | * | 823 | * |
825 | * FIXME: This really shouldn't busy wait like this. | 824 | * FIXME: This really shouldn't busy wait like this. |
826 | * | 825 | * |
827 | * Returns: errno | 826 | * Returns: errno |
828 | */ | 827 | */ |
829 | 828 | ||
830 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) | 829 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) |
831 | { | 830 | { |
832 | struct gfs2_holder ri_gh; | 831 | struct gfs2_holder ri_gh; |
833 | struct gfs2_rgrpd *rgd_next; | 832 | struct gfs2_rgrpd *rgd_next; |
834 | struct gfs2_holder *gha, *gh; | 833 | struct gfs2_holder *gha, *gh; |
835 | unsigned int slots = 64; | 834 | unsigned int slots = 64; |
836 | unsigned int x; | 835 | unsigned int x; |
837 | int done; | 836 | int done; |
838 | int error = 0, err; | 837 | int error = 0, err; |
839 | 838 | ||
840 | memset(sc, 0, sizeof(struct gfs2_statfs_change_host)); | 839 | memset(sc, 0, sizeof(struct gfs2_statfs_change_host)); |
841 | gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL); | 840 | gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL); |
842 | if (!gha) | 841 | if (!gha) |
843 | return -ENOMEM; | 842 | return -ENOMEM; |
844 | 843 | ||
845 | error = gfs2_rindex_hold(sdp, &ri_gh); | 844 | error = gfs2_rindex_hold(sdp, &ri_gh); |
846 | if (error) | 845 | if (error) |
847 | goto out; | 846 | goto out; |
848 | 847 | ||
849 | rgd_next = gfs2_rgrpd_get_first(sdp); | 848 | rgd_next = gfs2_rgrpd_get_first(sdp); |
850 | 849 | ||
851 | for (;;) { | 850 | for (;;) { |
852 | done = 1; | 851 | done = 1; |
853 | 852 | ||
854 | for (x = 0; x < slots; x++) { | 853 | for (x = 0; x < slots; x++) { |
855 | gh = gha + x; | 854 | gh = gha + x; |
856 | 855 | ||
857 | if (gh->gh_gl && gfs2_glock_poll(gh)) { | 856 | if (gh->gh_gl && gfs2_glock_poll(gh)) { |
858 | err = gfs2_glock_wait(gh); | 857 | err = gfs2_glock_wait(gh); |
859 | if (err) { | 858 | if (err) { |
860 | gfs2_holder_uninit(gh); | 859 | gfs2_holder_uninit(gh); |
861 | error = err; | 860 | error = err; |
862 | } else { | 861 | } else { |
863 | if (!error) | 862 | if (!error) |
864 | error = statfs_slow_fill( | 863 | error = statfs_slow_fill( |
865 | gh->gh_gl->gl_object, sc); | 864 | gh->gh_gl->gl_object, sc); |
866 | gfs2_glock_dq_uninit(gh); | 865 | gfs2_glock_dq_uninit(gh); |
867 | } | 866 | } |
868 | } | 867 | } |
869 | 868 | ||
870 | if (gh->gh_gl) | 869 | if (gh->gh_gl) |
871 | done = 0; | 870 | done = 0; |
872 | else if (rgd_next && !error) { | 871 | else if (rgd_next && !error) { |
873 | error = gfs2_glock_nq_init(rgd_next->rd_gl, | 872 | error = gfs2_glock_nq_init(rgd_next->rd_gl, |
874 | LM_ST_SHARED, | 873 | LM_ST_SHARED, |
875 | GL_ASYNC, | 874 | GL_ASYNC, |
876 | gh); | 875 | gh); |
877 | rgd_next = gfs2_rgrpd_get_next(rgd_next); | 876 | rgd_next = gfs2_rgrpd_get_next(rgd_next); |
878 | done = 0; | 877 | done = 0; |
879 | } | 878 | } |
880 | 879 | ||
881 | if (signal_pending(current)) | 880 | if (signal_pending(current)) |
882 | error = -ERESTARTSYS; | 881 | error = -ERESTARTSYS; |
883 | } | 882 | } |
884 | 883 | ||
885 | if (done) | 884 | if (done) |
886 | break; | 885 | break; |
887 | 886 | ||
888 | yield(); | 887 | yield(); |
889 | } | 888 | } |
890 | 889 | ||
891 | gfs2_glock_dq_uninit(&ri_gh); | 890 | gfs2_glock_dq_uninit(&ri_gh); |
892 | 891 | ||
893 | out: | 892 | out: |
894 | kfree(gha); | 893 | kfree(gha); |
895 | return error; | 894 | return error; |
896 | } | 895 | } |
897 | 896 | ||
898 | struct lfcc { | 897 | struct lfcc { |
899 | struct list_head list; | 898 | struct list_head list; |
900 | struct gfs2_holder gh; | 899 | struct gfs2_holder gh; |
901 | }; | 900 | }; |
902 | 901 | ||
903 | /** | 902 | /** |
904 | * gfs2_lock_fs_check_clean - Stop all writes to the FS and check that all | 903 | * gfs2_lock_fs_check_clean - Stop all writes to the FS and check that all |
905 | * journals are clean | 904 | * journals are clean |
906 | * @sdp: the file system | 905 | * @sdp: the file system |
907 | * @state: the state to put the transaction lock into | 906 | * @state: the state to put the transaction lock into |
908 | * @t_gh: the hold on the transaction lock | 907 | * @t_gh: the hold on the transaction lock |
909 | * | 908 | * |
910 | * Returns: errno | 909 | * Returns: errno |
911 | */ | 910 | */ |
912 | 911 | ||
913 | static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, | 912 | static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, |
914 | struct gfs2_holder *t_gh) | 913 | struct gfs2_holder *t_gh) |
915 | { | 914 | { |
916 | struct gfs2_inode *ip; | 915 | struct gfs2_inode *ip; |
917 | struct gfs2_holder ji_gh; | 916 | struct gfs2_holder ji_gh; |
918 | struct gfs2_jdesc *jd; | 917 | struct gfs2_jdesc *jd; |
919 | struct lfcc *lfcc; | 918 | struct lfcc *lfcc; |
920 | LIST_HEAD(list); | 919 | LIST_HEAD(list); |
921 | struct gfs2_log_header_host lh; | 920 | struct gfs2_log_header_host lh; |
922 | int error; | 921 | int error; |
923 | 922 | ||
924 | error = gfs2_jindex_hold(sdp, &ji_gh); | 923 | error = gfs2_jindex_hold(sdp, &ji_gh); |
925 | if (error) | 924 | if (error) |
926 | return error; | 925 | return error; |
927 | 926 | ||
928 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | 927 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { |
929 | lfcc = kmalloc(sizeof(struct lfcc), GFP_KERNEL); | 928 | lfcc = kmalloc(sizeof(struct lfcc), GFP_KERNEL); |
930 | if (!lfcc) { | 929 | if (!lfcc) { |
931 | error = -ENOMEM; | 930 | error = -ENOMEM; |
932 | goto out; | 931 | goto out; |
933 | } | 932 | } |
934 | ip = GFS2_I(jd->jd_inode); | 933 | ip = GFS2_I(jd->jd_inode); |
935 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &lfcc->gh); | 934 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &lfcc->gh); |
936 | if (error) { | 935 | if (error) { |
937 | kfree(lfcc); | 936 | kfree(lfcc); |
938 | goto out; | 937 | goto out; |
939 | } | 938 | } |
940 | list_add(&lfcc->list, &list); | 939 | list_add(&lfcc->list, &list); |
941 | } | 940 | } |
942 | 941 | ||
943 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_DEFERRED, | 942 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_DEFERRED, |
944 | GL_NOCACHE, t_gh); | 943 | GL_NOCACHE, t_gh); |
945 | 944 | ||
946 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | 945 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { |
947 | error = gfs2_jdesc_check(jd); | 946 | error = gfs2_jdesc_check(jd); |
948 | if (error) | 947 | if (error) |
949 | break; | 948 | break; |
950 | error = gfs2_find_jhead(jd, &lh); | 949 | error = gfs2_find_jhead(jd, &lh); |
951 | if (error) | 950 | if (error) |
952 | break; | 951 | break; |
953 | if (!(lh.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) { | 952 | if (!(lh.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) { |
954 | error = -EBUSY; | 953 | error = -EBUSY; |
955 | break; | 954 | break; |
956 | } | 955 | } |
957 | } | 956 | } |
958 | 957 | ||
959 | if (error) | 958 | if (error) |
960 | gfs2_glock_dq_uninit(t_gh); | 959 | gfs2_glock_dq_uninit(t_gh); |
961 | 960 | ||
962 | out: | 961 | out: |
963 | while (!list_empty(&list)) { | 962 | while (!list_empty(&list)) { |
964 | lfcc = list_entry(list.next, struct lfcc, list); | 963 | lfcc = list_entry(list.next, struct lfcc, list); |
965 | list_del(&lfcc->list); | 964 | list_del(&lfcc->list); |
966 | gfs2_glock_dq_uninit(&lfcc->gh); | 965 | gfs2_glock_dq_uninit(&lfcc->gh); |
967 | kfree(lfcc); | 966 | kfree(lfcc); |
968 | } | 967 | } |
969 | gfs2_glock_dq_uninit(&ji_gh); | 968 | gfs2_glock_dq_uninit(&ji_gh); |
970 | return error; | 969 | return error; |
971 | } | 970 | } |
972 | 971 | ||
973 | /** | 972 | /** |
974 | * gfs2_freeze_fs - freezes the file system | 973 | * gfs2_freeze_fs - freezes the file system |
975 | * @sdp: the file system | 974 | * @sdp: the file system |
976 | * | 975 | * |
977 | * This function flushes data and meta data for all machines by | 976 | * This function flushes data and meta data for all machines by |
978 | * aquiring the transaction log exclusively. All journals are | 977 | * aquiring the transaction log exclusively. All journals are |
979 | * ensured to be in a clean state as well. | 978 | * ensured to be in a clean state as well. |
980 | * | 979 | * |
981 | * Returns: errno | 980 | * Returns: errno |
982 | */ | 981 | */ |
983 | 982 | ||
984 | int gfs2_freeze_fs(struct gfs2_sbd *sdp) | 983 | int gfs2_freeze_fs(struct gfs2_sbd *sdp) |
985 | { | 984 | { |
986 | int error = 0; | 985 | int error = 0; |
987 | 986 | ||
988 | mutex_lock(&sdp->sd_freeze_lock); | 987 | mutex_lock(&sdp->sd_freeze_lock); |
989 | 988 | ||
990 | if (!sdp->sd_freeze_count++) { | 989 | if (!sdp->sd_freeze_count++) { |
991 | error = gfs2_lock_fs_check_clean(sdp, &sdp->sd_freeze_gh); | 990 | error = gfs2_lock_fs_check_clean(sdp, &sdp->sd_freeze_gh); |
992 | if (error) | 991 | if (error) |
993 | sdp->sd_freeze_count--; | 992 | sdp->sd_freeze_count--; |
994 | } | 993 | } |
995 | 994 | ||
996 | mutex_unlock(&sdp->sd_freeze_lock); | 995 | mutex_unlock(&sdp->sd_freeze_lock); |
997 | 996 | ||
998 | return error; | 997 | return error; |
999 | } | 998 | } |
1000 | 999 | ||
1001 | /** | 1000 | /** |
1002 | * gfs2_unfreeze_fs - unfreezes the file system | 1001 | * gfs2_unfreeze_fs - unfreezes the file system |
1003 | * @sdp: the file system | 1002 | * @sdp: the file system |
1004 | * | 1003 | * |
1005 | * This function allows the file system to proceed by unlocking | 1004 | * This function allows the file system to proceed by unlocking |
1006 | * the exclusively held transaction lock. Other GFS2 nodes are | 1005 | * the exclusively held transaction lock. Other GFS2 nodes are |
1007 | * now free to acquire the lock shared and go on with their lives. | 1006 | * now free to acquire the lock shared and go on with their lives. |
1008 | * | 1007 | * |
1009 | */ | 1008 | */ |
1010 | 1009 | ||
1011 | void gfs2_unfreeze_fs(struct gfs2_sbd *sdp) | 1010 | void gfs2_unfreeze_fs(struct gfs2_sbd *sdp) |
1012 | { | 1011 | { |
1013 | mutex_lock(&sdp->sd_freeze_lock); | 1012 | mutex_lock(&sdp->sd_freeze_lock); |
1014 | 1013 | ||
1015 | if (sdp->sd_freeze_count && !--sdp->sd_freeze_count) | 1014 | if (sdp->sd_freeze_count && !--sdp->sd_freeze_count) |
1016 | gfs2_glock_dq_uninit(&sdp->sd_freeze_gh); | 1015 | gfs2_glock_dq_uninit(&sdp->sd_freeze_gh); |
1017 | 1016 | ||
1018 | mutex_unlock(&sdp->sd_freeze_lock); | 1017 | mutex_unlock(&sdp->sd_freeze_lock); |
1019 | } | 1018 | } |
1020 | 1019 | ||
1021 | 1020 |
fs/gfs2/sys.c
1 | /* | 1 | /* |
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | 3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This copyrighted material is made available to anyone wishing to use, | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | * modify, copy, or redistribute it subject to the terms and conditions | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
7 | * of the GNU General Public License version 2. | 7 | * of the GNU General Public License version 2. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
13 | #include <linux/completion.h> | 13 | #include <linux/completion.h> |
14 | #include <linux/buffer_head.h> | 14 | #include <linux/buffer_head.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/kobject.h> | 16 | #include <linux/kobject.h> |
17 | #include <linux/gfs2_ondisk.h> | 17 | #include <linux/gfs2_ondisk.h> |
18 | #include <linux/lm_interface.h> | 18 | #include <linux/lm_interface.h> |
19 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
20 | 20 | ||
21 | #include "gfs2.h" | 21 | #include "gfs2.h" |
22 | #include "incore.h" | 22 | #include "incore.h" |
23 | #include "sys.h" | 23 | #include "sys.h" |
24 | #include "super.h" | 24 | #include "super.h" |
25 | #include "glock.h" | 25 | #include "glock.h" |
26 | #include "quota.h" | 26 | #include "quota.h" |
27 | #include "util.h" | 27 | #include "util.h" |
28 | 28 | ||
29 | char *gfs2_sys_margs; | 29 | char *gfs2_sys_margs; |
30 | spinlock_t gfs2_sys_margs_lock; | 30 | spinlock_t gfs2_sys_margs_lock; |
31 | 31 | ||
32 | static ssize_t id_show(struct gfs2_sbd *sdp, char *buf) | 32 | static ssize_t id_show(struct gfs2_sbd *sdp, char *buf) |
33 | { | 33 | { |
34 | return snprintf(buf, PAGE_SIZE, "%u:%u\n", | 34 | return snprintf(buf, PAGE_SIZE, "%u:%u\n", |
35 | MAJOR(sdp->sd_vfs->s_dev), MINOR(sdp->sd_vfs->s_dev)); | 35 | MAJOR(sdp->sd_vfs->s_dev), MINOR(sdp->sd_vfs->s_dev)); |
36 | } | 36 | } |
37 | 37 | ||
38 | static ssize_t fsname_show(struct gfs2_sbd *sdp, char *buf) | 38 | static ssize_t fsname_show(struct gfs2_sbd *sdp, char *buf) |
39 | { | 39 | { |
40 | return snprintf(buf, PAGE_SIZE, "%s\n", sdp->sd_fsname); | 40 | return snprintf(buf, PAGE_SIZE, "%s\n", sdp->sd_fsname); |
41 | } | 41 | } |
42 | 42 | ||
43 | static ssize_t freeze_show(struct gfs2_sbd *sdp, char *buf) | 43 | static ssize_t freeze_show(struct gfs2_sbd *sdp, char *buf) |
44 | { | 44 | { |
45 | unsigned int count; | 45 | unsigned int count; |
46 | 46 | ||
47 | mutex_lock(&sdp->sd_freeze_lock); | 47 | mutex_lock(&sdp->sd_freeze_lock); |
48 | count = sdp->sd_freeze_count; | 48 | count = sdp->sd_freeze_count; |
49 | mutex_unlock(&sdp->sd_freeze_lock); | 49 | mutex_unlock(&sdp->sd_freeze_lock); |
50 | 50 | ||
51 | return snprintf(buf, PAGE_SIZE, "%u\n", count); | 51 | return snprintf(buf, PAGE_SIZE, "%u\n", count); |
52 | } | 52 | } |
53 | 53 | ||
54 | static ssize_t freeze_store(struct gfs2_sbd *sdp, const char *buf, size_t len) | 54 | static ssize_t freeze_store(struct gfs2_sbd *sdp, const char *buf, size_t len) |
55 | { | 55 | { |
56 | ssize_t ret = len; | 56 | ssize_t ret = len; |
57 | int error = 0; | 57 | int error = 0; |
58 | int n = simple_strtol(buf, NULL, 0); | 58 | int n = simple_strtol(buf, NULL, 0); |
59 | 59 | ||
60 | if (!capable(CAP_SYS_ADMIN)) | 60 | if (!capable(CAP_SYS_ADMIN)) |
61 | return -EACCES; | 61 | return -EACCES; |
62 | 62 | ||
63 | switch (n) { | 63 | switch (n) { |
64 | case 0: | 64 | case 0: |
65 | gfs2_unfreeze_fs(sdp); | 65 | gfs2_unfreeze_fs(sdp); |
66 | break; | 66 | break; |
67 | case 1: | 67 | case 1: |
68 | error = gfs2_freeze_fs(sdp); | 68 | error = gfs2_freeze_fs(sdp); |
69 | break; | 69 | break; |
70 | default: | 70 | default: |
71 | ret = -EINVAL; | 71 | ret = -EINVAL; |
72 | } | 72 | } |
73 | 73 | ||
74 | if (error) | 74 | if (error) |
75 | fs_warn(sdp, "freeze %d error %d", n, error); | 75 | fs_warn(sdp, "freeze %d error %d", n, error); |
76 | 76 | ||
77 | return ret; | 77 | return ret; |
78 | } | 78 | } |
79 | 79 | ||
80 | static ssize_t withdraw_show(struct gfs2_sbd *sdp, char *buf) | 80 | static ssize_t withdraw_show(struct gfs2_sbd *sdp, char *buf) |
81 | { | 81 | { |
82 | unsigned int b = test_bit(SDF_SHUTDOWN, &sdp->sd_flags); | 82 | unsigned int b = test_bit(SDF_SHUTDOWN, &sdp->sd_flags); |
83 | return snprintf(buf, PAGE_SIZE, "%u\n", b); | 83 | return snprintf(buf, PAGE_SIZE, "%u\n", b); |
84 | } | 84 | } |
85 | 85 | ||
86 | static ssize_t withdraw_store(struct gfs2_sbd *sdp, const char *buf, size_t len) | 86 | static ssize_t withdraw_store(struct gfs2_sbd *sdp, const char *buf, size_t len) |
87 | { | 87 | { |
88 | if (!capable(CAP_SYS_ADMIN)) | 88 | if (!capable(CAP_SYS_ADMIN)) |
89 | return -EACCES; | 89 | return -EACCES; |
90 | 90 | ||
91 | if (simple_strtol(buf, NULL, 0) != 1) | 91 | if (simple_strtol(buf, NULL, 0) != 1) |
92 | return -EINVAL; | 92 | return -EINVAL; |
93 | 93 | ||
94 | gfs2_lm_withdraw(sdp, | 94 | gfs2_lm_withdraw(sdp, |
95 | "GFS2: fsid=%s: withdrawing from cluster at user's request\n", | 95 | "GFS2: fsid=%s: withdrawing from cluster at user's request\n", |
96 | sdp->sd_fsname); | 96 | sdp->sd_fsname); |
97 | return len; | 97 | return len; |
98 | } | 98 | } |
99 | 99 | ||
100 | static ssize_t statfs_sync_store(struct gfs2_sbd *sdp, const char *buf, | 100 | static ssize_t statfs_sync_store(struct gfs2_sbd *sdp, const char *buf, |
101 | size_t len) | 101 | size_t len) |
102 | { | 102 | { |
103 | if (!capable(CAP_SYS_ADMIN)) | 103 | if (!capable(CAP_SYS_ADMIN)) |
104 | return -EACCES; | 104 | return -EACCES; |
105 | 105 | ||
106 | if (simple_strtol(buf, NULL, 0) != 1) | 106 | if (simple_strtol(buf, NULL, 0) != 1) |
107 | return -EINVAL; | 107 | return -EINVAL; |
108 | 108 | ||
109 | gfs2_statfs_sync(sdp); | 109 | gfs2_statfs_sync(sdp); |
110 | return len; | 110 | return len; |
111 | } | 111 | } |
112 | 112 | ||
113 | static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf, | 113 | static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf, |
114 | size_t len) | 114 | size_t len) |
115 | { | 115 | { |
116 | if (!capable(CAP_SYS_ADMIN)) | 116 | if (!capable(CAP_SYS_ADMIN)) |
117 | return -EACCES; | 117 | return -EACCES; |
118 | 118 | ||
119 | if (simple_strtol(buf, NULL, 0) != 1) | 119 | if (simple_strtol(buf, NULL, 0) != 1) |
120 | return -EINVAL; | 120 | return -EINVAL; |
121 | 121 | ||
122 | gfs2_quota_sync(sdp); | 122 | gfs2_quota_sync(sdp); |
123 | return len; | 123 | return len; |
124 | } | 124 | } |
125 | 125 | ||
126 | static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf, | 126 | static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf, |
127 | size_t len) | 127 | size_t len) |
128 | { | 128 | { |
129 | u32 id; | 129 | u32 id; |
130 | 130 | ||
131 | if (!capable(CAP_SYS_ADMIN)) | 131 | if (!capable(CAP_SYS_ADMIN)) |
132 | return -EACCES; | 132 | return -EACCES; |
133 | 133 | ||
134 | id = simple_strtoul(buf, NULL, 0); | 134 | id = simple_strtoul(buf, NULL, 0); |
135 | 135 | ||
136 | gfs2_quota_refresh(sdp, 1, id); | 136 | gfs2_quota_refresh(sdp, 1, id); |
137 | return len; | 137 | return len; |
138 | } | 138 | } |
139 | 139 | ||
140 | static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf, | 140 | static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf, |
141 | size_t len) | 141 | size_t len) |
142 | { | 142 | { |
143 | u32 id; | 143 | u32 id; |
144 | 144 | ||
145 | if (!capable(CAP_SYS_ADMIN)) | 145 | if (!capable(CAP_SYS_ADMIN)) |
146 | return -EACCES; | 146 | return -EACCES; |
147 | 147 | ||
148 | id = simple_strtoul(buf, NULL, 0); | 148 | id = simple_strtoul(buf, NULL, 0); |
149 | 149 | ||
150 | gfs2_quota_refresh(sdp, 0, id); | 150 | gfs2_quota_refresh(sdp, 0, id); |
151 | return len; | 151 | return len; |
152 | } | 152 | } |
153 | 153 | ||
154 | struct gfs2_attr { | 154 | struct gfs2_attr { |
155 | struct attribute attr; | 155 | struct attribute attr; |
156 | ssize_t (*show)(struct gfs2_sbd *, char *); | 156 | ssize_t (*show)(struct gfs2_sbd *, char *); |
157 | ssize_t (*store)(struct gfs2_sbd *, const char *, size_t); | 157 | ssize_t (*store)(struct gfs2_sbd *, const char *, size_t); |
158 | }; | 158 | }; |
159 | 159 | ||
160 | #define GFS2_ATTR(name, mode, show, store) \ | 160 | #define GFS2_ATTR(name, mode, show, store) \ |
161 | static struct gfs2_attr gfs2_attr_##name = __ATTR(name, mode, show, store) | 161 | static struct gfs2_attr gfs2_attr_##name = __ATTR(name, mode, show, store) |
162 | 162 | ||
163 | GFS2_ATTR(id, 0444, id_show, NULL); | 163 | GFS2_ATTR(id, 0444, id_show, NULL); |
164 | GFS2_ATTR(fsname, 0444, fsname_show, NULL); | 164 | GFS2_ATTR(fsname, 0444, fsname_show, NULL); |
165 | GFS2_ATTR(freeze, 0644, freeze_show, freeze_store); | 165 | GFS2_ATTR(freeze, 0644, freeze_show, freeze_store); |
166 | GFS2_ATTR(withdraw, 0644, withdraw_show, withdraw_store); | 166 | GFS2_ATTR(withdraw, 0644, withdraw_show, withdraw_store); |
167 | GFS2_ATTR(statfs_sync, 0200, NULL, statfs_sync_store); | 167 | GFS2_ATTR(statfs_sync, 0200, NULL, statfs_sync_store); |
168 | GFS2_ATTR(quota_sync, 0200, NULL, quota_sync_store); | 168 | GFS2_ATTR(quota_sync, 0200, NULL, quota_sync_store); |
169 | GFS2_ATTR(quota_refresh_user, 0200, NULL, quota_refresh_user_store); | 169 | GFS2_ATTR(quota_refresh_user, 0200, NULL, quota_refresh_user_store); |
170 | GFS2_ATTR(quota_refresh_group, 0200, NULL, quota_refresh_group_store); | 170 | GFS2_ATTR(quota_refresh_group, 0200, NULL, quota_refresh_group_store); |
171 | 171 | ||
172 | static struct attribute *gfs2_attrs[] = { | 172 | static struct attribute *gfs2_attrs[] = { |
173 | &gfs2_attr_id.attr, | 173 | &gfs2_attr_id.attr, |
174 | &gfs2_attr_fsname.attr, | 174 | &gfs2_attr_fsname.attr, |
175 | &gfs2_attr_freeze.attr, | 175 | &gfs2_attr_freeze.attr, |
176 | &gfs2_attr_withdraw.attr, | 176 | &gfs2_attr_withdraw.attr, |
177 | &gfs2_attr_statfs_sync.attr, | 177 | &gfs2_attr_statfs_sync.attr, |
178 | &gfs2_attr_quota_sync.attr, | 178 | &gfs2_attr_quota_sync.attr, |
179 | &gfs2_attr_quota_refresh_user.attr, | 179 | &gfs2_attr_quota_refresh_user.attr, |
180 | &gfs2_attr_quota_refresh_group.attr, | 180 | &gfs2_attr_quota_refresh_group.attr, |
181 | NULL, | 181 | NULL, |
182 | }; | 182 | }; |
183 | 183 | ||
184 | static ssize_t gfs2_attr_show(struct kobject *kobj, struct attribute *attr, | 184 | static ssize_t gfs2_attr_show(struct kobject *kobj, struct attribute *attr, |
185 | char *buf) | 185 | char *buf) |
186 | { | 186 | { |
187 | struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); | 187 | struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); |
188 | struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr); | 188 | struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr); |
189 | return a->show ? a->show(sdp, buf) : 0; | 189 | return a->show ? a->show(sdp, buf) : 0; |
190 | } | 190 | } |
191 | 191 | ||
192 | static ssize_t gfs2_attr_store(struct kobject *kobj, struct attribute *attr, | 192 | static ssize_t gfs2_attr_store(struct kobject *kobj, struct attribute *attr, |
193 | const char *buf, size_t len) | 193 | const char *buf, size_t len) |
194 | { | 194 | { |
195 | struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); | 195 | struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); |
196 | struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr); | 196 | struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr); |
197 | return a->store ? a->store(sdp, buf, len) : len; | 197 | return a->store ? a->store(sdp, buf, len) : len; |
198 | } | 198 | } |
199 | 199 | ||
200 | static struct sysfs_ops gfs2_attr_ops = { | 200 | static struct sysfs_ops gfs2_attr_ops = { |
201 | .show = gfs2_attr_show, | 201 | .show = gfs2_attr_show, |
202 | .store = gfs2_attr_store, | 202 | .store = gfs2_attr_store, |
203 | }; | 203 | }; |
204 | 204 | ||
205 | static struct kobj_type gfs2_ktype = { | 205 | static struct kobj_type gfs2_ktype = { |
206 | .default_attrs = gfs2_attrs, | 206 | .default_attrs = gfs2_attrs, |
207 | .sysfs_ops = &gfs2_attr_ops, | 207 | .sysfs_ops = &gfs2_attr_ops, |
208 | }; | 208 | }; |
209 | 209 | ||
210 | static struct kset *gfs2_kset; | 210 | static struct kset *gfs2_kset; |
211 | 211 | ||
212 | /* | 212 | /* |
213 | * display struct lm_lockstruct fields | 213 | * display struct lm_lockstruct fields |
214 | */ | 214 | */ |
215 | 215 | ||
216 | struct lockstruct_attr { | 216 | struct lockstruct_attr { |
217 | struct attribute attr; | 217 | struct attribute attr; |
218 | ssize_t (*show)(struct gfs2_sbd *, char *); | 218 | ssize_t (*show)(struct gfs2_sbd *, char *); |
219 | }; | 219 | }; |
220 | 220 | ||
221 | #define LOCKSTRUCT_ATTR(name, fmt) \ | 221 | #define LOCKSTRUCT_ATTR(name, fmt) \ |
222 | static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf) \ | 222 | static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf) \ |
223 | { \ | 223 | { \ |
224 | return snprintf(buf, PAGE_SIZE, fmt, sdp->sd_lockstruct.ls_##name); \ | 224 | return snprintf(buf, PAGE_SIZE, fmt, sdp->sd_lockstruct.ls_##name); \ |
225 | } \ | 225 | } \ |
226 | static struct lockstruct_attr lockstruct_attr_##name = __ATTR_RO(name) | 226 | static struct lockstruct_attr lockstruct_attr_##name = __ATTR_RO(name) |
227 | 227 | ||
228 | LOCKSTRUCT_ATTR(jid, "%u\n"); | 228 | LOCKSTRUCT_ATTR(jid, "%u\n"); |
229 | LOCKSTRUCT_ATTR(first, "%u\n"); | 229 | LOCKSTRUCT_ATTR(first, "%u\n"); |
230 | LOCKSTRUCT_ATTR(lvb_size, "%u\n"); | 230 | LOCKSTRUCT_ATTR(lvb_size, "%u\n"); |
231 | LOCKSTRUCT_ATTR(flags, "%d\n"); | 231 | LOCKSTRUCT_ATTR(flags, "%d\n"); |
232 | 232 | ||
233 | static struct attribute *lockstruct_attrs[] = { | 233 | static struct attribute *lockstruct_attrs[] = { |
234 | &lockstruct_attr_jid.attr, | 234 | &lockstruct_attr_jid.attr, |
235 | &lockstruct_attr_first.attr, | 235 | &lockstruct_attr_first.attr, |
236 | &lockstruct_attr_lvb_size.attr, | 236 | &lockstruct_attr_lvb_size.attr, |
237 | &lockstruct_attr_flags.attr, | 237 | &lockstruct_attr_flags.attr, |
238 | NULL, | 238 | NULL, |
239 | }; | 239 | }; |
240 | 240 | ||
241 | /* | 241 | /* |
242 | * display struct gfs2_args fields | 242 | * display struct gfs2_args fields |
243 | */ | 243 | */ |
244 | 244 | ||
245 | struct args_attr { | 245 | struct args_attr { |
246 | struct attribute attr; | 246 | struct attribute attr; |
247 | ssize_t (*show)(struct gfs2_sbd *, char *); | 247 | ssize_t (*show)(struct gfs2_sbd *, char *); |
248 | }; | 248 | }; |
249 | 249 | ||
250 | #define ARGS_ATTR(name, fmt) \ | 250 | #define ARGS_ATTR(name, fmt) \ |
251 | static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf) \ | 251 | static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf) \ |
252 | { \ | 252 | { \ |
253 | return snprintf(buf, PAGE_SIZE, fmt, sdp->sd_args.ar_##name); \ | 253 | return snprintf(buf, PAGE_SIZE, fmt, sdp->sd_args.ar_##name); \ |
254 | } \ | 254 | } \ |
255 | static struct args_attr args_attr_##name = __ATTR_RO(name) | 255 | static struct args_attr args_attr_##name = __ATTR_RO(name) |
256 | 256 | ||
257 | ARGS_ATTR(lockproto, "%s\n"); | 257 | ARGS_ATTR(lockproto, "%s\n"); |
258 | ARGS_ATTR(locktable, "%s\n"); | 258 | ARGS_ATTR(locktable, "%s\n"); |
259 | ARGS_ATTR(hostdata, "%s\n"); | 259 | ARGS_ATTR(hostdata, "%s\n"); |
260 | ARGS_ATTR(spectator, "%d\n"); | 260 | ARGS_ATTR(spectator, "%d\n"); |
261 | ARGS_ATTR(ignore_local_fs, "%d\n"); | 261 | ARGS_ATTR(ignore_local_fs, "%d\n"); |
262 | ARGS_ATTR(localcaching, "%d\n"); | 262 | ARGS_ATTR(localcaching, "%d\n"); |
263 | ARGS_ATTR(localflocks, "%d\n"); | 263 | ARGS_ATTR(localflocks, "%d\n"); |
264 | ARGS_ATTR(debug, "%d\n"); | 264 | ARGS_ATTR(debug, "%d\n"); |
265 | ARGS_ATTR(upgrade, "%d\n"); | 265 | ARGS_ATTR(upgrade, "%d\n"); |
266 | ARGS_ATTR(num_glockd, "%u\n"); | 266 | ARGS_ATTR(num_glockd, "%u\n"); |
267 | ARGS_ATTR(posix_acl, "%d\n"); | 267 | ARGS_ATTR(posix_acl, "%d\n"); |
268 | ARGS_ATTR(quota, "%u\n"); | 268 | ARGS_ATTR(quota, "%u\n"); |
269 | ARGS_ATTR(suiddir, "%d\n"); | 269 | ARGS_ATTR(suiddir, "%d\n"); |
270 | ARGS_ATTR(data, "%d\n"); | 270 | ARGS_ATTR(data, "%d\n"); |
271 | 271 | ||
272 | /* one oddball doesn't fit the macro mold */ | 272 | /* one oddball doesn't fit the macro mold */ |
273 | static ssize_t noatime_show(struct gfs2_sbd *sdp, char *buf) | 273 | static ssize_t noatime_show(struct gfs2_sbd *sdp, char *buf) |
274 | { | 274 | { |
275 | return snprintf(buf, PAGE_SIZE, "%d\n", | 275 | return snprintf(buf, PAGE_SIZE, "%d\n", |
276 | !!test_bit(SDF_NOATIME, &sdp->sd_flags)); | 276 | !!test_bit(SDF_NOATIME, &sdp->sd_flags)); |
277 | } | 277 | } |
278 | static struct args_attr args_attr_noatime = __ATTR_RO(noatime); | 278 | static struct args_attr args_attr_noatime = __ATTR_RO(noatime); |
279 | 279 | ||
280 | static struct attribute *args_attrs[] = { | 280 | static struct attribute *args_attrs[] = { |
281 | &args_attr_lockproto.attr, | 281 | &args_attr_lockproto.attr, |
282 | &args_attr_locktable.attr, | 282 | &args_attr_locktable.attr, |
283 | &args_attr_hostdata.attr, | 283 | &args_attr_hostdata.attr, |
284 | &args_attr_spectator.attr, | 284 | &args_attr_spectator.attr, |
285 | &args_attr_ignore_local_fs.attr, | 285 | &args_attr_ignore_local_fs.attr, |
286 | &args_attr_localcaching.attr, | 286 | &args_attr_localcaching.attr, |
287 | &args_attr_localflocks.attr, | 287 | &args_attr_localflocks.attr, |
288 | &args_attr_debug.attr, | 288 | &args_attr_debug.attr, |
289 | &args_attr_upgrade.attr, | 289 | &args_attr_upgrade.attr, |
290 | &args_attr_num_glockd.attr, | 290 | &args_attr_num_glockd.attr, |
291 | &args_attr_posix_acl.attr, | 291 | &args_attr_posix_acl.attr, |
292 | &args_attr_quota.attr, | 292 | &args_attr_quota.attr, |
293 | &args_attr_suiddir.attr, | 293 | &args_attr_suiddir.attr, |
294 | &args_attr_data.attr, | 294 | &args_attr_data.attr, |
295 | &args_attr_noatime.attr, | 295 | &args_attr_noatime.attr, |
296 | NULL, | 296 | NULL, |
297 | }; | 297 | }; |
298 | 298 | ||
299 | /* | 299 | /* |
300 | * display counters from superblock | 300 | * display counters from superblock |
301 | */ | 301 | */ |
302 | 302 | ||
303 | struct counters_attr { | 303 | struct counters_attr { |
304 | struct attribute attr; | 304 | struct attribute attr; |
305 | ssize_t (*show)(struct gfs2_sbd *, char *); | 305 | ssize_t (*show)(struct gfs2_sbd *, char *); |
306 | }; | 306 | }; |
307 | 307 | ||
308 | #define COUNTERS_ATTR(name, fmt) \ | 308 | #define COUNTERS_ATTR(name, fmt) \ |
309 | static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf) \ | 309 | static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf) \ |
310 | { \ | 310 | { \ |
311 | return snprintf(buf, PAGE_SIZE, fmt, \ | 311 | return snprintf(buf, PAGE_SIZE, fmt, \ |
312 | (unsigned int)atomic_read(&sdp->sd_##name)); \ | 312 | (unsigned int)atomic_read(&sdp->sd_##name)); \ |
313 | } \ | 313 | } \ |
314 | static struct counters_attr counters_attr_##name = __ATTR_RO(name) | 314 | static struct counters_attr counters_attr_##name = __ATTR_RO(name) |
315 | 315 | ||
316 | COUNTERS_ATTR(reclaimed, "%u\n"); | 316 | COUNTERS_ATTR(reclaimed, "%u\n"); |
317 | 317 | ||
318 | static struct attribute *counters_attrs[] = { | 318 | static struct attribute *counters_attrs[] = { |
319 | &counters_attr_reclaimed.attr, | 319 | &counters_attr_reclaimed.attr, |
320 | NULL, | 320 | NULL, |
321 | }; | 321 | }; |
322 | 322 | ||
323 | /* | 323 | /* |
324 | * get and set struct gfs2_tune fields | 324 | * get and set struct gfs2_tune fields |
325 | */ | 325 | */ |
326 | 326 | ||
327 | static ssize_t quota_scale_show(struct gfs2_sbd *sdp, char *buf) | 327 | static ssize_t quota_scale_show(struct gfs2_sbd *sdp, char *buf) |
328 | { | 328 | { |
329 | return snprintf(buf, PAGE_SIZE, "%u %u\n", | 329 | return snprintf(buf, PAGE_SIZE, "%u %u\n", |
330 | sdp->sd_tune.gt_quota_scale_num, | 330 | sdp->sd_tune.gt_quota_scale_num, |
331 | sdp->sd_tune.gt_quota_scale_den); | 331 | sdp->sd_tune.gt_quota_scale_den); |
332 | } | 332 | } |
333 | 333 | ||
334 | static ssize_t quota_scale_store(struct gfs2_sbd *sdp, const char *buf, | 334 | static ssize_t quota_scale_store(struct gfs2_sbd *sdp, const char *buf, |
335 | size_t len) | 335 | size_t len) |
336 | { | 336 | { |
337 | struct gfs2_tune *gt = &sdp->sd_tune; | 337 | struct gfs2_tune *gt = &sdp->sd_tune; |
338 | unsigned int x, y; | 338 | unsigned int x, y; |
339 | 339 | ||
340 | if (!capable(CAP_SYS_ADMIN)) | 340 | if (!capable(CAP_SYS_ADMIN)) |
341 | return -EACCES; | 341 | return -EACCES; |
342 | 342 | ||
343 | if (sscanf(buf, "%u %u", &x, &y) != 2 || !y) | 343 | if (sscanf(buf, "%u %u", &x, &y) != 2 || !y) |
344 | return -EINVAL; | 344 | return -EINVAL; |
345 | 345 | ||
346 | spin_lock(>->gt_spin); | 346 | spin_lock(>->gt_spin); |
347 | gt->gt_quota_scale_num = x; | 347 | gt->gt_quota_scale_num = x; |
348 | gt->gt_quota_scale_den = y; | 348 | gt->gt_quota_scale_den = y; |
349 | spin_unlock(>->gt_spin); | 349 | spin_unlock(>->gt_spin); |
350 | return len; | 350 | return len; |
351 | } | 351 | } |
352 | 352 | ||
353 | static ssize_t tune_set(struct gfs2_sbd *sdp, unsigned int *field, | 353 | static ssize_t tune_set(struct gfs2_sbd *sdp, unsigned int *field, |
354 | int check_zero, const char *buf, size_t len) | 354 | int check_zero, const char *buf, size_t len) |
355 | { | 355 | { |
356 | struct gfs2_tune *gt = &sdp->sd_tune; | 356 | struct gfs2_tune *gt = &sdp->sd_tune; |
357 | unsigned int x; | 357 | unsigned int x; |
358 | 358 | ||
359 | if (!capable(CAP_SYS_ADMIN)) | 359 | if (!capable(CAP_SYS_ADMIN)) |
360 | return -EACCES; | 360 | return -EACCES; |
361 | 361 | ||
362 | x = simple_strtoul(buf, NULL, 0); | 362 | x = simple_strtoul(buf, NULL, 0); |
363 | 363 | ||
364 | if (check_zero && !x) | 364 | if (check_zero && !x) |
365 | return -EINVAL; | 365 | return -EINVAL; |
366 | 366 | ||
367 | spin_lock(>->gt_spin); | 367 | spin_lock(>->gt_spin); |
368 | *field = x; | 368 | *field = x; |
369 | spin_unlock(>->gt_spin); | 369 | spin_unlock(>->gt_spin); |
370 | return len; | 370 | return len; |
371 | } | 371 | } |
372 | 372 | ||
373 | struct tune_attr { | 373 | struct tune_attr { |
374 | struct attribute attr; | 374 | struct attribute attr; |
375 | ssize_t (*show)(struct gfs2_sbd *, char *); | 375 | ssize_t (*show)(struct gfs2_sbd *, char *); |
376 | ssize_t (*store)(struct gfs2_sbd *, const char *, size_t); | 376 | ssize_t (*store)(struct gfs2_sbd *, const char *, size_t); |
377 | }; | 377 | }; |
378 | 378 | ||
379 | #define TUNE_ATTR_3(name, show, store) \ | 379 | #define TUNE_ATTR_3(name, show, store) \ |
380 | static struct tune_attr tune_attr_##name = __ATTR(name, 0644, show, store) | 380 | static struct tune_attr tune_attr_##name = __ATTR(name, 0644, show, store) |
381 | 381 | ||
382 | #define TUNE_ATTR_2(name, store) \ | 382 | #define TUNE_ATTR_2(name, store) \ |
383 | static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf) \ | 383 | static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf) \ |
384 | { \ | 384 | { \ |
385 | return snprintf(buf, PAGE_SIZE, "%u\n", sdp->sd_tune.gt_##name); \ | 385 | return snprintf(buf, PAGE_SIZE, "%u\n", sdp->sd_tune.gt_##name); \ |
386 | } \ | 386 | } \ |
387 | TUNE_ATTR_3(name, name##_show, store) | 387 | TUNE_ATTR_3(name, name##_show, store) |
388 | 388 | ||
389 | #define TUNE_ATTR(name, check_zero) \ | 389 | #define TUNE_ATTR(name, check_zero) \ |
390 | static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\ | 390 | static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\ |
391 | { \ | 391 | { \ |
392 | return tune_set(sdp, &sdp->sd_tune.gt_##name, check_zero, buf, len); \ | 392 | return tune_set(sdp, &sdp->sd_tune.gt_##name, check_zero, buf, len); \ |
393 | } \ | 393 | } \ |
394 | TUNE_ATTR_2(name, name##_store) | 394 | TUNE_ATTR_2(name, name##_store) |
395 | 395 | ||
396 | #define TUNE_ATTR_DAEMON(name, process) \ | 396 | #define TUNE_ATTR_DAEMON(name, process) \ |
397 | static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\ | 397 | static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\ |
398 | { \ | 398 | { \ |
399 | ssize_t r = tune_set(sdp, &sdp->sd_tune.gt_##name, 1, buf, len); \ | 399 | ssize_t r = tune_set(sdp, &sdp->sd_tune.gt_##name, 1, buf, len); \ |
400 | wake_up_process(sdp->sd_##process); \ | 400 | wake_up_process(sdp->sd_##process); \ |
401 | return r; \ | 401 | return r; \ |
402 | } \ | 402 | } \ |
403 | TUNE_ATTR_2(name, name##_store) | 403 | TUNE_ATTR_2(name, name##_store) |
404 | 404 | ||
405 | TUNE_ATTR(demote_secs, 0); | 405 | TUNE_ATTR(demote_secs, 0); |
406 | TUNE_ATTR(incore_log_blocks, 0); | 406 | TUNE_ATTR(incore_log_blocks, 0); |
407 | TUNE_ATTR(log_flush_secs, 0); | 407 | TUNE_ATTR(log_flush_secs, 0); |
408 | TUNE_ATTR(quota_warn_period, 0); | 408 | TUNE_ATTR(quota_warn_period, 0); |
409 | TUNE_ATTR(quota_quantum, 0); | 409 | TUNE_ATTR(quota_quantum, 0); |
410 | TUNE_ATTR(atime_quantum, 0); | 410 | TUNE_ATTR(atime_quantum, 0); |
411 | TUNE_ATTR(max_readahead, 0); | 411 | TUNE_ATTR(max_readahead, 0); |
412 | TUNE_ATTR(complain_secs, 0); | 412 | TUNE_ATTR(complain_secs, 0); |
413 | TUNE_ATTR(statfs_slow, 0); | 413 | TUNE_ATTR(statfs_slow, 0); |
414 | TUNE_ATTR(new_files_jdata, 0); | 414 | TUNE_ATTR(new_files_jdata, 0); |
415 | TUNE_ATTR(new_files_directio, 0); | ||
416 | TUNE_ATTR(quota_simul_sync, 1); | 415 | TUNE_ATTR(quota_simul_sync, 1); |
417 | TUNE_ATTR(quota_cache_secs, 1); | 416 | TUNE_ATTR(quota_cache_secs, 1); |
418 | TUNE_ATTR(stall_secs, 1); | 417 | TUNE_ATTR(stall_secs, 1); |
419 | TUNE_ATTR(statfs_quantum, 1); | 418 | TUNE_ATTR(statfs_quantum, 1); |
420 | TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process); | 419 | TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process); |
421 | TUNE_ATTR_DAEMON(logd_secs, logd_process); | 420 | TUNE_ATTR_DAEMON(logd_secs, logd_process); |
422 | TUNE_ATTR_DAEMON(quotad_secs, quotad_process); | 421 | TUNE_ATTR_DAEMON(quotad_secs, quotad_process); |
423 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); | 422 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); |
424 | 423 | ||
425 | static struct attribute *tune_attrs[] = { | 424 | static struct attribute *tune_attrs[] = { |
426 | &tune_attr_demote_secs.attr, | 425 | &tune_attr_demote_secs.attr, |
427 | &tune_attr_incore_log_blocks.attr, | 426 | &tune_attr_incore_log_blocks.attr, |
428 | &tune_attr_log_flush_secs.attr, | 427 | &tune_attr_log_flush_secs.attr, |
429 | &tune_attr_quota_warn_period.attr, | 428 | &tune_attr_quota_warn_period.attr, |
430 | &tune_attr_quota_quantum.attr, | 429 | &tune_attr_quota_quantum.attr, |
431 | &tune_attr_atime_quantum.attr, | 430 | &tune_attr_atime_quantum.attr, |
432 | &tune_attr_max_readahead.attr, | 431 | &tune_attr_max_readahead.attr, |
433 | &tune_attr_complain_secs.attr, | 432 | &tune_attr_complain_secs.attr, |
434 | &tune_attr_statfs_slow.attr, | 433 | &tune_attr_statfs_slow.attr, |
435 | &tune_attr_quota_simul_sync.attr, | 434 | &tune_attr_quota_simul_sync.attr, |
436 | &tune_attr_quota_cache_secs.attr, | 435 | &tune_attr_quota_cache_secs.attr, |
437 | &tune_attr_stall_secs.attr, | 436 | &tune_attr_stall_secs.attr, |
438 | &tune_attr_statfs_quantum.attr, | 437 | &tune_attr_statfs_quantum.attr, |
439 | &tune_attr_recoverd_secs.attr, | 438 | &tune_attr_recoverd_secs.attr, |
440 | &tune_attr_logd_secs.attr, | 439 | &tune_attr_logd_secs.attr, |
441 | &tune_attr_quotad_secs.attr, | 440 | &tune_attr_quotad_secs.attr, |
442 | &tune_attr_quota_scale.attr, | 441 | &tune_attr_quota_scale.attr, |
443 | &tune_attr_new_files_jdata.attr, | 442 | &tune_attr_new_files_jdata.attr, |
444 | &tune_attr_new_files_directio.attr, | ||
445 | NULL, | 443 | NULL, |
446 | }; | 444 | }; |
447 | 445 | ||
448 | static struct attribute_group lockstruct_group = { | 446 | static struct attribute_group lockstruct_group = { |
449 | .name = "lockstruct", | 447 | .name = "lockstruct", |
450 | .attrs = lockstruct_attrs, | 448 | .attrs = lockstruct_attrs, |
451 | }; | 449 | }; |
452 | 450 | ||
453 | static struct attribute_group counters_group = { | 451 | static struct attribute_group counters_group = { |
454 | .name = "counters", | 452 | .name = "counters", |
455 | .attrs = counters_attrs, | 453 | .attrs = counters_attrs, |
456 | }; | 454 | }; |
457 | 455 | ||
458 | static struct attribute_group args_group = { | 456 | static struct attribute_group args_group = { |
459 | .name = "args", | 457 | .name = "args", |
460 | .attrs = args_attrs, | 458 | .attrs = args_attrs, |
461 | }; | 459 | }; |
462 | 460 | ||
463 | static struct attribute_group tune_group = { | 461 | static struct attribute_group tune_group = { |
464 | .name = "tune", | 462 | .name = "tune", |
465 | .attrs = tune_attrs, | 463 | .attrs = tune_attrs, |
466 | }; | 464 | }; |
467 | 465 | ||
468 | int gfs2_sys_fs_add(struct gfs2_sbd *sdp) | 466 | int gfs2_sys_fs_add(struct gfs2_sbd *sdp) |
469 | { | 467 | { |
470 | int error; | 468 | int error; |
471 | 469 | ||
472 | sdp->sd_kobj.kset = gfs2_kset; | 470 | sdp->sd_kobj.kset = gfs2_kset; |
473 | error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL, | 471 | error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL, |
474 | "%s", sdp->sd_table_name); | 472 | "%s", sdp->sd_table_name); |
475 | if (error) | 473 | if (error) |
476 | goto fail; | 474 | goto fail; |
477 | 475 | ||
478 | error = sysfs_create_group(&sdp->sd_kobj, &lockstruct_group); | 476 | error = sysfs_create_group(&sdp->sd_kobj, &lockstruct_group); |
479 | if (error) | 477 | if (error) |
480 | goto fail_reg; | 478 | goto fail_reg; |
481 | 479 | ||
482 | error = sysfs_create_group(&sdp->sd_kobj, &counters_group); | 480 | error = sysfs_create_group(&sdp->sd_kobj, &counters_group); |
483 | if (error) | 481 | if (error) |
484 | goto fail_lockstruct; | 482 | goto fail_lockstruct; |
485 | 483 | ||
486 | error = sysfs_create_group(&sdp->sd_kobj, &args_group); | 484 | error = sysfs_create_group(&sdp->sd_kobj, &args_group); |
487 | if (error) | 485 | if (error) |
488 | goto fail_counters; | 486 | goto fail_counters; |
489 | 487 | ||
490 | error = sysfs_create_group(&sdp->sd_kobj, &tune_group); | 488 | error = sysfs_create_group(&sdp->sd_kobj, &tune_group); |
491 | if (error) | 489 | if (error) |
492 | goto fail_args; | 490 | goto fail_args; |
493 | 491 | ||
494 | kobject_uevent(&sdp->sd_kobj, KOBJ_ADD); | 492 | kobject_uevent(&sdp->sd_kobj, KOBJ_ADD); |
495 | return 0; | 493 | return 0; |
496 | 494 | ||
497 | fail_args: | 495 | fail_args: |
498 | sysfs_remove_group(&sdp->sd_kobj, &args_group); | 496 | sysfs_remove_group(&sdp->sd_kobj, &args_group); |
499 | fail_counters: | 497 | fail_counters: |
500 | sysfs_remove_group(&sdp->sd_kobj, &counters_group); | 498 | sysfs_remove_group(&sdp->sd_kobj, &counters_group); |
501 | fail_lockstruct: | 499 | fail_lockstruct: |
502 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); | 500 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); |
503 | fail_reg: | 501 | fail_reg: |
504 | kobject_put(&sdp->sd_kobj); | 502 | kobject_put(&sdp->sd_kobj); |
505 | fail: | 503 | fail: |
506 | fs_err(sdp, "error %d adding sysfs files", error); | 504 | fs_err(sdp, "error %d adding sysfs files", error); |
507 | return error; | 505 | return error; |
508 | } | 506 | } |
509 | 507 | ||
510 | void gfs2_sys_fs_del(struct gfs2_sbd *sdp) | 508 | void gfs2_sys_fs_del(struct gfs2_sbd *sdp) |
511 | { | 509 | { |
512 | sysfs_remove_group(&sdp->sd_kobj, &tune_group); | 510 | sysfs_remove_group(&sdp->sd_kobj, &tune_group); |
513 | sysfs_remove_group(&sdp->sd_kobj, &args_group); | 511 | sysfs_remove_group(&sdp->sd_kobj, &args_group); |
514 | sysfs_remove_group(&sdp->sd_kobj, &counters_group); | 512 | sysfs_remove_group(&sdp->sd_kobj, &counters_group); |
515 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); | 513 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); |
516 | kobject_put(&sdp->sd_kobj); | 514 | kobject_put(&sdp->sd_kobj); |
517 | } | 515 | } |
518 | 516 | ||
519 | int gfs2_sys_init(void) | 517 | int gfs2_sys_init(void) |
520 | { | 518 | { |
521 | gfs2_sys_margs = NULL; | 519 | gfs2_sys_margs = NULL; |
522 | spin_lock_init(&gfs2_sys_margs_lock); | 520 | spin_lock_init(&gfs2_sys_margs_lock); |
523 | gfs2_kset = kset_create_and_add("gfs2", NULL, fs_kobj); | 521 | gfs2_kset = kset_create_and_add("gfs2", NULL, fs_kobj); |
524 | if (!gfs2_kset) | 522 | if (!gfs2_kset) |
525 | return -ENOMEM; | 523 | return -ENOMEM; |
526 | return 0; | 524 | return 0; |
527 | } | 525 | } |
528 | 526 | ||
529 | void gfs2_sys_uninit(void) | 527 | void gfs2_sys_uninit(void) |
530 | { | 528 | { |
531 | kfree(gfs2_sys_margs); | 529 | kfree(gfs2_sys_margs); |
532 | kset_unregister(gfs2_kset); | 530 | kset_unregister(gfs2_kset); |
533 | } | 531 | } |
534 | 532 | ||
535 | 533 |