LCOV - code coverage report
Current view: top level - lkbce/fs/autofs4 - waitq.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 300 300 100.0 %
Date: 2017-01-25 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /* -*- c -*- --------------------------------------------------------------- *
       2             :  *
       3             :  * linux/fs/autofs/waitq.c
       4             :  *
       5             :  *  Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
       6             :  *  Copyright 2001-2006 Ian Kent <raven@themaw.net>
       7             :  *
       8             :  * This file is part of the Linux kernel and is made available under
       9             :  * the terms of the GNU General Public License, version 2, or at your
      10             :  * option, any later version, incorporated herein by reference.
      11             :  *
      12             :  * ------------------------------------------------------------------------- */
      13             : 
      14             : #include <linux/slab.h>
      15             : #include <linux/time.h>
      16             : #include <linux/signal.h>
      17             : #include <linux/file.h>
      18             : #include "autofs_i.h"
      19             : 
      20             : /* We make this a static variable rather than a part of the superblock; it
      21             :    is better if we don't reassign numbers easily even across filesystems */
      22           1 : static autofs_wqt_t autofs4_next_wait_queue = 1;
      23             : 
      24             : /* These are the signals we allow interrupting a pending mount */
      25             : #define SHUTDOWN_SIGS   (sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGQUIT))
      26             : 
      27             : void autofs4_catatonic_mode(struct autofs_sb_info *sbi)
      28             : {
      29          28 :         struct autofs_wait_queue *wq, *nwq;
      30          28 : 
      31          28 :         mutex_lock(&sbi->wq_mutex);
      32          56 :         if (sbi->catatonic) {
      33          28 :                 mutex_unlock(&sbi->wq_mutex);
      34          28 :                 return;
      35             :         }
      36             : 
      37             :         DPRINTK("entering catatonic mode");
      38             : 
      39          28 :         sbi->catatonic = 1;
      40          28 :         wq = sbi->queues;
      41          28 :         sbi->queues = NULL;  /* Erase all wait queues */
      42          84 :         while (wq) {
      43          56 :                 nwq = wq->next;
      44          56 :                 wq->status = -ENOENT; /* Magic is gone - report failure */
      45          56 :                 if (wq->name.name) {
      46          28 :                         kfree(wq->name.name);
      47          28 :                         wq->name.name = NULL;
      48             :                 }
      49          28 :                 wq->wait_ctr--;
      50          28 :                 wake_up_interruptible(&wq->queue);
      51          28 :                 wq = nwq;
      52             :         }
      53          56 :         fput(sbi->pipe);     /* Close the pipe */
      54          28 :         sbi->pipe = NULL;
      55          28 :         sbi->pipefd = -1;
      56          28 :         mutex_unlock(&sbi->wq_mutex);
      57          28 : }
      58             : 
      59             : static int autofs4_write(struct file *file, const void *addr, int bytes)
      60             : {
      61          48 :         unsigned long sigpipe, flags;
      62          48 :         mm_segment_t fs;
      63          96 :         const char *data = (const char *)addr;
      64          96 :         ssize_t wr = 0;
      65          48 : 
      66          48 :         /** WARNING: this is not safe for writing more than PIPE_BUF bytes! **/
      67          48 : 
      68         288 :         sigpipe = sigismember(&current->pending.signal, SIGPIPE);
      69          48 : 
      70          48 :         /* Save pointer to user space and point back to kernel space */
      71         192 :         fs = get_fs();
      72         240 :         set_fs(KERNEL_DS);
      73          48 : 
      74         336 :         while (bytes &&
      75          96 :                (wr = file->f_op->write(file,data,bytes,&file->f_pos)) > 0) {
      76          48 :                 data += wr;
      77          96 :                 bytes -= wr;
      78          48 :         }
      79             : 
      80         192 :         set_fs(fs);
      81             : 
      82             :         /* Keep the currently executing process from receiving a
      83             :            SIGPIPE unless it was already supposed to get one */
      84         192 :         if (wr == -EPIPE && !sigpipe) {
      85         288 :                 spin_lock_irqsave(&current->sighand->siglock, flags);
      86         192 :                 sigdelset(&current->pending.signal, SIGPIPE);
      87          48 :                 recalc_sigpending();
      88         192 :                 spin_unlock_irqrestore(&current->sighand->siglock, flags);
      89             :         }
      90             : 
      91          96 :         return (bytes > 0);
      92             : }
      93             :         
      94             : static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
      95             :                                  struct autofs_wait_queue *wq,
      96             :                                  int type)
      97          24 : {
      98          24 :         union {
      99          24 :                 struct autofs_packet_hdr hdr;
     100          24 :                 union autofs_packet_union v4_pkt;
     101          24 :                 union autofs_v5_packet_union v5_pkt;
     102          25 :         } pkt;
     103          48 :         struct file *pipe = NULL;
     104             :         size_t pktsz;
     105             : 
     106             :         DPRINTK("wait id = 0x%08lx, name = %.*s, type=%d",
     107             :                 wq->wait_queue_token, wq->name.len, wq->name.name, type);
     108             : 
     109          24 :         memset(&pkt,0,sizeof pkt); /* For security reasons */
     110             : 
     111          24 :         pkt.hdr.proto_version = sbi->version;
     112          24 :         pkt.hdr.type = type;
     113             :         switch (type) {
     114             :         /* Kernel protocol v4 missing and expire packets */
     115          72 :         case autofs_ptype_missing:
     116             :         {
     117          24 :                 struct autofs_packet_missing *mp = &pkt.v4_pkt.missing;
     118             : 
     119          24 :                 pktsz = sizeof(*mp);
     120             : 
     121          24 :                 mp->wait_queue_token = wq->wait_queue_token;
     122          24 :                 mp->len = wq->name.len;
     123          24 :                 memcpy(mp->name, wq->name.name, wq->name.len);
     124          24 :                 mp->name[wq->name.len] = '\0';
     125          24 :                 break;
     126          24 :         }
     127          72 :         case autofs_ptype_expire_multi:
     128             :         {
     129          24 :                 struct autofs_packet_expire_multi *ep = &pkt.v4_pkt.expire_multi;
     130             : 
     131          24 :                 pktsz = sizeof(*ep);
     132             : 
     133          24 :                 ep->wait_queue_token = wq->wait_queue_token;
     134          24 :                 ep->len = wq->name.len;
     135          24 :                 memcpy(ep->name, wq->name.name, wq->name.len);
     136          24 :                 ep->name[wq->name.len] = '\0';
     137          24 :                 break;
     138          24 :         }
     139          24 :         /*
     140          24 :          * Kernel protocol v5 packet for handling indirect and direct
     141          24 :          * mount missing and expire requests
     142             :          */
     143          72 :         case autofs_ptype_missing_indirect:
     144          72 :         case autofs_ptype_expire_indirect:
     145          72 :         case autofs_ptype_missing_direct:
     146          72 :         case autofs_ptype_expire_direct:
     147             :         {
     148          24 :                 struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet;
     149             : 
     150          24 :                 pktsz = sizeof(*packet);
     151             : 
     152          24 :                 packet->wait_queue_token = wq->wait_queue_token;
     153          24 :                 packet->len = wq->name.len;
     154          24 :                 memcpy(packet->name, wq->name.name, wq->name.len);
     155          24 :                 packet->name[wq->name.len] = '\0';
     156          24 :                 packet->dev = wq->dev;
     157          24 :                 packet->ino = wq->ino;
     158          24 :                 packet->uid = wq->uid;
     159          24 :                 packet->gid = wq->gid;
     160          48 :                 packet->pid = wq->pid;
     161          48 :                 packet->tgid = wq->tgid;
     162          24 :                 break;
     163          24 :         }
     164          24 :         default:
     165          48 :                 printk("autofs4_notify_daemon: bad type %d!\n", type);
     166          24 :                 return;
     167             :         }
     168             : 
     169             :         /* Check if we have become catatonic */
     170          24 :         mutex_lock(&sbi->wq_mutex);
     171          48 :         if (!sbi->catatonic) {
     172          24 :                 pipe = sbi->pipe;
     173          48 :                 get_file(pipe);
     174             :         }
     175          48 :         mutex_unlock(&sbi->wq_mutex);
     176             : 
     177          96 :         if (pipe) {
     178         192 :                 if (autofs4_write(pipe, &pkt, pktsz))
     179          72 :                         autofs4_catatonic_mode(sbi);
     180          48 :                 fput(pipe);
     181             :         }
     182          96 : }
     183             : 
     184             : static int autofs4_getpath(struct autofs_sb_info *sbi,
     185             :                            struct dentry *dentry, char **name)
     186          16 : {
     187          32 :         struct dentry *root = sbi->sb->s_root;
     188          16 :         struct dentry *tmp;
     189          32 :         char *buf = *name;
     190          16 :         char *p;
     191          16 :         int len = 0;
     192             : 
     193          32 :         spin_lock(&dcache_lock);
     194          80 :         for (tmp = dentry ; tmp != root ; tmp = tmp->d_parent)
     195          48 :                 len += tmp->d_name.len + 1;
     196          16 : 
     197          80 :         if (!len || --len > NAME_MAX) {
     198          64 :                 spin_unlock(&dcache_lock);
     199          32 :                 return 0;
     200             :         }
     201             : 
     202          16 :         *(buf + len) = '\0';
     203          16 :         p = buf + len - dentry->d_name.len;
     204          16 :         strncpy(p, dentry->d_name.name, dentry->d_name.len);
     205             : 
     206          80 :         for (tmp = dentry->d_parent; tmp != root ; tmp = tmp->d_parent) {
     207          48 :                 *(--p) = '/';
     208          48 :                 p -= tmp->d_name.len;
     209          16 :                 strncpy(p, tmp->d_name.name, tmp->d_name.len);
     210             :         }
     211          32 :         spin_unlock(&dcache_lock);
     212             : 
     213          16 :         return len;
     214             : }
     215             : 
     216             : static struct autofs_wait_queue *
     217             : autofs4_find_wait(struct autofs_sb_info *sbi, struct qstr *qstr)
     218             : {
     219          16 :         struct autofs_wait_queue *wq;
     220          16 : 
     221          80 :         for (wq = sbi->queues; wq; wq = wq->next) {
     222         176 :                 if (wq->name.hash == qstr->hash &&
     223          16 :                     wq->name.len == qstr->len &&
     224             :                     wq->name.name &&
     225             :                          !memcmp(wq->name.name, qstr->name, qstr->len))
     226          16 :                         break;
     227          16 :         }
     228          16 :         return wq;
     229             : }
     230             : 
     231             : /*
     232             :  * Check if we have a valid request.
     233             :  * Returns
     234             :  * 1 if the request should continue.
     235             :  *   In this case we can return an autofs_wait_queue entry if one is
     236             :  *   found or NULL to idicate a new wait needs to be created.
     237             :  * 0 or a negative errno if the request shouldn't continue.
     238             :  */
     239             : static int validate_request(struct autofs_wait_queue **wait,
     240             :                             struct autofs_sb_info *sbi,
     241             :                             struct qstr *qstr,
     242           8 :                             struct dentry*dentry, enum autofs_notify notify)
     243           8 : {
     244           8 :         struct autofs_wait_queue *wq;
     245           8 :         struct autofs_info *ino;
     246             : 
     247             :         /* Wait in progress, continue; */
     248          16 :         wq = autofs4_find_wait(sbi, qstr);
     249          16 :         if (wq) {
     250           8 :                 *wait = wq;
     251           8 :                 return 1;
     252             :         }
     253             : 
     254           8 :         *wait = NULL;
     255             : 
     256             :         /* If we don't yet have any info this is a new request */
     257          16 :         ino = autofs4_dentry_ino(dentry);
     258          16 :         if (!ino)
     259           8 :                 return 1;
     260             : 
     261             :         /*
     262             :          * If we've been asked to wait on an existing expire (NFY_NONE)
     263             :          * but there is no wait in the queue ...
     264             :          */
     265          16 :         if (notify == NFY_NONE) {
     266             :                 /*
     267             :                  * Either we've betean the pending expire to post it's
     268             :                  * wait or it finished while we waited on the mutex.
     269             :                  * So we need to wait till either, the wait appears
     270             :                  * or the expire finishes.
     271             :                  */
     272             : 
     273          24 :                 while (ino->flags & AUTOFS_INF_EXPIRING) {
     274          16 :                         mutex_unlock(&sbi->wq_mutex);
     275          16 :                         schedule_timeout_interruptible(HZ/10);
     276          24 :                         if (mutex_lock_interruptible(&sbi->wq_mutex))
     277           8 :                                 return -EINTR;
     278             : 
     279          16 :                         wq = autofs4_find_wait(sbi, qstr);
     280          16 :                         if (wq) {
     281           8 :                                 *wait = wq;
     282           8 :                                 return 1;
     283             :                         }
     284             :                 }
     285             : 
     286           8 :                 /*
     287             :                  * Not ideal but the status has already gone. Of the two
     288             :                  * cases where we wait on NFY_NONE neither depend on the
     289             :                  * return status of the wait.
     290             :                  */
     291           8 :                 return 0;
     292             :         }
     293             : 
     294             :         /*
     295             :          * If we've been asked to trigger a mount and the request
     296             :          * completed while we waited on the mutex ...
     297             :          */
     298          16 :         if (notify == NFY_MOUNT) {
     299             :                 /*
     300             :                  * If the dentry was successfully mounted while we slept
     301             :                  * on the wait queue mutex we can return success. If it
     302             :                  * isn't mounted (doesn't have submounts for the case of
     303             :                  * a multi-mount with no mount at it's base) we can
     304             :                  * continue on and create a new request.
     305             :                  */
     306          24 :                 if (have_submounts(dentry))
     307           8 :                         return 0;
     308             :         }
     309             : 
     310           8 :         return 1;
     311             : }
     312             : 
     313             : int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
     314             :                 enum autofs_notify notify)
     315           8 : {
     316           8 :         struct autofs_wait_queue *wq;
     317           8 :         struct qstr qstr;
     318           8 :         char *name;
     319           8 :         int status, ret, type;
     320           8 : 
     321           8 :         /* In catatonic mode, we don't wait for nobody */
     322          24 :         if (sbi->catatonic)
     323          16 :                 return -ENOENT;
     324           8 : 
     325          32 :         if (!dentry->d_inode) {
     326           8 :                 /*
     327           8 :                  * A wait for a negative dentry is invalid for certain
     328           8 :                  * cases. A direct or offset mount "always" has its mount
     329           8 :                  * point directory created and so the request dentry must
     330           8 :                  * be positive or the map key doesn't exist. The situation
     331           8 :                  * is very similar for indirect mounts except only dentrys
     332           8 :                  * in the root of the autofs file system may be negative.
     333           8 :                  */
     334          40 :                 if (autofs_type_trigger(sbi->type))
     335          16 :                         return -ENOENT;
     336          40 :                 else if (!IS_ROOT(dentry->d_parent))
     337          16 :                         return -ENOENT;
     338           8 :         }
     339           8 : 
     340          48 :         name = kmalloc(NAME_MAX + 1, GFP_KERNEL);
     341          24 :         if (!name)
     342          16 :                 return -ENOMEM;
     343           8 : 
     344           8 :         /* If this is a direct mount request create a dummy name */
     345          72 :         if (IS_ROOT(dentry) && autofs_type_trigger(sbi->type))
     346          24 :                 qstr.len = sprintf(name, "%p", dentry);
     347           8 :         else {
     348          88 :                 qstr.len = autofs4_getpath(sbi, dentry, &name);
     349          24 :                 if (!qstr.len) {
     350          16 :                         kfree(name);
     351          16 :                         return -ENOENT;
     352           8 :                 }
     353             :         }
     354          16 :         qstr.name = name;
     355          32 :         qstr.hash = full_name_hash(name, qstr.len);
     356             : 
     357          24 :         if (mutex_lock_interruptible(&sbi->wq_mutex)) {
     358           8 :                 kfree(qstr.name);
     359           8 :                 return -EINTR;
     360             :         }
     361             : 
     362          40 :         ret = validate_request(&wq, sbi, &qstr, dentry, notify);
     363          16 :         if (ret <= 0) {
     364          16 :                 if (ret == 0)
     365           8 :                         mutex_unlock(&sbi->wq_mutex);
     366           8 :                 kfree(qstr.name);
     367           8 :                 return ret;
     368             :         }
     369             : 
     370          16 :         if (!wq) {
     371             :                 /* Create a new wait queue */
     372          24 :                 wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL);
     373          16 :                 if (!wq) {
     374           8 :                         kfree(qstr.name);
     375           8 :                         mutex_unlock(&sbi->wq_mutex);
     376           8 :                         return -ENOMEM;
     377             :                 }
     378             : 
     379           8 :                 wq->wait_queue_token = autofs4_next_wait_queue;
     380          24 :                 if (++autofs4_next_wait_queue == 0)
     381           8 :                         autofs4_next_wait_queue = 1;
     382           8 :                 wq->next = sbi->queues;
     383           8 :                 sbi->queues = wq;
     384           8 :                 init_waitqueue_head(&wq->queue);
     385           8 :                 memcpy(&wq->name, &qstr, sizeof(struct qstr));
     386          16 :                 wq->dev = autofs4_get_dev(sbi);
     387          16 :                 wq->ino = autofs4_get_ino(sbi);
     388          24 :                 wq->uid = current_uid();
     389          24 :                 wq->gid = current_gid();
     390          24 :                 wq->pid = current->pid;
     391          24 :                 wq->tgid = current->tgid;
     392           8 :                 wq->status = -EINTR; /* Status return if interrupted */
     393           8 :                 wq->wait_ctr = 2;
     394           8 :                 mutex_unlock(&sbi->wq_mutex);
     395             : 
     396          16 :                 if (sbi->version < 5) {
     397          16 :                         if (notify == NFY_MOUNT)
     398           8 :                                 type = autofs_ptype_missing;
     399             :                         else
     400           8 :                                 type = autofs_ptype_expire_multi;
     401             :                 } else {
     402          16 :                         if (notify == NFY_MOUNT)
     403          64 :                                 type = autofs_type_trigger(sbi->type) ?
     404             :                                         autofs_ptype_missing_direct :
     405             :                                          autofs_ptype_missing_indirect;
     406             :                         else
     407          64 :                                 type = autofs_type_trigger(sbi->type) ?
     408             :                                         autofs_ptype_expire_direct :
     409             :                                         autofs_ptype_expire_indirect;
     410             :                 }
     411             : 
     412             :                 DPRINTK("new wait id = 0x%08lx, name = %.*s, nfy=%d\n",
     413             :                         (unsigned long) wq->wait_queue_token, wq->name.len,
     414             :                         wq->name.name, notify);
     415             : 
     416             :                 /* autofs4_notify_daemon() may block */
     417         120 :                 autofs4_notify_daemon(sbi, wq, type);
     418             :         } else {
     419           8 :                 wq->wait_ctr++;
     420           8 :                 mutex_unlock(&sbi->wq_mutex);
     421           8 :                 kfree(qstr.name);
     422             :                 DPRINTK("existing wait id = 0x%08lx, name = %.*s, nfy=%d",
     423             :                         (unsigned long) wq->wait_queue_token, wq->name.len,
     424             :                         wq->name.name, notify);
     425             :         }
     426             : 
     427             :         /*
     428             :          * wq->name.name is NULL iff the lock is already released
     429             :          * or the mount has been made catatonic.
     430             :          */
     431          32 :         if (wq->name.name) {
     432             :                 /* Block all but "shutdown" signals while waiting */
     433             :                 sigset_t oldset;
     434             :                 unsigned long irqflags;
     435             : 
     436          56 :                 spin_lock_irqsave(&current->sighand->siglock, irqflags);
     437          24 :                 oldset = current->blocked;
     438          32 :                 siginitsetinv(&current->blocked, SHUTDOWN_SIGS & ~oldset.sig[0]);
     439           8 :                 recalc_sigpending();
     440          32 :                 spin_unlock_irqrestore(&current->sighand->siglock, irqflags);
     441             : 
     442         216 :                 wait_event_interruptible(wq->queue, wq->name.name == NULL);
     443          24 : 
     444          80 :                 spin_lock_irqsave(&current->sighand->siglock, irqflags);
     445          24 :                 current->blocked = oldset;
     446           8 :                 recalc_sigpending();
     447          32 :                 spin_unlock_irqrestore(&current->sighand->siglock, irqflags);
     448             :         } else {
     449             :                 DPRINTK("skipped sleeping");
     450             :         }
     451             : 
     452          24 :         status = wq->status;
     453             : 
     454             :         /*
     455             :          * For direct and offset mounts we need to track the requester's
     456             :          * uid and gid in the dentry info struct. This is so it can be
     457             :          * supplied, on request, by the misc device ioctl interface.
     458             :          * This is needed during daemon resatart when reconnecting
     459             :          * to existing, active, autofs mounts. The uid and gid (and
     460             :          * related string values) may be used for macro substitution
     461             :          * in autofs mount maps.
     462             :          */
     463          48 :         if (!status) {
     464             :                 struct autofs_info *ino;
     465          24 :                 struct dentry *de = NULL;
     466             : 
     467             :                 /* direct mount or browsable map */
     468          48 :                 ino = autofs4_dentry_ino(dentry);
     469          16 :                 if (!ino) {
     470             :                         /* If not lookup actual dentry used */
     471           8 :                         de = d_lookup(dentry->d_parent, &dentry->d_name);
     472          16 :                         if (de)
     473          16 :                                 ino = autofs4_dentry_ino(de);
     474             :                 }
     475             : 
     476             :                 /* Set mount requester */
     477          32 :                 if (ino) {
     478          32 :                         spin_lock(&sbi->fs_lock);
     479           8 :                         ino->uid = wq->uid;
     480           8 :                         ino->gid = wq->gid;
     481          16 :                         spin_unlock(&sbi->fs_lock);
     482             :                 }
     483             : 
     484          48 :                 if (de)
     485          24 :                         dput(de);
     486             :         }
     487             : 
     488             :         /* Are we the last process to need status? */
     489          48 :         mutex_lock(&sbi->wq_mutex);
     490         144 :         if (!--wq->wait_ctr)
     491          48 :                 kfree(wq);
     492          48 :         mutex_unlock(&sbi->wq_mutex);
     493             : 
     494          48 :         return status;
     495             : }
     496             : 
     497             : 
     498             : int autofs4_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_token, int status)
     499             : {
     500             :         struct autofs_wait_queue *wq, **wql;
     501           2 : 
     502           4 :         mutex_lock(&sbi->wq_mutex);
     503          12 :         for (wql = &sbi->queues; (wq = *wql) != NULL; wql = &wq->next) {
     504           8 :                 if (wq->wait_queue_token == wait_queue_token)
     505           4 :                         break;
     506             :         }
     507             : 
     508           4 :         if (!wq) {
     509           4 :                 mutex_unlock(&sbi->wq_mutex);
     510           2 :                 return -EINVAL;
     511             :         }
     512             : 
     513           2 :         *wql = wq->next;     /* Unlink from chain */
     514           2 :         kfree(wq->name.name);
     515           2 :         wq->name.name = NULL;        /* Do not wait on this queue */
     516           2 :         wq->status = status;
     517           2 :         wake_up_interruptible(&wq->queue);
     518           6 :         if (!--wq->wait_ctr)
     519           2 :                 kfree(wq);
     520           2 :         mutex_unlock(&sbi->wq_mutex);
     521             : 
     522           2 :         return 0;
     523             : }
     524             : 

Generated by: LCOV version 1.10