aboutsummaryrefslogtreecommitdiffstats
path: root/fs/autofs4/waitq.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/autofs4/waitq.c')
-rw-r--r--fs/autofs4/waitq.c86
1 files changed, 45 insertions, 41 deletions
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index 75e5955c3f6d..5208cfb1df4e 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -36,8 +36,10 @@ void autofs4_catatonic_mode(struct autofs_sb_info *sbi)
36 while (wq) { 36 while (wq) {
37 nwq = wq->next; 37 nwq = wq->next;
38 wq->status = -ENOENT; /* Magic is gone - report failure */ 38 wq->status = -ENOENT; /* Magic is gone - report failure */
39 kfree(wq->name); 39 if (wq->name.name) {
40 wq->name = NULL; 40 kfree(wq->name.name);
41 wq->name.name = NULL;
42 }
41 wake_up_interruptible(&wq->queue); 43 wake_up_interruptible(&wq->queue);
42 wq = nwq; 44 wq = nwq;
43 } 45 }
@@ -92,7 +94,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
92 size_t pktsz; 94 size_t pktsz;
93 95
94 DPRINTK("wait id = 0x%08lx, name = %.*s, type=%d", 96 DPRINTK("wait id = 0x%08lx, name = %.*s, type=%d",
95 wq->wait_queue_token, wq->len, wq->name, type); 97 wq->wait_queue_token, wq->name.len, wq->name.name, type);
96 98
97 memset(&pkt,0,sizeof pkt); /* For security reasons */ 99 memset(&pkt,0,sizeof pkt); /* For security reasons */
98 100
@@ -107,9 +109,9 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
107 pktsz = sizeof(*mp); 109 pktsz = sizeof(*mp);
108 110
109 mp->wait_queue_token = wq->wait_queue_token; 111 mp->wait_queue_token = wq->wait_queue_token;
110 mp->len = wq->len; 112 mp->len = wq->name.len;
111 memcpy(mp->name, wq->name, wq->len); 113 memcpy(mp->name, wq->name.name, wq->name.len);
112 mp->name[wq->len] = '\0'; 114 mp->name[wq->name.len] = '\0';
113 break; 115 break;
114 } 116 }
115 case autofs_ptype_expire_multi: 117 case autofs_ptype_expire_multi:
@@ -119,9 +121,9 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
119 pktsz = sizeof(*ep); 121 pktsz = sizeof(*ep);
120 122
121 ep->wait_queue_token = wq->wait_queue_token; 123 ep->wait_queue_token = wq->wait_queue_token;
122 ep->len = wq->len; 124 ep->len = wq->name.len;
123 memcpy(ep->name, wq->name, wq->len); 125 memcpy(ep->name, wq->name.name, wq->name.len);
124 ep->name[wq->len] = '\0'; 126 ep->name[wq->name.len] = '\0';
125 break; 127 break;
126 } 128 }
127 /* 129 /*
@@ -138,9 +140,9 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
138 pktsz = sizeof(*packet); 140 pktsz = sizeof(*packet);
139 141
140 packet->wait_queue_token = wq->wait_queue_token; 142 packet->wait_queue_token = wq->wait_queue_token;
141 packet->len = wq->len; 143 packet->len = wq->name.len;
142 memcpy(packet->name, wq->name, wq->len); 144 memcpy(packet->name, wq->name.name, wq->name.len);
143 packet->name[wq->len] = '\0'; 145 packet->name[wq->name.len] = '\0';
144 packet->dev = wq->dev; 146 packet->dev = wq->dev;
145 packet->ino = wq->ino; 147 packet->ino = wq->ino;
146 packet->uid = wq->uid; 148 packet->uid = wq->uid;
@@ -191,15 +193,15 @@ static int autofs4_getpath(struct autofs_sb_info *sbi,
191} 193}
192 194
193static struct autofs_wait_queue * 195static struct autofs_wait_queue *
194autofs4_find_wait(struct autofs_sb_info *sbi, 196autofs4_find_wait(struct autofs_sb_info *sbi, struct qstr *qstr)
195 char *name, unsigned int hash, unsigned int len)
196{ 197{
197 struct autofs_wait_queue *wq; 198 struct autofs_wait_queue *wq;
198 199
199 for (wq = sbi->queues; wq; wq = wq->next) { 200 for (wq = sbi->queues; wq; wq = wq->next) {
200 if (wq->hash == hash && 201 if (wq->name.hash == qstr->hash &&
201 wq->len == len && 202 wq->name.len == qstr->len &&
202 wq->name && !memcmp(wq->name, name, len)) 203 wq->name.name &&
204 !memcmp(wq->name.name, qstr->name, qstr->len))
203 break; 205 break;
204 } 206 }
205 return wq; 207 return wq;
@@ -210,9 +212,8 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
210{ 212{
211 struct autofs_info *ino; 213 struct autofs_info *ino;
212 struct autofs_wait_queue *wq; 214 struct autofs_wait_queue *wq;
215 struct qstr qstr;
213 char *name; 216 char *name;
214 unsigned int len = 0;
215 unsigned int hash = 0;
216 int status, type; 217 int status, type;
217 218
218 /* In catatonic mode, we don't wait for nobody */ 219 /* In catatonic mode, we don't wait for nobody */
@@ -225,22 +226,23 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
225 226
226 /* If this is a direct mount request create a dummy name */ 227 /* If this is a direct mount request create a dummy name */
227 if (IS_ROOT(dentry) && (sbi->type & AUTOFS_TYPE_DIRECT)) 228 if (IS_ROOT(dentry) && (sbi->type & AUTOFS_TYPE_DIRECT))
228 len = sprintf(name, "%p", dentry); 229 qstr.len = sprintf(name, "%p", dentry);
229 else { 230 else {
230 len = autofs4_getpath(sbi, dentry, &name); 231 qstr.len = autofs4_getpath(sbi, dentry, &name);
231 if (!len) { 232 if (!qstr.len) {
232 kfree(name); 233 kfree(name);
233 return -ENOENT; 234 return -ENOENT;
234 } 235 }
235 } 236 }
236 hash = full_name_hash(name, len); 237 qstr.name = name;
238 qstr.hash = full_name_hash(name, qstr.len);
237 239
238 if (mutex_lock_interruptible(&sbi->wq_mutex)) { 240 if (mutex_lock_interruptible(&sbi->wq_mutex)) {
239 kfree(name); 241 kfree(qstr.name);
240 return -EINTR; 242 return -EINTR;
241 } 243 }
242 244
243 wq = autofs4_find_wait(sbi, name, hash, len); 245 wq = autofs4_find_wait(sbi, &qstr);
244 ino = autofs4_dentry_ino(dentry); 246 ino = autofs4_dentry_ino(dentry);
245 if (!wq && ino && notify == NFY_NONE) { 247 if (!wq && ino && notify == NFY_NONE) {
246 /* 248 /*
@@ -254,10 +256,10 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
254 mutex_unlock(&sbi->wq_mutex); 256 mutex_unlock(&sbi->wq_mutex);
255 schedule_timeout_interruptible(HZ/10); 257 schedule_timeout_interruptible(HZ/10);
256 if (mutex_lock_interruptible(&sbi->wq_mutex)) { 258 if (mutex_lock_interruptible(&sbi->wq_mutex)) {
257 kfree(name); 259 kfree(qstr.name);
258 return -EINTR; 260 return -EINTR;
259 } 261 }
260 wq = autofs4_find_wait(sbi, name, hash, len); 262 wq = autofs4_find_wait(sbi, &qstr);
261 if (wq) 263 if (wq)
262 break; 264 break;
263 } 265 }
@@ -268,7 +270,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
268 * return status of the wait. 270 * return status of the wait.
269 */ 271 */
270 if (!wq) { 272 if (!wq) {
271 kfree(name); 273 kfree(qstr.name);
272 mutex_unlock(&sbi->wq_mutex); 274 mutex_unlock(&sbi->wq_mutex);
273 return 0; 275 return 0;
274 } 276 }
@@ -278,7 +280,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
278 /* Create a new wait queue */ 280 /* Create a new wait queue */
279 wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL); 281 wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL);
280 if (!wq) { 282 if (!wq) {
281 kfree(name); 283 kfree(qstr.name);
282 mutex_unlock(&sbi->wq_mutex); 284 mutex_unlock(&sbi->wq_mutex);
283 return -ENOMEM; 285 return -ENOMEM;
284 } 286 }
@@ -289,9 +291,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
289 wq->next = sbi->queues; 291 wq->next = sbi->queues;
290 sbi->queues = wq; 292 sbi->queues = wq;
291 init_waitqueue_head(&wq->queue); 293 init_waitqueue_head(&wq->queue);
292 wq->hash = hash; 294 memcpy(&wq->name, &qstr, sizeof(struct qstr));
293 wq->name = name;
294 wq->len = len;
295 wq->dev = autofs4_get_dev(sbi); 295 wq->dev = autofs4_get_dev(sbi);
296 wq->ino = autofs4_get_ino(sbi); 296 wq->ino = autofs4_get_ino(sbi);
297 wq->uid = current->uid; 297 wq->uid = current->uid;
@@ -319,16 +319,18 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
319 } 319 }
320 320
321 DPRINTK("new wait id = 0x%08lx, name = %.*s, nfy=%d\n", 321 DPRINTK("new wait id = 0x%08lx, name = %.*s, nfy=%d\n",
322 (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify); 322 (unsigned long) wq->wait_queue_token, wq->name.len,
323 wq->name.name, notify);
323 324
324 /* autofs4_notify_daemon() may block */ 325 /* autofs4_notify_daemon() may block */
325 autofs4_notify_daemon(sbi, wq, type); 326 autofs4_notify_daemon(sbi, wq, type);
326 } else { 327 } else {
327 atomic_inc(&wq->wait_ctr); 328 atomic_inc(&wq->wait_ctr);
328 mutex_unlock(&sbi->wq_mutex); 329 mutex_unlock(&sbi->wq_mutex);
329 kfree(name); 330 kfree(qstr.name);
330 DPRINTK("existing wait id = 0x%08lx, name = %.*s, nfy=%d", 331 DPRINTK("existing wait id = 0x%08lx, name = %.*s, nfy=%d",
331 (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify); 332 (unsigned long) wq->wait_queue_token, wq->name.len,
333 wq->name.name, notify);
332 } 334 }
333 335
334 /* wq->name is NULL if and only if the lock is already released */ 336 /* wq->name is NULL if and only if the lock is already released */
@@ -336,11 +338,13 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
336 if (sbi->catatonic) { 338 if (sbi->catatonic) {
337 /* We might have slept, so check again for catatonic mode */ 339 /* We might have slept, so check again for catatonic mode */
338 wq->status = -ENOENT; 340 wq->status = -ENOENT;
339 kfree(wq->name); 341 if (wq->name.name) {
340 wq->name = NULL; 342 kfree(wq->name.name);
343 wq->name.name = NULL;
344 }
341 } 345 }
342 346
343 if (wq->name) { 347 if (wq->name.name) {
344 /* Block all but "shutdown" signals while waiting */ 348 /* Block all but "shutdown" signals while waiting */
345 sigset_t oldset; 349 sigset_t oldset;
346 unsigned long irqflags; 350 unsigned long irqflags;
@@ -351,7 +355,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
351 recalc_sigpending(); 355 recalc_sigpending();
352 spin_unlock_irqrestore(&current->sighand->siglock, irqflags); 356 spin_unlock_irqrestore(&current->sighand->siglock, irqflags);
353 357
354 wait_event_interruptible(wq->queue, wq->name == NULL); 358 wait_event_interruptible(wq->queue, wq->name.name == NULL);
355 359
356 spin_lock_irqsave(&current->sighand->siglock, irqflags); 360 spin_lock_irqsave(&current->sighand->siglock, irqflags);
357 current->blocked = oldset; 361 current->blocked = oldset;
@@ -388,8 +392,8 @@ int autofs4_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_tok
388 392
389 *wql = wq->next; /* Unlink from chain */ 393 *wql = wq->next; /* Unlink from chain */
390 mutex_unlock(&sbi->wq_mutex); 394 mutex_unlock(&sbi->wq_mutex);
391 kfree(wq->name); 395 kfree(wq->name.name);
392 wq->name = NULL; /* Do not wait on this queue */ 396 wq->name.name = NULL; /* Do not wait on this queue */
393 397
394 wq->status = status; 398 wq->status = status;
395 399