summaryrefslogtreecommitdiff
path: root/fs/autofs4/waitq.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/autofs4/waitq.c')
-rw-r--r--fs/autofs4/waitq.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index 24a58bf9ca72..8fc41705c7cd 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -56,19 +56,14 @@ static int autofs4_write(struct autofs_sb_info *sbi,
struct file *file, const void *addr, int bytes)
{
unsigned long sigpipe, flags;
- mm_segment_t fs;
const char *data = (const char *)addr;
ssize_t wr = 0;
sigpipe = sigismember(&current->pending.signal, SIGPIPE);
- /* Save pointer to user space and point back to kernel space */
- fs = get_fs();
- set_fs(KERNEL_DS);
-
mutex_lock(&sbi->pipe_mutex);
while (bytes) {
- wr = __vfs_write(file, data, bytes, &file->f_pos);
+ wr = __kernel_write(file, data, bytes, &file->f_pos);
if (wr <= 0)
break;
data += wr;
@@ -76,8 +71,6 @@ static int autofs4_write(struct autofs_sb_info *sbi,
}
mutex_unlock(&sbi->pipe_mutex);
- set_fs(fs);
-
/* Keep the currently executing process from receiving a
* SIGPIPE unless it was already supposed to get one
*/
@@ -88,7 +81,8 @@ static int autofs4_write(struct autofs_sb_info *sbi,
spin_unlock_irqrestore(&current->sighand->siglock, flags);
}
- return (bytes > 0);
+ /* if 'wr' returned 0 (impossible) we assume -EIO (safe) */
+ return bytes == 0 ? 0 : wr < 0 ? wr : -EIO;
}
static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
@@ -102,6 +96,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
} pkt;
struct file *pipe = NULL;
size_t pktsz;
+ int ret;
pr_debug("wait id = 0x%08lx, name = %.*s, type=%d\n",
(unsigned long) wq->wait_queue_token,
@@ -176,7 +171,18 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
mutex_unlock(&sbi->wq_mutex);
if (autofs4_write(sbi, pipe, &pkt, pktsz))
+ switch (ret = autofs4_write(sbi, pipe, &pkt, pktsz)) {
+ case 0:
+ break;
+ case -ENOMEM:
+ case -ERESTARTSYS:
+ /* Just fail this one */
+ autofs4_wait_release(sbi, wq->wait_queue_token, ret);
+ break;
+ default:
autofs4_catatonic_mode(sbi);
+ break;
+ }
fput(pipe);
}