1 /* -*- linux-c -*- --------------------------------------------------------- * 2 * 3 * linux/fs/autofs/waitq.c 4 * 5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved 6 * 7 * This file is part of the Linux kernel and is made available under 8 * the terms of the GNU General Public License, version 2, or at your 9 * option, any later version, incorporated herein by reference. 10 * 11 * ------------------------------------------------------------------------- */ 12 13 #include <linux/slab.h> 14 #include <linux/time.h> 15 #include <linux/signal.h> 16 #include <linux/file.h> 17 #include "autofs_i.h" 18 19 /* We make this a static variable rather than a part of the superblock; it 20 is better if we don't reassign numbers easily even across filesystems */ 21 static autofs_wqt_t autofs_next_wait_queue = 1; 22 23 /* These are the signals we allow interrupting a pending mount */ 24 #define SHUTDOWN_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGQUIT)) 25 26 void autofs_catatonic_mode(struct autofs_sb_info *sbi) 27 { 28 struct autofs_wait_queue *wq, *nwq; 29 30 DPRINTK(("autofs: entering catatonic mode\n")); 31 32 sbi->catatonic = 1; 33 wq = sbi->queues; 34 sbi->queues = NULL; /* Erase all wait queues */ 35 while ( wq ) { 36 nwq = wq->next; 37 wq->status = -ENOENT; /* Magic is gone - report failure */ 38 kfree(wq->name); 39 wq->name = NULL; 40 wake_up(&wq->queue); 41 wq = nwq; 42 } 43 fput(sbi->pipe); /* Close the pipe */ 44 autofs_hash_dputall(&sbi->dirhash); /* Remove all dentry pointers */ 45 } 46 47 static int autofs_write(struct file *file, const void *addr, int bytes) 48 { 49 unsigned long sigpipe, flags; 50 mm_segment_t fs; 51 const char *data = (const char *)addr; 52 ssize_t wr = 0; 53 54 /** WARNING: this is not safe for writing more than PIPE_BUF bytes! **/ 55 56 sigpipe = sigismember(¤t->pending.signal, SIGPIPE); 57 58 /* Save pointer to user space and point back to kernel space */ 59 fs = get_fs(); 60 set_fs(KERNEL_DS); 61 62 while (bytes && 63 (wr = file->f_op->write(file,data,bytes,&file->f_pos)) > 0) { 64 data += wr; 65 bytes -= wr; 66 } 67 68 set_fs(fs); 69 70 /* Keep the currently executing process from receiving a 71 SIGPIPE unless it was already supposed to get one */ 72 if (wr == -EPIPE && !sigpipe) { 73 spin_lock_irqsave(¤t->sighand->siglock, flags); 74 sigdelset(¤t->pending.signal, SIGPIPE); 75 recalc_sigpending(); 76 spin_unlock_irqrestore(¤t->sighand->siglock, flags); 77 } 78 79 return (bytes > 0); 80 } 81 82 static void autofs_notify_daemon(struct autofs_sb_info *sbi, struct autofs_wait_queue *wq) 83 { 84 struct autofs_packet_missing pkt; 85 86 DPRINTK(("autofs_wait: wait id = 0x%08lx, name = ", wq->wait_queue_token)); 87 autofs_say(wq->name,wq->len); 88 89 memset(&pkt,0,sizeof pkt); /* For security reasons */ 90 91 pkt.hdr.proto_version = AUTOFS_PROTO_VERSION; 92 pkt.hdr.type = autofs_ptype_missing; 93 pkt.wait_queue_token = wq->wait_queue_token; 94 pkt.len = wq->len; 95 memcpy(pkt.name, wq->name, pkt.len); 96 pkt.name[pkt.len] = '\0'; 97 98 if ( autofs_write(sbi->pipe,&pkt,sizeof(struct autofs_packet_missing)) ) 99 autofs_catatonic_mode(sbi); 100 } 101 102 int autofs_wait(struct autofs_sb_info *sbi, struct qstr *name) 103 { 104 struct autofs_wait_queue *wq; 105 int status; 106 107 /* In catatonic mode, we don't wait for nobody */ 108 if ( sbi->catatonic ) 109 return -ENOENT; 110 111 /* We shouldn't be able to get here, but just in case */ 112 if ( name->len > NAME_MAX ) 113 return -ENOENT; 114 115 for ( wq = sbi->queues ; wq ; wq = wq->next ) { 116 if ( wq->hash == name->hash && 117 wq->len == name->len && 118 wq->name && !memcmp(wq->name,name->name,name->len) ) 119 break; 120 } 121 122 if ( !wq ) { 123 /* Create a new wait queue */ 124 wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL); 125 if ( !wq ) 126 return -ENOMEM; 127 128 wq->name = kmalloc(name->len,GFP_KERNEL); 129 if ( !wq->name ) { 130 kfree(wq); 131 return -ENOMEM; 132 } 133 wq->wait_queue_token = autofs_next_wait_queue++; 134 init_waitqueue_head(&wq->queue); 135 wq->hash = name->hash; 136 wq->len = name->len; 137 wq->status = -EINTR; /* Status return if interrupted */ 138 memcpy(wq->name, name->name, name->len); 139 wq->next = sbi->queues; 140 sbi->queues = wq; 141 142 /* autofs_notify_daemon() may block */ 143 wq->wait_ctr = 2; 144 autofs_notify_daemon(sbi,wq); 145 } else 146 wq->wait_ctr++; 147 148 /* wq->name is NULL if and only if the lock is already released */ 149 150 if ( sbi->catatonic ) { 151 /* We might have slept, so check again for catatonic mode */ 152 wq->status = -ENOENT; 153 if ( wq->name ) { 154 kfree(wq->name); 155 wq->name = NULL; 156 } 157 } 158 159 if ( wq->name ) { 160 /* Block all but "shutdown" signals while waiting */ 161 sigset_t sigmask; 162 163 siginitsetinv(&sigmask, SHUTDOWN_SIGS); 164 sigprocmask(SIG_BLOCK, &sigmask, &sigmask); 165 166 interruptible_sleep_on(&wq->queue); 167 168 sigprocmask(SIG_SETMASK, &sigmask, NULL); 169 } else { 170 DPRINTK(("autofs_wait: skipped sleeping\n")); 171 } 172 173 status = wq->status; 174 175 if ( ! --wq->wait_ctr ) /* Are we the last process to need status? */ 176 kfree(wq); 177 178 return status; 179 } 180 181 182 int autofs_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_token, int status) 183 { 184 struct autofs_wait_queue *wq, **wql; 185 186 for ( wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next ) { 187 if ( wq->wait_queue_token == wait_queue_token ) 188 break; 189 } 190 if ( !wq ) 191 return -EINVAL; 192 193 *wql = wq->next; /* Unlink from chain */ 194 kfree(wq->name); 195 wq->name = NULL; /* Do not wait on this queue */ 196 197 wq->status = status; 198 199 if ( ! --wq->wait_ctr ) /* Is anyone still waiting for this guy? */ 200 kfree(wq); 201 else 202 wake_up(&wq->queue); 203 204 return 0; 205 } 206 207