diff options
Diffstat (limited to 'fs')
56 files changed, 2224 insertions, 1190 deletions
diff --git a/fs/dlm/Kconfig b/fs/dlm/Kconfig index 81b2c6465eeb..b5654a284fef 100644 --- a/fs/dlm/Kconfig +++ b/fs/dlm/Kconfig | |||
@@ -1,14 +1,32 @@ | |||
1 | menu "Distributed Lock Manager" | 1 | menu "Distributed Lock Manager" |
2 | depends on INET && IP_SCTP && EXPERIMENTAL | 2 | depends on EXPERIMENTAL && INET |
3 | 3 | ||
4 | config DLM | 4 | config DLM |
5 | tristate "Distributed Lock Manager (DLM)" | 5 | tristate "Distributed Lock Manager (DLM)" |
6 | depends on IPV6 || IPV6=n | 6 | depends on IPV6 || IPV6=n |
7 | select CONFIGFS_FS | 7 | select CONFIGFS_FS |
8 | select IP_SCTP if DLM_SCTP | ||
8 | help | 9 | help |
9 | A general purpose distributed lock manager for kernel or userspace | 10 | A general purpose distributed lock manager for kernel or userspace |
10 | applications. | 11 | applications. |
11 | 12 | ||
13 | choice | ||
14 | prompt "Select DLM communications protocol" | ||
15 | depends on DLM | ||
16 | default DLM_TCP | ||
17 | help | ||
18 | The DLM Can use TCP or SCTP for it's network communications. | ||
19 | SCTP supports multi-homed operations whereas TCP doesn't. | ||
20 | However, SCTP seems to have stability problems at the moment. | ||
21 | |||
22 | config DLM_TCP | ||
23 | bool "TCP/IP" | ||
24 | |||
25 | config DLM_SCTP | ||
26 | bool "SCTP" | ||
27 | |||
28 | endchoice | ||
29 | |||
12 | config DLM_DEBUG | 30 | config DLM_DEBUG |
13 | bool "DLM debugging" | 31 | bool "DLM debugging" |
14 | depends on DLM | 32 | depends on DLM |
diff --git a/fs/dlm/Makefile b/fs/dlm/Makefile index 1832e0297f7d..65388944eba0 100644 --- a/fs/dlm/Makefile +++ b/fs/dlm/Makefile | |||
@@ -4,7 +4,6 @@ dlm-y := ast.o \ | |||
4 | dir.o \ | 4 | dir.o \ |
5 | lock.o \ | 5 | lock.o \ |
6 | lockspace.o \ | 6 | lockspace.o \ |
7 | lowcomms.o \ | ||
8 | main.o \ | 7 | main.o \ |
9 | member.o \ | 8 | member.o \ |
10 | memory.o \ | 9 | memory.o \ |
@@ -17,3 +16,6 @@ dlm-y := ast.o \ | |||
17 | util.o | 16 | util.o |
18 | dlm-$(CONFIG_DLM_DEBUG) += debug_fs.o | 17 | dlm-$(CONFIG_DLM_DEBUG) += debug_fs.o |
19 | 18 | ||
19 | dlm-$(CONFIG_DLM_TCP) += lowcomms-tcp.o | ||
20 | |||
21 | dlm-$(CONFIG_DLM_SCTP) += lowcomms-sctp.o \ No newline at end of file | ||
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 1e5cd67e1b7a..1ee8195e6fc0 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h | |||
@@ -471,6 +471,7 @@ struct dlm_ls { | |||
471 | char *ls_recover_buf; | 471 | char *ls_recover_buf; |
472 | int ls_recover_nodeid; /* for debugging */ | 472 | int ls_recover_nodeid; /* for debugging */ |
473 | uint64_t ls_rcom_seq; | 473 | uint64_t ls_rcom_seq; |
474 | spinlock_t ls_rcom_spin; | ||
474 | struct list_head ls_recover_list; | 475 | struct list_head ls_recover_list; |
475 | spinlock_t ls_recover_list_lock; | 476 | spinlock_t ls_recover_list_lock; |
476 | int ls_recover_list_count; | 477 | int ls_recover_list_count; |
@@ -488,7 +489,8 @@ struct dlm_ls { | |||
488 | #define LSFL_RUNNING 1 | 489 | #define LSFL_RUNNING 1 |
489 | #define LSFL_RECOVERY_STOP 2 | 490 | #define LSFL_RECOVERY_STOP 2 |
490 | #define LSFL_RCOM_READY 3 | 491 | #define LSFL_RCOM_READY 3 |
491 | #define LSFL_UEVENT_WAIT 4 | 492 | #define LSFL_RCOM_WAIT 4 |
493 | #define LSFL_UEVENT_WAIT 5 | ||
492 | 494 | ||
493 | /* much of this is just saving user space pointers associated with the | 495 | /* much of this is just saving user space pointers associated with the |
494 | lock that we pass back to the user lib with an ast */ | 496 | lock that we pass back to the user lib with an ast */ |
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 3f2befa4797b..30878defaeb6 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
@@ -2372,6 +2372,7 @@ static int send_lookup_reply(struct dlm_ls *ls, struct dlm_message *ms_in, | |||
2372 | static void receive_flags(struct dlm_lkb *lkb, struct dlm_message *ms) | 2372 | static void receive_flags(struct dlm_lkb *lkb, struct dlm_message *ms) |
2373 | { | 2373 | { |
2374 | lkb->lkb_exflags = ms->m_exflags; | 2374 | lkb->lkb_exflags = ms->m_exflags; |
2375 | lkb->lkb_sbflags = ms->m_sbflags; | ||
2375 | lkb->lkb_flags = (lkb->lkb_flags & 0xFFFF0000) | | 2376 | lkb->lkb_flags = (lkb->lkb_flags & 0xFFFF0000) | |
2376 | (ms->m_flags & 0x0000FFFF); | 2377 | (ms->m_flags & 0x0000FFFF); |
2377 | } | 2378 | } |
@@ -3028,10 +3029,17 @@ int dlm_receive_message(struct dlm_header *hd, int nodeid, int recovery) | |||
3028 | 3029 | ||
3029 | while (1) { | 3030 | while (1) { |
3030 | if (dlm_locking_stopped(ls)) { | 3031 | if (dlm_locking_stopped(ls)) { |
3031 | if (!recovery) | 3032 | if (recovery) { |
3032 | dlm_add_requestqueue(ls, nodeid, hd); | 3033 | error = -EINTR; |
3033 | error = -EINTR; | 3034 | goto out; |
3034 | goto out; | 3035 | } |
3036 | error = dlm_add_requestqueue(ls, nodeid, hd); | ||
3037 | if (error == -EAGAIN) | ||
3038 | continue; | ||
3039 | else { | ||
3040 | error = -EINTR; | ||
3041 | goto out; | ||
3042 | } | ||
3035 | } | 3043 | } |
3036 | 3044 | ||
3037 | if (lock_recovery_try(ls)) | 3045 | if (lock_recovery_try(ls)) |
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index f8842ca443c2..59012b089e8d 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "memory.h" | 22 | #include "memory.h" |
23 | #include "lock.h" | 23 | #include "lock.h" |
24 | #include "recover.h" | 24 | #include "recover.h" |
25 | #include "requestqueue.h" | ||
25 | 26 | ||
26 | #ifdef CONFIG_DLM_DEBUG | 27 | #ifdef CONFIG_DLM_DEBUG |
27 | int dlm_create_debug_file(struct dlm_ls *ls); | 28 | int dlm_create_debug_file(struct dlm_ls *ls); |
@@ -478,6 +479,8 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
478 | ls->ls_recoverd_task = NULL; | 479 | ls->ls_recoverd_task = NULL; |
479 | mutex_init(&ls->ls_recoverd_active); | 480 | mutex_init(&ls->ls_recoverd_active); |
480 | spin_lock_init(&ls->ls_recover_lock); | 481 | spin_lock_init(&ls->ls_recover_lock); |
482 | spin_lock_init(&ls->ls_rcom_spin); | ||
483 | get_random_bytes(&ls->ls_rcom_seq, sizeof(uint64_t)); | ||
481 | ls->ls_recover_status = 0; | 484 | ls->ls_recover_status = 0; |
482 | ls->ls_recover_seq = 0; | 485 | ls->ls_recover_seq = 0; |
483 | ls->ls_recover_args = NULL; | 486 | ls->ls_recover_args = NULL; |
@@ -684,6 +687,7 @@ static int release_lockspace(struct dlm_ls *ls, int force) | |||
684 | * Free structures on any other lists | 687 | * Free structures on any other lists |
685 | */ | 688 | */ |
686 | 689 | ||
690 | dlm_purge_requestqueue(ls); | ||
687 | kfree(ls->ls_recover_args); | 691 | kfree(ls->ls_recover_args); |
688 | dlm_clear_free_entries(ls); | 692 | dlm_clear_free_entries(ls); |
689 | dlm_clear_members(ls); | 693 | dlm_clear_members(ls); |
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms-sctp.c index 6da6b14d5a61..fe158d7a9285 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms-sctp.c | |||
@@ -2,7 +2,7 @@ | |||
2 | ******************************************************************************* | 2 | ******************************************************************************* |
3 | ** | 3 | ** |
4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
5 | ** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. | 5 | ** Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. |
6 | ** | 6 | ** |
7 | ** This copyrighted material is made available to anyone wishing to use, | 7 | ** This copyrighted material is made available to anyone wishing to use, |
8 | ** modify, copy, or redistribute it subject to the terms and conditions | 8 | ** modify, copy, or redistribute it subject to the terms and conditions |
@@ -75,13 +75,13 @@ struct nodeinfo { | |||
75 | }; | 75 | }; |
76 | 76 | ||
77 | static DEFINE_IDR(nodeinfo_idr); | 77 | static DEFINE_IDR(nodeinfo_idr); |
78 | static struct rw_semaphore nodeinfo_lock; | 78 | static DECLARE_RWSEM(nodeinfo_lock); |
79 | static int max_nodeid; | 79 | static int max_nodeid; |
80 | 80 | ||
81 | struct cbuf { | 81 | struct cbuf { |
82 | unsigned base; | 82 | unsigned int base; |
83 | unsigned len; | 83 | unsigned int len; |
84 | unsigned mask; | 84 | unsigned int mask; |
85 | }; | 85 | }; |
86 | 86 | ||
87 | /* Just the one of these, now. But this struct keeps | 87 | /* Just the one of these, now. But this struct keeps |
@@ -90,9 +90,9 @@ struct cbuf { | |||
90 | #define CF_READ_PENDING 1 | 90 | #define CF_READ_PENDING 1 |
91 | 91 | ||
92 | struct connection { | 92 | struct connection { |
93 | struct socket *sock; | 93 | struct socket *sock; |
94 | unsigned long flags; | 94 | unsigned long flags; |
95 | struct page *rx_page; | 95 | struct page *rx_page; |
96 | atomic_t waiting_requests; | 96 | atomic_t waiting_requests; |
97 | struct cbuf cb; | 97 | struct cbuf cb; |
98 | int eagain_flag; | 98 | int eagain_flag; |
@@ -102,36 +102,40 @@ struct connection { | |||
102 | 102 | ||
103 | struct writequeue_entry { | 103 | struct writequeue_entry { |
104 | struct list_head list; | 104 | struct list_head list; |
105 | struct page *page; | 105 | struct page *page; |
106 | int offset; | 106 | int offset; |
107 | int len; | 107 | int len; |
108 | int end; | 108 | int end; |
109 | int users; | 109 | int users; |
110 | struct nodeinfo *ni; | 110 | struct nodeinfo *ni; |
111 | }; | 111 | }; |
112 | 112 | ||
113 | #define CBUF_ADD(cb, n) do { (cb)->len += n; } while(0) | 113 | static void cbuf_add(struct cbuf *cb, int n) |
114 | #define CBUF_EMPTY(cb) ((cb)->len == 0) | 114 | { |
115 | #define CBUF_MAY_ADD(cb, n) (((cb)->len + (n)) < ((cb)->mask + 1)) | 115 | cb->len += n; |
116 | #define CBUF_DATA(cb) (((cb)->base + (cb)->len) & (cb)->mask) | 116 | } |
117 | 117 | ||
118 | #define CBUF_INIT(cb, size) \ | 118 | static int cbuf_data(struct cbuf *cb) |
119 | do { \ | 119 | { |
120 | (cb)->base = (cb)->len = 0; \ | 120 | return ((cb->base + cb->len) & cb->mask); |
121 | (cb)->mask = ((size)-1); \ | 121 | } |
122 | } while(0) | ||
123 | 122 | ||
124 | #define CBUF_EAT(cb, n) \ | 123 | static void cbuf_init(struct cbuf *cb, int size) |
125 | do { \ | 124 | { |
126 | (cb)->len -= (n); \ | 125 | cb->base = cb->len = 0; |
127 | (cb)->base += (n); \ | 126 | cb->mask = size-1; |
128 | (cb)->base &= (cb)->mask; \ | 127 | } |
129 | } while(0) | ||
130 | 128 | ||
129 | static void cbuf_eat(struct cbuf *cb, int n) | ||
130 | { | ||
131 | cb->len -= n; | ||
132 | cb->base += n; | ||
133 | cb->base &= cb->mask; | ||
134 | } | ||
131 | 135 | ||
132 | /* List of nodes which have writes pending */ | 136 | /* List of nodes which have writes pending */ |
133 | static struct list_head write_nodes; | 137 | static LIST_HEAD(write_nodes); |
134 | static spinlock_t write_nodes_lock; | 138 | static DEFINE_SPINLOCK(write_nodes_lock); |
135 | 139 | ||
136 | /* Maximum number of incoming messages to process before | 140 | /* Maximum number of incoming messages to process before |
137 | * doing a schedule() | 141 | * doing a schedule() |
@@ -141,8 +145,7 @@ static spinlock_t write_nodes_lock; | |||
141 | /* Manage daemons */ | 145 | /* Manage daemons */ |
142 | static struct task_struct *recv_task; | 146 | static struct task_struct *recv_task; |
143 | static struct task_struct *send_task; | 147 | static struct task_struct *send_task; |
144 | static wait_queue_head_t lowcomms_recv_wait; | 148 | static DECLARE_WAIT_QUEUE_HEAD(lowcomms_recv_wait); |
145 | static atomic_t accepting; | ||
146 | 149 | ||
147 | /* The SCTP connection */ | 150 | /* The SCTP connection */ |
148 | static struct connection sctp_con; | 151 | static struct connection sctp_con; |
@@ -161,11 +164,11 @@ static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr) | |||
161 | return error; | 164 | return error; |
162 | 165 | ||
163 | if (dlm_local_addr[0]->ss_family == AF_INET) { | 166 | if (dlm_local_addr[0]->ss_family == AF_INET) { |
164 | struct sockaddr_in *in4 = (struct sockaddr_in *) &addr; | 167 | struct sockaddr_in *in4 = (struct sockaddr_in *) &addr; |
165 | struct sockaddr_in *ret4 = (struct sockaddr_in *) retaddr; | 168 | struct sockaddr_in *ret4 = (struct sockaddr_in *) retaddr; |
166 | ret4->sin_addr.s_addr = in4->sin_addr.s_addr; | 169 | ret4->sin_addr.s_addr = in4->sin_addr.s_addr; |
167 | } else { | 170 | } else { |
168 | struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &addr; | 171 | struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &addr; |
169 | struct sockaddr_in6 *ret6 = (struct sockaddr_in6 *) retaddr; | 172 | struct sockaddr_in6 *ret6 = (struct sockaddr_in6 *) retaddr; |
170 | memcpy(&ret6->sin6_addr, &in6->sin6_addr, | 173 | memcpy(&ret6->sin6_addr, &in6->sin6_addr, |
171 | sizeof(in6->sin6_addr)); | 174 | sizeof(in6->sin6_addr)); |
@@ -174,6 +177,8 @@ static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr) | |||
174 | return 0; | 177 | return 0; |
175 | } | 178 | } |
176 | 179 | ||
180 | /* If alloc is 0 here we will not attempt to allocate a new | ||
181 | nodeinfo struct */ | ||
177 | static struct nodeinfo *nodeid2nodeinfo(int nodeid, gfp_t alloc) | 182 | static struct nodeinfo *nodeid2nodeinfo(int nodeid, gfp_t alloc) |
178 | { | 183 | { |
179 | struct nodeinfo *ni; | 184 | struct nodeinfo *ni; |
@@ -184,44 +189,45 @@ static struct nodeinfo *nodeid2nodeinfo(int nodeid, gfp_t alloc) | |||
184 | ni = idr_find(&nodeinfo_idr, nodeid); | 189 | ni = idr_find(&nodeinfo_idr, nodeid); |
185 | up_read(&nodeinfo_lock); | 190 | up_read(&nodeinfo_lock); |
186 | 191 | ||
187 | if (!ni && alloc) { | 192 | if (ni || !alloc) |
188 | down_write(&nodeinfo_lock); | 193 | return ni; |
189 | 194 | ||
190 | ni = idr_find(&nodeinfo_idr, nodeid); | 195 | down_write(&nodeinfo_lock); |
191 | if (ni) | ||
192 | goto out_up; | ||
193 | 196 | ||
194 | r = idr_pre_get(&nodeinfo_idr, alloc); | 197 | ni = idr_find(&nodeinfo_idr, nodeid); |
195 | if (!r) | 198 | if (ni) |
196 | goto out_up; | 199 | goto out_up; |
197 | 200 | ||
198 | ni = kmalloc(sizeof(struct nodeinfo), alloc); | 201 | r = idr_pre_get(&nodeinfo_idr, alloc); |
199 | if (!ni) | 202 | if (!r) |
200 | goto out_up; | 203 | goto out_up; |
201 | 204 | ||
202 | r = idr_get_new_above(&nodeinfo_idr, ni, nodeid, &n); | 205 | ni = kmalloc(sizeof(struct nodeinfo), alloc); |
203 | if (r) { | 206 | if (!ni) |
204 | kfree(ni); | 207 | goto out_up; |
205 | ni = NULL; | 208 | |
206 | goto out_up; | 209 | r = idr_get_new_above(&nodeinfo_idr, ni, nodeid, &n); |
207 | } | 210 | if (r) { |
208 | if (n != nodeid) { | 211 | kfree(ni); |
209 | idr_remove(&nodeinfo_idr, n); | 212 | ni = NULL; |
210 | kfree(ni); | 213 | goto out_up; |
211 | ni = NULL; | ||
212 | goto out_up; | ||
213 | } | ||
214 | memset(ni, 0, sizeof(struct nodeinfo)); | ||
215 | spin_lock_init(&ni->lock); | ||
216 | INIT_LIST_HEAD(&ni->writequeue); | ||
217 | spin_lock_init(&ni->writequeue_lock); | ||
218 | ni->nodeid = nodeid; | ||
219 | |||
220 | if (nodeid > max_nodeid) | ||
221 | max_nodeid = nodeid; | ||
222 | out_up: | ||
223 | up_write(&nodeinfo_lock); | ||
224 | } | 214 | } |
215 | if (n != nodeid) { | ||
216 | idr_remove(&nodeinfo_idr, n); | ||
217 | kfree(ni); | ||
218 | ni = NULL; | ||
219 | goto out_up; | ||
220 | } | ||
221 | memset(ni, 0, sizeof(struct nodeinfo)); | ||
222 | spin_lock_init(&ni->lock); | ||
223 | INIT_LIST_HEAD(&ni->writequeue); | ||
224 | spin_lock_init(&ni->writequeue_lock); | ||
225 | ni->nodeid = nodeid; | ||
226 | |||
227 | if (nodeid > max_nodeid) | ||
228 | max_nodeid = nodeid; | ||
229 | out_up: | ||
230 | up_write(&nodeinfo_lock); | ||
225 | 231 | ||
226 | return ni; | 232 | return ni; |
227 | } | 233 | } |
@@ -279,13 +285,13 @@ static void make_sockaddr(struct sockaddr_storage *saddr, uint16_t port, | |||
279 | in4_addr->sin_port = cpu_to_be16(port); | 285 | in4_addr->sin_port = cpu_to_be16(port); |
280 | memset(&in4_addr->sin_zero, 0, sizeof(in4_addr->sin_zero)); | 286 | memset(&in4_addr->sin_zero, 0, sizeof(in4_addr->sin_zero)); |
281 | memset(in4_addr+1, 0, sizeof(struct sockaddr_storage) - | 287 | memset(in4_addr+1, 0, sizeof(struct sockaddr_storage) - |
282 | sizeof(struct sockaddr_in)); | 288 | sizeof(struct sockaddr_in)); |
283 | *addr_len = sizeof(struct sockaddr_in); | 289 | *addr_len = sizeof(struct sockaddr_in); |
284 | } else { | 290 | } else { |
285 | struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)saddr; | 291 | struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)saddr; |
286 | in6_addr->sin6_port = cpu_to_be16(port); | 292 | in6_addr->sin6_port = cpu_to_be16(port); |
287 | memset(in6_addr+1, 0, sizeof(struct sockaddr_storage) - | 293 | memset(in6_addr+1, 0, sizeof(struct sockaddr_storage) - |
288 | sizeof(struct sockaddr_in6)); | 294 | sizeof(struct sockaddr_in6)); |
289 | *addr_len = sizeof(struct sockaddr_in6); | 295 | *addr_len = sizeof(struct sockaddr_in6); |
290 | } | 296 | } |
291 | } | 297 | } |
@@ -324,7 +330,7 @@ static void send_shutdown(sctp_assoc_t associd) | |||
324 | cmsg->cmsg_type = SCTP_SNDRCV; | 330 | cmsg->cmsg_type = SCTP_SNDRCV; |
325 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); | 331 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); |
326 | outmessage.msg_controllen = cmsg->cmsg_len; | 332 | outmessage.msg_controllen = cmsg->cmsg_len; |
327 | sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); | 333 | sinfo = CMSG_DATA(cmsg); |
328 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); | 334 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); |
329 | 335 | ||
330 | sinfo->sinfo_flags |= MSG_EOF; | 336 | sinfo->sinfo_flags |= MSG_EOF; |
@@ -387,7 +393,7 @@ static void process_sctp_notification(struct msghdr *msg, char *buf) | |||
387 | 393 | ||
388 | if ((int)sn->sn_assoc_change.sac_assoc_id <= 0) { | 394 | if ((int)sn->sn_assoc_change.sac_assoc_id <= 0) { |
389 | log_print("COMM_UP for invalid assoc ID %d", | 395 | log_print("COMM_UP for invalid assoc ID %d", |
390 | (int)sn->sn_assoc_change.sac_assoc_id); | 396 | (int)sn->sn_assoc_change.sac_assoc_id); |
391 | init_failed(); | 397 | init_failed(); |
392 | return; | 398 | return; |
393 | } | 399 | } |
@@ -398,15 +404,18 @@ static void process_sctp_notification(struct msghdr *msg, char *buf) | |||
398 | fs = get_fs(); | 404 | fs = get_fs(); |
399 | set_fs(get_ds()); | 405 | set_fs(get_ds()); |
400 | ret = sctp_con.sock->ops->getsockopt(sctp_con.sock, | 406 | ret = sctp_con.sock->ops->getsockopt(sctp_con.sock, |
401 | IPPROTO_SCTP, SCTP_PRIMARY_ADDR, | 407 | IPPROTO_SCTP, |
402 | (char*)&prim, &prim_len); | 408 | SCTP_PRIMARY_ADDR, |
409 | (char*)&prim, | ||
410 | &prim_len); | ||
403 | set_fs(fs); | 411 | set_fs(fs); |
404 | if (ret < 0) { | 412 | if (ret < 0) { |
405 | struct nodeinfo *ni; | 413 | struct nodeinfo *ni; |
406 | 414 | ||
407 | log_print("getsockopt/sctp_primary_addr on " | 415 | log_print("getsockopt/sctp_primary_addr on " |
408 | "new assoc %d failed : %d", | 416 | "new assoc %d failed : %d", |
409 | (int)sn->sn_assoc_change.sac_assoc_id, ret); | 417 | (int)sn->sn_assoc_change.sac_assoc_id, |
418 | ret); | ||
410 | 419 | ||
411 | /* Retry INIT later */ | 420 | /* Retry INIT later */ |
412 | ni = assoc2nodeinfo(sn->sn_assoc_change.sac_assoc_id); | 421 | ni = assoc2nodeinfo(sn->sn_assoc_change.sac_assoc_id); |
@@ -426,12 +435,10 @@ static void process_sctp_notification(struct msghdr *msg, char *buf) | |||
426 | return; | 435 | return; |
427 | 436 | ||
428 | /* Save the assoc ID */ | 437 | /* Save the assoc ID */ |
429 | spin_lock(&ni->lock); | ||
430 | ni->assoc_id = sn->sn_assoc_change.sac_assoc_id; | 438 | ni->assoc_id = sn->sn_assoc_change.sac_assoc_id; |
431 | spin_unlock(&ni->lock); | ||
432 | 439 | ||
433 | log_print("got new/restarted association %d nodeid %d", | 440 | log_print("got new/restarted association %d nodeid %d", |
434 | (int)sn->sn_assoc_change.sac_assoc_id, nodeid); | 441 | (int)sn->sn_assoc_change.sac_assoc_id, nodeid); |
435 | 442 | ||
436 | /* Send any pending writes */ | 443 | /* Send any pending writes */ |
437 | clear_bit(NI_INIT_PENDING, &ni->flags); | 444 | clear_bit(NI_INIT_PENDING, &ni->flags); |
@@ -507,13 +514,12 @@ static int receive_from_sock(void) | |||
507 | sctp_con.rx_page = alloc_page(GFP_ATOMIC); | 514 | sctp_con.rx_page = alloc_page(GFP_ATOMIC); |
508 | if (sctp_con.rx_page == NULL) | 515 | if (sctp_con.rx_page == NULL) |
509 | goto out_resched; | 516 | goto out_resched; |
510 | CBUF_INIT(&sctp_con.cb, PAGE_CACHE_SIZE); | 517 | cbuf_init(&sctp_con.cb, PAGE_CACHE_SIZE); |
511 | } | 518 | } |
512 | 519 | ||
513 | memset(&incmsg, 0, sizeof(incmsg)); | 520 | memset(&incmsg, 0, sizeof(incmsg)); |
514 | memset(&msgname, 0, sizeof(msgname)); | 521 | memset(&msgname, 0, sizeof(msgname)); |
515 | 522 | ||
516 | memset(incmsg, 0, sizeof(incmsg)); | ||
517 | msg.msg_name = &msgname; | 523 | msg.msg_name = &msgname; |
518 | msg.msg_namelen = sizeof(msgname); | 524 | msg.msg_namelen = sizeof(msgname); |
519 | msg.msg_flags = 0; | 525 | msg.msg_flags = 0; |
@@ -532,17 +538,17 @@ static int receive_from_sock(void) | |||
532 | * iov[0] is the bit of the circular buffer between the current end | 538 | * iov[0] is the bit of the circular buffer between the current end |
533 | * point (cb.base + cb.len) and the end of the buffer. | 539 | * point (cb.base + cb.len) and the end of the buffer. |
534 | */ | 540 | */ |
535 | iov[0].iov_len = sctp_con.cb.base - CBUF_DATA(&sctp_con.cb); | 541 | iov[0].iov_len = sctp_con.cb.base - cbuf_data(&sctp_con.cb); |
536 | iov[0].iov_base = page_address(sctp_con.rx_page) + | 542 | iov[0].iov_base = page_address(sctp_con.rx_page) + |
537 | CBUF_DATA(&sctp_con.cb); | 543 | cbuf_data(&sctp_con.cb); |
538 | iov[1].iov_len = 0; | 544 | iov[1].iov_len = 0; |
539 | 545 | ||
540 | /* | 546 | /* |
541 | * iov[1] is the bit of the circular buffer between the start of the | 547 | * iov[1] is the bit of the circular buffer between the start of the |
542 | * buffer and the start of the currently used section (cb.base) | 548 | * buffer and the start of the currently used section (cb.base) |
543 | */ | 549 | */ |
544 | if (CBUF_DATA(&sctp_con.cb) >= sctp_con.cb.base) { | 550 | if (cbuf_data(&sctp_con.cb) >= sctp_con.cb.base) { |
545 | iov[0].iov_len = PAGE_CACHE_SIZE - CBUF_DATA(&sctp_con.cb); | 551 | iov[0].iov_len = PAGE_CACHE_SIZE - cbuf_data(&sctp_con.cb); |
546 | iov[1].iov_len = sctp_con.cb.base; | 552 | iov[1].iov_len = sctp_con.cb.base; |
547 | iov[1].iov_base = page_address(sctp_con.rx_page); | 553 | iov[1].iov_base = page_address(sctp_con.rx_page); |
548 | msg.msg_iovlen = 2; | 554 | msg.msg_iovlen = 2; |
@@ -557,7 +563,7 @@ static int receive_from_sock(void) | |||
557 | msg.msg_control = incmsg; | 563 | msg.msg_control = incmsg; |
558 | msg.msg_controllen = sizeof(incmsg); | 564 | msg.msg_controllen = sizeof(incmsg); |
559 | cmsg = CMSG_FIRSTHDR(&msg); | 565 | cmsg = CMSG_FIRSTHDR(&msg); |
560 | sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); | 566 | sinfo = CMSG_DATA(cmsg); |
561 | 567 | ||
562 | if (msg.msg_flags & MSG_NOTIFICATION) { | 568 | if (msg.msg_flags & MSG_NOTIFICATION) { |
563 | process_sctp_notification(&msg, page_address(sctp_con.rx_page)); | 569 | process_sctp_notification(&msg, page_address(sctp_con.rx_page)); |
@@ -583,29 +589,29 @@ static int receive_from_sock(void) | |||
583 | if (r == 1) | 589 | if (r == 1) |
584 | return 0; | 590 | return 0; |
585 | 591 | ||
586 | CBUF_ADD(&sctp_con.cb, ret); | 592 | cbuf_add(&sctp_con.cb, ret); |
587 | ret = dlm_process_incoming_buffer(cpu_to_le32(sinfo->sinfo_ppid), | 593 | ret = dlm_process_incoming_buffer(cpu_to_le32(sinfo->sinfo_ppid), |
588 | page_address(sctp_con.rx_page), | 594 | page_address(sctp_con.rx_page), |
589 | sctp_con.cb.base, sctp_con.cb.len, | 595 | sctp_con.cb.base, sctp_con.cb.len, |
590 | PAGE_CACHE_SIZE); | 596 | PAGE_CACHE_SIZE); |
591 | if (ret < 0) | 597 | if (ret < 0) |
592 | goto out_close; | 598 | goto out_close; |
593 | CBUF_EAT(&sctp_con.cb, ret); | 599 | cbuf_eat(&sctp_con.cb, ret); |
594 | 600 | ||
595 | out: | 601 | out: |
596 | ret = 0; | 602 | ret = 0; |
597 | goto out_ret; | 603 | goto out_ret; |
598 | 604 | ||
599 | out_resched: | 605 | out_resched: |
600 | lowcomms_data_ready(sctp_con.sock->sk, 0); | 606 | lowcomms_data_ready(sctp_con.sock->sk, 0); |
601 | ret = 0; | 607 | ret = 0; |
602 | schedule(); | 608 | cond_resched(); |
603 | goto out_ret; | 609 | goto out_ret; |
604 | 610 | ||
605 | out_close: | 611 | out_close: |
606 | if (ret != -EAGAIN) | 612 | if (ret != -EAGAIN) |
607 | log_print("error reading from sctp socket: %d", ret); | 613 | log_print("error reading from sctp socket: %d", ret); |
608 | out_ret: | 614 | out_ret: |
609 | return ret; | 615 | return ret; |
610 | } | 616 | } |
611 | 617 | ||
@@ -619,10 +625,12 @@ static int add_bind_addr(struct sockaddr_storage *addr, int addr_len, int num) | |||
619 | set_fs(get_ds()); | 625 | set_fs(get_ds()); |
620 | if (num == 1) | 626 | if (num == 1) |
621 | result = sctp_con.sock->ops->bind(sctp_con.sock, | 627 | result = sctp_con.sock->ops->bind(sctp_con.sock, |
622 | (struct sockaddr *) addr, addr_len); | 628 | (struct sockaddr *) addr, |
629 | addr_len); | ||
623 | else | 630 | else |
624 | result = sctp_con.sock->ops->setsockopt(sctp_con.sock, SOL_SCTP, | 631 | result = sctp_con.sock->ops->setsockopt(sctp_con.sock, SOL_SCTP, |
625 | SCTP_SOCKOPT_BINDX_ADD, (char *)addr, addr_len); | 632 | SCTP_SOCKOPT_BINDX_ADD, |
633 | (char *)addr, addr_len); | ||
626 | set_fs(fs); | 634 | set_fs(fs); |
627 | 635 | ||
628 | if (result < 0) | 636 | if (result < 0) |
@@ -719,10 +727,10 @@ static int init_sock(void) | |||
719 | 727 | ||
720 | return 0; | 728 | return 0; |
721 | 729 | ||
722 | create_delsock: | 730 | create_delsock: |
723 | sock_release(sock); | 731 | sock_release(sock); |
724 | sctp_con.sock = NULL; | 732 | sctp_con.sock = NULL; |
725 | out: | 733 | out: |
726 | return result; | 734 | return result; |
727 | } | 735 | } |
728 | 736 | ||
@@ -756,16 +764,13 @@ void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc) | |||
756 | int users = 0; | 764 | int users = 0; |
757 | struct nodeinfo *ni; | 765 | struct nodeinfo *ni; |
758 | 766 | ||
759 | if (!atomic_read(&accepting)) | ||
760 | return NULL; | ||
761 | |||
762 | ni = nodeid2nodeinfo(nodeid, allocation); | 767 | ni = nodeid2nodeinfo(nodeid, allocation); |
763 | if (!ni) | 768 | if (!ni) |
764 | return NULL; | 769 | return NULL; |
765 | 770 | ||
766 | spin_lock(&ni->writequeue_lock); | 771 | spin_lock(&ni->writequeue_lock); |
767 | e = list_entry(ni->writequeue.prev, struct writequeue_entry, list); | 772 | e = list_entry(ni->writequeue.prev, struct writequeue_entry, list); |
768 | if (((struct list_head *) e == &ni->writequeue) || | 773 | if ((&e->list == &ni->writequeue) || |
769 | (PAGE_CACHE_SIZE - e->end < len)) { | 774 | (PAGE_CACHE_SIZE - e->end < len)) { |
770 | e = NULL; | 775 | e = NULL; |
771 | } else { | 776 | } else { |
@@ -776,7 +781,7 @@ void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc) | |||
776 | spin_unlock(&ni->writequeue_lock); | 781 | spin_unlock(&ni->writequeue_lock); |
777 | 782 | ||
778 | if (e) { | 783 | if (e) { |
779 | got_one: | 784 | got_one: |
780 | if (users == 0) | 785 | if (users == 0) |
781 | kmap(e->page); | 786 | kmap(e->page); |
782 | *ppc = page_address(e->page) + offset; | 787 | *ppc = page_address(e->page) + offset; |
@@ -803,9 +808,6 @@ void dlm_lowcomms_commit_buffer(void *arg) | |||
803 | int users; | 808 | int users; |
804 | struct nodeinfo *ni = e->ni; | 809 | struct nodeinfo *ni = e->ni; |
805 | 810 | ||
806 | if (!atomic_read(&accepting)) | ||
807 | return; | ||
808 | |||
809 | spin_lock(&ni->writequeue_lock); | 811 | spin_lock(&ni->writequeue_lock); |
810 | users = --e->users; | 812 | users = --e->users; |
811 | if (users) | 813 | if (users) |
@@ -822,7 +824,7 @@ void dlm_lowcomms_commit_buffer(void *arg) | |||
822 | } | 824 | } |
823 | return; | 825 | return; |
824 | 826 | ||
825 | out: | 827 | out: |
826 | spin_unlock(&ni->writequeue_lock); | 828 | spin_unlock(&ni->writequeue_lock); |
827 | return; | 829 | return; |
828 | } | 830 | } |
@@ -878,7 +880,7 @@ static void initiate_association(int nodeid) | |||
878 | cmsg->cmsg_level = IPPROTO_SCTP; | 880 | cmsg->cmsg_level = IPPROTO_SCTP; |
879 | cmsg->cmsg_type = SCTP_SNDRCV; | 881 | cmsg->cmsg_type = SCTP_SNDRCV; |
880 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); | 882 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); |
881 | sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); | 883 | sinfo = CMSG_DATA(cmsg); |
882 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); | 884 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); |
883 | sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid); | 885 | sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid); |
884 | 886 | ||
@@ -892,7 +894,7 @@ static void initiate_association(int nodeid) | |||
892 | } | 894 | } |
893 | 895 | ||
894 | /* Send a message */ | 896 | /* Send a message */ |
895 | static int send_to_sock(struct nodeinfo *ni) | 897 | static void send_to_sock(struct nodeinfo *ni) |
896 | { | 898 | { |
897 | int ret = 0; | 899 | int ret = 0; |
898 | struct writequeue_entry *e; | 900 | struct writequeue_entry *e; |
@@ -903,13 +905,13 @@ static int send_to_sock(struct nodeinfo *ni) | |||
903 | struct sctp_sndrcvinfo *sinfo; | 905 | struct sctp_sndrcvinfo *sinfo; |
904 | struct kvec iov; | 906 | struct kvec iov; |
905 | 907 | ||
906 | /* See if we need to init an association before we start | 908 | /* See if we need to init an association before we start |
907 | sending precious messages */ | 909 | sending precious messages */ |
908 | spin_lock(&ni->lock); | 910 | spin_lock(&ni->lock); |
909 | if (!ni->assoc_id && !test_and_set_bit(NI_INIT_PENDING, &ni->flags)) { | 911 | if (!ni->assoc_id && !test_and_set_bit(NI_INIT_PENDING, &ni->flags)) { |
910 | spin_unlock(&ni->lock); | 912 | spin_unlock(&ni->lock); |
911 | initiate_association(ni->nodeid); | 913 | initiate_association(ni->nodeid); |
912 | return 0; | 914 | return; |
913 | } | 915 | } |
914 | spin_unlock(&ni->lock); | 916 | spin_unlock(&ni->lock); |
915 | 917 | ||
@@ -923,7 +925,7 @@ static int send_to_sock(struct nodeinfo *ni) | |||
923 | cmsg->cmsg_level = IPPROTO_SCTP; | 925 | cmsg->cmsg_level = IPPROTO_SCTP; |
924 | cmsg->cmsg_type = SCTP_SNDRCV; | 926 | cmsg->cmsg_type = SCTP_SNDRCV; |
925 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); | 927 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); |
926 | sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); | 928 | sinfo = CMSG_DATA(cmsg); |
927 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); | 929 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); |
928 | sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid); | 930 | sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid); |
929 | sinfo->sinfo_assoc_id = ni->assoc_id; | 931 | sinfo->sinfo_assoc_id = ni->assoc_id; |
@@ -955,7 +957,7 @@ static int send_to_sock(struct nodeinfo *ni) | |||
955 | goto send_error; | 957 | goto send_error; |
956 | } else { | 958 | } else { |
957 | /* Don't starve people filling buffers */ | 959 | /* Don't starve people filling buffers */ |
958 | schedule(); | 960 | cond_resched(); |
959 | } | 961 | } |
960 | 962 | ||
961 | spin_lock(&ni->writequeue_lock); | 963 | spin_lock(&ni->writequeue_lock); |
@@ -964,15 +966,16 @@ static int send_to_sock(struct nodeinfo *ni) | |||
964 | 966 | ||
965 | if (e->len == 0 && e->users == 0) { | 967 | if (e->len == 0 && e->users == 0) { |
966 | list_del(&e->list); | 968 | list_del(&e->list); |
969 | kunmap(e->page); | ||
967 | free_entry(e); | 970 | free_entry(e); |
968 | continue; | 971 | continue; |
969 | } | 972 | } |
970 | } | 973 | } |
971 | spin_unlock(&ni->writequeue_lock); | 974 | spin_unlock(&ni->writequeue_lock); |
972 | out: | 975 | out: |
973 | return ret; | 976 | return; |
974 | 977 | ||
975 | send_error: | 978 | send_error: |
976 | log_print("Error sending to node %d %d", ni->nodeid, ret); | 979 | log_print("Error sending to node %d %d", ni->nodeid, ret); |
977 | spin_lock(&ni->lock); | 980 | spin_lock(&ni->lock); |
978 | if (!test_and_set_bit(NI_INIT_PENDING, &ni->flags)) { | 981 | if (!test_and_set_bit(NI_INIT_PENDING, &ni->flags)) { |
@@ -982,7 +985,7 @@ static int send_to_sock(struct nodeinfo *ni) | |||
982 | } else | 985 | } else |
983 | spin_unlock(&ni->lock); | 986 | spin_unlock(&ni->lock); |
984 | 987 | ||
985 | return ret; | 988 | return; |
986 | } | 989 | } |
987 | 990 | ||
988 | /* Try to send any messages that are pending */ | 991 | /* Try to send any messages that are pending */ |
@@ -994,7 +997,7 @@ static void process_output_queue(void) | |||
994 | spin_lock_bh(&write_nodes_lock); | 997 | spin_lock_bh(&write_nodes_lock); |
995 | list_for_each_safe(list, temp, &write_nodes) { | 998 | list_for_each_safe(list, temp, &write_nodes) { |
996 | struct nodeinfo *ni = | 999 | struct nodeinfo *ni = |
997 | list_entry(list, struct nodeinfo, write_list); | 1000 | list_entry(list, struct nodeinfo, write_list); |
998 | clear_bit(NI_WRITE_PENDING, &ni->flags); | 1001 | clear_bit(NI_WRITE_PENDING, &ni->flags); |
999 | list_del(&ni->write_list); | 1002 | list_del(&ni->write_list); |
1000 | 1003 | ||
@@ -1106,7 +1109,7 @@ static int dlm_recvd(void *data) | |||
1106 | set_current_state(TASK_INTERRUPTIBLE); | 1109 | set_current_state(TASK_INTERRUPTIBLE); |
1107 | add_wait_queue(&lowcomms_recv_wait, &wait); | 1110 | add_wait_queue(&lowcomms_recv_wait, &wait); |
1108 | if (!test_bit(CF_READ_PENDING, &sctp_con.flags)) | 1111 | if (!test_bit(CF_READ_PENDING, &sctp_con.flags)) |
1109 | schedule(); | 1112 | cond_resched(); |
1110 | remove_wait_queue(&lowcomms_recv_wait, &wait); | 1113 | remove_wait_queue(&lowcomms_recv_wait, &wait); |
1111 | set_current_state(TASK_RUNNING); | 1114 | set_current_state(TASK_RUNNING); |
1112 | 1115 | ||
@@ -1118,12 +1121,12 @@ static int dlm_recvd(void *data) | |||
1118 | 1121 | ||
1119 | /* Don't starve out everyone else */ | 1122 | /* Don't starve out everyone else */ |
1120 | if (++count >= MAX_RX_MSG_COUNT) { | 1123 | if (++count >= MAX_RX_MSG_COUNT) { |
1121 | schedule(); | 1124 | cond_resched(); |
1122 | count = 0; | 1125 | count = 0; |
1123 | } | 1126 | } |
1124 | } while (!kthread_should_stop() && ret >=0); | 1127 | } while (!kthread_should_stop() && ret >=0); |
1125 | } | 1128 | } |
1126 | schedule(); | 1129 | cond_resched(); |
1127 | } | 1130 | } |
1128 | 1131 | ||
1129 | return 0; | 1132 | return 0; |
@@ -1138,7 +1141,7 @@ static int dlm_sendd(void *data) | |||
1138 | while (!kthread_should_stop()) { | 1141 | while (!kthread_should_stop()) { |
1139 | set_current_state(TASK_INTERRUPTIBLE); | 1142 | set_current_state(TASK_INTERRUPTIBLE); |
1140 | if (write_list_empty()) | 1143 | if (write_list_empty()) |
1141 | schedule(); | 1144 | cond_resched(); |
1142 | set_current_state(TASK_RUNNING); | 1145 | set_current_state(TASK_RUNNING); |
1143 | 1146 | ||
1144 | if (sctp_con.eagain_flag) { | 1147 | if (sctp_con.eagain_flag) { |
@@ -1166,7 +1169,7 @@ static int daemons_start(void) | |||
1166 | 1169 | ||
1167 | p = kthread_run(dlm_recvd, NULL, "dlm_recvd"); | 1170 | p = kthread_run(dlm_recvd, NULL, "dlm_recvd"); |
1168 | error = IS_ERR(p); | 1171 | error = IS_ERR(p); |
1169 | if (error) { | 1172 | if (error) { |
1170 | log_print("can't start dlm_recvd %d", error); | 1173 | log_print("can't start dlm_recvd %d", error); |
1171 | return error; | 1174 | return error; |
1172 | } | 1175 | } |
@@ -1174,7 +1177,7 @@ static int daemons_start(void) | |||
1174 | 1177 | ||
1175 | p = kthread_run(dlm_sendd, NULL, "dlm_sendd"); | 1178 | p = kthread_run(dlm_sendd, NULL, "dlm_sendd"); |
1176 | error = IS_ERR(p); | 1179 | error = IS_ERR(p); |
1177 | if (error) { | 1180 | if (error) { |
1178 | log_print("can't start dlm_sendd %d", error); | 1181 | log_print("can't start dlm_sendd %d", error); |
1179 | kthread_stop(recv_task); | 1182 | kthread_stop(recv_task); |
1180 | return error; | 1183 | return error; |
@@ -1197,43 +1200,28 @@ int dlm_lowcomms_start(void) | |||
1197 | error = daemons_start(); | 1200 | error = daemons_start(); |
1198 | if (error) | 1201 | if (error) |
1199 | goto fail_sock; | 1202 | goto fail_sock; |
1200 | atomic_set(&accepting, 1); | ||
1201 | return 0; | 1203 | return 0; |
1202 | 1204 | ||
1203 | fail_sock: | 1205 | fail_sock: |
1204 | close_connection(); | 1206 | close_connection(); |
1205 | return error; | 1207 | return error; |
1206 | } | 1208 | } |
1207 | 1209 | ||
1208 | /* Set all the activity flags to prevent any socket activity. */ | ||
1209 | |||
1210 | void dlm_lowcomms_stop(void) | 1210 | void dlm_lowcomms_stop(void) |
1211 | { | 1211 | { |
1212 | atomic_set(&accepting, 0); | 1212 | int i; |
1213 | |||
1213 | sctp_con.flags = 0x7; | 1214 | sctp_con.flags = 0x7; |
1214 | daemons_stop(); | 1215 | daemons_stop(); |
1215 | clean_writequeues(); | 1216 | clean_writequeues(); |
1216 | close_connection(); | 1217 | close_connection(); |
1217 | dealloc_nodeinfo(); | 1218 | dealloc_nodeinfo(); |
1218 | max_nodeid = 0; | 1219 | max_nodeid = 0; |
1219 | } | ||
1220 | 1220 | ||
1221 | int dlm_lowcomms_init(void) | 1221 | dlm_local_count = 0; |
1222 | { | 1222 | dlm_local_nodeid = 0; |
1223 | init_waitqueue_head(&lowcomms_recv_wait); | ||
1224 | spin_lock_init(&write_nodes_lock); | ||
1225 | INIT_LIST_HEAD(&write_nodes); | ||
1226 | init_rwsem(&nodeinfo_lock); | ||
1227 | return 0; | ||
1228 | } | ||
1229 | |||
1230 | void dlm_lowcomms_exit(void) | ||
1231 | { | ||
1232 | int i; | ||
1233 | 1223 | ||
1234 | for (i = 0; i < dlm_local_count; i++) | 1224 | for (i = 0; i < dlm_local_count; i++) |
1235 | kfree(dlm_local_addr[i]); | 1225 | kfree(dlm_local_addr[i]); |
1236 | dlm_local_count = 0; | ||
1237 | dlm_local_nodeid = 0; | ||
1238 | } | 1226 | } |
1239 | 1227 | ||
diff --git a/fs/dlm/lowcomms-tcp.c b/fs/dlm/lowcomms-tcp.c new file mode 100644 index 000000000000..8f2791fc8447 --- /dev/null +++ b/fs/dlm/lowcomms-tcp.c | |||
@@ -0,0 +1,1189 @@ | |||
1 | /****************************************************************************** | ||
2 | ******************************************************************************* | ||
3 | ** | ||
4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
5 | ** Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | ||
6 | ** | ||
7 | ** This copyrighted material is made available to anyone wishing to use, | ||
8 | ** modify, copy, or redistribute it subject to the terms and conditions | ||
9 | ** of the GNU General Public License v.2. | ||
10 | ** | ||
11 | ******************************************************************************* | ||
12 | ******************************************************************************/ | ||
13 | |||
14 | /* | ||
15 | * lowcomms.c | ||
16 | * | ||
17 | * This is the "low-level" comms layer. | ||
18 | * | ||
19 | * It is responsible for sending/receiving messages | ||
20 | * from other nodes in the cluster. | ||
21 | * | ||
22 | * Cluster nodes are referred to by their nodeids. nodeids are | ||
23 | * simply 32 bit numbers to the locking module - if they need to | ||
24 | * be expanded for the cluster infrastructure then that is it's | ||
25 | * responsibility. It is this layer's | ||
26 | * responsibility to resolve these into IP address or | ||
27 | * whatever it needs for inter-node communication. | ||
28 | * | ||
29 | * The comms level is two kernel threads that deal mainly with | ||
30 | * the receiving of messages from other nodes and passing them | ||
31 | * up to the mid-level comms layer (which understands the | ||
32 | * message format) for execution by the locking core, and | ||
33 | * a send thread which does all the setting up of connections | ||
34 | * to remote nodes and the sending of data. Threads are not allowed | ||
35 | * to send their own data because it may cause them to wait in times | ||
36 | * of high load. Also, this way, the sending thread can collect together | ||
37 | * messages bound for one node and send them in one block. | ||
38 | * | ||
39 | * I don't see any problem with the recv thread executing the locking | ||
40 | * code on behalf of remote processes as the locking code is | ||
41 | * short, efficient and never waits. | ||
42 | * | ||
43 | */ | ||
44 | |||
45 | |||
46 | #include <asm/ioctls.h> | ||
47 | #include <net/sock.h> | ||
48 | #include <net/tcp.h> | ||
49 | #include <linux/pagemap.h> | ||
50 | |||
51 | #include "dlm_internal.h" | ||
52 | #include "lowcomms.h" | ||
53 | #include "midcomms.h" | ||
54 | #include "config.h" | ||
55 | |||
56 | struct cbuf { | ||
57 | unsigned int base; | ||
58 | unsigned int len; | ||
59 | unsigned int mask; | ||
60 | }; | ||
61 | |||
62 | #define NODE_INCREMENT 32 | ||
63 | static void cbuf_add(struct cbuf *cb, int n) | ||
64 | { | ||
65 | cb->len += n; | ||
66 | } | ||
67 | |||
68 | static int cbuf_data(struct cbuf *cb) | ||
69 | { | ||
70 | return ((cb->base + cb->len) & cb->mask); | ||
71 | } | ||
72 | |||
73 | static void cbuf_init(struct cbuf *cb, int size) | ||
74 | { | ||
75 | cb->base = cb->len = 0; | ||
76 | cb->mask = size-1; | ||
77 | } | ||
78 | |||
79 | static void cbuf_eat(struct cbuf *cb, int n) | ||
80 | { | ||
81 | cb->len -= n; | ||
82 | cb->base += n; | ||
83 | cb->base &= cb->mask; | ||
84 | } | ||
85 | |||
86 | static bool cbuf_empty(struct cbuf *cb) | ||
87 | { | ||
88 | return cb->len == 0; | ||
89 | } | ||
90 | |||
91 | /* Maximum number of incoming messages to process before | ||
92 | doing a cond_resched() | ||
93 | */ | ||
94 | #define MAX_RX_MSG_COUNT 25 | ||
95 | |||
96 | struct connection { | ||
97 | struct socket *sock; /* NULL if not connected */ | ||
98 | uint32_t nodeid; /* So we know who we are in the list */ | ||
99 | struct rw_semaphore sock_sem; /* Stop connect races */ | ||
100 | struct list_head read_list; /* On this list when ready for reading */ | ||
101 | struct list_head write_list; /* On this list when ready for writing */ | ||
102 | struct list_head state_list; /* On this list when ready to connect */ | ||
103 | unsigned long flags; /* bit 1,2 = We are on the read/write lists */ | ||
104 | #define CF_READ_PENDING 1 | ||
105 | #define CF_WRITE_PENDING 2 | ||
106 | #define CF_CONNECT_PENDING 3 | ||
107 | #define CF_IS_OTHERCON 4 | ||
108 | struct list_head writequeue; /* List of outgoing writequeue_entries */ | ||
109 | struct list_head listenlist; /* List of allocated listening sockets */ | ||
110 | spinlock_t writequeue_lock; | ||
111 | int (*rx_action) (struct connection *); /* What to do when active */ | ||
112 | struct page *rx_page; | ||
113 | struct cbuf cb; | ||
114 | int retries; | ||
115 | atomic_t waiting_requests; | ||
116 | #define MAX_CONNECT_RETRIES 3 | ||
117 | struct connection *othercon; | ||
118 | }; | ||
119 | #define sock2con(x) ((struct connection *)(x)->sk_user_data) | ||
120 | |||
121 | /* An entry waiting to be sent */ | ||
122 | struct writequeue_entry { | ||
123 | struct list_head list; | ||
124 | struct page *page; | ||
125 | int offset; | ||
126 | int len; | ||
127 | int end; | ||
128 | int users; | ||
129 | struct connection *con; | ||
130 | }; | ||
131 | |||
132 | static struct sockaddr_storage dlm_local_addr; | ||
133 | |||
134 | /* Manage daemons */ | ||
135 | static struct task_struct *recv_task; | ||
136 | static struct task_struct *send_task; | ||
137 | |||
138 | static wait_queue_t lowcomms_send_waitq_head; | ||
139 | static DECLARE_WAIT_QUEUE_HEAD(lowcomms_send_waitq); | ||
140 | static wait_queue_t lowcomms_recv_waitq_head; | ||
141 | static DECLARE_WAIT_QUEUE_HEAD(lowcomms_recv_waitq); | ||
142 | |||
143 | /* An array of pointers to connections, indexed by NODEID */ | ||
144 | static struct connection **connections; | ||
145 | static DECLARE_MUTEX(connections_lock); | ||
146 | static kmem_cache_t *con_cache; | ||
147 | static int conn_array_size; | ||
148 | |||
149 | /* List of sockets that have reads pending */ | ||
150 | static LIST_HEAD(read_sockets); | ||
151 | static DEFINE_SPINLOCK(read_sockets_lock); | ||
152 | |||
153 | /* List of sockets which have writes pending */ | ||
154 | static LIST_HEAD(write_sockets); | ||
155 | static DEFINE_SPINLOCK(write_sockets_lock); | ||
156 | |||
157 | /* List of sockets which have connects pending */ | ||
158 | static LIST_HEAD(state_sockets); | ||
159 | static DEFINE_SPINLOCK(state_sockets_lock); | ||
160 | |||
161 | static struct connection *nodeid2con(int nodeid, gfp_t allocation) | ||
162 | { | ||
163 | struct connection *con = NULL; | ||
164 | |||
165 | down(&connections_lock); | ||
166 | if (nodeid >= conn_array_size) { | ||
167 | int new_size = nodeid + NODE_INCREMENT; | ||
168 | struct connection **new_conns; | ||
169 | |||
170 | new_conns = kzalloc(sizeof(struct connection *) * | ||
171 | new_size, allocation); | ||
172 | if (!new_conns) | ||
173 | goto finish; | ||
174 | |||
175 | memcpy(new_conns, connections, sizeof(struct connection *) * conn_array_size); | ||
176 | conn_array_size = new_size; | ||
177 | kfree(connections); | ||
178 | connections = new_conns; | ||
179 | |||
180 | } | ||
181 | |||
182 | con = connections[nodeid]; | ||
183 | if (con == NULL && allocation) { | ||
184 | con = kmem_cache_zalloc(con_cache, allocation); | ||
185 | if (!con) | ||
186 | goto finish; | ||
187 | |||
188 | con->nodeid = nodeid; | ||
189 | init_rwsem(&con->sock_sem); | ||
190 | INIT_LIST_HEAD(&con->writequeue); | ||
191 | spin_lock_init(&con->writequeue_lock); | ||
192 | |||
193 | connections[nodeid] = con; | ||
194 | } | ||
195 | |||
196 | finish: | ||
197 | up(&connections_lock); | ||
198 | return con; | ||
199 | } | ||
200 | |||
201 | /* Data available on socket or listen socket received a connect */ | ||
202 | static void lowcomms_data_ready(struct sock *sk, int count_unused) | ||
203 | { | ||
204 | struct connection *con = sock2con(sk); | ||
205 | |||
206 | atomic_inc(&con->waiting_requests); | ||
207 | if (test_and_set_bit(CF_READ_PENDING, &con->flags)) | ||
208 | return; | ||
209 | |||
210 | spin_lock_bh(&read_sockets_lock); | ||
211 | list_add_tail(&con->read_list, &read_sockets); | ||
212 | spin_unlock_bh(&read_sockets_lock); | ||
213 | |||
214 | wake_up_interruptible(&lowcomms_recv_waitq); | ||
215 | } | ||
216 | |||
217 | static void lowcomms_write_space(struct sock *sk) | ||
218 | { | ||
219 | struct connection *con = sock2con(sk); | ||
220 | |||
221 | if (test_and_set_bit(CF_WRITE_PENDING, &con->flags)) | ||
222 | return; | ||
223 | |||
224 | spin_lock_bh(&write_sockets_lock); | ||
225 | list_add_tail(&con->write_list, &write_sockets); | ||
226 | spin_unlock_bh(&write_sockets_lock); | ||
227 | |||
228 | wake_up_interruptible(&lowcomms_send_waitq); | ||
229 | } | ||
230 | |||
231 | static inline void lowcomms_connect_sock(struct connection *con) | ||
232 | { | ||
233 | if (test_and_set_bit(CF_CONNECT_PENDING, &con->flags)) | ||
234 | return; | ||
235 | |||
236 | spin_lock_bh(&state_sockets_lock); | ||
237 | list_add_tail(&con->state_list, &state_sockets); | ||
238 | spin_unlock_bh(&state_sockets_lock); | ||
239 | |||
240 | wake_up_interruptible(&lowcomms_send_waitq); | ||
241 | } | ||
242 | |||
243 | static void lowcomms_state_change(struct sock *sk) | ||
244 | { | ||
245 | if (sk->sk_state == TCP_ESTABLISHED) | ||
246 | lowcomms_write_space(sk); | ||
247 | } | ||
248 | |||
249 | /* Make a socket active */ | ||
250 | static int add_sock(struct socket *sock, struct connection *con) | ||
251 | { | ||
252 | con->sock = sock; | ||
253 | |||
254 | /* Install a data_ready callback */ | ||
255 | con->sock->sk->sk_data_ready = lowcomms_data_ready; | ||
256 | con->sock->sk->sk_write_space = lowcomms_write_space; | ||
257 | con->sock->sk->sk_state_change = lowcomms_state_change; | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | /* Add the port number to an IP6 or 4 sockaddr and return the address | ||
263 | length */ | ||
264 | static void make_sockaddr(struct sockaddr_storage *saddr, uint16_t port, | ||
265 | int *addr_len) | ||
266 | { | ||
267 | saddr->ss_family = dlm_local_addr.ss_family; | ||
268 | if (saddr->ss_family == AF_INET) { | ||
269 | struct sockaddr_in *in4_addr = (struct sockaddr_in *)saddr; | ||
270 | in4_addr->sin_port = cpu_to_be16(port); | ||
271 | *addr_len = sizeof(struct sockaddr_in); | ||
272 | } else { | ||
273 | struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)saddr; | ||
274 | in6_addr->sin6_port = cpu_to_be16(port); | ||
275 | *addr_len = sizeof(struct sockaddr_in6); | ||
276 | } | ||
277 | } | ||
278 | |||
279 | /* Close a remote connection and tidy up */ | ||
280 | static void close_connection(struct connection *con, bool and_other) | ||
281 | { | ||
282 | down_write(&con->sock_sem); | ||
283 | |||
284 | if (con->sock) { | ||
285 | sock_release(con->sock); | ||
286 | con->sock = NULL; | ||
287 | } | ||
288 | if (con->othercon && and_other) { | ||
289 | /* Will only re-enter once. */ | ||
290 | close_connection(con->othercon, false); | ||
291 | } | ||
292 | if (con->rx_page) { | ||
293 | __free_page(con->rx_page); | ||
294 | con->rx_page = NULL; | ||
295 | } | ||
296 | con->retries = 0; | ||
297 | up_write(&con->sock_sem); | ||
298 | } | ||
299 | |||
300 | /* Data received from remote end */ | ||
301 | static int receive_from_sock(struct connection *con) | ||
302 | { | ||
303 | int ret = 0; | ||
304 | struct msghdr msg; | ||
305 | struct iovec iov[2]; | ||
306 | mm_segment_t fs; | ||
307 | unsigned len; | ||
308 | int r; | ||
309 | int call_again_soon = 0; | ||
310 | |||
311 | down_read(&con->sock_sem); | ||
312 | |||
313 | if (con->sock == NULL) | ||
314 | goto out; | ||
315 | if (con->rx_page == NULL) { | ||
316 | /* | ||
317 | * This doesn't need to be atomic, but I think it should | ||
318 | * improve performance if it is. | ||
319 | */ | ||
320 | con->rx_page = alloc_page(GFP_ATOMIC); | ||
321 | if (con->rx_page == NULL) | ||
322 | goto out_resched; | ||
323 | cbuf_init(&con->cb, PAGE_CACHE_SIZE); | ||
324 | } | ||
325 | |||
326 | msg.msg_control = NULL; | ||
327 | msg.msg_controllen = 0; | ||
328 | msg.msg_iovlen = 1; | ||
329 | msg.msg_iov = iov; | ||
330 | msg.msg_name = NULL; | ||
331 | msg.msg_namelen = 0; | ||
332 | msg.msg_flags = 0; | ||
333 | |||
334 | /* | ||
335 | * iov[0] is the bit of the circular buffer between the current end | ||
336 | * point (cb.base + cb.len) and the end of the buffer. | ||
337 | */ | ||
338 | iov[0].iov_len = con->cb.base - cbuf_data(&con->cb); | ||
339 | iov[0].iov_base = page_address(con->rx_page) + cbuf_data(&con->cb); | ||
340 | iov[1].iov_len = 0; | ||
341 | |||
342 | /* | ||
343 | * iov[1] is the bit of the circular buffer between the start of the | ||
344 | * buffer and the start of the currently used section (cb.base) | ||
345 | */ | ||
346 | if (cbuf_data(&con->cb) >= con->cb.base) { | ||
347 | iov[0].iov_len = PAGE_CACHE_SIZE - cbuf_data(&con->cb); | ||
348 | iov[1].iov_len = con->cb.base; | ||
349 | iov[1].iov_base = page_address(con->rx_page); | ||
350 | msg.msg_iovlen = 2; | ||
351 | } | ||
352 | len = iov[0].iov_len + iov[1].iov_len; | ||
353 | |||
354 | fs = get_fs(); | ||
355 | set_fs(get_ds()); | ||
356 | r = ret = sock_recvmsg(con->sock, &msg, len, | ||
357 | MSG_DONTWAIT | MSG_NOSIGNAL); | ||
358 | set_fs(fs); | ||
359 | |||
360 | if (ret <= 0) | ||
361 | goto out_close; | ||
362 | if (ret == len) | ||
363 | call_again_soon = 1; | ||
364 | cbuf_add(&con->cb, ret); | ||
365 | ret = dlm_process_incoming_buffer(con->nodeid, | ||
366 | page_address(con->rx_page), | ||
367 | con->cb.base, con->cb.len, | ||
368 | PAGE_CACHE_SIZE); | ||
369 | if (ret == -EBADMSG) { | ||
370 | printk(KERN_INFO "dlm: lowcomms: addr=%p, base=%u, len=%u, " | ||
371 | "iov_len=%u, iov_base[0]=%p, read=%d\n", | ||
372 | page_address(con->rx_page), con->cb.base, con->cb.len, | ||
373 | len, iov[0].iov_base, r); | ||
374 | } | ||
375 | if (ret < 0) | ||
376 | goto out_close; | ||
377 | cbuf_eat(&con->cb, ret); | ||
378 | |||
379 | if (cbuf_empty(&con->cb) && !call_again_soon) { | ||
380 | __free_page(con->rx_page); | ||
381 | con->rx_page = NULL; | ||
382 | } | ||
383 | |||
384 | out: | ||
385 | if (call_again_soon) | ||
386 | goto out_resched; | ||
387 | up_read(&con->sock_sem); | ||
388 | return 0; | ||
389 | |||
390 | out_resched: | ||
391 | lowcomms_data_ready(con->sock->sk, 0); | ||
392 | up_read(&con->sock_sem); | ||
393 | cond_resched(); | ||
394 | return 0; | ||
395 | |||
396 | out_close: | ||
397 | up_read(&con->sock_sem); | ||
398 | if (ret != -EAGAIN && !test_bit(CF_IS_OTHERCON, &con->flags)) { | ||
399 | close_connection(con, false); | ||
400 | /* Reconnect when there is something to send */ | ||
401 | } | ||
402 | |||
403 | return ret; | ||
404 | } | ||
405 | |||
406 | /* Listening socket is busy, accept a connection */ | ||
407 | static int accept_from_sock(struct connection *con) | ||
408 | { | ||
409 | int result; | ||
410 | struct sockaddr_storage peeraddr; | ||
411 | struct socket *newsock; | ||
412 | int len; | ||
413 | int nodeid; | ||
414 | struct connection *newcon; | ||
415 | |||
416 | memset(&peeraddr, 0, sizeof(peeraddr)); | ||
417 | result = sock_create_kern(dlm_local_addr.ss_family, SOCK_STREAM, | ||
418 | IPPROTO_TCP, &newsock); | ||
419 | if (result < 0) | ||
420 | return -ENOMEM; | ||
421 | |||
422 | down_read(&con->sock_sem); | ||
423 | |||
424 | result = -ENOTCONN; | ||
425 | if (con->sock == NULL) | ||
426 | goto accept_err; | ||
427 | |||
428 | newsock->type = con->sock->type; | ||
429 | newsock->ops = con->sock->ops; | ||
430 | |||
431 | result = con->sock->ops->accept(con->sock, newsock, O_NONBLOCK); | ||
432 | if (result < 0) | ||
433 | goto accept_err; | ||
434 | |||
435 | /* Get the connected socket's peer */ | ||
436 | memset(&peeraddr, 0, sizeof(peeraddr)); | ||
437 | if (newsock->ops->getname(newsock, (struct sockaddr *)&peeraddr, | ||
438 | &len, 2)) { | ||
439 | result = -ECONNABORTED; | ||
440 | goto accept_err; | ||
441 | } | ||
442 | |||
443 | /* Get the new node's NODEID */ | ||
444 | make_sockaddr(&peeraddr, 0, &len); | ||
445 | if (dlm_addr_to_nodeid(&peeraddr, &nodeid)) { | ||
446 | printk("dlm: connect from non cluster node\n"); | ||
447 | sock_release(newsock); | ||
448 | up_read(&con->sock_sem); | ||
449 | return -1; | ||
450 | } | ||
451 | |||
452 | log_print("got connection from %d", nodeid); | ||
453 | |||
454 | /* Check to see if we already have a connection to this node. This | ||
455 | * could happen if the two nodes initiate a connection at roughly | ||
456 | * the same time and the connections cross on the wire. | ||
457 | * TEMPORARY FIX: | ||
458 | * In this case we store the incoming one in "othercon" | ||
459 | */ | ||
460 | newcon = nodeid2con(nodeid, GFP_KERNEL); | ||
461 | if (!newcon) { | ||
462 | result = -ENOMEM; | ||
463 | goto accept_err; | ||
464 | } | ||
465 | down_write(&newcon->sock_sem); | ||
466 | if (newcon->sock) { | ||
467 | struct connection *othercon = newcon->othercon; | ||
468 | |||
469 | if (!othercon) { | ||
470 | othercon = kmem_cache_zalloc(con_cache, GFP_KERNEL); | ||
471 | if (!othercon) { | ||
472 | printk("dlm: failed to allocate incoming socket\n"); | ||
473 | up_write(&newcon->sock_sem); | ||
474 | result = -ENOMEM; | ||
475 | goto accept_err; | ||
476 | } | ||
477 | othercon->nodeid = nodeid; | ||
478 | othercon->rx_action = receive_from_sock; | ||
479 | init_rwsem(&othercon->sock_sem); | ||
480 | set_bit(CF_IS_OTHERCON, &othercon->flags); | ||
481 | newcon->othercon = othercon; | ||
482 | } | ||
483 | othercon->sock = newsock; | ||
484 | newsock->sk->sk_user_data = othercon; | ||
485 | add_sock(newsock, othercon); | ||
486 | } | ||
487 | else { | ||
488 | newsock->sk->sk_user_data = newcon; | ||
489 | newcon->rx_action = receive_from_sock; | ||
490 | add_sock(newsock, newcon); | ||
491 | |||
492 | } | ||
493 | |||
494 | up_write(&newcon->sock_sem); | ||
495 | |||
496 | /* | ||
497 | * Add it to the active queue in case we got data | ||
498 | * beween processing the accept adding the socket | ||
499 | * to the read_sockets list | ||
500 | */ | ||
501 | lowcomms_data_ready(newsock->sk, 0); | ||
502 | up_read(&con->sock_sem); | ||
503 | |||
504 | return 0; | ||
505 | |||
506 | accept_err: | ||
507 | up_read(&con->sock_sem); | ||
508 | sock_release(newsock); | ||
509 | |||
510 | if (result != -EAGAIN) | ||
511 | printk("dlm: error accepting connection from node: %d\n", result); | ||
512 | return result; | ||
513 | } | ||
514 | |||
515 | /* Connect a new socket to its peer */ | ||
516 | static void connect_to_sock(struct connection *con) | ||
517 | { | ||
518 | int result = -EHOSTUNREACH; | ||
519 | struct sockaddr_storage saddr; | ||
520 | int addr_len; | ||
521 | struct socket *sock; | ||
522 | |||
523 | if (con->nodeid == 0) { | ||
524 | log_print("attempt to connect sock 0 foiled"); | ||
525 | return; | ||
526 | } | ||
527 | |||
528 | down_write(&con->sock_sem); | ||
529 | if (con->retries++ > MAX_CONNECT_RETRIES) | ||
530 | goto out; | ||
531 | |||
532 | /* Some odd races can cause double-connects, ignore them */ | ||
533 | if (con->sock) { | ||
534 | result = 0; | ||
535 | goto out; | ||
536 | } | ||
537 | |||
538 | /* Create a socket to communicate with */ | ||
539 | result = sock_create_kern(dlm_local_addr.ss_family, SOCK_STREAM, | ||
540 | IPPROTO_TCP, &sock); | ||
541 | if (result < 0) | ||
542 | goto out_err; | ||
543 | |||
544 | memset(&saddr, 0, sizeof(saddr)); | ||
545 | if (dlm_nodeid_to_addr(con->nodeid, &saddr)) | ||
546 | goto out_err; | ||
547 | |||
548 | sock->sk->sk_user_data = con; | ||
549 | con->rx_action = receive_from_sock; | ||
550 | |||
551 | make_sockaddr(&saddr, dlm_config.tcp_port, &addr_len); | ||
552 | |||
553 | add_sock(sock, con); | ||
554 | |||
555 | log_print("connecting to %d", con->nodeid); | ||
556 | result = | ||
557 | sock->ops->connect(sock, (struct sockaddr *)&saddr, addr_len, | ||
558 | O_NONBLOCK); | ||
559 | if (result == -EINPROGRESS) | ||
560 | result = 0; | ||
561 | if (result == 0) | ||
562 | goto out; | ||
563 | |||
564 | out_err: | ||
565 | if (con->sock) { | ||
566 | sock_release(con->sock); | ||
567 | con->sock = NULL; | ||
568 | } | ||
569 | /* | ||
570 | * Some errors are fatal and this list might need adjusting. For other | ||
571 | * errors we try again until the max number of retries is reached. | ||
572 | */ | ||
573 | if (result != -EHOSTUNREACH && result != -ENETUNREACH && | ||
574 | result != -ENETDOWN && result != EINVAL | ||
575 | && result != -EPROTONOSUPPORT) { | ||
576 | lowcomms_connect_sock(con); | ||
577 | result = 0; | ||
578 | } | ||
579 | out: | ||
580 | up_write(&con->sock_sem); | ||
581 | return; | ||
582 | } | ||
583 | |||
584 | static struct socket *create_listen_sock(struct connection *con, | ||
585 | struct sockaddr_storage *saddr) | ||
586 | { | ||
587 | struct socket *sock = NULL; | ||
588 | mm_segment_t fs; | ||
589 | int result = 0; | ||
590 | int one = 1; | ||
591 | int addr_len; | ||
592 | |||
593 | if (dlm_local_addr.ss_family == AF_INET) | ||
594 | addr_len = sizeof(struct sockaddr_in); | ||
595 | else | ||
596 | addr_len = sizeof(struct sockaddr_in6); | ||
597 | |||
598 | /* Create a socket to communicate with */ | ||
599 | result = sock_create_kern(dlm_local_addr.ss_family, SOCK_STREAM, IPPROTO_TCP, &sock); | ||
600 | if (result < 0) { | ||
601 | printk("dlm: Can't create listening comms socket\n"); | ||
602 | goto create_out; | ||
603 | } | ||
604 | |||
605 | fs = get_fs(); | ||
606 | set_fs(get_ds()); | ||
607 | result = sock_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, | ||
608 | (char *)&one, sizeof(one)); | ||
609 | set_fs(fs); | ||
610 | if (result < 0) { | ||
611 | printk("dlm: Failed to set SO_REUSEADDR on socket: result=%d\n", | ||
612 | result); | ||
613 | } | ||
614 | sock->sk->sk_user_data = con; | ||
615 | con->rx_action = accept_from_sock; | ||
616 | con->sock = sock; | ||
617 | |||
618 | /* Bind to our port */ | ||
619 | make_sockaddr(saddr, dlm_config.tcp_port, &addr_len); | ||
620 | result = sock->ops->bind(sock, (struct sockaddr *) saddr, addr_len); | ||
621 | if (result < 0) { | ||
622 | printk("dlm: Can't bind to port %d\n", dlm_config.tcp_port); | ||
623 | sock_release(sock); | ||
624 | sock = NULL; | ||
625 | con->sock = NULL; | ||
626 | goto create_out; | ||
627 | } | ||
628 | |||
629 | fs = get_fs(); | ||
630 | set_fs(get_ds()); | ||
631 | |||
632 | result = sock_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, | ||
633 | (char *)&one, sizeof(one)); | ||
634 | set_fs(fs); | ||
635 | if (result < 0) { | ||
636 | printk("dlm: Set keepalive failed: %d\n", result); | ||
637 | } | ||
638 | |||
639 | result = sock->ops->listen(sock, 5); | ||
640 | if (result < 0) { | ||
641 | printk("dlm: Can't listen on port %d\n", dlm_config.tcp_port); | ||
642 | sock_release(sock); | ||
643 | sock = NULL; | ||
644 | goto create_out; | ||
645 | } | ||
646 | |||
647 | create_out: | ||
648 | return sock; | ||
649 | } | ||
650 | |||
651 | |||
652 | /* Listen on all interfaces */ | ||
653 | static int listen_for_all(void) | ||
654 | { | ||
655 | struct socket *sock = NULL; | ||
656 | struct connection *con = nodeid2con(0, GFP_KERNEL); | ||
657 | int result = -EINVAL; | ||
658 | |||
659 | /* We don't support multi-homed hosts */ | ||
660 | set_bit(CF_IS_OTHERCON, &con->flags); | ||
661 | |||
662 | sock = create_listen_sock(con, &dlm_local_addr); | ||
663 | if (sock) { | ||
664 | add_sock(sock, con); | ||
665 | result = 0; | ||
666 | } | ||
667 | else { | ||
668 | result = -EADDRINUSE; | ||
669 | } | ||
670 | |||
671 | return result; | ||
672 | } | ||
673 | |||
674 | |||
675 | |||
676 | static struct writequeue_entry *new_writequeue_entry(struct connection *con, | ||
677 | gfp_t allocation) | ||
678 | { | ||
679 | struct writequeue_entry *entry; | ||
680 | |||
681 | entry = kmalloc(sizeof(struct writequeue_entry), allocation); | ||
682 | if (!entry) | ||
683 | return NULL; | ||
684 | |||
685 | entry->page = alloc_page(allocation); | ||
686 | if (!entry->page) { | ||
687 | kfree(entry); | ||
688 | return NULL; | ||
689 | } | ||
690 | |||
691 | entry->offset = 0; | ||
692 | entry->len = 0; | ||
693 | entry->end = 0; | ||
694 | entry->users = 0; | ||
695 | entry->con = con; | ||
696 | |||
697 | return entry; | ||
698 | } | ||
699 | |||
700 | void *dlm_lowcomms_get_buffer(int nodeid, int len, | ||
701 | gfp_t allocation, char **ppc) | ||
702 | { | ||
703 | struct connection *con; | ||
704 | struct writequeue_entry *e; | ||
705 | int offset = 0; | ||
706 | int users = 0; | ||
707 | |||
708 | con = nodeid2con(nodeid, allocation); | ||
709 | if (!con) | ||
710 | return NULL; | ||
711 | |||
712 | e = list_entry(con->writequeue.prev, struct writequeue_entry, list); | ||
713 | if ((&e->list == &con->writequeue) || | ||
714 | (PAGE_CACHE_SIZE - e->end < len)) { | ||
715 | e = NULL; | ||
716 | } else { | ||
717 | offset = e->end; | ||
718 | e->end += len; | ||
719 | users = e->users++; | ||
720 | } | ||
721 | spin_unlock(&con->writequeue_lock); | ||
722 | |||
723 | if (e) { | ||
724 | got_one: | ||
725 | if (users == 0) | ||
726 | kmap(e->page); | ||
727 | *ppc = page_address(e->page) + offset; | ||
728 | return e; | ||
729 | } | ||
730 | |||
731 | e = new_writequeue_entry(con, allocation); | ||
732 | if (e) { | ||
733 | spin_lock(&con->writequeue_lock); | ||
734 | offset = e->end; | ||
735 | e->end += len; | ||
736 | users = e->users++; | ||
737 | list_add_tail(&e->list, &con->writequeue); | ||
738 | spin_unlock(&con->writequeue_lock); | ||
739 | goto got_one; | ||
740 | } | ||
741 | return NULL; | ||
742 | } | ||
743 | |||
744 | void dlm_lowcomms_commit_buffer(void *mh) | ||
745 | { | ||
746 | struct writequeue_entry *e = (struct writequeue_entry *)mh; | ||
747 | struct connection *con = e->con; | ||
748 | int users; | ||
749 | |||
750 | users = --e->users; | ||
751 | if (users) | ||
752 | goto out; | ||
753 | e->len = e->end - e->offset; | ||
754 | kunmap(e->page); | ||
755 | spin_unlock(&con->writequeue_lock); | ||
756 | |||
757 | if (test_and_set_bit(CF_WRITE_PENDING, &con->flags) == 0) { | ||
758 | spin_lock_bh(&write_sockets_lock); | ||
759 | list_add_tail(&con->write_list, &write_sockets); | ||
760 | spin_unlock_bh(&write_sockets_lock); | ||
761 | |||
762 | wake_up_interruptible(&lowcomms_send_waitq); | ||
763 | } | ||
764 | return; | ||
765 | |||
766 | out: | ||
767 | spin_unlock(&con->writequeue_lock); | ||
768 | return; | ||
769 | } | ||
770 | |||
771 | static void free_entry(struct writequeue_entry *e) | ||
772 | { | ||
773 | __free_page(e->page); | ||
774 | kfree(e); | ||
775 | } | ||
776 | |||
777 | /* Send a message */ | ||
778 | static void send_to_sock(struct connection *con) | ||
779 | { | ||
780 | int ret = 0; | ||
781 | ssize_t(*sendpage) (struct socket *, struct page *, int, size_t, int); | ||
782 | const int msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL; | ||
783 | struct writequeue_entry *e; | ||
784 | int len, offset; | ||
785 | |||
786 | down_read(&con->sock_sem); | ||
787 | if (con->sock == NULL) | ||
788 | goto out_connect; | ||
789 | |||
790 | sendpage = con->sock->ops->sendpage; | ||
791 | |||
792 | spin_lock(&con->writequeue_lock); | ||
793 | for (;;) { | ||
794 | e = list_entry(con->writequeue.next, struct writequeue_entry, | ||
795 | list); | ||
796 | if ((struct list_head *) e == &con->writequeue) | ||
797 | break; | ||
798 | |||
799 | len = e->len; | ||
800 | offset = e->offset; | ||
801 | BUG_ON(len == 0 && e->users == 0); | ||
802 | spin_unlock(&con->writequeue_lock); | ||
803 | |||
804 | ret = 0; | ||
805 | if (len) { | ||
806 | ret = sendpage(con->sock, e->page, offset, len, | ||
807 | msg_flags); | ||
808 | if (ret == -EAGAIN || ret == 0) | ||
809 | goto out; | ||
810 | if (ret <= 0) | ||
811 | goto send_error; | ||
812 | } | ||
813 | else { | ||
814 | /* Don't starve people filling buffers */ | ||
815 | cond_resched(); | ||
816 | } | ||
817 | |||
818 | spin_lock(&con->writequeue_lock); | ||
819 | e->offset += ret; | ||
820 | e->len -= ret; | ||
821 | |||
822 | if (e->len == 0 && e->users == 0) { | ||
823 | list_del(&e->list); | ||
824 | kunmap(e->page); | ||
825 | free_entry(e); | ||
826 | continue; | ||
827 | } | ||
828 | } | ||
829 | spin_unlock(&con->writequeue_lock); | ||
830 | out: | ||
831 | up_read(&con->sock_sem); | ||
832 | return; | ||
833 | |||
834 | send_error: | ||
835 | up_read(&con->sock_sem); | ||
836 | close_connection(con, false); | ||
837 | lowcomms_connect_sock(con); | ||
838 | return; | ||
839 | |||
840 | out_connect: | ||
841 | up_read(&con->sock_sem); | ||
842 | lowcomms_connect_sock(con); | ||
843 | return; | ||
844 | } | ||
845 | |||
846 | static void clean_one_writequeue(struct connection *con) | ||
847 | { | ||
848 | struct list_head *list; | ||
849 | struct list_head *temp; | ||
850 | |||
851 | spin_lock(&con->writequeue_lock); | ||
852 | list_for_each_safe(list, temp, &con->writequeue) { | ||
853 | struct writequeue_entry *e = | ||
854 | list_entry(list, struct writequeue_entry, list); | ||
855 | list_del(&e->list); | ||
856 | free_entry(e); | ||
857 | } | ||
858 | spin_unlock(&con->writequeue_lock); | ||
859 | } | ||
860 | |||
861 | /* Called from recovery when it knows that a node has | ||
862 | left the cluster */ | ||
863 | int dlm_lowcomms_close(int nodeid) | ||
864 | { | ||
865 | struct connection *con; | ||
866 | |||
867 | if (!connections) | ||
868 | goto out; | ||
869 | |||
870 | log_print("closing connection to node %d", nodeid); | ||
871 | con = nodeid2con(nodeid, 0); | ||
872 | if (con) { | ||
873 | clean_one_writequeue(con); | ||
874 | close_connection(con, true); | ||
875 | atomic_set(&con->waiting_requests, 0); | ||
876 | } | ||
877 | return 0; | ||
878 | |||
879 | out: | ||
880 | return -1; | ||
881 | } | ||
882 | |||
883 | /* API send message call, may queue the request */ | ||
884 | /* N.B. This is the old interface - use the new one for new calls */ | ||
885 | int lowcomms_send_message(int nodeid, char *buf, int len, gfp_t allocation) | ||
886 | { | ||
887 | struct writequeue_entry *e; | ||
888 | char *b; | ||
889 | |||
890 | e = dlm_lowcomms_get_buffer(nodeid, len, allocation, &b); | ||
891 | if (e) { | ||
892 | memcpy(b, buf, len); | ||
893 | dlm_lowcomms_commit_buffer(e); | ||
894 | return 0; | ||
895 | } | ||
896 | return -ENOBUFS; | ||
897 | } | ||
898 | |||
899 | /* Look for activity on active sockets */ | ||
900 | static void process_sockets(void) | ||
901 | { | ||
902 | struct list_head *list; | ||
903 | struct list_head *temp; | ||
904 | int count = 0; | ||
905 | |||
906 | spin_lock_bh(&read_sockets_lock); | ||
907 | list_for_each_safe(list, temp, &read_sockets) { | ||
908 | |||
909 | struct connection *con = | ||
910 | list_entry(list, struct connection, read_list); | ||
911 | list_del(&con->read_list); | ||
912 | clear_bit(CF_READ_PENDING, &con->flags); | ||
913 | |||
914 | spin_unlock_bh(&read_sockets_lock); | ||
915 | |||
916 | /* This can reach zero if we are processing requests | ||
917 | * as they come in. | ||
918 | */ | ||
919 | if (atomic_read(&con->waiting_requests) == 0) { | ||
920 | spin_lock_bh(&read_sockets_lock); | ||
921 | continue; | ||
922 | } | ||
923 | |||
924 | do { | ||
925 | con->rx_action(con); | ||
926 | |||
927 | /* Don't starve out everyone else */ | ||
928 | if (++count >= MAX_RX_MSG_COUNT) { | ||
929 | cond_resched(); | ||
930 | count = 0; | ||
931 | } | ||
932 | |||
933 | } while (!atomic_dec_and_test(&con->waiting_requests) && | ||
934 | !kthread_should_stop()); | ||
935 | |||
936 | spin_lock_bh(&read_sockets_lock); | ||
937 | } | ||
938 | spin_unlock_bh(&read_sockets_lock); | ||
939 | } | ||
940 | |||
941 | /* Try to send any messages that are pending | ||
942 | */ | ||
943 | static void process_output_queue(void) | ||
944 | { | ||
945 | struct list_head *list; | ||
946 | struct list_head *temp; | ||
947 | |||
948 | spin_lock_bh(&write_sockets_lock); | ||
949 | list_for_each_safe(list, temp, &write_sockets) { | ||
950 | struct connection *con = | ||
951 | list_entry(list, struct connection, write_list); | ||
952 | clear_bit(CF_WRITE_PENDING, &con->flags); | ||
953 | list_del(&con->write_list); | ||
954 | |||
955 | spin_unlock_bh(&write_sockets_lock); | ||
956 | send_to_sock(con); | ||
957 | spin_lock_bh(&write_sockets_lock); | ||
958 | } | ||
959 | spin_unlock_bh(&write_sockets_lock); | ||
960 | } | ||
961 | |||
962 | static void process_state_queue(void) | ||
963 | { | ||
964 | struct list_head *list; | ||
965 | struct list_head *temp; | ||
966 | |||
967 | spin_lock_bh(&state_sockets_lock); | ||
968 | list_for_each_safe(list, temp, &state_sockets) { | ||
969 | struct connection *con = | ||
970 | list_entry(list, struct connection, state_list); | ||
971 | list_del(&con->state_list); | ||
972 | clear_bit(CF_CONNECT_PENDING, &con->flags); | ||
973 | spin_unlock_bh(&state_sockets_lock); | ||
974 | |||
975 | connect_to_sock(con); | ||
976 | spin_lock_bh(&state_sockets_lock); | ||
977 | } | ||
978 | spin_unlock_bh(&state_sockets_lock); | ||
979 | } | ||
980 | |||
981 | |||
982 | /* Discard all entries on the write queues */ | ||
983 | static void clean_writequeues(void) | ||
984 | { | ||
985 | int nodeid; | ||
986 | |||
987 | for (nodeid = 1; nodeid < conn_array_size; nodeid++) { | ||
988 | struct connection *con = nodeid2con(nodeid, 0); | ||
989 | |||
990 | if (con) | ||
991 | clean_one_writequeue(con); | ||
992 | } | ||
993 | } | ||
994 | |||
995 | static int read_list_empty(void) | ||
996 | { | ||
997 | int status; | ||
998 | |||
999 | spin_lock_bh(&read_sockets_lock); | ||
1000 | status = list_empty(&read_sockets); | ||
1001 | spin_unlock_bh(&read_sockets_lock); | ||
1002 | |||
1003 | return status; | ||
1004 | } | ||
1005 | |||
1006 | /* DLM Transport comms receive daemon */ | ||
1007 | static int dlm_recvd(void *data) | ||
1008 | { | ||
1009 | init_waitqueue_entry(&lowcomms_recv_waitq_head, current); | ||
1010 | add_wait_queue(&lowcomms_recv_waitq, &lowcomms_recv_waitq_head); | ||
1011 | |||
1012 | while (!kthread_should_stop()) { | ||
1013 | set_current_state(TASK_INTERRUPTIBLE); | ||
1014 | if (read_list_empty()) | ||
1015 | cond_resched(); | ||
1016 | set_current_state(TASK_RUNNING); | ||
1017 | |||
1018 | process_sockets(); | ||
1019 | } | ||
1020 | |||
1021 | return 0; | ||
1022 | } | ||
1023 | |||
1024 | static int write_and_state_lists_empty(void) | ||
1025 | { | ||
1026 | int status; | ||
1027 | |||
1028 | spin_lock_bh(&write_sockets_lock); | ||
1029 | status = list_empty(&write_sockets); | ||
1030 | spin_unlock_bh(&write_sockets_lock); | ||
1031 | |||
1032 | spin_lock_bh(&state_sockets_lock); | ||
1033 | if (list_empty(&state_sockets) == 0) | ||
1034 | status = 0; | ||
1035 | spin_unlock_bh(&state_sockets_lock); | ||
1036 | |||
1037 | return status; | ||
1038 | } | ||
1039 | |||
1040 | /* DLM Transport send daemon */ | ||
1041 | static int dlm_sendd(void *data) | ||
1042 | { | ||
1043 | init_waitqueue_entry(&lowcomms_send_waitq_head, current); | ||
1044 | add_wait_queue(&lowcomms_send_waitq, &lowcomms_send_waitq_head); | ||
1045 | |||
1046 | while (!kthread_should_stop()) { | ||
1047 | set_current_state(TASK_INTERRUPTIBLE); | ||
1048 | if (write_and_state_lists_empty()) | ||
1049 | cond_resched(); | ||
1050 | set_current_state(TASK_RUNNING); | ||
1051 | |||
1052 | process_state_queue(); | ||
1053 | process_output_queue(); | ||
1054 | } | ||
1055 | |||
1056 | return 0; | ||
1057 | } | ||
1058 | |||
1059 | static void daemons_stop(void) | ||
1060 | { | ||
1061 | kthread_stop(recv_task); | ||
1062 | kthread_stop(send_task); | ||
1063 | } | ||
1064 | |||
1065 | static int daemons_start(void) | ||
1066 | { | ||
1067 | struct task_struct *p; | ||
1068 | int error; | ||
1069 | |||
1070 | p = kthread_run(dlm_recvd, NULL, "dlm_recvd"); | ||
1071 | error = IS_ERR(p); | ||
1072 | if (error) { | ||
1073 | log_print("can't start dlm_recvd %d", error); | ||
1074 | return error; | ||
1075 | } | ||
1076 | recv_task = p; | ||
1077 | |||
1078 | p = kthread_run(dlm_sendd, NULL, "dlm_sendd"); | ||
1079 | error = IS_ERR(p); | ||
1080 | if (error) { | ||
1081 | log_print("can't start dlm_sendd %d", error); | ||
1082 | kthread_stop(recv_task); | ||
1083 | return error; | ||
1084 | } | ||
1085 | send_task = p; | ||
1086 | |||
1087 | return 0; | ||
1088 | } | ||
1089 | |||
1090 | /* | ||
1091 | * Return the largest buffer size we can cope with. | ||
1092 | */ | ||
1093 | int lowcomms_max_buffer_size(void) | ||
1094 | { | ||
1095 | return PAGE_CACHE_SIZE; | ||
1096 | } | ||
1097 | |||
1098 | void dlm_lowcomms_stop(void) | ||
1099 | { | ||
1100 | int i; | ||
1101 | |||
1102 | /* Set all the flags to prevent any | ||
1103 | socket activity. | ||
1104 | */ | ||
1105 | for (i = 0; i < conn_array_size; i++) { | ||
1106 | if (connections[i]) | ||
1107 | connections[i]->flags |= 0xFF; | ||
1108 | } | ||
1109 | |||
1110 | daemons_stop(); | ||
1111 | clean_writequeues(); | ||
1112 | |||
1113 | for (i = 0; i < conn_array_size; i++) { | ||
1114 | if (connections[i]) { | ||
1115 | close_connection(connections[i], true); | ||
1116 | if (connections[i]->othercon) | ||
1117 | kmem_cache_free(con_cache, connections[i]->othercon); | ||
1118 | kmem_cache_free(con_cache, connections[i]); | ||
1119 | } | ||
1120 | } | ||
1121 | |||
1122 | kfree(connections); | ||
1123 | connections = NULL; | ||
1124 | |||
1125 | kmem_cache_destroy(con_cache); | ||
1126 | } | ||
1127 | |||
1128 | /* This is quite likely to sleep... */ | ||
1129 | int dlm_lowcomms_start(void) | ||
1130 | { | ||
1131 | int error = 0; | ||
1132 | |||
1133 | error = -ENOMEM; | ||
1134 | connections = kzalloc(sizeof(struct connection *) * | ||
1135 | NODE_INCREMENT, GFP_KERNEL); | ||
1136 | if (!connections) | ||
1137 | goto out; | ||
1138 | |||
1139 | conn_array_size = NODE_INCREMENT; | ||
1140 | |||
1141 | if (dlm_our_addr(&dlm_local_addr, 0)) { | ||
1142 | log_print("no local IP address has been set"); | ||
1143 | goto fail_free_conn; | ||
1144 | } | ||
1145 | if (!dlm_our_addr(&dlm_local_addr, 1)) { | ||
1146 | log_print("This dlm comms module does not support multi-homed clustering"); | ||
1147 | goto fail_free_conn; | ||
1148 | } | ||
1149 | |||
1150 | con_cache = kmem_cache_create("dlm_conn", sizeof(struct connection), | ||
1151 | __alignof__(struct connection), 0, | ||
1152 | NULL, NULL); | ||
1153 | if (!con_cache) | ||
1154 | goto fail_free_conn; | ||
1155 | |||
1156 | |||
1157 | /* Start listening */ | ||
1158 | error = listen_for_all(); | ||
1159 | if (error) | ||
1160 | goto fail_unlisten; | ||
1161 | |||
1162 | error = daemons_start(); | ||
1163 | if (error) | ||
1164 | goto fail_unlisten; | ||
1165 | |||
1166 | return 0; | ||
1167 | |||
1168 | fail_unlisten: | ||
1169 | close_connection(connections[0], false); | ||
1170 | kmem_cache_free(con_cache, connections[0]); | ||
1171 | kmem_cache_destroy(con_cache); | ||
1172 | |||
1173 | fail_free_conn: | ||
1174 | kfree(connections); | ||
1175 | |||
1176 | out: | ||
1177 | return error; | ||
1178 | } | ||
1179 | |||
1180 | /* | ||
1181 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
1182 | * Emacs will notice this stuff at the end of the file and automatically | ||
1183 | * adjust the settings for this buffer only. This must remain at the end | ||
1184 | * of the file. | ||
1185 | * --------------------------------------------------------------------------- | ||
1186 | * Local variables: | ||
1187 | * c-file-style: "linux" | ||
1188 | * End: | ||
1189 | */ | ||
diff --git a/fs/dlm/lowcomms.h b/fs/dlm/lowcomms.h index 2d045e0daae1..a9a9618c0d3f 100644 --- a/fs/dlm/lowcomms.h +++ b/fs/dlm/lowcomms.h | |||
@@ -14,8 +14,6 @@ | |||
14 | #ifndef __LOWCOMMS_DOT_H__ | 14 | #ifndef __LOWCOMMS_DOT_H__ |
15 | #define __LOWCOMMS_DOT_H__ | 15 | #define __LOWCOMMS_DOT_H__ |
16 | 16 | ||
17 | int dlm_lowcomms_init(void); | ||
18 | void dlm_lowcomms_exit(void); | ||
19 | int dlm_lowcomms_start(void); | 17 | int dlm_lowcomms_start(void); |
20 | void dlm_lowcomms_stop(void); | 18 | void dlm_lowcomms_stop(void); |
21 | int dlm_lowcomms_close(int nodeid); | 19 | int dlm_lowcomms_close(int nodeid); |
diff --git a/fs/dlm/main.c b/fs/dlm/main.c index a8da8dc36b2e..162fbae58fe5 100644 --- a/fs/dlm/main.c +++ b/fs/dlm/main.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include "lock.h" | 16 | #include "lock.h" |
17 | #include "user.h" | 17 | #include "user.h" |
18 | #include "memory.h" | 18 | #include "memory.h" |
19 | #include "lowcomms.h" | ||
20 | #include "config.h" | 19 | #include "config.h" |
21 | 20 | ||
22 | #ifdef CONFIG_DLM_DEBUG | 21 | #ifdef CONFIG_DLM_DEBUG |
@@ -47,20 +46,14 @@ static int __init init_dlm(void) | |||
47 | if (error) | 46 | if (error) |
48 | goto out_config; | 47 | goto out_config; |
49 | 48 | ||
50 | error = dlm_lowcomms_init(); | ||
51 | if (error) | ||
52 | goto out_debug; | ||
53 | |||
54 | error = dlm_user_init(); | 49 | error = dlm_user_init(); |
55 | if (error) | 50 | if (error) |
56 | goto out_lowcomms; | 51 | goto out_debug; |
57 | 52 | ||
58 | printk("DLM (built %s %s) installed\n", __DATE__, __TIME__); | 53 | printk("DLM (built %s %s) installed\n", __DATE__, __TIME__); |
59 | 54 | ||
60 | return 0; | 55 | return 0; |
61 | 56 | ||
62 | out_lowcomms: | ||
63 | dlm_lowcomms_exit(); | ||
64 | out_debug: | 57 | out_debug: |
65 | dlm_unregister_debugfs(); | 58 | dlm_unregister_debugfs(); |
66 | out_config: | 59 | out_config: |
@@ -76,7 +69,6 @@ static int __init init_dlm(void) | |||
76 | static void __exit exit_dlm(void) | 69 | static void __exit exit_dlm(void) |
77 | { | 70 | { |
78 | dlm_user_exit(); | 71 | dlm_user_exit(); |
79 | dlm_lowcomms_exit(); | ||
80 | dlm_config_exit(); | 72 | dlm_config_exit(); |
81 | dlm_memory_exit(); | 73 | dlm_memory_exit(); |
82 | dlm_lockspace_exit(); | 74 | dlm_lockspace_exit(); |
diff --git a/fs/dlm/member.c b/fs/dlm/member.c index a3f7de7f3a8f..85e2897bd740 100644 --- a/fs/dlm/member.c +++ b/fs/dlm/member.c | |||
@@ -186,6 +186,14 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) | |||
186 | struct dlm_member *memb, *safe; | 186 | struct dlm_member *memb, *safe; |
187 | int i, error, found, pos = 0, neg = 0, low = -1; | 187 | int i, error, found, pos = 0, neg = 0, low = -1; |
188 | 188 | ||
189 | /* previously removed members that we've not finished removing need to | ||
190 | count as a negative change so the "neg" recovery steps will happen */ | ||
191 | |||
192 | list_for_each_entry(memb, &ls->ls_nodes_gone, list) { | ||
193 | log_debug(ls, "prev removed member %d", memb->nodeid); | ||
194 | neg++; | ||
195 | } | ||
196 | |||
189 | /* move departed members from ls_nodes to ls_nodes_gone */ | 197 | /* move departed members from ls_nodes to ls_nodes_gone */ |
190 | 198 | ||
191 | list_for_each_entry_safe(memb, safe, &ls->ls_nodes, list) { | 199 | list_for_each_entry_safe(memb, safe, &ls->ls_nodes, list) { |
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c index 518239a8b1e9..4cc31be9cd9d 100644 --- a/fs/dlm/rcom.c +++ b/fs/dlm/rcom.c | |||
@@ -90,13 +90,28 @@ static int check_config(struct dlm_ls *ls, struct rcom_config *rf, int nodeid) | |||
90 | return 0; | 90 | return 0; |
91 | } | 91 | } |
92 | 92 | ||
93 | static void allow_sync_reply(struct dlm_ls *ls, uint64_t *new_seq) | ||
94 | { | ||
95 | spin_lock(&ls->ls_rcom_spin); | ||
96 | *new_seq = ++ls->ls_rcom_seq; | ||
97 | set_bit(LSFL_RCOM_WAIT, &ls->ls_flags); | ||
98 | spin_unlock(&ls->ls_rcom_spin); | ||
99 | } | ||
100 | |||
101 | static void disallow_sync_reply(struct dlm_ls *ls) | ||
102 | { | ||
103 | spin_lock(&ls->ls_rcom_spin); | ||
104 | clear_bit(LSFL_RCOM_WAIT, &ls->ls_flags); | ||
105 | clear_bit(LSFL_RCOM_READY, &ls->ls_flags); | ||
106 | spin_unlock(&ls->ls_rcom_spin); | ||
107 | } | ||
108 | |||
93 | int dlm_rcom_status(struct dlm_ls *ls, int nodeid) | 109 | int dlm_rcom_status(struct dlm_ls *ls, int nodeid) |
94 | { | 110 | { |
95 | struct dlm_rcom *rc; | 111 | struct dlm_rcom *rc; |
96 | struct dlm_mhandle *mh; | 112 | struct dlm_mhandle *mh; |
97 | int error = 0; | 113 | int error = 0; |
98 | 114 | ||
99 | memset(ls->ls_recover_buf, 0, dlm_config.buffer_size); | ||
100 | ls->ls_recover_nodeid = nodeid; | 115 | ls->ls_recover_nodeid = nodeid; |
101 | 116 | ||
102 | if (nodeid == dlm_our_nodeid()) { | 117 | if (nodeid == dlm_our_nodeid()) { |
@@ -108,12 +123,14 @@ int dlm_rcom_status(struct dlm_ls *ls, int nodeid) | |||
108 | error = create_rcom(ls, nodeid, DLM_RCOM_STATUS, 0, &rc, &mh); | 123 | error = create_rcom(ls, nodeid, DLM_RCOM_STATUS, 0, &rc, &mh); |
109 | if (error) | 124 | if (error) |
110 | goto out; | 125 | goto out; |
111 | rc->rc_id = ++ls->ls_rcom_seq; | 126 | |
127 | allow_sync_reply(ls, &rc->rc_id); | ||
128 | memset(ls->ls_recover_buf, 0, dlm_config.buffer_size); | ||
112 | 129 | ||
113 | send_rcom(ls, mh, rc); | 130 | send_rcom(ls, mh, rc); |
114 | 131 | ||
115 | error = dlm_wait_function(ls, &rcom_response); | 132 | error = dlm_wait_function(ls, &rcom_response); |
116 | clear_bit(LSFL_RCOM_READY, &ls->ls_flags); | 133 | disallow_sync_reply(ls); |
117 | if (error) | 134 | if (error) |
118 | goto out; | 135 | goto out; |
119 | 136 | ||
@@ -150,14 +167,21 @@ static void receive_rcom_status(struct dlm_ls *ls, struct dlm_rcom *rc_in) | |||
150 | 167 | ||
151 | static void receive_sync_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) | 168 | static void receive_sync_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) |
152 | { | 169 | { |
153 | if (rc_in->rc_id != ls->ls_rcom_seq) { | 170 | spin_lock(&ls->ls_rcom_spin); |
154 | log_debug(ls, "reject old reply %d got %llx wanted %llx", | 171 | if (!test_bit(LSFL_RCOM_WAIT, &ls->ls_flags) || |
155 | rc_in->rc_type, rc_in->rc_id, ls->ls_rcom_seq); | 172 | rc_in->rc_id != ls->ls_rcom_seq) { |
156 | return; | 173 | log_debug(ls, "reject reply %d from %d seq %llx expect %llx", |
174 | rc_in->rc_type, rc_in->rc_header.h_nodeid, | ||
175 | (unsigned long long)rc_in->rc_id, | ||
176 | (unsigned long long)ls->ls_rcom_seq); | ||
177 | goto out; | ||
157 | } | 178 | } |
158 | memcpy(ls->ls_recover_buf, rc_in, rc_in->rc_header.h_length); | 179 | memcpy(ls->ls_recover_buf, rc_in, rc_in->rc_header.h_length); |
159 | set_bit(LSFL_RCOM_READY, &ls->ls_flags); | 180 | set_bit(LSFL_RCOM_READY, &ls->ls_flags); |
181 | clear_bit(LSFL_RCOM_WAIT, &ls->ls_flags); | ||
160 | wake_up(&ls->ls_wait_general); | 182 | wake_up(&ls->ls_wait_general); |
183 | out: | ||
184 | spin_unlock(&ls->ls_rcom_spin); | ||
161 | } | 185 | } |
162 | 186 | ||
163 | static void receive_rcom_status_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) | 187 | static void receive_rcom_status_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) |
@@ -171,7 +195,6 @@ int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len) | |||
171 | struct dlm_mhandle *mh; | 195 | struct dlm_mhandle *mh; |
172 | int error = 0, len = sizeof(struct dlm_rcom); | 196 | int error = 0, len = sizeof(struct dlm_rcom); |
173 | 197 | ||
174 | memset(ls->ls_recover_buf, 0, dlm_config.buffer_size); | ||
175 | ls->ls_recover_nodeid = nodeid; | 198 | ls->ls_recover_nodeid = nodeid; |
176 | 199 | ||
177 | if (nodeid == dlm_our_nodeid()) { | 200 | if (nodeid == dlm_our_nodeid()) { |
@@ -185,12 +208,14 @@ int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len) | |||
185 | if (error) | 208 | if (error) |
186 | goto out; | 209 | goto out; |
187 | memcpy(rc->rc_buf, last_name, last_len); | 210 | memcpy(rc->rc_buf, last_name, last_len); |
188 | rc->rc_id = ++ls->ls_rcom_seq; | 211 | |
212 | allow_sync_reply(ls, &rc->rc_id); | ||
213 | memset(ls->ls_recover_buf, 0, dlm_config.buffer_size); | ||
189 | 214 | ||
190 | send_rcom(ls, mh, rc); | 215 | send_rcom(ls, mh, rc); |
191 | 216 | ||
192 | error = dlm_wait_function(ls, &rcom_response); | 217 | error = dlm_wait_function(ls, &rcom_response); |
193 | clear_bit(LSFL_RCOM_READY, &ls->ls_flags); | 218 | disallow_sync_reply(ls); |
194 | out: | 219 | out: |
195 | return error; | 220 | return error; |
196 | } | 221 | } |
@@ -370,9 +395,10 @@ static void receive_rcom_lock_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) | |||
370 | static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) | 395 | static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) |
371 | { | 396 | { |
372 | struct dlm_rcom *rc; | 397 | struct dlm_rcom *rc; |
398 | struct rcom_config *rf; | ||
373 | struct dlm_mhandle *mh; | 399 | struct dlm_mhandle *mh; |
374 | char *mb; | 400 | char *mb; |
375 | int mb_len = sizeof(struct dlm_rcom); | 401 | int mb_len = sizeof(struct dlm_rcom) + sizeof(struct rcom_config); |
376 | 402 | ||
377 | mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_KERNEL, &mb); | 403 | mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_KERNEL, &mb); |
378 | if (!mh) | 404 | if (!mh) |
@@ -391,6 +417,9 @@ static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) | |||
391 | rc->rc_id = rc_in->rc_id; | 417 | rc->rc_id = rc_in->rc_id; |
392 | rc->rc_result = -ESRCH; | 418 | rc->rc_result = -ESRCH; |
393 | 419 | ||
420 | rf = (struct rcom_config *) rc->rc_buf; | ||
421 | rf->rf_lvblen = -1; | ||
422 | |||
394 | dlm_rcom_out(rc); | 423 | dlm_rcom_out(rc); |
395 | dlm_lowcomms_commit_buffer(mh); | 424 | dlm_lowcomms_commit_buffer(mh); |
396 | 425 | ||
@@ -412,9 +441,10 @@ void dlm_receive_rcom(struct dlm_header *hd, int nodeid) | |||
412 | 441 | ||
413 | ls = dlm_find_lockspace_global(hd->h_lockspace); | 442 | ls = dlm_find_lockspace_global(hd->h_lockspace); |
414 | if (!ls) { | 443 | if (!ls) { |
415 | log_print("lockspace %x from %d not found", | 444 | log_print("lockspace %x from %d type %x not found", |
416 | hd->h_lockspace, nodeid); | 445 | hd->h_lockspace, nodeid, rc->rc_type); |
417 | send_ls_not_ready(nodeid, rc); | 446 | if (rc->rc_type == DLM_RCOM_STATUS) |
447 | send_ls_not_ready(nodeid, rc); | ||
418 | return; | 448 | return; |
419 | } | 449 | } |
420 | 450 | ||
diff --git a/fs/dlm/recover.c b/fs/dlm/recover.c index a5e6d184872e..cf9f6831bab5 100644 --- a/fs/dlm/recover.c +++ b/fs/dlm/recover.c | |||
@@ -252,6 +252,7 @@ static void recover_list_clear(struct dlm_ls *ls) | |||
252 | spin_lock(&ls->ls_recover_list_lock); | 252 | spin_lock(&ls->ls_recover_list_lock); |
253 | list_for_each_entry_safe(r, s, &ls->ls_recover_list, res_recover_list) { | 253 | list_for_each_entry_safe(r, s, &ls->ls_recover_list, res_recover_list) { |
254 | list_del_init(&r->res_recover_list); | 254 | list_del_init(&r->res_recover_list); |
255 | r->res_recover_locks_count = 0; | ||
255 | dlm_put_rsb(r); | 256 | dlm_put_rsb(r); |
256 | ls->ls_recover_list_count--; | 257 | ls->ls_recover_list_count--; |
257 | } | 258 | } |
diff --git a/fs/dlm/recoverd.c b/fs/dlm/recoverd.c index 362e3eff4dc9..650536aa5139 100644 --- a/fs/dlm/recoverd.c +++ b/fs/dlm/recoverd.c | |||
@@ -45,7 +45,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
45 | unsigned long start; | 45 | unsigned long start; |
46 | int error, neg = 0; | 46 | int error, neg = 0; |
47 | 47 | ||
48 | log_debug(ls, "recover %llx", rv->seq); | 48 | log_debug(ls, "recover %llx", (unsigned long long)rv->seq); |
49 | 49 | ||
50 | mutex_lock(&ls->ls_recoverd_active); | 50 | mutex_lock(&ls->ls_recoverd_active); |
51 | 51 | ||
@@ -94,14 +94,6 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
94 | } | 94 | } |
95 | 95 | ||
96 | /* | 96 | /* |
97 | * Purge directory-related requests that are saved in requestqueue. | ||
98 | * All dir requests from before recovery are invalid now due to the dir | ||
99 | * rebuild and will be resent by the requesting nodes. | ||
100 | */ | ||
101 | |||
102 | dlm_purge_requestqueue(ls); | ||
103 | |||
104 | /* | ||
105 | * Wait for all nodes to complete directory rebuild. | 97 | * Wait for all nodes to complete directory rebuild. |
106 | */ | 98 | */ |
107 | 99 | ||
@@ -164,10 +156,31 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
164 | */ | 156 | */ |
165 | 157 | ||
166 | dlm_recover_rsbs(ls); | 158 | dlm_recover_rsbs(ls); |
159 | } else { | ||
160 | /* | ||
161 | * Other lockspace members may be going through the "neg" steps | ||
162 | * while also adding us to the lockspace, in which case they'll | ||
163 | * be doing the recover_locks (RS_LOCKS) barrier. | ||
164 | */ | ||
165 | dlm_set_recover_status(ls, DLM_RS_LOCKS); | ||
166 | |||
167 | error = dlm_recover_locks_wait(ls); | ||
168 | if (error) { | ||
169 | log_error(ls, "recover_locks_wait failed %d", error); | ||
170 | goto fail; | ||
171 | } | ||
167 | } | 172 | } |
168 | 173 | ||
169 | dlm_release_root_list(ls); | 174 | dlm_release_root_list(ls); |
170 | 175 | ||
176 | /* | ||
177 | * Purge directory-related requests that are saved in requestqueue. | ||
178 | * All dir requests from before recovery are invalid now due to the dir | ||
179 | * rebuild and will be resent by the requesting nodes. | ||
180 | */ | ||
181 | |||
182 | dlm_purge_requestqueue(ls); | ||
183 | |||
171 | dlm_set_recover_status(ls, DLM_RS_DONE); | 184 | dlm_set_recover_status(ls, DLM_RS_DONE); |
172 | error = dlm_recover_done_wait(ls); | 185 | error = dlm_recover_done_wait(ls); |
173 | if (error) { | 186 | if (error) { |
@@ -199,7 +212,8 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
199 | 212 | ||
200 | dlm_astd_wake(); | 213 | dlm_astd_wake(); |
201 | 214 | ||
202 | log_debug(ls, "recover %llx done: %u ms", rv->seq, | 215 | log_debug(ls, "recover %llx done: %u ms", |
216 | (unsigned long long)rv->seq, | ||
203 | jiffies_to_msecs(jiffies - start)); | 217 | jiffies_to_msecs(jiffies - start)); |
204 | mutex_unlock(&ls->ls_recoverd_active); | 218 | mutex_unlock(&ls->ls_recoverd_active); |
205 | 219 | ||
@@ -207,11 +221,16 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
207 | 221 | ||
208 | fail: | 222 | fail: |
209 | dlm_release_root_list(ls); | 223 | dlm_release_root_list(ls); |
210 | log_debug(ls, "recover %llx error %d", rv->seq, error); | 224 | log_debug(ls, "recover %llx error %d", |
225 | (unsigned long long)rv->seq, error); | ||
211 | mutex_unlock(&ls->ls_recoverd_active); | 226 | mutex_unlock(&ls->ls_recoverd_active); |
212 | return error; | 227 | return error; |
213 | } | 228 | } |
214 | 229 | ||
230 | /* The dlm_ls_start() that created the rv we take here may already have been | ||
231 | stopped via dlm_ls_stop(); in that case we need to leave the RECOVERY_STOP | ||
232 | flag set. */ | ||
233 | |||
215 | static void do_ls_recovery(struct dlm_ls *ls) | 234 | static void do_ls_recovery(struct dlm_ls *ls) |
216 | { | 235 | { |
217 | struct dlm_recover *rv = NULL; | 236 | struct dlm_recover *rv = NULL; |
@@ -219,7 +238,8 @@ static void do_ls_recovery(struct dlm_ls *ls) | |||
219 | spin_lock(&ls->ls_recover_lock); | 238 | spin_lock(&ls->ls_recover_lock); |
220 | rv = ls->ls_recover_args; | 239 | rv = ls->ls_recover_args; |
221 | ls->ls_recover_args = NULL; | 240 | ls->ls_recover_args = NULL; |
222 | clear_bit(LSFL_RECOVERY_STOP, &ls->ls_flags); | 241 | if (rv && ls->ls_recover_seq == rv->seq) |
242 | clear_bit(LSFL_RECOVERY_STOP, &ls->ls_flags); | ||
223 | spin_unlock(&ls->ls_recover_lock); | 243 | spin_unlock(&ls->ls_recover_lock); |
224 | 244 | ||
225 | if (rv) { | 245 | if (rv) { |
diff --git a/fs/dlm/requestqueue.c b/fs/dlm/requestqueue.c index 7b2b089634a2..65008d79c96d 100644 --- a/fs/dlm/requestqueue.c +++ b/fs/dlm/requestqueue.c | |||
@@ -30,26 +30,36 @@ struct rq_entry { | |||
30 | * lockspace is enabled on some while still suspended on others. | 30 | * lockspace is enabled on some while still suspended on others. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd) | 33 | int dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd) |
34 | { | 34 | { |
35 | struct rq_entry *e; | 35 | struct rq_entry *e; |
36 | int length = hd->h_length; | 36 | int length = hd->h_length; |
37 | 37 | int rv = 0; | |
38 | if (dlm_is_removed(ls, nodeid)) | ||
39 | return; | ||
40 | 38 | ||
41 | e = kmalloc(sizeof(struct rq_entry) + length, GFP_KERNEL); | 39 | e = kmalloc(sizeof(struct rq_entry) + length, GFP_KERNEL); |
42 | if (!e) { | 40 | if (!e) { |
43 | log_print("dlm_add_requestqueue: out of memory\n"); | 41 | log_print("dlm_add_requestqueue: out of memory\n"); |
44 | return; | 42 | return 0; |
45 | } | 43 | } |
46 | 44 | ||
47 | e->nodeid = nodeid; | 45 | e->nodeid = nodeid; |
48 | memcpy(e->request, hd, length); | 46 | memcpy(e->request, hd, length); |
49 | 47 | ||
48 | /* We need to check dlm_locking_stopped() after taking the mutex to | ||
49 | avoid a race where dlm_recoverd enables locking and runs | ||
50 | process_requestqueue between our earlier dlm_locking_stopped check | ||
51 | and this addition to the requestqueue. */ | ||
52 | |||
50 | mutex_lock(&ls->ls_requestqueue_mutex); | 53 | mutex_lock(&ls->ls_requestqueue_mutex); |
51 | list_add_tail(&e->list, &ls->ls_requestqueue); | 54 | if (dlm_locking_stopped(ls)) |
55 | list_add_tail(&e->list, &ls->ls_requestqueue); | ||
56 | else { | ||
57 | log_debug(ls, "dlm_add_requestqueue skip from %d", nodeid); | ||
58 | kfree(e); | ||
59 | rv = -EAGAIN; | ||
60 | } | ||
52 | mutex_unlock(&ls->ls_requestqueue_mutex); | 61 | mutex_unlock(&ls->ls_requestqueue_mutex); |
62 | return rv; | ||
53 | } | 63 | } |
54 | 64 | ||
55 | int dlm_process_requestqueue(struct dlm_ls *ls) | 65 | int dlm_process_requestqueue(struct dlm_ls *ls) |
@@ -120,6 +130,10 @@ static int purge_request(struct dlm_ls *ls, struct dlm_message *ms, int nodeid) | |||
120 | { | 130 | { |
121 | uint32_t type = ms->m_type; | 131 | uint32_t type = ms->m_type; |
122 | 132 | ||
133 | /* the ls is being cleaned up and freed by release_lockspace */ | ||
134 | if (!ls->ls_count) | ||
135 | return 1; | ||
136 | |||
123 | if (dlm_is_removed(ls, nodeid)) | 137 | if (dlm_is_removed(ls, nodeid)) |
124 | return 1; | 138 | return 1; |
125 | 139 | ||
diff --git a/fs/dlm/requestqueue.h b/fs/dlm/requestqueue.h index 349f0d292d95..6a53ea03335d 100644 --- a/fs/dlm/requestqueue.h +++ b/fs/dlm/requestqueue.h | |||
@@ -13,7 +13,7 @@ | |||
13 | #ifndef __REQUESTQUEUE_DOT_H__ | 13 | #ifndef __REQUESTQUEUE_DOT_H__ |
14 | #define __REQUESTQUEUE_DOT_H__ | 14 | #define __REQUESTQUEUE_DOT_H__ |
15 | 15 | ||
16 | void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd); | 16 | int dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd); |
17 | int dlm_process_requestqueue(struct dlm_ls *ls); | 17 | int dlm_process_requestqueue(struct dlm_ls *ls); |
18 | void dlm_wait_requestqueue(struct dlm_ls *ls); | 18 | void dlm_wait_requestqueue(struct dlm_ls *ls); |
19 | void dlm_purge_requestqueue(struct dlm_ls *ls); | 19 | void dlm_purge_requestqueue(struct dlm_ls *ls); |
diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig index 8c27de8b9568..c0791cbacad9 100644 --- a/fs/gfs2/Kconfig +++ b/fs/gfs2/Kconfig | |||
@@ -2,6 +2,7 @@ config GFS2_FS | |||
2 | tristate "GFS2 file system support" | 2 | tristate "GFS2 file system support" |
3 | depends on EXPERIMENTAL | 3 | depends on EXPERIMENTAL |
4 | select FS_POSIX_ACL | 4 | select FS_POSIX_ACL |
5 | select CRC32 | ||
5 | help | 6 | help |
6 | A cluster filesystem. | 7 | A cluster filesystem. |
7 | 8 | ||
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 5f959b8ce406..6e80844367ee 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
@@ -74,11 +74,11 @@ int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access) | |||
74 | { | 74 | { |
75 | if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl) | 75 | if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl) |
76 | return -EOPNOTSUPP; | 76 | return -EOPNOTSUPP; |
77 | if (current->fsuid != ip->i_di.di_uid && !capable(CAP_FOWNER)) | 77 | if (current->fsuid != ip->i_inode.i_uid && !capable(CAP_FOWNER)) |
78 | return -EPERM; | 78 | return -EPERM; |
79 | if (S_ISLNK(ip->i_di.di_mode)) | 79 | if (S_ISLNK(ip->i_inode.i_mode)) |
80 | return -EOPNOTSUPP; | 80 | return -EOPNOTSUPP; |
81 | if (!access && !S_ISDIR(ip->i_di.di_mode)) | 81 | if (!access && !S_ISDIR(ip->i_inode.i_mode)) |
82 | return -EACCES; | 82 | return -EACCES; |
83 | 83 | ||
84 | return 0; | 84 | return 0; |
@@ -145,14 +145,14 @@ out: | |||
145 | } | 145 | } |
146 | 146 | ||
147 | /** | 147 | /** |
148 | * gfs2_check_acl_locked - Check an ACL to see if we're allowed to do something | 148 | * gfs2_check_acl - Check an ACL to see if we're allowed to do something |
149 | * @inode: the file we want to do something to | 149 | * @inode: the file we want to do something to |
150 | * @mask: what we want to do | 150 | * @mask: what we want to do |
151 | * | 151 | * |
152 | * Returns: errno | 152 | * Returns: errno |
153 | */ | 153 | */ |
154 | 154 | ||
155 | int gfs2_check_acl_locked(struct inode *inode, int mask) | 155 | int gfs2_check_acl(struct inode *inode, int mask) |
156 | { | 156 | { |
157 | struct posix_acl *acl = NULL; | 157 | struct posix_acl *acl = NULL; |
158 | int error; | 158 | int error; |
@@ -170,21 +170,6 @@ int gfs2_check_acl_locked(struct inode *inode, int mask) | |||
170 | return -EAGAIN; | 170 | return -EAGAIN; |
171 | } | 171 | } |
172 | 172 | ||
173 | int gfs2_check_acl(struct inode *inode, int mask) | ||
174 | { | ||
175 | struct gfs2_inode *ip = GFS2_I(inode); | ||
176 | struct gfs2_holder i_gh; | ||
177 | int error; | ||
178 | |||
179 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | ||
180 | if (!error) { | ||
181 | error = gfs2_check_acl_locked(inode, mask); | ||
182 | gfs2_glock_dq_uninit(&i_gh); | ||
183 | } | ||
184 | |||
185 | return error; | ||
186 | } | ||
187 | |||
188 | static int munge_mode(struct gfs2_inode *ip, mode_t mode) | 173 | static int munge_mode(struct gfs2_inode *ip, mode_t mode) |
189 | { | 174 | { |
190 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 175 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
@@ -198,10 +183,10 @@ static int munge_mode(struct gfs2_inode *ip, mode_t mode) | |||
198 | error = gfs2_meta_inode_buffer(ip, &dibh); | 183 | error = gfs2_meta_inode_buffer(ip, &dibh); |
199 | if (!error) { | 184 | if (!error) { |
200 | gfs2_assert_withdraw(sdp, | 185 | gfs2_assert_withdraw(sdp, |
201 | (ip->i_di.di_mode & S_IFMT) == (mode & S_IFMT)); | 186 | (ip->i_inode.i_mode & S_IFMT) == (mode & S_IFMT)); |
202 | ip->i_di.di_mode = mode; | 187 | ip->i_inode.i_mode = mode; |
203 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 188 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
204 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 189 | gfs2_dinode_out(ip, dibh->b_data); |
205 | brelse(dibh); | 190 | brelse(dibh); |
206 | } | 191 | } |
207 | 192 | ||
@@ -215,12 +200,12 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
215 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 200 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
216 | struct posix_acl *acl = NULL, *clone; | 201 | struct posix_acl *acl = NULL, *clone; |
217 | struct gfs2_ea_request er; | 202 | struct gfs2_ea_request er; |
218 | mode_t mode = ip->i_di.di_mode; | 203 | mode_t mode = ip->i_inode.i_mode; |
219 | int error; | 204 | int error; |
220 | 205 | ||
221 | if (!sdp->sd_args.ar_posix_acl) | 206 | if (!sdp->sd_args.ar_posix_acl) |
222 | return 0; | 207 | return 0; |
223 | if (S_ISLNK(ip->i_di.di_mode)) | 208 | if (S_ISLNK(ip->i_inode.i_mode)) |
224 | return 0; | 209 | return 0; |
225 | 210 | ||
226 | memset(&er, 0, sizeof(struct gfs2_ea_request)); | 211 | memset(&er, 0, sizeof(struct gfs2_ea_request)); |
@@ -232,7 +217,7 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
232 | return error; | 217 | return error; |
233 | if (!acl) { | 218 | if (!acl) { |
234 | mode &= ~current->fs->umask; | 219 | mode &= ~current->fs->umask; |
235 | if (mode != ip->i_di.di_mode) | 220 | if (mode != ip->i_inode.i_mode) |
236 | error = munge_mode(ip, mode); | 221 | error = munge_mode(ip, mode); |
237 | return error; | 222 | return error; |
238 | } | 223 | } |
@@ -244,7 +229,7 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
244 | posix_acl_release(acl); | 229 | posix_acl_release(acl); |
245 | acl = clone; | 230 | acl = clone; |
246 | 231 | ||
247 | if (S_ISDIR(ip->i_di.di_mode)) { | 232 | if (S_ISDIR(ip->i_inode.i_mode)) { |
248 | er.er_name = GFS2_POSIX_ACL_DEFAULT; | 233 | er.er_name = GFS2_POSIX_ACL_DEFAULT; |
249 | er.er_name_len = GFS2_POSIX_ACL_DEFAULT_LEN; | 234 | er.er_name_len = GFS2_POSIX_ACL_DEFAULT_LEN; |
250 | error = gfs2_system_eaops.eo_set(ip, &er); | 235 | error = gfs2_system_eaops.eo_set(ip, &er); |
diff --git a/fs/gfs2/acl.h b/fs/gfs2/acl.h index 05c294fe0d78..6751930bfb64 100644 --- a/fs/gfs2/acl.h +++ b/fs/gfs2/acl.h | |||
@@ -31,7 +31,6 @@ int gfs2_acl_validate_set(struct gfs2_inode *ip, int access, | |||
31 | struct gfs2_ea_request *er, | 31 | struct gfs2_ea_request *er, |
32 | int *remove, mode_t *mode); | 32 | int *remove, mode_t *mode); |
33 | int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access); | 33 | int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access); |
34 | int gfs2_check_acl_locked(struct inode *inode, int mask); | ||
35 | int gfs2_check_acl(struct inode *inode, int mask); | 34 | int gfs2_check_acl(struct inode *inode, int mask); |
36 | int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip); | 35 | int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip); |
37 | int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); | 36 | int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 06e9a8cb45e9..8240c1ff94f4 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -38,8 +38,8 @@ struct metapath { | |||
38 | }; | 38 | }; |
39 | 39 | ||
40 | typedef int (*block_call_t) (struct gfs2_inode *ip, struct buffer_head *dibh, | 40 | typedef int (*block_call_t) (struct gfs2_inode *ip, struct buffer_head *dibh, |
41 | struct buffer_head *bh, u64 *top, | 41 | struct buffer_head *bh, __be64 *top, |
42 | u64 *bottom, unsigned int height, | 42 | __be64 *bottom, unsigned int height, |
43 | void *data); | 43 | void *data); |
44 | 44 | ||
45 | struct strip_mine { | 45 | struct strip_mine { |
@@ -163,6 +163,7 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page) | |||
163 | if (ip->i_di.di_size) { | 163 | if (ip->i_di.di_size) { |
164 | *(__be64 *)(di + 1) = cpu_to_be64(block); | 164 | *(__be64 *)(di + 1) = cpu_to_be64(block); |
165 | ip->i_di.di_blocks++; | 165 | ip->i_di.di_blocks++; |
166 | gfs2_set_inode_blocks(&ip->i_inode); | ||
166 | di->di_blocks = cpu_to_be64(ip->i_di.di_blocks); | 167 | di->di_blocks = cpu_to_be64(ip->i_di.di_blocks); |
167 | } | 168 | } |
168 | 169 | ||
@@ -230,7 +231,7 @@ static int build_height(struct inode *inode, unsigned height) | |||
230 | struct buffer_head *blocks[GFS2_MAX_META_HEIGHT]; | 231 | struct buffer_head *blocks[GFS2_MAX_META_HEIGHT]; |
231 | struct gfs2_dinode *di; | 232 | struct gfs2_dinode *di; |
232 | int error; | 233 | int error; |
233 | u64 *bp; | 234 | __be64 *bp; |
234 | u64 bn; | 235 | u64 bn; |
235 | unsigned n; | 236 | unsigned n; |
236 | 237 | ||
@@ -255,7 +256,7 @@ static int build_height(struct inode *inode, unsigned height) | |||
255 | GFS2_FORMAT_IN); | 256 | GFS2_FORMAT_IN); |
256 | gfs2_buffer_clear_tail(blocks[n], | 257 | gfs2_buffer_clear_tail(blocks[n], |
257 | sizeof(struct gfs2_meta_header)); | 258 | sizeof(struct gfs2_meta_header)); |
258 | bp = (u64 *)(blocks[n]->b_data + | 259 | bp = (__be64 *)(blocks[n]->b_data + |
259 | sizeof(struct gfs2_meta_header)); | 260 | sizeof(struct gfs2_meta_header)); |
260 | *bp = cpu_to_be64(blocks[n+1]->b_blocknr); | 261 | *bp = cpu_to_be64(blocks[n+1]->b_blocknr); |
261 | brelse(blocks[n]); | 262 | brelse(blocks[n]); |
@@ -272,6 +273,7 @@ static int build_height(struct inode *inode, unsigned height) | |||
272 | *(__be64 *)(di + 1) = cpu_to_be64(bn); | 273 | *(__be64 *)(di + 1) = cpu_to_be64(bn); |
273 | ip->i_di.di_height += new_height; | 274 | ip->i_di.di_height += new_height; |
274 | ip->i_di.di_blocks += new_height; | 275 | ip->i_di.di_blocks += new_height; |
276 | gfs2_set_inode_blocks(&ip->i_inode); | ||
275 | di->di_height = cpu_to_be16(ip->i_di.di_height); | 277 | di->di_height = cpu_to_be16(ip->i_di.di_height); |
276 | di->di_blocks = cpu_to_be64(ip->i_di.di_blocks); | 278 | di->di_blocks = cpu_to_be64(ip->i_di.di_blocks); |
277 | brelse(dibh); | 279 | brelse(dibh); |
@@ -360,15 +362,15 @@ static void find_metapath(struct gfs2_inode *ip, u64 block, | |||
360 | * metadata tree. | 362 | * metadata tree. |
361 | */ | 363 | */ |
362 | 364 | ||
363 | static inline u64 *metapointer(struct buffer_head *bh, int *boundary, | 365 | static inline __be64 *metapointer(struct buffer_head *bh, int *boundary, |
364 | unsigned int height, const struct metapath *mp) | 366 | unsigned int height, const struct metapath *mp) |
365 | { | 367 | { |
366 | unsigned int head_size = (height > 0) ? | 368 | unsigned int head_size = (height > 0) ? |
367 | sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_dinode); | 369 | sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_dinode); |
368 | u64 *ptr; | 370 | __be64 *ptr; |
369 | *boundary = 0; | 371 | *boundary = 0; |
370 | ptr = ((u64 *)(bh->b_data + head_size)) + mp->mp_list[height]; | 372 | ptr = ((__be64 *)(bh->b_data + head_size)) + mp->mp_list[height]; |
371 | if (ptr + 1 == (u64 *)(bh->b_data + bh->b_size)) | 373 | if (ptr + 1 == (__be64 *)(bh->b_data + bh->b_size)) |
372 | *boundary = 1; | 374 | *boundary = 1; |
373 | return ptr; | 375 | return ptr; |
374 | } | 376 | } |
@@ -394,7 +396,7 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, | |||
394 | int *new, u64 *block) | 396 | int *new, u64 *block) |
395 | { | 397 | { |
396 | int boundary; | 398 | int boundary; |
397 | u64 *ptr = metapointer(bh, &boundary, height, mp); | 399 | __be64 *ptr = metapointer(bh, &boundary, height, mp); |
398 | 400 | ||
399 | if (*ptr) { | 401 | if (*ptr) { |
400 | *block = be64_to_cpu(*ptr); | 402 | *block = be64_to_cpu(*ptr); |
@@ -415,17 +417,35 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, | |||
415 | 417 | ||
416 | *ptr = cpu_to_be64(*block); | 418 | *ptr = cpu_to_be64(*block); |
417 | ip->i_di.di_blocks++; | 419 | ip->i_di.di_blocks++; |
420 | gfs2_set_inode_blocks(&ip->i_inode); | ||
418 | 421 | ||
419 | *new = 1; | 422 | *new = 1; |
420 | return 0; | 423 | return 0; |
421 | } | 424 | } |
422 | 425 | ||
426 | static inline void bmap_lock(struct inode *inode, int create) | ||
427 | { | ||
428 | struct gfs2_inode *ip = GFS2_I(inode); | ||
429 | if (create) | ||
430 | down_write(&ip->i_rw_mutex); | ||
431 | else | ||
432 | down_read(&ip->i_rw_mutex); | ||
433 | } | ||
434 | |||
435 | static inline void bmap_unlock(struct inode *inode, int create) | ||
436 | { | ||
437 | struct gfs2_inode *ip = GFS2_I(inode); | ||
438 | if (create) | ||
439 | up_write(&ip->i_rw_mutex); | ||
440 | else | ||
441 | up_read(&ip->i_rw_mutex); | ||
442 | } | ||
443 | |||
423 | /** | 444 | /** |
424 | * gfs2_block_pointers - Map a block from an inode to a disk block | 445 | * gfs2_block_map - Map a block from an inode to a disk block |
425 | * @inode: The inode | 446 | * @inode: The inode |
426 | * @lblock: The logical block number | 447 | * @lblock: The logical block number |
427 | * @map_bh: The bh to be mapped | 448 | * @bh_map: The bh to be mapped |
428 | * @mp: metapath to use | ||
429 | * | 449 | * |
430 | * Find the block number on the current device which corresponds to an | 450 | * Find the block number on the current device which corresponds to an |
431 | * inode's block. If the block had to be created, "new" will be set. | 451 | * inode's block. If the block had to be created, "new" will be set. |
@@ -433,8 +453,8 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, | |||
433 | * Returns: errno | 453 | * Returns: errno |
434 | */ | 454 | */ |
435 | 455 | ||
436 | static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, | 456 | int gfs2_block_map(struct inode *inode, u64 lblock, int create, |
437 | struct buffer_head *bh_map, struct metapath *mp) | 457 | struct buffer_head *bh_map) |
438 | { | 458 | { |
439 | struct gfs2_inode *ip = GFS2_I(inode); | 459 | struct gfs2_inode *ip = GFS2_I(inode); |
440 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 460 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
@@ -448,57 +468,61 @@ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, | |||
448 | u64 dblock = 0; | 468 | u64 dblock = 0; |
449 | int boundary; | 469 | int boundary; |
450 | unsigned int maxlen = bh_map->b_size >> inode->i_blkbits; | 470 | unsigned int maxlen = bh_map->b_size >> inode->i_blkbits; |
471 | struct metapath mp; | ||
472 | u64 size; | ||
451 | 473 | ||
452 | BUG_ON(maxlen == 0); | 474 | BUG_ON(maxlen == 0); |
453 | 475 | ||
454 | if (gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip))) | 476 | if (gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip))) |
455 | return 0; | 477 | return 0; |
456 | 478 | ||
479 | bmap_lock(inode, create); | ||
480 | clear_buffer_mapped(bh_map); | ||
481 | clear_buffer_new(bh_map); | ||
482 | clear_buffer_boundary(bh_map); | ||
457 | bsize = gfs2_is_dir(ip) ? sdp->sd_jbsize : sdp->sd_sb.sb_bsize; | 483 | bsize = gfs2_is_dir(ip) ? sdp->sd_jbsize : sdp->sd_sb.sb_bsize; |
458 | 484 | size = (lblock + 1) * bsize; | |
459 | height = calc_tree_height(ip, (lblock + 1) * bsize); | 485 | |
460 | if (ip->i_di.di_height < height) { | 486 | if (size > ip->i_di.di_size) { |
461 | if (!create) | 487 | height = calc_tree_height(ip, size); |
462 | return 0; | 488 | if (ip->i_di.di_height < height) { |
463 | 489 | if (!create) | |
464 | error = build_height(inode, height); | 490 | goto out_ok; |
465 | if (error) | 491 | |
466 | return error; | 492 | error = build_height(inode, height); |
493 | if (error) | ||
494 | goto out_fail; | ||
495 | } | ||
467 | } | 496 | } |
468 | 497 | ||
469 | find_metapath(ip, lblock, mp); | 498 | find_metapath(ip, lblock, &mp); |
470 | end_of_metadata = ip->i_di.di_height - 1; | 499 | end_of_metadata = ip->i_di.di_height - 1; |
471 | |||
472 | error = gfs2_meta_inode_buffer(ip, &bh); | 500 | error = gfs2_meta_inode_buffer(ip, &bh); |
473 | if (error) | 501 | if (error) |
474 | return error; | 502 | goto out_fail; |
475 | 503 | ||
476 | for (x = 0; x < end_of_metadata; x++) { | 504 | for (x = 0; x < end_of_metadata; x++) { |
477 | lookup_block(ip, bh, x, mp, create, &new, &dblock); | 505 | lookup_block(ip, bh, x, &mp, create, &new, &dblock); |
478 | brelse(bh); | 506 | brelse(bh); |
479 | if (!dblock) | 507 | if (!dblock) |
480 | return 0; | 508 | goto out_ok; |
481 | 509 | ||
482 | error = gfs2_meta_indirect_buffer(ip, x+1, dblock, new, &bh); | 510 | error = gfs2_meta_indirect_buffer(ip, x+1, dblock, new, &bh); |
483 | if (error) | 511 | if (error) |
484 | return error; | 512 | goto out_fail; |
485 | } | 513 | } |
486 | 514 | ||
487 | boundary = lookup_block(ip, bh, end_of_metadata, mp, create, &new, &dblock); | 515 | boundary = lookup_block(ip, bh, end_of_metadata, &mp, create, &new, &dblock); |
488 | clear_buffer_mapped(bh_map); | ||
489 | clear_buffer_new(bh_map); | ||
490 | clear_buffer_boundary(bh_map); | ||
491 | |||
492 | if (dblock) { | 516 | if (dblock) { |
493 | map_bh(bh_map, inode->i_sb, dblock); | 517 | map_bh(bh_map, inode->i_sb, dblock); |
494 | if (boundary) | 518 | if (boundary) |
495 | set_buffer_boundary(bh); | 519 | set_buffer_boundary(bh_map); |
496 | if (new) { | 520 | if (new) { |
497 | struct buffer_head *dibh; | 521 | struct buffer_head *dibh; |
498 | error = gfs2_meta_inode_buffer(ip, &dibh); | 522 | error = gfs2_meta_inode_buffer(ip, &dibh); |
499 | if (!error) { | 523 | if (!error) { |
500 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 524 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
501 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 525 | gfs2_dinode_out(ip, dibh->b_data); |
502 | brelse(dibh); | 526 | brelse(dibh); |
503 | } | 527 | } |
504 | set_buffer_new(bh_map); | 528 | set_buffer_new(bh_map); |
@@ -507,8 +531,8 @@ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, | |||
507 | while(--maxlen && !buffer_boundary(bh_map)) { | 531 | while(--maxlen && !buffer_boundary(bh_map)) { |
508 | u64 eblock; | 532 | u64 eblock; |
509 | 533 | ||
510 | mp->mp_list[end_of_metadata]++; | 534 | mp.mp_list[end_of_metadata]++; |
511 | boundary = lookup_block(ip, bh, end_of_metadata, mp, 0, &new, &eblock); | 535 | boundary = lookup_block(ip, bh, end_of_metadata, &mp, 0, &new, &eblock); |
512 | if (eblock != ++dblock) | 536 | if (eblock != ++dblock) |
513 | break; | 537 | break; |
514 | bh_map->b_size += (1 << inode->i_blkbits); | 538 | bh_map->b_size += (1 << inode->i_blkbits); |
@@ -518,43 +542,15 @@ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, | |||
518 | } | 542 | } |
519 | out_brelse: | 543 | out_brelse: |
520 | brelse(bh); | 544 | brelse(bh); |
521 | return 0; | 545 | out_ok: |
522 | } | 546 | error = 0; |
523 | 547 | out_fail: | |
524 | |||
525 | static inline void bmap_lock(struct inode *inode, int create) | ||
526 | { | ||
527 | struct gfs2_inode *ip = GFS2_I(inode); | ||
528 | if (create) | ||
529 | down_write(&ip->i_rw_mutex); | ||
530 | else | ||
531 | down_read(&ip->i_rw_mutex); | ||
532 | } | ||
533 | |||
534 | static inline void bmap_unlock(struct inode *inode, int create) | ||
535 | { | ||
536 | struct gfs2_inode *ip = GFS2_I(inode); | ||
537 | if (create) | ||
538 | up_write(&ip->i_rw_mutex); | ||
539 | else | ||
540 | up_read(&ip->i_rw_mutex); | ||
541 | } | ||
542 | |||
543 | int gfs2_block_map(struct inode *inode, u64 lblock, int create, | ||
544 | struct buffer_head *bh) | ||
545 | { | ||
546 | struct metapath mp; | ||
547 | int ret; | ||
548 | |||
549 | bmap_lock(inode, create); | ||
550 | ret = gfs2_block_pointers(inode, lblock, create, bh, &mp); | ||
551 | bmap_unlock(inode, create); | 548 | bmap_unlock(inode, create); |
552 | return ret; | 549 | return error; |
553 | } | 550 | } |
554 | 551 | ||
555 | int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen) | 552 | int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen) |
556 | { | 553 | { |
557 | struct metapath mp; | ||
558 | struct buffer_head bh = { .b_state = 0, .b_blocknr = 0 }; | 554 | struct buffer_head bh = { .b_state = 0, .b_blocknr = 0 }; |
559 | int ret; | 555 | int ret; |
560 | int create = *new; | 556 | int create = *new; |
@@ -564,9 +560,7 @@ int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsi | |||
564 | BUG_ON(!new); | 560 | BUG_ON(!new); |
565 | 561 | ||
566 | bh.b_size = 1 << (inode->i_blkbits + 5); | 562 | bh.b_size = 1 << (inode->i_blkbits + 5); |
567 | bmap_lock(inode, create); | 563 | ret = gfs2_block_map(inode, lblock, create, &bh); |
568 | ret = gfs2_block_pointers(inode, lblock, create, &bh, &mp); | ||
569 | bmap_unlock(inode, create); | ||
570 | *extlen = bh.b_size >> inode->i_blkbits; | 564 | *extlen = bh.b_size >> inode->i_blkbits; |
571 | *dblock = bh.b_blocknr; | 565 | *dblock = bh.b_blocknr; |
572 | if (buffer_new(&bh)) | 566 | if (buffer_new(&bh)) |
@@ -600,7 +594,7 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
600 | { | 594 | { |
601 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 595 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
602 | struct buffer_head *bh = NULL; | 596 | struct buffer_head *bh = NULL; |
603 | u64 *top, *bottom; | 597 | __be64 *top, *bottom; |
604 | u64 bn; | 598 | u64 bn; |
605 | int error; | 599 | int error; |
606 | int mh_size = sizeof(struct gfs2_meta_header); | 600 | int mh_size = sizeof(struct gfs2_meta_header); |
@@ -611,17 +605,17 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
611 | return error; | 605 | return error; |
612 | dibh = bh; | 606 | dibh = bh; |
613 | 607 | ||
614 | top = (u64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + mp->mp_list[0]; | 608 | top = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + mp->mp_list[0]; |
615 | bottom = (u64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + sdp->sd_diptrs; | 609 | bottom = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + sdp->sd_diptrs; |
616 | } else { | 610 | } else { |
617 | error = gfs2_meta_indirect_buffer(ip, height, block, 0, &bh); | 611 | error = gfs2_meta_indirect_buffer(ip, height, block, 0, &bh); |
618 | if (error) | 612 | if (error) |
619 | return error; | 613 | return error; |
620 | 614 | ||
621 | top = (u64 *)(bh->b_data + mh_size) + | 615 | top = (__be64 *)(bh->b_data + mh_size) + |
622 | (first ? mp->mp_list[height] : 0); | 616 | (first ? mp->mp_list[height] : 0); |
623 | 617 | ||
624 | bottom = (u64 *)(bh->b_data + mh_size) + sdp->sd_inptrs; | 618 | bottom = (__be64 *)(bh->b_data + mh_size) + sdp->sd_inptrs; |
625 | } | 619 | } |
626 | 620 | ||
627 | error = bc(ip, dibh, bh, top, bottom, height, data); | 621 | error = bc(ip, dibh, bh, top, bottom, height, data); |
@@ -660,7 +654,7 @@ out: | |||
660 | */ | 654 | */ |
661 | 655 | ||
662 | static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | 656 | static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, |
663 | struct buffer_head *bh, u64 *top, u64 *bottom, | 657 | struct buffer_head *bh, __be64 *top, __be64 *bottom, |
664 | unsigned int height, void *data) | 658 | unsigned int height, void *data) |
665 | { | 659 | { |
666 | struct strip_mine *sm = data; | 660 | struct strip_mine *sm = data; |
@@ -668,7 +662,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
668 | struct gfs2_rgrp_list rlist; | 662 | struct gfs2_rgrp_list rlist; |
669 | u64 bn, bstart; | 663 | u64 bn, bstart; |
670 | u32 blen; | 664 | u32 blen; |
671 | u64 *p; | 665 | __be64 *p; |
672 | unsigned int rg_blocks = 0; | 666 | unsigned int rg_blocks = 0; |
673 | int metadata; | 667 | int metadata; |
674 | unsigned int revokes = 0; | 668 | unsigned int revokes = 0; |
@@ -770,6 +764,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
770 | if (!ip->i_di.di_blocks) | 764 | if (!ip->i_di.di_blocks) |
771 | gfs2_consist_inode(ip); | 765 | gfs2_consist_inode(ip); |
772 | ip->i_di.di_blocks--; | 766 | ip->i_di.di_blocks--; |
767 | gfs2_set_inode_blocks(&ip->i_inode); | ||
773 | } | 768 | } |
774 | if (bstart) { | 769 | if (bstart) { |
775 | if (metadata) | 770 | if (metadata) |
@@ -778,9 +773,9 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
778 | gfs2_free_data(ip, bstart, blen); | 773 | gfs2_free_data(ip, bstart, blen); |
779 | } | 774 | } |
780 | 775 | ||
781 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 776 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
782 | 777 | ||
783 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 778 | gfs2_dinode_out(ip, dibh->b_data); |
784 | 779 | ||
785 | up_write(&ip->i_rw_mutex); | 780 | up_write(&ip->i_rw_mutex); |
786 | 781 | ||
@@ -819,7 +814,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size) | |||
819 | if (error) | 814 | if (error) |
820 | goto out; | 815 | goto out; |
821 | 816 | ||
822 | error = gfs2_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); | 817 | error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); |
823 | if (error) | 818 | if (error) |
824 | goto out_gunlock_q; | 819 | goto out_gunlock_q; |
825 | 820 | ||
@@ -853,14 +848,14 @@ static int do_grow(struct gfs2_inode *ip, u64 size) | |||
853 | } | 848 | } |
854 | 849 | ||
855 | ip->i_di.di_size = size; | 850 | ip->i_di.di_size = size; |
856 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 851 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
857 | 852 | ||
858 | error = gfs2_meta_inode_buffer(ip, &dibh); | 853 | error = gfs2_meta_inode_buffer(ip, &dibh); |
859 | if (error) | 854 | if (error) |
860 | goto out_end_trans; | 855 | goto out_end_trans; |
861 | 856 | ||
862 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 857 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
863 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 858 | gfs2_dinode_out(ip, dibh->b_data); |
864 | brelse(dibh); | 859 | brelse(dibh); |
865 | 860 | ||
866 | out_end_trans: | 861 | out_end_trans: |
@@ -968,9 +963,9 @@ static int trunc_start(struct gfs2_inode *ip, u64 size) | |||
968 | 963 | ||
969 | if (gfs2_is_stuffed(ip)) { | 964 | if (gfs2_is_stuffed(ip)) { |
970 | ip->i_di.di_size = size; | 965 | ip->i_di.di_size = size; |
971 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 966 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
972 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 967 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
973 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 968 | gfs2_dinode_out(ip, dibh->b_data); |
974 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size); | 969 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size); |
975 | error = 1; | 970 | error = 1; |
976 | 971 | ||
@@ -980,10 +975,10 @@ static int trunc_start(struct gfs2_inode *ip, u64 size) | |||
980 | 975 | ||
981 | if (!error) { | 976 | if (!error) { |
982 | ip->i_di.di_size = size; | 977 | ip->i_di.di_size = size; |
983 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 978 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
984 | ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG; | 979 | ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG; |
985 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 980 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
986 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 981 | gfs2_dinode_out(ip, dibh->b_data); |
987 | } | 982 | } |
988 | } | 983 | } |
989 | 984 | ||
@@ -1053,11 +1048,11 @@ static int trunc_end(struct gfs2_inode *ip) | |||
1053 | ip->i_num.no_addr; | 1048 | ip->i_num.no_addr; |
1054 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | 1049 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); |
1055 | } | 1050 | } |
1056 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 1051 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
1057 | ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG; | 1052 | ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG; |
1058 | 1053 | ||
1059 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1054 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1060 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1055 | gfs2_dinode_out(ip, dibh->b_data); |
1061 | brelse(dibh); | 1056 | brelse(dibh); |
1062 | 1057 | ||
1063 | out: | 1058 | out: |
@@ -1109,7 +1104,7 @@ int gfs2_truncatei(struct gfs2_inode *ip, u64 size) | |||
1109 | { | 1104 | { |
1110 | int error; | 1105 | int error; |
1111 | 1106 | ||
1112 | if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_di.di_mode))) | 1107 | if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_inode.i_mode))) |
1113 | return -EINVAL; | 1108 | return -EINVAL; |
1114 | 1109 | ||
1115 | if (size > ip->i_di.di_size) | 1110 | if (size > ip->i_di.di_size) |
diff --git a/fs/gfs2/daemon.c b/fs/gfs2/daemon.c index cab1f68d4685..683cb5bda870 100644 --- a/fs/gfs2/daemon.c +++ b/fs/gfs2/daemon.c | |||
@@ -112,6 +112,7 @@ int gfs2_logd(void *data) | |||
112 | struct gfs2_sbd *sdp = data; | 112 | struct gfs2_sbd *sdp = data; |
113 | struct gfs2_holder ji_gh; | 113 | struct gfs2_holder ji_gh; |
114 | unsigned long t; | 114 | unsigned long t; |
115 | int need_flush; | ||
115 | 116 | ||
116 | while (!kthread_should_stop()) { | 117 | while (!kthread_should_stop()) { |
117 | /* Advance the log tail */ | 118 | /* Advance the log tail */ |
@@ -120,8 +121,10 @@ int gfs2_logd(void *data) | |||
120 | gfs2_tune_get(sdp, gt_log_flush_secs) * HZ; | 121 | gfs2_tune_get(sdp, gt_log_flush_secs) * HZ; |
121 | 122 | ||
122 | gfs2_ail1_empty(sdp, DIO_ALL); | 123 | gfs2_ail1_empty(sdp, DIO_ALL); |
123 | 124 | gfs2_log_lock(sdp); | |
124 | if (time_after_eq(jiffies, t)) { | 125 | need_flush = sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks); |
126 | gfs2_log_unlock(sdp); | ||
127 | if (need_flush || time_after_eq(jiffies, t)) { | ||
125 | gfs2_log_flush(sdp, NULL); | 128 | gfs2_log_flush(sdp, NULL); |
126 | sdp->sd_log_flush_time = jiffies; | 129 | sdp->sd_log_flush_time = jiffies; |
127 | } | 130 | } |
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index e24af28b1a12..0fdcb7713cd9 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -131,8 +131,8 @@ static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf, | |||
131 | memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); | 131 | memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); |
132 | if (ip->i_di.di_size < offset + size) | 132 | if (ip->i_di.di_size < offset + size) |
133 | ip->i_di.di_size = offset + size; | 133 | ip->i_di.di_size = offset + size; |
134 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 134 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
135 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 135 | gfs2_dinode_out(ip, dibh->b_data); |
136 | 136 | ||
137 | brelse(dibh); | 137 | brelse(dibh); |
138 | 138 | ||
@@ -229,10 +229,10 @@ out: | |||
229 | 229 | ||
230 | if (ip->i_di.di_size < offset + copied) | 230 | if (ip->i_di.di_size < offset + copied) |
231 | ip->i_di.di_size = offset + copied; | 231 | ip->i_di.di_size = offset + copied; |
232 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 232 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
233 | 233 | ||
234 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 234 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
235 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 235 | gfs2_dinode_out(ip, dibh->b_data); |
236 | brelse(dibh); | 236 | brelse(dibh); |
237 | 237 | ||
238 | return copied; | 238 | return copied; |
@@ -340,10 +340,15 @@ fail: | |||
340 | return (copied) ? copied : error; | 340 | return (copied) ? copied : error; |
341 | } | 341 | } |
342 | 342 | ||
343 | static inline int gfs2_dirent_sentinel(const struct gfs2_dirent *dent) | ||
344 | { | ||
345 | return dent->de_inum.no_addr == 0 || dent->de_inum.no_formal_ino == 0; | ||
346 | } | ||
347 | |||
343 | static inline int __gfs2_dirent_find(const struct gfs2_dirent *dent, | 348 | static inline int __gfs2_dirent_find(const struct gfs2_dirent *dent, |
344 | const struct qstr *name, int ret) | 349 | const struct qstr *name, int ret) |
345 | { | 350 | { |
346 | if (dent->de_inum.no_addr != 0 && | 351 | if (!gfs2_dirent_sentinel(dent) && |
347 | be32_to_cpu(dent->de_hash) == name->hash && | 352 | be32_to_cpu(dent->de_hash) == name->hash && |
348 | be16_to_cpu(dent->de_name_len) == name->len && | 353 | be16_to_cpu(dent->de_name_len) == name->len && |
349 | memcmp(dent+1, name->name, name->len) == 0) | 354 | memcmp(dent+1, name->name, name->len) == 0) |
@@ -388,7 +393,7 @@ static int gfs2_dirent_find_space(const struct gfs2_dirent *dent, | |||
388 | unsigned actual = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); | 393 | unsigned actual = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); |
389 | unsigned totlen = be16_to_cpu(dent->de_rec_len); | 394 | unsigned totlen = be16_to_cpu(dent->de_rec_len); |
390 | 395 | ||
391 | if (!dent->de_inum.no_addr) | 396 | if (gfs2_dirent_sentinel(dent)) |
392 | actual = GFS2_DIRENT_SIZE(0); | 397 | actual = GFS2_DIRENT_SIZE(0); |
393 | if (totlen - actual >= required) | 398 | if (totlen - actual >= required) |
394 | return 1; | 399 | return 1; |
@@ -405,7 +410,7 @@ static int gfs2_dirent_gather(const struct gfs2_dirent *dent, | |||
405 | void *opaque) | 410 | void *opaque) |
406 | { | 411 | { |
407 | struct dirent_gather *g = opaque; | 412 | struct dirent_gather *g = opaque; |
408 | if (dent->de_inum.no_addr) { | 413 | if (!gfs2_dirent_sentinel(dent)) { |
409 | g->pdent[g->offset++] = dent; | 414 | g->pdent[g->offset++] = dent; |
410 | } | 415 | } |
411 | return 0; | 416 | return 0; |
@@ -433,10 +438,10 @@ static int gfs2_check_dirent(struct gfs2_dirent *dent, unsigned int offset, | |||
433 | if (unlikely(offset + size > len)) | 438 | if (unlikely(offset + size > len)) |
434 | goto error; | 439 | goto error; |
435 | msg = "zero inode number"; | 440 | msg = "zero inode number"; |
436 | if (unlikely(!first && !dent->de_inum.no_addr)) | 441 | if (unlikely(!first && gfs2_dirent_sentinel(dent))) |
437 | goto error; | 442 | goto error; |
438 | msg = "name length is greater than space in dirent"; | 443 | msg = "name length is greater than space in dirent"; |
439 | if (dent->de_inum.no_addr && | 444 | if (!gfs2_dirent_sentinel(dent) && |
440 | unlikely(sizeof(struct gfs2_dirent)+be16_to_cpu(dent->de_name_len) > | 445 | unlikely(sizeof(struct gfs2_dirent)+be16_to_cpu(dent->de_name_len) > |
441 | size)) | 446 | size)) |
442 | goto error; | 447 | goto error; |
@@ -598,7 +603,7 @@ static int dirent_next(struct gfs2_inode *dip, struct buffer_head *bh, | |||
598 | return ret; | 603 | return ret; |
599 | 604 | ||
600 | /* Only the first dent could ever have de_inum.no_addr == 0 */ | 605 | /* Only the first dent could ever have de_inum.no_addr == 0 */ |
601 | if (!tmp->de_inum.no_addr) { | 606 | if (gfs2_dirent_sentinel(tmp)) { |
602 | gfs2_consist_inode(dip); | 607 | gfs2_consist_inode(dip); |
603 | return -EIO; | 608 | return -EIO; |
604 | } | 609 | } |
@@ -621,7 +626,7 @@ static void dirent_del(struct gfs2_inode *dip, struct buffer_head *bh, | |||
621 | { | 626 | { |
622 | u16 cur_rec_len, prev_rec_len; | 627 | u16 cur_rec_len, prev_rec_len; |
623 | 628 | ||
624 | if (!cur->de_inum.no_addr) { | 629 | if (gfs2_dirent_sentinel(cur)) { |
625 | gfs2_consist_inode(dip); | 630 | gfs2_consist_inode(dip); |
626 | return; | 631 | return; |
627 | } | 632 | } |
@@ -633,7 +638,8 @@ static void dirent_del(struct gfs2_inode *dip, struct buffer_head *bh, | |||
633 | out the inode number and return. */ | 638 | out the inode number and return. */ |
634 | 639 | ||
635 | if (!prev) { | 640 | if (!prev) { |
636 | cur->de_inum.no_addr = 0; /* No endianess worries */ | 641 | cur->de_inum.no_addr = 0; |
642 | cur->de_inum.no_formal_ino = 0; | ||
637 | return; | 643 | return; |
638 | } | 644 | } |
639 | 645 | ||
@@ -664,7 +670,7 @@ static struct gfs2_dirent *gfs2_init_dirent(struct inode *inode, | |||
664 | struct gfs2_dirent *ndent; | 670 | struct gfs2_dirent *ndent; |
665 | unsigned offset = 0, totlen; | 671 | unsigned offset = 0, totlen; |
666 | 672 | ||
667 | if (dent->de_inum.no_addr) | 673 | if (!gfs2_dirent_sentinel(dent)) |
668 | offset = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); | 674 | offset = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); |
669 | totlen = be16_to_cpu(dent->de_rec_len); | 675 | totlen = be16_to_cpu(dent->de_rec_len); |
670 | BUG_ON(offset + name->len > totlen); | 676 | BUG_ON(offset + name->len > totlen); |
@@ -713,12 +719,12 @@ static int get_leaf(struct gfs2_inode *dip, u64 leaf_no, | |||
713 | static int get_leaf_nr(struct gfs2_inode *dip, u32 index, | 719 | static int get_leaf_nr(struct gfs2_inode *dip, u32 index, |
714 | u64 *leaf_out) | 720 | u64 *leaf_out) |
715 | { | 721 | { |
716 | u64 leaf_no; | 722 | __be64 leaf_no; |
717 | int error; | 723 | int error; |
718 | 724 | ||
719 | error = gfs2_dir_read_data(dip, (char *)&leaf_no, | 725 | error = gfs2_dir_read_data(dip, (char *)&leaf_no, |
720 | index * sizeof(u64), | 726 | index * sizeof(__be64), |
721 | sizeof(u64), 0); | 727 | sizeof(__be64), 0); |
722 | if (error != sizeof(u64)) | 728 | if (error != sizeof(u64)) |
723 | return (error < 0) ? error : -EIO; | 729 | return (error < 0) ? error : -EIO; |
724 | 730 | ||
@@ -837,7 +843,8 @@ static int dir_make_exhash(struct inode *inode) | |||
837 | struct gfs2_leaf *leaf; | 843 | struct gfs2_leaf *leaf; |
838 | int y; | 844 | int y; |
839 | u32 x; | 845 | u32 x; |
840 | u64 *lp, bn; | 846 | __be64 *lp; |
847 | u64 bn; | ||
841 | int error; | 848 | int error; |
842 | 849 | ||
843 | error = gfs2_meta_inode_buffer(dip, &dibh); | 850 | error = gfs2_meta_inode_buffer(dip, &dibh); |
@@ -893,20 +900,20 @@ static int dir_make_exhash(struct inode *inode) | |||
893 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); | 900 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); |
894 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | 901 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); |
895 | 902 | ||
896 | lp = (u64 *)(dibh->b_data + sizeof(struct gfs2_dinode)); | 903 | lp = (__be64 *)(dibh->b_data + sizeof(struct gfs2_dinode)); |
897 | 904 | ||
898 | for (x = sdp->sd_hash_ptrs; x--; lp++) | 905 | for (x = sdp->sd_hash_ptrs; x--; lp++) |
899 | *lp = cpu_to_be64(bn); | 906 | *lp = cpu_to_be64(bn); |
900 | 907 | ||
901 | dip->i_di.di_size = sdp->sd_sb.sb_bsize / 2; | 908 | dip->i_di.di_size = sdp->sd_sb.sb_bsize / 2; |
902 | dip->i_di.di_blocks++; | 909 | dip->i_di.di_blocks++; |
910 | gfs2_set_inode_blocks(&dip->i_inode); | ||
903 | dip->i_di.di_flags |= GFS2_DIF_EXHASH; | 911 | dip->i_di.di_flags |= GFS2_DIF_EXHASH; |
904 | dip->i_di.di_payload_format = 0; | ||
905 | 912 | ||
906 | for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; | 913 | for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; |
907 | dip->i_di.di_depth = y; | 914 | dip->i_di.di_depth = y; |
908 | 915 | ||
909 | gfs2_dinode_out(&dip->i_di, dibh->b_data); | 916 | gfs2_dinode_out(dip, dibh->b_data); |
910 | 917 | ||
911 | brelse(dibh); | 918 | brelse(dibh); |
912 | 919 | ||
@@ -929,7 +936,8 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
929 | struct gfs2_leaf *nleaf, *oleaf; | 936 | struct gfs2_leaf *nleaf, *oleaf; |
930 | struct gfs2_dirent *dent = NULL, *prev = NULL, *next = NULL, *new; | 937 | struct gfs2_dirent *dent = NULL, *prev = NULL, *next = NULL, *new; |
931 | u32 start, len, half_len, divider; | 938 | u32 start, len, half_len, divider; |
932 | u64 bn, *lp, leaf_no; | 939 | u64 bn, leaf_no; |
940 | __be64 *lp; | ||
933 | u32 index; | 941 | u32 index; |
934 | int x, moved = 0; | 942 | int x, moved = 0; |
935 | int error; | 943 | int error; |
@@ -974,7 +982,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
974 | /* Change the pointers. | 982 | /* Change the pointers. |
975 | Don't bother distinguishing stuffed from non-stuffed. | 983 | Don't bother distinguishing stuffed from non-stuffed. |
976 | This code is complicated enough already. */ | 984 | This code is complicated enough already. */ |
977 | lp = kmalloc(half_len * sizeof(u64), GFP_NOFS | __GFP_NOFAIL); | 985 | lp = kmalloc(half_len * sizeof(__be64), GFP_NOFS | __GFP_NOFAIL); |
978 | /* Change the pointers */ | 986 | /* Change the pointers */ |
979 | for (x = 0; x < half_len; x++) | 987 | for (x = 0; x < half_len; x++) |
980 | lp[x] = cpu_to_be64(bn); | 988 | lp[x] = cpu_to_be64(bn); |
@@ -1000,7 +1008,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
1000 | if (dirent_next(dip, obh, &next)) | 1008 | if (dirent_next(dip, obh, &next)) |
1001 | next = NULL; | 1009 | next = NULL; |
1002 | 1010 | ||
1003 | if (dent->de_inum.no_addr && | 1011 | if (!gfs2_dirent_sentinel(dent) && |
1004 | be32_to_cpu(dent->de_hash) < divider) { | 1012 | be32_to_cpu(dent->de_hash) < divider) { |
1005 | struct qstr str; | 1013 | struct qstr str; |
1006 | str.name = (char*)(dent+1); | 1014 | str.name = (char*)(dent+1); |
@@ -1037,7 +1045,8 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
1037 | error = gfs2_meta_inode_buffer(dip, &dibh); | 1045 | error = gfs2_meta_inode_buffer(dip, &dibh); |
1038 | if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) { | 1046 | if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) { |
1039 | dip->i_di.di_blocks++; | 1047 | dip->i_di.di_blocks++; |
1040 | gfs2_dinode_out(&dip->i_di, dibh->b_data); | 1048 | gfs2_set_inode_blocks(&dip->i_inode); |
1049 | gfs2_dinode_out(dip, dibh->b_data); | ||
1041 | brelse(dibh); | 1050 | brelse(dibh); |
1042 | } | 1051 | } |
1043 | 1052 | ||
@@ -1117,7 +1126,7 @@ static int dir_double_exhash(struct gfs2_inode *dip) | |||
1117 | error = gfs2_meta_inode_buffer(dip, &dibh); | 1126 | error = gfs2_meta_inode_buffer(dip, &dibh); |
1118 | if (!gfs2_assert_withdraw(sdp, !error)) { | 1127 | if (!gfs2_assert_withdraw(sdp, !error)) { |
1119 | dip->i_di.di_depth++; | 1128 | dip->i_di.di_depth++; |
1120 | gfs2_dinode_out(&dip->i_di, dibh->b_data); | 1129 | gfs2_dinode_out(dip, dibh->b_data); |
1121 | brelse(dibh); | 1130 | brelse(dibh); |
1122 | } | 1131 | } |
1123 | 1132 | ||
@@ -1194,7 +1203,7 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset, | |||
1194 | int *copied) | 1203 | int *copied) |
1195 | { | 1204 | { |
1196 | const struct gfs2_dirent *dent, *dent_next; | 1205 | const struct gfs2_dirent *dent, *dent_next; |
1197 | struct gfs2_inum inum; | 1206 | struct gfs2_inum_host inum; |
1198 | u64 off, off_next; | 1207 | u64 off, off_next; |
1199 | unsigned int x, y; | 1208 | unsigned int x, y; |
1200 | int run = 0; | 1209 | int run = 0; |
@@ -1341,7 +1350,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1341 | u32 hsize, len = 0; | 1350 | u32 hsize, len = 0; |
1342 | u32 ht_offset, lp_offset, ht_offset_cur = -1; | 1351 | u32 ht_offset, lp_offset, ht_offset_cur = -1; |
1343 | u32 hash, index; | 1352 | u32 hash, index; |
1344 | u64 *lp; | 1353 | __be64 *lp; |
1345 | int copied = 0; | 1354 | int copied = 0; |
1346 | int error = 0; | 1355 | int error = 0; |
1347 | unsigned depth = 0; | 1356 | unsigned depth = 0; |
@@ -1365,7 +1374,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1365 | 1374 | ||
1366 | if (ht_offset_cur != ht_offset) { | 1375 | if (ht_offset_cur != ht_offset) { |
1367 | error = gfs2_dir_read_data(dip, (char *)lp, | 1376 | error = gfs2_dir_read_data(dip, (char *)lp, |
1368 | ht_offset * sizeof(u64), | 1377 | ht_offset * sizeof(__be64), |
1369 | sdp->sd_hash_bsize, 1); | 1378 | sdp->sd_hash_bsize, 1); |
1370 | if (error != sdp->sd_hash_bsize) { | 1379 | if (error != sdp->sd_hash_bsize) { |
1371 | if (error >= 0) | 1380 | if (error >= 0) |
@@ -1456,7 +1465,7 @@ out: | |||
1456 | */ | 1465 | */ |
1457 | 1466 | ||
1458 | int gfs2_dir_search(struct inode *dir, const struct qstr *name, | 1467 | int gfs2_dir_search(struct inode *dir, const struct qstr *name, |
1459 | struct gfs2_inum *inum, unsigned int *type) | 1468 | struct gfs2_inum_host *inum, unsigned int *type) |
1460 | { | 1469 | { |
1461 | struct buffer_head *bh; | 1470 | struct buffer_head *bh; |
1462 | struct gfs2_dirent *dent; | 1471 | struct gfs2_dirent *dent; |
@@ -1515,7 +1524,8 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name) | |||
1515 | return error; | 1524 | return error; |
1516 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 1525 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
1517 | ip->i_di.di_blocks++; | 1526 | ip->i_di.di_blocks++; |
1518 | gfs2_dinode_out(&ip->i_di, bh->b_data); | 1527 | gfs2_set_inode_blocks(&ip->i_inode); |
1528 | gfs2_dinode_out(ip, bh->b_data); | ||
1519 | brelse(bh); | 1529 | brelse(bh); |
1520 | return 0; | 1530 | return 0; |
1521 | } | 1531 | } |
@@ -1531,7 +1541,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name) | |||
1531 | */ | 1541 | */ |
1532 | 1542 | ||
1533 | int gfs2_dir_add(struct inode *inode, const struct qstr *name, | 1543 | int gfs2_dir_add(struct inode *inode, const struct qstr *name, |
1534 | const struct gfs2_inum *inum, unsigned type) | 1544 | const struct gfs2_inum_host *inum, unsigned type) |
1535 | { | 1545 | { |
1536 | struct gfs2_inode *ip = GFS2_I(inode); | 1546 | struct gfs2_inode *ip = GFS2_I(inode); |
1537 | struct buffer_head *bh; | 1547 | struct buffer_head *bh; |
@@ -1558,8 +1568,8 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, | |||
1558 | break; | 1568 | break; |
1559 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 1569 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
1560 | ip->i_di.di_entries++; | 1570 | ip->i_di.di_entries++; |
1561 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 1571 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
1562 | gfs2_dinode_out(&ip->i_di, bh->b_data); | 1572 | gfs2_dinode_out(ip, bh->b_data); |
1563 | brelse(bh); | 1573 | brelse(bh); |
1564 | error = 0; | 1574 | error = 0; |
1565 | break; | 1575 | break; |
@@ -1644,8 +1654,8 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) | |||
1644 | gfs2_consist_inode(dip); | 1654 | gfs2_consist_inode(dip); |
1645 | gfs2_trans_add_bh(dip->i_gl, bh, 1); | 1655 | gfs2_trans_add_bh(dip->i_gl, bh, 1); |
1646 | dip->i_di.di_entries--; | 1656 | dip->i_di.di_entries--; |
1647 | dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); | 1657 | dip->i_inode.i_mtime.tv_sec = dip->i_inode.i_ctime.tv_sec = get_seconds(); |
1648 | gfs2_dinode_out(&dip->i_di, bh->b_data); | 1658 | gfs2_dinode_out(dip, bh->b_data); |
1649 | brelse(bh); | 1659 | brelse(bh); |
1650 | mark_inode_dirty(&dip->i_inode); | 1660 | mark_inode_dirty(&dip->i_inode); |
1651 | 1661 | ||
@@ -1666,7 +1676,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) | |||
1666 | */ | 1676 | */ |
1667 | 1677 | ||
1668 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | 1678 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, |
1669 | struct gfs2_inum *inum, unsigned int new_type) | 1679 | struct gfs2_inum_host *inum, unsigned int new_type) |
1670 | { | 1680 | { |
1671 | struct buffer_head *bh; | 1681 | struct buffer_head *bh; |
1672 | struct gfs2_dirent *dent; | 1682 | struct gfs2_dirent *dent; |
@@ -1692,8 +1702,8 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | |||
1692 | gfs2_trans_add_bh(dip->i_gl, bh, 1); | 1702 | gfs2_trans_add_bh(dip->i_gl, bh, 1); |
1693 | } | 1703 | } |
1694 | 1704 | ||
1695 | dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); | 1705 | dip->i_inode.i_mtime.tv_sec = dip->i_inode.i_ctime.tv_sec = get_seconds(); |
1696 | gfs2_dinode_out(&dip->i_di, bh->b_data); | 1706 | gfs2_dinode_out(dip, bh->b_data); |
1697 | brelse(bh); | 1707 | brelse(bh); |
1698 | return 0; | 1708 | return 0; |
1699 | } | 1709 | } |
@@ -1715,7 +1725,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data) | |||
1715 | u32 hsize, len; | 1725 | u32 hsize, len; |
1716 | u32 ht_offset, lp_offset, ht_offset_cur = -1; | 1726 | u32 ht_offset, lp_offset, ht_offset_cur = -1; |
1717 | u32 index = 0; | 1727 | u32 index = 0; |
1718 | u64 *lp; | 1728 | __be64 *lp; |
1719 | u64 leaf_no; | 1729 | u64 leaf_no; |
1720 | int error = 0; | 1730 | int error = 0; |
1721 | 1731 | ||
@@ -1735,7 +1745,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data) | |||
1735 | 1745 | ||
1736 | if (ht_offset_cur != ht_offset) { | 1746 | if (ht_offset_cur != ht_offset) { |
1737 | error = gfs2_dir_read_data(dip, (char *)lp, | 1747 | error = gfs2_dir_read_data(dip, (char *)lp, |
1738 | ht_offset * sizeof(u64), | 1748 | ht_offset * sizeof(__be64), |
1739 | sdp->sd_hash_bsize, 1); | 1749 | sdp->sd_hash_bsize, 1); |
1740 | if (error != sdp->sd_hash_bsize) { | 1750 | if (error != sdp->sd_hash_bsize) { |
1741 | if (error >= 0) | 1751 | if (error >= 0) |
@@ -1859,6 +1869,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | |||
1859 | if (!dip->i_di.di_blocks) | 1869 | if (!dip->i_di.di_blocks) |
1860 | gfs2_consist_inode(dip); | 1870 | gfs2_consist_inode(dip); |
1861 | dip->i_di.di_blocks--; | 1871 | dip->i_di.di_blocks--; |
1872 | gfs2_set_inode_blocks(&dip->i_inode); | ||
1862 | } | 1873 | } |
1863 | 1874 | ||
1864 | error = gfs2_dir_write_data(dip, ht, index * sizeof(u64), size); | 1875 | error = gfs2_dir_write_data(dip, ht, index * sizeof(u64), size); |
@@ -1873,7 +1884,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | |||
1873 | goto out_end_trans; | 1884 | goto out_end_trans; |
1874 | 1885 | ||
1875 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); | 1886 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); |
1876 | gfs2_dinode_out(&dip->i_di, dibh->b_data); | 1887 | gfs2_dinode_out(dip, dibh->b_data); |
1877 | brelse(dibh); | 1888 | brelse(dibh); |
1878 | 1889 | ||
1879 | out_end_trans: | 1890 | out_end_trans: |
diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h index 371233419b07..b21b33668a5b 100644 --- a/fs/gfs2/dir.h +++ b/fs/gfs2/dir.h | |||
@@ -31,17 +31,17 @@ struct gfs2_inum; | |||
31 | typedef int (*gfs2_filldir_t) (void *opaque, | 31 | typedef int (*gfs2_filldir_t) (void *opaque, |
32 | const char *name, unsigned int length, | 32 | const char *name, unsigned int length, |
33 | u64 offset, | 33 | u64 offset, |
34 | struct gfs2_inum *inum, unsigned int type); | 34 | struct gfs2_inum_host *inum, unsigned int type); |
35 | 35 | ||
36 | int gfs2_dir_search(struct inode *dir, const struct qstr *filename, | 36 | int gfs2_dir_search(struct inode *dir, const struct qstr *filename, |
37 | struct gfs2_inum *inum, unsigned int *type); | 37 | struct gfs2_inum_host *inum, unsigned int *type); |
38 | int gfs2_dir_add(struct inode *inode, const struct qstr *filename, | 38 | int gfs2_dir_add(struct inode *inode, const struct qstr *filename, |
39 | const struct gfs2_inum *inum, unsigned int type); | 39 | const struct gfs2_inum_host *inum, unsigned int type); |
40 | int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename); | 40 | int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename); |
41 | int gfs2_dir_read(struct inode *inode, u64 * offset, void *opaque, | 41 | int gfs2_dir_read(struct inode *inode, u64 * offset, void *opaque, |
42 | gfs2_filldir_t filldir); | 42 | gfs2_filldir_t filldir); |
43 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | 43 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, |
44 | struct gfs2_inum *new_inum, unsigned int new_type); | 44 | struct gfs2_inum_host *new_inum, unsigned int new_type); |
45 | 45 | ||
46 | int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip); | 46 | int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip); |
47 | 47 | ||
diff --git a/fs/gfs2/eaops.c b/fs/gfs2/eaops.c index 92c54e9b0dc3..cd747c00f670 100644 --- a/fs/gfs2/eaops.c +++ b/fs/gfs2/eaops.c | |||
@@ -120,7 +120,7 @@ static int system_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er) | |||
120 | 120 | ||
121 | if (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len)) { | 121 | if (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len)) { |
122 | if (!(er->er_flags & GFS2_ERF_MODE)) { | 122 | if (!(er->er_flags & GFS2_ERF_MODE)) { |
123 | er->er_mode = ip->i_di.di_mode; | 123 | er->er_mode = ip->i_inode.i_mode; |
124 | er->er_flags |= GFS2_ERF_MODE; | 124 | er->er_flags |= GFS2_ERF_MODE; |
125 | } | 125 | } |
126 | error = gfs2_acl_validate_set(ip, 1, er, | 126 | error = gfs2_acl_validate_set(ip, 1, er, |
diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index a65a4ccfd4dd..ebebbdcd7057 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c | |||
@@ -112,7 +112,7 @@ fail: | |||
112 | static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data) | 112 | static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data) |
113 | { | 113 | { |
114 | struct buffer_head *bh, *eabh; | 114 | struct buffer_head *bh, *eabh; |
115 | u64 *eablk, *end; | 115 | __be64 *eablk, *end; |
116 | int error; | 116 | int error; |
117 | 117 | ||
118 | error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_WAIT, &bh); | 118 | error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_WAIT, &bh); |
@@ -129,7 +129,7 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data) | |||
129 | goto out; | 129 | goto out; |
130 | } | 130 | } |
131 | 131 | ||
132 | eablk = (u64 *)(bh->b_data + sizeof(struct gfs2_meta_header)); | 132 | eablk = (__be64 *)(bh->b_data + sizeof(struct gfs2_meta_header)); |
133 | end = eablk + GFS2_SB(&ip->i_inode)->sd_inptrs; | 133 | end = eablk + GFS2_SB(&ip->i_inode)->sd_inptrs; |
134 | 134 | ||
135 | for (; eablk < end; eablk++) { | 135 | for (; eablk < end; eablk++) { |
@@ -224,7 +224,8 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, | |||
224 | struct gfs2_rgrpd *rgd; | 224 | struct gfs2_rgrpd *rgd; |
225 | struct gfs2_holder rg_gh; | 225 | struct gfs2_holder rg_gh; |
226 | struct buffer_head *dibh; | 226 | struct buffer_head *dibh; |
227 | u64 *dataptrs, bn = 0; | 227 | __be64 *dataptrs; |
228 | u64 bn = 0; | ||
228 | u64 bstart = 0; | 229 | u64 bstart = 0; |
229 | unsigned int blen = 0; | 230 | unsigned int blen = 0; |
230 | unsigned int blks = 0; | 231 | unsigned int blks = 0; |
@@ -280,6 +281,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, | |||
280 | if (!ip->i_di.di_blocks) | 281 | if (!ip->i_di.di_blocks) |
281 | gfs2_consist_inode(ip); | 282 | gfs2_consist_inode(ip); |
282 | ip->i_di.di_blocks--; | 283 | ip->i_di.di_blocks--; |
284 | gfs2_set_inode_blocks(&ip->i_inode); | ||
283 | } | 285 | } |
284 | if (bstart) | 286 | if (bstart) |
285 | gfs2_free_meta(ip, bstart, blen); | 287 | gfs2_free_meta(ip, bstart, blen); |
@@ -299,9 +301,9 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, | |||
299 | 301 | ||
300 | error = gfs2_meta_inode_buffer(ip, &dibh); | 302 | error = gfs2_meta_inode_buffer(ip, &dibh); |
301 | if (!error) { | 303 | if (!error) { |
302 | ip->i_di.di_ctime = get_seconds(); | 304 | ip->i_inode.i_ctime.tv_sec = get_seconds(); |
303 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 305 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
304 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 306 | gfs2_dinode_out(ip, dibh->b_data); |
305 | brelse(dibh); | 307 | brelse(dibh); |
306 | } | 308 | } |
307 | 309 | ||
@@ -444,7 +446,7 @@ static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea, | |||
444 | struct buffer_head **bh; | 446 | struct buffer_head **bh; |
445 | unsigned int amount = GFS2_EA_DATA_LEN(ea); | 447 | unsigned int amount = GFS2_EA_DATA_LEN(ea); |
446 | unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize); | 448 | unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize); |
447 | u64 *dataptrs = GFS2_EA2DATAPTRS(ea); | 449 | __be64 *dataptrs = GFS2_EA2DATAPTRS(ea); |
448 | unsigned int x; | 450 | unsigned int x; |
449 | int error = 0; | 451 | int error = 0; |
450 | 452 | ||
@@ -597,6 +599,7 @@ static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp) | |||
597 | ea->ea_num_ptrs = 0; | 599 | ea->ea_num_ptrs = 0; |
598 | 600 | ||
599 | ip->i_di.di_blocks++; | 601 | ip->i_di.di_blocks++; |
602 | gfs2_set_inode_blocks(&ip->i_inode); | ||
600 | 603 | ||
601 | return 0; | 604 | return 0; |
602 | } | 605 | } |
@@ -629,7 +632,7 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea, | |||
629 | ea->ea_num_ptrs = 0; | 632 | ea->ea_num_ptrs = 0; |
630 | memcpy(GFS2_EA2DATA(ea), er->er_data, er->er_data_len); | 633 | memcpy(GFS2_EA2DATA(ea), er->er_data, er->er_data_len); |
631 | } else { | 634 | } else { |
632 | u64 *dataptr = GFS2_EA2DATAPTRS(ea); | 635 | __be64 *dataptr = GFS2_EA2DATAPTRS(ea); |
633 | const char *data = er->er_data; | 636 | const char *data = er->er_data; |
634 | unsigned int data_len = er->er_data_len; | 637 | unsigned int data_len = er->er_data_len; |
635 | unsigned int copy; | 638 | unsigned int copy; |
@@ -648,6 +651,7 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea, | |||
648 | gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED); | 651 | gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED); |
649 | 652 | ||
650 | ip->i_di.di_blocks++; | 653 | ip->i_di.di_blocks++; |
654 | gfs2_set_inode_blocks(&ip->i_inode); | ||
651 | 655 | ||
652 | copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize : | 656 | copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize : |
653 | data_len; | 657 | data_len; |
@@ -686,7 +690,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
686 | if (error) | 690 | if (error) |
687 | goto out; | 691 | goto out; |
688 | 692 | ||
689 | error = gfs2_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); | 693 | error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); |
690 | if (error) | 694 | if (error) |
691 | goto out_gunlock_q; | 695 | goto out_gunlock_q; |
692 | 696 | ||
@@ -710,13 +714,13 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
710 | if (!error) { | 714 | if (!error) { |
711 | if (er->er_flags & GFS2_ERF_MODE) { | 715 | if (er->er_flags & GFS2_ERF_MODE) { |
712 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), | 716 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), |
713 | (ip->i_di.di_mode & S_IFMT) == | 717 | (ip->i_inode.i_mode & S_IFMT) == |
714 | (er->er_mode & S_IFMT)); | 718 | (er->er_mode & S_IFMT)); |
715 | ip->i_di.di_mode = er->er_mode; | 719 | ip->i_inode.i_mode = er->er_mode; |
716 | } | 720 | } |
717 | ip->i_di.di_ctime = get_seconds(); | 721 | ip->i_inode.i_ctime.tv_sec = get_seconds(); |
718 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 722 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
719 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 723 | gfs2_dinode_out(ip, dibh->b_data); |
720 | brelse(dibh); | 724 | brelse(dibh); |
721 | } | 725 | } |
722 | 726 | ||
@@ -846,12 +850,12 @@ static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh, | |||
846 | 850 | ||
847 | if (er->er_flags & GFS2_ERF_MODE) { | 851 | if (er->er_flags & GFS2_ERF_MODE) { |
848 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), | 852 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), |
849 | (ip->i_di.di_mode & S_IFMT) == (er->er_mode & S_IFMT)); | 853 | (ip->i_inode.i_mode & S_IFMT) == (er->er_mode & S_IFMT)); |
850 | ip->i_di.di_mode = er->er_mode; | 854 | ip->i_inode.i_mode = er->er_mode; |
851 | } | 855 | } |
852 | ip->i_di.di_ctime = get_seconds(); | 856 | ip->i_inode.i_ctime.tv_sec = get_seconds(); |
853 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 857 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
854 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 858 | gfs2_dinode_out(ip, dibh->b_data); |
855 | brelse(dibh); | 859 | brelse(dibh); |
856 | out: | 860 | out: |
857 | gfs2_trans_end(GFS2_SB(&ip->i_inode)); | 861 | gfs2_trans_end(GFS2_SB(&ip->i_inode)); |
@@ -931,12 +935,12 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
931 | { | 935 | { |
932 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 936 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
933 | struct buffer_head *indbh, *newbh; | 937 | struct buffer_head *indbh, *newbh; |
934 | u64 *eablk; | 938 | __be64 *eablk; |
935 | int error; | 939 | int error; |
936 | int mh_size = sizeof(struct gfs2_meta_header); | 940 | int mh_size = sizeof(struct gfs2_meta_header); |
937 | 941 | ||
938 | if (ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT) { | 942 | if (ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT) { |
939 | u64 *end; | 943 | __be64 *end; |
940 | 944 | ||
941 | error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_WAIT, | 945 | error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_WAIT, |
942 | &indbh); | 946 | &indbh); |
@@ -948,7 +952,7 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
948 | goto out; | 952 | goto out; |
949 | } | 953 | } |
950 | 954 | ||
951 | eablk = (u64 *)(indbh->b_data + mh_size); | 955 | eablk = (__be64 *)(indbh->b_data + mh_size); |
952 | end = eablk + sdp->sd_inptrs; | 956 | end = eablk + sdp->sd_inptrs; |
953 | 957 | ||
954 | for (; eablk < end; eablk++) | 958 | for (; eablk < end; eablk++) |
@@ -971,11 +975,12 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
971 | gfs2_metatype_set(indbh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); | 975 | gfs2_metatype_set(indbh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); |
972 | gfs2_buffer_clear_tail(indbh, mh_size); | 976 | gfs2_buffer_clear_tail(indbh, mh_size); |
973 | 977 | ||
974 | eablk = (u64 *)(indbh->b_data + mh_size); | 978 | eablk = (__be64 *)(indbh->b_data + mh_size); |
975 | *eablk = cpu_to_be64(ip->i_di.di_eattr); | 979 | *eablk = cpu_to_be64(ip->i_di.di_eattr); |
976 | ip->i_di.di_eattr = blk; | 980 | ip->i_di.di_eattr = blk; |
977 | ip->i_di.di_flags |= GFS2_DIF_EA_INDIRECT; | 981 | ip->i_di.di_flags |= GFS2_DIF_EA_INDIRECT; |
978 | ip->i_di.di_blocks++; | 982 | ip->i_di.di_blocks++; |
983 | gfs2_set_inode_blocks(&ip->i_inode); | ||
979 | 984 | ||
980 | eablk++; | 985 | eablk++; |
981 | } | 986 | } |
@@ -1129,9 +1134,9 @@ static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el) | |||
1129 | 1134 | ||
1130 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1135 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1131 | if (!error) { | 1136 | if (!error) { |
1132 | ip->i_di.di_ctime = get_seconds(); | 1137 | ip->i_inode.i_ctime.tv_sec = get_seconds(); |
1133 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1138 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1134 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1139 | gfs2_dinode_out(ip, dibh->b_data); |
1135 | brelse(dibh); | 1140 | brelse(dibh); |
1136 | } | 1141 | } |
1137 | 1142 | ||
@@ -1202,7 +1207,7 @@ static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip, | |||
1202 | struct buffer_head **bh; | 1207 | struct buffer_head **bh; |
1203 | unsigned int amount = GFS2_EA_DATA_LEN(ea); | 1208 | unsigned int amount = GFS2_EA_DATA_LEN(ea); |
1204 | unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize); | 1209 | unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize); |
1205 | u64 *dataptrs = GFS2_EA2DATAPTRS(ea); | 1210 | __be64 *dataptrs = GFS2_EA2DATAPTRS(ea); |
1206 | unsigned int x; | 1211 | unsigned int x; |
1207 | int error; | 1212 | int error; |
1208 | 1213 | ||
@@ -1284,9 +1289,8 @@ int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el, | |||
1284 | if (!error) { | 1289 | if (!error) { |
1285 | error = inode_setattr(&ip->i_inode, attr); | 1290 | error = inode_setattr(&ip->i_inode, attr); |
1286 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); | 1291 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); |
1287 | gfs2_inode_attr_out(ip); | ||
1288 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1292 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1289 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1293 | gfs2_dinode_out(ip, dibh->b_data); |
1290 | brelse(dibh); | 1294 | brelse(dibh); |
1291 | } | 1295 | } |
1292 | 1296 | ||
@@ -1300,7 +1304,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1300 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1304 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1301 | struct gfs2_rgrp_list rlist; | 1305 | struct gfs2_rgrp_list rlist; |
1302 | struct buffer_head *indbh, *dibh; | 1306 | struct buffer_head *indbh, *dibh; |
1303 | u64 *eablk, *end; | 1307 | __be64 *eablk, *end; |
1304 | unsigned int rg_blocks = 0; | 1308 | unsigned int rg_blocks = 0; |
1305 | u64 bstart = 0; | 1309 | u64 bstart = 0; |
1306 | unsigned int blen = 0; | 1310 | unsigned int blen = 0; |
@@ -1319,7 +1323,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1319 | goto out; | 1323 | goto out; |
1320 | } | 1324 | } |
1321 | 1325 | ||
1322 | eablk = (u64 *)(indbh->b_data + sizeof(struct gfs2_meta_header)); | 1326 | eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header)); |
1323 | end = eablk + sdp->sd_inptrs; | 1327 | end = eablk + sdp->sd_inptrs; |
1324 | 1328 | ||
1325 | for (; eablk < end; eablk++) { | 1329 | for (; eablk < end; eablk++) { |
@@ -1363,7 +1367,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1363 | 1367 | ||
1364 | gfs2_trans_add_bh(ip->i_gl, indbh, 1); | 1368 | gfs2_trans_add_bh(ip->i_gl, indbh, 1); |
1365 | 1369 | ||
1366 | eablk = (u64 *)(indbh->b_data + sizeof(struct gfs2_meta_header)); | 1370 | eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header)); |
1367 | bstart = 0; | 1371 | bstart = 0; |
1368 | blen = 0; | 1372 | blen = 0; |
1369 | 1373 | ||
@@ -1387,6 +1391,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1387 | if (!ip->i_di.di_blocks) | 1391 | if (!ip->i_di.di_blocks) |
1388 | gfs2_consist_inode(ip); | 1392 | gfs2_consist_inode(ip); |
1389 | ip->i_di.di_blocks--; | 1393 | ip->i_di.di_blocks--; |
1394 | gfs2_set_inode_blocks(&ip->i_inode); | ||
1390 | } | 1395 | } |
1391 | if (bstart) | 1396 | if (bstart) |
1392 | gfs2_free_meta(ip, bstart, blen); | 1397 | gfs2_free_meta(ip, bstart, blen); |
@@ -1396,7 +1401,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1396 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1401 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1397 | if (!error) { | 1402 | if (!error) { |
1398 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1403 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1399 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1404 | gfs2_dinode_out(ip, dibh->b_data); |
1400 | brelse(dibh); | 1405 | brelse(dibh); |
1401 | } | 1406 | } |
1402 | 1407 | ||
@@ -1441,11 +1446,12 @@ static int ea_dealloc_block(struct gfs2_inode *ip) | |||
1441 | if (!ip->i_di.di_blocks) | 1446 | if (!ip->i_di.di_blocks) |
1442 | gfs2_consist_inode(ip); | 1447 | gfs2_consist_inode(ip); |
1443 | ip->i_di.di_blocks--; | 1448 | ip->i_di.di_blocks--; |
1449 | gfs2_set_inode_blocks(&ip->i_inode); | ||
1444 | 1450 | ||
1445 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1451 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1446 | if (!error) { | 1452 | if (!error) { |
1447 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1453 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1448 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1454 | gfs2_dinode_out(ip, dibh->b_data); |
1449 | brelse(dibh); | 1455 | brelse(dibh); |
1450 | } | 1456 | } |
1451 | 1457 | ||
diff --git a/fs/gfs2/eattr.h b/fs/gfs2/eattr.h index ffa65947d686..c82dbe01d713 100644 --- a/fs/gfs2/eattr.h +++ b/fs/gfs2/eattr.h | |||
@@ -19,7 +19,7 @@ struct iattr; | |||
19 | #define GFS2_EA_SIZE(ea) \ | 19 | #define GFS2_EA_SIZE(ea) \ |
20 | ALIGN(sizeof(struct gfs2_ea_header) + (ea)->ea_name_len + \ | 20 | ALIGN(sizeof(struct gfs2_ea_header) + (ea)->ea_name_len + \ |
21 | ((GFS2_EA_IS_STUFFED(ea)) ? GFS2_EA_DATA_LEN(ea) : \ | 21 | ((GFS2_EA_IS_STUFFED(ea)) ? GFS2_EA_DATA_LEN(ea) : \ |
22 | (sizeof(u64) * (ea)->ea_num_ptrs)), 8) | 22 | (sizeof(__be64) * (ea)->ea_num_ptrs)), 8) |
23 | 23 | ||
24 | #define GFS2_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs) | 24 | #define GFS2_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs) |
25 | #define GFS2_EA_IS_LAST(ea) ((ea)->ea_flags & GFS2_EAFLAG_LAST) | 25 | #define GFS2_EA_IS_LAST(ea) ((ea)->ea_flags & GFS2_EAFLAG_LAST) |
@@ -29,13 +29,13 @@ ALIGN(sizeof(struct gfs2_ea_header) + (er)->er_name_len + (er)->er_data_len, 8) | |||
29 | 29 | ||
30 | #define GFS2_EAREQ_SIZE_UNSTUFFED(sdp, er) \ | 30 | #define GFS2_EAREQ_SIZE_UNSTUFFED(sdp, er) \ |
31 | ALIGN(sizeof(struct gfs2_ea_header) + (er)->er_name_len + \ | 31 | ALIGN(sizeof(struct gfs2_ea_header) + (er)->er_name_len + \ |
32 | sizeof(u64) * DIV_ROUND_UP((er)->er_data_len, (sdp)->sd_jbsize), 8) | 32 | sizeof(__be64) * DIV_ROUND_UP((er)->er_data_len, (sdp)->sd_jbsize), 8) |
33 | 33 | ||
34 | #define GFS2_EA2NAME(ea) ((char *)((struct gfs2_ea_header *)(ea) + 1)) | 34 | #define GFS2_EA2NAME(ea) ((char *)((struct gfs2_ea_header *)(ea) + 1)) |
35 | #define GFS2_EA2DATA(ea) (GFS2_EA2NAME(ea) + (ea)->ea_name_len) | 35 | #define GFS2_EA2DATA(ea) (GFS2_EA2NAME(ea) + (ea)->ea_name_len) |
36 | 36 | ||
37 | #define GFS2_EA2DATAPTRS(ea) \ | 37 | #define GFS2_EA2DATAPTRS(ea) \ |
38 | ((u64 *)(GFS2_EA2NAME(ea) + ALIGN((ea)->ea_name_len, 8))) | 38 | ((__be64 *)(GFS2_EA2NAME(ea) + ALIGN((ea)->ea_name_len, 8))) |
39 | 39 | ||
40 | #define GFS2_EA2NEXT(ea) \ | 40 | #define GFS2_EA2NEXT(ea) \ |
41 | ((struct gfs2_ea_header *)((char *)(ea) + GFS2_EA_REC_LEN(ea))) | 41 | ((struct gfs2_ea_header *)((char *)(ea) + GFS2_EA_REC_LEN(ea))) |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 55f5333dae99..438146904b58 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -96,7 +96,7 @@ static inline rwlock_t *gl_lock_addr(unsigned int x) | |||
96 | return &gl_hash_locks[x & (GL_HASH_LOCK_SZ-1)]; | 96 | return &gl_hash_locks[x & (GL_HASH_LOCK_SZ-1)]; |
97 | } | 97 | } |
98 | #else /* not SMP, so no spinlocks required */ | 98 | #else /* not SMP, so no spinlocks required */ |
99 | static inline rwlock_t *gl_lock_addr(x) | 99 | static inline rwlock_t *gl_lock_addr(unsigned int x) |
100 | { | 100 | { |
101 | return NULL; | 101 | return NULL; |
102 | } | 102 | } |
@@ -769,7 +769,7 @@ restart: | |||
769 | } else { | 769 | } else { |
770 | spin_unlock(&gl->gl_spin); | 770 | spin_unlock(&gl->gl_spin); |
771 | 771 | ||
772 | new_gh = gfs2_holder_get(gl, state, LM_FLAG_TRY, GFP_KERNEL); | 772 | new_gh = gfs2_holder_get(gl, state, LM_FLAG_TRY, GFP_NOFS); |
773 | if (!new_gh) | 773 | if (!new_gh) |
774 | return; | 774 | return; |
775 | set_bit(HIF_DEMOTE, &new_gh->gh_iflags); | 775 | set_bit(HIF_DEMOTE, &new_gh->gh_iflags); |
@@ -785,21 +785,6 @@ out: | |||
785 | gfs2_holder_put(new_gh); | 785 | gfs2_holder_put(new_gh); |
786 | } | 786 | } |
787 | 787 | ||
788 | void gfs2_glock_inode_squish(struct inode *inode) | ||
789 | { | ||
790 | struct gfs2_holder gh; | ||
791 | struct gfs2_glock *gl = GFS2_I(inode)->i_gl; | ||
792 | gfs2_holder_init(gl, LM_ST_UNLOCKED, 0, &gh); | ||
793 | set_bit(HIF_DEMOTE, &gh.gh_iflags); | ||
794 | spin_lock(&gl->gl_spin); | ||
795 | gfs2_assert(inode->i_sb->s_fs_info, list_empty(&gl->gl_holders)); | ||
796 | list_add_tail(&gh.gh_list, &gl->gl_waiters2); | ||
797 | run_queue(gl); | ||
798 | spin_unlock(&gl->gl_spin); | ||
799 | wait_for_completion(&gh.gh_wait); | ||
800 | gfs2_holder_uninit(&gh); | ||
801 | } | ||
802 | |||
803 | /** | 788 | /** |
804 | * state_change - record that the glock is now in a different state | 789 | * state_change - record that the glock is now in a different state |
805 | * @gl: the glock | 790 | * @gl: the glock |
@@ -847,12 +832,12 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret) | |||
847 | 832 | ||
848 | if (prev_state != LM_ST_UNLOCKED && !(ret & LM_OUT_CACHEABLE)) { | 833 | if (prev_state != LM_ST_UNLOCKED && !(ret & LM_OUT_CACHEABLE)) { |
849 | if (glops->go_inval) | 834 | if (glops->go_inval) |
850 | glops->go_inval(gl, DIO_METADATA | DIO_DATA); | 835 | glops->go_inval(gl, DIO_METADATA); |
851 | } else if (gl->gl_state == LM_ST_DEFERRED) { | 836 | } else if (gl->gl_state == LM_ST_DEFERRED) { |
852 | /* We might not want to do this here. | 837 | /* We might not want to do this here. |
853 | Look at moving to the inode glops. */ | 838 | Look at moving to the inode glops. */ |
854 | if (glops->go_inval) | 839 | if (glops->go_inval) |
855 | glops->go_inval(gl, DIO_DATA); | 840 | glops->go_inval(gl, 0); |
856 | } | 841 | } |
857 | 842 | ||
858 | /* Deal with each possible exit condition */ | 843 | /* Deal with each possible exit condition */ |
@@ -954,7 +939,7 @@ void gfs2_glock_xmote_th(struct gfs2_glock *gl, unsigned int state, int flags) | |||
954 | gfs2_assert_warn(sdp, state != gl->gl_state); | 939 | gfs2_assert_warn(sdp, state != gl->gl_state); |
955 | 940 | ||
956 | if (gl->gl_state == LM_ST_EXCLUSIVE && glops->go_sync) | 941 | if (gl->gl_state == LM_ST_EXCLUSIVE && glops->go_sync) |
957 | glops->go_sync(gl, DIO_METADATA | DIO_DATA | DIO_RELEASE); | 942 | glops->go_sync(gl); |
958 | 943 | ||
959 | gfs2_glock_hold(gl); | 944 | gfs2_glock_hold(gl); |
960 | gl->gl_req_bh = xmote_bh; | 945 | gl->gl_req_bh = xmote_bh; |
@@ -995,7 +980,7 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret) | |||
995 | state_change(gl, LM_ST_UNLOCKED); | 980 | state_change(gl, LM_ST_UNLOCKED); |
996 | 981 | ||
997 | if (glops->go_inval) | 982 | if (glops->go_inval) |
998 | glops->go_inval(gl, DIO_METADATA | DIO_DATA); | 983 | glops->go_inval(gl, DIO_METADATA); |
999 | 984 | ||
1000 | if (gh) { | 985 | if (gh) { |
1001 | spin_lock(&gl->gl_spin); | 986 | spin_lock(&gl->gl_spin); |
@@ -1041,7 +1026,7 @@ void gfs2_glock_drop_th(struct gfs2_glock *gl) | |||
1041 | gfs2_assert_warn(sdp, gl->gl_state != LM_ST_UNLOCKED); | 1026 | gfs2_assert_warn(sdp, gl->gl_state != LM_ST_UNLOCKED); |
1042 | 1027 | ||
1043 | if (gl->gl_state == LM_ST_EXCLUSIVE && glops->go_sync) | 1028 | if (gl->gl_state == LM_ST_EXCLUSIVE && glops->go_sync) |
1044 | glops->go_sync(gl, DIO_METADATA | DIO_DATA | DIO_RELEASE); | 1029 | glops->go_sync(gl); |
1045 | 1030 | ||
1046 | gfs2_glock_hold(gl); | 1031 | gfs2_glock_hold(gl); |
1047 | gl->gl_req_bh = drop_bh; | 1032 | gl->gl_req_bh = drop_bh; |
@@ -1244,9 +1229,6 @@ restart: | |||
1244 | 1229 | ||
1245 | clear_bit(GLF_PREFETCH, &gl->gl_flags); | 1230 | clear_bit(GLF_PREFETCH, &gl->gl_flags); |
1246 | 1231 | ||
1247 | if (error == GLR_TRYFAILED && (gh->gh_flags & GL_DUMP)) | ||
1248 | dump_glock(gl); | ||
1249 | |||
1250 | return error; | 1232 | return error; |
1251 | } | 1233 | } |
1252 | 1234 | ||
@@ -1923,7 +1905,7 @@ out: | |||
1923 | 1905 | ||
1924 | static void scan_glock(struct gfs2_glock *gl) | 1906 | static void scan_glock(struct gfs2_glock *gl) |
1925 | { | 1907 | { |
1926 | if (gl->gl_ops == &gfs2_inode_glops) | 1908 | if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) |
1927 | return; | 1909 | return; |
1928 | 1910 | ||
1929 | if (gfs2_glmutex_trylock(gl)) { | 1911 | if (gfs2_glmutex_trylock(gl)) { |
@@ -2078,7 +2060,7 @@ static int dump_inode(struct gfs2_inode *ip) | |||
2078 | printk(KERN_INFO " num = %llu %llu\n", | 2060 | printk(KERN_INFO " num = %llu %llu\n", |
2079 | (unsigned long long)ip->i_num.no_formal_ino, | 2061 | (unsigned long long)ip->i_num.no_formal_ino, |
2080 | (unsigned long long)ip->i_num.no_addr); | 2062 | (unsigned long long)ip->i_num.no_addr); |
2081 | printk(KERN_INFO " type = %u\n", IF2DT(ip->i_di.di_mode)); | 2063 | printk(KERN_INFO " type = %u\n", IF2DT(ip->i_inode.i_mode)); |
2082 | printk(KERN_INFO " i_flags ="); | 2064 | printk(KERN_INFO " i_flags ="); |
2083 | for (x = 0; x < 32; x++) | 2065 | for (x = 0; x < 32; x++) |
2084 | if (test_bit(x, &ip->i_flags)) | 2066 | if (test_bit(x, &ip->i_flags)) |
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index 2b2a889ee2cc..fb39108fc05c 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h | |||
@@ -27,8 +27,6 @@ | |||
27 | #define GL_ATIME 0x00000200 | 27 | #define GL_ATIME 0x00000200 |
28 | #define GL_NOCACHE 0x00000400 | 28 | #define GL_NOCACHE 0x00000400 |
29 | #define GL_NOCANCEL 0x00001000 | 29 | #define GL_NOCANCEL 0x00001000 |
30 | #define GL_AOP 0x00004000 | ||
31 | #define GL_DUMP 0x00008000 | ||
32 | 30 | ||
33 | #define GLR_TRYFAILED 13 | 31 | #define GLR_TRYFAILED 13 |
34 | #define GLR_CANCELED 14 | 32 | #define GLR_CANCELED 14 |
@@ -108,7 +106,6 @@ void gfs2_glock_dq_uninit_m(unsigned int num_gh, struct gfs2_holder *ghs); | |||
108 | void gfs2_glock_prefetch_num(struct gfs2_sbd *sdp, u64 number, | 106 | void gfs2_glock_prefetch_num(struct gfs2_sbd *sdp, u64 number, |
109 | const struct gfs2_glock_operations *glops, | 107 | const struct gfs2_glock_operations *glops, |
110 | unsigned int state, int flags); | 108 | unsigned int state, int flags); |
111 | void gfs2_glock_inode_squish(struct inode *inode); | ||
112 | 109 | ||
113 | /** | 110 | /** |
114 | * gfs2_glock_nq_init - intialize a holder and enqueue it on a glock | 111 | * gfs2_glock_nq_init - intialize a holder and enqueue it on a glock |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 41a6b6818a50..b068d10bcb6e 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -92,7 +92,7 @@ static void gfs2_pte_inval(struct gfs2_glock *gl) | |||
92 | 92 | ||
93 | ip = gl->gl_object; | 93 | ip = gl->gl_object; |
94 | inode = &ip->i_inode; | 94 | inode = &ip->i_inode; |
95 | if (!ip || !S_ISREG(ip->i_di.di_mode)) | 95 | if (!ip || !S_ISREG(inode->i_mode)) |
96 | return; | 96 | return; |
97 | 97 | ||
98 | if (!test_bit(GIF_PAGED, &ip->i_flags)) | 98 | if (!test_bit(GIF_PAGED, &ip->i_flags)) |
@@ -107,89 +107,20 @@ static void gfs2_pte_inval(struct gfs2_glock *gl) | |||
107 | } | 107 | } |
108 | 108 | ||
109 | /** | 109 | /** |
110 | * gfs2_page_inval - Invalidate all pages associated with a glock | ||
111 | * @gl: the glock | ||
112 | * | ||
113 | */ | ||
114 | |||
115 | static void gfs2_page_inval(struct gfs2_glock *gl) | ||
116 | { | ||
117 | struct gfs2_inode *ip; | ||
118 | struct inode *inode; | ||
119 | |||
120 | ip = gl->gl_object; | ||
121 | inode = &ip->i_inode; | ||
122 | if (!ip || !S_ISREG(ip->i_di.di_mode)) | ||
123 | return; | ||
124 | |||
125 | truncate_inode_pages(inode->i_mapping, 0); | ||
126 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !inode->i_mapping->nrpages); | ||
127 | clear_bit(GIF_PAGED, &ip->i_flags); | ||
128 | } | ||
129 | |||
130 | /** | ||
131 | * gfs2_page_wait - Wait for writeback of data | ||
132 | * @gl: the glock | ||
133 | * | ||
134 | * Syncs data (not metadata) for a regular file. | ||
135 | * No-op for all other types. | ||
136 | */ | ||
137 | |||
138 | static void gfs2_page_wait(struct gfs2_glock *gl) | ||
139 | { | ||
140 | struct gfs2_inode *ip = gl->gl_object; | ||
141 | struct inode *inode = &ip->i_inode; | ||
142 | struct address_space *mapping = inode->i_mapping; | ||
143 | int error; | ||
144 | |||
145 | if (!S_ISREG(ip->i_di.di_mode)) | ||
146 | return; | ||
147 | |||
148 | error = filemap_fdatawait(mapping); | ||
149 | |||
150 | /* Put back any errors cleared by filemap_fdatawait() | ||
151 | so they can be caught by someone who can pass them | ||
152 | up to user space. */ | ||
153 | |||
154 | if (error == -ENOSPC) | ||
155 | set_bit(AS_ENOSPC, &mapping->flags); | ||
156 | else if (error) | ||
157 | set_bit(AS_EIO, &mapping->flags); | ||
158 | |||
159 | } | ||
160 | |||
161 | static void gfs2_page_writeback(struct gfs2_glock *gl) | ||
162 | { | ||
163 | struct gfs2_inode *ip = gl->gl_object; | ||
164 | struct inode *inode = &ip->i_inode; | ||
165 | struct address_space *mapping = inode->i_mapping; | ||
166 | |||
167 | if (!S_ISREG(ip->i_di.di_mode)) | ||
168 | return; | ||
169 | |||
170 | filemap_fdatawrite(mapping); | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * meta_go_sync - sync out the metadata for this glock | 110 | * meta_go_sync - sync out the metadata for this glock |
175 | * @gl: the glock | 111 | * @gl: the glock |
176 | * @flags: DIO_* | ||
177 | * | 112 | * |
178 | * Called when demoting or unlocking an EX glock. We must flush | 113 | * Called when demoting or unlocking an EX glock. We must flush |
179 | * to disk all dirty buffers/pages relating to this glock, and must not | 114 | * to disk all dirty buffers/pages relating to this glock, and must not |
180 | * not return to caller to demote/unlock the glock until I/O is complete. | 115 | * not return to caller to demote/unlock the glock until I/O is complete. |
181 | */ | 116 | */ |
182 | 117 | ||
183 | static void meta_go_sync(struct gfs2_glock *gl, int flags) | 118 | static void meta_go_sync(struct gfs2_glock *gl) |
184 | { | 119 | { |
185 | if (!(flags & DIO_METADATA)) | ||
186 | return; | ||
187 | |||
188 | if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) { | 120 | if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) { |
189 | gfs2_log_flush(gl->gl_sbd, gl); | 121 | gfs2_log_flush(gl->gl_sbd, gl); |
190 | gfs2_meta_sync(gl); | 122 | gfs2_meta_sync(gl); |
191 | if (flags & DIO_RELEASE) | 123 | gfs2_ail_empty_gl(gl); |
192 | gfs2_ail_empty_gl(gl); | ||
193 | } | 124 | } |
194 | 125 | ||
195 | } | 126 | } |
@@ -264,31 +195,31 @@ static void inode_go_drop_th(struct gfs2_glock *gl) | |||
264 | /** | 195 | /** |
265 | * inode_go_sync - Sync the dirty data and/or metadata for an inode glock | 196 | * inode_go_sync - Sync the dirty data and/or metadata for an inode glock |
266 | * @gl: the glock protecting the inode | 197 | * @gl: the glock protecting the inode |
267 | * @flags: | ||
268 | * | 198 | * |
269 | */ | 199 | */ |
270 | 200 | ||
271 | static void inode_go_sync(struct gfs2_glock *gl, int flags) | 201 | static void inode_go_sync(struct gfs2_glock *gl) |
272 | { | 202 | { |
273 | int meta = (flags & DIO_METADATA); | 203 | struct gfs2_inode *ip = gl->gl_object; |
274 | int data = (flags & DIO_DATA); | 204 | |
205 | if (ip && !S_ISREG(ip->i_inode.i_mode)) | ||
206 | ip = NULL; | ||
275 | 207 | ||
276 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) { | 208 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) { |
277 | if (meta && data) { | 209 | gfs2_log_flush(gl->gl_sbd, gl); |
278 | gfs2_page_writeback(gl); | 210 | if (ip) |
279 | gfs2_log_flush(gl->gl_sbd, gl); | 211 | filemap_fdatawrite(ip->i_inode.i_mapping); |
280 | gfs2_meta_sync(gl); | 212 | gfs2_meta_sync(gl); |
281 | gfs2_page_wait(gl); | 213 | if (ip) { |
282 | clear_bit(GLF_DIRTY, &gl->gl_flags); | 214 | struct address_space *mapping = ip->i_inode.i_mapping; |
283 | } else if (meta) { | 215 | int error = filemap_fdatawait(mapping); |
284 | gfs2_log_flush(gl->gl_sbd, gl); | 216 | if (error == -ENOSPC) |
285 | gfs2_meta_sync(gl); | 217 | set_bit(AS_ENOSPC, &mapping->flags); |
286 | } else if (data) { | 218 | else if (error) |
287 | gfs2_page_writeback(gl); | 219 | set_bit(AS_EIO, &mapping->flags); |
288 | gfs2_page_wait(gl); | ||
289 | } | 220 | } |
290 | if (flags & DIO_RELEASE) | 221 | clear_bit(GLF_DIRTY, &gl->gl_flags); |
291 | gfs2_ail_empty_gl(gl); | 222 | gfs2_ail_empty_gl(gl); |
292 | } | 223 | } |
293 | } | 224 | } |
294 | 225 | ||
@@ -301,15 +232,20 @@ static void inode_go_sync(struct gfs2_glock *gl, int flags) | |||
301 | 232 | ||
302 | static void inode_go_inval(struct gfs2_glock *gl, int flags) | 233 | static void inode_go_inval(struct gfs2_glock *gl, int flags) |
303 | { | 234 | { |
235 | struct gfs2_inode *ip = gl->gl_object; | ||
304 | int meta = (flags & DIO_METADATA); | 236 | int meta = (flags & DIO_METADATA); |
305 | int data = (flags & DIO_DATA); | ||
306 | 237 | ||
307 | if (meta) { | 238 | if (meta) { |
308 | gfs2_meta_inval(gl); | 239 | gfs2_meta_inval(gl); |
309 | gl->gl_vn++; | 240 | if (ip) |
241 | set_bit(GIF_INVALID, &ip->i_flags); | ||
242 | } | ||
243 | |||
244 | if (ip && S_ISREG(ip->i_inode.i_mode)) { | ||
245 | truncate_inode_pages(ip->i_inode.i_mapping, 0); | ||
246 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !ip->i_inode.i_mapping->nrpages); | ||
247 | clear_bit(GIF_PAGED, &ip->i_flags); | ||
310 | } | 248 | } |
311 | if (data) | ||
312 | gfs2_page_inval(gl); | ||
313 | } | 249 | } |
314 | 250 | ||
315 | /** | 251 | /** |
@@ -351,11 +287,10 @@ static int inode_go_lock(struct gfs2_holder *gh) | |||
351 | if (!ip) | 287 | if (!ip) |
352 | return 0; | 288 | return 0; |
353 | 289 | ||
354 | if (ip->i_vn != gl->gl_vn) { | 290 | if (test_bit(GIF_INVALID, &ip->i_flags)) { |
355 | error = gfs2_inode_refresh(ip); | 291 | error = gfs2_inode_refresh(ip); |
356 | if (error) | 292 | if (error) |
357 | return error; | 293 | return error; |
358 | gfs2_inode_attr_in(ip); | ||
359 | } | 294 | } |
360 | 295 | ||
361 | if ((ip->i_di.di_flags & GFS2_DIF_TRUNC_IN_PROG) && | 296 | if ((ip->i_di.di_flags & GFS2_DIF_TRUNC_IN_PROG) && |
@@ -379,11 +314,8 @@ static void inode_go_unlock(struct gfs2_holder *gh) | |||
379 | struct gfs2_glock *gl = gh->gh_gl; | 314 | struct gfs2_glock *gl = gh->gh_gl; |
380 | struct gfs2_inode *ip = gl->gl_object; | 315 | struct gfs2_inode *ip = gl->gl_object; |
381 | 316 | ||
382 | if (ip == NULL) | 317 | if (ip) |
383 | return; | 318 | gfs2_meta_cache_flush(ip); |
384 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) | ||
385 | gfs2_inode_attr_in(ip); | ||
386 | gfs2_meta_cache_flush(ip); | ||
387 | } | 319 | } |
388 | 320 | ||
389 | /** | 321 | /** |
@@ -491,13 +423,13 @@ static void trans_go_xmote_bh(struct gfs2_glock *gl) | |||
491 | struct gfs2_sbd *sdp = gl->gl_sbd; | 423 | struct gfs2_sbd *sdp = gl->gl_sbd; |
492 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); | 424 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); |
493 | struct gfs2_glock *j_gl = ip->i_gl; | 425 | struct gfs2_glock *j_gl = ip->i_gl; |
494 | struct gfs2_log_header head; | 426 | struct gfs2_log_header_host head; |
495 | int error; | 427 | int error; |
496 | 428 | ||
497 | if (gl->gl_state != LM_ST_UNLOCKED && | 429 | if (gl->gl_state != LM_ST_UNLOCKED && |
498 | test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { | 430 | test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { |
499 | gfs2_meta_cache_flush(GFS2_I(sdp->sd_jdesc->jd_inode)); | 431 | gfs2_meta_cache_flush(GFS2_I(sdp->sd_jdesc->jd_inode)); |
500 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA); | 432 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); |
501 | 433 | ||
502 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); | 434 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); |
503 | if (error) | 435 | if (error) |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 118dc693d111..734421edae85 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -14,8 +14,6 @@ | |||
14 | 14 | ||
15 | #define DIO_WAIT 0x00000010 | 15 | #define DIO_WAIT 0x00000010 |
16 | #define DIO_METADATA 0x00000020 | 16 | #define DIO_METADATA 0x00000020 |
17 | #define DIO_DATA 0x00000040 | ||
18 | #define DIO_RELEASE 0x00000080 | ||
19 | #define DIO_ALL 0x00000100 | 17 | #define DIO_ALL 0x00000100 |
20 | 18 | ||
21 | struct gfs2_log_operations; | 19 | struct gfs2_log_operations; |
@@ -41,7 +39,7 @@ struct gfs2_log_operations { | |||
41 | void (*lo_before_commit) (struct gfs2_sbd *sdp); | 39 | void (*lo_before_commit) (struct gfs2_sbd *sdp); |
42 | void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_ail *ai); | 40 | void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_ail *ai); |
43 | void (*lo_before_scan) (struct gfs2_jdesc *jd, | 41 | void (*lo_before_scan) (struct gfs2_jdesc *jd, |
44 | struct gfs2_log_header *head, int pass); | 42 | struct gfs2_log_header_host *head, int pass); |
45 | int (*lo_scan_elements) (struct gfs2_jdesc *jd, unsigned int start, | 43 | int (*lo_scan_elements) (struct gfs2_jdesc *jd, unsigned int start, |
46 | struct gfs2_log_descriptor *ld, __be64 *ptr, | 44 | struct gfs2_log_descriptor *ld, __be64 *ptr, |
47 | int pass); | 45 | int pass); |
@@ -67,8 +65,8 @@ struct gfs2_rgrpd { | |||
67 | struct list_head rd_list_mru; | 65 | struct list_head rd_list_mru; |
68 | struct list_head rd_recent; /* Recently used rgrps */ | 66 | struct list_head rd_recent; /* Recently used rgrps */ |
69 | struct gfs2_glock *rd_gl; /* Glock for this rgrp */ | 67 | struct gfs2_glock *rd_gl; /* Glock for this rgrp */ |
70 | struct gfs2_rindex rd_ri; | 68 | struct gfs2_rindex_host rd_ri; |
71 | struct gfs2_rgrp rd_rg; | 69 | struct gfs2_rgrp_host rd_rg; |
72 | u64 rd_rg_vn; | 70 | u64 rd_rg_vn; |
73 | struct gfs2_bitmap *rd_bits; | 71 | struct gfs2_bitmap *rd_bits; |
74 | unsigned int rd_bh_count; | 72 | unsigned int rd_bh_count; |
@@ -103,18 +101,17 @@ struct gfs2_bufdata { | |||
103 | }; | 101 | }; |
104 | 102 | ||
105 | struct gfs2_glock_operations { | 103 | struct gfs2_glock_operations { |
106 | void (*go_xmote_th) (struct gfs2_glock * gl, unsigned int state, | 104 | void (*go_xmote_th) (struct gfs2_glock *gl, unsigned int state, int flags); |
107 | int flags); | 105 | void (*go_xmote_bh) (struct gfs2_glock *gl); |
108 | void (*go_xmote_bh) (struct gfs2_glock * gl); | 106 | void (*go_drop_th) (struct gfs2_glock *gl); |
109 | void (*go_drop_th) (struct gfs2_glock * gl); | 107 | void (*go_drop_bh) (struct gfs2_glock *gl); |
110 | void (*go_drop_bh) (struct gfs2_glock * gl); | 108 | void (*go_sync) (struct gfs2_glock *gl); |
111 | void (*go_sync) (struct gfs2_glock * gl, int flags); | 109 | void (*go_inval) (struct gfs2_glock *gl, int flags); |
112 | void (*go_inval) (struct gfs2_glock * gl, int flags); | 110 | int (*go_demote_ok) (struct gfs2_glock *gl); |
113 | int (*go_demote_ok) (struct gfs2_glock * gl); | 111 | int (*go_lock) (struct gfs2_holder *gh); |
114 | int (*go_lock) (struct gfs2_holder * gh); | 112 | void (*go_unlock) (struct gfs2_holder *gh); |
115 | void (*go_unlock) (struct gfs2_holder * gh); | 113 | void (*go_callback) (struct gfs2_glock *gl, unsigned int state); |
116 | void (*go_callback) (struct gfs2_glock * gl, unsigned int state); | 114 | void (*go_greedy) (struct gfs2_glock *gl); |
117 | void (*go_greedy) (struct gfs2_glock * gl); | ||
118 | const int go_type; | 115 | const int go_type; |
119 | }; | 116 | }; |
120 | 117 | ||
@@ -217,6 +214,7 @@ struct gfs2_alloc { | |||
217 | }; | 214 | }; |
218 | 215 | ||
219 | enum { | 216 | enum { |
217 | GIF_INVALID = 0, | ||
220 | GIF_QD_LOCKED = 1, | 218 | GIF_QD_LOCKED = 1, |
221 | GIF_PAGED = 2, | 219 | GIF_PAGED = 2, |
222 | GIF_SW_PAGED = 3, | 220 | GIF_SW_PAGED = 3, |
@@ -224,12 +222,11 @@ enum { | |||
224 | 222 | ||
225 | struct gfs2_inode { | 223 | struct gfs2_inode { |
226 | struct inode i_inode; | 224 | struct inode i_inode; |
227 | struct gfs2_inum i_num; | 225 | struct gfs2_inum_host i_num; |
228 | 226 | ||
229 | unsigned long i_flags; /* GIF_... */ | 227 | unsigned long i_flags; /* GIF_... */ |
230 | 228 | ||
231 | u64 i_vn; | 229 | struct gfs2_dinode_host i_di; /* To be replaced by ref to block */ |
232 | struct gfs2_dinode i_di; /* To be replaced by ref to block */ | ||
233 | 230 | ||
234 | struct gfs2_glock *i_gl; /* Move into i_gh? */ | 231 | struct gfs2_glock *i_gl; /* Move into i_gh? */ |
235 | struct gfs2_holder i_iopen_gh; | 232 | struct gfs2_holder i_iopen_gh; |
@@ -450,7 +447,7 @@ struct gfs2_sbd { | |||
450 | struct super_block *sd_vfs_meta; | 447 | struct super_block *sd_vfs_meta; |
451 | struct kobject sd_kobj; | 448 | struct kobject sd_kobj; |
452 | unsigned long sd_flags; /* SDF_... */ | 449 | unsigned long sd_flags; /* SDF_... */ |
453 | struct gfs2_sb sd_sb; | 450 | struct gfs2_sb_host sd_sb; |
454 | 451 | ||
455 | /* Constants computed on mount */ | 452 | /* Constants computed on mount */ |
456 | 453 | ||
@@ -503,8 +500,8 @@ struct gfs2_sbd { | |||
503 | 500 | ||
504 | spinlock_t sd_statfs_spin; | 501 | spinlock_t sd_statfs_spin; |
505 | struct mutex sd_statfs_mutex; | 502 | struct mutex sd_statfs_mutex; |
506 | struct gfs2_statfs_change sd_statfs_master; | 503 | struct gfs2_statfs_change_host sd_statfs_master; |
507 | struct gfs2_statfs_change sd_statfs_local; | 504 | struct gfs2_statfs_change_host sd_statfs_local; |
508 | unsigned long sd_statfs_sync_time; | 505 | unsigned long sd_statfs_sync_time; |
509 | 506 | ||
510 | /* Resource group stuff */ | 507 | /* Resource group stuff */ |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index d470e5286ecd..d122074c45e1 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -38,83 +38,12 @@ | |||
38 | #include "trans.h" | 38 | #include "trans.h" |
39 | #include "util.h" | 39 | #include "util.h" |
40 | 40 | ||
41 | /** | ||
42 | * gfs2_inode_attr_in - Copy attributes from the dinode into the VFS inode | ||
43 | * @ip: The GFS2 inode (with embedded disk inode data) | ||
44 | * @inode: The Linux VFS inode | ||
45 | * | ||
46 | */ | ||
47 | |||
48 | void gfs2_inode_attr_in(struct gfs2_inode *ip) | ||
49 | { | ||
50 | struct inode *inode = &ip->i_inode; | ||
51 | struct gfs2_dinode *di = &ip->i_di; | ||
52 | |||
53 | inode->i_ino = ip->i_num.no_addr; | ||
54 | |||
55 | switch (di->di_mode & S_IFMT) { | ||
56 | case S_IFBLK: | ||
57 | case S_IFCHR: | ||
58 | inode->i_rdev = MKDEV(di->di_major, di->di_minor); | ||
59 | break; | ||
60 | default: | ||
61 | inode->i_rdev = 0; | ||
62 | break; | ||
63 | }; | ||
64 | |||
65 | inode->i_mode = di->di_mode; | ||
66 | inode->i_nlink = di->di_nlink; | ||
67 | inode->i_uid = di->di_uid; | ||
68 | inode->i_gid = di->di_gid; | ||
69 | i_size_write(inode, di->di_size); | ||
70 | inode->i_atime.tv_sec = di->di_atime; | ||
71 | inode->i_mtime.tv_sec = di->di_mtime; | ||
72 | inode->i_ctime.tv_sec = di->di_ctime; | ||
73 | inode->i_atime.tv_nsec = 0; | ||
74 | inode->i_mtime.tv_nsec = 0; | ||
75 | inode->i_ctime.tv_nsec = 0; | ||
76 | inode->i_blocks = di->di_blocks << | ||
77 | (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); | ||
78 | |||
79 | if (di->di_flags & GFS2_DIF_IMMUTABLE) | ||
80 | inode->i_flags |= S_IMMUTABLE; | ||
81 | else | ||
82 | inode->i_flags &= ~S_IMMUTABLE; | ||
83 | |||
84 | if (di->di_flags & GFS2_DIF_APPENDONLY) | ||
85 | inode->i_flags |= S_APPEND; | ||
86 | else | ||
87 | inode->i_flags &= ~S_APPEND; | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * gfs2_inode_attr_out - Copy attributes from VFS inode into the dinode | ||
92 | * @ip: The GFS2 inode | ||
93 | * | ||
94 | * Only copy out the attributes that we want the VFS layer | ||
95 | * to be able to modify. | ||
96 | */ | ||
97 | |||
98 | void gfs2_inode_attr_out(struct gfs2_inode *ip) | ||
99 | { | ||
100 | struct inode *inode = &ip->i_inode; | ||
101 | struct gfs2_dinode *di = &ip->i_di; | ||
102 | gfs2_assert_withdraw(GFS2_SB(inode), | ||
103 | (di->di_mode & S_IFMT) == (inode->i_mode & S_IFMT)); | ||
104 | di->di_mode = inode->i_mode; | ||
105 | di->di_uid = inode->i_uid; | ||
106 | di->di_gid = inode->i_gid; | ||
107 | di->di_atime = inode->i_atime.tv_sec; | ||
108 | di->di_mtime = inode->i_mtime.tv_sec; | ||
109 | di->di_ctime = inode->i_ctime.tv_sec; | ||
110 | } | ||
111 | |||
112 | static int iget_test(struct inode *inode, void *opaque) | 41 | static int iget_test(struct inode *inode, void *opaque) |
113 | { | 42 | { |
114 | struct gfs2_inode *ip = GFS2_I(inode); | 43 | struct gfs2_inode *ip = GFS2_I(inode); |
115 | struct gfs2_inum *inum = opaque; | 44 | struct gfs2_inum_host *inum = opaque; |
116 | 45 | ||
117 | if (ip && ip->i_num.no_addr == inum->no_addr) | 46 | if (ip->i_num.no_addr == inum->no_addr) |
118 | return 1; | 47 | return 1; |
119 | 48 | ||
120 | return 0; | 49 | return 0; |
@@ -123,19 +52,20 @@ static int iget_test(struct inode *inode, void *opaque) | |||
123 | static int iget_set(struct inode *inode, void *opaque) | 52 | static int iget_set(struct inode *inode, void *opaque) |
124 | { | 53 | { |
125 | struct gfs2_inode *ip = GFS2_I(inode); | 54 | struct gfs2_inode *ip = GFS2_I(inode); |
126 | struct gfs2_inum *inum = opaque; | 55 | struct gfs2_inum_host *inum = opaque; |
127 | 56 | ||
128 | ip->i_num = *inum; | 57 | ip->i_num = *inum; |
58 | inode->i_ino = inum->no_addr; | ||
129 | return 0; | 59 | return 0; |
130 | } | 60 | } |
131 | 61 | ||
132 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum *inum) | 62 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum) |
133 | { | 63 | { |
134 | return ilookup5(sb, (unsigned long)inum->no_formal_ino, | 64 | return ilookup5(sb, (unsigned long)inum->no_formal_ino, |
135 | iget_test, inum); | 65 | iget_test, inum); |
136 | } | 66 | } |
137 | 67 | ||
138 | static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum) | 68 | static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum) |
139 | { | 69 | { |
140 | return iget5_locked(sb, (unsigned long)inum->no_formal_ino, | 70 | return iget5_locked(sb, (unsigned long)inum->no_formal_ino, |
141 | iget_test, iget_set, inum); | 71 | iget_test, iget_set, inum); |
@@ -150,7 +80,7 @@ static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum) | |||
150 | * Returns: A VFS inode, or an error | 80 | * Returns: A VFS inode, or an error |
151 | */ | 81 | */ |
152 | 82 | ||
153 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, unsigned int type) | 83 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned int type) |
154 | { | 84 | { |
155 | struct inode *inode = gfs2_iget(sb, inum); | 85 | struct inode *inode = gfs2_iget(sb, inum); |
156 | struct gfs2_inode *ip = GFS2_I(inode); | 86 | struct gfs2_inode *ip = GFS2_I(inode); |
@@ -188,7 +118,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, | |||
188 | if (unlikely(error)) | 118 | if (unlikely(error)) |
189 | goto fail_put; | 119 | goto fail_put; |
190 | 120 | ||
191 | ip->i_vn = ip->i_gl->gl_vn - 1; | 121 | set_bit(GIF_INVALID, &ip->i_flags); |
192 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); | 122 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); |
193 | if (unlikely(error)) | 123 | if (unlikely(error)) |
194 | goto fail_iopen; | 124 | goto fail_iopen; |
@@ -208,6 +138,63 @@ fail: | |||
208 | return ERR_PTR(error); | 138 | return ERR_PTR(error); |
209 | } | 139 | } |
210 | 140 | ||
141 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | ||
142 | { | ||
143 | struct gfs2_dinode_host *di = &ip->i_di; | ||
144 | const struct gfs2_dinode *str = buf; | ||
145 | |||
146 | if (ip->i_num.no_addr != be64_to_cpu(str->di_num.no_addr)) { | ||
147 | if (gfs2_consist_inode(ip)) | ||
148 | gfs2_dinode_print(ip); | ||
149 | return -EIO; | ||
150 | } | ||
151 | if (ip->i_num.no_formal_ino != be64_to_cpu(str->di_num.no_formal_ino)) | ||
152 | return -ESTALE; | ||
153 | |||
154 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); | ||
155 | ip->i_inode.i_rdev = 0; | ||
156 | switch (ip->i_inode.i_mode & S_IFMT) { | ||
157 | case S_IFBLK: | ||
158 | case S_IFCHR: | ||
159 | ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major), | ||
160 | be32_to_cpu(str->di_minor)); | ||
161 | break; | ||
162 | }; | ||
163 | |||
164 | ip->i_inode.i_uid = be32_to_cpu(str->di_uid); | ||
165 | ip->i_inode.i_gid = be32_to_cpu(str->di_gid); | ||
166 | /* | ||
167 | * We will need to review setting the nlink count here in the | ||
168 | * light of the forthcoming ro bind mount work. This is a reminder | ||
169 | * to do that. | ||
170 | */ | ||
171 | ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink); | ||
172 | di->di_size = be64_to_cpu(str->di_size); | ||
173 | i_size_write(&ip->i_inode, di->di_size); | ||
174 | di->di_blocks = be64_to_cpu(str->di_blocks); | ||
175 | gfs2_set_inode_blocks(&ip->i_inode); | ||
176 | ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime); | ||
177 | ip->i_inode.i_atime.tv_nsec = 0; | ||
178 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); | ||
179 | ip->i_inode.i_mtime.tv_nsec = 0; | ||
180 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); | ||
181 | ip->i_inode.i_ctime.tv_nsec = 0; | ||
182 | |||
183 | di->di_goal_meta = be64_to_cpu(str->di_goal_meta); | ||
184 | di->di_goal_data = be64_to_cpu(str->di_goal_data); | ||
185 | di->di_generation = be64_to_cpu(str->di_generation); | ||
186 | |||
187 | di->di_flags = be32_to_cpu(str->di_flags); | ||
188 | gfs2_set_inode_flags(&ip->i_inode); | ||
189 | di->di_height = be16_to_cpu(str->di_height); | ||
190 | |||
191 | di->di_depth = be16_to_cpu(str->di_depth); | ||
192 | di->di_entries = be32_to_cpu(str->di_entries); | ||
193 | |||
194 | di->di_eattr = be64_to_cpu(str->di_eattr); | ||
195 | return 0; | ||
196 | } | ||
197 | |||
211 | /** | 198 | /** |
212 | * gfs2_inode_refresh - Refresh the incore copy of the dinode | 199 | * gfs2_inode_refresh - Refresh the incore copy of the dinode |
213 | * @ip: The GFS2 inode | 200 | * @ip: The GFS2 inode |
@@ -229,21 +216,11 @@ int gfs2_inode_refresh(struct gfs2_inode *ip) | |||
229 | return -EIO; | 216 | return -EIO; |
230 | } | 217 | } |
231 | 218 | ||
232 | gfs2_dinode_in(&ip->i_di, dibh->b_data); | 219 | error = gfs2_dinode_in(ip, dibh->b_data); |
233 | |||
234 | brelse(dibh); | 220 | brelse(dibh); |
221 | clear_bit(GIF_INVALID, &ip->i_flags); | ||
235 | 222 | ||
236 | if (ip->i_num.no_addr != ip->i_di.di_num.no_addr) { | 223 | return error; |
237 | if (gfs2_consist_inode(ip)) | ||
238 | gfs2_dinode_print(&ip->i_di); | ||
239 | return -EIO; | ||
240 | } | ||
241 | if (ip->i_num.no_formal_ino != ip->i_di.di_num.no_formal_ino) | ||
242 | return -ESTALE; | ||
243 | |||
244 | ip->i_vn = ip->i_gl->gl_vn; | ||
245 | |||
246 | return 0; | ||
247 | } | 224 | } |
248 | 225 | ||
249 | int gfs2_dinode_dealloc(struct gfs2_inode *ip) | 226 | int gfs2_dinode_dealloc(struct gfs2_inode *ip) |
@@ -255,7 +232,7 @@ int gfs2_dinode_dealloc(struct gfs2_inode *ip) | |||
255 | 232 | ||
256 | if (ip->i_di.di_blocks != 1) { | 233 | if (ip->i_di.di_blocks != 1) { |
257 | if (gfs2_consist_inode(ip)) | 234 | if (gfs2_consist_inode(ip)) |
258 | gfs2_dinode_print(&ip->i_di); | 235 | gfs2_dinode_print(ip); |
259 | return -EIO; | 236 | return -EIO; |
260 | } | 237 | } |
261 | 238 | ||
@@ -318,14 +295,14 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | |||
318 | u32 nlink; | 295 | u32 nlink; |
319 | int error; | 296 | int error; |
320 | 297 | ||
321 | BUG_ON(ip->i_di.di_nlink != ip->i_inode.i_nlink); | 298 | BUG_ON(diff != 1 && diff != -1); |
322 | nlink = ip->i_di.di_nlink + diff; | 299 | nlink = ip->i_inode.i_nlink + diff; |
323 | 300 | ||
324 | /* If we are reducing the nlink count, but the new value ends up being | 301 | /* If we are reducing the nlink count, but the new value ends up being |
325 | bigger than the old one, we must have underflowed. */ | 302 | bigger than the old one, we must have underflowed. */ |
326 | if (diff < 0 && nlink > ip->i_di.di_nlink) { | 303 | if (diff < 0 && nlink > ip->i_inode.i_nlink) { |
327 | if (gfs2_consist_inode(ip)) | 304 | if (gfs2_consist_inode(ip)) |
328 | gfs2_dinode_print(&ip->i_di); | 305 | gfs2_dinode_print(ip); |
329 | return -EIO; | 306 | return -EIO; |
330 | } | 307 | } |
331 | 308 | ||
@@ -333,16 +310,19 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | |||
333 | if (error) | 310 | if (error) |
334 | return error; | 311 | return error; |
335 | 312 | ||
336 | ip->i_di.di_nlink = nlink; | 313 | if (diff > 0) |
337 | ip->i_di.di_ctime = get_seconds(); | 314 | inc_nlink(&ip->i_inode); |
338 | ip->i_inode.i_nlink = nlink; | 315 | else |
316 | drop_nlink(&ip->i_inode); | ||
317 | |||
318 | ip->i_inode.i_ctime.tv_sec = get_seconds(); | ||
339 | 319 | ||
340 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 320 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
341 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 321 | gfs2_dinode_out(ip, dibh->b_data); |
342 | brelse(dibh); | 322 | brelse(dibh); |
343 | mark_inode_dirty(&ip->i_inode); | 323 | mark_inode_dirty(&ip->i_inode); |
344 | 324 | ||
345 | if (ip->i_di.di_nlink == 0) { | 325 | if (ip->i_inode.i_nlink == 0) { |
346 | struct gfs2_rgrpd *rgd; | 326 | struct gfs2_rgrpd *rgd; |
347 | struct gfs2_holder ri_gh, rg_gh; | 327 | struct gfs2_holder ri_gh, rg_gh; |
348 | 328 | ||
@@ -357,7 +337,6 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | |||
357 | if (error) | 337 | if (error) |
358 | goto out_norgrp; | 338 | goto out_norgrp; |
359 | 339 | ||
360 | clear_nlink(&ip->i_inode); | ||
361 | gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */ | 340 | gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */ |
362 | gfs2_glock_dq_uninit(&rg_gh); | 341 | gfs2_glock_dq_uninit(&rg_gh); |
363 | out_norgrp: | 342 | out_norgrp: |
@@ -394,7 +373,7 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | |||
394 | struct super_block *sb = dir->i_sb; | 373 | struct super_block *sb = dir->i_sb; |
395 | struct gfs2_inode *dip = GFS2_I(dir); | 374 | struct gfs2_inode *dip = GFS2_I(dir); |
396 | struct gfs2_holder d_gh; | 375 | struct gfs2_holder d_gh; |
397 | struct gfs2_inum inum; | 376 | struct gfs2_inum_host inum; |
398 | unsigned int type; | 377 | unsigned int type; |
399 | int error = 0; | 378 | int error = 0; |
400 | struct inode *inode = NULL; | 379 | struct inode *inode = NULL; |
@@ -436,7 +415,7 @@ static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino) | |||
436 | { | 415 | { |
437 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); | 416 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); |
438 | struct buffer_head *bh; | 417 | struct buffer_head *bh; |
439 | struct gfs2_inum_range ir; | 418 | struct gfs2_inum_range_host ir; |
440 | int error; | 419 | int error; |
441 | 420 | ||
442 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); | 421 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); |
@@ -479,7 +458,7 @@ static int pick_formal_ino_2(struct gfs2_sbd *sdp, u64 *formal_ino) | |||
479 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode); | 458 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode); |
480 | struct gfs2_holder gh; | 459 | struct gfs2_holder gh; |
481 | struct buffer_head *bh; | 460 | struct buffer_head *bh; |
482 | struct gfs2_inum_range ir; | 461 | struct gfs2_inum_range_host ir; |
483 | int error; | 462 | int error; |
484 | 463 | ||
485 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 464 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
@@ -500,21 +479,22 @@ static int pick_formal_ino_2(struct gfs2_sbd *sdp, u64 *formal_ino) | |||
500 | if (!ir.ir_length) { | 479 | if (!ir.ir_length) { |
501 | struct buffer_head *m_bh; | 480 | struct buffer_head *m_bh; |
502 | u64 x, y; | 481 | u64 x, y; |
482 | __be64 z; | ||
503 | 483 | ||
504 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); | 484 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); |
505 | if (error) | 485 | if (error) |
506 | goto out_brelse; | 486 | goto out_brelse; |
507 | 487 | ||
508 | x = *(u64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)); | 488 | z = *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)); |
509 | x = y = be64_to_cpu(x); | 489 | x = y = be64_to_cpu(z); |
510 | ir.ir_start = x; | 490 | ir.ir_start = x; |
511 | ir.ir_length = GFS2_INUM_QUANTUM; | 491 | ir.ir_length = GFS2_INUM_QUANTUM; |
512 | x += GFS2_INUM_QUANTUM; | 492 | x += GFS2_INUM_QUANTUM; |
513 | if (x < y) | 493 | if (x < y) |
514 | gfs2_consist_inode(m_ip); | 494 | gfs2_consist_inode(m_ip); |
515 | x = cpu_to_be64(x); | 495 | z = cpu_to_be64(x); |
516 | gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); | 496 | gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); |
517 | *(u64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = x; | 497 | *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = z; |
518 | 498 | ||
519 | brelse(m_bh); | 499 | brelse(m_bh); |
520 | } | 500 | } |
@@ -567,7 +547,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
567 | return error; | 547 | return error; |
568 | 548 | ||
569 | /* Don't create entries in an unlinked directory */ | 549 | /* Don't create entries in an unlinked directory */ |
570 | if (!dip->i_di.di_nlink) | 550 | if (!dip->i_inode.i_nlink) |
571 | return -EPERM; | 551 | return -EPERM; |
572 | 552 | ||
573 | error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL); | 553 | error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL); |
@@ -583,7 +563,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
583 | 563 | ||
584 | if (dip->i_di.di_entries == (u32)-1) | 564 | if (dip->i_di.di_entries == (u32)-1) |
585 | return -EFBIG; | 565 | return -EFBIG; |
586 | if (S_ISDIR(mode) && dip->i_di.di_nlink == (u32)-1) | 566 | if (S_ISDIR(mode) && dip->i_inode.i_nlink == (u32)-1) |
587 | return -EMLINK; | 567 | return -EMLINK; |
588 | 568 | ||
589 | return 0; | 569 | return 0; |
@@ -593,24 +573,24 @@ static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode, | |||
593 | unsigned int *uid, unsigned int *gid) | 573 | unsigned int *uid, unsigned int *gid) |
594 | { | 574 | { |
595 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && | 575 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && |
596 | (dip->i_di.di_mode & S_ISUID) && dip->i_di.di_uid) { | 576 | (dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) { |
597 | if (S_ISDIR(*mode)) | 577 | if (S_ISDIR(*mode)) |
598 | *mode |= S_ISUID; | 578 | *mode |= S_ISUID; |
599 | else if (dip->i_di.di_uid != current->fsuid) | 579 | else if (dip->i_inode.i_uid != current->fsuid) |
600 | *mode &= ~07111; | 580 | *mode &= ~07111; |
601 | *uid = dip->i_di.di_uid; | 581 | *uid = dip->i_inode.i_uid; |
602 | } else | 582 | } else |
603 | *uid = current->fsuid; | 583 | *uid = current->fsuid; |
604 | 584 | ||
605 | if (dip->i_di.di_mode & S_ISGID) { | 585 | if (dip->i_inode.i_mode & S_ISGID) { |
606 | if (S_ISDIR(*mode)) | 586 | if (S_ISDIR(*mode)) |
607 | *mode |= S_ISGID; | 587 | *mode |= S_ISGID; |
608 | *gid = dip->i_di.di_gid; | 588 | *gid = dip->i_inode.i_gid; |
609 | } else | 589 | } else |
610 | *gid = current->fsgid; | 590 | *gid = current->fsgid; |
611 | } | 591 | } |
612 | 592 | ||
613 | static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum *inum, | 593 | static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum, |
614 | u64 *generation) | 594 | u64 *generation) |
615 | { | 595 | { |
616 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 596 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
@@ -650,9 +630,9 @@ out: | |||
650 | */ | 630 | */ |
651 | 631 | ||
652 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 632 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, |
653 | const struct gfs2_inum *inum, unsigned int mode, | 633 | const struct gfs2_inum_host *inum, unsigned int mode, |
654 | unsigned int uid, unsigned int gid, | 634 | unsigned int uid, unsigned int gid, |
655 | const u64 *generation) | 635 | const u64 *generation, dev_t dev) |
656 | { | 636 | { |
657 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 637 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
658 | struct gfs2_dinode *di; | 638 | struct gfs2_dinode *di; |
@@ -669,14 +649,15 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
669 | di->di_mode = cpu_to_be32(mode); | 649 | di->di_mode = cpu_to_be32(mode); |
670 | di->di_uid = cpu_to_be32(uid); | 650 | di->di_uid = cpu_to_be32(uid); |
671 | di->di_gid = cpu_to_be32(gid); | 651 | di->di_gid = cpu_to_be32(gid); |
672 | di->di_nlink = cpu_to_be32(0); | 652 | di->di_nlink = 0; |
673 | di->di_size = cpu_to_be64(0); | 653 | di->di_size = 0; |
674 | di->di_blocks = cpu_to_be64(1); | 654 | di->di_blocks = cpu_to_be64(1); |
675 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds()); | 655 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds()); |
676 | di->di_major = di->di_minor = cpu_to_be32(0); | 656 | di->di_major = cpu_to_be32(MAJOR(dev)); |
657 | di->di_minor = cpu_to_be32(MINOR(dev)); | ||
677 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); | 658 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); |
678 | di->di_generation = cpu_to_be64(*generation); | 659 | di->di_generation = cpu_to_be64(*generation); |
679 | di->di_flags = cpu_to_be32(0); | 660 | di->di_flags = 0; |
680 | 661 | ||
681 | if (S_ISREG(mode)) { | 662 | if (S_ISREG(mode)) { |
682 | if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA) || | 663 | if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA) || |
@@ -693,22 +674,22 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
693 | } | 674 | } |
694 | 675 | ||
695 | di->__pad1 = 0; | 676 | di->__pad1 = 0; |
696 | di->di_payload_format = cpu_to_be32(0); | 677 | di->di_payload_format = cpu_to_be32(S_ISDIR(mode) ? GFS2_FORMAT_DE : 0); |
697 | di->di_height = cpu_to_be32(0); | 678 | di->di_height = 0; |
698 | di->__pad2 = 0; | 679 | di->__pad2 = 0; |
699 | di->__pad3 = 0; | 680 | di->__pad3 = 0; |
700 | di->di_depth = cpu_to_be16(0); | 681 | di->di_depth = 0; |
701 | di->di_entries = cpu_to_be32(0); | 682 | di->di_entries = 0; |
702 | memset(&di->__pad4, 0, sizeof(di->__pad4)); | 683 | memset(&di->__pad4, 0, sizeof(di->__pad4)); |
703 | di->di_eattr = cpu_to_be64(0); | 684 | di->di_eattr = 0; |
704 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); | 685 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); |
705 | 686 | ||
706 | brelse(dibh); | 687 | brelse(dibh); |
707 | } | 688 | } |
708 | 689 | ||
709 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 690 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, |
710 | unsigned int mode, const struct gfs2_inum *inum, | 691 | unsigned int mode, const struct gfs2_inum_host *inum, |
711 | const u64 *generation) | 692 | const u64 *generation, dev_t dev) |
712 | { | 693 | { |
713 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 694 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
714 | unsigned int uid, gid; | 695 | unsigned int uid, gid; |
@@ -729,7 +710,7 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
729 | if (error) | 710 | if (error) |
730 | goto out_quota; | 711 | goto out_quota; |
731 | 712 | ||
732 | init_dinode(dip, gl, inum, mode, uid, gid, generation); | 713 | init_dinode(dip, gl, inum, mode, uid, gid, generation, dev); |
733 | gfs2_quota_change(dip, +1, uid, gid); | 714 | gfs2_quota_change(dip, +1, uid, gid); |
734 | gfs2_trans_end(sdp); | 715 | gfs2_trans_end(sdp); |
735 | 716 | ||
@@ -759,8 +740,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
759 | if (alloc_required < 0) | 740 | if (alloc_required < 0) |
760 | goto fail; | 741 | goto fail; |
761 | if (alloc_required) { | 742 | if (alloc_required) { |
762 | error = gfs2_quota_check(dip, dip->i_di.di_uid, | 743 | error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid); |
763 | dip->i_di.di_gid); | ||
764 | if (error) | 744 | if (error) |
765 | goto fail_quota_locks; | 745 | goto fail_quota_locks; |
766 | 746 | ||
@@ -782,16 +762,16 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
782 | goto fail_quota_locks; | 762 | goto fail_quota_locks; |
783 | } | 763 | } |
784 | 764 | ||
785 | error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_di.di_mode)); | 765 | error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_inode.i_mode)); |
786 | if (error) | 766 | if (error) |
787 | goto fail_end_trans; | 767 | goto fail_end_trans; |
788 | 768 | ||
789 | error = gfs2_meta_inode_buffer(ip, &dibh); | 769 | error = gfs2_meta_inode_buffer(ip, &dibh); |
790 | if (error) | 770 | if (error) |
791 | goto fail_end_trans; | 771 | goto fail_end_trans; |
792 | ip->i_di.di_nlink = 1; | 772 | ip->i_inode.i_nlink = 1; |
793 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 773 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
794 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 774 | gfs2_dinode_out(ip, dibh->b_data); |
795 | brelse(dibh); | 775 | brelse(dibh); |
796 | return 0; | 776 | return 0; |
797 | 777 | ||
@@ -860,13 +840,13 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
860 | */ | 840 | */ |
861 | 841 | ||
862 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | 842 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, |
863 | unsigned int mode) | 843 | unsigned int mode, dev_t dev) |
864 | { | 844 | { |
865 | struct inode *inode; | 845 | struct inode *inode; |
866 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; | 846 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; |
867 | struct inode *dir = &dip->i_inode; | 847 | struct inode *dir = &dip->i_inode; |
868 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 848 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
869 | struct gfs2_inum inum; | 849 | struct gfs2_inum_host inum; |
870 | int error; | 850 | int error; |
871 | u64 generation; | 851 | u64 generation; |
872 | 852 | ||
@@ -890,35 +870,12 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
890 | if (error) | 870 | if (error) |
891 | goto fail_gunlock; | 871 | goto fail_gunlock; |
892 | 872 | ||
893 | if (inum.no_addr < dip->i_num.no_addr) { | 873 | error = gfs2_glock_nq_num(sdp, inum.no_addr, &gfs2_inode_glops, |
894 | gfs2_glock_dq(ghs); | 874 | LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); |
895 | 875 | if (error) | |
896 | error = gfs2_glock_nq_num(sdp, inum.no_addr, | 876 | goto fail_gunlock; |
897 | &gfs2_inode_glops, LM_ST_EXCLUSIVE, | ||
898 | GL_SKIP, ghs + 1); | ||
899 | if (error) { | ||
900 | return ERR_PTR(error); | ||
901 | } | ||
902 | |||
903 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs); | ||
904 | error = gfs2_glock_nq(ghs); | ||
905 | if (error) { | ||
906 | gfs2_glock_dq_uninit(ghs + 1); | ||
907 | return ERR_PTR(error); | ||
908 | } | ||
909 | |||
910 | error = create_ok(dip, name, mode); | ||
911 | if (error) | ||
912 | goto fail_gunlock2; | ||
913 | } else { | ||
914 | error = gfs2_glock_nq_num(sdp, inum.no_addr, | ||
915 | &gfs2_inode_glops, LM_ST_EXCLUSIVE, | ||
916 | GL_SKIP, ghs + 1); | ||
917 | if (error) | ||
918 | goto fail_gunlock; | ||
919 | } | ||
920 | 877 | ||
921 | error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation); | 878 | error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev); |
922 | if (error) | 879 | if (error) |
923 | goto fail_gunlock2; | 880 | goto fail_gunlock2; |
924 | 881 | ||
@@ -975,7 +932,7 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | |||
975 | 932 | ||
976 | if (ip->i_di.di_entries != 2) { | 933 | if (ip->i_di.di_entries != 2) { |
977 | if (gfs2_consist_inode(ip)) | 934 | if (gfs2_consist_inode(ip)) |
978 | gfs2_dinode_print(&ip->i_di); | 935 | gfs2_dinode_print(ip); |
979 | return -EIO; | 936 | return -EIO; |
980 | } | 937 | } |
981 | 938 | ||
@@ -997,7 +954,12 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | |||
997 | if (error) | 954 | if (error) |
998 | return error; | 955 | return error; |
999 | 956 | ||
1000 | error = gfs2_change_nlink(ip, -2); | 957 | /* It looks odd, but it really should be done twice */ |
958 | error = gfs2_change_nlink(ip, -1); | ||
959 | if (error) | ||
960 | return error; | ||
961 | |||
962 | error = gfs2_change_nlink(ip, -1); | ||
1001 | if (error) | 963 | if (error) |
1002 | return error; | 964 | return error; |
1003 | 965 | ||
@@ -1018,16 +980,16 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | |||
1018 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | 980 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, |
1019 | struct gfs2_inode *ip) | 981 | struct gfs2_inode *ip) |
1020 | { | 982 | { |
1021 | struct gfs2_inum inum; | 983 | struct gfs2_inum_host inum; |
1022 | unsigned int type; | 984 | unsigned int type; |
1023 | int error; | 985 | int error; |
1024 | 986 | ||
1025 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | 987 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) |
1026 | return -EPERM; | 988 | return -EPERM; |
1027 | 989 | ||
1028 | if ((dip->i_di.di_mode & S_ISVTX) && | 990 | if ((dip->i_inode.i_mode & S_ISVTX) && |
1029 | dip->i_di.di_uid != current->fsuid && | 991 | dip->i_inode.i_uid != current->fsuid && |
1030 | ip->i_di.di_uid != current->fsuid && !capable(CAP_FOWNER)) | 992 | ip->i_inode.i_uid != current->fsuid && !capable(CAP_FOWNER)) |
1031 | return -EPERM; | 993 | return -EPERM; |
1032 | 994 | ||
1033 | if (IS_APPEND(&dip->i_inode)) | 995 | if (IS_APPEND(&dip->i_inode)) |
@@ -1044,7 +1006,7 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
1044 | if (!gfs2_inum_equal(&inum, &ip->i_num)) | 1006 | if (!gfs2_inum_equal(&inum, &ip->i_num)) |
1045 | return -ENOENT; | 1007 | return -ENOENT; |
1046 | 1008 | ||
1047 | if (IF2DT(ip->i_di.di_mode) != type) { | 1009 | if (IF2DT(ip->i_inode.i_mode) != type) { |
1048 | gfs2_consist_inode(dip); | 1010 | gfs2_consist_inode(dip); |
1049 | return -EIO; | 1011 | return -EIO; |
1050 | } | 1012 | } |
@@ -1194,7 +1156,7 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1194 | return 0; | 1156 | return 0; |
1195 | 1157 | ||
1196 | curtime = get_seconds(); | 1158 | curtime = get_seconds(); |
1197 | if (curtime - ip->i_di.di_atime >= quantum) { | 1159 | if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) { |
1198 | gfs2_glock_dq(gh); | 1160 | gfs2_glock_dq(gh); |
1199 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, | 1161 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, |
1200 | gh); | 1162 | gh); |
@@ -1206,7 +1168,7 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1206 | trying to get exclusive lock. */ | 1168 | trying to get exclusive lock. */ |
1207 | 1169 | ||
1208 | curtime = get_seconds(); | 1170 | curtime = get_seconds(); |
1209 | if (curtime - ip->i_di.di_atime >= quantum) { | 1171 | if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) { |
1210 | struct buffer_head *dibh; | 1172 | struct buffer_head *dibh; |
1211 | struct gfs2_dinode *di; | 1173 | struct gfs2_dinode *di; |
1212 | 1174 | ||
@@ -1220,11 +1182,11 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1220 | if (error) | 1182 | if (error) |
1221 | goto fail_end_trans; | 1183 | goto fail_end_trans; |
1222 | 1184 | ||
1223 | ip->i_di.di_atime = curtime; | 1185 | ip->i_inode.i_atime.tv_sec = curtime; |
1224 | 1186 | ||
1225 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1187 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1226 | di = (struct gfs2_dinode *)dibh->b_data; | 1188 | di = (struct gfs2_dinode *)dibh->b_data; |
1227 | di->di_atime = cpu_to_be64(ip->i_di.di_atime); | 1189 | di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); |
1228 | brelse(dibh); | 1190 | brelse(dibh); |
1229 | 1191 | ||
1230 | gfs2_trans_end(sdp); | 1192 | gfs2_trans_end(sdp); |
@@ -1249,92 +1211,6 @@ fail: | |||
1249 | return error; | 1211 | return error; |
1250 | } | 1212 | } |
1251 | 1213 | ||
1252 | /** | ||
1253 | * glock_compare_atime - Compare two struct gfs2_glock structures for sort | ||
1254 | * @arg_a: the first structure | ||
1255 | * @arg_b: the second structure | ||
1256 | * | ||
1257 | * Returns: 1 if A > B | ||
1258 | * -1 if A < B | ||
1259 | * 0 if A == B | ||
1260 | */ | ||
1261 | |||
1262 | static int glock_compare_atime(const void *arg_a, const void *arg_b) | ||
1263 | { | ||
1264 | const struct gfs2_holder *gh_a = *(const struct gfs2_holder **)arg_a; | ||
1265 | const struct gfs2_holder *gh_b = *(const struct gfs2_holder **)arg_b; | ||
1266 | const struct lm_lockname *a = &gh_a->gh_gl->gl_name; | ||
1267 | const struct lm_lockname *b = &gh_b->gh_gl->gl_name; | ||
1268 | |||
1269 | if (a->ln_number > b->ln_number) | ||
1270 | return 1; | ||
1271 | if (a->ln_number < b->ln_number) | ||
1272 | return -1; | ||
1273 | if (gh_a->gh_state == LM_ST_SHARED && gh_b->gh_state == LM_ST_EXCLUSIVE) | ||
1274 | return 1; | ||
1275 | if (gh_a->gh_state == LM_ST_SHARED && (gh_b->gh_flags & GL_ATIME)) | ||
1276 | return 1; | ||
1277 | |||
1278 | return 0; | ||
1279 | } | ||
1280 | |||
1281 | /** | ||
1282 | * gfs2_glock_nq_m_atime - acquire multiple glocks where one may need an | ||
1283 | * atime update | ||
1284 | * @num_gh: the number of structures | ||
1285 | * @ghs: an array of struct gfs2_holder structures | ||
1286 | * | ||
1287 | * Returns: 0 on success (all glocks acquired), | ||
1288 | * errno on failure (no glocks acquired) | ||
1289 | */ | ||
1290 | |||
1291 | int gfs2_glock_nq_m_atime(unsigned int num_gh, struct gfs2_holder *ghs) | ||
1292 | { | ||
1293 | struct gfs2_holder **p; | ||
1294 | unsigned int x; | ||
1295 | int error = 0; | ||
1296 | |||
1297 | if (!num_gh) | ||
1298 | return 0; | ||
1299 | |||
1300 | if (num_gh == 1) { | ||
1301 | ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); | ||
1302 | if (ghs->gh_flags & GL_ATIME) | ||
1303 | error = gfs2_glock_nq_atime(ghs); | ||
1304 | else | ||
1305 | error = gfs2_glock_nq(ghs); | ||
1306 | return error; | ||
1307 | } | ||
1308 | |||
1309 | p = kcalloc(num_gh, sizeof(struct gfs2_holder *), GFP_KERNEL); | ||
1310 | if (!p) | ||
1311 | return -ENOMEM; | ||
1312 | |||
1313 | for (x = 0; x < num_gh; x++) | ||
1314 | p[x] = &ghs[x]; | ||
1315 | |||
1316 | sort(p, num_gh, sizeof(struct gfs2_holder *), glock_compare_atime,NULL); | ||
1317 | |||
1318 | for (x = 0; x < num_gh; x++) { | ||
1319 | p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); | ||
1320 | |||
1321 | if (p[x]->gh_flags & GL_ATIME) | ||
1322 | error = gfs2_glock_nq_atime(p[x]); | ||
1323 | else | ||
1324 | error = gfs2_glock_nq(p[x]); | ||
1325 | |||
1326 | if (error) { | ||
1327 | while (x--) | ||
1328 | gfs2_glock_dq(p[x]); | ||
1329 | break; | ||
1330 | } | ||
1331 | } | ||
1332 | |||
1333 | kfree(p); | ||
1334 | return error; | ||
1335 | } | ||
1336 | |||
1337 | |||
1338 | static int | 1214 | static int |
1339 | __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | 1215 | __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) |
1340 | { | 1216 | { |
@@ -1345,10 +1221,8 @@ __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | |||
1345 | if (!error) { | 1221 | if (!error) { |
1346 | error = inode_setattr(&ip->i_inode, attr); | 1222 | error = inode_setattr(&ip->i_inode, attr); |
1347 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); | 1223 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); |
1348 | gfs2_inode_attr_out(ip); | ||
1349 | |||
1350 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1224 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1351 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1225 | gfs2_dinode_out(ip, dibh->b_data); |
1352 | brelse(dibh); | 1226 | brelse(dibh); |
1353 | } | 1227 | } |
1354 | return error; | 1228 | return error; |
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index f5d861760579..b57f448b15bc 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h | |||
@@ -22,13 +22,19 @@ static inline int gfs2_is_jdata(struct gfs2_inode *ip) | |||
22 | 22 | ||
23 | static inline int gfs2_is_dir(struct gfs2_inode *ip) | 23 | static inline int gfs2_is_dir(struct gfs2_inode *ip) |
24 | { | 24 | { |
25 | return S_ISDIR(ip->i_di.di_mode); | 25 | return S_ISDIR(ip->i_inode.i_mode); |
26 | } | ||
27 | |||
28 | static inline void gfs2_set_inode_blocks(struct inode *inode) | ||
29 | { | ||
30 | struct gfs2_inode *ip = GFS2_I(inode); | ||
31 | inode->i_blocks = ip->i_di.di_blocks << | ||
32 | (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); | ||
26 | } | 33 | } |
27 | 34 | ||
28 | void gfs2_inode_attr_in(struct gfs2_inode *ip); | 35 | void gfs2_inode_attr_in(struct gfs2_inode *ip); |
29 | void gfs2_inode_attr_out(struct gfs2_inode *ip); | 36 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned type); |
30 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, unsigned type); | 37 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum); |
31 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum *inum); | ||
32 | 38 | ||
33 | int gfs2_inode_refresh(struct gfs2_inode *ip); | 39 | int gfs2_inode_refresh(struct gfs2_inode *ip); |
34 | 40 | ||
@@ -37,19 +43,15 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff); | |||
37 | struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | 43 | struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, |
38 | int is_root, struct nameidata *nd); | 44 | int is_root, struct nameidata *nd); |
39 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | 45 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, |
40 | unsigned int mode); | 46 | unsigned int mode, dev_t dev); |
41 | int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | 47 | int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, |
42 | struct gfs2_inode *ip); | 48 | struct gfs2_inode *ip); |
43 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | 49 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, |
44 | struct gfs2_inode *ip); | 50 | struct gfs2_inode *ip); |
45 | int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to); | 51 | int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to); |
46 | int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len); | 52 | int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len); |
47 | |||
48 | int gfs2_glock_nq_atime(struct gfs2_holder *gh); | 53 | int gfs2_glock_nq_atime(struct gfs2_holder *gh); |
49 | int gfs2_glock_nq_m_atime(unsigned int num_gh, struct gfs2_holder *ghs); | ||
50 | |||
51 | int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); | 54 | int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); |
52 | |||
53 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); | 55 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); |
54 | 56 | ||
55 | #endif /* __INODE_DOT_H__ */ | 57 | #endif /* __INODE_DOT_H__ */ |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 0cace3da9dbb..291415ddfe51 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/gfs2_ondisk.h> | 15 | #include <linux/gfs2_ondisk.h> |
16 | #include <linux/crc32.h> | 16 | #include <linux/crc32.h> |
17 | #include <linux/lm_interface.h> | 17 | #include <linux/lm_interface.h> |
18 | #include <linux/delay.h> | ||
18 | 19 | ||
19 | #include "gfs2.h" | 20 | #include "gfs2.h" |
20 | #include "incore.h" | 21 | #include "incore.h" |
@@ -142,7 +143,7 @@ static int gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai, int fl | |||
142 | return list_empty(&ai->ai_ail1_list); | 143 | return list_empty(&ai->ai_ail1_list); |
143 | } | 144 | } |
144 | 145 | ||
145 | void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags) | 146 | static void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags) |
146 | { | 147 | { |
147 | struct list_head *head = &sdp->sd_ail1_list; | 148 | struct list_head *head = &sdp->sd_ail1_list; |
148 | u64 sync_gen; | 149 | u64 sync_gen; |
@@ -261,6 +262,12 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) | |||
261 | * @sdp: The GFS2 superblock | 262 | * @sdp: The GFS2 superblock |
262 | * @blks: The number of blocks to reserve | 263 | * @blks: The number of blocks to reserve |
263 | * | 264 | * |
265 | * Note that we never give out the last 6 blocks of the journal. Thats | ||
266 | * due to the fact that there is are a small number of header blocks | ||
267 | * associated with each log flush. The exact number can't be known until | ||
268 | * flush time, so we ensure that we have just enough free blocks at all | ||
269 | * times to avoid running out during a log flush. | ||
270 | * | ||
264 | * Returns: errno | 271 | * Returns: errno |
265 | */ | 272 | */ |
266 | 273 | ||
@@ -274,7 +281,7 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) | |||
274 | 281 | ||
275 | mutex_lock(&sdp->sd_log_reserve_mutex); | 282 | mutex_lock(&sdp->sd_log_reserve_mutex); |
276 | gfs2_log_lock(sdp); | 283 | gfs2_log_lock(sdp); |
277 | while(sdp->sd_log_blks_free <= blks) { | 284 | while(sdp->sd_log_blks_free <= (blks + 6)) { |
278 | gfs2_log_unlock(sdp); | 285 | gfs2_log_unlock(sdp); |
279 | gfs2_ail1_empty(sdp, 0); | 286 | gfs2_ail1_empty(sdp, 0); |
280 | gfs2_log_flush(sdp, NULL); | 287 | gfs2_log_flush(sdp, NULL); |
@@ -319,7 +326,8 @@ static u64 log_bmap(struct gfs2_sbd *sdp, unsigned int lbn) | |||
319 | bh_map.b_size = 1 << inode->i_blkbits; | 326 | bh_map.b_size = 1 << inode->i_blkbits; |
320 | error = gfs2_block_map(inode, lbn, 0, &bh_map); | 327 | error = gfs2_block_map(inode, lbn, 0, &bh_map); |
321 | if (error || !bh_map.b_blocknr) | 328 | if (error || !bh_map.b_blocknr) |
322 | printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, bh_map.b_blocknr, lbn); | 329 | printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, |
330 | (unsigned long long)bh_map.b_blocknr, lbn); | ||
323 | gfs2_assert_withdraw(sdp, !error && bh_map.b_blocknr); | 331 | gfs2_assert_withdraw(sdp, !error && bh_map.b_blocknr); |
324 | 332 | ||
325 | return bh_map.b_blocknr; | 333 | return bh_map.b_blocknr; |
@@ -643,12 +651,9 @@ void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | |||
643 | up_read(&sdp->sd_log_flush_lock); | 651 | up_read(&sdp->sd_log_flush_lock); |
644 | 652 | ||
645 | gfs2_log_lock(sdp); | 653 | gfs2_log_lock(sdp); |
646 | if (sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks)) { | 654 | if (sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks)) |
647 | gfs2_log_unlock(sdp); | 655 | wake_up_process(sdp->sd_logd_process); |
648 | gfs2_log_flush(sdp, NULL); | 656 | gfs2_log_unlock(sdp); |
649 | } else { | ||
650 | gfs2_log_unlock(sdp); | ||
651 | } | ||
652 | } | 657 | } |
653 | 658 | ||
654 | /** | 659 | /** |
@@ -686,3 +691,21 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp) | |||
686 | up_write(&sdp->sd_log_flush_lock); | 691 | up_write(&sdp->sd_log_flush_lock); |
687 | } | 692 | } |
688 | 693 | ||
694 | |||
695 | /** | ||
696 | * gfs2_meta_syncfs - sync all the buffers in a filesystem | ||
697 | * @sdp: the filesystem | ||
698 | * | ||
699 | */ | ||
700 | |||
701 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp) | ||
702 | { | ||
703 | gfs2_log_flush(sdp, NULL); | ||
704 | for (;;) { | ||
705 | gfs2_ail1_start(sdp, DIO_ALL); | ||
706 | if (gfs2_ail1_empty(sdp, DIO_ALL)) | ||
707 | break; | ||
708 | msleep(10); | ||
709 | } | ||
710 | } | ||
711 | |||
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h index 7f5737d55612..8e7aa0f29109 100644 --- a/fs/gfs2/log.h +++ b/fs/gfs2/log.h | |||
@@ -48,7 +48,6 @@ static inline void gfs2_log_pointers_init(struct gfs2_sbd *sdp, | |||
48 | unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, | 48 | unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, |
49 | unsigned int ssize); | 49 | unsigned int ssize); |
50 | 50 | ||
51 | void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags); | ||
52 | int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags); | 51 | int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags); |
53 | 52 | ||
54 | int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); | 53 | int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); |
@@ -61,5 +60,6 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); | |||
61 | void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); | 60 | void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); |
62 | 61 | ||
63 | void gfs2_log_shutdown(struct gfs2_sbd *sdp); | 62 | void gfs2_log_shutdown(struct gfs2_sbd *sdp); |
63 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp); | ||
64 | 64 | ||
65 | #endif /* __LOG_DOT_H__ */ | 65 | #endif /* __LOG_DOT_H__ */ |
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index ab6d1115f95d..4d7f94d8c7bd 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -182,7 +182,7 @@ static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | |||
182 | } | 182 | } |
183 | 183 | ||
184 | static void buf_lo_before_scan(struct gfs2_jdesc *jd, | 184 | static void buf_lo_before_scan(struct gfs2_jdesc *jd, |
185 | struct gfs2_log_header *head, int pass) | 185 | struct gfs2_log_header_host *head, int pass) |
186 | { | 186 | { |
187 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); | 187 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
188 | 188 | ||
@@ -328,7 +328,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp) | |||
328 | } | 328 | } |
329 | 329 | ||
330 | static void revoke_lo_before_scan(struct gfs2_jdesc *jd, | 330 | static void revoke_lo_before_scan(struct gfs2_jdesc *jd, |
331 | struct gfs2_log_header *head, int pass) | 331 | struct gfs2_log_header_host *head, int pass) |
332 | { | 332 | { |
333 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); | 333 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
334 | 334 | ||
@@ -509,7 +509,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
509 | { | 509 | { |
510 | LIST_HEAD(started); | 510 | LIST_HEAD(started); |
511 | struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt; | 511 | struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt; |
512 | struct buffer_head *bh = NULL; | 512 | struct buffer_head *bh = NULL,*bh1 = NULL; |
513 | unsigned int offset = sizeof(struct gfs2_log_descriptor); | 513 | unsigned int offset = sizeof(struct gfs2_log_descriptor); |
514 | struct gfs2_log_descriptor *ld; | 514 | struct gfs2_log_descriptor *ld; |
515 | unsigned int limit; | 515 | unsigned int limit; |
@@ -537,8 +537,13 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
537 | list_for_each_entry_safe_continue(bd1, bdt, | 537 | list_for_each_entry_safe_continue(bd1, bdt, |
538 | &sdp->sd_log_le_databuf, | 538 | &sdp->sd_log_le_databuf, |
539 | bd_le.le_list) { | 539 | bd_le.le_list) { |
540 | /* store off the buffer head in a local ptr since | ||
541 | * gfs2_bufdata might change when we drop the log lock | ||
542 | */ | ||
543 | bh1 = bd1->bd_bh; | ||
544 | |||
540 | /* An ordered write buffer */ | 545 | /* An ordered write buffer */ |
541 | if (bd1->bd_bh && !buffer_pinned(bd1->bd_bh)) { | 546 | if (bh1 && !buffer_pinned(bh1)) { |
542 | list_move(&bd1->bd_le.le_list, &started); | 547 | list_move(&bd1->bd_le.le_list, &started); |
543 | if (bd1 == bd2) { | 548 | if (bd1 == bd2) { |
544 | bd2 = NULL; | 549 | bd2 = NULL; |
@@ -547,20 +552,21 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
547 | bd_le.le_list); | 552 | bd_le.le_list); |
548 | } | 553 | } |
549 | total_dbuf--; | 554 | total_dbuf--; |
550 | if (bd1->bd_bh) { | 555 | if (bh1) { |
551 | get_bh(bd1->bd_bh); | 556 | if (buffer_dirty(bh1)) { |
552 | if (buffer_dirty(bd1->bd_bh)) { | 557 | get_bh(bh1); |
558 | |||
553 | gfs2_log_unlock(sdp); | 559 | gfs2_log_unlock(sdp); |
554 | wait_on_buffer(bd1->bd_bh); | 560 | |
555 | ll_rw_block(WRITE, 1, | 561 | ll_rw_block(SWRITE, 1, &bh1); |
556 | &bd1->bd_bh); | 562 | brelse(bh1); |
563 | |||
557 | gfs2_log_lock(sdp); | 564 | gfs2_log_lock(sdp); |
558 | } | 565 | } |
559 | brelse(bd1->bd_bh); | ||
560 | continue; | 566 | continue; |
561 | } | 567 | } |
562 | continue; | 568 | continue; |
563 | } else if (bd1->bd_bh) { /* A journaled buffer */ | 569 | } else if (bh1) { /* A journaled buffer */ |
564 | int magic; | 570 | int magic; |
565 | gfs2_log_unlock(sdp); | 571 | gfs2_log_unlock(sdp); |
566 | if (!bh) { | 572 | if (!bh) { |
@@ -582,16 +588,16 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
582 | ld->ld_data2 = cpu_to_be32(0); | 588 | ld->ld_data2 = cpu_to_be32(0); |
583 | memset(ld->ld_reserved, 0, sizeof(ld->ld_reserved)); | 589 | memset(ld->ld_reserved, 0, sizeof(ld->ld_reserved)); |
584 | } | 590 | } |
585 | magic = gfs2_check_magic(bd1->bd_bh); | 591 | magic = gfs2_check_magic(bh1); |
586 | *ptr++ = cpu_to_be64(bd1->bd_bh->b_blocknr); | 592 | *ptr++ = cpu_to_be64(bh1->b_blocknr); |
587 | *ptr++ = cpu_to_be64((__u64)magic); | 593 | *ptr++ = cpu_to_be64((__u64)magic); |
588 | clear_buffer_escaped(bd1->bd_bh); | 594 | clear_buffer_escaped(bh1); |
589 | if (unlikely(magic != 0)) | 595 | if (unlikely(magic != 0)) |
590 | set_buffer_escaped(bd1->bd_bh); | 596 | set_buffer_escaped(bh1); |
591 | gfs2_log_lock(sdp); | 597 | gfs2_log_lock(sdp); |
592 | if (n++ > num) | 598 | if (n++ > num) |
593 | break; | 599 | break; |
594 | } else if (!bd1->bd_bh) { | 600 | } else if (!bh1) { |
595 | total_dbuf--; | 601 | total_dbuf--; |
596 | sdp->sd_log_num_databuf--; | 602 | sdp->sd_log_num_databuf--; |
597 | list_del_init(&bd1->bd_le.le_list); | 603 | list_del_init(&bd1->bd_le.le_list); |
diff --git a/fs/gfs2/lops.h b/fs/gfs2/lops.h index 5839c05ae6be..965bc65c7c64 100644 --- a/fs/gfs2/lops.h +++ b/fs/gfs2/lops.h | |||
@@ -60,7 +60,7 @@ static inline void lops_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | |||
60 | } | 60 | } |
61 | 61 | ||
62 | static inline void lops_before_scan(struct gfs2_jdesc *jd, | 62 | static inline void lops_before_scan(struct gfs2_jdesc *jd, |
63 | struct gfs2_log_header *head, | 63 | struct gfs2_log_header_host *head, |
64 | unsigned int pass) | 64 | unsigned int pass) |
65 | { | 65 | { |
66 | int x; | 66 | int x; |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 3912d6a4b1e6..0e34d9918973 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -127,17 +127,17 @@ void gfs2_meta_sync(struct gfs2_glock *gl) | |||
127 | 127 | ||
128 | /** | 128 | /** |
129 | * getbuf - Get a buffer with a given address space | 129 | * getbuf - Get a buffer with a given address space |
130 | * @sdp: the filesystem | 130 | * @gl: the glock |
131 | * @aspace: the address space | ||
132 | * @blkno: the block number (filesystem scope) | 131 | * @blkno: the block number (filesystem scope) |
133 | * @create: 1 if the buffer should be created | 132 | * @create: 1 if the buffer should be created |
134 | * | 133 | * |
135 | * Returns: the buffer | 134 | * Returns: the buffer |
136 | */ | 135 | */ |
137 | 136 | ||
138 | static struct buffer_head *getbuf(struct gfs2_sbd *sdp, struct inode *aspace, | 137 | static struct buffer_head *getbuf(struct gfs2_glock *gl, u64 blkno, int create) |
139 | u64 blkno, int create) | ||
140 | { | 138 | { |
139 | struct address_space *mapping = gl->gl_aspace->i_mapping; | ||
140 | struct gfs2_sbd *sdp = gl->gl_sbd; | ||
141 | struct page *page; | 141 | struct page *page; |
142 | struct buffer_head *bh; | 142 | struct buffer_head *bh; |
143 | unsigned int shift; | 143 | unsigned int shift; |
@@ -150,13 +150,13 @@ static struct buffer_head *getbuf(struct gfs2_sbd *sdp, struct inode *aspace, | |||
150 | 150 | ||
151 | if (create) { | 151 | if (create) { |
152 | for (;;) { | 152 | for (;;) { |
153 | page = grab_cache_page(aspace->i_mapping, index); | 153 | page = grab_cache_page(mapping, index); |
154 | if (page) | 154 | if (page) |
155 | break; | 155 | break; |
156 | yield(); | 156 | yield(); |
157 | } | 157 | } |
158 | } else { | 158 | } else { |
159 | page = find_lock_page(aspace->i_mapping, index); | 159 | page = find_lock_page(mapping, index); |
160 | if (!page) | 160 | if (!page) |
161 | return NULL; | 161 | return NULL; |
162 | } | 162 | } |
@@ -202,7 +202,7 @@ static void meta_prep_new(struct buffer_head *bh) | |||
202 | struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) | 202 | struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) |
203 | { | 203 | { |
204 | struct buffer_head *bh; | 204 | struct buffer_head *bh; |
205 | bh = getbuf(gl->gl_sbd, gl->gl_aspace, blkno, CREATE); | 205 | bh = getbuf(gl, blkno, CREATE); |
206 | meta_prep_new(bh); | 206 | meta_prep_new(bh); |
207 | return bh; | 207 | return bh; |
208 | } | 208 | } |
@@ -220,7 +220,7 @@ struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) | |||
220 | int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, | 220 | int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, |
221 | struct buffer_head **bhp) | 221 | struct buffer_head **bhp) |
222 | { | 222 | { |
223 | *bhp = getbuf(gl->gl_sbd, gl->gl_aspace, blkno, CREATE); | 223 | *bhp = getbuf(gl, blkno, CREATE); |
224 | if (!buffer_uptodate(*bhp)) | 224 | if (!buffer_uptodate(*bhp)) |
225 | ll_rw_block(READ_META, 1, bhp); | 225 | ll_rw_block(READ_META, 1, bhp); |
226 | if (flags & DIO_WAIT) { | 226 | if (flags & DIO_WAIT) { |
@@ -379,11 +379,10 @@ void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh, | |||
379 | void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen) | 379 | void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen) |
380 | { | 380 | { |
381 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 381 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
382 | struct inode *aspace = ip->i_gl->gl_aspace; | ||
383 | struct buffer_head *bh; | 382 | struct buffer_head *bh; |
384 | 383 | ||
385 | while (blen) { | 384 | while (blen) { |
386 | bh = getbuf(sdp, aspace, bstart, NO_CREATE); | 385 | bh = getbuf(ip->i_gl, bstart, NO_CREATE); |
387 | if (bh) { | 386 | if (bh) { |
388 | struct gfs2_bufdata *bd = bh->b_private; | 387 | struct gfs2_bufdata *bd = bh->b_private; |
389 | 388 | ||
@@ -472,6 +471,9 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, | |||
472 | struct buffer_head *bh = NULL, **bh_slot = ip->i_cache + height; | 471 | struct buffer_head *bh = NULL, **bh_slot = ip->i_cache + height; |
473 | int in_cache = 0; | 472 | int in_cache = 0; |
474 | 473 | ||
474 | BUG_ON(!gl); | ||
475 | BUG_ON(!sdp); | ||
476 | |||
475 | spin_lock(&ip->i_spin); | 477 | spin_lock(&ip->i_spin); |
476 | if (*bh_slot && (*bh_slot)->b_blocknr == num) { | 478 | if (*bh_slot && (*bh_slot)->b_blocknr == num) { |
477 | bh = *bh_slot; | 479 | bh = *bh_slot; |
@@ -481,7 +483,7 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, | |||
481 | spin_unlock(&ip->i_spin); | 483 | spin_unlock(&ip->i_spin); |
482 | 484 | ||
483 | if (!bh) | 485 | if (!bh) |
484 | bh = getbuf(gl->gl_sbd, gl->gl_aspace, num, CREATE); | 486 | bh = getbuf(gl, num, CREATE); |
485 | 487 | ||
486 | if (!bh) | 488 | if (!bh) |
487 | return -ENOBUFS; | 489 | return -ENOBUFS; |
@@ -532,7 +534,6 @@ err: | |||
532 | struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) | 534 | struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) |
533 | { | 535 | { |
534 | struct gfs2_sbd *sdp = gl->gl_sbd; | 536 | struct gfs2_sbd *sdp = gl->gl_sbd; |
535 | struct inode *aspace = gl->gl_aspace; | ||
536 | struct buffer_head *first_bh, *bh; | 537 | struct buffer_head *first_bh, *bh; |
537 | u32 max_ra = gfs2_tune_get(sdp, gt_max_readahead) >> | 538 | u32 max_ra = gfs2_tune_get(sdp, gt_max_readahead) >> |
538 | sdp->sd_sb.sb_bsize_shift; | 539 | sdp->sd_sb.sb_bsize_shift; |
@@ -544,7 +545,7 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) | |||
544 | if (extlen > max_ra) | 545 | if (extlen > max_ra) |
545 | extlen = max_ra; | 546 | extlen = max_ra; |
546 | 547 | ||
547 | first_bh = getbuf(sdp, aspace, dblock, CREATE); | 548 | first_bh = getbuf(gl, dblock, CREATE); |
548 | 549 | ||
549 | if (buffer_uptodate(first_bh)) | 550 | if (buffer_uptodate(first_bh)) |
550 | goto out; | 551 | goto out; |
@@ -555,7 +556,7 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) | |||
555 | extlen--; | 556 | extlen--; |
556 | 557 | ||
557 | while (extlen) { | 558 | while (extlen) { |
558 | bh = getbuf(sdp, aspace, dblock, CREATE); | 559 | bh = getbuf(gl, dblock, CREATE); |
559 | 560 | ||
560 | if (!buffer_uptodate(bh) && !buffer_locked(bh)) | 561 | if (!buffer_uptodate(bh) && !buffer_locked(bh)) |
561 | ll_rw_block(READA, 1, &bh); | 562 | ll_rw_block(READA, 1, &bh); |
@@ -571,20 +572,3 @@ out: | |||
571 | return first_bh; | 572 | return first_bh; |
572 | } | 573 | } |
573 | 574 | ||
574 | /** | ||
575 | * gfs2_meta_syncfs - sync all the buffers in a filesystem | ||
576 | * @sdp: the filesystem | ||
577 | * | ||
578 | */ | ||
579 | |||
580 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp) | ||
581 | { | ||
582 | gfs2_log_flush(sdp, NULL); | ||
583 | for (;;) { | ||
584 | gfs2_ail1_start(sdp, DIO_ALL); | ||
585 | if (gfs2_ail1_empty(sdp, DIO_ALL)) | ||
586 | break; | ||
587 | msleep(10); | ||
588 | } | ||
589 | } | ||
590 | |||
diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h index 3ec939e20dff..e037425bc042 100644 --- a/fs/gfs2/meta_io.h +++ b/fs/gfs2/meta_io.h | |||
@@ -67,7 +67,6 @@ static inline int gfs2_meta_inode_buffer(struct gfs2_inode *ip, | |||
67 | } | 67 | } |
68 | 68 | ||
69 | struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen); | 69 | struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen); |
70 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp); | ||
71 | 70 | ||
72 | #define buffer_busy(bh) \ | 71 | #define buffer_busy(bh) \ |
73 | ((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock) | (1ul << BH_Pinned))) | 72 | ((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock) | (1ul << BH_Pinned))) |
diff --git a/fs/gfs2/ondisk.c b/fs/gfs2/ondisk.c index 1025960b0e6e..f2495f1e21ad 100644 --- a/fs/gfs2/ondisk.c +++ b/fs/gfs2/ondisk.c | |||
@@ -15,6 +15,8 @@ | |||
15 | 15 | ||
16 | #include "gfs2.h" | 16 | #include "gfs2.h" |
17 | #include <linux/gfs2_ondisk.h> | 17 | #include <linux/gfs2_ondisk.h> |
18 | #include <linux/lm_interface.h> | ||
19 | #include "incore.h" | ||
18 | 20 | ||
19 | #define pv(struct, member, fmt) printk(KERN_INFO " "#member" = "fmt"\n", \ | 21 | #define pv(struct, member, fmt) printk(KERN_INFO " "#member" = "fmt"\n", \ |
20 | struct->member); | 22 | struct->member); |
@@ -32,7 +34,7 @@ | |||
32 | * first arg: the cpu-order structure | 34 | * first arg: the cpu-order structure |
33 | */ | 35 | */ |
34 | 36 | ||
35 | void gfs2_inum_in(struct gfs2_inum *no, const void *buf) | 37 | void gfs2_inum_in(struct gfs2_inum_host *no, const void *buf) |
36 | { | 38 | { |
37 | const struct gfs2_inum *str = buf; | 39 | const struct gfs2_inum *str = buf; |
38 | 40 | ||
@@ -40,7 +42,7 @@ void gfs2_inum_in(struct gfs2_inum *no, const void *buf) | |||
40 | no->no_addr = be64_to_cpu(str->no_addr); | 42 | no->no_addr = be64_to_cpu(str->no_addr); |
41 | } | 43 | } |
42 | 44 | ||
43 | void gfs2_inum_out(const struct gfs2_inum *no, void *buf) | 45 | void gfs2_inum_out(const struct gfs2_inum_host *no, void *buf) |
44 | { | 46 | { |
45 | struct gfs2_inum *str = buf; | 47 | struct gfs2_inum *str = buf; |
46 | 48 | ||
@@ -48,13 +50,13 @@ void gfs2_inum_out(const struct gfs2_inum *no, void *buf) | |||
48 | str->no_addr = cpu_to_be64(no->no_addr); | 50 | str->no_addr = cpu_to_be64(no->no_addr); |
49 | } | 51 | } |
50 | 52 | ||
51 | static void gfs2_inum_print(const struct gfs2_inum *no) | 53 | static void gfs2_inum_print(const struct gfs2_inum_host *no) |
52 | { | 54 | { |
53 | printk(KERN_INFO " no_formal_ino = %llu\n", (unsigned long long)no->no_formal_ino); | 55 | printk(KERN_INFO " no_formal_ino = %llu\n", (unsigned long long)no->no_formal_ino); |
54 | printk(KERN_INFO " no_addr = %llu\n", (unsigned long long)no->no_addr); | 56 | printk(KERN_INFO " no_addr = %llu\n", (unsigned long long)no->no_addr); |
55 | } | 57 | } |
56 | 58 | ||
57 | static void gfs2_meta_header_in(struct gfs2_meta_header *mh, const void *buf) | 59 | static void gfs2_meta_header_in(struct gfs2_meta_header_host *mh, const void *buf) |
58 | { | 60 | { |
59 | const struct gfs2_meta_header *str = buf; | 61 | const struct gfs2_meta_header *str = buf; |
60 | 62 | ||
@@ -63,23 +65,7 @@ static void gfs2_meta_header_in(struct gfs2_meta_header *mh, const void *buf) | |||
63 | mh->mh_format = be32_to_cpu(str->mh_format); | 65 | mh->mh_format = be32_to_cpu(str->mh_format); |
64 | } | 66 | } |
65 | 67 | ||
66 | static void gfs2_meta_header_out(const struct gfs2_meta_header *mh, void *buf) | 68 | void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) |
67 | { | ||
68 | struct gfs2_meta_header *str = buf; | ||
69 | |||
70 | str->mh_magic = cpu_to_be32(mh->mh_magic); | ||
71 | str->mh_type = cpu_to_be32(mh->mh_type); | ||
72 | str->mh_format = cpu_to_be32(mh->mh_format); | ||
73 | } | ||
74 | |||
75 | static void gfs2_meta_header_print(const struct gfs2_meta_header *mh) | ||
76 | { | ||
77 | pv(mh, mh_magic, "0x%.8X"); | ||
78 | pv(mh, mh_type, "%u"); | ||
79 | pv(mh, mh_format, "%u"); | ||
80 | } | ||
81 | |||
82 | void gfs2_sb_in(struct gfs2_sb *sb, const void *buf) | ||
83 | { | 69 | { |
84 | const struct gfs2_sb *str = buf; | 70 | const struct gfs2_sb *str = buf; |
85 | 71 | ||
@@ -97,7 +83,7 @@ void gfs2_sb_in(struct gfs2_sb *sb, const void *buf) | |||
97 | memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); | 83 | memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); |
98 | } | 84 | } |
99 | 85 | ||
100 | void gfs2_rindex_in(struct gfs2_rindex *ri, const void *buf) | 86 | void gfs2_rindex_in(struct gfs2_rindex_host *ri, const void *buf) |
101 | { | 87 | { |
102 | const struct gfs2_rindex *str = buf; | 88 | const struct gfs2_rindex *str = buf; |
103 | 89 | ||
@@ -109,7 +95,7 @@ void gfs2_rindex_in(struct gfs2_rindex *ri, const void *buf) | |||
109 | 95 | ||
110 | } | 96 | } |
111 | 97 | ||
112 | void gfs2_rindex_print(const struct gfs2_rindex *ri) | 98 | void gfs2_rindex_print(const struct gfs2_rindex_host *ri) |
113 | { | 99 | { |
114 | printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)ri->ri_addr); | 100 | printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)ri->ri_addr); |
115 | pv(ri, ri_length, "%u"); | 101 | pv(ri, ri_length, "%u"); |
@@ -120,22 +106,20 @@ void gfs2_rindex_print(const struct gfs2_rindex *ri) | |||
120 | pv(ri, ri_bitbytes, "%u"); | 106 | pv(ri, ri_bitbytes, "%u"); |
121 | } | 107 | } |
122 | 108 | ||
123 | void gfs2_rgrp_in(struct gfs2_rgrp *rg, const void *buf) | 109 | void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf) |
124 | { | 110 | { |
125 | const struct gfs2_rgrp *str = buf; | 111 | const struct gfs2_rgrp *str = buf; |
126 | 112 | ||
127 | gfs2_meta_header_in(&rg->rg_header, buf); | ||
128 | rg->rg_flags = be32_to_cpu(str->rg_flags); | 113 | rg->rg_flags = be32_to_cpu(str->rg_flags); |
129 | rg->rg_free = be32_to_cpu(str->rg_free); | 114 | rg->rg_free = be32_to_cpu(str->rg_free); |
130 | rg->rg_dinodes = be32_to_cpu(str->rg_dinodes); | 115 | rg->rg_dinodes = be32_to_cpu(str->rg_dinodes); |
131 | rg->rg_igeneration = be64_to_cpu(str->rg_igeneration); | 116 | rg->rg_igeneration = be64_to_cpu(str->rg_igeneration); |
132 | } | 117 | } |
133 | 118 | ||
134 | void gfs2_rgrp_out(const struct gfs2_rgrp *rg, void *buf) | 119 | void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf) |
135 | { | 120 | { |
136 | struct gfs2_rgrp *str = buf; | 121 | struct gfs2_rgrp *str = buf; |
137 | 122 | ||
138 | gfs2_meta_header_out(&rg->rg_header, buf); | ||
139 | str->rg_flags = cpu_to_be32(rg->rg_flags); | 123 | str->rg_flags = cpu_to_be32(rg->rg_flags); |
140 | str->rg_free = cpu_to_be32(rg->rg_free); | 124 | str->rg_free = cpu_to_be32(rg->rg_free); |
141 | str->rg_dinodes = cpu_to_be32(rg->rg_dinodes); | 125 | str->rg_dinodes = cpu_to_be32(rg->rg_dinodes); |
@@ -144,7 +128,7 @@ void gfs2_rgrp_out(const struct gfs2_rgrp *rg, void *buf) | |||
144 | memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); | 128 | memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); |
145 | } | 129 | } |
146 | 130 | ||
147 | void gfs2_quota_in(struct gfs2_quota *qu, const void *buf) | 131 | void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf) |
148 | { | 132 | { |
149 | const struct gfs2_quota *str = buf; | 133 | const struct gfs2_quota *str = buf; |
150 | 134 | ||
@@ -153,96 +137,56 @@ void gfs2_quota_in(struct gfs2_quota *qu, const void *buf) | |||
153 | qu->qu_value = be64_to_cpu(str->qu_value); | 137 | qu->qu_value = be64_to_cpu(str->qu_value); |
154 | } | 138 | } |
155 | 139 | ||
156 | void gfs2_dinode_in(struct gfs2_dinode *di, const void *buf) | 140 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) |
157 | { | ||
158 | const struct gfs2_dinode *str = buf; | ||
159 | |||
160 | gfs2_meta_header_in(&di->di_header, buf); | ||
161 | gfs2_inum_in(&di->di_num, &str->di_num); | ||
162 | |||
163 | di->di_mode = be32_to_cpu(str->di_mode); | ||
164 | di->di_uid = be32_to_cpu(str->di_uid); | ||
165 | di->di_gid = be32_to_cpu(str->di_gid); | ||
166 | di->di_nlink = be32_to_cpu(str->di_nlink); | ||
167 | di->di_size = be64_to_cpu(str->di_size); | ||
168 | di->di_blocks = be64_to_cpu(str->di_blocks); | ||
169 | di->di_atime = be64_to_cpu(str->di_atime); | ||
170 | di->di_mtime = be64_to_cpu(str->di_mtime); | ||
171 | di->di_ctime = be64_to_cpu(str->di_ctime); | ||
172 | di->di_major = be32_to_cpu(str->di_major); | ||
173 | di->di_minor = be32_to_cpu(str->di_minor); | ||
174 | |||
175 | di->di_goal_meta = be64_to_cpu(str->di_goal_meta); | ||
176 | di->di_goal_data = be64_to_cpu(str->di_goal_data); | ||
177 | di->di_generation = be64_to_cpu(str->di_generation); | ||
178 | |||
179 | di->di_flags = be32_to_cpu(str->di_flags); | ||
180 | di->di_payload_format = be32_to_cpu(str->di_payload_format); | ||
181 | di->di_height = be16_to_cpu(str->di_height); | ||
182 | |||
183 | di->di_depth = be16_to_cpu(str->di_depth); | ||
184 | di->di_entries = be32_to_cpu(str->di_entries); | ||
185 | |||
186 | di->di_eattr = be64_to_cpu(str->di_eattr); | ||
187 | |||
188 | } | ||
189 | |||
190 | void gfs2_dinode_out(const struct gfs2_dinode *di, void *buf) | ||
191 | { | 141 | { |
142 | const struct gfs2_dinode_host *di = &ip->i_di; | ||
192 | struct gfs2_dinode *str = buf; | 143 | struct gfs2_dinode *str = buf; |
193 | 144 | ||
194 | gfs2_meta_header_out(&di->di_header, buf); | 145 | str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); |
195 | gfs2_inum_out(&di->di_num, (char *)&str->di_num); | 146 | str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI); |
147 | str->di_header.__pad0 = 0; | ||
148 | str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); | ||
149 | str->di_header.__pad1 = 0; | ||
196 | 150 | ||
197 | str->di_mode = cpu_to_be32(di->di_mode); | 151 | gfs2_inum_out(&ip->i_num, &str->di_num); |
198 | str->di_uid = cpu_to_be32(di->di_uid); | 152 | |
199 | str->di_gid = cpu_to_be32(di->di_gid); | 153 | str->di_mode = cpu_to_be32(ip->i_inode.i_mode); |
200 | str->di_nlink = cpu_to_be32(di->di_nlink); | 154 | str->di_uid = cpu_to_be32(ip->i_inode.i_uid); |
155 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); | ||
156 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); | ||
201 | str->di_size = cpu_to_be64(di->di_size); | 157 | str->di_size = cpu_to_be64(di->di_size); |
202 | str->di_blocks = cpu_to_be64(di->di_blocks); | 158 | str->di_blocks = cpu_to_be64(di->di_blocks); |
203 | str->di_atime = cpu_to_be64(di->di_atime); | 159 | str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); |
204 | str->di_mtime = cpu_to_be64(di->di_mtime); | 160 | str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); |
205 | str->di_ctime = cpu_to_be64(di->di_ctime); | 161 | str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); |
206 | str->di_major = cpu_to_be32(di->di_major); | ||
207 | str->di_minor = cpu_to_be32(di->di_minor); | ||
208 | 162 | ||
209 | str->di_goal_meta = cpu_to_be64(di->di_goal_meta); | 163 | str->di_goal_meta = cpu_to_be64(di->di_goal_meta); |
210 | str->di_goal_data = cpu_to_be64(di->di_goal_data); | 164 | str->di_goal_data = cpu_to_be64(di->di_goal_data); |
211 | str->di_generation = cpu_to_be64(di->di_generation); | 165 | str->di_generation = cpu_to_be64(di->di_generation); |
212 | 166 | ||
213 | str->di_flags = cpu_to_be32(di->di_flags); | 167 | str->di_flags = cpu_to_be32(di->di_flags); |
214 | str->di_payload_format = cpu_to_be32(di->di_payload_format); | ||
215 | str->di_height = cpu_to_be16(di->di_height); | 168 | str->di_height = cpu_to_be16(di->di_height); |
216 | 169 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && | |
170 | !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ? | ||
171 | GFS2_FORMAT_DE : 0); | ||
217 | str->di_depth = cpu_to_be16(di->di_depth); | 172 | str->di_depth = cpu_to_be16(di->di_depth); |
218 | str->di_entries = cpu_to_be32(di->di_entries); | 173 | str->di_entries = cpu_to_be32(di->di_entries); |
219 | 174 | ||
220 | str->di_eattr = cpu_to_be64(di->di_eattr); | 175 | str->di_eattr = cpu_to_be64(di->di_eattr); |
221 | |||
222 | } | 176 | } |
223 | 177 | ||
224 | void gfs2_dinode_print(const struct gfs2_dinode *di) | 178 | void gfs2_dinode_print(const struct gfs2_inode *ip) |
225 | { | 179 | { |
226 | gfs2_meta_header_print(&di->di_header); | 180 | const struct gfs2_dinode_host *di = &ip->i_di; |
227 | gfs2_inum_print(&di->di_num); | 181 | |
182 | gfs2_inum_print(&ip->i_num); | ||
228 | 183 | ||
229 | pv(di, di_mode, "0%o"); | ||
230 | pv(di, di_uid, "%u"); | ||
231 | pv(di, di_gid, "%u"); | ||
232 | pv(di, di_nlink, "%u"); | ||
233 | printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); | 184 | printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); |
234 | printk(KERN_INFO " di_blocks = %llu\n", (unsigned long long)di->di_blocks); | 185 | printk(KERN_INFO " di_blocks = %llu\n", (unsigned long long)di->di_blocks); |
235 | printk(KERN_INFO " di_atime = %lld\n", (long long)di->di_atime); | ||
236 | printk(KERN_INFO " di_mtime = %lld\n", (long long)di->di_mtime); | ||
237 | printk(KERN_INFO " di_ctime = %lld\n", (long long)di->di_ctime); | ||
238 | pv(di, di_major, "%u"); | ||
239 | pv(di, di_minor, "%u"); | ||
240 | |||
241 | printk(KERN_INFO " di_goal_meta = %llu\n", (unsigned long long)di->di_goal_meta); | 186 | printk(KERN_INFO " di_goal_meta = %llu\n", (unsigned long long)di->di_goal_meta); |
242 | printk(KERN_INFO " di_goal_data = %llu\n", (unsigned long long)di->di_goal_data); | 187 | printk(KERN_INFO " di_goal_data = %llu\n", (unsigned long long)di->di_goal_data); |
243 | 188 | ||
244 | pv(di, di_flags, "0x%.8X"); | 189 | pv(di, di_flags, "0x%.8X"); |
245 | pv(di, di_payload_format, "%u"); | ||
246 | pv(di, di_height, "%u"); | 190 | pv(di, di_height, "%u"); |
247 | 191 | ||
248 | pv(di, di_depth, "%u"); | 192 | pv(di, di_depth, "%u"); |
@@ -251,7 +195,7 @@ void gfs2_dinode_print(const struct gfs2_dinode *di) | |||
251 | printk(KERN_INFO " di_eattr = %llu\n", (unsigned long long)di->di_eattr); | 195 | printk(KERN_INFO " di_eattr = %llu\n", (unsigned long long)di->di_eattr); |
252 | } | 196 | } |
253 | 197 | ||
254 | void gfs2_log_header_in(struct gfs2_log_header *lh, const void *buf) | 198 | void gfs2_log_header_in(struct gfs2_log_header_host *lh, const void *buf) |
255 | { | 199 | { |
256 | const struct gfs2_log_header *str = buf; | 200 | const struct gfs2_log_header *str = buf; |
257 | 201 | ||
@@ -263,7 +207,7 @@ void gfs2_log_header_in(struct gfs2_log_header *lh, const void *buf) | |||
263 | lh->lh_hash = be32_to_cpu(str->lh_hash); | 207 | lh->lh_hash = be32_to_cpu(str->lh_hash); |
264 | } | 208 | } |
265 | 209 | ||
266 | void gfs2_inum_range_in(struct gfs2_inum_range *ir, const void *buf) | 210 | void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf) |
267 | { | 211 | { |
268 | const struct gfs2_inum_range *str = buf; | 212 | const struct gfs2_inum_range *str = buf; |
269 | 213 | ||
@@ -271,7 +215,7 @@ void gfs2_inum_range_in(struct gfs2_inum_range *ir, const void *buf) | |||
271 | ir->ir_length = be64_to_cpu(str->ir_length); | 215 | ir->ir_length = be64_to_cpu(str->ir_length); |
272 | } | 216 | } |
273 | 217 | ||
274 | void gfs2_inum_range_out(const struct gfs2_inum_range *ir, void *buf) | 218 | void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf) |
275 | { | 219 | { |
276 | struct gfs2_inum_range *str = buf; | 220 | struct gfs2_inum_range *str = buf; |
277 | 221 | ||
@@ -279,7 +223,7 @@ void gfs2_inum_range_out(const struct gfs2_inum_range *ir, void *buf) | |||
279 | str->ir_length = cpu_to_be64(ir->ir_length); | 223 | str->ir_length = cpu_to_be64(ir->ir_length); |
280 | } | 224 | } |
281 | 225 | ||
282 | void gfs2_statfs_change_in(struct gfs2_statfs_change *sc, const void *buf) | 226 | void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) |
283 | { | 227 | { |
284 | const struct gfs2_statfs_change *str = buf; | 228 | const struct gfs2_statfs_change *str = buf; |
285 | 229 | ||
@@ -288,7 +232,7 @@ void gfs2_statfs_change_in(struct gfs2_statfs_change *sc, const void *buf) | |||
288 | sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); | 232 | sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); |
289 | } | 233 | } |
290 | 234 | ||
291 | void gfs2_statfs_change_out(const struct gfs2_statfs_change *sc, void *buf) | 235 | void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf) |
292 | { | 236 | { |
293 | struct gfs2_statfs_change *str = buf; | 237 | struct gfs2_statfs_change *str = buf; |
294 | 238 | ||
@@ -297,7 +241,7 @@ void gfs2_statfs_change_out(const struct gfs2_statfs_change *sc, void *buf) | |||
297 | str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); | 241 | str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); |
298 | } | 242 | } |
299 | 243 | ||
300 | void gfs2_quota_change_in(struct gfs2_quota_change *qc, const void *buf) | 244 | void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf) |
301 | { | 245 | { |
302 | const struct gfs2_quota_change *str = buf; | 246 | const struct gfs2_quota_change *str = buf; |
303 | 247 | ||
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 015640b3f123..d8d69a72a10d 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
@@ -156,19 +156,6 @@ out_ignore: | |||
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | static int zero_readpage(struct page *page) | ||
160 | { | ||
161 | void *kaddr; | ||
162 | |||
163 | kaddr = kmap_atomic(page, KM_USER0); | ||
164 | memset(kaddr, 0, PAGE_CACHE_SIZE); | ||
165 | kunmap_atomic(kaddr, KM_USER0); | ||
166 | |||
167 | SetPageUptodate(page); | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | /** | 159 | /** |
173 | * stuffed_readpage - Fill in a Linux page with stuffed file data | 160 | * stuffed_readpage - Fill in a Linux page with stuffed file data |
174 | * @ip: the inode | 161 | * @ip: the inode |
@@ -183,9 +170,7 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) | |||
183 | void *kaddr; | 170 | void *kaddr; |
184 | int error; | 171 | int error; |
185 | 172 | ||
186 | /* Only the first page of a stuffed file might contain data */ | 173 | BUG_ON(page->index); |
187 | if (unlikely(page->index)) | ||
188 | return zero_readpage(page); | ||
189 | 174 | ||
190 | error = gfs2_meta_inode_buffer(ip, &dibh); | 175 | error = gfs2_meta_inode_buffer(ip, &dibh); |
191 | if (error) | 176 | if (error) |
@@ -230,9 +215,9 @@ static int gfs2_readpage(struct file *file, struct page *page) | |||
230 | /* gfs2_sharewrite_nopage has grabbed the ip->i_gl already */ | 215 | /* gfs2_sharewrite_nopage has grabbed the ip->i_gl already */ |
231 | goto skip_lock; | 216 | goto skip_lock; |
232 | } | 217 | } |
233 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|GL_AOP, &gh); | 218 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|LM_FLAG_TRY_1CB, &gh); |
234 | do_unlock = 1; | 219 | do_unlock = 1; |
235 | error = gfs2_glock_nq_m_atime(1, &gh); | 220 | error = gfs2_glock_nq_atime(&gh); |
236 | if (unlikely(error)) | 221 | if (unlikely(error)) |
237 | goto out_unlock; | 222 | goto out_unlock; |
238 | } | 223 | } |
@@ -254,6 +239,8 @@ skip_lock: | |||
254 | out: | 239 | out: |
255 | return error; | 240 | return error; |
256 | out_unlock: | 241 | out_unlock: |
242 | if (error == GLR_TRYFAILED) | ||
243 | error = AOP_TRUNCATED_PAGE; | ||
257 | unlock_page(page); | 244 | unlock_page(page); |
258 | if (do_unlock) | 245 | if (do_unlock) |
259 | gfs2_holder_uninit(&gh); | 246 | gfs2_holder_uninit(&gh); |
@@ -293,9 +280,9 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping, | |||
293 | goto skip_lock; | 280 | goto skip_lock; |
294 | } | 281 | } |
295 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, | 282 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, |
296 | LM_FLAG_TRY_1CB|GL_ATIME|GL_AOP, &gh); | 283 | LM_FLAG_TRY_1CB|GL_ATIME, &gh); |
297 | do_unlock = 1; | 284 | do_unlock = 1; |
298 | ret = gfs2_glock_nq_m_atime(1, &gh); | 285 | ret = gfs2_glock_nq_atime(&gh); |
299 | if (ret == GLR_TRYFAILED) | 286 | if (ret == GLR_TRYFAILED) |
300 | goto out_noerror; | 287 | goto out_noerror; |
301 | if (unlikely(ret)) | 288 | if (unlikely(ret)) |
@@ -366,10 +353,13 @@ static int gfs2_prepare_write(struct file *file, struct page *page, | |||
366 | unsigned int write_len = to - from; | 353 | unsigned int write_len = to - from; |
367 | 354 | ||
368 | 355 | ||
369 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME|GL_AOP, &ip->i_gh); | 356 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME|LM_FLAG_TRY_1CB, &ip->i_gh); |
370 | error = gfs2_glock_nq_m_atime(1, &ip->i_gh); | 357 | error = gfs2_glock_nq_atime(&ip->i_gh); |
371 | if (error) | 358 | if (unlikely(error)) { |
359 | if (error == GLR_TRYFAILED) | ||
360 | error = AOP_TRUNCATED_PAGE; | ||
372 | goto out_uninit; | 361 | goto out_uninit; |
362 | } | ||
373 | 363 | ||
374 | gfs2_write_calc_reserv(ip, write_len, &data_blocks, &ind_blocks); | 364 | gfs2_write_calc_reserv(ip, write_len, &data_blocks, &ind_blocks); |
375 | 365 | ||
@@ -386,7 +376,7 @@ static int gfs2_prepare_write(struct file *file, struct page *page, | |||
386 | if (error) | 376 | if (error) |
387 | goto out_alloc_put; | 377 | goto out_alloc_put; |
388 | 378 | ||
389 | error = gfs2_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); | 379 | error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); |
390 | if (error) | 380 | if (error) |
391 | goto out_qunlock; | 381 | goto out_qunlock; |
392 | 382 | ||
@@ -482,8 +472,10 @@ static int gfs2_commit_write(struct file *file, struct page *page, | |||
482 | 472 | ||
483 | SetPageUptodate(page); | 473 | SetPageUptodate(page); |
484 | 474 | ||
485 | if (inode->i_size < file_size) | 475 | if (inode->i_size < file_size) { |
486 | i_size_write(inode, file_size); | 476 | i_size_write(inode, file_size); |
477 | mark_inode_dirty(inode); | ||
478 | } | ||
487 | } else { | 479 | } else { |
488 | if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || | 480 | if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || |
489 | gfs2_is_jdata(ip)) | 481 | gfs2_is_jdata(ip)) |
@@ -498,11 +490,6 @@ static int gfs2_commit_write(struct file *file, struct page *page, | |||
498 | di->di_size = cpu_to_be64(inode->i_size); | 490 | di->di_size = cpu_to_be64(inode->i_size); |
499 | } | 491 | } |
500 | 492 | ||
501 | di->di_mode = cpu_to_be32(inode->i_mode); | ||
502 | di->di_atime = cpu_to_be64(inode->i_atime.tv_sec); | ||
503 | di->di_mtime = cpu_to_be64(inode->i_mtime.tv_sec); | ||
504 | di->di_ctime = cpu_to_be64(inode->i_ctime.tv_sec); | ||
505 | |||
506 | brelse(dibh); | 493 | brelse(dibh); |
507 | gfs2_trans_end(sdp); | 494 | gfs2_trans_end(sdp); |
508 | if (al->al_requested) { | 495 | if (al->al_requested) { |
@@ -624,7 +611,7 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, | |||
624 | * on this path. All we need change is atime. | 611 | * on this path. All we need change is atime. |
625 | */ | 612 | */ |
626 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); | 613 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); |
627 | rv = gfs2_glock_nq_m_atime(1, &gh); | 614 | rv = gfs2_glock_nq_atime(&gh); |
628 | if (rv) | 615 | if (rv) |
629 | goto out; | 616 | goto out; |
630 | 617 | ||
@@ -737,6 +724,9 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) | |||
737 | if (!atomic_read(&aspace->i_writecount)) | 724 | if (!atomic_read(&aspace->i_writecount)) |
738 | return 0; | 725 | return 0; |
739 | 726 | ||
727 | if (!(gfp_mask & __GFP_WAIT)) | ||
728 | return 0; | ||
729 | |||
740 | if (time_after_eq(jiffies, t)) { | 730 | if (time_after_eq(jiffies, t)) { |
741 | stuck_releasepage(bh); | 731 | stuck_releasepage(bh); |
742 | /* should we withdraw here? */ | 732 | /* should we withdraw here? */ |
diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c index 00041b1b8025..d355899585d8 100644 --- a/fs/gfs2/ops_dentry.c +++ b/fs/gfs2/ops_dentry.c | |||
@@ -43,7 +43,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) | |||
43 | struct inode *inode = dentry->d_inode; | 43 | struct inode *inode = dentry->d_inode; |
44 | struct gfs2_holder d_gh; | 44 | struct gfs2_holder d_gh; |
45 | struct gfs2_inode *ip; | 45 | struct gfs2_inode *ip; |
46 | struct gfs2_inum inum; | 46 | struct gfs2_inum_host inum; |
47 | unsigned int type; | 47 | unsigned int type; |
48 | int error; | 48 | int error; |
49 | 49 | ||
@@ -76,7 +76,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) | |||
76 | if (!gfs2_inum_equal(&ip->i_num, &inum)) | 76 | if (!gfs2_inum_equal(&ip->i_num, &inum)) |
77 | goto invalid_gunlock; | 77 | goto invalid_gunlock; |
78 | 78 | ||
79 | if (IF2DT(ip->i_di.di_mode) != type) { | 79 | if (IF2DT(ip->i_inode.i_mode) != type) { |
80 | gfs2_consist_inode(dip); | 80 | gfs2_consist_inode(dip); |
81 | goto fail_gunlock; | 81 | goto fail_gunlock; |
82 | } | 82 | } |
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c index 86127d93bd35..b4e7b8775315 100644 --- a/fs/gfs2/ops_export.c +++ b/fs/gfs2/ops_export.c | |||
@@ -27,15 +27,16 @@ | |||
27 | #include "util.h" | 27 | #include "util.h" |
28 | 28 | ||
29 | static struct dentry *gfs2_decode_fh(struct super_block *sb, | 29 | static struct dentry *gfs2_decode_fh(struct super_block *sb, |
30 | __u32 *fh, | 30 | __u32 *p, |
31 | int fh_len, | 31 | int fh_len, |
32 | int fh_type, | 32 | int fh_type, |
33 | int (*acceptable)(void *context, | 33 | int (*acceptable)(void *context, |
34 | struct dentry *dentry), | 34 | struct dentry *dentry), |
35 | void *context) | 35 | void *context) |
36 | { | 36 | { |
37 | __be32 *fh = (__force __be32 *)p; | ||
37 | struct gfs2_fh_obj fh_obj; | 38 | struct gfs2_fh_obj fh_obj; |
38 | struct gfs2_inum *this, parent; | 39 | struct gfs2_inum_host *this, parent; |
39 | 40 | ||
40 | if (fh_type != fh_len) | 41 | if (fh_type != fh_len) |
41 | return NULL; | 42 | return NULL; |
@@ -65,9 +66,10 @@ static struct dentry *gfs2_decode_fh(struct super_block *sb, | |||
65 | acceptable, context); | 66 | acceptable, context); |
66 | } | 67 | } |
67 | 68 | ||
68 | static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len, | 69 | static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, |
69 | int connectable) | 70 | int connectable) |
70 | { | 71 | { |
72 | __be32 *fh = (__force __be32 *)p; | ||
71 | struct inode *inode = dentry->d_inode; | 73 | struct inode *inode = dentry->d_inode; |
72 | struct super_block *sb = inode->i_sb; | 74 | struct super_block *sb = inode->i_sb; |
73 | struct gfs2_inode *ip = GFS2_I(inode); | 75 | struct gfs2_inode *ip = GFS2_I(inode); |
@@ -76,14 +78,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len, | |||
76 | (connectable && *len < GFS2_LARGE_FH_SIZE)) | 78 | (connectable && *len < GFS2_LARGE_FH_SIZE)) |
77 | return 255; | 79 | return 255; |
78 | 80 | ||
79 | fh[0] = ip->i_num.no_formal_ino >> 32; | 81 | fh[0] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); |
80 | fh[0] = cpu_to_be32(fh[0]); | 82 | fh[1] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); |
81 | fh[1] = ip->i_num.no_formal_ino & 0xFFFFFFFF; | 83 | fh[2] = cpu_to_be32(ip->i_num.no_addr >> 32); |
82 | fh[1] = cpu_to_be32(fh[1]); | 84 | fh[3] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); |
83 | fh[2] = ip->i_num.no_addr >> 32; | ||
84 | fh[2] = cpu_to_be32(fh[2]); | ||
85 | fh[3] = ip->i_num.no_addr & 0xFFFFFFFF; | ||
86 | fh[3] = cpu_to_be32(fh[3]); | ||
87 | *len = GFS2_SMALL_FH_SIZE; | 85 | *len = GFS2_SMALL_FH_SIZE; |
88 | 86 | ||
89 | if (!connectable || inode == sb->s_root->d_inode) | 87 | if (!connectable || inode == sb->s_root->d_inode) |
@@ -95,14 +93,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len, | |||
95 | igrab(inode); | 93 | igrab(inode); |
96 | spin_unlock(&dentry->d_lock); | 94 | spin_unlock(&dentry->d_lock); |
97 | 95 | ||
98 | fh[4] = ip->i_num.no_formal_ino >> 32; | 96 | fh[4] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); |
99 | fh[4] = cpu_to_be32(fh[4]); | 97 | fh[5] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); |
100 | fh[5] = ip->i_num.no_formal_ino & 0xFFFFFFFF; | 98 | fh[6] = cpu_to_be32(ip->i_num.no_addr >> 32); |
101 | fh[5] = cpu_to_be32(fh[5]); | 99 | fh[7] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); |
102 | fh[6] = ip->i_num.no_addr >> 32; | ||
103 | fh[6] = cpu_to_be32(fh[6]); | ||
104 | fh[7] = ip->i_num.no_addr & 0xFFFFFFFF; | ||
105 | fh[7] = cpu_to_be32(fh[7]); | ||
106 | 100 | ||
107 | fh[8] = cpu_to_be32(inode->i_mode); | 101 | fh[8] = cpu_to_be32(inode->i_mode); |
108 | fh[9] = 0; /* pad to double word */ | 102 | fh[9] = 0; /* pad to double word */ |
@@ -114,12 +108,12 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len, | |||
114 | } | 108 | } |
115 | 109 | ||
116 | struct get_name_filldir { | 110 | struct get_name_filldir { |
117 | struct gfs2_inum inum; | 111 | struct gfs2_inum_host inum; |
118 | char *name; | 112 | char *name; |
119 | }; | 113 | }; |
120 | 114 | ||
121 | static int get_name_filldir(void *opaque, const char *name, unsigned int length, | 115 | static int get_name_filldir(void *opaque, const char *name, unsigned int length, |
122 | u64 offset, struct gfs2_inum *inum, | 116 | u64 offset, struct gfs2_inum_host *inum, |
123 | unsigned int type) | 117 | unsigned int type) |
124 | { | 118 | { |
125 | struct get_name_filldir *gnfd = (struct get_name_filldir *)opaque; | 119 | struct get_name_filldir *gnfd = (struct get_name_filldir *)opaque; |
@@ -202,7 +196,7 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) | |||
202 | { | 196 | { |
203 | struct gfs2_sbd *sdp = sb->s_fs_info; | 197 | struct gfs2_sbd *sdp = sb->s_fs_info; |
204 | struct gfs2_fh_obj *fh_obj = (struct gfs2_fh_obj *)inum_obj; | 198 | struct gfs2_fh_obj *fh_obj = (struct gfs2_fh_obj *)inum_obj; |
205 | struct gfs2_inum *inum = &fh_obj->this; | 199 | struct gfs2_inum_host *inum = &fh_obj->this; |
206 | struct gfs2_holder i_gh, ri_gh, rgd_gh; | 200 | struct gfs2_holder i_gh, ri_gh, rgd_gh; |
207 | struct gfs2_rgrpd *rgd; | 201 | struct gfs2_rgrpd *rgd; |
208 | struct inode *inode; | 202 | struct inode *inode; |
diff --git a/fs/gfs2/ops_export.h b/fs/gfs2/ops_export.h index 09aca5046fb1..f925a955b3b8 100644 --- a/fs/gfs2/ops_export.h +++ b/fs/gfs2/ops_export.h | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | extern struct export_operations gfs2_export_ops; | 16 | extern struct export_operations gfs2_export_ops; |
17 | struct gfs2_fh_obj { | 17 | struct gfs2_fh_obj { |
18 | struct gfs2_inum this; | 18 | struct gfs2_inum_host this; |
19 | __u32 imode; | 19 | __u32 imode; |
20 | }; | 20 | }; |
21 | 21 | ||
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 3064f133bf3c..b3f1e0349ae0 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/ext2_fs.h> | 22 | #include <linux/ext2_fs.h> |
23 | #include <linux/crc32.h> | 23 | #include <linux/crc32.h> |
24 | #include <linux/lm_interface.h> | 24 | #include <linux/lm_interface.h> |
25 | #include <linux/writeback.h> | ||
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
26 | 27 | ||
27 | #include "gfs2.h" | 28 | #include "gfs2.h" |
@@ -71,7 +72,7 @@ static int gfs2_read_actor(read_descriptor_t *desc, struct page *page, | |||
71 | size = count; | 72 | size = count; |
72 | 73 | ||
73 | kaddr = kmap(page); | 74 | kaddr = kmap(page); |
74 | memcpy(desc->arg.buf, kaddr + offset, size); | 75 | memcpy(desc->arg.data, kaddr + offset, size); |
75 | kunmap(page); | 76 | kunmap(page); |
76 | 77 | ||
77 | desc->count = count - size; | 78 | desc->count = count - size; |
@@ -86,7 +87,7 @@ int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state, | |||
86 | struct inode *inode = &ip->i_inode; | 87 | struct inode *inode = &ip->i_inode; |
87 | read_descriptor_t desc; | 88 | read_descriptor_t desc; |
88 | desc.written = 0; | 89 | desc.written = 0; |
89 | desc.arg.buf = buf; | 90 | desc.arg.data = buf; |
90 | desc.count = size; | 91 | desc.count = size; |
91 | desc.error = 0; | 92 | desc.error = 0; |
92 | do_generic_mapping_read(inode->i_mapping, ra_state, | 93 | do_generic_mapping_read(inode->i_mapping, ra_state, |
@@ -139,7 +140,7 @@ static loff_t gfs2_llseek(struct file *file, loff_t offset, int origin) | |||
139 | */ | 140 | */ |
140 | 141 | ||
141 | static int filldir_func(void *opaque, const char *name, unsigned int length, | 142 | static int filldir_func(void *opaque, const char *name, unsigned int length, |
142 | u64 offset, struct gfs2_inum *inum, | 143 | u64 offset, struct gfs2_inum_host *inum, |
143 | unsigned int type) | 144 | unsigned int type) |
144 | { | 145 | { |
145 | struct filldir_reg *fdr = (struct filldir_reg *)opaque; | 146 | struct filldir_reg *fdr = (struct filldir_reg *)opaque; |
@@ -253,7 +254,7 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr) | |||
253 | u32 fsflags; | 254 | u32 fsflags; |
254 | 255 | ||
255 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); | 256 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); |
256 | error = gfs2_glock_nq_m_atime(1, &gh); | 257 | error = gfs2_glock_nq_atime(&gh); |
257 | if (error) | 258 | if (error) |
258 | return error; | 259 | return error; |
259 | 260 | ||
@@ -266,6 +267,24 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr) | |||
266 | return error; | 267 | return error; |
267 | } | 268 | } |
268 | 269 | ||
270 | void gfs2_set_inode_flags(struct inode *inode) | ||
271 | { | ||
272 | struct gfs2_inode *ip = GFS2_I(inode); | ||
273 | struct gfs2_dinode_host *di = &ip->i_di; | ||
274 | unsigned int flags = inode->i_flags; | ||
275 | |||
276 | flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); | ||
277 | if (di->di_flags & GFS2_DIF_IMMUTABLE) | ||
278 | flags |= S_IMMUTABLE; | ||
279 | if (di->di_flags & GFS2_DIF_APPENDONLY) | ||
280 | flags |= S_APPEND; | ||
281 | if (di->di_flags & GFS2_DIF_NOATIME) | ||
282 | flags |= S_NOATIME; | ||
283 | if (di->di_flags & GFS2_DIF_SYNC) | ||
284 | flags |= S_SYNC; | ||
285 | inode->i_flags = flags; | ||
286 | } | ||
287 | |||
269 | /* Flags that can be set by user space */ | 288 | /* Flags that can be set by user space */ |
270 | #define GFS2_FLAGS_USER_SET (GFS2_DIF_JDATA| \ | 289 | #define GFS2_FLAGS_USER_SET (GFS2_DIF_JDATA| \ |
271 | GFS2_DIF_DIRECTIO| \ | 290 | GFS2_DIF_DIRECTIO| \ |
@@ -336,8 +355,9 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) | |||
336 | goto out_trans_end; | 355 | goto out_trans_end; |
337 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 356 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
338 | ip->i_di.di_flags = new_flags; | 357 | ip->i_di.di_flags = new_flags; |
339 | gfs2_dinode_out(&ip->i_di, bh->b_data); | 358 | gfs2_dinode_out(ip, bh->b_data); |
340 | brelse(bh); | 359 | brelse(bh); |
360 | gfs2_set_inode_flags(inode); | ||
341 | out_trans_end: | 361 | out_trans_end: |
342 | gfs2_trans_end(sdp); | 362 | gfs2_trans_end(sdp); |
343 | out: | 363 | out: |
@@ -425,7 +445,7 @@ static int gfs2_open(struct inode *inode, struct file *file) | |||
425 | gfs2_assert_warn(GFS2_SB(inode), !file->private_data); | 445 | gfs2_assert_warn(GFS2_SB(inode), !file->private_data); |
426 | file->private_data = fp; | 446 | file->private_data = fp; |
427 | 447 | ||
428 | if (S_ISREG(ip->i_di.di_mode)) { | 448 | if (S_ISREG(ip->i_inode.i_mode)) { |
429 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, | 449 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, |
430 | &i_gh); | 450 | &i_gh); |
431 | if (error) | 451 | if (error) |
@@ -484,16 +504,40 @@ static int gfs2_close(struct inode *inode, struct file *file) | |||
484 | * @file: the file that points to the dentry (we ignore this) | 504 | * @file: the file that points to the dentry (we ignore this) |
485 | * @dentry: the dentry that points to the inode to sync | 505 | * @dentry: the dentry that points to the inode to sync |
486 | * | 506 | * |
507 | * The VFS will flush "normal" data for us. We only need to worry | ||
508 | * about metadata here. For journaled data, we just do a log flush | ||
509 | * as we can't avoid it. Otherwise we can just bale out if datasync | ||
510 | * is set. For stuffed inodes we must flush the log in order to | ||
511 | * ensure that all data is on disk. | ||
512 | * | ||
513 | * The call to write_inode_now() is there to write back metadata and | ||
514 | * the inode itself. It does also try and write the data, but thats | ||
515 | * (hopefully) a no-op due to the VFS having already called filemap_fdatawrite() | ||
516 | * for us. | ||
517 | * | ||
487 | * Returns: errno | 518 | * Returns: errno |
488 | */ | 519 | */ |
489 | 520 | ||
490 | static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) | 521 | static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) |
491 | { | 522 | { |
492 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | 523 | struct inode *inode = dentry->d_inode; |
524 | int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); | ||
525 | int ret = 0; | ||
493 | 526 | ||
494 | gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl); | 527 | if (gfs2_is_jdata(GFS2_I(inode))) { |
528 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); | ||
529 | return 0; | ||
530 | } | ||
495 | 531 | ||
496 | return 0; | 532 | if (sync_state != 0) { |
533 | if (!datasync) | ||
534 | ret = write_inode_now(inode, 0); | ||
535 | |||
536 | if (gfs2_is_stuffed(GFS2_I(inode))) | ||
537 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); | ||
538 | } | ||
539 | |||
540 | return ret; | ||
497 | } | 541 | } |
498 | 542 | ||
499 | /** | 543 | /** |
@@ -515,7 +559,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) | |||
515 | 559 | ||
516 | if (!(fl->fl_flags & FL_POSIX)) | 560 | if (!(fl->fl_flags & FL_POSIX)) |
517 | return -ENOLCK; | 561 | return -ENOLCK; |
518 | if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID) | 562 | if ((ip->i_inode.i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) |
519 | return -ENOLCK; | 563 | return -ENOLCK; |
520 | 564 | ||
521 | if (sdp->sd_args.ar_localflocks) { | 565 | if (sdp->sd_args.ar_localflocks) { |
@@ -617,7 +661,7 @@ static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl) | |||
617 | 661 | ||
618 | if (!(fl->fl_flags & FL_FLOCK)) | 662 | if (!(fl->fl_flags & FL_FLOCK)) |
619 | return -ENOLCK; | 663 | return -ENOLCK; |
620 | if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID) | 664 | if ((ip->i_inode.i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) |
621 | return -ENOLCK; | 665 | return -ENOLCK; |
622 | 666 | ||
623 | if (sdp->sd_args.ar_localflocks) | 667 | if (sdp->sd_args.ar_localflocks) |
diff --git a/fs/gfs2/ops_file.h b/fs/gfs2/ops_file.h index ce319f89ec8e..7e5d8ec9c846 100644 --- a/fs/gfs2/ops_file.h +++ b/fs/gfs2/ops_file.h | |||
@@ -17,7 +17,7 @@ extern struct file gfs2_internal_file_sentinel; | |||
17 | extern int gfs2_internal_read(struct gfs2_inode *ip, | 17 | extern int gfs2_internal_read(struct gfs2_inode *ip, |
18 | struct file_ra_state *ra_state, | 18 | struct file_ra_state *ra_state, |
19 | char *buf, loff_t *pos, unsigned size); | 19 | char *buf, loff_t *pos, unsigned size); |
20 | 20 | extern void gfs2_set_inode_flags(struct inode *inode); | |
21 | extern const struct file_operations gfs2_file_fops; | 21 | extern const struct file_operations gfs2_file_fops; |
22 | extern const struct file_operations gfs2_dir_fops; | 22 | extern const struct file_operations gfs2_dir_fops; |
23 | 23 | ||
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 882873a6bd69..d14e139d2674 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -237,7 +237,7 @@ fail: | |||
237 | } | 237 | } |
238 | 238 | ||
239 | static struct inode *gfs2_lookup_root(struct super_block *sb, | 239 | static struct inode *gfs2_lookup_root(struct super_block *sb, |
240 | struct gfs2_inum *inum) | 240 | struct gfs2_inum_host *inum) |
241 | { | 241 | { |
242 | return gfs2_inode_lookup(sb, inum, DT_DIR); | 242 | return gfs2_inode_lookup(sb, inum, DT_DIR); |
243 | } | 243 | } |
@@ -246,7 +246,7 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) | |||
246 | { | 246 | { |
247 | struct super_block *sb = sdp->sd_vfs; | 247 | struct super_block *sb = sdp->sd_vfs; |
248 | struct gfs2_holder sb_gh; | 248 | struct gfs2_holder sb_gh; |
249 | struct gfs2_inum *inum; | 249 | struct gfs2_inum_host *inum; |
250 | struct inode *inode; | 250 | struct inode *inode; |
251 | int error = 0; | 251 | int error = 0; |
252 | 252 | ||
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index ef6e5ed70e94..636dda4c7d38 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -59,7 +59,7 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry, | |||
59 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 59 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
60 | 60 | ||
61 | for (;;) { | 61 | for (;;) { |
62 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode); | 62 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode, 0); |
63 | if (!IS_ERR(inode)) { | 63 | if (!IS_ERR(inode)) { |
64 | gfs2_trans_end(sdp); | 64 | gfs2_trans_end(sdp); |
65 | if (dip->i_alloc.al_rgd) | 65 | if (dip->i_alloc.al_rgd) |
@@ -144,7 +144,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
144 | int alloc_required; | 144 | int alloc_required; |
145 | int error; | 145 | int error; |
146 | 146 | ||
147 | if (S_ISDIR(ip->i_di.di_mode)) | 147 | if (S_ISDIR(inode->i_mode)) |
148 | return -EPERM; | 148 | return -EPERM; |
149 | 149 | ||
150 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 150 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
@@ -169,7 +169,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
169 | } | 169 | } |
170 | 170 | ||
171 | error = -EINVAL; | 171 | error = -EINVAL; |
172 | if (!dip->i_di.di_nlink) | 172 | if (!dip->i_inode.i_nlink) |
173 | goto out_gunlock; | 173 | goto out_gunlock; |
174 | error = -EFBIG; | 174 | error = -EFBIG; |
175 | if (dip->i_di.di_entries == (u32)-1) | 175 | if (dip->i_di.di_entries == (u32)-1) |
@@ -178,10 +178,10 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
178 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 178 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
179 | goto out_gunlock; | 179 | goto out_gunlock; |
180 | error = -EINVAL; | 180 | error = -EINVAL; |
181 | if (!ip->i_di.di_nlink) | 181 | if (!ip->i_inode.i_nlink) |
182 | goto out_gunlock; | 182 | goto out_gunlock; |
183 | error = -EMLINK; | 183 | error = -EMLINK; |
184 | if (ip->i_di.di_nlink == (u32)-1) | 184 | if (ip->i_inode.i_nlink == (u32)-1) |
185 | goto out_gunlock; | 185 | goto out_gunlock; |
186 | 186 | ||
187 | alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name); | 187 | alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name); |
@@ -196,8 +196,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
196 | if (error) | 196 | if (error) |
197 | goto out_alloc; | 197 | goto out_alloc; |
198 | 198 | ||
199 | error = gfs2_quota_check(dip, dip->i_di.di_uid, | 199 | error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid); |
200 | dip->i_di.di_gid); | ||
201 | if (error) | 200 | if (error) |
202 | goto out_gunlock_q; | 201 | goto out_gunlock_q; |
203 | 202 | ||
@@ -220,7 +219,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
220 | } | 219 | } |
221 | 220 | ||
222 | error = gfs2_dir_add(dir, &dentry->d_name, &ip->i_num, | 221 | error = gfs2_dir_add(dir, &dentry->d_name, &ip->i_num, |
223 | IF2DT(ip->i_di.di_mode)); | 222 | IF2DT(inode->i_mode)); |
224 | if (error) | 223 | if (error) |
225 | goto out_end_trans; | 224 | goto out_end_trans; |
226 | 225 | ||
@@ -326,7 +325,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | |||
326 | 325 | ||
327 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 326 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
328 | 327 | ||
329 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO); | 328 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO, 0); |
330 | if (IS_ERR(inode)) { | 329 | if (IS_ERR(inode)) { |
331 | gfs2_holder_uninit(ghs); | 330 | gfs2_holder_uninit(ghs); |
332 | return PTR_ERR(inode); | 331 | return PTR_ERR(inode); |
@@ -339,7 +338,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | |||
339 | error = gfs2_meta_inode_buffer(ip, &dibh); | 338 | error = gfs2_meta_inode_buffer(ip, &dibh); |
340 | 339 | ||
341 | if (!gfs2_assert_withdraw(sdp, !error)) { | 340 | if (!gfs2_assert_withdraw(sdp, !error)) { |
342 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 341 | gfs2_dinode_out(ip, dibh->b_data); |
343 | memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname, | 342 | memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname, |
344 | size); | 343 | size); |
345 | brelse(dibh); | 344 | brelse(dibh); |
@@ -379,7 +378,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
379 | 378 | ||
380 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 379 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
381 | 380 | ||
382 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode); | 381 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode, 0); |
383 | if (IS_ERR(inode)) { | 382 | if (IS_ERR(inode)) { |
384 | gfs2_holder_uninit(ghs); | 383 | gfs2_holder_uninit(ghs); |
385 | return PTR_ERR(inode); | 384 | return PTR_ERR(inode); |
@@ -387,10 +386,9 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
387 | 386 | ||
388 | ip = ghs[1].gh_gl->gl_object; | 387 | ip = ghs[1].gh_gl->gl_object; |
389 | 388 | ||
390 | ip->i_di.di_nlink = 2; | 389 | ip->i_inode.i_nlink = 2; |
391 | ip->i_di.di_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); | 390 | ip->i_di.di_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); |
392 | ip->i_di.di_flags |= GFS2_DIF_JDATA; | 391 | ip->i_di.di_flags |= GFS2_DIF_JDATA; |
393 | ip->i_di.di_payload_format = GFS2_FORMAT_DE; | ||
394 | ip->i_di.di_entries = 2; | 392 | ip->i_di.di_entries = 2; |
395 | 393 | ||
396 | error = gfs2_meta_inode_buffer(ip, &dibh); | 394 | error = gfs2_meta_inode_buffer(ip, &dibh); |
@@ -414,7 +412,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
414 | gfs2_inum_out(&dip->i_num, &dent->de_inum); | 412 | gfs2_inum_out(&dip->i_num, &dent->de_inum); |
415 | dent->de_type = cpu_to_be16(DT_DIR); | 413 | dent->de_type = cpu_to_be16(DT_DIR); |
416 | 414 | ||
417 | gfs2_dinode_out(&ip->i_di, di); | 415 | gfs2_dinode_out(ip, di); |
418 | 416 | ||
419 | brelse(dibh); | 417 | brelse(dibh); |
420 | } | 418 | } |
@@ -467,7 +465,7 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry) | |||
467 | 465 | ||
468 | if (ip->i_di.di_entries < 2) { | 466 | if (ip->i_di.di_entries < 2) { |
469 | if (gfs2_consist_inode(ip)) | 467 | if (gfs2_consist_inode(ip)) |
470 | gfs2_dinode_print(&ip->i_di); | 468 | gfs2_dinode_print(ip); |
471 | error = -EIO; | 469 | error = -EIO; |
472 | goto out_gunlock; | 470 | goto out_gunlock; |
473 | } | 471 | } |
@@ -504,47 +502,19 @@ out: | |||
504 | static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode, | 502 | static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode, |
505 | dev_t dev) | 503 | dev_t dev) |
506 | { | 504 | { |
507 | struct gfs2_inode *dip = GFS2_I(dir), *ip; | 505 | struct gfs2_inode *dip = GFS2_I(dir); |
508 | struct gfs2_sbd *sdp = GFS2_SB(dir); | 506 | struct gfs2_sbd *sdp = GFS2_SB(dir); |
509 | struct gfs2_holder ghs[2]; | 507 | struct gfs2_holder ghs[2]; |
510 | struct inode *inode; | 508 | struct inode *inode; |
511 | struct buffer_head *dibh; | ||
512 | u32 major = 0, minor = 0; | ||
513 | int error; | ||
514 | |||
515 | switch (mode & S_IFMT) { | ||
516 | case S_IFBLK: | ||
517 | case S_IFCHR: | ||
518 | major = MAJOR(dev); | ||
519 | minor = MINOR(dev); | ||
520 | break; | ||
521 | case S_IFIFO: | ||
522 | case S_IFSOCK: | ||
523 | break; | ||
524 | default: | ||
525 | return -EOPNOTSUPP; | ||
526 | }; | ||
527 | 509 | ||
528 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 510 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
529 | 511 | ||
530 | inode = gfs2_createi(ghs, &dentry->d_name, mode); | 512 | inode = gfs2_createi(ghs, &dentry->d_name, mode, dev); |
531 | if (IS_ERR(inode)) { | 513 | if (IS_ERR(inode)) { |
532 | gfs2_holder_uninit(ghs); | 514 | gfs2_holder_uninit(ghs); |
533 | return PTR_ERR(inode); | 515 | return PTR_ERR(inode); |
534 | } | 516 | } |
535 | 517 | ||
536 | ip = ghs[1].gh_gl->gl_object; | ||
537 | |||
538 | ip->i_di.di_major = major; | ||
539 | ip->i_di.di_minor = minor; | ||
540 | |||
541 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
542 | |||
543 | if (!gfs2_assert_withdraw(sdp, !error)) { | ||
544 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | ||
545 | brelse(dibh); | ||
546 | } | ||
547 | |||
548 | gfs2_trans_end(sdp); | 518 | gfs2_trans_end(sdp); |
549 | if (dip->i_alloc.al_rgd) | 519 | if (dip->i_alloc.al_rgd) |
550 | gfs2_inplace_release(dip); | 520 | gfs2_inplace_release(dip); |
@@ -592,11 +562,10 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
592 | 562 | ||
593 | /* Make sure we aren't trying to move a dirctory into it's subdir */ | 563 | /* Make sure we aren't trying to move a dirctory into it's subdir */ |
594 | 564 | ||
595 | if (S_ISDIR(ip->i_di.di_mode) && odip != ndip) { | 565 | if (S_ISDIR(ip->i_inode.i_mode) && odip != ndip) { |
596 | dir_rename = 1; | 566 | dir_rename = 1; |
597 | 567 | ||
598 | error = gfs2_glock_nq_init(sdp->sd_rename_gl, | 568 | error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, 0, |
599 | LM_ST_EXCLUSIVE, 0, | ||
600 | &r_gh); | 569 | &r_gh); |
601 | if (error) | 570 | if (error) |
602 | goto out; | 571 | goto out; |
@@ -637,10 +606,10 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
637 | if (error) | 606 | if (error) |
638 | goto out_gunlock; | 607 | goto out_gunlock; |
639 | 608 | ||
640 | if (S_ISDIR(nip->i_di.di_mode)) { | 609 | if (S_ISDIR(nip->i_inode.i_mode)) { |
641 | if (nip->i_di.di_entries < 2) { | 610 | if (nip->i_di.di_entries < 2) { |
642 | if (gfs2_consist_inode(nip)) | 611 | if (gfs2_consist_inode(nip)) |
643 | gfs2_dinode_print(&nip->i_di); | 612 | gfs2_dinode_print(nip); |
644 | error = -EIO; | 613 | error = -EIO; |
645 | goto out_gunlock; | 614 | goto out_gunlock; |
646 | } | 615 | } |
@@ -666,7 +635,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
666 | }; | 635 | }; |
667 | 636 | ||
668 | if (odip != ndip) { | 637 | if (odip != ndip) { |
669 | if (!ndip->i_di.di_nlink) { | 638 | if (!ndip->i_inode.i_nlink) { |
670 | error = -EINVAL; | 639 | error = -EINVAL; |
671 | goto out_gunlock; | 640 | goto out_gunlock; |
672 | } | 641 | } |
@@ -674,8 +643,8 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
674 | error = -EFBIG; | 643 | error = -EFBIG; |
675 | goto out_gunlock; | 644 | goto out_gunlock; |
676 | } | 645 | } |
677 | if (S_ISDIR(ip->i_di.di_mode) && | 646 | if (S_ISDIR(ip->i_inode.i_mode) && |
678 | ndip->i_di.di_nlink == (u32)-1) { | 647 | ndip->i_inode.i_nlink == (u32)-1) { |
679 | error = -EMLINK; | 648 | error = -EMLINK; |
680 | goto out_gunlock; | 649 | goto out_gunlock; |
681 | } | 650 | } |
@@ -702,8 +671,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
702 | if (error) | 671 | if (error) |
703 | goto out_alloc; | 672 | goto out_alloc; |
704 | 673 | ||
705 | error = gfs2_quota_check(ndip, ndip->i_di.di_uid, | 674 | error = gfs2_quota_check(ndip, ndip->i_inode.i_uid, ndip->i_inode.i_gid); |
706 | ndip->i_di.di_gid); | ||
707 | if (error) | 675 | if (error) |
708 | goto out_gunlock_q; | 676 | goto out_gunlock_q; |
709 | 677 | ||
@@ -729,7 +697,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
729 | /* Remove the target file, if it exists */ | 697 | /* Remove the target file, if it exists */ |
730 | 698 | ||
731 | if (nip) { | 699 | if (nip) { |
732 | if (S_ISDIR(nip->i_di.di_mode)) | 700 | if (S_ISDIR(nip->i_inode.i_mode)) |
733 | error = gfs2_rmdiri(ndip, &ndentry->d_name, nip); | 701 | error = gfs2_rmdiri(ndip, &ndentry->d_name, nip); |
734 | else { | 702 | else { |
735 | error = gfs2_dir_del(ndip, &ndentry->d_name); | 703 | error = gfs2_dir_del(ndip, &ndentry->d_name); |
@@ -760,9 +728,9 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
760 | error = gfs2_meta_inode_buffer(ip, &dibh); | 728 | error = gfs2_meta_inode_buffer(ip, &dibh); |
761 | if (error) | 729 | if (error) |
762 | goto out_end_trans; | 730 | goto out_end_trans; |
763 | ip->i_di.di_ctime = get_seconds(); | 731 | ip->i_inode.i_ctime.tv_sec = get_seconds(); |
764 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 732 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
765 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 733 | gfs2_dinode_out(ip, dibh->b_data); |
766 | brelse(dibh); | 734 | brelse(dibh); |
767 | } | 735 | } |
768 | 736 | ||
@@ -771,7 +739,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
771 | goto out_end_trans; | 739 | goto out_end_trans; |
772 | 740 | ||
773 | error = gfs2_dir_add(ndir, &ndentry->d_name, &ip->i_num, | 741 | error = gfs2_dir_add(ndir, &ndentry->d_name, &ip->i_num, |
774 | IF2DT(ip->i_di.di_mode)); | 742 | IF2DT(ip->i_inode.i_mode)); |
775 | if (error) | 743 | if (error) |
776 | goto out_end_trans; | 744 | goto out_end_trans; |
777 | 745 | ||
@@ -867,6 +835,10 @@ static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
867 | * @mask: | 835 | * @mask: |
868 | * @nd: passed from Linux VFS, ignored by us | 836 | * @nd: passed from Linux VFS, ignored by us |
869 | * | 837 | * |
838 | * This may be called from the VFS directly, or from within GFS2 with the | ||
839 | * inode locked, so we look to see if the glock is already locked and only | ||
840 | * lock the glock if its not already been done. | ||
841 | * | ||
870 | * Returns: errno | 842 | * Returns: errno |
871 | */ | 843 | */ |
872 | 844 | ||
@@ -875,15 +847,18 @@ static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
875 | struct gfs2_inode *ip = GFS2_I(inode); | 847 | struct gfs2_inode *ip = GFS2_I(inode); |
876 | struct gfs2_holder i_gh; | 848 | struct gfs2_holder i_gh; |
877 | int error; | 849 | int error; |
850 | int unlock = 0; | ||
878 | 851 | ||
879 | if (ip->i_vn == ip->i_gl->gl_vn) | 852 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == 0) { |
880 | return generic_permission(inode, mask, gfs2_check_acl); | 853 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); |
854 | if (error) | ||
855 | return error; | ||
856 | unlock = 1; | ||
857 | } | ||
881 | 858 | ||
882 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | 859 | error = generic_permission(inode, mask, gfs2_check_acl); |
883 | if (!error) { | 860 | if (unlock) |
884 | error = generic_permission(inode, mask, gfs2_check_acl_locked); | ||
885 | gfs2_glock_dq_uninit(&i_gh); | 861 | gfs2_glock_dq_uninit(&i_gh); |
886 | } | ||
887 | 862 | ||
888 | return error; | 863 | return error; |
889 | } | 864 | } |
@@ -914,8 +889,8 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
914 | u32 ouid, ogid, nuid, ngid; | 889 | u32 ouid, ogid, nuid, ngid; |
915 | int error; | 890 | int error; |
916 | 891 | ||
917 | ouid = ip->i_di.di_uid; | 892 | ouid = inode->i_uid; |
918 | ogid = ip->i_di.di_gid; | 893 | ogid = inode->i_gid; |
919 | nuid = attr->ia_uid; | 894 | nuid = attr->ia_uid; |
920 | ngid = attr->ia_gid; | 895 | ngid = attr->ia_gid; |
921 | 896 | ||
@@ -946,10 +921,9 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
946 | 921 | ||
947 | error = inode_setattr(inode, attr); | 922 | error = inode_setattr(inode, attr); |
948 | gfs2_assert_warn(sdp, !error); | 923 | gfs2_assert_warn(sdp, !error); |
949 | gfs2_inode_attr_out(ip); | ||
950 | 924 | ||
951 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 925 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
952 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 926 | gfs2_dinode_out(ip, dibh->b_data); |
953 | brelse(dibh); | 927 | brelse(dibh); |
954 | 928 | ||
955 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { | 929 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { |
@@ -1018,6 +992,12 @@ out: | |||
1018 | * @dentry: The dentry to stat | 992 | * @dentry: The dentry to stat |
1019 | * @stat: The inode's stats | 993 | * @stat: The inode's stats |
1020 | * | 994 | * |
995 | * This may be called from the VFS directly, or from within GFS2 with the | ||
996 | * inode locked, so we look to see if the glock is already locked and only | ||
997 | * lock the glock if its not already been done. Note that its the NFS | ||
998 | * readdirplus operation which causes this to be called (from filldir) | ||
999 | * with the glock already held. | ||
1000 | * | ||
1021 | * Returns: errno | 1001 | * Returns: errno |
1022 | */ | 1002 | */ |
1023 | 1003 | ||
@@ -1028,14 +1008,20 @@ static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
1028 | struct gfs2_inode *ip = GFS2_I(inode); | 1008 | struct gfs2_inode *ip = GFS2_I(inode); |
1029 | struct gfs2_holder gh; | 1009 | struct gfs2_holder gh; |
1030 | int error; | 1010 | int error; |
1011 | int unlock = 0; | ||
1031 | 1012 | ||
1032 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); | 1013 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == 0) { |
1033 | if (!error) { | 1014 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); |
1034 | generic_fillattr(inode, stat); | 1015 | if (error) |
1035 | gfs2_glock_dq_uninit(&gh); | 1016 | return error; |
1017 | unlock = 1; | ||
1036 | } | 1018 | } |
1037 | 1019 | ||
1038 | return error; | 1020 | generic_fillattr(inode, stat); |
1021 | if (unlock); | ||
1022 | gfs2_glock_dq_uninit(&gh); | ||
1023 | |||
1024 | return 0; | ||
1039 | } | 1025 | } |
1040 | 1026 | ||
1041 | static int gfs2_setxattr(struct dentry *dentry, const char *name, | 1027 | static int gfs2_setxattr(struct dentry *dentry, const char *name, |
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index b47d9598c047..7685b46f934b 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c | |||
@@ -157,7 +157,8 @@ static void gfs2_write_super(struct super_block *sb) | |||
157 | static int gfs2_sync_fs(struct super_block *sb, int wait) | 157 | static int gfs2_sync_fs(struct super_block *sb, int wait) |
158 | { | 158 | { |
159 | sb->s_dirt = 0; | 159 | sb->s_dirt = 0; |
160 | gfs2_log_flush(sb->s_fs_info, NULL); | 160 | if (wait) |
161 | gfs2_log_flush(sb->s_fs_info, NULL); | ||
161 | return 0; | 162 | return 0; |
162 | } | 163 | } |
163 | 164 | ||
@@ -215,7 +216,7 @@ static int gfs2_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
215 | { | 216 | { |
216 | struct super_block *sb = dentry->d_inode->i_sb; | 217 | struct super_block *sb = dentry->d_inode->i_sb; |
217 | struct gfs2_sbd *sdp = sb->s_fs_info; | 218 | struct gfs2_sbd *sdp = sb->s_fs_info; |
218 | struct gfs2_statfs_change sc; | 219 | struct gfs2_statfs_change_host sc; |
219 | int error; | 220 | int error; |
220 | 221 | ||
221 | if (gfs2_tune_get(sdp, gt_statfs_slow)) | 222 | if (gfs2_tune_get(sdp, gt_statfs_slow)) |
@@ -293,8 +294,6 @@ static void gfs2_clear_inode(struct inode *inode) | |||
293 | */ | 294 | */ |
294 | if (inode->i_private) { | 295 | if (inode->i_private) { |
295 | struct gfs2_inode *ip = GFS2_I(inode); | 296 | struct gfs2_inode *ip = GFS2_I(inode); |
296 | gfs2_glock_inode_squish(inode); | ||
297 | gfs2_assert(inode->i_sb->s_fs_info, ip->i_gl->gl_state == LM_ST_UNLOCKED); | ||
298 | ip->i_gl->gl_object = NULL; | 297 | ip->i_gl->gl_object = NULL; |
299 | gfs2_glock_schedule_for_reclaim(ip->i_gl); | 298 | gfs2_glock_schedule_for_reclaim(ip->i_gl); |
300 | gfs2_glock_put(ip->i_gl); | 299 | gfs2_glock_put(ip->i_gl); |
@@ -395,7 +394,7 @@ static void gfs2_delete_inode(struct inode *inode) | |||
395 | if (!inode->i_private) | 394 | if (!inode->i_private) |
396 | goto out; | 395 | goto out; |
397 | 396 | ||
398 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &gh); | 397 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB, &gh); |
399 | if (unlikely(error)) { | 398 | if (unlikely(error)) { |
400 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | 399 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); |
401 | goto out; | 400 | goto out; |
@@ -407,7 +406,7 @@ static void gfs2_delete_inode(struct inode *inode) | |||
407 | if (error) | 406 | if (error) |
408 | goto out_uninit; | 407 | goto out_uninit; |
409 | 408 | ||
410 | if (S_ISDIR(ip->i_di.di_mode) && | 409 | if (S_ISDIR(inode->i_mode) && |
411 | (ip->i_di.di_flags & GFS2_DIF_EXHASH)) { | 410 | (ip->i_di.di_flags & GFS2_DIF_EXHASH)) { |
412 | error = gfs2_dir_exhash_dealloc(ip); | 411 | error = gfs2_dir_exhash_dealloc(ip); |
413 | if (error) | 412 | if (error) |
diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c index 5453d2947ab3..45a5f11fc39a 100644 --- a/fs/gfs2/ops_vm.c +++ b/fs/gfs2/ops_vm.c | |||
@@ -76,7 +76,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) | |||
76 | if (error) | 76 | if (error) |
77 | goto out; | 77 | goto out; |
78 | 78 | ||
79 | error = gfs2_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); | 79 | error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); |
80 | if (error) | 80 | if (error) |
81 | goto out_gunlock_q; | 81 | goto out_gunlock_q; |
82 | 82 | ||
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index a3deae7416c9..d0db881b55d2 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -452,19 +452,19 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
452 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | 452 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) |
453 | return 0; | 453 | return 0; |
454 | 454 | ||
455 | error = qdsb_get(sdp, QUOTA_USER, ip->i_di.di_uid, CREATE, qd); | 455 | error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, CREATE, qd); |
456 | if (error) | 456 | if (error) |
457 | goto out; | 457 | goto out; |
458 | al->al_qd_num++; | 458 | al->al_qd_num++; |
459 | qd++; | 459 | qd++; |
460 | 460 | ||
461 | error = qdsb_get(sdp, QUOTA_GROUP, ip->i_di.di_gid, CREATE, qd); | 461 | error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, CREATE, qd); |
462 | if (error) | 462 | if (error) |
463 | goto out; | 463 | goto out; |
464 | al->al_qd_num++; | 464 | al->al_qd_num++; |
465 | qd++; | 465 | qd++; |
466 | 466 | ||
467 | if (uid != NO_QUOTA_CHANGE && uid != ip->i_di.di_uid) { | 467 | if (uid != NO_QUOTA_CHANGE && uid != ip->i_inode.i_uid) { |
468 | error = qdsb_get(sdp, QUOTA_USER, uid, CREATE, qd); | 468 | error = qdsb_get(sdp, QUOTA_USER, uid, CREATE, qd); |
469 | if (error) | 469 | if (error) |
470 | goto out; | 470 | goto out; |
@@ -472,7 +472,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
472 | qd++; | 472 | qd++; |
473 | } | 473 | } |
474 | 474 | ||
475 | if (gid != NO_QUOTA_CHANGE && gid != ip->i_di.di_gid) { | 475 | if (gid != NO_QUOTA_CHANGE && gid != ip->i_inode.i_gid) { |
476 | error = qdsb_get(sdp, QUOTA_GROUP, gid, CREATE, qd); | 476 | error = qdsb_get(sdp, QUOTA_GROUP, gid, CREATE, qd); |
477 | if (error) | 477 | if (error) |
478 | goto out; | 478 | goto out; |
@@ -539,8 +539,7 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change) | |||
539 | qc->qc_id = cpu_to_be32(qd->qd_id); | 539 | qc->qc_id = cpu_to_be32(qd->qd_id); |
540 | } | 540 | } |
541 | 541 | ||
542 | x = qc->qc_change; | 542 | x = be64_to_cpu(qc->qc_change) + change; |
543 | x = be64_to_cpu(x) + change; | ||
544 | qc->qc_change = cpu_to_be64(x); | 543 | qc->qc_change = cpu_to_be64(x); |
545 | 544 | ||
546 | spin_lock(&sdp->sd_quota_spin); | 545 | spin_lock(&sdp->sd_quota_spin); |
@@ -743,7 +742,7 @@ static int do_glock(struct gfs2_quota_data *qd, int force_refresh, | |||
743 | struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd; | 742 | struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd; |
744 | struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode); | 743 | struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode); |
745 | struct gfs2_holder i_gh; | 744 | struct gfs2_holder i_gh; |
746 | struct gfs2_quota q; | 745 | struct gfs2_quota_host q; |
747 | char buf[sizeof(struct gfs2_quota)]; | 746 | char buf[sizeof(struct gfs2_quota)]; |
748 | struct file_ra_state ra_state; | 747 | struct file_ra_state ra_state; |
749 | int error; | 748 | int error; |
@@ -1103,7 +1102,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp) | |||
1103 | 1102 | ||
1104 | for (y = 0; y < sdp->sd_qc_per_block && slot < sdp->sd_quota_slots; | 1103 | for (y = 0; y < sdp->sd_qc_per_block && slot < sdp->sd_quota_slots; |
1105 | y++, slot++) { | 1104 | y++, slot++) { |
1106 | struct gfs2_quota_change qc; | 1105 | struct gfs2_quota_change_host qc; |
1107 | struct gfs2_quota_data *qd; | 1106 | struct gfs2_quota_data *qd; |
1108 | 1107 | ||
1109 | gfs2_quota_change_in(&qc, bh->b_data + | 1108 | gfs2_quota_change_in(&qc, bh->b_data + |
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 62cd223819b7..d0c806b85c86 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c | |||
@@ -132,10 +132,11 @@ void gfs2_revoke_clean(struct gfs2_sbd *sdp) | |||
132 | */ | 132 | */ |
133 | 133 | ||
134 | static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, | 134 | static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, |
135 | struct gfs2_log_header *head) | 135 | struct gfs2_log_header_host *head) |
136 | { | 136 | { |
137 | struct buffer_head *bh; | 137 | struct buffer_head *bh; |
138 | struct gfs2_log_header lh; | 138 | struct gfs2_log_header_host lh; |
139 | const u32 nothing = 0; | ||
139 | u32 hash; | 140 | u32 hash; |
140 | int error; | 141 | int error; |
141 | 142 | ||
@@ -143,11 +144,11 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, | |||
143 | if (error) | 144 | if (error) |
144 | return error; | 145 | return error; |
145 | 146 | ||
146 | memcpy(&lh, bh->b_data, sizeof(struct gfs2_log_header)); | 147 | hash = crc32_le((u32)~0, bh->b_data, sizeof(struct gfs2_log_header) - |
147 | lh.lh_hash = 0; | 148 | sizeof(u32)); |
148 | hash = gfs2_disk_hash((char *)&lh, sizeof(struct gfs2_log_header)); | 149 | hash = crc32_le(hash, (unsigned char const *)¬hing, sizeof(nothing)); |
150 | hash ^= (u32)~0; | ||
149 | gfs2_log_header_in(&lh, bh->b_data); | 151 | gfs2_log_header_in(&lh, bh->b_data); |
150 | |||
151 | brelse(bh); | 152 | brelse(bh); |
152 | 153 | ||
153 | if (lh.lh_header.mh_magic != GFS2_MAGIC || | 154 | if (lh.lh_header.mh_magic != GFS2_MAGIC || |
@@ -174,7 +175,7 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, | |||
174 | */ | 175 | */ |
175 | 176 | ||
176 | static int find_good_lh(struct gfs2_jdesc *jd, unsigned int *blk, | 177 | static int find_good_lh(struct gfs2_jdesc *jd, unsigned int *blk, |
177 | struct gfs2_log_header *head) | 178 | struct gfs2_log_header_host *head) |
178 | { | 179 | { |
179 | unsigned int orig_blk = *blk; | 180 | unsigned int orig_blk = *blk; |
180 | int error; | 181 | int error; |
@@ -205,10 +206,10 @@ static int find_good_lh(struct gfs2_jdesc *jd, unsigned int *blk, | |||
205 | * Returns: errno | 206 | * Returns: errno |
206 | */ | 207 | */ |
207 | 208 | ||
208 | static int jhead_scan(struct gfs2_jdesc *jd, struct gfs2_log_header *head) | 209 | static int jhead_scan(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head) |
209 | { | 210 | { |
210 | unsigned int blk = head->lh_blkno; | 211 | unsigned int blk = head->lh_blkno; |
211 | struct gfs2_log_header lh; | 212 | struct gfs2_log_header_host lh; |
212 | int error; | 213 | int error; |
213 | 214 | ||
214 | for (;;) { | 215 | for (;;) { |
@@ -245,9 +246,9 @@ static int jhead_scan(struct gfs2_jdesc *jd, struct gfs2_log_header *head) | |||
245 | * Returns: errno | 246 | * Returns: errno |
246 | */ | 247 | */ |
247 | 248 | ||
248 | int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header *head) | 249 | int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head) |
249 | { | 250 | { |
250 | struct gfs2_log_header lh_1, lh_m; | 251 | struct gfs2_log_header_host lh_1, lh_m; |
251 | u32 blk_1, blk_2, blk_m; | 252 | u32 blk_1, blk_2, blk_m; |
252 | int error; | 253 | int error; |
253 | 254 | ||
@@ -320,7 +321,7 @@ static int foreach_descriptor(struct gfs2_jdesc *jd, unsigned int start, | |||
320 | length = be32_to_cpu(ld->ld_length); | 321 | length = be32_to_cpu(ld->ld_length); |
321 | 322 | ||
322 | if (be32_to_cpu(ld->ld_header.mh_type) == GFS2_METATYPE_LH) { | 323 | if (be32_to_cpu(ld->ld_header.mh_type) == GFS2_METATYPE_LH) { |
323 | struct gfs2_log_header lh; | 324 | struct gfs2_log_header_host lh; |
324 | error = get_log_header(jd, start, &lh); | 325 | error = get_log_header(jd, start, &lh); |
325 | if (!error) { | 326 | if (!error) { |
326 | gfs2_replay_incr_blk(sdp, &start); | 327 | gfs2_replay_incr_blk(sdp, &start); |
@@ -363,7 +364,7 @@ static int foreach_descriptor(struct gfs2_jdesc *jd, unsigned int start, | |||
363 | * Returns: errno | 364 | * Returns: errno |
364 | */ | 365 | */ |
365 | 366 | ||
366 | static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head) | 367 | static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head) |
367 | { | 368 | { |
368 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); | 369 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); |
369 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); | 370 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
@@ -425,7 +426,7 @@ int gfs2_recover_journal(struct gfs2_jdesc *jd) | |||
425 | { | 426 | { |
426 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); | 427 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); |
427 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); | 428 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
428 | struct gfs2_log_header head; | 429 | struct gfs2_log_header_host head; |
429 | struct gfs2_holder j_gh, ji_gh, t_gh; | 430 | struct gfs2_holder j_gh, ji_gh, t_gh; |
430 | unsigned long t; | 431 | unsigned long t; |
431 | int ro = 0; | 432 | int ro = 0; |
diff --git a/fs/gfs2/recovery.h b/fs/gfs2/recovery.h index 961feedf4d8b..f7235e61c723 100644 --- a/fs/gfs2/recovery.h +++ b/fs/gfs2/recovery.h | |||
@@ -26,7 +26,7 @@ int gfs2_revoke_check(struct gfs2_sbd *sdp, u64 blkno, unsigned int where); | |||
26 | void gfs2_revoke_clean(struct gfs2_sbd *sdp); | 26 | void gfs2_revoke_clean(struct gfs2_sbd *sdp); |
27 | 27 | ||
28 | int gfs2_find_jhead(struct gfs2_jdesc *jd, | 28 | int gfs2_find_jhead(struct gfs2_jdesc *jd, |
29 | struct gfs2_log_header *head); | 29 | struct gfs2_log_header_host *head); |
30 | int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd); | 30 | int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd); |
31 | void gfs2_check_journals(struct gfs2_sbd *sdp); | 31 | void gfs2_check_journals(struct gfs2_sbd *sdp); |
32 | 32 | ||
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index b261385c0065..ff0846528d54 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -253,7 +253,7 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd) | |||
253 | 253 | ||
254 | } | 254 | } |
255 | 255 | ||
256 | static inline int rgrp_contains_block(struct gfs2_rindex *ri, u64 block) | 256 | static inline int rgrp_contains_block(struct gfs2_rindex_host *ri, u64 block) |
257 | { | 257 | { |
258 | u64 first = ri->ri_data0; | 258 | u64 first = ri->ri_data0; |
259 | u64 last = first + ri->ri_data; | 259 | u64 last = first + ri->ri_data; |
@@ -1217,7 +1217,7 @@ u64 gfs2_alloc_data(struct gfs2_inode *ip) | |||
1217 | al->al_alloced++; | 1217 | al->al_alloced++; |
1218 | 1218 | ||
1219 | gfs2_statfs_change(sdp, 0, -1, 0); | 1219 | gfs2_statfs_change(sdp, 0, -1, 0); |
1220 | gfs2_quota_change(ip, +1, ip->i_di.di_uid, ip->i_di.di_gid); | 1220 | gfs2_quota_change(ip, +1, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1221 | 1221 | ||
1222 | spin_lock(&sdp->sd_rindex_spin); | 1222 | spin_lock(&sdp->sd_rindex_spin); |
1223 | rgd->rd_free_clone--; | 1223 | rgd->rd_free_clone--; |
@@ -1261,7 +1261,7 @@ u64 gfs2_alloc_meta(struct gfs2_inode *ip) | |||
1261 | al->al_alloced++; | 1261 | al->al_alloced++; |
1262 | 1262 | ||
1263 | gfs2_statfs_change(sdp, 0, -1, 0); | 1263 | gfs2_statfs_change(sdp, 0, -1, 0); |
1264 | gfs2_quota_change(ip, +1, ip->i_di.di_uid, ip->i_di.di_gid); | 1264 | gfs2_quota_change(ip, +1, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1265 | gfs2_trans_add_unrevoke(sdp, block); | 1265 | gfs2_trans_add_unrevoke(sdp, block); |
1266 | 1266 | ||
1267 | spin_lock(&sdp->sd_rindex_spin); | 1267 | spin_lock(&sdp->sd_rindex_spin); |
@@ -1337,8 +1337,7 @@ void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
1337 | gfs2_trans_add_rg(rgd); | 1337 | gfs2_trans_add_rg(rgd); |
1338 | 1338 | ||
1339 | gfs2_statfs_change(sdp, 0, +blen, 0); | 1339 | gfs2_statfs_change(sdp, 0, +blen, 0); |
1340 | gfs2_quota_change(ip, -(s64)blen, | 1340 | gfs2_quota_change(ip, -(s64)blen, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1341 | ip->i_di.di_uid, ip->i_di.di_gid); | ||
1342 | } | 1341 | } |
1343 | 1342 | ||
1344 | /** | 1343 | /** |
@@ -1366,7 +1365,7 @@ void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
1366 | gfs2_trans_add_rg(rgd); | 1365 | gfs2_trans_add_rg(rgd); |
1367 | 1366 | ||
1368 | gfs2_statfs_change(sdp, 0, +blen, 0); | 1367 | gfs2_statfs_change(sdp, 0, +blen, 0); |
1369 | gfs2_quota_change(ip, -(s64)blen, ip->i_di.di_uid, ip->i_di.di_gid); | 1368 | gfs2_quota_change(ip, -(s64)blen, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1370 | gfs2_meta_wipe(ip, bstart, blen); | 1369 | gfs2_meta_wipe(ip, bstart, blen); |
1371 | } | 1370 | } |
1372 | 1371 | ||
@@ -1411,7 +1410,7 @@ static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) | |||
1411 | void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) | 1410 | void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) |
1412 | { | 1411 | { |
1413 | gfs2_free_uninit_di(rgd, ip->i_num.no_addr); | 1412 | gfs2_free_uninit_di(rgd, ip->i_num.no_addr); |
1414 | gfs2_quota_change(ip, -1, ip->i_di.di_uid, ip->i_di.di_gid); | 1413 | gfs2_quota_change(ip, -1, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1415 | gfs2_meta_wipe(ip, ip->i_num.no_addr, 1); | 1414 | gfs2_meta_wipe(ip, ip->i_num.no_addr, 1); |
1416 | } | 1415 | } |
1417 | 1416 | ||
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 6a78b1b32e25..43a24f2e5905 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -97,7 +97,7 @@ void gfs2_tune_init(struct gfs2_tune *gt) | |||
97 | * changed. | 97 | * changed. |
98 | */ | 98 | */ |
99 | 99 | ||
100 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb *sb, int silent) | 100 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent) |
101 | { | 101 | { |
102 | unsigned int x; | 102 | unsigned int x; |
103 | 103 | ||
@@ -180,6 +180,24 @@ static int end_bio_io_page(struct bio *bio, unsigned int bytes_done, int error) | |||
180 | return 0; | 180 | return 0; |
181 | } | 181 | } |
182 | 182 | ||
183 | /** | ||
184 | * gfs2_read_super - Read the gfs2 super block from disk | ||
185 | * @sb: The VFS super block | ||
186 | * @sector: The location of the super block | ||
187 | * | ||
188 | * This uses the bio functions to read the super block from disk | ||
189 | * because we want to be 100% sure that we never read cached data. | ||
190 | * A super block is read twice only during each GFS2 mount and is | ||
191 | * never written to by the filesystem. The first time its read no | ||
192 | * locks are held, and the only details which are looked at are those | ||
193 | * relating to the locking protocol. Once locking is up and working, | ||
194 | * the sb is read again under the lock to establish the location of | ||
195 | * the master directory (contains pointers to journals etc) and the | ||
196 | * root directory. | ||
197 | * | ||
198 | * Returns: A page containing the sb or NULL | ||
199 | */ | ||
200 | |||
183 | struct page *gfs2_read_super(struct super_block *sb, sector_t sector) | 201 | struct page *gfs2_read_super(struct super_block *sb, sector_t sector) |
184 | { | 202 | { |
185 | struct page *page; | 203 | struct page *page; |
@@ -199,7 +217,7 @@ struct page *gfs2_read_super(struct super_block *sb, sector_t sector) | |||
199 | return NULL; | 217 | return NULL; |
200 | } | 218 | } |
201 | 219 | ||
202 | bio->bi_sector = sector; | 220 | bio->bi_sector = sector * (sb->s_blocksize >> 9); |
203 | bio->bi_bdev = sb->s_bdev; | 221 | bio->bi_bdev = sb->s_bdev; |
204 | bio_add_page(bio, page, PAGE_SIZE, 0); | 222 | bio_add_page(bio, page, PAGE_SIZE, 0); |
205 | 223 | ||
@@ -508,7 +526,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) | |||
508 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); | 526 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); |
509 | struct gfs2_glock *j_gl = ip->i_gl; | 527 | struct gfs2_glock *j_gl = ip->i_gl; |
510 | struct gfs2_holder t_gh; | 528 | struct gfs2_holder t_gh; |
511 | struct gfs2_log_header head; | 529 | struct gfs2_log_header_host head; |
512 | int error; | 530 | int error; |
513 | 531 | ||
514 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, | 532 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, |
@@ -517,7 +535,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) | |||
517 | return error; | 535 | return error; |
518 | 536 | ||
519 | gfs2_meta_cache_flush(ip); | 537 | gfs2_meta_cache_flush(ip); |
520 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA); | 538 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); |
521 | 539 | ||
522 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); | 540 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); |
523 | if (error) | 541 | if (error) |
@@ -587,9 +605,9 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | |||
587 | int gfs2_statfs_init(struct gfs2_sbd *sdp) | 605 | int gfs2_statfs_init(struct gfs2_sbd *sdp) |
588 | { | 606 | { |
589 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); | 607 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); |
590 | struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master; | 608 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; |
591 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 609 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
592 | struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; | 610 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
593 | struct buffer_head *m_bh, *l_bh; | 611 | struct buffer_head *m_bh, *l_bh; |
594 | struct gfs2_holder gh; | 612 | struct gfs2_holder gh; |
595 | int error; | 613 | int error; |
@@ -634,7 +652,7 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, | |||
634 | s64 dinodes) | 652 | s64 dinodes) |
635 | { | 653 | { |
636 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 654 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
637 | struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; | 655 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
638 | struct buffer_head *l_bh; | 656 | struct buffer_head *l_bh; |
639 | int error; | 657 | int error; |
640 | 658 | ||
@@ -660,8 +678,8 @@ int gfs2_statfs_sync(struct gfs2_sbd *sdp) | |||
660 | { | 678 | { |
661 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); | 679 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); |
662 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 680 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
663 | struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master; | 681 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; |
664 | struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; | 682 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
665 | struct gfs2_holder gh; | 683 | struct gfs2_holder gh; |
666 | struct buffer_head *m_bh, *l_bh; | 684 | struct buffer_head *m_bh, *l_bh; |
667 | int error; | 685 | int error; |
@@ -727,10 +745,10 @@ out: | |||
727 | * Returns: errno | 745 | * Returns: errno |
728 | */ | 746 | */ |
729 | 747 | ||
730 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) | 748 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) |
731 | { | 749 | { |
732 | struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master; | 750 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; |
733 | struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; | 751 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
734 | 752 | ||
735 | spin_lock(&sdp->sd_statfs_spin); | 753 | spin_lock(&sdp->sd_statfs_spin); |
736 | 754 | ||
@@ -760,7 +778,7 @@ int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) | |||
760 | */ | 778 | */ |
761 | 779 | ||
762 | static int statfs_slow_fill(struct gfs2_rgrpd *rgd, | 780 | static int statfs_slow_fill(struct gfs2_rgrpd *rgd, |
763 | struct gfs2_statfs_change *sc) | 781 | struct gfs2_statfs_change_host *sc) |
764 | { | 782 | { |
765 | gfs2_rgrp_verify(rgd); | 783 | gfs2_rgrp_verify(rgd); |
766 | sc->sc_total += rgd->rd_ri.ri_data; | 784 | sc->sc_total += rgd->rd_ri.ri_data; |
@@ -782,7 +800,7 @@ static int statfs_slow_fill(struct gfs2_rgrpd *rgd, | |||
782 | * Returns: errno | 800 | * Returns: errno |
783 | */ | 801 | */ |
784 | 802 | ||
785 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) | 803 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) |
786 | { | 804 | { |
787 | struct gfs2_holder ri_gh; | 805 | struct gfs2_holder ri_gh; |
788 | struct gfs2_rgrpd *rgd_next; | 806 | struct gfs2_rgrpd *rgd_next; |
@@ -792,7 +810,7 @@ int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) | |||
792 | int done; | 810 | int done; |
793 | int error = 0, err; | 811 | int error = 0, err; |
794 | 812 | ||
795 | memset(sc, 0, sizeof(struct gfs2_statfs_change)); | 813 | memset(sc, 0, sizeof(struct gfs2_statfs_change_host)); |
796 | gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL); | 814 | gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL); |
797 | if (!gha) | 815 | if (!gha) |
798 | return -ENOMEM; | 816 | return -ENOMEM; |
@@ -873,7 +891,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, | |||
873 | struct gfs2_jdesc *jd; | 891 | struct gfs2_jdesc *jd; |
874 | struct lfcc *lfcc; | 892 | struct lfcc *lfcc; |
875 | LIST_HEAD(list); | 893 | LIST_HEAD(list); |
876 | struct gfs2_log_header lh; | 894 | struct gfs2_log_header_host lh; |
877 | int error; | 895 | int error; |
878 | 896 | ||
879 | error = gfs2_jindex_hold(sdp, &ji_gh); | 897 | error = gfs2_jindex_hold(sdp, &ji_gh); |
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h index 5bb443ae0f59..e590b2df11dc 100644 --- a/fs/gfs2/super.h +++ b/fs/gfs2/super.h | |||
@@ -14,7 +14,7 @@ | |||
14 | 14 | ||
15 | void gfs2_tune_init(struct gfs2_tune *gt); | 15 | void gfs2_tune_init(struct gfs2_tune *gt); |
16 | 16 | ||
17 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb *sb, int silent); | 17 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent); |
18 | int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent); | 18 | int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent); |
19 | struct page *gfs2_read_super(struct super_block *sb, sector_t sector); | 19 | struct page *gfs2_read_super(struct super_block *sb, sector_t sector); |
20 | 20 | ||
@@ -45,8 +45,8 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp); | |||
45 | void gfs2_statfs_change(struct gfs2_sbd *sdp, | 45 | void gfs2_statfs_change(struct gfs2_sbd *sdp, |
46 | s64 total, s64 free, s64 dinodes); | 46 | s64 total, s64 free, s64 dinodes); |
47 | int gfs2_statfs_sync(struct gfs2_sbd *sdp); | 47 | int gfs2_statfs_sync(struct gfs2_sbd *sdp); |
48 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc); | 48 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc); |
49 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc); | 49 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc); |
50 | 50 | ||
51 | int gfs2_freeze_fs(struct gfs2_sbd *sdp); | 51 | int gfs2_freeze_fs(struct gfs2_sbd *sdp); |
52 | void gfs2_unfreeze_fs(struct gfs2_sbd *sdp); | 52 | void gfs2_unfreeze_fs(struct gfs2_sbd *sdp); |
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 0e0ec988f731..983eaf1e06be 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -426,9 +426,6 @@ static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\ | |||
426 | } \ | 426 | } \ |
427 | TUNE_ATTR_2(name, name##_store) | 427 | TUNE_ATTR_2(name, name##_store) |
428 | 428 | ||
429 | TUNE_ATTR(ilimit, 0); | ||
430 | TUNE_ATTR(ilimit_tries, 0); | ||
431 | TUNE_ATTR(ilimit_min, 0); | ||
432 | TUNE_ATTR(demote_secs, 0); | 429 | TUNE_ATTR(demote_secs, 0); |
433 | TUNE_ATTR(incore_log_blocks, 0); | 430 | TUNE_ATTR(incore_log_blocks, 0); |
434 | TUNE_ATTR(log_flush_secs, 0); | 431 | TUNE_ATTR(log_flush_secs, 0); |
@@ -447,7 +444,6 @@ TUNE_ATTR(quota_simul_sync, 1); | |||
447 | TUNE_ATTR(quota_cache_secs, 1); | 444 | TUNE_ATTR(quota_cache_secs, 1); |
448 | TUNE_ATTR(max_atomic_write, 1); | 445 | TUNE_ATTR(max_atomic_write, 1); |
449 | TUNE_ATTR(stall_secs, 1); | 446 | TUNE_ATTR(stall_secs, 1); |
450 | TUNE_ATTR(entries_per_readdir, 1); | ||
451 | TUNE_ATTR(greedy_default, 1); | 447 | TUNE_ATTR(greedy_default, 1); |
452 | TUNE_ATTR(greedy_quantum, 1); | 448 | TUNE_ATTR(greedy_quantum, 1); |
453 | TUNE_ATTR(greedy_max, 1); | 449 | TUNE_ATTR(greedy_max, 1); |
@@ -459,9 +455,6 @@ TUNE_ATTR_DAEMON(quotad_secs, quotad_process); | |||
459 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); | 455 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); |
460 | 456 | ||
461 | static struct attribute *tune_attrs[] = { | 457 | static struct attribute *tune_attrs[] = { |
462 | &tune_attr_ilimit.attr, | ||
463 | &tune_attr_ilimit_tries.attr, | ||
464 | &tune_attr_ilimit_min.attr, | ||
465 | &tune_attr_demote_secs.attr, | 458 | &tune_attr_demote_secs.attr, |
466 | &tune_attr_incore_log_blocks.attr, | 459 | &tune_attr_incore_log_blocks.attr, |
467 | &tune_attr_log_flush_secs.attr, | 460 | &tune_attr_log_flush_secs.attr, |
@@ -478,7 +471,6 @@ static struct attribute *tune_attrs[] = { | |||
478 | &tune_attr_quota_cache_secs.attr, | 471 | &tune_attr_quota_cache_secs.attr, |
479 | &tune_attr_max_atomic_write.attr, | 472 | &tune_attr_max_atomic_write.attr, |
480 | &tune_attr_stall_secs.attr, | 473 | &tune_attr_stall_secs.attr, |
481 | &tune_attr_entries_per_readdir.attr, | ||
482 | &tune_attr_greedy_default.attr, | 474 | &tune_attr_greedy_default.attr, |
483 | &tune_attr_greedy_quantum.attr, | 475 | &tune_attr_greedy_quantum.attr, |
484 | &tune_attr_greedy_max.attr, | 476 | &tune_attr_greedy_max.attr, |
diff --git a/fs/gfs2/util.h b/fs/gfs2/util.h index 7984dcf89ad0..28938a46cf47 100644 --- a/fs/gfs2/util.h +++ b/fs/gfs2/util.h | |||
@@ -83,8 +83,7 @@ static inline int gfs2_meta_check_i(struct gfs2_sbd *sdp, | |||
83 | char *file, unsigned int line) | 83 | char *file, unsigned int line) |
84 | { | 84 | { |
85 | struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; | 85 | struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; |
86 | u32 magic = mh->mh_magic; | 86 | u32 magic = be32_to_cpu(mh->mh_magic); |
87 | magic = be32_to_cpu(magic); | ||
88 | if (unlikely(magic != GFS2_MAGIC)) | 87 | if (unlikely(magic != GFS2_MAGIC)) |
89 | return gfs2_meta_check_ii(sdp, bh, "magic number", function, | 88 | return gfs2_meta_check_ii(sdp, bh, "magic number", function, |
90 | file, line); | 89 | file, line); |
@@ -107,9 +106,8 @@ static inline int gfs2_metatype_check_i(struct gfs2_sbd *sdp, | |||
107 | char *file, unsigned int line) | 106 | char *file, unsigned int line) |
108 | { | 107 | { |
109 | struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; | 108 | struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; |
110 | u32 magic = mh->mh_magic; | 109 | u32 magic = be32_to_cpu(mh->mh_magic); |
111 | u16 t = be32_to_cpu(mh->mh_type); | 110 | u16 t = be32_to_cpu(mh->mh_type); |
112 | magic = be32_to_cpu(magic); | ||
113 | if (unlikely(magic != GFS2_MAGIC)) | 111 | if (unlikely(magic != GFS2_MAGIC)) |
114 | return gfs2_meta_check_ii(sdp, bh, "magic number", function, | 112 | return gfs2_meta_check_ii(sdp, bh, "magic number", function, |
115 | file, line); | 113 | file, line); |